Page 1 of 1
Linking a shared 64-bit kernel
Posted: Fri Jun 22, 2012 9:13 pm
by jbemmel
In the process of converting my 32-bit kernel to 64-bit, I encountered a small but annoying issue that I'd like to share with the group, hoping for tips & suggestions.
I compile my 32-bit kernel as a shared object and use the ELF linker features to export its symbols dynamically. This worked fine before, but when I try to do the same for 64-bit mode, the linker complains that it cannot make certain symbolic links when creating a shared object.
ld gives errors like "relocation R_X86_64_32S against `.data' can not be used when making a shared object; recompile with -fPIC"
I tried compiling with -fPIC as suggested, however this triggers all sorts of other errors. What's the best way to deal with this?
Re: Linking a shared 64-bit kernel
Posted: Fri Jun 22, 2012 11:50 pm
by bluemoon
I use this to compile my kernel, it is static linked ELF
Code: Select all
-ffreestanding -masm=intel -std=c99 -O2 -mcmodel=kernel -mno-red-zone -mno-mmx -mno-sse -mno-sse2 -mno-sse3 -mno-3dnow
And my ELF64 kernel modules:
Code: Select all
-ffreestanding -masm=intel -O2 -fPIC -mno-red-zone -mno-mmx -mno-sse -mno-sse2 -mno-sse3 -mno-3dnow
The problem with R_X86_64_32S is that certain instruction do not take 64-bit immediate, which cannot be linked with 64-bit objects(it simply can't fit with relocation).
with certain compiler flags the compiler may generate 64-bit MOV sequent for every access but it's considered a performance penalty.
Then it come to the -mcmodel-kernel trick to workaround, you may find more detail with the wiki/forum/google search.
Re: Linking a shared 64-bit kernel
Posted: Sat Jun 23, 2012 1:03 am
by xenos
If I remember correctly, the -mcmodel=kernel switch only works if your kernel resides in the top 2GB of the address space. Using -mcmodel=large should always work, but as bluemoon said, always generating 64 bit instructions is considered a performance penalty.
Re: Linking a shared 64-bit kernel
Posted: Sun Jun 24, 2012 4:41 pm
by jbemmel
OK, so how do you export symbols from the kernel then? I was using "-shared" to have ld build the export tables for me, but -shared implies relocatable code and that's not strictly needed.
Is there a way to have ld generate symbol tables without relocatable code?
I know Linux uses its own mechanism; see
http://lxr.free-electrons.com/source/in ... port.h#L63 and
http://lxr.free-electrons.com/source/sc ... genksyms.c
Re: Linking a shared 64-bit kernel
Posted: Mon Jun 25, 2012 12:06 am
by xenos
Using -shared does not require relocatable code. I use it for my kernel as well, without ever using -fPIC anywhere. Further, I have an ldscript that declares the symbols that should be exported:
http://xenos.svn.sourceforge.net/viewvc ... iew=markup
Re: Linking a shared 64-bit kernel
Posted: Mon Jun 25, 2012 11:46 am
by jbemmel
I downloaded XenOS and tried to configure (which fails, trying to use "-V" options with g++). From config.log I noticed that you are using -mcmodel=large. I am trying to use -mcmodel=kernel, which does not seem to work if you also want -shared
Perhaps using -mcmodel=large is the answer, or using a custom symbol exporting tool like Linux
Re: Linking a shared 64-bit kernel
Posted: Mon Jun 25, 2012 12:31 pm
by xenos
Even if it's a bit off-topic - could you post the full error you get when configuring XeNOS? I'm curious what exactly is going wrong there...
Yes, indeed, -mcmodel=kernel might be an issue with -shared...
Re: Linking a shared 64-bit kernel
Posted: Tue Jun 26, 2012 1:19 am
by jbemmel
Regarding XenOS: I got a bit further when I used "configure --host=x86" (to trigger a cross compile, even though the prefix was bogus). I also edited the script to remove -V from the list of options to try with the compiler, just in case
It compiled (for x86_64), but then linking failed, complaining there was not enough room for program headers (?) Suggestion to use "-N" did not seem to help
Re: Linking a shared 64-bit kernel
Posted: Tue Jun 26, 2012 7:29 am
by xenos
I have tested my code with cross compilers configured for i686-pc-elf and x86_64-pc-elf, so setting --host to one of these values should work (provided you have a cross compiler for that target - somethings similar like i585-elf or whatever should work as well). The linker error indeed sounds a bit strange to me...