elf_backend_archive_symbol_lookup
authorAlan Modra <amodra@gmail.com>
Mon, 12 Apr 2021 07:46:58 +0000 (17:16 +0930)
committerAlan Modra <amodra@gmail.com>
Mon, 12 Apr 2021 11:49:02 +0000 (21:19 +0930)
elf_backend_archive_symbol_lookup might be called when the linker hash
table has entries of type generic_link_hash_entry.  This happens for
instance when running the mmix target linker testsuite where the
output is mmo but input is elf64-mmix.

* elf-bfd.h (struct elf_backend_data): Return bfd_link_hash_entry*
from elf_backend_archive_symbol_lookup.
(_bfd_elf_archive_symbol_lookup): Return bfd_link_hash_entry*.
* elf64-ppc.c (ppc64_elf_archive_symbol_lookup): Likewise.  Check
we have a ppc_hash_table before accessing ppc_link_hash_entry
fields.
* elflink.c (_bfd_elf_archive_symbol_lookup): Return
bfd_link_hash_entry*.
(elf_link_add_archive_symbols): Adjust to suit.

bfd/ChangeLog
bfd/elf-bfd.h
bfd/elf64-ppc.c
bfd/elflink.c

index cb85678a716eda5981346adb9b2e79701914c333..68224f86fe90f794853a8b60c69d21f6f5a1f21d 100644 (file)
@@ -1,3 +1,15 @@
+2021-04-12  Alan Modra  <amodra@gmail.com>
+
+       * elf-bfd.h (struct elf_backend_data): Return bfd_link_hash_entry*
+       from elf_backend_archive_symbol_lookup.
+       (_bfd_elf_archive_symbol_lookup): Return bfd_link_hash_entry*.
+       * elf64-ppc.c (ppc64_elf_archive_symbol_lookup): Likewise.  Check
+       we have a ppc_hash_table before accessing ppc_link_hash_entry
+       fields.
+       * elflink.c (_bfd_elf_archive_symbol_lookup): Return
+       bfd_link_hash_entry*.
+       (elf_link_add_archive_symbols): Adjust to suit.
+
 2021-04-12  Nelson Chu  <nelson.chu@sifive.com>
 
        * elfxx-riscv.c (riscv_parse_std_ext): Fixed the wrong versions of
index 296b80ad95228e4934afa280ba60da531f9801da..6f9d7375eaf4db2067081b45f643d57a4b15dec4 100644 (file)
@@ -975,7 +975,7 @@ struct elf_backend_data
 
   /* A function to return the linker hash table entry of a symbol that
      might be satisfied by an archive symbol.  */
-  struct elf_link_hash_entry * (*elf_backend_archive_symbol_lookup)
+  struct bfd_link_hash_entry * (*elf_backend_archive_symbol_lookup)
     (bfd *, struct bfd_link_info *, const char *);
 
   /* Return true if local section symbols should have a non-null st_name.
@@ -2581,7 +2581,7 @@ extern bool _bfd_elf_relocs_compatible
 extern bool _bfd_elf_notice_as_needed
   (bfd *, struct bfd_link_info *, enum notice_asneeded_action);
 
-extern struct elf_link_hash_entry *_bfd_elf_archive_symbol_lookup
+extern struct bfd_link_hash_entry *_bfd_elf_archive_symbol_lookup
   (bfd *, struct bfd_link_info *, const char *);
 extern bool bfd_elf_link_add_symbols
   (bfd *, struct bfd_link_info *);
index c306954dacb7240a97bd20cb0bb6aacd07e1e8d8..7873f97ab32fd4b2c71b7857c08075e4cb5c82d1 100644 (file)
@@ -4196,20 +4196,21 @@ ppc64_elf_merge_symbol (struct elf_link_hash_entry *h,
    NAME is a symbol defined in an archive.  Return a symbol in the hash
    table that might be satisfied by the archive symbols.  */
 
-static struct elf_link_hash_entry *
+static struct bfd_link_hash_entry *
 ppc64_elf_archive_symbol_lookup (bfd *abfd,
                                 struct bfd_link_info *info,
                                 const char *name)
 {
-  struct elf_link_hash_entry *h;
+  struct bfd_link_hash_entry *h;
   char *dot_name;
   size_t len;
 
   h = _bfd_elf_archive_symbol_lookup (abfd, info, name);
   if (h != NULL
+      && ppc_hash_table (info) != NULL
       /* Don't return this sym if it is a fake function descriptor
         created by add_symbol_adjust.  */
-      && !ppc_elf_hash_entry (h)->fake)
+      && !((struct ppc_link_hash_entry *) h)->fake)
     return h;
 
   if (name[0] == '.')
