Description
I'm developing a kernel with Rust and wanted to use the built-in x86_64-unknown-none
compiler target. This target uses the "kernel" code model of the System V ABI. However, when I link the code statically (-C relocation-model=static
) to 0xffffffff88000000
, i.e., in the range specified by the kernel code model in System V ABI, Rust says "relocation R_X86_64_32 out of range".
In #70992 I found that the problem perhaps is the way libcore was pre-compiled. Since Rust 1.62 x86_64-unknown-none
is a Tier 2 target which means that libcore is pre-compiled and delivered via Rustup. If I switch back from the built-in compiler target and compile libcore with the build-std
functionality of Cargo, it doesn't work either.
UPDATE When I use build-std
to cross-compile the libcore with RUSTFLAGS="-C code-model=kernel" cargo build
, it builds. But right know the object file contains no code. This could be another error on my side, however.
So I guess here is a bug. If the target is intended to be used with the kernel code-model, it should also be allowed to link to such an address.
UPDATE 2 When I use the built-in target x86_64-unknown-none
but invoke the build with RUSTFLAGS="-C code-model=kernel" cargo build
then it works too. However.. is this intended? Is it a bug?
I figured out that if I invoke Cargo with "RUSTFLAGS=-C code-model=kernel -C link-arg=-Tlink.ld -C relocation-model=static" cargo build
, the code is linked to the right position in the upper half of the address space. The build succeeeds. However, if I specify those options in .cargo/config.toml
, it doesn't work. Is this how it is supposed to work? Shouldn't it work out of the box?
I created a repository that shows a working example with the "workaround": https://github.com/phip1611/rust-kernel-x86_64-static-link-code-model-kernel
Meta
I'm using 1.65.0-nightly.