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

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
Ameise
Member
Member
Posts: 61
Joined: Fri Jul 16, 2010 7:46 am
Location: Chicago

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

Post 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?
User avatar
NickJohnson
Member
Member
Posts: 1249
Joined: Tue Mar 24, 2009 8:11 pm
Location: Sunnyvale, California

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

Post 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.
User avatar
Ameise
Member
Member
Posts: 61
Joined: Fri Jul 16, 2010 7:46 am
Location: Chicago

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

Post 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?
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:

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

Post 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.
"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
Ameise
Member
Member
Posts: 61
Joined: Fri Jul 16, 2010 7:46 am
Location: Chicago

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

Post by Ameise »

Ah, I never noticed the shell script - strange.
Post Reply