From 750877bad8740895d88b9f2f284e2400ef79f844 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Fri, 30 Sep 2005 17:45:54 +0000 Subject: [PATCH] ld/ 2005-09-30 H.J. Lu * 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 * ld-elf/sec64k.exp: Enabled for all ELF targets. --- ld/ChangeLog | 19 ++++++++++ ld/ldlang.c | 84 ++++++++++++++++++++++++++++++++++++++---- ld/ldlang.h | 2 + ld/ldmain.c | 2 + ld/testsuite/ChangeLog | 4 ++ ld/testsuite/ld-elf/sec64k.exp | 6 --- 6 files changed, 104 insertions(+), 13 deletions(-) diff --git a/ld/ChangeLog b/ld/ChangeLog index 24ae88f..8b743d2 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,22 @@ +2005-09-30 H.J. Lu + + * 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. + 2005-09-30 Mark Mitchell * ldmain.c (main): Use expandargv. 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 */ diff --git a/ld/ldlang.h b/ld/ldlang.h index 26b7d68..8ce312d 100644 --- a/ld/ldlang.h +++ b/ld/ldlang.h @@ -449,6 +449,8 @@ extern int lang_statement_iteration; extern void lang_init (void); +extern void lang_finish + (void); extern lang_memory_region_type *lang_memory_region_lookup (const char *const, bfd_boolean); extern lang_memory_region_type *lang_memory_region_default diff --git a/ld/ldmain.c b/ld/ldmain.c index dd79c23..f9e1348 100644 --- a/ld/ldmain.c +++ b/ld/ldmain.c @@ -474,6 +474,8 @@ main (int argc, char **argv) if (nocrossref_list != NULL) check_nocrossrefs (); + lang_finish (); + /* Even if we're producing relocatable output, some non-fatal errors should be reported in the exit status. (What non-fatal errors, if any, do we want to ignore for relocatable output?) */ diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog index 2408dc3..3fdfa9e 100644 --- a/ld/testsuite/ChangeLog +++ b/ld/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2005-09-30 H.J. Lu + + * ld-elf/sec64k.exp: Enabled for all ELF targets. + 2005-09-30 Catherine Moore * ld-elf/merge.d: Xfail bfin. diff --git a/ld/testsuite/ld-elf/sec64k.exp b/ld/testsuite/ld-elf/sec64k.exp index 5737fcf..cc15afb 100644 --- a/ld/testsuite/ld-elf/sec64k.exp +++ b/ld/testsuite/ld-elf/sec64k.exp @@ -24,12 +24,6 @@ if ![is_elf_format] { return } -# Per-port excludes, since this test takes an overwhelmingly long time -# currently. -if { ![istarget cris-*-*] } { - return -} - # Test >64k sections, with and without -r. First, create the assembly # files. Have a relocation to another section and one within the local # section. -- 2.7.4