Bug 13817

Summary: Broken IFUNC support
Product: binutils Reporter: Jakub Jelinek <jakub>
Component: ldAssignee: Not yet assigned to anyone <unassigned>
Status: RESOLVED FIXED    
Severity: normal CC: hjl.tools
Priority: P2    
Version: unspecified   
Target Milestone: ---   
Host: Target: i386-linux
Build: Last reconfirmed:
Attachments: ifunctest.tar.bz2

Description Jakub Jelinek 2012-03-07 10:21:33 UTC
The PR ld/13302 changes broke not only x86_64 (fixed http://sources.redhat.com/ml/binutils-cvs/2012-03/msg00019.html ), but also i386.
ifunc3.sh test in prelink fails because of that.
The problem is that you just can't on i?86 use a standard PLT entry for what you want to do, because unlike x86_64 in i?86 shared libraries/PIEs the PLT slot assumes that %ebx of the caller points to the _GLOBAL_OFFSET_TABLE_ symbol of
the library containing the PLT slot.  That is normally the responsibility of the compiler or assembly writer, but in this case where you just have a function pointer that resolves internally to an IFUNC symbol you have no such guarantee.
If that function pointer is called from the main binary, %ebx can contain random garbage, if it is called from some other shared library, it will contain address of a different _GLOBAL_OFFSET_TABLE_ symbol.
Comment 1 Jakub Jelinek 2012-03-07 10:24:56 UTC
Created attachment 6264 [details]
ifunctest.tar.bz2

CC='gcc -m32' sh ./ifunc.sh
LD_LIBRARY_PATH=. ./ifunc3
shows the segfault (the PLT calling completely unrelated function).
Comment 2 H.J. Lu 2012-03-08 01:14:08 UTC
So we have to use real function, not PLT entry for non-GOT reference to
locally defined IFUNC symbols, at least on i386.  Will revert:

http://sourceware.org/ml/binutils/2011-10/msg00203.html

cause any problems? It will put IRELATIVE relocations in .rel.dyn/.rela.dyn
section, which was the previous behavior.
Comment 3 Jakub Jelinek 2012-03-08 08:09:51 UTC
I think you can keep x86_64 as is.  For i386 such PLT slots in the non-pic binaries could stay, but if we don't have any registers that we can clobber, the special alternate plt slots that would be needed would be complicated, especially when there is no red zone on i386.
So perhaps reverting that patch for i386 or limiting it to non-PIE executables is the best short time fix, until we figure out something that will work.  Without spare registers/red zone the only alternatives I can imagine are either one breaking the call/ret heuristics in the CPU (i.e. compute the desired address in the return slot on the stack (after call) and then ret to it), or using some __thread variable to hold where would we jump to.
Comment 4 H.J. Lu 2012-03-08 15:08:22 UTC
I'd like to keep i386 consistent with x86-64 as much as possible.
I will revert both changes.
Comment 5 Sourceware Commits 2012-03-09 16:28:50 UTC
CVSROOT:	/cvs/src
Module name:	src
Changes by:	hjl@sourceware.org	2012-03-09 16:28:38

Modified files:
	bfd            : ChangeLog elf32-i386.c elf64-x86-64.c 
	ld/testsuite   : ChangeLog 
	ld/testsuite/ld-i386: pr13302.d 
	ld/testsuite/ld-x86-64: pr13082-5b.d pr13082-6a.d pr13082-6b.d 

Log message:
	Restore R_386_IRELATIVE and R_X86_64_IRELATIVE
	
	bfd/
	
	2012-03-09  H.J. Lu  <hongjiu.lu@intel.com>
	
	PR ld/13817
	* bfd/elf32-i386.c (elf_i386_relocate_section): Restore
	R_386_IRELATIVE.
	
	* * elf64-x86-64.c (elf_x86_64_relocate_section): Restore
	R_X86_64_IRELATIVE.
	
	ld/testsuite/
	
	2012-03-09  H.J. Lu  <hongjiu.lu@intel.com>
	
	PR ld/13817
	* ld-i386/pr13302.d: Updated.
	* ld-x86-64/pr13082-5b.d: Likewise.
	* ld-x86-64/pr13082-6a.d: Likewise.
	* ld-x86-64/pr13082-6b.d: Likewise.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/src/bfd/ChangeLog.diff?cvsroot=src&r1=1.5624&r2=1.5625
http://sourceware.org/cgi-bin/cvsweb.cgi/src/bfd/elf32-i386.c.diff?cvsroot=src&r1=1.265&r2=1.266
http://sourceware.org/cgi-bin/cvsweb.cgi/src/bfd/elf64-x86-64.c.diff?cvsroot=src&r1=1.248&r2=1.249
http://sourceware.org/cgi-bin/cvsweb.cgi/src/ld/testsuite/ChangeLog.diff?cvsroot=src&r1=1.1499&r2=1.1500
http://sourceware.org/cgi-bin/cvsweb.cgi/src/ld/testsuite/ld-i386/pr13302.d.diff?cvsroot=src&r1=1.1&r2=1.2
http://sourceware.org/cgi-bin/cvsweb.cgi/src/ld/testsuite/ld-x86-64/pr13082-5b.d.diff?cvsroot=src&r1=1.2&r2=1.3
http://sourceware.org/cgi-bin/cvsweb.cgi/src/ld/testsuite/ld-x86-64/pr13082-6a.d.diff?cvsroot=src&r1=1.2&r2=1.3
http://sourceware.org/cgi-bin/cvsweb.cgi/src/ld/testsuite/ld-x86-64/pr13082-6b.d.diff?cvsroot=src&r1=1.2&r2=1.3
Comment 6 H.J. Lu 2012-03-13 02:27:39 UTC
Fixed.