OSDev.org

The Place to Start for Operating System Developers
It is currently Thu Sep 19, 2019 12:23 am

All times are UTC - 6 hours




Post new topic Reply to topic  [ 4 posts ] 
Author Message
 Post subject: Do lazy PLT entries need a R_X86_64_RELATIVE?
PostPosted: Sat Dec 01, 2018 10:12 am 
Offline
Member
Member
User avatar

Joined: Sat Oct 16, 2010 3:38 pm
Posts: 636
Looking at the code I wrote some time ago for my OS, they don't (and my code works). But trying to confirm some stuff here.

I'm writing a linker for educational reasons, and I'm trying to make it support ELF64 shared libraries. I have some confusion about how the GOT/PLT relocation entries should be generated.

Judging by the code in my OS:
1. The PLTGOT has 3 special entries: PLTGOT[0] points to the DYNAMIC section, PLTGOT[1] is whatever the dynamic loader wants it to be, PLTGOT[2] is the dynamic loader "resolve" function
2. Every other entry in the PLTGOT (the number of these "other" entries == the number of PLTRELA relocation entries) contains the address of the corresponding PLT entry (before it is loaded by the dynamic linker)

For number (2), is the "standard" GOT relocation entry supposed to contain R_X86_64_RELATIVE entries to fix the address when the library is loaded at a specific base?

Looking at a random library through "readelf" seems to indicate that it is not needed, and in fact my OS simply adds the base address to all these entries, without looking at the relocation table. But I saw some code somewhere which claimed an undocumented case where "pre-linking" (not sure what is meant by it) is indicated by pre-setting PLTGOT[1] to a nonzero value.

So in summary, the question is:

1. What should the STATIC linker (ld) set the first three PLTGOT entries to?
2. Should the static linker emit R_X86_64_RELATIVE relocations to set PLTGOT[3..] to the correct values, or is the dynamic linker expected to iterate over them (by considering the number of PLTRELA entries) and update them automatically?
3. Does the PLTGOT and GOT have to be completly separate tables, or can the PLTGOT simply be a prefix of the GOT?

_________________
Glidix: An x86_64 POSIX-compliant operating system, aiming to be as optimized as possible, especially in graphics.
https://glidix.madd-games.org/


Top
 Profile  
 
 Post subject: Re: Do lazy PLT entries need a R_X86_64_RELATIVE?
PostPosted: Mon Dec 03, 2018 12:10 pm 
Offline
Member
Member

Joined: Wed Aug 30, 2017 8:24 am
Posts: 239
I suggest you read the System V ABI, AMD64 processor supplement, as it holds answers to some of your questions. But to be specific:

1. The first entry should be set to the address of the dynamic section, such as you know. For an executable, this will be the address in memory where it is loaded, and for a DSO this will be the offset from the start. The second and third entry should be empty (i.e. set to 0).

2. The relocation type for PLTGOT entries is R_X86_64_JUMP_SLOT. Here, it is helpful to read other implementations that already did this. dietlibc is the simplest libc I know that implements lazy binding, and it was a helpful read. So how this is supposed to work is like this: The dynamic section contains two relocation table definitions. The relocations defined with DT_REL, DT_RELENT, and DT_RELSZ are processed immediately, including symbol lookup, if needed. The other table, defined by DT_JMPREL, DT_PLTREL, and DT_PLTRELSZ is only rebased to the new membase, unless the LD_NOW flag is set, in which case each entry is immediately looked up.

3. Apparently yes, they are completely different tables.

Oh, and one more thing:
mariuszp wrote:
But I saw some code somewhere which claimed an undocumented case where "pre-linking" (not sure what is meant by it) is indicated by pre-setting PLTGOT[1] to a nonzero value.


I'd wager this is a by-now unsupported GNU extension. Windows has some support for this, and on i386 it might have made sense. "Pre-linking" refers to linking a library with a non-zero base address. The idea is to try to layout all the shared libs in the system such that no relocation is necessary because the space will always be unused at first. Of course this doesn't work in any non-trivial case (such as LD_PRELOAD), because ELF has no notion of "importing" a function from a library. ELF only has dependencies and symbols that on their face have nothing to do with each other (the "hello world" program only declares its need for "libc.so", and then, mirabile dictu, somehow there's a "printf" symbol in the linkage. But there is no way to say "import printf from libc.so"). So the entire thing becomes incredibly fragile, and you have to relocate your libraries anyway if anything happened at all. If any lib moved, they all have to be relocated. And again, LD_PRELOAD is a thing.

And another thing I had overlooked before:
mariuszp wrote:
2. Every other entry in the PLTGOT (the number of these "other" entries == the number of PLTRELA relocation entries) contains the address of the corresponding PLT entry (before it is loaded by the dynamic linker)


They should contain the offset to 6 bytes into their PLT offset. Otherwise you're currently building an infinite loop.


Top
 Profile  
 
 Post subject: Re: Do lazy PLT entries need a R_X86_64_RELATIVE?
PostPosted: Mon Dec 03, 2018 3:20 pm 
Offline
Member
Member
User avatar

Joined: Sat Oct 16, 2010 3:38 pm
Posts: 636
Thanks for the answer. I am aware that there are two tables: the "GOT relocation table" and the "PLT relocation table" (with the R_X86_64_JUMP_SLOT relocations). My question however is simply whether the PLTGOT table should simply be initialised with offsets from the base, like you mentioned, or should there ADDITIONALLY be R_X86_64_RELATIVE entries in the GOT relocation table to shift those to the correct position, or does the dynamic linker already know that the PLTGOT is an array where it must initially add the base to all entries.

By the looks of it, the answer is NO: I am NOT supposed to have R_X86_64_RELATIVE entries in the GOT reloc table for every corresponding JUMP_SLOT reloc entry. I just wanted to make sure.

_________________
Glidix: An x86_64 POSIX-compliant operating system, aiming to be as optimized as possible, especially in graphics.
https://glidix.madd-games.org/


Top
 Profile  
 
 Post subject: Re: Do lazy PLT entries need a R_X86_64_RELATIVE?
PostPosted: Mon Dec 03, 2018 9:35 pm 
Offline
Member
Member

Joined: Wed Aug 30, 2017 8:24 am
Posts: 239
Correct, the base address is added to the PLTGOT slots, but only because they are in DT_JMPREL, not because of a R_foo_RELATIVE relocation.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 4 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: No registered users and 5 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group