ELF Shared Library compilation troubles (badly aligned ptrs)

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
thepowersgang
Member
Member
Posts: 734
Joined: Tue Dec 25, 2007 6:03 am
Libera.chat IRC: thePowersGang
Location: Perth, Western Australia
Contact:

ELF Shared Library compilation troubles (badly aligned ptrs)

Post by thepowersgang »

When attempting to implement dynamic linking in my OS I started implementing my own version of libc to use in link testing.
After blaming my kernel, then the dynamic linker it seems that the problem is in the binary file itself.

The problem is that when the code tries to get the address of the GOT, the address is two bytes out.
objdump output:

Code: Select all

     627:	e8 00 05 00 00       	call   b2c <_sbrk+0xa5>
     62c:	81 c3 aa 1d 00 00    	add    $0x1daa,%ebx
     632:	c7 45 ec 00 00 00 00 	movl   $0x0,-0x14(%ebp)
     639:	c7 45 f0 00 00 00 00 	movl   $0x0,-0x10(%ebp)
     640:	8b 83 f8 ff ff ff    	mov    -0x8(%ebx),%eax
     646:	8b 00                	mov    (%eax),%eax
**SNIP**
     b2c:	8b 1c 24             	mov    (%esp),%ebx
     b2f:	c3                   	ret    
The address of the GOT obtained from the LD linking map is 0x23d8, but the value in EBX after the second instruction is 0x23d6.

I am using the standard linux toolchain (Ubuntu 9.04, gcc 4.3.3, binutils 2.19.1), compiling the library with

Code: Select all

$(CC) -Wall -fPIC -nostdinc -fno-builtin -I./include -fleading-underscore -DBUILD_SO -o $@ -c $<
and linking with

Code: Select all

$(LD) -x -shared -soname libc.so.1 $(OBJ_LIBC) -o $@ -Map map.txt -e _SoMain
Does anyone know what could be causing this error?
Kernel Development, It's the brain surgery of programming.
Acess2 OS (c) | Tifflin OS (rust) | mrustc - Rust compiler
Currently Working on: mrustc
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Re: ELF Shared Library compilation troubles (badly aligned ptrs)

Post by JamesM »

Hi,

I must say that I'm stumped. The code is functioning correctly - 0x62c+0x1daa is indeed 0x23d6. Does "readelf -d libc.so" agree with your linker map number of 0x23d8?

Cheers,

James
User avatar
thepowersgang
Member
Member
Posts: 734
Joined: Tue Dec 25, 2007 6:03 am
Libera.chat IRC: thePowersGang
Location: Perth, Western Australia
Contact:

Re: ELF Shared Library compilation troubles (badly aligned ptrs)

Post by thepowersgang »

JamesM: Yes it does (0x00000003 (PLTGOT) 0x23d8) and so does my dynamic linker.

I'm almost considering just binary editing the file to change the value used for the add, but I don't really like hacks like that.
Kernel Development, It's the brain surgery of programming.
Acess2 OS (c) | Tifflin OS (rust) | mrustc - Rust compiler
Currently Working on: mrustc
ru2aqare
Member
Member
Posts: 342
Joined: Fri Jul 11, 2008 5:15 am
Location: Hungary

Re: ELF Shared Library compilation troubles (badly aligned ptrs)

Post by ru2aqare »

Code: Select all

     62c:	81 c3 aa 1d 00 00    	add    $0x1daa,%ebx
If you look closer, there are two bytes (opcode + R/M) before the displacement in this particular instruction. Could it be that these need to be accounted for? If you add 0x1DAA to 0x62E you actually get the correct GOT address.

Then again, I have no experience whatsoever with the ELF format, so the reasoning could be wrong.
User avatar
thepowersgang
Member
Member
Posts: 734
Joined: Tue Dec 25, 2007 6:03 am
Libera.chat IRC: thePowersGang
Location: Perth, Western Australia
Contact:

Re: ELF Shared Library compilation troubles (badly aligned ptrs)

Post by thepowersgang »

I think that is why GCC/ld is getting it wrong.
The location of the displacement means nothing. The first line gets the address of the next instruction and puts it into ebx, this then has 0x1daa added to it.

Looking at the dump of the object file, it appears that the operand to add is relocated during linking as a R_386_GOTPC with an addend of 0, and hence uses the address of the operand instead of the current IP.
Kernel Development, It's the brain surgery of programming.
Acess2 OS (c) | Tifflin OS (rust) | mrustc - Rust compiler
Currently Working on: mrustc
User avatar
thepowersgang
Member
Member
Posts: 734
Joined: Tue Dec 25, 2007 6:03 am
Libera.chat IRC: thePowersGang
Location: Perth, Western Australia
Contact:

Solved: ELF Shared Library compilation troubles

Post by thepowersgang »

I found the bug. The toolchain I was using by default does not append leadning underscores but I was forcing it to, this meant that the GOT's symbol was different and hence was not treated properly.
I've disabled the "-fleading-underscore" flag in gcc and the problem was fixed.
Kernel Development, It's the brain surgery of programming.
Acess2 OS (c) | Tifflin OS (rust) | mrustc - Rust compiler
Currently Working on: mrustc
Post Reply