Dynamic linking, general query

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Dynamic linking, general query

Post by JamesM »

OK, so I've been implementing dynamic linking, and being quite successful at it as well (It works :P). I have a pretty simple query regarding a couple of tutorials/howto's I followed, about ELF headers.

I used this one on bonafide:
http://www.iecc.com/linker/linker10.html
and this HOWTO about parsing elf dynamic symbol tables
http://em386.blogspot.com/2006/10/resol ... mbols.html

In the second one, they are describing which section to look in, to find the Elf32_Rel entries...
$ readelf -S /bin/ls
There are 26 section headers, starting at offset 0x126d8:

Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
...
[ 4] .dynsym DYNSYM 080484a0 0004a0 0006b0 10 A 5 1 4
...
[ 8] .rel.dyn REL 08049170 001170 000028 08 A 4 0 4
[ 9] .rel.plt REL 08049198 001198 0002f0 08 A 4 11 4
They say that 'the section that has type SHT_REL is the one we're after', but two of those sections have type SHT_REL. .rel.plt is the one in my own test code which holds all the relavent relocation data, but what do I do if I get a situation as above, where there are multiple .rel sections? The only information my dynamic linker gets passed is an offset, and this can be applied to both .rel.dyn and .rel.plt. Do I just find the entry labeled '.rel.plt' and ignore all other sections with SHT_REL set?

Cheers for any help,

JamesM
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Post by Combuster »

Parse them all. Both may contain necessary relocations. It depends on the linker where what ends up.

If you look at

Code: Select all

[ 8] .rel.dyn REL 08049170 001170 000028 08 A 4 0 4
[ 9] .rel.plt REL 08049198 001198 0002f0 08 A 4 11 4 
you'll see that one is relatively long (0x2f0 bytes) while the other contains only a few entries (0x28). IIRC my elf files have a .rel section for each data section (.code, .data, ...)
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Post by JamesM »

combuster: Thanks for the reply.

The problem is, that when my dynamic linker is called, it recieves an offset into the relocation table. Nothing else.

Take, for example, the offset 0x08. That could be an entry in .rel.dyn, or .rel.plt... How am I supposed to know which one to use in which case?

Thanks,

JamesM
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Post by Combuster »

Its been a while when I last touched my application loader, you may find it useful for reference.

Before I continue with the details, you should know that an ELF application does not require patching when you load it to the addresses it expects.

What happens is that .rel sections are a list of triplets containing the location to patch (bytes 1-4), the symbol referred to and the type of relocation (bytes 5-8 ). You look up the symbol in the symbol table, and look up the details of the section where it is located. Then you compute the difference between the location where the target is loaded and where the target intended to be, and the difference between where the location to be patched is located and where it was intended to be. Next, depending on the type of relocation, you add or subtract either or both of these numbers to the location that needs patching to make it point to the correct address.

The header of the relocation section contains two fields that point to other tables:
sh_info points to the data section where relocations are to be applied
sh_link points to the symbol table to be used
The side effect is that you need separate relocation sections for each data section

As an example, for absolute relocations, you get the following sequence:
1: load the virtual address from the relocation table
2: use sh_info to get the base address of the section that needs to be altered
3: add the two to get the location that needs to be patched.
4: load the second dword from the relocation table
5: check the relocation type contained in the lower 8 bits. for absolute relocations its 1
6: load the remaining 24 bits to get the symbol index
7: locate the symbol that corresponds to this index
8: load the section of that symbol (each symbol is 16 bytes, the section is stored in the last two bytes of each entry)
9: look up the section's info and compute the difference between the current address and the original address
10: add the result to the location that needs to be patched
... and continue with the next relocation entry ...
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Post by JamesM »

Combuster:

Thanks! I'm just about to go to bed but I'll have a scanread of your application launcher before I do.

The relocations I'm trying to do are lazy - so not resolving every undefined symbol at application startup, but when they are required. ELF has a method to do this - it calls a user-defined function (you tell it this function my writing to the global offset table).

It gives that function a value of your choice (to identify the calling library/executable), and a symbol offset. This is an offset, in bytes, from the start of 'a' dynamic relocation section. The problem is, which one?, given only a symbol offset and a user-defined function?

I understand from your post that each segment (.text, data, bss etc) has it's own relocation segment. How do you find out which segment the call refers to?

Thanks for your helpful replies,

JamesM
Post Reply