Force rust compiler to use RIP relative addressing for global variables

Hello,

I am building a very simple kernel, and I am using globals here and there like so:

// some mod.rs

static FOO: () = ()

I am building my code using the following config.toml:

[build]
target = "x86_64-unknown-none"

[target.x86_64-unknown-none]
rustflags = [
    "-C", '''link-args=
 --image-base=0xffffffff80000000
 --no-nmagic
 --entry=_start
 -z separate-loadable-segments''',
    "-C", "relocation-model=static",
    "-C", "code-model=kernel"
]

[profile.dev]
panic = "abort"
debug = true

[profile.release]
panic = "abort"
opt-level = "z"
lto = "fat"
debug = true

This was working fine a couple of weeks ago, the compiler would produce some rip relative code and everything was good.
Now, however, the compiler is issuing gs relative code for some reason, f.e.:

<my_func_doing_smth>:
ffffffff800023c0:       48 83 ec 48             sub    $0x48,%rsp
ffffffff800023c4:       65 48 8b 04 25 00 00    mov    %gs:0x0,%rax
...

This obviously is pretty terrible because gs is used for my own structures.
Two questions:

  1. Why did this behavior change?
  2. Can I somehow get the compiler to do the right thing?

Compiler doesn't issue gs accesses “for some reason”, it uses it for TLS.

If your OS doesn't provide TLS then you need to find and remove code that uses it.

That is some reason. No reason to be antagonistic like that.

5 Likes

Are you showing the output from objdump applied to an object file? If you use objdump -Cdr on an object file it will show relocations in its disassembly (and demangle) which makes the output more readable. In this case would you have gotten a relocation for thread-local storage?

1 Like

If you want rip-relative addressing, don't use -Crelocation-model=static. That is for when the address of the executable is fixed at link time. The default -Crelocation-model=pie of the x86_64-unknown-none target should work for using rip-relative addressing.

x86_64 uses %fs for TLS, not %gs. Also unless you use the unstable #[thread_local], on no_std targets no TLS usage is possible at all.

5 Likes

Alright. Thanks everyone. I was indeed just being stupid and messed up %gs references which I miss-interpreted.

If you use objdump -Cdr on an object file it will show relocations in its disassembly

Thanks. That's a nice trick I did not know.

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.