PR28523, ld.bfd created undefined symbols on ppc64
authorAlan Modra <amodra@gmail.com>
Tue, 2 Nov 2021 08:31:06 +0000 (19:01 +1030)
committerAlan Modra <amodra@gmail.com>
Wed, 3 Nov 2021 00:16:29 +0000 (10:46 +1030)
This patch removes any fake (linker created) function descriptor
symbol if its code entry symbol isn't dynamic, to ensure bogus dynamic
symbols are not created.  The change to func_desc_adjust requires that
it be run only once, which means ppc64_elf_tls_setup can't call it for
just a few selected symbols.

PR 28523
* elf64-ppc.c (func_desc_adjust): If a function entry sym is
not dynamic and has no plt entry, hide any associated fake
function descriptor symbol.
(ppc64_elf_edit): Move func_desc_adjust iteration over syms to..
(ppc64_elf_tls_setup): ..here.

bfd/elf64-ppc.c

index 4ebacbd99457bcc6ea1d239159bd9d8b065115dc..40ae96b00d5e67ff08d987a53a0ff06048551f6c 100644 (file)
@@ -6281,7 +6281,8 @@ tls_get_addr_epilogue (bfd *obfd, bfd_byte *p, struct ppc_link_hash_table *htab)
 
 /* Called via elf_link_hash_traverse to transfer dynamic linking
    information on function code symbol entries to their corresponding
-   function descriptor symbol entries.  */
+   function descriptor symbol entries.  Must not be called twice for
+   any given code symbol.  */
 
 static bool
 func_desc_adjust (struct elf_link_hash_entry *h, void *inf)
@@ -6339,7 +6340,11 @@ func_desc_adjust (struct elf_link_hash_entry *h, void *inf)
        if (ent->plt.refcount > 0)
          break;
       if (ent == NULL)
-       return true;
+       {
+         if (fdh != NULL && fdh->fake)
+           _bfd_elf_link_hash_hide_symbol (info, &fdh->elf, true);
+         return true;
+       }
     }
 
   /* Create a descriptor as undefined if necessary.  */
@@ -6464,12 +6469,6 @@ ppc64_elf_edit (bfd *obfd ATTRIBUTE_UNUSED, struct bfd_link_info *info)
        = (htab->elf.hgot->other & ~ELF_ST_VISIBILITY (-1)) | STV_HIDDEN;
     }
 
-  if (htab->need_func_desc_adj)
-    {
-      elf_link_hash_traverse (&htab->elf, func_desc_adjust, info);
-      htab->need_func_desc_adj = 0;
-    }
-
   return true;
 }
 
@@ -7783,6 +7782,13 @@ ppc64_elf_tls_setup (struct bfd_link_info *info)
   if (htab == NULL)
     return false;
 
+  /* Move dynamic linking info to the function descriptor sym.  */
+  if (htab->need_func_desc_adj)
+    {
+      elf_link_hash_traverse (&htab->elf, func_desc_adjust, info);
+      htab->need_func_desc_adj = 0;
+    }
+
   if (abiversion (info->output_bfd) == 1)
     htab->opd_abi = 1;
 
@@ -7830,10 +7836,6 @@ ppc64_elf_tls_setup (struct bfd_link_info *info)
   tga = elf_link_hash_lookup (&htab->elf, ".__tls_get_addr",
                              false, false, true);
   htab->tls_get_addr = ppc_elf_hash_entry (tga);
-
-  /* Move dynamic linking info to the function descriptor sym.  */
-  if (tga != NULL)
-    func_desc_adjust (tga, info);
   tga_fd = elf_link_hash_lookup (&htab->elf, "__tls_get_addr",
                                 false, false, true);
   htab->tls_get_addr_fd = ppc_elf_hash_entry (tga_fd);
@@ -7841,8 +7843,6 @@ ppc64_elf_tls_setup (struct bfd_link_info *info)
   desc = elf_link_hash_lookup (&htab->elf, ".__tls_get_addr_desc",
                               false, false, true);
   htab->tga_desc = ppc_elf_hash_entry (desc);
-  if (desc != NULL)
-    func_desc_adjust (desc, info);
   desc_fd = elf_link_hash_lookup (&htab->elf, "__tls_get_addr_desc",
                                  false, false, true);
   htab->tga_desc_fd = ppc_elf_hash_entry (desc_fd);
@@ -7853,8 +7853,6 @@ ppc64_elf_tls_setup (struct bfd_link_info *info)
 
       opt = elf_link_hash_lookup (&htab->elf, ".__tls_get_addr_opt",
                                  false, false, true);
-      if (opt != NULL)
-       func_desc_adjust (opt, info);
       opt_fd = elf_link_hash_lookup (&htab->elf, "__tls_get_addr_opt",
                                     false, false, true);
       if (opt_fd != NULL