Page 1 of 1

Compiler flags for 64-bit higher half kernel.

Posted: Mon Jul 04, 2011 8:52 pm
by torshie
Since addesses in 64-bit higher half kernel are 64-bit, we need special compiler flags to handle the "relocation truncated to fit: R_X86_64_32S against symbol xxx" problem. Currently I know two flags: one is "-mcmodel=large", the other one is "-fPIC".

When compiled with flag "-mcmodel=large", all function calls are translated to 2 instructions:

Code: Select all

ffffff8000200051:       48 b8 10 00 20 00 80    movabs $0xffffff8000200010,%rax
ffffff8000200058:       ff ff ff 
ffffff800020005b:       ff d0                   callq  *%rax
Because 64-bit CPU has IP-relative addessing support, when compiled with flag "-fPIC", all function calls are translated to 1 instruction:

Code: Select all

ffffff8000200071:       e8 d1 ff ff ff          callq  200047 <_start-0xffffff7fffffffb9>
My question is which flag will get better performance? Probably "-fPIC" beats "-mcmodel=large" in function calls. How about other situations, for example, memory copy, jump, etc. Anyone knows the flag used by linux/freebsd?

Thanks
torshie

Re: Compiler flags for 64-bit higher half kernel.

Posted: Mon Jul 04, 2011 9:09 pm
by gerryg400
Linux lives in the top 2GB of RAM and is compiled with the -mcmodel=kernel flag.

function calls look like

Code: Select all

ffffffff8000001f:   e8 28 20 00 00     callq ffffffff8000204c  <kinit>

Re: Compiler flags for 64-bit higher half kernel.

Posted: Mon Jul 04, 2011 9:25 pm
by torshie
Great, seems my kernel lives in the wrong place, lol :mrgreen:

Re: Compiler flags for 64-bit higher half kernel.

Posted: Mon Jul 04, 2011 9:34 pm
by gerryg400
The top 2 GB seems to work okay. You can still use 64bit pointers to access all of memory. I moved my kernel up there a little while ago.

The main issue I had was that I now need to build 2 copies of libc, one -mcmodel=kernel and one -mcmodel=small (I think).

Re: Compiler flags for 64-bit higher half kernel.

Posted: Mon Jul 04, 2011 9:51 pm
by torshie
I use cmake to build my kernel, so build an extra libc is very easy. In fact, I already have built two libc, one for the loader(32-bit), one for my kernel(64-bit).