Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

x86_64-unknown-none uses code-model kernel but statically linking code to high address results in "relocation R_X86_64_32 out of range" #101209

Closed
phip1611 opened this issue Aug 30, 2022 · 2 comments
Labels
C-bug Category: This is a bug.

Comments

@phip1611
Copy link

phip1611 commented Aug 30, 2022

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.

@phip1611 phip1611 added the C-bug Category: This is a bug. label Aug 30, 2022
@phip1611 phip1611 changed the title x86_64-unknown-none uses code-model kernel but statically linking it to high address results in "relocation R_X86_64_32 out of range" x86_64-unknown-none uses code-model kernel but statically linking it to high address results in "relocation R_X86_64_32 out of range" Aug 30, 2022
@phip1611 phip1611 changed the title x86_64-unknown-none uses code-model kernel but statically linking it to high address results in "relocation R_X86_64_32 out of range" x86_64-unknown-none uses code-model kernel but statically linking code to high address results in "relocation R_X86_64_32 out of range" Aug 30, 2022
@luqmana
Copy link
Member

luqmana commented Sep 6, 2022

Seems to work fine adding to .cargo/config.toml:

diff --git a/.cargo/config.toml b/.cargo/config.toml
index af119a9..0bd940a 100644
--- a/.cargo/config.toml
+++ b/.cargo/config.toml
@@ -4,4 +4,8 @@ target = "x86_64-unknown-none"
 
 # Unused as we have to provide them via an environmental variable. Build doesn't work if we
 # only specifcy them here.
-# rustflags = []
+rustflags = [
+    "-C", "code-model=kernel",
+    "-C", "link-arg=-Tlink.ld",
+    "-C", "relocation-model=static",
+]
$ cargo build
   Compiling bitflags v1.3.2
   Compiling x86 v0.51.0
   Compiling bit_field v0.10.1
   Compiling kernel v0.1.0 (/code/rust-kernel-x86_64-static-link-code-model-kernel)
   Compiling raw-cpuid v10.5.0
    Finished dev [optimized + debuginfo] target(s) in 2.04s

$ objdump -f target/x86_64-unknown-none/debug/kernel

target/x86_64-unknown-none/debug/kernel:	file format elf64-x86-64

architecture: x86_64
start address: 0xffffffff88000000

Though, you might want to move those rustflags to be target specific because the ones in [build] may apply to all rustc invocations (including any build.rs scripts, proc macros, etc). (See https://doc.rust-lang.org/cargo/reference/config.html#buildrustflags)

@phip1611
Copy link
Author

phip1611 commented Jun 28, 2023

Closing, as I can't reproduce it anymore. The comment of @luqmana is perfectly right.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: This is a bug.
Projects
None yet
Development

No branches or pull requests

2 participants