From 21d68fcd0c2f9113369d860ee1e5841bfacc35ff Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Thu, 27 Apr 2017 09:19:26 +0930 Subject: [PATCH] PowerPC undefweak handling This patch fixes a number of cases where -z nodynamic-undefined-weak was not effective in preventing dynamic relocations or linkage stubs. * elf32-ppc.c (UNDEFWEAK_NO_DYNAMIC_RELOC): Define. (ppc_elf_select_plt_layout, ppc_elf_tls_setup): Use it. (ppc_elf_adjust_dynamic_symbol, allocate_dynrelocs): Likewise. (ppc_elf_relocate_section): Likewise. Delete silly optimisation for undef and undefweak dyn_relocs. * elf64-ppc.c (UNDEFWEAK_NO_DYNAMIC_RELOC): Define. (ppc64_elf_adjust_dynamic_symbol, ppc64_elf_tls_setup): Use it. (allocate_got, allocate_dynrelocs): Likewise. (ppc64_elf_relocate_section): Likewise. --- bfd/ChangeLog | 12 ++++++++++++ bfd/elf32-ppc.c | 38 ++++++++++++++++---------------------- bfd/elf64-ppc.c | 27 +++++++++++++-------------- 3 files changed, 41 insertions(+), 36 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 32342300757..6cda710ff2a 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,15 @@ +2017-04-27 Alan Modra + + * elf32-ppc.c (UNDEFWEAK_NO_DYNAMIC_RELOC): Define. + (ppc_elf_select_plt_layout, ppc_elf_tls_setup): Use it. + (ppc_elf_adjust_dynamic_symbol, allocate_dynrelocs): Likewise. + (ppc_elf_relocate_section): Likewise. Delete silly optimisation + for undef and undefweak dyn_relocs. + * elf64-ppc.c (UNDEFWEAK_NO_DYNAMIC_RELOC): Define. + (ppc64_elf_adjust_dynamic_symbol, ppc64_elf_tls_setup): Use it. + (allocate_got, allocate_dynrelocs): Likewise. + (ppc64_elf_relocate_section): Likewise. + 2017-04-26 H.J. Lu * elf32-i386.c (elf_i386_size_dynamic_sections): Alwasys add diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c index 6a24a460391..7a462337dda 100644 --- a/bfd/elf32-ppc.c +++ b/bfd/elf32-ppc.c @@ -3221,6 +3221,13 @@ must_be_dyn_reloc (struct bfd_link_info *info, } } +/* Whether an undefined weak symbol should resolve to its link-time + value, even in PIC or PIE objects. */ +#define UNDEFWEAK_NO_DYNAMIC_RELOC(INFO, H) \ + ((H)->root.type == bfd_link_hash_undefweak \ + && (ELF_ST_VISIBILITY ((H)->other) != STV_DEFAULT \ + || (INFO)->dynamic_undefined_weak == 0)) + /* If ELIMINATE_COPY_RELOCS is non-zero, the linker will try to avoid copying dynamic variables from a shared lib into an app's dynbss section, and instead use a dynamic relocation to point into the @@ -4996,8 +5003,7 @@ ppc_elf_select_plt_layout (bfd *output_bfd ATTRIBUTE_UNUSED, || h->needs_plt) && h->ref_regular && !(SYMBOL_CALLS_LOCAL (info, h) - || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT - && h->root.type == bfd_link_hash_undefweak))) + || UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))) { /* Profiling of shared libs (and pies) is not supported with secure plt, because ppc32 does profiling before a @@ -5297,8 +5303,7 @@ ppc_elf_tls_setup (bfd *obfd, struct bfd_link_info *info) && (tga->type == STT_FUNC || tga->needs_plt) && !(SYMBOL_CALLS_LOCAL (info, tga) - || (ELF_ST_VISIBILITY (tga->other) != STV_DEFAULT - && tga->root.type == bfd_link_hash_undefweak))) + || UNDEFWEAK_NO_DYNAMIC_RELOC (info, tga))) { struct plt_entry *ent; for (ent = tga->plt.plist; ent != NULL; ent = ent->next) @@ -5684,8 +5689,7 @@ ppc_elf_adjust_dynamic_symbol (struct bfd_link_info *info, if (ent == NULL || (h->type != STT_GNU_IFUNC && (SYMBOL_CALLS_LOCAL (info, h) - || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT - && h->root.type == bfd_link_hash_undefweak)))) + || UNDEFWEAK_NO_DYNAMIC_RELOC (info, h)))) { /* A PLT entry is not required/allowed when: @@ -6018,8 +6022,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) || (htab->elf.dynamic_sections_created && eh->elf.dynindx != -1 && !SYMBOL_REFERENCES_LOCAL (info, &eh->elf))) - && (ELF_ST_VISIBILITY (eh->elf.other) == STV_DEFAULT - || eh->elf.root.type != bfd_link_hash_undefweak)) + && !UNDEFWEAK_NO_DYNAMIC_RELOC (info, &eh->elf)) { asection *rsec = htab->elf.srelgot; @@ -6060,9 +6063,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) /* Also discard relocs on undefined weak syms with non-default visibility, or when dynamic_undefined_weak says so. */ - else if (h->root.type == bfd_link_hash_undefweak - && (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT - || info->dynamic_undefined_weak == 0)) + else if (UNDEFWEAK_NO_DYNAMIC_RELOC (info, h)) eh->dyn_relocs = NULL; /* Relocs that use pc_count are those that appear on a call insn, @@ -8504,8 +8505,7 @@ ppc_elf_relocate_section (bfd *output_bfd, if (!htab->elf.dynamic_sections_created || h->dynindx == -1 || SYMBOL_REFERENCES_LOCAL (info, h) - || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT - && h->root.type == bfd_link_hash_undefweak)) + || UNDEFWEAK_NO_DYNAMIC_RELOC (info, h)) /* This is actually a static link, or it is a -Bsymbolic link and the symbol is defined locally, or the symbol was forced to be local @@ -8574,8 +8574,7 @@ ppc_elf_relocate_section (bfd *output_bfd, if (indx != 0 || (bfd_link_pic (info) && (h == NULL - || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT - || h->root.type != bfd_link_hash_undefweak + || !UNDEFWEAK_NO_DYNAMIC_RELOC (info, h) || offp == &htab->tlsld_got.offset))) { asection *rsec = htab->elf.srelgot; @@ -8862,9 +8861,7 @@ ppc_elf_relocate_section (bfd *output_bfd, && !(h != NULL && ((h->root.type == bfd_link_hash_undefined && ELF_ST_VISIBILITY (h->other) != STV_DEFAULT) - || (h->root.type == bfd_link_hash_undefweak - && (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT - || info->dynamic_undefined_weak == 0)))) + || UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))) && (must_be_dyn_reloc (info, r_type) || !SYMBOL_CALLS_LOCAL (info, h))) || (ELIMINATE_COPY_RELOCS @@ -8905,10 +8902,7 @@ ppc_elf_relocate_section (bfd *output_bfd, if (skip) memset (&outrel, 0, sizeof outrel); - else if ((h != NULL - && (h->root.type == bfd_link_hash_undefined - || h->root.type == bfd_link_hash_undefweak)) - || !SYMBOL_REFERENCES_LOCAL (info, h)) + else if (!SYMBOL_REFERENCES_LOCAL (info, h)) { indx = h->dynindx; BFD_ASSERT (indx != -1); diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c index 2e8f338748b..a20d9b3a285 100644 --- a/bfd/elf64-ppc.c +++ b/bfd/elf64-ppc.c @@ -3820,6 +3820,13 @@ must_be_dyn_reloc (struct bfd_link_info *info, } } +/* Whether an undefined weak symbol should resolve to its link-time + value, even in PIC or PIE objects. */ +#define UNDEFWEAK_NO_DYNAMIC_RELOC(INFO, H) \ + ((H)->root.type == bfd_link_hash_undefweak \ + && (ELF_ST_VISIBILITY ((H)->other) != STV_DEFAULT \ + || (INFO)->dynamic_undefined_weak == 0)) + /* If ELIMINATE_COPY_RELOCS is non-zero, the linker will try to avoid copying dynamic variables from a shared lib into an app's dynbss section, and instead use a dynamic relocation to point into the @@ -7297,8 +7304,7 @@ ppc64_elf_adjust_dynamic_symbol (struct bfd_link_info *info, if (ent == NULL || (h->type != STT_GNU_IFUNC && (SYMBOL_CALLS_LOCAL (info, h) - || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT - && h->root.type == bfd_link_hash_undefweak))) + || UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))) || ((struct ppc_link_hash_entry *) h)->save_res) { h->plt.plist = NULL; @@ -8354,8 +8360,7 @@ ppc64_elf_tls_setup (struct bfd_link_info *info) && (tga_fd->type == STT_FUNC || tga_fd->needs_plt) && !(SYMBOL_CALLS_LOCAL (info, tga_fd) - || (ELF_ST_VISIBILITY (tga_fd->other) != STV_DEFAULT - && tga_fd->root.type == bfd_link_hash_undefweak))) + || UNDEFWEAK_NO_DYNAMIC_RELOC (info, tga_fd))) { struct plt_entry *ent; @@ -9659,8 +9664,7 @@ allocate_got (struct elf_link_hash_entry *h, || (htab->elf.dynamic_sections_created && h->dynindx != -1 && !SYMBOL_REFERENCES_LOCAL (info, h))) - && (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT - || h->root.type != bfd_link_hash_undefweak)) + && !UNDEFWEAK_NO_DYNAMIC_RELOC (info, h)) { asection *relgot = ppc64_elf_tdata (gent->owner)->relgot; relgot->size += rentsize; @@ -9795,9 +9799,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) /* Also discard relocs on undefined weak syms with non-default visibility, or when dynamic_undefined_weak says so. */ - else if (h->root.type == bfd_link_hash_undefweak - && (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT - || info->dynamic_undefined_weak == 0)) + else if (UNDEFWEAK_NO_DYNAMIC_RELOC (info, h)) eh->dyn_relocs = NULL; if (eh->dyn_relocs != NULL) @@ -14458,8 +14460,7 @@ ppc64_elf_relocate_section (bfd *output_bfd, if (!htab->elf.dynamic_sections_created || h->elf.dynindx == -1 || SYMBOL_REFERENCES_LOCAL (info, &h->elf) - || (ELF_ST_VISIBILITY (h->elf.other) != STV_DEFAULT - && h->elf.root.type == bfd_link_hash_undefweak)) + || UNDEFWEAK_NO_DYNAMIC_RELOC (info, &h->elf)) /* This is actually a static link, or it is a -Bsymbolic link and the symbol is defined locally, or the symbol was forced to be local @@ -14525,9 +14526,7 @@ ppc64_elf_relocate_section (bfd *output_bfd, else if (indx != 0 || (bfd_link_pic (info) && (h == NULL - || (ELF_ST_VISIBILITY (h->elf.other) - == STV_DEFAULT) - || h->elf.root.type != bfd_link_hash_undefweak + || !UNDEFWEAK_NO_DYNAMIC_RELOC (info, &h->elf) || (tls_type == (TLS_TLS | TLS_LD) && !h->elf.def_dynamic)))) relgot = ppc64_elf_tdata (ent->owner)->relgot; -- 2.30.2