Linking a shared 64-bit kernel

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
jbemmel
Member
Member
Posts: 53
Joined: Fri May 11, 2012 11:54 am

Linking a shared 64-bit kernel

Post 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?
User avatar
bluemoon
Member
Member
Posts: 1761
Joined: Wed Dec 01, 2010 3:41 am
Location: Hong Kong

Re: Linking a shared 64-bit kernel

Post 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.
User avatar
xenos
Member
Member
Posts: 1121
Joined: Thu Aug 11, 2005 11:00 pm
Libera.chat IRC: xenos1984
Location: Tartu, Estonia
Contact:

Re: Linking a shared 64-bit kernel

Post 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.
Programmers' Hardware Database // GitHub user: xenos1984; OS project: NOS
jbemmel
Member
Member
Posts: 53
Joined: Fri May 11, 2012 11:54 am

Re: Linking a shared 64-bit kernel

Post 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
User avatar
xenos
Member
Member
Posts: 1121
Joined: Thu Aug 11, 2005 11:00 pm
Libera.chat IRC: xenos1984
Location: Tartu, Estonia
Contact:

Re: Linking a shared 64-bit kernel

Post 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
Programmers' Hardware Database // GitHub user: xenos1984; OS project: NOS
jbemmel
Member
Member
Posts: 53
Joined: Fri May 11, 2012 11:54 am

Re: Linking a shared 64-bit kernel

Post 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
User avatar
xenos
Member
Member
Posts: 1121
Joined: Thu Aug 11, 2005 11:00 pm
Libera.chat IRC: xenos1984
Location: Tartu, Estonia
Contact:

Re: Linking a shared 64-bit kernel

Post 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...
Programmers' Hardware Database // GitHub user: xenos1984; OS project: NOS
jbemmel
Member
Member
Posts: 53
Joined: Fri May 11, 2012 11:54 am

Re: Linking a shared 64-bit kernel

Post 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
User avatar
xenos
Member
Member
Posts: 1121
Joined: Thu Aug 11, 2005 11:00 pm
Libera.chat IRC: xenos1984
Location: Tartu, Estonia
Contact:

Re: Linking a shared 64-bit kernel

Post 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...
Programmers' Hardware Database // GitHub user: xenos1984; OS project: NOS
Post Reply