aboutsummaryrefslogtreecommitdiff
path: root/bfd/elf64-ppc.c
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2021-03-02 21:22:31 +1030
committerAlan Modra <amodra@gmail.com>2021-03-02 21:47:42 +1030
commitf5b9c288a3057f0f04e74f00fdb0e79d171d54a8 (patch)
tree8286125cbea609ffb437fcd0155dbc6b913336a2 /bfd/elf64-ppc.c
parentec11fcffc00ed02eed7b18b312a1af857f5a8caa (diff)
downloadfsf-binutils-gdb-f5b9c288a3057f0f04e74f00fdb0e79d171d54a8.zip
fsf-binutils-gdb-f5b9c288a3057f0f04e74f00fdb0e79d171d54a8.tar.gz
fsf-binutils-gdb-f5b9c288a3057f0f04e74f00fdb0e79d171d54a8.tar.bz2
PowerPC64 undefined weak visibility vs GOT optimisation
Undefined weak symbols with non-default visibility are seen as local by SYMBOL_REFERENCES_LOCAL. This stops a got indirect to relative optimisation for them, so that pies and dlls don't get non-zero values when loading somewhere other than the address they are linked at (which always happens). The optimisation could be allowed for pdes, but I thought it best not to allow it there too. bfd/ * elf64-ppc.c (ppc64_elf_relocate_section): Don't optimise got indirect to pc-relative or toc-relative for undefined symbols. ld/ * testsuite/ld-powerpc/weak1.d, * testsuite/ld-powerpc/weak1.r, * testsuite/ld-powerpc/weak1.s, * testsuite/ld-powerpc/weak1so.d, * testsuite/ld-powerpc/weak1so.r: New tests. * testsuite/ld-powerpc/powerpc.exp: Run them.
Diffstat (limited to 'bfd/elf64-ppc.c')
-rw-r--r--bfd/elf64-ppc.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c
index dcd427b..769fff9 100644
--- a/bfd/elf64-ppc.c
+++ b/bfd/elf64-ppc.c
@@ -16081,6 +16081,9 @@ ppc64_elf_relocate_section (bfd *output_bfd,
break;
from = TOCstart + htab->sec_info[input_section->id].toc_off;
if (relocation + addend - from + 0x8000 < 0x10000
+ && sec != NULL
+ && sec->output_section != NULL
+ && !discarded_section (sec)
&& (h == NULL || SYMBOL_REFERENCES_LOCAL (info, &h->elf)))
{
insn = bfd_get_32 (input_bfd, contents + (rel->r_offset & ~3));
@@ -16101,6 +16104,9 @@ ppc64_elf_relocate_section (bfd *output_bfd,
break;
from = TOCstart + htab->sec_info[input_section->id].toc_off;
if (relocation + addend - from + 0x80008000ULL < 0x100000000ULL
+ && sec != NULL
+ && sec->output_section != NULL
+ && !discarded_section (sec)
&& (h == NULL || SYMBOL_REFERENCES_LOCAL (info, &h->elf)))
{
insn = bfd_get_32 (input_bfd, contents + (rel->r_offset & ~3));
@@ -16129,6 +16135,9 @@ ppc64_elf_relocate_section (bfd *output_bfd,
+ input_section->output_section->vma
+ input_section->output_offset);
if (!(relocation - from + (1ULL << 33) < 1ULL << 34
+ && sec != NULL
+ && sec->output_section != NULL
+ && !discarded_section (sec)
&& (h == NULL || SYMBOL_REFERENCES_LOCAL (info, &h->elf))))
break;