summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2008-02-23 01:56:21 +0000
committerAlan Modra <amodra@gmail.com>2008-02-23 01:56:21 +0000
commit0eb4a168d474b103ece58f499e34ae7e99962f2a (patch)
tree7a433b7e22eff7bf5ed2a3fb73aa7d07df369575
parent3ae181ee8903e608d34e41dc92a28b22808bc495 (diff)
downloadbinutils-gdb-0eb4a168d474b103ece58f499e34ae7e99962f2a.tar.gz
* 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.
-rw-r--r--bfd/ChangeLog24
-rw-r--r--bfd/elf32-ppc.c73
2 files changed, 74 insertions, 23 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index ea813ff50af..b47d1331928 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,15 @@
+2008-02-23 Alan Modra <amodra@bigpond.net.au>
+
+ * 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 <hongjiu.lu@intel.com>
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 <nickc@redhat.com>
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 <amodra@bigpond.net.au>
@@ -342,13 +354,13 @@
Adjust initialisations relating to _ovly_buf_table.
2008-02-04 Bob Wilson <bob.wilson@acm.org>
-
+
* 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 <kai.tietz@onevision.com>
H.J. Lu <hongjiu.lu@intel.com>
diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c
index 0e215932de1..a859adfa361 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