* ldlang.c (struct output_statement_hash_entry): Don't indirect to os.

(output_statement_newfunc): Rewrite.
	(lang_output_section_find_1): Merge into..
	(lang_output_section_find): ..here.
	(lang_output_section_statement_lookup_1): Rewrite to handle
	multiple sections with the same name.
	(output_statement_table_init): Commonise error message.
	(lang_init, open_output): Likewise.
This commit is contained in:
Alan Modra 2005-11-04 13:26:53 +00:00
parent 774d73da58
commit 384a9dda99
2 changed files with 97 additions and 75 deletions

View File

@ -1,3 +1,14 @@
2005-11-04 Alan Modra <amodra@bigpond.net.au>
* ldlang.c (struct output_statement_hash_entry): Don't indirect to os.
(output_statement_newfunc): Rewrite.
(lang_output_section_find_1): Merge into..
(lang_output_section_find): ..here.
(lang_output_section_statement_lookup_1): Rewrite to handle
multiple sections with the same name.
(output_statement_table_init): Commonise error message.
(lang_init, open_output): Likewise.
2005-11-03 Paul Brook <paul@codesourcery.com> 2005-11-03 Paul Brook <paul@codesourcery.com>
* scripttempl/elf.sc: Add .init_array.* and .fini_array.*. * scripttempl/elf.sc: Add .init_array.* and .fini_array.*.
@ -145,7 +156,7 @@
* ldmain.c (main): Use expandargv. * ldmain.c (main): Use expandargv.
2005-09-30 Catherine Moore <clm@cm00re.com> 2005-09-30 Catherine Moore <clm@cm00re.com>
* Makefile.am: Bfin support. * Makefile.am: Bfin support.
* Makefile.in: Regenerated. * Makefile.in: Regenerated.
* aclocal.m4: Regenerated. * aclocal.m4: Regenerated.

View File

