diff options
author | Alan Modra <amodra@gmail.com> | 2021-03-02 21:22:31 +1030 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2021-03-02 21:47:42 +1030 |
commit | f5b9c288a3057f0f04e74f00fdb0e79d171d54a8 (patch) | |
tree | 8286125cbea609ffb437fcd0155dbc6b913336a2 /bfd | |
parent | ec11fcffc00ed02eed7b18b312a1af857f5a8caa (diff) | |
download | binutils-f5b9c288a3057f0f04e74f00fdb0e79d171d54a8.zip binutils-f5b9c288a3057f0f04e74f00fdb0e79d171d54a8.tar.gz binutils-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')
-rw-r--r-- | bfd/ChangeLog | 5 | ||||
-rw-r--r-- | bfd/elf64-ppc.c | 9 |
2 files changed, 14 insertions, 0 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 818f580..44286c2 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,8 @@ +2021-03-02 Alan Modra <amodra@gmail.com> + + * elf64-ppc.c (ppc64_elf_relocate_section): Don't optimise got + indirect to pc-relative or toc-relative for undefined symbols. + 2021-03-01 Alan Modra <amodra@gmail.com> Fangrui Song <maskray@google.com> 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; |