With a brand new binutils and gcc, when I compile gcc/testsuite/gcc.dg/attr-ifunc-4.c I see the call to magic() in main() going via a plt stub. There's an IRELATIVE reloc on the .iplt entry used by the stub. That's all as expected but the IRELATIVE reloc points at resolver+8. It should point at resolver+0. As it is, when ld.so calls the resolver func r2 will have ld.so's TOC pointer value and thus calculate the wrong offset to implementation().
The master branch has been updated by Alan Modra <amodra@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=ba85c15dabe144e4bcee5a1b388b32bee10729e1 commit ba85c15dabe144e4bcee5a1b388b32bee10729e1 Author: Alan Modra <amodra@gmail.com> Date: Fri Nov 30 15:34:11 2018 +1030 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.
The binutils-2_31-branch branch has been updated by Alan Modra <amodra@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=0f494b01431de53959dd72ccfed06a01d5172e3f commit 0f494b01431de53959dd72ccfed06a01d5172e3f Author: Alan Modra <amodra@gmail.com> Date: Fri Nov 30 15:34:11 2018 +1030 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. (cherry picked from commit ba85c15dabe144e4bcee5a1b388b32bee10729e1)
Fixed.