From 4a7e52349807017f9bc09ea25f07924f2ec971b3 Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Fri, 1 Dec 2017 07:53:16 +1030 Subject: [PATCH] PR22533, dynamic relocs generated for weak aliases This cleans up yet more craziness with non_got_ref. PR 22533 * elf32-hppa.c (elf32_hppa_copy_indirect_symbol): Don't do anything special with non_got_ref for weak aliases. (elf32_hppa_check_relocs): Tweak setting of non_got_ref. (elf32_hppa_adjust_dynamic_symbol): When initialising weak aliases, don't uselessly copy non_got_ref. Clear dyn_relocs instead if strong symbol is allocated in dynbss. Tidy comments. (elf32_hppa_relocate_section): Comment fix. * elf32-ppc.c (ppc_elf_copy_indirect_symbol): Don't do anything special with non_got_ref for weak aliases. (ppc_elf_adjust_dynamic_symbol): When initialising weak aliases, don't uselessly copy non_got_ref. Clear dyn_relocs instead if strong symbol is allocated in dynbss. Tidy comments. * elf64-ppc.c (ppc64_elf_copy_indirect_symbol): Don't do anything special with non_got_ref for weak aliases. (ppc64_elf_adjust_dynamic_symbol): When initialising weak aliases, don't uselessly copy non_got_ref. Clear dyn_relocs instead if strong symbol is allocated in dynbss. Tidy comments. --- bfd/ChangeLog | 21 ++++++++++++++++++++ bfd/elf32-hppa.c | 50 ++++++++++++++++-------------------------------- bfd/elf32-ppc.c | 23 ++++++++-------------- bfd/elf64-ppc.c | 22 +++++++-------------- 4 files changed, 53 insertions(+), 63 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index c23ac598ad8..1b2db461dd5 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,24 @@ +2017-12-01 Alan Modra + + PR 22533 + * elf32-hppa.c (elf32_hppa_copy_indirect_symbol): Don't do anything + special with non_got_ref for weak aliases. + (elf32_hppa_check_relocs): Tweak setting of non_got_ref. + (elf32_hppa_adjust_dynamic_symbol): When initialising weak aliases, + don't uselessly copy non_got_ref. Clear dyn_relocs instead if + strong symbol is allocated in dynbss. Tidy comments. + (elf32_hppa_relocate_section): Comment fix. + * elf32-ppc.c (ppc_elf_copy_indirect_symbol): Don't do anything + special with non_got_ref for weak aliases. + (ppc_elf_adjust_dynamic_symbol): When initialising weak aliases, + don't uselessly copy non_got_ref. Clear dyn_relocs instead if + strong symbol is allocated in dynbss. Tidy comments. + * elf64-ppc.c (ppc64_elf_copy_indirect_symbol): Don't do anything + special with non_got_ref for weak aliases. + (ppc64_elf_adjust_dynamic_symbol): When initialising weak aliases, + don't uselessly copy non_got_ref. Clear dyn_relocs instead if + strong symbol is allocated in dynbss. Tidy comments. + 2017-11-29 Nick Clifton PR 22509 diff --git a/bfd/elf32-hppa.c b/bfd/elf32-hppa.c index 6b2abb26a14..3f71159531d 100644 --- a/bfd/elf32-hppa.c +++ b/bfd/elf32-hppa.c @@ -1057,30 +1057,14 @@ elf32_hppa_copy_indirect_symbol (struct bfd_link_info *info, hh_ind->dyn_relocs = NULL; } - if (ELIMINATE_COPY_RELOCS - && eh_ind->root.type != bfd_link_hash_indirect - && eh_dir->dynamic_adjusted) + if (eh_ind->root.type == bfd_link_hash_indirect) { - /* If called to transfer flags for a weakdef during processing - of elf_adjust_dynamic_symbol, don't copy non_got_ref. - We clear it ourselves for ELIMINATE_COPY_RELOCS. */ - if (eh_dir->versioned != versioned_hidden) - eh_dir->ref_dynamic |= eh_ind->ref_dynamic; - eh_dir->ref_regular |= eh_ind->ref_regular; - eh_dir->ref_regular_nonweak |= eh_ind->ref_regular_nonweak; - eh_dir->needs_plt |= eh_ind->needs_plt; + hh_dir->plabel |= hh_ind->plabel; + hh_dir->tls_type |= hh_ind->tls_type; + hh_ind->tls_type = GOT_UNKNOWN; } - else - { - if (eh_ind->root.type == bfd_link_hash_indirect) - { - hh_dir->plabel |= hh_ind->plabel; - hh_dir->tls_type |= hh_ind->tls_type; - hh_ind->tls_type = GOT_UNKNOWN; - } - _bfd_elf_link_hash_copy_indirect (info, eh_dir, eh_ind); - } + _bfd_elf_link_hash_copy_indirect (info, eh_dir, eh_ind); } static int @@ -1424,7 +1408,7 @@ elf32_hppa_check_relocs (bfd *abfd, /* Flag this symbol as having a non-got, non-plt reference so that we generate copy relocs if it turns out to be dynamic. */ - if (hh != NULL && !bfd_link_pic (info)) + if (hh != NULL) hh->eh.non_got_ref = 1; /* If we are creating a shared library then we need to copy @@ -1748,6 +1732,10 @@ elf32_hppa_adjust_dynamic_symbol (struct bfd_link_info *info, else eh->plt.offset = (bfd_vma) -1; + htab = hppa_link_hash_table (info); + if (htab == NULL) + return FALSE; + /* If this is a weak symbol, and there is a real definition, the processor independent code will have arranged for us to see the real definition first, and we can just use the same value. */ @@ -1757,8 +1745,9 @@ elf32_hppa_adjust_dynamic_symbol (struct bfd_link_info *info, BFD_ASSERT (def->root.type == bfd_link_hash_defined); eh->root.u.def.section = def->root.u.def.section; eh->root.u.def.value = def->root.u.def.value; - if (ELIMINATE_COPY_RELOCS) - eh->non_got_ref = def->non_got_ref; + if (def->root.u.def.section == htab->etab.sdynbss + || def->root.u.def.section == htab->etab.sdynrelro) + hppa_elf_hash_entry (eh)->dyn_relocs = NULL; return TRUE; } @@ -1798,14 +1787,6 @@ elf32_hppa_adjust_dynamic_symbol (struct bfd_link_info *info, determine the address it must put in the global offset table, so both the dynamic object and the regular object will refer to the same memory location for the variable. */ - - htab = hppa_link_hash_table (info); - if (htab == NULL) - return FALSE; - - /* We must generate a COPY reloc to tell the dynamic linker to - copy the initial value out of the dynamic object and into the - runtime process image. */ if ((eh->root.u.def.section->flags & SEC_READONLY) != 0) { sec = htab->etab.sdynrelro; @@ -1818,6 +1799,9 @@ elf32_hppa_adjust_dynamic_symbol (struct bfd_link_info *info, } if ((eh->root.u.def.section->flags & SEC_ALLOC) != 0 && eh->size != 0) { + /* We must generate a COPY reloc to tell the dynamic linker to + copy the initial value out of the dynamic object and into the + runtime process image. */ srel->size += sizeof (Elf32_External_Rela); eh->needs_copy = 1; } @@ -3797,7 +3781,7 @@ elf32_hppa_relocate_section (bfd *output_bfd, bfd_link_pic (info), &hh->eh)) { - /* In a non-shared link, adjust_dynamic_symbols + /* In a non-shared link, adjust_dynamic_symbol isn't called for symbols forced local. We need to write out the plt entry here. */ if ((off & 1) != 0) diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c index 89069715191..80454eb3cee 100644 --- a/bfd/elf32-ppc.c +++ b/bfd/elf32-ppc.c @@ -3579,18 +3579,11 @@ ppc_elf_copy_indirect_symbol (struct bfd_link_info *info, edir->tls_mask |= eind->tls_mask; edir->has_sda_refs |= eind->has_sda_refs; - /* If called to transfer flags for a weakdef during processing - of elf_adjust_dynamic_symbol, don't copy non_got_ref. - We clear it ourselves for ELIMINATE_COPY_RELOCS. */ - if (!(ELIMINATE_COPY_RELOCS - && eind->elf.root.type != bfd_link_hash_indirect - && edir->elf.dynamic_adjusted)) - edir->elf.non_got_ref |= eind->elf.non_got_ref; - if (edir->elf.versioned != versioned_hidden) edir->elf.ref_dynamic |= eind->elf.ref_dynamic; edir->elf.ref_regular |= eind->elf.ref_regular; edir->elf.ref_regular_nonweak |= eind->elf.ref_regular_nonweak; + edir->elf.non_got_ref |= eind->elf.non_got_ref; edir->elf.needs_plt |= eind->elf.needs_plt; edir->elf.pointer_equality_needed |= eind->elf.pointer_equality_needed; @@ -5571,8 +5564,10 @@ ppc_elf_adjust_dynamic_symbol (struct bfd_link_info *info, BFD_ASSERT (def->root.type == bfd_link_hash_defined); h->root.u.def.section = def->root.u.def.section; h->root.u.def.value = def->root.u.def.value; - if (ELIMINATE_COPY_RELOCS) - h->non_got_ref = def->non_got_ref; + if (def->root.u.def.section == htab->elf.sdynbss + || def->root.u.def.section == htab->elf.sdynrelro + || def->root.u.def.section == htab->dynsbss) + ppc_elf_hash_entry (h)->dyn_relocs = NULL; return TRUE; } @@ -5641,7 +5636,6 @@ ppc_elf_adjust_dynamic_symbol (struct bfd_link_info *info, Of course, if the symbol is referenced using SDAREL relocs, we must instead allocate it in .sbss. */ - if (ppc_elf_hash_entry (h)->has_sda_refs) s = htab->dynsbss; else if ((h->root.u.def.section->flags & SEC_READONLY) != 0) @@ -5650,14 +5644,13 @@ ppc_elf_adjust_dynamic_symbol (struct bfd_link_info *info, s = htab->elf.sdynbss; BFD_ASSERT (s != NULL); - /* We must generate a R_PPC_COPY reloc to tell the dynamic linker to - copy the initial value out of the dynamic object and into the - runtime process image. We need to remember the offset into the - .rela.bss section we are going to use. */ if ((h->root.u.def.section->flags & SEC_ALLOC) != 0 && h->size != 0) { asection *srel; + /* We must generate a R_PPC_COPY reloc to tell the dynamic + linker to copy the initial value out of the dynamic object + and into the runtime process image. */ if (ppc_elf_hash_entry (h)->has_sda_refs) srel = htab->relsbss; else if ((h->root.u.def.section->flags & SEC_READONLY) != 0) diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c index 2486390babf..b7f4029bf56 100644 --- a/bfd/elf64-ppc.c +++ b/bfd/elf64-ppc.c @@ -4761,18 +4761,11 @@ ppc64_elf_copy_indirect_symbol (struct bfd_link_info *info, if (eind->oh != NULL) edir->oh = ppc_follow_link (eind->oh); - /* If called to transfer flags for a weakdef during processing - of elf_adjust_dynamic_symbol, don't copy NON_GOT_REF. - We clear it ourselves for ELIMINATE_COPY_RELOCS. */ - if (!(ELIMINATE_COPY_RELOCS - && eind->elf.root.type != bfd_link_hash_indirect - && edir->elf.dynamic_adjusted)) - edir->elf.non_got_ref |= eind->elf.non_got_ref; - if (edir->elf.versioned != versioned_hidden) edir->elf.ref_dynamic |= eind->elf.ref_dynamic; edir->elf.ref_regular |= eind->elf.ref_regular; edir->elf.ref_regular_nonweak |= eind->elf.ref_regular_nonweak; + edir->elf.non_got_ref |= eind->elf.non_got_ref; edir->elf.needs_plt |= eind->elf.needs_plt; edir->elf.pointer_equality_needed |= eind->elf.pointer_equality_needed; @@ -7216,8 +7209,9 @@ ppc64_elf_adjust_dynamic_symbol (struct bfd_link_info *info, BFD_ASSERT (def->root.type == bfd_link_hash_defined); h->root.u.def.section = def->root.u.def.section; h->root.u.def.value = def->root.u.def.value; - if (ELIMINATE_COPY_RELOCS) - h->non_got_ref = def->non_got_ref; + if (def->root.u.def.section == htab->elf.sdynbss + || def->root.u.def.section == htab->elf.sdynrelro) + ((struct ppc_link_hash_entry *) h)->dyn_relocs = NULL; return TRUE; } @@ -7275,11 +7269,6 @@ ppc64_elf_adjust_dynamic_symbol (struct bfd_link_info *info, determine the address it must put in the global offset table, so both the dynamic object and the regular object will refer to the same memory location for the variable. */ - - /* We must generate a R_PPC64_COPY reloc to tell the dynamic linker - to copy the initial value out of the dynamic object and into the - runtime process image. We need to remember the offset into the - .rela.bss section we are going to use. */ if ((h->root.u.def.section->flags & SEC_READONLY) != 0) { s = htab->elf.sdynrelro; @@ -7292,6 +7281,9 @@ ppc64_elf_adjust_dynamic_symbol (struct bfd_link_info *info, } if ((h->root.u.def.section->flags & SEC_ALLOC) != 0 && h->size != 0) { + /* We must generate a R_PPC64_COPY reloc to tell the dynamic + linker to copy the initial value out of the dynamic object + and into the runtime process image. */ srel->size += sizeof (Elf64_External_Rela); h->needs_copy = 1; } -- 2.30.2