From 0eb4a168d474b103ece58f499e34ae7e99962f2a Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Sat, 23 Feb 2008 01:56:21 +0000 Subject: [PATCH] * elf32-ppc.c (ppc_elf_copy_indirect_symbol): Copy pointer_equality_needed. (ppc_elf_check_relocs): Split out non-branch relocs from others that might emit dynamic relocs. Set pointer_equality_needed for their symbols. Don't set non_got_ref on branch reloc symbols. (ppc_elf_hash_symbol): New function. (elf_backend_hash_symbol): Define. (ppc_elf_finish_dynamic_symbol): Handle pointer_equality_needed. Error if pointer_equality_needed on weak plt symbol. --- bfd/ChangeLog | 24 ++++++++++++++----- bfd/elf32-ppc.c | 73 +++++++++++++++++++++++++++++++++++++++++++-------------- 2 files changed, 74 insertions(+), 23 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index ea813ff..b47d133 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,15 @@ +2008-02-23 Alan Modra + + * elf32-ppc.c (ppc_elf_copy_indirect_symbol): Copy + pointer_equality_needed. + (ppc_elf_check_relocs): Split out non-branch relocs from others + that might emit dynamic relocs. Set pointer_equality_needed + for their symbols. Don't set non_got_ref on branch reloc symbols. + (ppc_elf_hash_symbol): New function. + (elf_backend_hash_symbol): Define. + (ppc_elf_finish_dynamic_symbol): Handle pointer_equality_needed. + Error if pointer_equality_needed on weak plt symbol. + 2008-02-22 H.J. Lu PR ld/5788 @@ -9,7 +21,7 @@ PR 868 * dwarf2.c: Revert previous patch. All of the allocate memory is on an obstack which will be freed at some other time. - + 2008-02-20 Nick Clifton PR 868 @@ -224,7 +236,7 @@ (elf_s390_check_relocs): Use elf_symtab_hdr. (elf_s390_gc_sweep_hook): Likewise. (elf_s390_size_dynamic_sections): Likewise. - (elf_s390_relocate_section): Likewise. + (elf_s390_relocate_section): Likewise. * elf32-sh.c (sh_elf_mkobject): Call bfd_elf_allocate_object. (is_sh_elf): New macro. Checks a BFD to make sure that is an SH ELF bfd. @@ -280,7 +292,7 @@ (elf_s390_check_relocs): Use is_s390_elf macro to check the bfd being processed. (elf_s390_size_dynamic_sections): Likewise. - (elf_s390_relocate_section): Likewise. + (elf_s390_relocate_section): Likewise. (elf_s390_check_relocs): Use elf_symtab_hdr. (elf_s390_gc_sweep_hook): Likewise. (elf_s390_size_dynamic_sections): Likewise. @@ -306,7 +318,7 @@ (_bfd_sparc_elf_check_relocs): Use elf_symtab_hdr. (_bfd_sparc_elf_gc_sweep_hook): Likewise. (_bfd_sparc_elf_size_dynamic_sections): Likewise. - (_bfd_sparc_elf_relocate_section): Likewise. + (_bfd_sparc_elf_relocate_section): Likewise. 2008-02-12 Alan Modra @@ -342,13 +354,13 @@ Adjust initialisations relating to _ovly_buf_table. 2008-02-04 Bob Wilson - + * elf32-xtensa (elf_xtensa_relocate_section): After finding an invalid relocation, do not continue processing it. Ignore R_XTENSA_ASM_EXPAND relocations against dynamic symbols. (elf_xtensa_finish_dynamic_sections): Do not fail if there is no .xt.lit section. - + 2008-02-04 Kai Tietz H.J. Lu diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c index 0e21593..a859adf 100644 --- a/bfd/elf32-ppc.c +++ b/bfd/elf32-ppc.c @@ -2696,6 +2696,7 @@ ppc_elf_copy_indirect_symbol (struct bfd_link_info *info, edir->elf.ref_regular |= eind->elf.ref_regular; edir->elf.ref_regular_nonweak |= eind->elf.ref_regular_nonweak; edir->elf.needs_plt |= eind->elf.needs_plt; + edir->elf.pointer_equality_needed |= eind->elf.pointer_equality_needed; /* If we were called to copy over info for a weak sym, that's all. */ if (eind->elf.root.type != bfd_link_hash_indirect) @@ -3388,6 +3389,26 @@ ppc_elf_check_relocs (bfd *abfd, info->flags |= DF_STATIC_TLS; goto dodyn; + case R_PPC_ADDR32: + case R_PPC_ADDR16: + case R_PPC_ADDR16_LO: + case R_PPC_ADDR16_HI: + case R_PPC_ADDR16_HA: + case R_PPC_UADDR32: + case R_PPC_UADDR16: + if (h != NULL && !info->shared) + { + /* We may need a plt entry if the symbol turns out to be + a function defined in a dynamic object. */ + if (!update_plt_info (abfd, h, NULL, 0)) + return FALSE; + + /* We may need a copy reloc too. */ + h->non_got_ref = 1; + h->pointer_equality_needed = 1; + } + goto dodyn; + case R_PPC_REL32: if (h == NULL && got2 != NULL @@ -3432,17 +3453,10 @@ ppc_elf_check_relocs (bfd *abfd, } /* fall through */ - case R_PPC_ADDR32: case R_PPC_ADDR24: - case R_PPC_ADDR16: - case R_PPC_ADDR16_LO: - case R_PPC_ADDR16_HI: - case R_PPC_ADDR16_HA: case R_PPC_ADDR14: case R_PPC_ADDR14_BRTAKEN: case R_PPC_ADDR14_BRNTAKEN: - case R_PPC_UADDR32: - case R_PPC_UADDR16: dodyn1: if (h != NULL && !info->shared) { @@ -3450,9 +3464,6 @@ ppc_elf_check_relocs (bfd *abfd, a function defined in a dynamic object. */ if (!update_plt_info (abfd, h, NULL, 0)) return FALSE; - - /* We may need a copy reloc too. */ - h->non_got_ref = 1; } dodyn: @@ -5186,6 +5197,20 @@ ppc_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, return TRUE; } + +/* Return TRUE if symbol should be hashed in the `.gnu.hash' section. */ + +static bfd_boolean +ppc_elf_hash_symbol (struct elf_link_hash_entry *h) +{ + if (h->plt.plist != NULL + && !h->def_regular + && (!h->pointer_equality_needed + || !h->ref_regular_nonweak)) + return FALSE; + + return _bfd_elf_hash_symbol (h); +} #define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0])) @@ -7127,15 +7152,28 @@ ppc_elf_finish_dynamic_symbol (bfd *output_bfd, if (!h->def_regular) { - /* Mark the symbol as undefined, rather than as defined in - the .plt section. Leave the value alone. */ + /* Mark the symbol as undefined, rather than as + defined in the .plt section. Leave the value if + there were any relocations where pointer equality + matters (this is a clue for the dynamic linker, to + make function pointer comparisons work between an + application and shared library), otherwise set it + to zero. */ sym->st_shndx = SHN_UNDEF; - /* If the symbol is weak, we do need to clear the value. - Otherwise, the PLT entry would provide a definition for - the symbol even if the symbol wasn't defined anywhere, - and so the symbol would never be NULL. */ - if (!h->ref_regular_nonweak) + if (!h->pointer_equality_needed) sym->st_value = 0; + else if (!h->ref_regular_nonweak) + { + /* Choose your poison. We must have either text + dynamic relocations, broken function pointer + comparisons, or broken tests for a NULL + function pointer. */ + (*_bfd_error_handler) + (_("weak reference to %s in non-pic code" + " will break function pointer comparisons"), + h->root.root.string); + sym->st_value = 0; + } } doneone = TRUE; } @@ -7687,6 +7725,7 @@ ppc_elf_finish_dynamic_sections (bfd *output_bfd, #define elf_backend_adjust_dynamic_symbol ppc_elf_adjust_dynamic_symbol #define elf_backend_add_symbol_hook ppc_elf_add_symbol_hook #define elf_backend_size_dynamic_sections ppc_elf_size_dynamic_sections +#define elf_backend_hash_symbol ppc_elf_hash_symbol #define elf_backend_finish_dynamic_symbol ppc_elf_finish_dynamic_symbol #define elf_backend_finish_dynamic_sections ppc_elf_finish_dynamic_sections #define elf_backend_fake_sections ppc_elf_fake_sections -- 2.7.4