See https://bugzilla.redhat.com/show_bug.cgi?id=512937 No SHN_UNDEF symbols should ever have STT_GNU_IFUNC type, they should be STT_FUNC instead. Whether a symbol in the shared library some other shared library or binary is linked dynamically against is STT_GNU_IFUNC or not doesn't say anything about whether it will be actually indirect or direct function call at runtime. IFUNC is always only a property of a symbol definition. Especially for PLT SHN_UNDEF symbols with non-zero st_value this is fatal problem, see e.g. https://bugzilla.redhat.com/show_bug.cgi?id=512078 Testcase: BINUTILS_OBJ=/usr/src/binutils/obj BINUTILS_SRC=/usr/src/binutils gcc -B$BINUTILS_OBJ/ld/tmpdir/gas/ -I$BINUTILS_SRC/ld/testsuite/ld-ifunc -g -O2 \ -c -fPIC -DWITH_IFUNC -c $BINUTILS_SRC/ld/testsuite/ld-ifunc/lib.c \ -o shared_ifunc.o $BINUTILS_OBJ/ld/ld-new -o libshared_ifunc.so -shared shared_ifunc.o echo 'extern int library_func2 (void);' > test.c echo 'int main (void) { library_func2 (); return 0; }' >> test.c gcc -B $BINUTILS_OBJ/ld/tmpdir/ld/ -o test test.c ./libshared_ifunc.so $BINUTILS_OBJ/binutils/readelf -Ws test | grep IFUNC.*UND echo 'extern int library_func2 (void);' > test2.c echo 'int (*fn) (void) = library_func2;' >> test2.c echo 'int main (void) { fn (); return 0; }' >> test2.c gcc -B $BINUTILS_OBJ/ld/tmpdir/ld/ -o test2 test2.c ./libshared_ifunc.so $BINUTILS_OBJ/binutils/readelf -Ws test2 | grep IFUNC.*UND Should print nothing, prints: 1: 0000000000000000 0 IFUNC GLOBAL DEFAULT UND library_func2 49: 0000000000000000 0 IFUNC GLOBAL DEFAULT UND library_func2 5: 0000000000400458 0 IFUNC GLOBAL DEFAULT UND library_func2 49: 0000000000400458 0 IFUNC GLOBAL DEFAULT UND library_func2 with CVS trunk.
Created attachment 4072 [details] A patch Can you try this patch?
Works for me.
Subject: Bug 10426 CVSROOT: /cvs/src Module name: src Changes by: hjl@sourceware.org 2009-07-21 21:37:26 Modified files: bfd : ChangeLog elflink.c ld/testsuite : ChangeLog ld/testsuite/ld-ifunc: ifunc.exp Added files: ld/testsuite/ld-ifunc: test-1.c test-2.c Log message: bfd/ 2009-07-21 H.J. Lu <hongjiu.lu@intel.com> PR ld/10426 * elflink.c (elf_link_add_object_symbols): Turn an IFUNC symbol from a DSO into a normal FUNC symbol. (elf_link_output_extsym): Turn an undefined IFUNC symbol into a normal FUNC symbol. ld/testsuite/ 2009-07-21 H.J. Lu <hongjiu.lu@intel.com> PR ld/10426 * ld-ifunc/ifunc.exp: Check test-1 and libtest-2.so. Updated. * ld-ifunc/test-1.c: New. * ld-ifunc/test-2.c: Likewise. Patches: http://sources.redhat.com/cgi-bin/cvsweb.cgi/src/bfd/ChangeLog.diff?cvsroot=src&r1=1.4695&r2=1.4696 http://sources.redhat.com/cgi-bin/cvsweb.cgi/src/bfd/elflink.c.diff?cvsroot=src&r1=1.346&r2=1.347 http://sources.redhat.com/cgi-bin/cvsweb.cgi/src/ld/testsuite/ChangeLog.diff?cvsroot=src&r1=1.1131&r2=1.1132 http://sources.redhat.com/cgi-bin/cvsweb.cgi/src/ld/testsuite/ld-ifunc/test-1.c.diff?cvsroot=src&r1=NONE&r2=1.1 http://sources.redhat.com/cgi-bin/cvsweb.cgi/src/ld/testsuite/ld-ifunc/test-2.c.diff?cvsroot=src&r1=NONE&r2=1.1 http://sources.redhat.com/cgi-bin/cvsweb.cgi/src/ld/testsuite/ld-ifunc/ifunc.exp.diff?cvsroot=src&r1=1.5&r2=1.6
Fixed.