Infamous relocation problem amd64
-
- Posts: 9
- Joined: Fri Apr 11, 2008 12:36 am
Infamous relocation problem amd64
Hi,
I started to rewrite my OS in 64 bits, but I'm stuck with this ******* message "relocation truncated to fit: R_X86_64_32S against `.data'"
I suppose that this is due to the fact that the code generated has 32 bits pointers or similar even if I use elf64-x86-64 as output format.
I tried with GCC options -mcmodel=medium/kernel -fpic/PIC but none worked for me.
My standard compilation flags are CFLAGS=-O2 -fomit-frame-pointer -nostdinc -I $(INCLUDE_PATH) -Wall
Am I missing something?
To retain compatibility with my old loader I've linked my kernel to run at 0x0c0010000 (real addr 0x10000) and everything compiles until the .code64 tag in assembly file is reached.
Such instructions :
leaq boot_isr_msg,%rax
are truncated to fit a 32 bit pointer and prevents the generation of the image file.
Can anybody help me? How am I supposed to produce 64(52) bits addressing in my kernel?
I've studied manuals and searched for days but with no fortune!
Thanks in advance!
I started to rewrite my OS in 64 bits, but I'm stuck with this ******* message "relocation truncated to fit: R_X86_64_32S against `.data'"
I suppose that this is due to the fact that the code generated has 32 bits pointers or similar even if I use elf64-x86-64 as output format.
I tried with GCC options -mcmodel=medium/kernel -fpic/PIC but none worked for me.
My standard compilation flags are CFLAGS=-O2 -fomit-frame-pointer -nostdinc -I $(INCLUDE_PATH) -Wall
Am I missing something?
To retain compatibility with my old loader I've linked my kernel to run at 0x0c0010000 (real addr 0x10000) and everything compiles until the .code64 tag in assembly file is reached.
Such instructions :
leaq boot_isr_msg,%rax
are truncated to fit a 32 bit pointer and prevents the generation of the image file.
Can anybody help me? How am I supposed to produce 64(52) bits addressing in my kernel?
I've studied manuals and searched for days but with no fortune!
Thanks in advance!
- Attachments
-
- link.rules.64.txt
- This is my linker script added for clarity
- (649 Bytes) Downloaded 85 times
Hi,
A google found this page, in which a gcc board member suggests using the flag -mcmodel=medium.
Try that and see if it works.
Cheers,
James
EDIT: our project's cxxflags also include "-mcmodel=kernel". Try that as well.
A google found this page, in which a gcc board member suggests using the flag -mcmodel=medium.
Try that and see if it works.
Cheers,
James
EDIT: our project's cxxflags also include "-mcmodel=kernel". Try that as well.
-
- Posts: 9
- Joined: Fri Apr 11, 2008 12:36 am
I've tried everything before posting, with no results You guys are my last hope , at least until the -mcmodel=large will be supportedJamesM wrote:Hi,
A google found this page, in which a gcc board member suggests using the flag -mcmodel=medium.
Try that and see if it works.
Cheers,
James
EDIT: our project's cxxflags also include "-mcmodel=kernel". Try that as well.
A few things:
- Are you using a seperate elf32 loader for your file, GRUB (no elf64 support), GRUB2, or is the 32-bit bootstrap code compiled into the executable as well?
- Make sure you're using a 64-bit (x86_64-pc-elf-gcc) cross-compiler!
- Also, make sure to add .code32 at the top of any 32-bit assembly files
- AFAIK, GCC 4.3 supports -mcmodel=large (I'm using it right now)
There should be a wiki tutorial on how to compile and load a 64-bit kernel... I'll get on it.
- Are you using a seperate elf32 loader for your file, GRUB (no elf64 support), GRUB2, or is the 32-bit bootstrap code compiled into the executable as well?
- Make sure you're using a 64-bit (x86_64-pc-elf-gcc) cross-compiler!
- Also, make sure to add .code32 at the top of any 32-bit assembly files
- AFAIK, GCC 4.3 supports -mcmodel=large (I'm using it right now)
There should be a wiki tutorial on how to compile and load a 64-bit kernel... I'll get on it.
"Sufficiently advanced stupidity is indistinguishable from malice."
-
- Posts: 9
- Joined: Fri Apr 11, 2008 12:36 am
No, I use a self developed OS loader, which works well - I have only this compile problemkarekare0 wrote:A few things:
- Are you using a seperate elf32 loader for your file, GRUB (no elf64 support), GRUB2, or is the 32-bit bootstrap code compiled into the executable as well?
I'm pretty sure the result is an elf x86_64...karekare0 wrote: - Make sure you're using a 64-bit (x86_64-pc-elf-gcc) cross-compiler!
I use the .code32 to initialize long mode, then I switch to .code64 just before reloading CS.karekare0 wrote: - Also, make sure to add .code32 at the top of any 32-bit assembly files
I'm compiling it just now!karekare0 wrote: - AFAIK, GCC 4.3 supports -mcmodel=large (I'm using it right now)
This is a very precious information, I'll have a look on it. But I'm confident that the -mcmodel=large will solve the problem,,,karekare0 wrote: There should be a wiki tutorial on how to compile and load a 64-bit kernel... I'll get on it.
Thanks!
-
- Posts: 9
- Joined: Fri Apr 11, 2008 12:36 am
LD still does not link....
I've recompiled gcc 4.3.0 (nearly 4 hours on my poor notebook!) so I'm able to compile my sources using the -mcmodel=large. But GNU LD does not link so I don't know what else to do . Am I missing some linker option? Have I to compile binutils?
May be I'm wrong on the logic - the kernel is linked to be at 0x0c0010000 when it really is at 0x10000.
Thanks!
May be I'm wrong on the logic - the kernel is linked to be at 0x0c0010000 when it really is at 0x10000.
Thanks!
Note that it should by 0x100000, not 0x10000. You're forgetting one zero.
If you're linking your kernel to 0xc0100000, make sure your code enters virtual memory too.
Also, what error does GNU LD give? I'm assuming you're using a cross-compiled LD, right?
If you're linking your kernel to 0xc0100000, make sure your code enters virtual memory too.
Also, what error does GNU LD give? I'm assuming you're using a cross-compiled LD, right?
"Sufficiently advanced stupidity is indistinguishable from malice."
-
- Posts: 9
- Joined: Fri Apr 11, 2008 12:36 am
karekare0 wrote:Note that it should by 0x100000, not 0x10000. You're forgetting one zero.
If you're linking your kernel to 0xc0100000, make sure your code enters virtual memory too.
Yes, I'm running my small kernel at 0x10000 in low memory by design, but I've compiled it as if it is 3 Gb above. I put the paging tables at 0x100000 (absolute address) so I have to patch every address (eg gdt-0x0c0000000) until I reload segments in long mode, when pages from 0x0c0000000 to 0x0c0200000 are mapped to point the first two megs of ram.
No I'm not using a cross compiler at this stage; Note that I'm not having execution issues (my setup code works), the problem is that istructions like the following:karekare0 wrote:Also, what error does GNU LD give? I'm assuming you're using a cross-compiled LD, right?
leaq isr_msg,%rax #-> causes the relocation problem
leaq isr_msg-0x0c0000000,%rax #-> assembles well
Since the virtual memory is enabled they are both equivalent.
My linker invocation is
ld -M --cref -o kernel.img -T link.rules.64 -nodefaultlibs -nostdlib -Map kernel.map *.o
where link.rules.64 is the linker script posted in my first post.
-
- Posts: 9
- Joined: Fri Apr 11, 2008 12:36 am
Force gcc to generate large memory model on asm sources
My problem is that the GCC insists to generate 32 bits addressing on .text coming from asm files; code from C files is true 64 bit in both code and pointers.
So the question is obvious: how can I force the generation of 64 bits addressing in assembly files? Is there something which overrides the .code64 statement?
My relevant CFLAGS are:
-c -O2 -mcmodel=large -m64 -fomit-frame-pointer -nostdinc -nostdlib -ffreestanding -Wall
I use GCC 4.3.0 and recompiled binutils
Any help? Thanks!
So the question is obvious: how can I force the generation of 64 bits addressing in assembly files? Is there something which overrides the .code64 statement?
My relevant CFLAGS are:
-c -O2 -mcmodel=large -m64 -fomit-frame-pointer -nostdinc -nostdlib -ffreestanding -Wall
I use GCC 4.3.0 and recompiled binutils
Any help? Thanks!
-
- Posts: 9
- Joined: Fri Apr 11, 2008 12:36 am
SOLVED!!!!
The solution is to change the asm from:
lealq my_C_func,%rax / movq $my_C_func,%rax
(which generates the truncation error)
to:
movabsq $my_C_func,%rax
which forces GCC to generate the absolute address.
This may be obvious for the most of you, but I report this because this stupid thing was like a thorn twisted in my side....
Matteo
lealq my_C_func,%rax / movq $my_C_func,%rax
(which generates the truncation error)
to:
movabsq $my_C_func,%rax
which forces GCC to generate the absolute address.
This may be obvious for the most of you, but I report this because this stupid thing was like a thorn twisted in my side....
Matteo