An adaptation of the existing pr19784 testcase. cat > pr19784a.c <<\EOF #include <stdio.h> int bar(void); int main(void) { if (bar()) printf ("PASS\n"); else __builtin_abort (); return 0; } EOF cat > pr19784b.c <<\EOF int foo (int x) __attribute__ ((ifunc ("resolve_foo"))); static int foo_impl(int x) { return x; } void *resolve_foo (void) { return (void *) foo_impl; } EOF cat > pr19784c.c <<\EOF extern int foo (int) __attribute__ ((visibility("hidden"))); int bar() { return foo (5) == 5; } EOF gcc -m32 -c -g -O2 -fPIC pr19784a.c gcc -m32 -c -g -O2 -fPIC pr19784b.c gcc -m32 -c -g -O2 -fPIC pr19784c.c gcc -m32 -shared -o libpr19784a.so pr19784b.o pr19784c.o gcc -m32 -shared -o libpr19784b.so pr19784c.o pr19784b.o gcc -m32 -o pr19784a pr19784a.o -Wl,--rpath=. libpr19784a.so gcc -m32 -o pr19784b pr19784a.o -Wl,--rpath=. libpr19784b.so ./pr19784a ./pr19784b The linker ought to issue an error rather than building invalid shared libraries that segfault at runtime. Ditto for the pr14961 testcase.
diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c index 4179572..aa6b8d0 100644 --- a/bfd/elf32-i386.c +++ b/bfd/elf32-i386.c @@ -2178,6 +2178,20 @@ do_relocation: a function defined in a shared library. */ if ((sec->flags & SEC_CODE) == 0) h->pointer_equality_needed = 1; + else if (h->type == STT_GNU_IFUNC + && bfd_link_pic (info)) + { + if (isym == NULL) + name = h->root.root.string; + else + name = bfd_elf_sym_name (abfd, symtab_hdr, isym, + NULL); + (*_bfd_error_handler) + (_("%B: unspported local call to IFUNC `%s'"), + abfd, name); + bfd_set_error (bfd_error_bad_value); + goto error_return; + } } else {
*** Bug 14961 has been marked as a duplicate of this bug. ***
The master branch has been updated by H.J. Lu <hjl@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=74437ea28fb611d4c88077b486fd7c0a8b4c2a25 commit 74437ea28fb611d4c88077b486fd7c0a8b4c2a25 Author: H.J. Lu <hjl.tools@gmail.com> Date: Mon Aug 29 08:12:59 2016 -0700 i386: Issue an error on non-PIC call to IFUNC in PIC object On i386, IFUNC function must be called via PLT. Since PLT in PIC object uses EBX register, R_386_PLT32 relocation must be used to call IFUNC function even when IFUNC function is defined locally. Linker should issue an error when R_386_PC32 relocation is used to call IFUNC function. Since PR ld/19784 tests doesn't use PLT relocation to local IFUNC function, they are moved to the x86-64 test directory. bfd/ PR ld/14961 PR ld/20515 * elf32-i386.c (elf_i386_check_relocs): Issue an error when R_386_PC32 relocation is used to call IFUNC function in PIC object. ld/ PR ld/14961 PR ld/20515 * testsuite/ld-i386/i386.exp: Run pr20515. * testsuite/ld-i386/pr20515.d: New file. * testsuite/ld-i386/pr20515.s: Likewise. * testsuite/ld-ifunc/ifunc-14a.s: Use R_386_PLT32 to call IFUNC function. * testsuite/ld-ifunc/ifunc-14c.s: Likewise. * testsuite/ld-ifunc/ifunc-2-i386.s: Likewise. * testsuite/ld-ifunc/ifunc-2-local-i386.s: Likewise. * testsuite/ld-ifunc/ifunc.exp: Move PR ld/19784 tests to ... * testsuite/ld-x86-64/x86-64.exp: Here. * testsuite/ld-ifunc/pr19784a.c: Moved to ... * testsuite/ld-x86-64/pr19784a.c: Here. * testsuite/ld-ifunc/pr19784b.c: Moved to ... * testsuite/ld-x86-64/pr19784b.c: Here. * testsuite/ld-ifunc/pr19784c.c: Moved to ... * testsuite/ld-x86-64/pr19784c.c: Here.
Fixed.