* 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:
parent
774d73da58
commit
384a9dda99
13
ld/ChangeLog
13
ld/ChangeLog
@ -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.
|
||||||
|
159
ld/ldlang.c
159
ld/ldlang.c
@ -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;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user