1999-11-01 Steve Chamberlain <sac@pobox.com>

* ldlang.c (section_already_linked): Rework to use hash table.
	(already_linked_newfunc): New function.
	(already_linked_table_init): New function.
	(already_linked_table_free): New function.
	(lang_process): Initialize and free the already_linked hash table.
This commit is contained in:
Ian Lance Taylor 1999-11-01 23:37:48 +00:00
parent 2bd7f1f332
commit 9503fd8735
2 changed files with 92 additions and 21 deletions

View File

@ -1,3 +1,11 @@
1999-11-01 Steve Chamberlain <sac@pobox.com>
* ldlang.c (section_already_linked): Rework to use hash table.
(already_linked_newfunc): New function.
(already_linked_table_init): New function.
(already_linked_table_free): New function.
(lang_process): Initialize and free the already_linked hash table.
1999-10-27 Andreas Jaeger <aj@suse.de>
* ld/configure.host: Added HOSTING_CRT0, HOSTING_LIBS for

View File

@ -73,6 +73,11 @@ static lang_input_statement_type *new_afile
static void init_os PARAMS ((lang_output_section_statement_type *s));
static void exp_init_os PARAMS ((etree_type *));
static void section_already_linked PARAMS ((bfd *, asection *, PTR));
static struct bfd_hash_entry *already_linked_newfunc
PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *,
const char *string));
static void already_linked_table_init PARAMS ((void));
static void already_linked_table_free PARAMS ((void));
static boolean wildcardp PARAMS ((const char *));
static lang_statement_union_type *wild_sort
PARAMS ((lang_wild_statement_type *, lang_input_statement_type *,
@ -858,15 +863,36 @@ exp_init_os (exp)
break;
}
}
/* Sections marked with the SEC_LINK_ONCE flag should only be linked
once into the output. This routine checks each sections, and
arranges to discard it if a section of the same name has already
once into the output. This routine checks each section, and
arrange to discard it if a section of the same name has already
been linked. If the section has COMDAT information, then it uses
that to decide whether the section should be included. This code
assumes that all relevant sections have the SEC_LINK_ONCE flag set;
that is, it does not depend solely upon the section name. This is
called via bfd_map_over_sections. */
that is, it does not depend solely upon the section name.
section_already_linked is called via bfd_map_over_sections. */
/* This is the shape of the elements inside the already_linked hash
table. It maps a name onto a list of already_linked elements with
the same name. It's possible to get more than one element in a
list if the COMDAT sections have different names. */
struct already_linked_hash_entry
{
struct bfd_hash_entry root;
struct already_linked *entry;
};
struct already_linked
{
struct already_linked *next;
asection *sec;
};
/* The hash table. */
static struct bfd_hash_table already_linked_table;
/*ARGSUSED*/
static void
@ -876,15 +902,10 @@ section_already_linked (abfd, sec, data)
PTR data;
{
lang_input_statement_type *entry = (lang_input_statement_type *) data;
struct sec_link_once
{
struct sec_link_once *next;
asection *sec;
};
static struct sec_link_once *sec_link_once_list;
flagword flags;
const char *name;
struct sec_link_once *l;
struct already_linked *l;
struct already_linked_hash_entry *already_linked_list;
/* If we are only reading symbols from this object, then we want to
discard all sections. */
@ -919,12 +940,15 @@ section_already_linked (abfd, sec, data)
name = bfd_get_section_name (abfd, sec);
for (l = sec_link_once_list; l != NULL; l = l->next)
already_linked_list =
((struct already_linked_hash_entry *)
bfd_hash_lookup (&already_linked_table, name, true, false));
for (l = already_linked_list->entry; l != NULL; l = l->next)
{
if (strcmp (name, bfd_get_section_name (l->sec->owner, l->sec)) == 0
&& (sec->comdat == NULL
|| l->sec->comdat == NULL
|| strcmp (sec->comdat->name, l->sec->comdat->name) == 0))
if (sec->comdat == NULL
|| l->sec->comdat == NULL
|| strcmp (sec->comdat->name, l->sec->comdat->name) == 0)
{
/* The section has already been linked. See if we should
issue a warning. */
@ -973,12 +997,47 @@ section_already_linked (abfd, sec, data)
}
}
/* This is the first section with this name. Record it. */
/* This is the first section with this name. Record it. Allocate
the memory from the same obstack as the hash table is kept in. */
l = ((struct already_linked *)
bfd_hash_allocate (&already_linked_table, sizeof *l));
l = (struct sec_link_once *) xmalloc (sizeof *l);
l->sec = sec;
l->next = sec_link_once_list;
sec_link_once_list = l;
l->next = already_linked_list->entry;
already_linked_list->entry = l;
}
/* Support routines for the hash table used by section_already_linked,
initialize the table, fill in an entry and remove the table. */
static struct bfd_hash_entry *
already_linked_newfunc (entry, table, string)
struct bfd_hash_entry *entry ATTRIBUTE_UNUSED;
struct bfd_hash_table *table;
const char *string ATTRIBUTE_UNUSED;
{
struct already_linked_hash_entry *ret =
bfd_hash_allocate (table, sizeof (struct already_linked_hash_entry));
ret->entry = NULL;
return (struct bfd_hash_entry *) ret;
}
static void
already_linked_table_init ()
{
if (! bfd_hash_table_init_n (&already_linked_table,
already_linked_newfunc,
42))
einfo (_("%P%F: Failed to create hash table\n"));
}
static void
already_linked_table_free ()
{
bfd_hash_table_free (&already_linked_table);
}
/* The wild routines.
@ -3848,12 +3907,16 @@ lang_process ()
/* Add to the hash table all undefineds on the command line */
lang_place_undefineds ();
already_linked_table_init ();
/* Create a bfd for each input file */
current_target = default_target;
open_input_bfds (statement_list.head, false);
ldemul_after_open ();
already_linked_table_free ();
/* Make sure that we're not mixing architectures. We call this
after all the input files have been opened, but before we do any
other processing, so that any operations merge_private_bfd_data