aboutsummaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2014-07-02 15:07:18 +0930
committerAlan Modra <amodra@gmail.com>2014-07-02 18:16:14 +0930
commitd1eca1e41ddae8c3cd925be827640de919301432 (patch)
tree94f81941bc024992334cec35ad62ad86418db131 /bfd
parent9b11e3a7327f7b1fd5d40a6450a3cc323a78380c (diff)
downloadgdb-d1eca1e41ddae8c3cd925be827640de919301432.zip
gdb-d1eca1e41ddae8c3cd925be827640de919301432.tar.gz
gdb-d1eca1e41ddae8c3cd925be827640de919301432.tar.bz2
Taking an undefined function's address in an executable
doesn't always mean you need to define a function symbol on plt code. If all references are in read-write sections, then using dynamic relocs is OK. bfd/ * elf32-ppc.c (ppc_elf_adjust_dynamic_symbol): Clear pointer_equality_needed when !readonly_dynrelocs. * elf64-ppc.c (ppc64_elf_adjust_dynamic_symbol): Likewise. ld/testsuite/ * ld-powerpc/ambiguousv1.d: Match symbol table too. * ld-powerpc/ambiguousv2.d: Likewise. * ld-powerpc/ambiguousv1b.d: New. * ld-powerpc/ambiguousv2b.d: New. * ld-powerpc/powerpc.exp: Run new tests.
Diffstat (limited to 'bfd')
-rw-r--r--bfd/ChangeLog6
-rw-r--r--bfd/elf32-ppc.c24
-rw-r--r--bfd/elf64-ppc.c20
3 files changed, 40 insertions, 10 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 9eb3eda..1218fc9 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,5 +1,11 @@
2014-07-02 Alan Modra <amodra@gmail.com>
+ * elf32-ppc.c (ppc_elf_adjust_dynamic_symbol): Clear
+ pointer_equality_needed when !readonly_dynrelocs.
+ * elf64-ppc.c (ppc64_elf_adjust_dynamic_symbol): Likewise.
+
+2014-07-02 Alan Modra <amodra@gmail.com>
+
* elf32-ppc.c (ppc_elf_check_relocs): Set DF_STATIC_TLS for PIEs too.
* elf64-ppc.c (ppc64_elf_check_relocs): Likewise.
diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c
index 0a9c8f9..e20e804 100644
--- a/bfd/elf32-ppc.c
+++ b/bfd/elf32-ppc.c
@@ -5506,9 +5506,21 @@ ppc_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
will go to this object, or will remain undefined. */
h->plt.plist = NULL;
h->needs_plt = 0;
+ h->pointer_equality_needed = 0;
}
else
{
+ /* Taking a function's address in a read/write section
+ doesn't require us to define the function symbol in the
+ executable on a global entry stub. A dynamic reloc can
+ be used instead. */
+ if (h->pointer_equality_needed
+ && !readonly_dynrelocs (h))
+ {
+ h->pointer_equality_needed = 0;
+ h->non_got_ref = 0;
+ }
+
/* After adjust_dynamic_symbol, non_got_ref set in the
non-shared case means that we have allocated space in
.dynbss for the symbol and thus dyn_relocs for this
@@ -5518,12 +5530,12 @@ ppc_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
relocations against this symbol to the PLT entry. Allow
dynamic relocs if the reference is weak, and the dynamic
relocs will not cause text relocation. */
- if (!h->ref_regular_nonweak
- && h->non_got_ref
- && h->type != STT_GNU_IFUNC
- && !htab->is_vxworks
- && !ppc_elf_hash_entry (h)->has_sda_refs
- && !readonly_dynrelocs (h))
+ else if (!h->ref_regular_nonweak
+ && h->non_got_ref
+ && h->type != STT_GNU_IFUNC
+ && !htab->is_vxworks
+ && !ppc_elf_hash_entry (h)->has_sda_refs
+ && !readonly_dynrelocs (h))
h->non_got_ref = 0;
}
return TRUE;
diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c
index 81e54a7..0efc602 100644
--- a/bfd/elf64-ppc.c
+++ b/bfd/elf64-ppc.c
@@ -6993,9 +6993,21 @@ ppc64_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
{
h->plt.plist = NULL;
h->needs_plt = 0;
+ h->pointer_equality_needed = 0;
}
else if (abiversion (info->output_bfd) == 2)
{
+ /* Taking a function's address in a read/write section
+ doesn't require us to define the function symbol in the
+ executable on a global entry stub. A dynamic reloc can
+ be used instead. */
+ if (h->pointer_equality_needed
+ && !readonly_dynrelocs (h))
+ {
+ h->pointer_equality_needed = 0;
+ h->non_got_ref = 0;
+ }
+
/* After adjust_dynamic_symbol, non_got_ref set in the
non-shared case means that we have allocated space in
.dynbss for the symbol and thus dyn_relocs for this
@@ -7005,10 +7017,10 @@ ppc64_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
relocations against this symbol to the PLT entry. Allow
dynamic relocs if the reference is weak, and the dynamic
relocs will not cause text relocation. */
- if (!h->ref_regular_nonweak
- && h->non_got_ref
- && h->type != STT_GNU_IFUNC
- && !readonly_dynrelocs (h))
+ else if (!h->ref_regular_nonweak
+ && h->non_got_ref
+ && h->type != STT_GNU_IFUNC
+ && !readonly_dynrelocs (h))
h->non_got_ref = 0;
/* If making a plt entry, then we don't need copy relocs. */