Page 1 of 1
ELF GOT Relocations - Bad Values?
Posted: Fri Jan 30, 2009 2:17 am
by thepowersgang
I'm working on implementing ELF PIC support but I'm confused by some of the relocations used.
At the top of my libc's malloc function there is this code
Code: Select all
7c7: e8 00 05 00 00 call ccc <_sbrk+0xa5>
7cc: 81 c3 00 00 00 00 add $0x0,%ebx
7d2: c7 45 ec 00 00 00 00 movl $0x0,-0x14(%ebp) // <-- Inconsequential
7d9: c7 45 f0 00 00 00 00 movl $0x0,-0x10(%ebp) // <-- Inconsequential
7e0: 8b 83 f8 ff ff ff mov -0x8(%ebx),%eax
The address 0xccc has this:
Code: Select all
ccc: 8b 1c 24 mov (%esp),%ebx
ccf: c3 ret
My confusion comes in at the relocation entries applied to get the address of the GOT.
Code: Select all
DYNAMIC RELOCATION RECORDS
OFFSET TYPE VALUE
000007ce R_386_32 __GLOBAL_OFFSET_TABLE_
00000a02 R_386_32 __GLOBAL_OFFSET_TABLE_
00000adc R_386_32 __GLOBAL_OFFSET_TABLE_
00000b6b R_386_32 __GLOBAL_OFFSET_TABLE_
00000c35 R_386_32 __GLOBAL_OFFSET_TABLE_
...
The relocation R_386_32 is defined by the ELF spec to be A+S, meaning the value at the specified address plus the value of the specified symbol.
At each of these addresses the value is 0, so that would mean that the ebx value would be progressively incorrect as the call to 0xCCC gets further away from the image base.
Does anyone know why this is happening?, because to me this looks completely wrong, but I can't see where the error is.
Re: ELF GOT Relocations - Bad Values?
Posted: Fri Jan 30, 2009 8:17 am
by JamesM
Hi,
I'm confused as to why you are confused.
At each of these addresses the value is 0, so that would mean that the ebx value would be progressively incorrect as the call to 0xCCC gets further away from the image base.
Correct, the value is zero. So, when relocating, you encounter this relocation:
Code: Select all
000007ce R_386_32 __GLOBAL_OFFSET_TABLE_
The result of this relocation is, as you stated, A+S. A is the current value at the address given - 0. S is the absolute address of the symbol __GLOBAL_OFFSET_TABLE__. A+S is therefore equal to just the address of that symbol, so you look it up (symbol lookup) and paste the result of that symbol lookup in 0x7ce.
How exactly can this address change? Could you please explain your logic slightly more?
Cheers,
James
Re: ELF GOT Relocations - Bad Values?
Posted: Fri Jan 30, 2009 8:56 am
by Tomaka17
JamesM wrote:The result of this relocation is, as you stated, A+S. A is the current value at the address given - 0. S is the absolute address of the symbol __GLOBAL_OFFSET_TABLE__. A+S is therefore equal to just the address of that symbol, so you look it up (symbol lookup) and paste the result of that symbol lookup in 0x7ce.
I think the problem doesn't come from this
After relocation the given code becomes:
Code: Select all
mov %eip, %ebx // equivalent to: call ccc <_sbrk+0xa5>
add __GLOBAL_OFFSET_TABLE__, %ebx
movl $0x0,-0x14(%ebp) // <-- Inconsequential
movl $0x0,-0x10(%ebp) // <-- Inconsequential
mov -0x8(%ebx),%eax
After the second instruction, EBX points to address of GOT + 0x7cc which is weird
@thepowersgang:
Did you even try if it was working?
I had similar problems, not understanding how it could work. But it works!
Anyway as long as your relocation code is correct, you could only blame your compilator
Re: ELF GOT Relocations - Bad Values?
Posted: Fri Jan 30, 2009 9:34 am
by thepowersgang
I have tried it, that's how I discovered that it didn't work. When I run it I get a PF, and I'm pretty sure that my relocation code is right.
Re: ELF GOT Relocations - Bad Values?
Posted: Fri Jan 30, 2009 10:08 am
by JamesM
thepowersgang wrote:I have tried it, that's how I discovered that it didn't work. When I run it I get a PF, and I'm pretty sure that my relocation code is right.
It's obviously not, because it pagefaults.
I've explained how that relocation works, how it is processed. I need a little more to go on than "it didn't work" in order to help you fix it.
Cheers,
James
Re: ELF GOT Relocations - Bad Values?
Posted: Fri Jan 30, 2009 7:23 pm
by thepowersgang
I thought that there was something I missed in the original code. I suspect it might have something to do with either toolchain or the fact that I'm using "__GLOBAL_OFFSET_TABLE_" instead of "_GLOBAL_OFFSET_TABLE".
My linking command for my library:
Code: Select all
i686-pc-elf-ld.exe -x --oformat elf32-i386 --defsym __GLOBAL_OFFSET_TABLE_=_GLOBAL_OFFSET_TABLE_ -shared -soname libc.so.1 heap.o syscalls.ao stdlib.o -o ../libc.so.1 -Map map.txt
I've just checked a library compiled on Linux and there is no relocation references to _GLOBAL_OFFSET_TABLE_, only this:
Code: Select all
00002d7c R_386_RELATIVE *ABS*
00002de9 R_386_RELATIVE *ABS*
00002df3 R_386_RELATIVE *ABS*
00002e0d R_386_RELATIVE *ABS*
00002e4d R_386_RELATIVE *ABS*
Re: ELF GOT Relocations - Bad Values?
Posted: Sat Jan 31, 2009 6:11 am
by JamesM
thepowersgang wrote:I thought that there was something I missed in the original code. I suspect it might have something to do with either toolchain or the fact that I'm using "__GLOBAL_OFFSET_TABLE_" instead of "_GLOBAL_OFFSET_TABLE".
My linking command for my library:
Code: Select all
i686-pc-elf-ld.exe -x --oformat elf32-i386 --defsym __GLOBAL_OFFSET_TABLE_=_GLOBAL_OFFSET_TABLE_ -shared -soname libc.so.1 heap.o syscalls.ao stdlib.o -o ../libc.so.1 -Map map.txt
I've just checked a library compiled on Linux and there is no relocation references to _GLOBAL_OFFSET_TABLE_, only this:
Code: Select all
00002d7c R_386_RELATIVE *ABS*
00002de9 R_386_RELATIVE *ABS*
00002df3 R_386_RELATIVE *ABS*
00002e0d R_386_RELATIVE *ABS*
00002e4d R_386_RELATIVE *ABS*
... Because the GOT is used for accessing dynamically linked
variables. This isn't the main use case for shared libraries, most access dynamic
functions only (which uses the PLT).
Re: ELF GOT Relocations - Bad Values?
Posted: Sat Jan 31, 2009 7:29 am
by thepowersgang
I should have mentioned that those were in place of GOT relocation entries, the library I used I know DID have dynamic variables.
Does anyone know if there is a way of setting the -fleading-underscore flag without causing the GOT symbol to also get one? (I've currently hacked my as executable to work but it seems to work, with no references to the GOT emitted but appears be 2 bytes out of alignment)