From: Alan Modra Date: Fri, 30 Nov 2018 05:04:11 +0000 (+1030) Subject: PR23937, powerpc64le local ifunc IRELATIVE relocs are wrong X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=ba85c15dabe144e4bcee5a1b388b32bee10729e1;p=binutils-gdb.git PR23937, powerpc64le local ifunc IRELATIVE relocs are wrong IFUNC resolvers must always be called via their global entry point. They will be called from ld.so rather than from the local executable. PR 23937 bfd/ * elf64-ppc.c (write_plt_relocs_for_local_syms): Don't add local entry offset for ifuncs. ld/ * testsuite/ld-powerpc/pr23937.d, * testsuite/ld-powerpc/pr23937.s: New test. * testsuite/ld-powerpc/powerpc.exp: Run it. --- diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 602e0a2ead3..8f455ae15f8 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,9 @@ +2018-11-30 Alan Modra + + PR 23937 + * elf64-ppc.c (write_plt_relocs_for_local_syms): Don't add local + entry offset for ifuncs. + 2018-11-29 H.J. Lu PR ld/23929 diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c index 7c3534ac654..a2d3ea067c3 100644 --- a/bfd/elf64-ppc.c +++ b/bfd/elf64-ppc.c @@ -12882,7 +12882,8 @@ write_plt_relocs_for_local_syms (struct bfd_link_info *info) } val = sym->st_value + ent->addend; - val += PPC64_LOCAL_ENTRY_OFFSET (sym->st_other); + if (ELF_ST_TYPE (sym->st_info) != STT_GNU_IFUNC) + val += PPC64_LOCAL_ENTRY_OFFSET (sym->st_other); if (sym_sec != NULL && sym_sec->output_section != NULL) val += sym_sec->output_offset + sym_sec->output_section->vma; diff --git a/ld/ChangeLog b/ld/ChangeLog index 5df13b80a3e..e203edcf2df 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,9 @@ +2018-11-30 Alan Modra + + * testsuite/ld-powerpc/pr23937.d, + * testsuite/ld-powerpc/pr23937.s: New test. + * testsuite/ld-powerpc/powerpc.exp: Run it. + 2018-11-29 Thomas Preud'homme * ldlang.c (statement_list): Document purpose and what next field it diff --git a/ld/testsuite/ld-powerpc/powerpc.exp b/ld/testsuite/ld-powerpc/powerpc.exp index 12590f18177..826dfedc121 100644 --- a/ld/testsuite/ld-powerpc/powerpc.exp +++ b/ld/testsuite/ld-powerpc/powerpc.exp @@ -334,6 +334,7 @@ if [ supports_ppc64 ] then { run_dump_test "dotsym2" run_dump_test "dotsym3" run_dump_test "dotsym4" + run_dump_test "pr23937" } run_dump_test "tlsld32" diff --git a/ld/testsuite/ld-powerpc/pr23937.d b/ld/testsuite/ld-powerpc/pr23937.d new file mode 100644 index 00000000000..6ef79e81cf6 --- /dev/null +++ b/ld/testsuite/ld-powerpc/pr23937.d @@ -0,0 +1,10 @@ +#as: -a64 +#ld: -melf64ppc --defsym puts=0 --defsym _start=0 +#readelf: -srW +# Check that the IRELATIVE addend is magic+0, not magic+8 + +#... +.* R_PPC64_IRELATIVE +10000180 +#... +.*: 0+10000180 +20 IFUNC +LOCAL +DEFAULT .* magic +#pass diff --git a/ld/testsuite/ld-powerpc/pr23937.s b/ld/testsuite/ld-powerpc/pr23937.s new file mode 100644 index 00000000000..155e53adb7a --- /dev/null +++ b/ld/testsuite/ld-powerpc/pr23937.s @@ -0,0 +1,65 @@ + .abiversion 2 + .text + .p2align 4,,15 + .type implementation, @function +implementation: +.LCF0: + addis 2,12,.TOC.-.LCF0@ha + addi 2,2,.TOC.-.LCF0@l + .localentry implementation,.-implementation + mflr 0 + addis 3,2,.LC0@toc@ha + addi 3,3,.LC0@toc@l + std 0,16(1) + stdu 1,-32(1) + bl puts + nop + addi 1,1,32 + li 3,0 + ld 0,16(1) + mtlr 0 + blr + .size implementation,.-implementation + + .p2align 4,,15 + .type resolver, @function +resolver: +.LCF1: + addis 2,12,.TOC.-.LCF1@ha + addi 2,2,.TOC.-.LCF1@l + .localentry resolver,.-resolver + addis 3,2,implementation@toc@ha + addi 3,3,implementation@toc@l + blr + .size resolver,.-resolver + + .type magic, @gnu_indirect_function + .set magic,resolver + + .section .text.startup,"ax",@progbits + .p2align 4,,15 + .globl main + .type main, @function +main: +.LCF2: + addis 2,12,.TOC.-.LCF2@ha + addi 2,2,.TOC.-.LCF2@l + .localentry main,.-main + mflr 0 + std 0,16(1) + stdu 1,-32(1) + bl magic + nop + addi 1,1,32 + cntlzw 3,3 + ld 0,16(1) + srwi 3,3,5 + mtlr 0 + xori 3,3,0x1 + blr + .size main,.-main + + .section .rodata.str1.8,"aMS",@progbits,1 + .p2align 3 +.LC0: + .string "'ere I am JH"