Page 1 of 2

Relocation truncated to fit error from ld

Posted: Wed Jul 01, 2020 6:34 am
by nexos
Hello,
I am switching my kernel from PE to ELF. When I did so, the 64 bit link failed. Here are the errors from ld

Code: Select all

../../Libs/Klib.lib(Cpu.o): in function `HalCpuInit':
/home/nexware/NexOS/NexKe/Hal/x64/Cpu.c:18:(.text+0x29): relocation truncated to fit: R_X86_64_32 against `.rodata.str1.1'
../../Libs/Klib.lib(Idt.o): in function `HalDefHandler':
/home/nexware/NexOS/NexKe/Hal/x64/Idt.c:19:(.text+0x1): relocation truncated to fit: R_X86_64_32 against `.rodata.str1.1'
../../Libs/Klib.lib(Idt.o): in function `HalIdtInit':
/home/nexware/NexOS/NexKe/Hal/x64/Idt.c:26:(.text+0x20): relocation truncated to fit: R_X86_64_32 against symbol `idt' defined in .bss section in ../../Libs/Klib.lib(Idt.o)
/home/nexware/NexOS/NexKe/Hal/x64/Idt.c:30:(.text+0x3f): relocation truncated to fit: R_X86_64_32 against symbol `HalDefHandler' defined in .text section in ../../Libs/Klib.lib(Idt.o)
../../Libs/Klib.lib(Isr.o): in function `HalIsrInstall':
/home/nexware/NexOS/NexKe/Hal/x64/Isr.c:49:(.text+0x11): relocation truncated to fit: R_X86_64_32 against symbol `isr0' defined in .text section in ../../Libs/Klib.lib(IsrStub.o)
/home/nexware/NexOS/NexKe/Hal/x64/Isr.c:50:(.text+0x2b): relocation truncated to fit: R_X86_64_32 against symbol `isr1' defined in .text section in ../../Libs/Klib.lib(IsrStub.o)
/home/nexware/NexOS/NexKe/Hal/x64/Isr.c:51:(.text+0x47): relocation truncated to fit: R_X86_64_32 against symbol `isr2' defined in .text section in ../../Libs/Klib.lib(IsrStub.o)
/home/nexware/NexOS/NexKe/Hal/x64/Isr.c:52:(.text+0x63): relocation truncated to fit: R_X86_64_32 against symbol `isr3' defined in .text section in ../../Libs/Klib.lib(IsrStub.o)
/home/nexware/NexOS/NexKe/Hal/x64/Isr.c:53:(.text+0x7f): relocation truncated to fit: R_X86_64_32 against symbol `isr4' defined in .text section in ../../Libs/Klib.lib(IsrStub.o)
/home/nexware/NexOS/NexKe/Hal/x64/Isr.c:54:(.text+0x9b): relocation truncated to fit: R_X86_64_32 against symbol `isr5' defined in .text section in ../../Libs/Klib.lib(IsrStub.o)
/home/nexware/NexOS/NexKe/Hal/x64/Isr.c:55:(.text+0xb7): additional relocation overflows omitted from the output
The linker command line looks like this:

Code: Select all

x86_64-elf-gcc -o NexKe.elf -z max-page-size=0x1000 -TArch/x64/link.ld -g -O2 -mno-red-zone -ffreestanding -fPIC Start/Entry.o Start/Init.o Start/Panic.o Memmgr/Placement.o    ../../Libs/Klib.lib -nostdlib -lgcc
And finally, the linker script looks like this

Code: Select all

ENTRY(KeEntry)

SECTIONS {
   . = 0xFFFFFFFF80000000;

   .text ALIGN(4096) : AT(ADDR(.text)) {
       *(.text)
       *(.rodata*)
   }

   .data ALIGN (4096) : AT(ADDR(.data)) {
       *(.data)
   }

   .bss ALIGN (4096) : AT(ADDR(.bss)) {
       _sbss = .;
       *(.bss)
       _ebss = .;
   }
	end = .; _end = .; __end = .;
}
Thanks for your help,
nexos

