Page 1 of 1
Relocation truncated to fit... even with mcmodel=large?
Posted: Sun Oct 23, 2011 11:55 pm
by TryHarder
Hey,
I'm trying to link my 64bit kernel. When the kernel laid at 0xF0100000 virtual address the relocation problem
solved with -mcmodel=large flag. But now I decided to change memory layout and place the kernel
at 0xFFFFFE0000000000 (~2TB). The relocation errors appeared again. Here's part of my linker script:
Code: Select all
OUTPUT_FORMAT("elf64-x86-64")
OUTPUT_ARCH("i386:x86-64")
ENTRY(_start)
KERN_BOOTSTRAP = 0xF0100000;
KERN_VA = 0xFFFFFF8000000000;
SECTIONS
{
. = KERN_BOOTSTRAP;
.bootentry : AT(0x100000) {
obj/kern/entry.o
}
. += KERN_VA;
.text : {
*(.text .stub .text.* .gnu.linkonce.t.*)
}
bootentry section(entry.o) contains code that setup long mode environment and jumps to kernel address.
What can cause the relocation troubles here?
Thanks!
Re: Relocation truncated to fit... even with mcmodel=large?
Posted: Mon Oct 24, 2011 12:13 am
by xenos
Could you provide the code in which the error is located? Are you possibly trying to jump from 32 bit code to some high 64 bit address?
Re: Relocation truncated to fit... even with mcmodel=large?
Posted: Mon Oct 24, 2011 12:21 am
by TryHarder
Thanks for fast respond. The error located in every obj file I'm trying to link.
Here's a small part of error log:
Code: Select all
ern/printf.c:25: relocation truncated to fit: R_X86_64_32 against `.text'
obj/kern/printf.o: In function `putch':
kern/printf.c:18: relocation truncated to fit: R_X86_64_32 against symbol `vcprintf' defined in .text section in obj/kern/printf.o
kern/printf.c:18: relocation truncated to fit: R_X86_64_32 against symbol `cprintf' defined in .text section in obj/kern/printf.o
kern/printf.c:18: relocation truncated to fit: R_X86_64_32 against `.text'
kern/printf.c:18: relocation truncated to fit: R_X86_64_32 against `.text'
obj/kern/picirq.o: In function `dummyfunc':
./inc/x86.h:99: relocation truncated to fit: R_X86_64_32 against `.text'
obj/kern/picirq.o: In function `pic_init':
kern/picirq.c:68: relocation truncated to fit: R_X86_64_32 against symbol `irq_eoi' defined in .text section in obj/kern/picirq.o
kern/picirq.c:68: relocation truncated to fit: R_X86_64_32 against `.text'
kern/picirq.c:68: relocation truncated to fit: R_X86_64_32 against `.text'
kern/picirq.c:68: relocation truncated to fit: R_X86_64_32 against symbol `dummyfunc' defined in .text section in obj/kern/picirq.o
kern/picirq.c:68: relocation truncated to fit: R_X86_64_32 against `.text'
kern/picirq.c:68: relocation truncated to fit: R_X86_64_32 against `.text'
kern/picirq.c:68: relocation truncated to fit: R_X86_64_32 against symbol `irq_setmask_8259A' defined in .text section in obj/kern/picirq.o
kern/picirq.c:68: relocation truncated to fit: R_X86_64_32 against `.text'
kern/picirq.c:68: relocation truncated to fit: R_X86_64_32 against `.text'
kern/picirq.c:68: relocation truncated to fit: R_X86_64_32 against symbol `pic_init' defined in .text section in obj/kern/picirq.o
kern/picirq.c:68: relocation truncated to fit: R_X86_64_32 against `.text'
kern/picirq.c:68: relocation truncated to fit: R_X86_64_32 against `.text'
kern/picirq.c:68: relocation truncated to fit: R_X86_64_32 against `.bss'
kern/picirq.c:68: relocation truncated to fit: R_X86_64_32 against `.text'
obj/kern/printfmt.o: In function `printnum':
lib/printfmt.c:51: relocation truncated to fit: R_X86_64_32 against `.text'
obj/kern/printfmt.o: In function `vprintfmt':
lib/printfmt.c:106: relocation truncated to fit: R_X86_64_32 against `.text'
lib/printfmt.c:195: relocation truncated to fit: R_X86_64_32 against `.text'
lib/printfmt.c:220: relocation truncated to fit: R_X86_64_32 against `.text'
lib/printfmt.c:224: relocation truncated to fit: R_X86_64_32 against symbol `vprintfmt' defined in .text section in obj/kern/printfmt.o
obj/kern/printfmt.o: In function `printfmt':
lib/printfmt.c:307: relocation truncated to fit: R_X86_64_32 against symbol `vsnprintf' defined in .text section in obj/kern/printfmt.o
XenOS wrote:Are you possibly trying to jump from 32 bit code to some high 64 bit address?
I have a small .code64 stub in my entry file, which does that:
Code: Select all
# Perform long jump to 64bit code.
ljmp $CODE_SEL, $bridge
.code64
bridge:
movabsq $i386_init, %rax
jmp *%rax
Btw, I'm not sure about the last jmp instruction to be fine, but since I can't link it, I can't debug...
Re: Relocation truncated to fit... even with mcmodel=large?
Posted: Mon Oct 24, 2011 1:02 am
by Combuster
Apparently it still consistently uses 32-bit addresses to something that requires them to be 64-bit
Older GCC manual wrote:-mcmodel=large
Generate code for the large model: This model makes no assumptions about addresses and sizes of sections. Currently GCC does not implement this model.
What's your GCC version? (and post the entire command line for compilation while you're at it)
Re: Relocation truncated to fit... even with mcmodel=large?
Posted: Mon Oct 24, 2011 1:39 am
by TryHarder
Combuster wrote:What's your GCC version? (and post the entire command line for compilation while you're at it)
GCC-4.4.3. Now I'm compiling 4.6.1. Typical compilation line is:
Code: Select all
'x86_64-elf-'gcc -pipe -nostdinc -O1 -fno-builtin -I. -MD -Wall -Wno-format -Wno-unused -Werror -gstabs -fno-stack-protector -m64 -mcmodel=large -mno-red-zone -mno-mmx -mno-sse -mno-sse2 -mno-sse3 -mno-3dnow -gstabs -c -o obj/kern/string.o lib/string.c
Re: Relocation truncated to fit... even with mcmodel=large?
Posted: Mon Oct 24, 2011 1:56 am
by TryHarder
mcmodel=large
Generate code for the large model: This model makes no assumptions about addresses and sizes of sections.
From:
http://gcc.gnu.org/onlinedocs/gcc/i386- ... tions.html
Where did you found that
Combuster wrote:Currently GCC does not implement this model.
?
EDIT: I've tried with latest binutils/gcc. Same result. I'd be thankful for some ideas or your working examples like
ld script, long mode switch code, gcc/ld flags.
Re: Relocation truncated to fit... even with mcmodel=large?
Posted: Mon Oct 24, 2011 8:30 am
by TryHarder
UPDATE: I think that this might be interesting:
Code: Select all
x86_64-elf-readelf --relocs obj/kern/init.o
Relocation section '.rela.text' at offset 0x1ed8 contains 10 entries:
Offset Info Type Sym. Value Sym. Name + Addend
000000000009 000c00000001 R_X86_64_64 0000000000000000 edata + 0
000000000013 000d00000001 R_X86_64_64 0000000000000000 end + 0
000000000025 000e00000001 R_X86_64_64 0000000000000000 memset + 0
000000000031 000f00000001 R_X86_64_64 0000000000000000 cons_init + 0
00000000003d 000500000001 R_X86_64_64 0000000000000000 .rodata + 0
00000000004c 001000000001 R_X86_64_64 0000000000000000 cprintf + 0
000000000058 000500000001 R_X86_64_64 0000000000000000 .rodata + 20
000000000069 000500000001 R_X86_64_64 0000000000000000 .rodata + 41
00000000007a 000500000001 R_X86_64_64 0000000000000000 .rodata + 5a
000000000091 000b00000001 R_X86_64_64 0000000000000006 main_bootstrap1 + 0
Relocation section '.rela.stab' at offset 0x1fc8 contains 5 entries:
Offset Info Type Sym. Value Sym. Name + Addend
000000000014 00020000000a R_X86_64_32 0000000000000000 .text + 0
0000000003ec 000a0000000a R_X86_64_32 0000000000000000 is_bootstrap + 0
000000000410 000b0000000a R_X86_64_32 0000000000000006 main_bootstrap1 + 0
000000000470 00110000000a R_X86_64_32 000000000000008b i386_init + 0
0000000004a0 00020000000a R_X86_64_32 0000000000000000 .text + 9b
Relocation section '.rela.eh_frame' at offset 0x2040 contains 3 entries:
Offset Info Type Sym. Value Sym. Name + Addend
000000000020 000200000001 R_X86_64_64 0000000000000000 .text + 0
000000000038 000200000001 R_X86_64_64 0000000000000000 .text + 6
000000000058 000200000001 R_X86_64_64 0000000000000000 .text + 8b
.rela.stab section relocation type seems to be 32bit. How can I force GCC to generate relocation type of R_X86_64_64?
Recall, -m64 -mcmode=large already there....
Re: Relocation truncated to fit... even with mcmodel=large?
Posted: Mon Oct 24, 2011 11:15 am
by kscguru
TryHarder wrote:UPDATE: I think that this might be interesting:
Code: Select all
Relocation section '.rela.stab' at offset 0x1fc8 contains 5 entries:
Offset Info Type Sym. Value Sym. Name + Addend
000000000014 00020000000a R_X86_64_32 0000000000000000 .text + 0
0000000003ec 000a0000000a R_X86_64_32 0000000000000000 is_bootstrap + 0
Very helpful update!
The stabs debug format (IIRC) only has 32 bits of relocation. For 64-bit code, you definitely want dwarf debug information. (And nowadays, I'd use dwarf for 32-bit code too, it's just that much richer.)
I think the option is -gdwarf2, but you should check the gcc docs. This should replace -gstabs on your compilation line.
Re: Relocation truncated to fit... even with mcmodel=large?
Posted: Mon Oct 24, 2011 11:31 am
by TryHarder
Thanks a lot for respond! How this will affect the output file format? It still will be "elf"ish with
only "dwarf"ish stab section? It's important, because I have my own bootloader.
Re: Relocation truncated to fit... even with mcmodel=large?
Posted: Mon Oct 24, 2011 11:52 am
by TryHarder
Now I feel a little silly about my previous question
. Worked like a charm! Now I can see properly linked kernel file.
Still need to figure out how to deal with new sections of dwarf (facing him first time), but It's a matter of time.