1999-11-01 Steve Chamberlain <sac@pobox.com>
* ldlang.c (section_already_linked): Rework to use hash table. (already_linked_newfunc): New function. (already_linked_table_init): New function. (already_linked_table_free): New function. (lang_process): Initialize and free the already_linked hash table.
This commit is contained in:
parent
2bd7f1f332
commit
9503fd8735
2 changed files with 92 additions and 21 deletions
|
@ -1,3 +1,11 @@
|
|||
1999-11-01 Steve Chamberlain <sac@pobox.com>
|
||||
|
||||
* ldlang.c (section_already_linked): Rework to use hash table.
|
||||
(already_linked_newfunc): New function.
|
||||
(already_linked_table_init): New function.
|
||||
(already_linked_table_free): New function.
|
||||
(lang_process): Initialize and free the already_linked hash table.
|
||||
|
||||
1999-10-27 Andreas Jaeger <aj@suse.de>
|
||||
|
||||
* ld/configure.host: Added HOSTING_CRT0, HOSTING_LIBS for
|
||||
|
|
105
ld/ldlang.c
105
ld/ldlang.c
|
@ -73,6 +73,11 @@ static lang_input_statement_type *new_afile
|
|||
static void init_os PARAMS ((lang_output_section_statement_type *s));
|
||||
static void exp_init_os PARAMS ((etree_type *));
|
||||
static void section_already_linked PARAMS ((bfd *, asection *, PTR));
|
||||
static struct bfd_hash_entry *already_linked_newfunc
|
||||
PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *,
|
||||
const char *string));
|
||||
static void already_linked_table_init PARAMS ((void));
|
||||
static void already_linked_table_free PARAMS ((void));
|
||||
static boolean wildcardp PARAMS ((const char *));
|
||||
static lang_statement_union_type *wild_sort
|
||||
PARAMS ((lang_wild_statement_type *, lang_input_statement_type *,
|
||||
|
@ -858,15 +863,36 @@ exp_init_os (exp)
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Sections marked with the SEC_LINK_ONCE flag should only be linked
|
||||
once into the output. This routine checks each sections, and
|
||||
arranges to discard it if a section of the same name has already
|
||||
once into the output. This routine checks each section, and
|
||||
arrange to discard it if a section of the same name has already
|
||||
been linked. If the section has COMDAT information, then it uses
|
||||
that to decide whether the section should be included. This code
|
||||
assumes that all relevant sections have the SEC_LINK_ONCE flag set;
|
||||
that is, it does not depend solely upon the section name. This is
|
||||
called via bfd_map_over_sections. */
|
||||
that is, it does not depend solely upon the section name.
|
||||
section_already_linked is called via bfd_map_over_sections. */
|
||||
|
||||
/* This is the shape of the elements inside the already_linked hash
|
||||
table. It maps a name onto a list of already_linked elements with
|
||||
the same name. It's possible to get more than one element in a
|
||||
list if the COMDAT sections have different names. */
|
||||
|
||||
struct already_linked_hash_entry
|
||||
{
|
||||
struct bfd_hash_entry root;
|
||||
struct already_linked *entry;
|
||||
};
|
||||
|
||||
struct already_linked
|
||||
{
|
||||
struct already_linked *next;
|
||||
asection *sec;
|
||||
};
|
||||
|
||||
/* The hash table. */
|
||||
|
||||
static struct bfd_hash_table already_linked_table;
|
||||
|
||||
/*ARGSUSED*/
|
||||
static void
|
||||
|
@ -876,15 +902,10 @@ section_already_linked (abfd, sec, data)
|
|||
PTR data;
|
||||
{
|
||||
lang_input_statement_type *entry = (lang_input_statement_type *) data;
|
||||
struct sec_link_once
|
||||
{
|
||||
struct sec_link_once *next;
|
||||
asection *sec;
|
||||
};
|
||||
static struct sec_link_once *sec_link_once_list;
|
||||
flagword flags;
|
||||
const char *name;
|
||||
struct sec_link_once *l;
|
||||
struct already_linked *l;
|
||||
struct already_linked_hash_entry *already_linked_list;
|
||||
|
||||
/* If we are only reading symbols from this object, then we want to
|
||||
discard all sections. */
|
||||
|
@ -919,12 +940,15 @@ section_already_linked (abfd, sec, data)
|
|||
|
||||
name = bfd_get_section_name (abfd, sec);
|
||||
|
||||
for (l = sec_link_once_list; l != NULL; l = l->next)
|
||||
already_linked_list =
|
||||
((struct already_linked_hash_entry *)
|
||||
bfd_hash_lookup (&already_linked_table, name, true, false));
|
||||
|
||||
for (l = already_linked_list->entry; l != NULL; l = l->next)
|
||||
{
|
||||
if (strcmp (name, bfd_get_section_name (l->sec->owner, l->sec)) == 0
|
||||
&& (sec->comdat == NULL
|
||||
|| l->sec->comdat == NULL
|
||||
|| strcmp (sec->comdat->name, l->sec->comdat->name) == 0))
|
||||
if (sec->comdat == NULL
|
||||
|| l->sec->comdat == NULL
|
||||
|| strcmp (sec->comdat->name, l->sec->comdat->name) == 0)
|
||||
{
|
||||
/* The section has already been linked. See if we should
|
||||
issue a warning. */
|
||||
|
@ -973,12 +997,47 @@ section_already_linked (abfd, sec, data)
|
|||
}
|
||||
}
|
||||
|
||||
/* This is the first section with this name. Record it. */
|
||||
/* This is the first section with this name. Record it. Allocate
|
||||
the memory from the same obstack as the hash table is kept in. */
|
||||
|
||||
l = ((struct already_linked *)
|
||||
bfd_hash_allocate (&already_linked_table, sizeof *l));
|
||||
|
||||
l = (struct sec_link_once *) xmalloc (sizeof *l);
|
||||
l->sec = sec;
|
||||
l->next = sec_link_once_list;
|
||||
sec_link_once_list = l;
|
||||
l->next = already_linked_list->entry;
|
||||
already_linked_list->entry = l;
|
||||
}
|
||||
|
||||
/* Support routines for the hash table used by section_already_linked,
|
||||
initialize the table, fill in an entry and remove the table. */
|
||||
|
||||
static struct bfd_hash_entry *
|
||||
already_linked_newfunc (entry, table, string)
|
||||
struct bfd_hash_entry *entry ATTRIBUTE_UNUSED;
|
||||
struct bfd_hash_table *table;
|
||||
const char *string ATTRIBUTE_UNUSED;
|
||||
{
|
||||
struct already_linked_hash_entry *ret =
|
||||
bfd_hash_allocate (table, sizeof (struct already_linked_hash_entry));
|
||||
|
||||
ret->entry = NULL;
|
||||
|
||||
return (struct bfd_hash_entry *) ret;
|
||||
}
|
||||
|
||||
static void
|
||||
already_linked_table_init ()
|
||||
{
|
||||
if (! bfd_hash_table_init_n (&already_linked_table,
|
||||
already_linked_newfunc,
|
||||
42))
|
||||
einfo (_("%P%F: Failed to create hash table\n"));
|
||||
}
|
||||
|
||||
static void
|
||||
already_linked_table_free ()
|
||||
{
|
||||
bfd_hash_table_free (&already_linked_table);
|
||||
}
|
||||
|
||||
/* The wild routines.
|
||||
|
@ -3848,12 +3907,16 @@ lang_process ()
|
|||
/* Add to the hash table all undefineds on the command line */
|
||||
lang_place_undefineds ();
|
||||
|
||||
already_linked_table_init ();
|
||||
|
||||
/* Create a bfd for each input file */
|
||||
current_target = default_target;
|
||||
open_input_bfds (statement_list.head, false);
|
||||
|
||||
ldemul_after_open ();
|
||||
|
||||
already_linked_table_free ();
|
||||
|
||||
/* Make sure that we're not mixing architectures. We call this
|
||||
after all the input files have been opened, but before we do any
|
||||
other processing, so that any operations merge_private_bfd_data
|
||||
|
|
Loading…
Reference in a new issue