diff options
author | Alan Modra <amodra@gmail.com> | 2017-10-31 22:13:21 +1030 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2017-11-01 18:46:34 +1030 |
commit | 3988aed54acce3c682a877b51b0e09cce1079e81 (patch) | |
tree | f06e9392e2810d410cd007b7d8ee52fb75320c99 /bfd/elf64-ppc.c | |
parent | e48f0c8f1b9fdb195394dc7afea02ce55e4ba5e4 (diff) | |
download | binutils-gdb-3988aed54acce3c682a877b51b0e09cce1079e81.tar.gz |
PR22374, PowerPC unnecessary PLT entries
We don't need a PLT entry when function pointer initialization in a
read/write section is the only reference to a given function symbol.
This patch prevents the unnecessary PLT entry, and ensures no dynamic
relocs are emitted when UNDEFWEAK_NO_DYNAMIC_RELOC says so.
bfd/
PR 22374
* elf32-ppc.c (ppc_elf_adjust_dynamic_symbol): Don't create a plt
entry when just a dynamic reloc can serve. Ensure no dynamic
relocations when UNDEFWEAK_NO_DYNAMIC_RELOC by setting non_got_ref.
Expand and move the non_got_ref comment.
* elf64-ppc.c (ppc64_elf_adjust_dynamic_symbol): Likewise.
ld/
* testsuite/ld-powerpc/ambiguousv2.d: Remove FIXME.
Diffstat (limited to 'bfd/elf64-ppc.c')
-rw-r--r-- | bfd/elf64-ppc.c | 30 |
1 files changed, 26 insertions, 4 deletions
diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c index 8c98fd5d0eb..5cf862b2dca 100644 --- a/bfd/elf64-ppc.c +++ b/bfd/elf64-ppc.c @@ -7193,6 +7193,16 @@ ppc64_elf_adjust_dynamic_symbol (struct bfd_link_info *info, h->plt.plist = NULL; h->needs_plt = 0; h->pointer_equality_needed = 0; + /* After adjust_dynamic_symbol, non_got_ref set in the + non-pic case means that dyn_relocs for this symbol should + be discarded. We either want the symbol to remain + undefined, or we have a local definition of some sort. + The "local definition" for non-function symbols may be + due to creating a local definition in .dynbss, and for + ELFv2 function symbols, defining the symbol on the PLT + call stub code. Set non_got_ref here to ensure undef + weaks stay undefined. */ + h->non_got_ref = 1; } else if (abiversion (info->output_bfd) >= 2) { @@ -7207,13 +7217,25 @@ ppc64_elf_adjust_dynamic_symbol (struct bfd_link_info *info, && !alias_readonly_dynrelocs (h)) { h->pointer_equality_needed = 0; - /* After adjust_dynamic_symbol, non_got_ref set in - the non-pic case means that dyn_relocs for this - symbol should be discarded. */ + /* Say that we do want dynamic relocs. */ h->non_got_ref = 0; + /* If we haven't seen a branch reloc then we don't need + a plt entry. */ + if (!h->needs_plt) + h->plt.plist = NULL; } - /* If making a plt entry, then we don't need copy relocs. */ + /* ELFv2 function symbols can't have copy relocs. */ + return TRUE; + } + else if (!h->needs_plt + && !alias_readonly_dynrelocs (h)) + { + /* If we haven't seen a branch reloc then we don't need a + plt entry. */ + h->plt.plist = NULL; + h->pointer_equality_needed = 0; + h->non_got_ref = 0; return TRUE; } } |