Re: Relocation truncated to fit error from ld

Posted: Wed Jul 01, 2020 7:00 am
by iansjack

Re: Relocation truncated to fit error from ld

Posted: Wed Jul 01, 2020 8:17 am
by nexos
Ok thanks for the resource!

Re: Relocation truncated to fit error from ld

Posted: Wed Jul 01, 2020 8:25 am
by nexos
Got it fixed. The problem was that I didn't pass -fPIC to GCC.

Re: Relocation truncated to fit error from ld

Posted: Wed Jul 01, 2020 11:48 am
by Octocontrabass
Wouldn't "-mcmodel=kernel" also work? You wouldn't need to use "-fPIC" in that case. (There's a bit of additional overhead when you use position-independent code.)

Re: Relocation truncated to fit error from ld

Posted: Wed Jul 01, 2020 11:58 am
by nexos
What is that overhead? -mcmodel=kernel didn't work for me

Re: Relocation truncated to fit error from ld

Posted: Wed Jul 01, 2020 12:40 pm
by Octocontrabass
The overhead is some extra instructions and memory accesses to read the global offset table at runtime for each of those relocations that are giving you errors.

Did you try passing -mcmodel=kernel to GCC when compiling, or just when linking? (You may also need to build libgcc with -mcmodel=kernel.)

Re: Relocation truncated to fit error from ld

Posted: Wed Jul 01, 2020 12:57 pm
by nexos
Would GRUB take care of that for me? I haven't had any problem so far.

Re: Relocation truncated to fit error from ld

Posted: Wed Jul 01, 2020 1:06 pm
by Octocontrabass
Would GRUB take care of what?

Re: Relocation truncated to fit error from ld

Posted: Wed Jul 01, 2020 1:16 pm
by nexos
Would GRUB take care of the GOT?

Re: Relocation truncated to fit error from ld

Posted: Wed Jul 01, 2020 1:25 pm
by Octocontrabass
GRUB doesn't need to take care of anything, the linker will fix up any relocations so that it can be loaded like normal.

GRUB can't remove the overhead from using the GOT.

Re: Relocation truncated to fit error from ld

Posted: Wed Jul 01, 2020 1:28 pm
by nexos
Ok I will keep trying to fix it. Thanks for your help!

Re: Relocation truncated to fit error from ld

Posted: Sat Sep 12, 2020 11:33 am
by sj95126
Sorry for bumping a slightly old thread, but my question is related to the topic.

Is there an equivalent for -mcmodel=large for GNU as? I'm getting 'relocation truncated' errors in some of my 64-bit assembly code. I've been able to work around some of it with 'movabs' but some other things are a bit clumsy.

For example:

sidt idt_data

has to be done as:

movabsq $idt_data, %rax
sidt (%rax)

There is a workaround for leaq using %rip-relative addressing, though you only get to use a 32-bit offset.

None of these changes are that big a deal but it seems like it'd be easier if gas had a large memory model option like gcc does.

Re: Relocation truncated to fit error from ld

Posted: Sat Sep 12, 2020 12:06 pm
by Octocontrabass
Most x64 instructions allow only signed 32-bit offsets in their effective addresses. The GCC option -mcmodel=large tells GCC to emit movabs instructions, just like you've been doing.

You'll have a much easier time if you stick to -mcmodel=kernel instead.

Re: Relocation truncated to fit error from ld

Posted: Sat Sep 12, 2020 12:34 pm
by sj95126
Um, ok, but I was asking about gas, not gcc. I know gcc has -mcmodel.

And yes, some 64-bit instructions can only take a 32-bit operand, but some, like lea, can take a 64-bit operand, yet gas is forcing this to be truncated to 32-bits. You can even see from the encoding:

Code: Select all

  21:   48 8d 04 25 00 00 00    lea    0x0,%rax
  28:   00
It's only left 4 bytes for the linker to fill in the address, even though when a) using REX.W (0x48) and b) NOT using the 0x67 override prefix, lea is supposed to accept a 64-bit address.

Is there really no way to overcome this and use the instructions the way they were designed?