This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Proposal for STT_GNU_IFUNC and R_*_IRELATIVE


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.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]