aboutsummaryrefslogtreecommitdiff
path: root/ld/ldlang.c
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2005-09-30 17:45:54 +0000
committerH.J. Lu <hjl.tools@gmail.com>2005-09-30 17:45:54 +0000
commit750877bad8740895d88b9f2f284e2400ef79f844 (patch)
treeb3b9da46444fe90f99f8d9d180b0351dc6013cd9 /ld/ldlang.c
parent869b9d07bbfd935cc39b6bccb3da0506e467b6a7 (diff)
downloadgdb-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.c84
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 */