Page 1 of 1

Linking 32-bit object file and 64-bit object file

Posted: Wed Feb 16, 2011 11:42 am
by Ameise
I am not currently at home so I cannot test this in regards to kernel development, but I was experimenting with linking a 32-bit object file (such as a boot loader) with a 64-bit object file (64-bit entry/kernel).

I came up with a solution that was workable in a test:

linker.ld:
OUTPUT_FORMAT(elf64-x86-64)
OUTPUT_ARCH(i386)

32.cpp:
int f32 ()
{
return sizeof(void *);
}

64.cpp
#include <stdio>
extern int f32 ();
int main ()
{
printf("64: %i\n", (int)sizeof(void *));
printf("32, %i\n", f32());
}
To build:
g++ -m32 32.cpp -c -nostdlib -fno-exceptions -fno-rtti
g++ -m64 64.cpp -c -fno-exceptions -fno-rtti
ld -T linker.ld 32.o -o 32a.o
g++ -o out 32a.o 64.o

running it results in:
./out:
64: 8
32: 4

If you alter 32.cpp to include actual operations, such as:
32.cpp:
int f32 ()
{
int a = sizeof(void *);
a *= 2;
a /= 2;
return a;
}

it then segfaults.

Haven't disassembled anything yet, but I'm guessing a simple function that just returns is the same in 32 and 64-bit. Since I am not at home and unable to fully test this, could anyone confirm for me that this works?

Re: Linking 32-bit object file and 64-bit object file

Posted: Wed Feb 16, 2011 11:53 am
by NickJohnson
Your issue stems from the fact that 32 bit code and 64 bit code not only operate on different sized integers but are also differently encoded. The opcodes (especially with immediate operands) are slightly different between x86 and x86_64, which is why doing arithmetic with 32 bit code in a 64 bit environment breaks. That simple function is simply simple enough that all of the 32 bit opcodes it uses match the 64 bit opcodes. You won't have these problems in your kernel/bootloader if you switch to long mode before calling the 64 bit code, however.

Re: Linking 32-bit object file and 64-bit object file

Posted: Wed Feb 16, 2011 1:50 pm
by Ameise
Yeah, that wasn't my concern. I was just verifying it was working as expected (just linking a 32-bit object file to a 64-bit binary). The fact that I was receiving a segfault was proof to me that it was indeed 32-bit code.

Why isn't this method discussed on the wiki?

Re: Linking 32-bit object file and 64-bit object file

Posted: Wed Feb 16, 2011 4:29 pm
by Combuster
It is, but not explicitly. Basic knowledge of processor modes dictates that you can't mix code for two different modes together as each in [real mode, 16-bit protected mode, 32-bit mode, 64-bit mode] is decoded and interpreted differently. I suggest you find the page on long mode, and especially the part on entering long mode, and you should be able to spot the hint.

Re: Linking 32-bit object file and 64-bit object file

Posted: Wed Feb 16, 2011 5:39 pm
by Ameise
Ah, I never noticed the shell script - strange.