diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2005-09-30 17:45:54 +0000 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2005-09-30 17:45:54 +0000 |
commit | 750877bad8740895d88b9f2f284e2400ef79f844 (patch) | |
tree | b3b9da46444fe90f99f8d9d180b0351dc6013cd9 /ld/ldlang.c | |
parent | 869b9d07bbfd935cc39b6bccb3da0506e467b6a7 (diff) | |
download | gdb-750877bad8740895d88b9f2f284e2400ef79f844.zip gdb-750877bad8740895d88b9f2f284e2400ef79f844.tar.gz gdb-750877bad8740895d88b9f2f284e2400ef79f844.tar.bz2 |
ld/
2005-09-30 H.J. Lu <hongjiu.lu@intel.com>
* ldlang.c (output_statement_hash_entry): New type.
(output_statement_table): New variable for hash table.
(output_statement_newfunc): New function.
(output_statement_table_init): Likewise.
(output_statement_table_free): Likewise.
(lang_init): Call output_statement_table_init.
(lang_finish): Renamed to ...
(lang_end): This.
(lang_process): Updated.
(lang_finish): New function.
(lang_output_section_find_1): Use hash table.
(lang_output_section_statement_lookup_1): Likewise.
* ldlang.h (lang_finish): New.
* ldmain.c (main): Call lang_finish.
ld/testsuite/
2005-09-30 H.J. Lu <hongjiu.lu@intel.com>
* ld-elf/sec64k.exp: Enabled for all ELF targets.
Diffstat (limited to 'ld/ldlang.c')
-rw-r--r-- | ld/ldlang.c | 84 |
1 files changed, 77 insertions, 7 deletions
diff --git a/ld/ldlang.c b/ld/ldlang.c index dc5f4ee..ecac4e4 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -868,6 +868,45 @@ lang_add_input_file (const char *name, return new_afile (name, file_type, target, TRUE); } +struct output_statement_hash_entry +{ + struct bfd_hash_entry root; + lang_output_section_statement_type *entry; +}; + +/* The hash table. */ + +static struct bfd_hash_table output_statement_table; + +/* Support routines for the hash table used by lang_output_section_find_1, + initialize the table, fill in an entry and remove the table. */ + +static struct bfd_hash_entry * +output_statement_newfunc (struct bfd_hash_entry *entry ATTRIBUTE_UNUSED, + struct bfd_hash_table *table, + const char *string ATTRIBUTE_UNUSED) +{ + struct output_statement_hash_entry *ret + = bfd_hash_allocate (table, + sizeof (struct output_statement_hash_entry)); + ret->entry = NULL; + return (struct bfd_hash_entry *) ret; +} + +static void +output_statement_table_init (void) +{ + if (! bfd_hash_table_init_n (&output_statement_table, + output_statement_newfunc, 61)) + einfo (_("%P%F: Failed to create hash table\n")); +} + +static void +output_statement_table_free (void) +{ + bfd_hash_table_free (&output_statement_table); +} + /* Build enough state so that the parser can build its tree. */ void @@ -877,6 +916,8 @@ lang_init (void) stat_ptr = &statement_list; + output_statement_table_init (); + lang_list_init (stat_ptr); lang_list_init (&input_file_chain); @@ -900,6 +941,12 @@ lang_init (void) einfo (_("%P%F: out of memory during initialization")); } +void +lang_finish (void) +{ + output_statement_table_free (); +} + /*---------------------------------------------------------------------- A region is an area of memory declared with the MEMORY { name:org=exp, len=exp ... } @@ -985,18 +1032,30 @@ static lang_output_section_statement_type * lang_output_section_find_1 (const char *const name, int constraint) { lang_output_section_statement_type *lookup; + struct output_statement_hash_entry *entry; + unsigned long hash; - for (lookup = &lang_output_section_statement.head->output_section_statement; - lookup != NULL; - lookup = lookup->next) + entry = ((struct output_statement_hash_entry *) + bfd_hash_lookup (&output_statement_table, name, FALSE, + FALSE)); + if (entry == NULL || (lookup = entry->entry) == NULL) + return NULL; + + hash = entry->root.hash; + do { - if (strcmp (name, lookup->name) == 0 - && lookup->constraint != -1 + if (lookup->constraint != -1 && (constraint == 0 || (constraint == lookup->constraint && constraint != SPECIAL))) return lookup; + entry = (struct output_statement_hash_entry *) entry->root.next; + lookup = entry ? entry->entry : NULL; } + while (entry != NULL + && entry->root.hash == hash + && strcmp (name, lookup->name) == 0); + return NULL; } @@ -1015,6 +1074,8 @@ lang_output_section_statement_lookup_1 (const char *const name, int constraint) lookup = lang_output_section_find_1 (name, constraint); if (lookup == NULL) { + struct output_statement_hash_entry *entry; + lookup = new_stat (lang_output_section_statement, stat_ptr); lookup->region = NULL; lookup->lma_region = NULL; @@ -1039,6 +1100,15 @@ lang_output_section_statement_lookup_1 (const char *const name, int constraint) lookup->update_dot_tree = NULL; lookup->phdrs = NULL; + entry = ((struct output_statement_hash_entry *) + bfd_hash_lookup (&output_statement_table, name, TRUE, + FALSE)); + if (entry == NULL) + einfo (_("%P%F: bfd_hash_lookup failed creating section `%s'\n"), + name); + + entry->entry = lookup; + /* GCC's strict aliasing rules prevent us from just casting the address, so we store the pointer in a variable and cast that instead. */ @@ -4637,7 +4707,7 @@ lang_set_startof (void) } static void -lang_finish (void) +lang_end (void) { struct bfd_link_hash_entry *h; bfd_boolean warn; @@ -5413,7 +5483,7 @@ lang_process (void) /* Final stuffs. */ ldemul_finish (); - lang_finish (); + lang_end (); } /* EXPORTED TO YACC */ |