STT_GNU_IFUNC definition doesn't work in executable. I have a glibc patch: http://sourceware.org/ml/libc-alpha/2009-05/msg00182.html But it doesn't work with static executables. Should we allow STT_GNU_IFUNC definition in executable at all? [hjl@gnu-34 ifunc-2]$ cat prog.c extern int foo (int); int main (void) { foo (-3); return 0; } [hjl@gnu-34 ifunc-2]$ cat foo.c #include <stdio.h> int global = 1; static int minus_one (int x) { printf ("Hello minus_one: %d\n", x); return -1; } static int zero (int x) { printf ("Hello zero: %d\n", x); return 0; } void * foo_ifunc (void) __asm__ ("foo"); void * foo_ifunc (void) { return global ? minus_one : zero ; } __asm__(".type foo, %gnu_indirect_function"); [hjl@gnu-34 ifunc-2]$ make gcc -B./ -g -c -o prog.o prog.c gcc -B./ -g -c -o foo.o foo.c gcc -B./ -L. -nostdlib -nostartfiles -o dynamic \ -Wl,-dynamic-linker=/export/build/gnu/glibc-sse/build-x86_64-linux/elf/ld-linux-x86-64.so.2 \ -Wl,-z,combreloc \ /export/build/gnu/glibc-sse/build-x86_64-linux/csu/crt1.o /export/build/gnu/glibc-sse/build-x86_64-linux/csu/crti.o \ `gcc -B./ --print-file-name=crtbegin.o` \ prog.o foo.o -Wl,-rpath,. \ -Wl,-rpath=/export/build/gnu/glibc-sse/build-x86_64-linux:/export/build/gnu/glibc-sse/build-x86_64-linux/math \ /export/build/gnu/glibc-sse/build-x86_64-linux/elf/ld-linux-x86-64.so.2 \ /export/build/gnu/glibc-sse/build-x86_64-linux/libc.so.6 /export/build/gnu/glibc-sse/build-x86_64-linux/libc_nonshared.a \ -lgcc -lgcc_eh `gcc --print-file-name=crtend.o` \ /export/build/gnu/glibc-sse/build-x86_64-linux/csu/crtn.o ./dynamic segfault [hjl@gnu-34 ifunc-2]$ make static gcc -B./ -static -nostdlib -nostartfiles -o static \ /export/build/gnu/glibc-sse/build-x86_64-linux/csu/crt1.o /export/build/gnu/glibc-sse/build-x86_64-linux/csu/crti.o \ `gcc -B./ --print-file-name=crtbegin.o` \ prog.o foo.o \ /export/build/gnu/glibc-sse/build-x86_64-linux/libc.a \ -lgcc -lgcc_eh \ /export/build/gnu/glibc-sse/build-x86_64-linux/libc.a \ `gcc -B./ --print-file-name=crtend.o` \ /export/build/gnu/glibc-sse/build-x86_64-linux/csu/crtn.o [hjl@gnu-34 ifunc-2]$ ./static [hjl@gnu-34 ifunc-2]$
A patch is posted at http://sourceware.org/ml/binutils/2009-05/msg00531.html
Subject: Bug 10205 CVSROOT: /cvs/src Module name: src Changes by: hjl@sourceware.org 2009-06-01 13:11:52 Modified files: bfd : ChangeLog bfd-in2.h elf32-i386.c elf64-x86-64.c libbfd.h reloc.c include/elf : ChangeLog i386.h x86-64.h ld/testsuite : ChangeLog ld/testsuite/ld-ifunc: ifunc.exp lib.c Added files: ld/testsuite/ld-ifunc: ifunc-1-x86.d ifunc-1-x86.s ifunc-2-i386.d ifunc-2-i386.s ifunc-2-x86-64.d ifunc-2-x86-64.s ifunc-3-x86.s ifunc-3a-x86.d ifunc-3b-x86.d ifunc-4-x86.d ifunc-4-x86.s ifunc-5-i386.d ifunc-5-i386.s ifunc-5-x86-64.d ifunc-5-x86-64.s Log message: bfd/ 2009-06-01 H.J. Lu <hongjiu.lu@intel.com> PR ld/10205 * elf32-i386.c (elf_howto_table): Add R_386_IRELATIVE. (elf_i386_reloc_type_lookup): Likewise. (R_386_tls): Removed. (R_386_irelative): New. (R_386_vt_offset): Updated. (elf_i386_rtype_to_howto): Likewise. (elf_i386_link_hash_table): Add igotplt, iplt and irelplt. (elf_i386_link_hash_table_create): Initialize igotplt, iplt and irelplt. (elf_i386_check_relocs): Handle STT_GNU_IFUNC symbol first. (elf_i386_adjust_dynamic_symbol): Likewise. (elf_i386_allocate_dynrelocs): Likewise. (elf_i386_relocate_section): Likewise. (elf_i386_size_dynamic_sections): Set up .iplt and .igot.plt sections. (elf_i386_finish_dynamic_symbol): When building a static executable, use .iplt, .igot.plt and .rel.iplt sections for STT_GNU_IFUNC symbols. Generate R_386_IRELATIVE relocation for locally defined STT_GNU_IFUNC symbol. * elf64-x86-64.c (x86_64_elf_howto): Add R_X86_64_IRELATIVE. (x86_64_reloc_map): Likewise. (R_X86_64_standard): Updated. (elf64_x86_64_link_hash_table): Add igotplt, iplt and irelplt. (elf64_x86_64_link_hash_table_create): Initialize igotplt, iplt and irelplt. (elf64_x86_64_check_relocs): Handle STT_GNU_IFUNC symbol first. (elf64_x86_64_adjust_dynamic_symbol): Likewise. (elf64_x86_64_allocate_dynrelocs): Likewise. (elf64_x86_64_relocate_section): Likewise. (elf64_x86_64_size_dynamic_sections): Set up .iplt and .igot.plt sections. (elf64_x86_64_finish_dynamic_symbol): When building a static executable, use .iplt, .igot.plt and .rela.iplt sections for STT_GNU_IFUNC symbols. Generate R_X86_64_IRELATIVE relocation for locally defined STT_GNU_IFUNC symbol. * reloc.c (BFD_RELOC_386_IRELATIVE): New. (BFD_RELOC_X86_64_IRELATIVE): Likewise. * bfd-in2.h: Regenerated. * libbfd.h: Likewise. include/elf/ 2009-06-01 H.J. Lu <hongjiu.lu@intel.com> PR ld/10205 * i386.h (R_386_IRELATIVE): New. * x86-64.h (R_X86_64_IRELATIVE): Likewise. ld/testsuite/ 2009-06-01 H.J. Lu <hongjiu.lu@intel.com> PR ld/10205 * ld-ifunc/ifunc.exp (contains_irelative_reloc): New. Use it on executable and shared library. Run *.d. * ld-ifunc/lib.c: Add a hidden alias, __GI_library_func2, for library_func2. (library_func): New. * ld-ifunc/ifunc-1-x86.d: New. * ld-ifunc/ifunc-1-x86.s: Likewise. * ld-ifunc/ifunc-2-i386.d: Likewise. * ld-ifunc/ifunc-2-i386.s: Likewise. * ld-ifunc/ifunc-2-x86-64.d: Likewise. * ld-ifunc/ifunc-2-x86-64.s: Likewise. * ld-ifunc/ifunc-3a-x86.d: Likewise. * ld-ifunc/ifunc-3b-x86.d: Likewise. * ld-ifunc/ifunc-3-x86.s: Likewise. * ld-ifunc/ifunc-4-x86.d: Likewise. * ld-ifunc/ifunc-4-x86.s: Likewise. * ld-ifunc/ifunc-5-i386.d: Likewise. * ld-ifunc/ifunc-5-i386.s: Likewise. * ld-ifunc/ifunc-5-x86-64.d: Likewise. * ld-ifunc/ifunc-5-x86-64.s: Likewise. Patches: http://sources.redhat.com/cgi-bin/cvsweb.cgi/src/bfd/ChangeLog.diff?cvsroot=src&r1=1.4610&r2=1.4611 http://sources.redhat.com/cgi-bin/cvsweb.cgi/src/bfd/bfd-in2.h.diff?cvsroot=src&r1=1.481&r2=1.482 http://sources.redhat.com/cgi-bin/cvsweb.cgi/src/bfd/elf32-i386.c.diff?cvsroot=src&r1=1.196&r2=1.197 http://sources.redhat.com/cgi-bin/cvsweb.cgi/src/bfd/elf64-x86-64.c.diff?cvsroot=src&r1=1.155&r2=1.156 http://sources.redhat.com/cgi-bin/cvsweb.cgi/src/bfd/libbfd.h.diff?cvsroot=src&r1=1.215&r2=1.216 http://sources.redhat.com/cgi-bin/cvsweb.cgi/src/bfd/reloc.c.diff?cvsroot=src&r1=1.186&r2=1.187 http://sources.redhat.com/cgi-bin/cvsweb.cgi/src/include/elf/ChangeLog.diff?cvsroot=src&r1=1.364&r2=1.365 http://sources.redhat.com/cgi-bin/cvsweb.cgi/src/include/elf/i386.h.diff?cvsroot=src&r1=1.11&r2=1.12 http://sources.redhat.com/cgi-bin/cvsweb.cgi/src/include/elf/x86-64.h.diff?cvsroot=src&r1=1.11&r2=1.12 http://sources.redhat.com/cgi-bin/cvsweb.cgi/src/ld/testsuite/ChangeLog.diff?cvsroot=src&r1=1.1105&r2=1.1106 http://sources.redhat.com/cgi-bin/cvsweb.cgi/src/ld/testsuite/ld-ifunc/ifunc-1-x86.d.diff?cvsroot=src&r1=NONE&r2=1.1 http://sources.redhat.com/cgi-bin/cvsweb.cgi/src/ld/testsuite/ld-ifunc/ifunc-1-x86.s.diff?cvsroot=src&r1=NONE&r2=1.1 http://sources.redhat.com/cgi-bin/cvsweb.cgi/src/ld/testsuite/ld-ifunc/ifunc-2-i386.d.diff?cvsroot=src&r1=NONE&r2=1.1 http://sources.redhat.com/cgi-bin/cvsweb.cgi/src/ld/testsuite/ld-ifunc/ifunc-2-i386.s.diff?cvsroot=src&r1=NONE&r2=1.1 http://sources.redhat.com/cgi-bin/cvsweb.cgi/src/ld/testsuite/ld-ifunc/ifunc-2-x86-64.d.diff?cvsroot=src&r1=NONE&r2=1.1 http://sources.redhat.com/cgi-bin/cvsweb.cgi/src/ld/testsuite/ld-ifunc/ifunc-2-x86-64.s.diff?cvsroot=src&r1=NONE&r2=1.1 http://sources.redhat.com/cgi-bin/cvsweb.cgi/src/ld/testsuite/ld-ifunc/ifunc-3-x86.s.diff?cvsroot=src&r1=NONE&r2=1.1 http://sources.redhat.com/cgi-bin/cvsweb.cgi/src/ld/testsuite/ld-ifunc/ifunc-3a-x86.d.diff?cvsroot=src&r1=NONE&r2=1.1 http://sources.redhat.com/cgi-bin/cvsweb.cgi/src/ld/testsuite/ld-ifunc/ifunc-3b-x86.d.diff?cvsroot=src&r1=NONE&r2=1.1 http://sources.redhat.com/cgi-bin/cvsweb.cgi/src/ld/testsuite/ld-ifunc/ifunc-4-x86.d.diff?cvsroot=src&r1=NONE&r2=1.1 http://sources.redhat.com/cgi-bin/cvsweb.cgi/src/ld/testsuite/ld-ifunc/ifunc-4-x86.s.diff?cvsroot=src&r1=NONE&r2=1.1 http://sources.redhat.com/cgi-bin/cvsweb.cgi/src/ld/testsuite/ld-ifunc/ifunc-5-i386.d.diff?cvsroot=src&r1=NONE&r2=1.1 http://sources.redhat.com/cgi-bin/cvsweb.cgi/src/ld/testsuite/ld-ifunc/ifunc-5-i386.s.diff?cvsroot=src&r1=NONE&r2=1.1 http://sources.redhat.com/cgi-bin/cvsweb.cgi/src/ld/testsuite/ld-ifunc/ifunc-5-x86-64.d.diff?cvsroot=src&r1=NONE&r2=1.1 http://sources.redhat.com/cgi-bin/cvsweb.cgi/src/ld/testsuite/ld-ifunc/ifunc-5-x86-64.s.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.1&r2=1.2 http://sources.redhat.com/cgi-bin/cvsweb.cgi/src/ld/testsuite/ld-ifunc/lib.c.diff?cvsroot=src&r1=1.1&r2=1.2
Fixed.