]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
1999-11-01 Steve Chamberlain <sac@pobox.com>
authorIan Lance Taylor <ian@airs.com>
Mon, 1 Nov 1999 23:37:48 +0000 (23:37 +0000)
committerIan Lance Taylor <ian@airs.com>
Mon, 1 Nov 1999 23:37:48 +0000 (23:37 +0000)
* 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.

ld/ChangeLog
ld/ldlang.c

index 99f59627b33c1a31bc6b9382487431082af9fe7d..ed7519d4e03ef3ab48d3a8fca1f5bafd9e27a6cd 100644 (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 
index 56a00540103c06d0fa7af70e12243c49a64712d6..33dc573c0d7ea26043b5a7c73b424f9960291a12 100644 (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;
     }
 }
-
+\f
 /* 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);
 }
 \f
 /* 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