@ -871,26 +871,54 @@ lang_add_input_file (const char *name,
struct output_statement_hash_entry struct output_statement_hash_entry
{ {
struct bfd_hash_entry root; struct bfd_hash_entry root;
lang_output_section_statement_type *entry; lang_output_section_statement_type os;
}; };
/* The hash table. */ /* The hash table. */
static struct bfd_hash_table output_statement_table; static struct bfd_hash_table output_statement_table;
/* Support routines for the hash table used by lang_output_section_find_1, /* Support routines for the hash table used by lang_output_section_find,
initialize the table, fill in an entry and remove the table. */ initialize the table, fill in an entry and remove the table. */
static struct bfd_hash_entry * static struct bfd_hash_entry *
output_statement_newfunc (struct bfd_hash_entry *entry ATTRIBUTE_UNUSED, output_statement_newfunc (struct bfd_hash_entry *entry,
struct bfd_hash_table *table, struct bfd_hash_table *table,
const char *string ATTRIBUTE_UNUSED) const char *string)
{ {
struct output_statement_hash_entry *ret lang_output_section_statement_type **nextp;
= bfd_hash_allocate (table, struct output_statement_hash_entry *ret;
sizeof (struct output_statement_hash_entry));
ret->entry = NULL; if (entry == NULL)
return (struct bfd_hash_entry *) ret; {
entry = bfd_hash_allocate (table, sizeof (*ret));
if (entry == NULL)
return entry;
}
entry = bfd_hash_newfunc (entry, table, string);
if (entry == NULL)
return entry;
ret = (struct output_statement_hash_entry *) entry;
memset (&ret->os, 0, sizeof (ret->os));
ret->os.header.type = lang_output_section_statement_enum;
ret->os.subsection_alignment = -1;
ret->os.section_alignment = -1;
ret->os.block_value = 1;
lang_list_init (&ret->os.children);
lang_statement_append (stat_ptr,
(lang_statement_union_type *) &ret->os,
&ret->os.header.next);
/* GCC's strict aliasing rules prevent us from just casting the
address, so we store the pointer in a variable and cast that
instead. */
nextp = &ret->os.next;
lang_statement_append (&lang_output_section_statement,
(lang_statement_union_type *) &ret->os,
(lang_statement_union_type **) nextp);
return &ret->root;
} }
static void static void
@ -898,7 +926,7 @@ output_statement_table_init (void)
{ {
if (! bfd_hash_table_init_n (&output_statement_table, if (! bfd_hash_table_init_n (&output_statement_table,
output_statement_newfunc, 61)) output_statement_newfunc, 61))
einfo (_("%P%F: Failed to create hash table\n")); einfo (_("%P%F: can not create hash table: %E\n"));
} }
static void static void
@ -938,7 +966,7 @@ lang_init (void)
looks like other code here. */ looks like other code here. */
if (!bfd_hash_table_init_n (&lang_definedness_table, if (!bfd_hash_table_init_n (&lang_definedness_table,
lang_definedness_newfunc, 3)) lang_definedness_newfunc, 3))
einfo (_("%P%F: out of memory during initialization")); einfo (_("%P%F: can not create hash table: %E\n"));
} }
void void
@ -1028,96 +1056,79 @@ lang_memory_default (asection *section)
return lang_memory_region_lookup (DEFAULT_MEMORY_REGION, FALSE); return lang_memory_region_lookup (DEFAULT_MEMORY_REGION, FALSE);
} }
static lang_output_section_statement_type * lang_output_section_statement_type *
lang_output_section_find_1 (const char *const name, int constraint) lang_output_section_find (const char *const name)
{ {
lang_output_section_statement_type *lookup;
struct output_statement_hash_entry *entry; struct output_statement_hash_entry *entry;
unsigned long hash; unsigned long hash;
entry = ((struct output_statement_hash_entry *) entry = ((struct output_statement_hash_entry *)
bfd_hash_lookup (&output_statement_table, name, FALSE, bfd_hash_lookup (&output_statement_table, name, FALSE, FALSE));
FALSE)); if (entry == NULL)
if (entry == NULL || (lookup = entry->entry) == NULL)
return NULL; return NULL;
hash = entry->root.hash; hash = entry->root.hash;
do do
{ {
if (lookup->constraint != -1 if (entry->os.constraint != -1)
&& (constraint == 0 return &entry->os;
|| (constraint == lookup->constraint
&& constraint != SPECIAL)))
return lookup;
entry = (struct output_statement_hash_entry *) entry->root.next; entry = (struct output_statement_hash_entry *) entry->root.next;
lookup = entry ? entry->entry : NULL;
} }
while (entry != NULL while (entry != NULL
&& entry->root.hash == hash && entry->root.hash == hash
&& strcmp (name, lookup->name) == 0); && strcmp (name, entry->os.name) == 0);
return NULL; return NULL;
} }
lang_output_section_statement_type *
lang_output_section_find (const char *const name)
{
return lang_output_section_find_1 (name, 0);
}
static lang_output_section_statement_type * static lang_output_section_statement_type *
lang_output_section_statement_lookup_1 (const char *const name, int constraint) lang_output_section_statement_lookup_1 (const char *const name, int constraint)
{ {
lang_output_section_statement_type *lookup; struct output_statement_hash_entry *entry;
lang_output_section_statement_type **nextp; struct output_statement_hash_entry *last_ent;
unsigned long hash;
lookup = lang_output_section_find_1 (name, constraint); entry = ((struct output_statement_hash_entry *)
if (lookup == NULL) bfd_hash_lookup (&output_statement_table, name, TRUE, FALSE));
if (entry == NULL)
{ {
struct output_statement_hash_entry *entry; einfo (_("%P%F: failed creating section `%s': %E\n"), name);
return NULL;
}
lookup = new_stat (lang_output_section_statement, stat_ptr); if (entry->os.name != NULL)
lookup->region = NULL; {
lookup->lma_region = NULL; /* We have a section of this name, but it might not have the correct
lookup->fill = 0; constraint. */
lookup->block_value = 1; hash = entry->root.hash;
lookup->name = name; do
{
lookup->next = NULL; if (entry->os.constraint != -1
lookup->bfd_section = NULL; && (constraint == 0
lookup->processed = FALSE; || (constraint == entry->os.constraint
lookup->constraint = constraint; && constraint != SPECIAL)))
lookup->all_input_readonly = FALSE; return &entry->os;
lookup->ignored = FALSE; last_ent = entry;
lookup->sectype = normal_section; entry = (struct output_statement_hash_entry *) entry->root.next;
lookup->addr_tree = NULL; }
lang_list_init (&lookup->children); while (entry != NULL
&& entry->root.hash == hash
lookup->flags = 0; && strcmp (name, entry->os.name) == 0);
lookup->subsection_alignment = -1;
lookup->section_alignment = -1;
lookup->load_base = NULL;
lookup->update_dot_tree = NULL;
lookup->phdrs = NULL;
entry = ((struct output_statement_hash_entry *) entry = ((struct output_statement_hash_entry *)
bfd_hash_lookup (&output_statement_table, name, TRUE, output_statement_newfunc (NULL, &output_statement_table, name));
FALSE));
if (entry == NULL) if (entry == NULL)
einfo (_("%P%F: bfd_hash_lookup failed creating section `%s'\n"), {
name); einfo (_("%P%F: failed creating section `%s': %E\n"), name);
return NULL;
entry->entry = lookup; }
entry->root = last_ent->root;
/* GCC's strict aliasing rules prevent us from just casting the last_ent->root.next = &entry->root;
address, so we store the pointer in a variable and cast that
instead. */
nextp = &lookup->next;
lang_statement_append (&lang_output_section_statement,
(lang_statement_union_type *) lookup,
(lang_statement_union_type **) nextp);
} }
return lookup;
entry->os.name = name;
entry->os.constraint = constraint;
return &entry->os;
} }
lang_output_section_statement_type * lang_output_section_statement_type *
@ -2671,7 +2682,7 @@ open_output (const char *name)
link_info.hash = bfd_link_hash_table_create (output); link_info.hash = bfd_link_hash_table_create (output);
if (link_info.hash == NULL) if (link_info.hash == NULL)
einfo (_("%P%F: can not create link hash table: %E\n")); einfo (_("%P%F: can not create hash table: %E\n"));
bfd_set_gp_size (output, g_switch_value); bfd_set_gp_size (output, g_switch_value);
return output; return output;