Proposal for STT_GNU_IFUNC and R_*_IRELATIVE
H.J. Lu
hjl.tools@gmail.com
Wed May 27 19:40:00 GMT 2009
On Wed, May 27, 2009 at 10:54 AM, Ulrich Drepper <drepper@redhat.com> wrote:
>
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> H.J. Lu wrote:
>> How to do you handle R_*_PC32 relocation to a locally defined
>> STT_GNU_IFUNC symbol in dynamic and static executables?
>
> When I compile the test code you sent yesterday I see this in the
> executable:
>
> 000000000040050c <main>:
> 40050c: 55 push %rbp
> 40050d: 48 89 e5 mov %rsp,%rbp
> 400510: bf fd ff ff ff mov $0xfffffffd,%edi
> 400515: e8 00 00 00 00 callq 40051a <main+0xe>
> 40051a: b8 00 00 00 00 mov $0x0,%eax
> 40051f: c9 leaveq
> 400520: c3 retq
I got
00000000004005ac <main>:
4005ac: 55 push %rbp
4005ad: 48 89 e5 mov %rsp,%rbp
4005b0: bf fd ff ff ff mov $0xfffffffd,%edi
4005b5: e8 00 00 00 00 callq 4005ba <main+0xe>
4005ba: b8 00 00 00 00 mov $0x0,%eax
4005bf: c9 leaveq
Relocation section '.rela.ifunc.dyn' at offset 0x430 contains 1 entries:
Offset Info Type Sym. Value Sym. Name + Addend
0000004005b6 000400000002 R_X86_64_PC32 foo() foo - 4
Dynamic linker will lookup STT_GNU_IFUNC foo and resolve
R_X86_64_PC32. But dynamic linker will segfaut as soon as
it tries to run foo () since the text segment isn't executable
when it is changed to PROT_READ|PROT_WRITE before
updating the text segment.
>
> This is of course not going to work. The program doesn't even contain a
> R_*_IRELATIVE relocation.
>
> Every call to an IFUNC must be indirect somewhere. You cannot change
> the relative jmp into an indirect one (opcode is too long). Therefore,
> as I explained before, you allocate and jump to a PLT slot. The PLT
> slot as a GOT entry and that GOT entry in modified by the R_*_IRELATIVE
> relocation.
>
The current linker doesn't do that. I will investigate if it is easy to fix,
especially for static executables where executable has to manage
PLT and GOT itself. Certain static executables like kernel may
have
call STT_GNU_IFUNC foo
where the best foo will be selected at boot time for a given hardware.
PLT/GOT isn't needed here.
--
H.J.
More information about the Libc-alpha
mailing list