Bug 13817 - Broken IFUNC support
Summary: Broken IFUNC support
Alias: None
Product: binutils
Classification: Unclassified
Component: ld (show other bugs)
Version: unspecified
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
Depends on:
Reported: 2012-03-07 10:21 UTC by Jakub Jelinek
Modified: 2012-03-13 02:27 UTC (History)
1 user (show)

See Also:
Target: i386-linux
Last reconfirmed:

ifunctest.tar.bz2 (1.48 KB, text/plain)
2012-03-07 10:24 UTC, Jakub Jelinek

Note You need to log in before you can comment on or make changes to this bug.
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]

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:


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 cvs-commit@gcc.gnu.org 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
	2012-03-09  H.J. Lu  <hongjiu.lu@intel.com>
	PR ld/13817
	* bfd/elf32-i386.c (elf_i386_relocate_section): Restore
	* * elf64-x86-64.c (elf_x86_64_relocate_section): Restore
	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.

Comment 6 H.J. Lu 2012-03-13 02:27:39 UTC