I'm writing firmware for bare-metal x86 (x86_64-unknown-none) and keep hitting relocation out of range errors that I haven't been able to solve by messing with the linker script, code generation options or linker options.
The specific error I'm seeing seems to be related to sections prefixed with .rodata..Lanon:
rust-lld: error: /home/finchie/Projects/Rust/linker_panic_codegen/target/x86_64-unknown-none/debug/build/linker_panic_codegen/597092d75453df74/out/linker_panic_codegen.a4oktnzon0hpo8l8o9gb7g9f2.0r37x4l.rcgu.o:(function reset: .text.reset+0x4): relocation R_X86_64_32S out of range: 2147483648 is not in [-2147483648, 2147483647]; references section '.rodata..Lanon.ab7aeef485f60b46b136ed38406e9087.0'
>>> referenced by main.rs:14 (src/main.rs:14)
rust-lld: error: /home/finchie/Projects/Rust/linker_panic_codegen/target/x86_64-unknown-none/debug/build/linker_panic_codegen/597092d75453df74/out/linker_panic_codegen.a4oktnzon0hpo8l8o9gb7g9f2.0r37x4l.rcgu.o:(function reset: .text.reset+0xb): relocation R_X86_64_32S out of range: 2147483704 is not in [-2147483648, 2147483647]; references section '.rodata..Lanon.ab7aeef485f60b46b136ed38406e9087.2'
>>> referenced by main.rs:14 (src/main.rs:14)
And viewing those sections with objdump they seem to be somewhat related to panic messages:
> rust-objdump --all-headers --full-contents target/x86_64-unknown-none/debug/build/linker_panic_codegen/597092d75453df74/out/linker_panic_codegen.a4oktnzon0hpo8l8o9gb7g9f2.0gdqlaw.rcgu.o
...
Contents of section .rodata..Lanon.ab7aeef485f60b46b136ed38406e9087.0:
0000 696e7465 726e616c 20657272 6f723a20 internal error:
0010 656e7465 72656420 756e7265 61636861 entered unreacha
0020 626c6520 636f6465 ble code
Contents of section .rodata.str1.1:
0000 7372632f 6d61696e 2e727300 src/main.rs.
Contents of section .rodata..Lanon.ab7aeef485f60b46b136ed38406e9087.2:
0000 00000000 00000000 0b000000 00000000 ................
0010 0e000000 05000000 ........
Contents of section .rela.rodata..Lanon.ab7aeef485f60b46b136ed38406e9087.2:
0000 00000000 00000000 01000000 05000000 ................
0010 00000000 00000000 ........
...
I've found a few different ways to fix the error, none of which work for my use case unfortunately:
- Commenting out the single
unreachable!()expression (I'd like to be able to panic!) - Changing the codegen backend to
cranelift, which seems to generate these sections under.rodatainstead of.rodata..Lanon(cranelift doesn't support thex86-interruptABI that I'm trying to use) - Changing the
ORIGINof the memory region in the linker script to below2048M(the code is loaded just under4096Maccording to the x86 spec)
I have the feeling it's an issue with my linker script, but running -Clink-arg=--print-map seems to show everything being within a range of a couple hundred bytes, so I'm not sure where the relocation error is coming from. If anyone knows what might be causing this, or anything else I could try, I would very much appreciate it ![]()
Source code
> cargo build --target x86_64-unknown-none -Zbuild-std=core
// src/main.rs
#![no_std]
#![no_main]
use core::panic::PanicInfo;
#[panic_handler]
fn panic(_panic_info: &PanicInfo) -> ! {
loop {}
}
#[unsafe(no_mangle)]
fn reset() -> ! {
// Changing this to `loop {}` fixes the error
unreachable!()
}
/* src/link.ld */
MEMORY {
/* Lowering the origin any further fixes the error (but the firmware needs to be loaded just under 4GiB in this case) */
ROM : ORIGIN = 2048M, LENGTH = 512K
}
ENTRY(reset);
SECTIONS {
.eh_frame : { *(.eh_frame); *(.eh_frame.*); } > ROM
.eh_frame_hdr : { *(.eh_frame_hdr); *(.eh_frame_hdr.*); } > ROM
.rodata : { *(.rodata); *(.rodata.*); } > ROM
.text : { *(.text); *(.text.*); } > ROM
.got : { *(.got); *(.got.*); } > ROM
.data.rel.ro : { *(.data.rel.ro); *(.data.rel.ro.*); } > ROM
.data : { *(.data); *(.data.*); } > ROM
.bss : { *(.bss); *(.bss.*); } > ROM
.reset : {
KEEP(*(.reset));
} > ROM
}
# .cargo/config.toml
[target.x86_64-unknown-none]
rustflags = [
"-Clink-arg=-Tsrc/link.ld",
"-Crelocation-model=static",
# Changing this to cranelift fixes the error
"-Zcodegen-backend=llvm",
]