diff options
author | Ian Lance Taylor <ian@airs.com> | 1999-11-01 23:37:48 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@airs.com> | 1999-11-01 23:37:48 +0000 |
commit | 9503fd8735ec438fcb2fca34afa276e3e6ca94f5 (patch) | |
tree | c11a325558742324f26d022d24ed65514fd21e93 /ld/ldlang.c | |
parent | 2bd7f1f332946c3baeef11111d1dfb1994ce9942 (diff) | |
download | gdb-9503fd8735ec438fcb2fca34afa276e3e6ca94f5.zip gdb-9503fd8735ec438fcb2fca34afa276e3e6ca94f5.tar.gz gdb-9503fd8735ec438fcb2fca34afa276e3e6ca94f5.tar.bz2 |
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.
Diffstat (limited to 'ld/ldlang.c')
-rw-r--r-- | ld/ldlang.c | 105 |
1 files changed, 84 insertions, 21 deletions
diff --git a/ld/ldlang.c b/ld/ldlang.c index 56a0054..33dc573 100644 --- a/ld/ldlang.c +++ b/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 |