aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2021-11-02 19:01:06 +1030
committerAndreas K. Hüttel <dilfridge@gentoo.org>2021-12-08 19:43:49 +0100
commit252fcc790dcac157260bd5a904f7cef9950f5cad (patch)
treef850bab68bbd2e780cca858b980a447a44bea6b3
parentPR28417, std::string no longer allows accepting nullptr_t (diff)
downloadbinutils-gdb-252fcc790dcac157260bd5a904f7cef9950f5cad.tar.gz
binutils-gdb-252fcc790dcac157260bd5a904f7cef9950f5cad.tar.bz2
binutils-gdb-252fcc790dcac157260bd5a904f7cef9950f5cad.zip
PR28523, ld.bfd created undefined symbols on ppc64
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. (cherry picked from commit a442059f66075e4e503c43b119cc8b7de04e5718) (cherry picked from commit b1d7b59622f9941e7fa72418b7a41f148d83155e)
-rw-r--r--bfd/elf64-ppc.c30
1 files changed, 14 insertions, 16 deletions
diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c
index 55c5e500d06..38c2ccf78be 100644
--- a/bfd/elf64-ppc.c
+++ b/bfd/elf64-ppc.c
@@ -6243,7 +6243,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)
@@ -6301,7 +6302,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. */
@@ -6426,12 +6431,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;
}
@@ -7745,6 +7744,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;
@@ -7792,10 +7798,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);
@@ -7803,8 +7805,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);
@@ -7815,8 +7815,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