@@ -4218,7 +4219,7 @@ ppc64_elf_archive_symbol_lookup (bfd *abfd,
   len = strlen (name);
   dot_name = bfd_alloc (abfd, len + 2);
   if (dot_name == NULL)
-    return (struct elf_link_hash_entry *) -1;
+    return (struct bfd_link_hash_entry *) -1;
   dot_name[0] = '.';
   memcpy (dot_name + 1, name, len + 1);
   h = _bfd_elf_archive_symbol_lookup (abfd, info, dot_name);
index e8f3a9edc620220e0f1abf1587dd06a99e217b84..3acf7951b5bd07efe653aefa85b7df1c69b82f0d 100644 (file)
@@ -5742,16 +5742,16 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
 /* Return the linker hash table entry of a symbol that might be
    satisfied by an archive symbol.  Return -1 on error.  */
 
-struct elf_link_hash_entry *
+struct bfd_link_hash_entry *
 _bfd_elf_archive_symbol_lookup (bfd *abfd,
                                struct bfd_link_info *info,
                                const char *name)
 {
-  struct elf_link_hash_entry *h;
+  struct bfd_link_hash_entry *h;
   char *p, *copy;
   size_t len, first;
 
-  h = elf_link_hash_lookup (elf_hash_table (info), name, false, false, true);
+  h = bfd_link_hash_lookup (info->hash, name, false, false, true);
   if (h != NULL)
     return h;
 
@@ -5768,20 +5768,19 @@ _bfd_elf_archive_symbol_lookup (bfd *abfd,
   len = strlen (name);
   copy = (char *) bfd_alloc (abfd, len);
   if (copy == NULL)
-    return (struct elf_link_hash_entry *) -1;
+    return (struct bfd_link_hash_entry *) -1;
 
   first = p - name + 1;
   memcpy (copy, name, first);
   memcpy (copy + first, name + first + 1, len - first);
 
-  h = elf_link_hash_lookup (elf_hash_table (info), copy, false, false, true);
+  h = bfd_link_hash_lookup (info->hash, copy, false, false, true);
   if (h == NULL)
     {
       /* We also need to check references to the symbol without the
         version.  */
       copy[first - 1] = '\0';
-      h = elf_link_hash_lookup (elf_hash_table (info), copy,
-                               false, false, true);
+      h = bfd_link_hash_lookup (info->hash, copy, false, false, true);
     }
 
   bfd_release (abfd, copy);
@@ -5810,7 +5809,7 @@ elf_link_add_archive_symbols (bfd *abfd, struct bfd_link_info *info)
   bool loop;
   size_t amt;
   const struct elf_backend_data *bed;
-  struct elf_link_hash_entry * (*archive_symbol_lookup)
+  struct bfd_link_hash_entry * (*archive_symbol_lookup)
     (bfd *, struct bfd_link_info *, const char *);
 
   if (! bfd_has_map (abfd))
@@ -5851,7 +5850,7 @@ elf_link_add_archive_symbols (bfd *abfd, struct bfd_link_info *info)
       symdefend = symdef + c;
       for (i = 0; symdef < symdefend; symdef++, i++)
        {
-         struct elf_link_hash_entry *h;
+         struct bfd_link_hash_entry *h;
          bfd *element;
          struct bfd_link_hash_entry *undefs_tail;
          symindex mark;
@@ -5865,21 +5864,22 @@ elf_link_add_archive_symbols (bfd *abfd, struct bfd_link_info *info)
            }
 
          h = archive_symbol_lookup (abfd, info, symdef->name);
-         if (h == (struct elf_link_hash_entry *) -1)
+         if (h == (struct bfd_link_hash_entry *) -1)
            goto error_return;
 
          if (h == NULL)
            continue;
 
-         if (h->root.type == bfd_link_hash_undefined)
+         if (h->type == bfd_link_hash_undefined)
            {
              /* If the archive element has already been loaded then one
                 of the symbols defined by that element might have been
                 made undefined due to being in a discarded section.  */
-             if (h->indx == -3)
+             if (is_elf_hash_table (info->hash)
+                 && ((struct elf_link_hash_entry *) h)->indx == -3)
                continue;
            }
-         else if (h->root.type == bfd_link_hash_common)
+         else if (h->type == bfd_link_hash_common)
            {
              /* We currently have a common symbol.  The archive map contains
                 a reference to this symbol, so we may want to include it.  We
@@ -5898,7 +5898,7 @@ elf_link_add_archive_symbols (bfd *abfd, struct bfd_link_info *info)
            }
          else
            {
-             if (h->root.type != bfd_link_hash_undefweak)
+             if (h->type != bfd_link_hash_undefweak)
                /* Symbol must be defined.  Don't check it again.  */
                included[i] = true;
              continue;