aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2020-04-16 10:43:25 +0930
committerAlan Modra <amodra@gmail.com>2020-04-16 15:39:48 +0930
commit06507dab6172582d3924a3d7dc92a9e7d4ab60ff (patch)
tree688850722876dc681d649a397d610eed8dc07ada
parent937f6614685b83c67574d6549cea431b2069dfd8 (diff)
downloadfsf-binutils-gdb-06507dab6172582d3924a3d7dc92a9e7d4ab60ff.zip
fsf-binutils-gdb-06507dab6172582d3924a3d7dc92a9e7d4ab60ff.tar.gz
fsf-binutils-gdb-06507dab6172582d3924a3d7dc92a9e7d4ab60ff.tar.bz2
PowerPC64 GOT reloc optimisation
When the symbol referenced by a GOT reloc is an ifunc, we can't optimise away the GOT indirection. Well, we can, but only if a global entry stub is created with the ifunc symbol redefined to the stub. But that results in slower code and an indirection via the PLT so there isn't much to like about that solution. * elf64-ppc.c (ppc64_elf_edit_toc): Exclude ifunc from GOT optimisation. (ppc64_elf_relocate_section): Likewise.
-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 945f83c..25a3e46 100644
--- a/bfd/elf64-ppc.c
+++ b/bfd/elf64-ppc.c
@@ -9371,6 +9371,9 @@ ppc64_elf_edit_toc (struct bfd_link_info *info)
|| discarded_section (sym_sec))
continue;
+ if ((h ? h->type : ELF_ST_TYPE (sym->st_info)) == STT_GNU_IFUNC)
+ continue;
+
if (!SYMBOL_REFERENCES_LOCAL (info, h))
continue;
@@ -15886,6 +15889,8 @@ ppc64_elf_relocate_section (bfd *output_bfd,
break;
case R_PPC64_GOT16_DS:
+ if ((h ? h->elf.type : ELF_ST_TYPE (sym->st_info)) == STT_GNU_IFUNC)
+ break;
from = TOCstart + htab->sec_info[input_section->id].toc_off;
if (relocation + addend - from + 0x8000 < 0x10000
&& SYMBOL_REFERENCES_LOCAL (info, &h->elf))
@@ -15903,6 +15908,8 @@ ppc64_elf_relocate_section (bfd *output_bfd,
case R_PPC64_GOT16_LO_DS:
case R_PPC64_GOT16_HA:
+ if ((h ? h->elf.type : ELF_ST_TYPE (sym->st_info)) == STT_GNU_IFUNC)
+ break;
from = TOCstart + htab->sec_info[input_section->id].toc_off;
if (relocation + addend - from + 0x80008000ULL < 0x100000000ULL
&& SYMBOL_REFERENCES_LOCAL (info, &h->elf))
@@ -15924,6 +15931,8 @@ ppc64_elf_relocate_section (bfd *output_bfd,
break;
case R_PPC64_GOT_PCREL34:
+ if ((h ? h->elf.type : ELF_ST_TYPE (sym->st_info)) == STT_GNU_IFUNC)
+ break;
from = (rel->r_offset
+ input_section->output_section->vma
+ input_section->output_offset);