Skip to content

Commit

Permalink
Forbid rustc from using -f{function,data}-sections (fixes thesofproje…
Browse files Browse the repository at this point in the history
…ct#20 panic)

Some kernel configs were panicking at the Rust example driver
initialization. The `__MOD` static value had a bogus value,
which meant that trying to initialize it was dropping the object
that was, supposedly, there.

The memory corruption happened during rootfs unpacking,
which explains why it only happened in some configs (like in CI)
and why it also didn't happen if there was an early error
during unpacking.

That memory corruption, in turn, was caused because the
`__MOD` symbol was being placed after the end of the
kernel reserve. That happened due to the kernel's linker
script not supporting unique sections per symbol for dead
code data elimination -- yet. Some arches do, but until
we can rely on that, we need to disable their generation
in rustc's side for the moment.

Since we discussed to have the target spec on our side,
and since `-Z function-sections=false` was added just
a month ago, I went with the spec route.

Other symbols were being placed in unexpected places,
which should be fixed now too.

Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
  • Loading branch information
ojeda committed Nov 26, 2020
1 parent fe8d5f6 commit 096dd7c
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 4 deletions.
4 changes: 1 addition & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -510,11 +510,9 @@ KBUILD_CFLAGS := -Wall -Wundef -Werror=strict-prototypes -Wno-trigraphs \
KBUILD_CPPFLAGS := -D__KERNEL__
KBUILD_RUSTCFLAGS :=
# TODO: a simple way to update `Cargo.lock` when we add a new driver
# TODO: another option is using explicit target specs, e.g.
# `--target=$(srctree)/arch/$(SRCARCH)/rust-target-spec.json`
KBUILD_CARGOFLAGS := $(CARGO_VERBOSE) --locked \
-Z build-std=core,alloc -Z unstable-options \
--out-dir=out --target=x86_64-linux-kernel
--out-dir=out --target=$(PWD)/$(srctree)/arch/$(SRCARCH)/rust/target.json
KBUILD_AFLAGS_KERNEL :=
KBUILD_CFLAGS_KERNEL :=
KBUILD_RUSTCFLAGS_KERNEL :=
Expand Down
34 changes: 34 additions & 0 deletions arch/x86/rust/target.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"arch": "x86_64",
"code-model": "kernel",
"cpu": "x86-64",
"data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128",
"disable-redzone": true,
"eliminate-frame-pointer": false,
"env": "gnu",
"features": "-mmx,-sse,-sse2,-sse3,-ssse3,-sse4.1,-sse4.2,-3dnow,-3dnowa,-avx,-avx2,+soft-float",
"function-sections": false,
"is-builtin": true,
"linker-flavor": "gcc",
"linker-is-gnu": true,
"llvm-target": "x86_64-elf",
"max-atomic-width": 64,
"needs-plt": true,
"os": "none",
"panic-strategy": "abort",
"position-independent-executables": true,
"pre-link-args": {
"gcc": [
"-Wl,--as-needed",
"-Wl,-z,noexecstack",
"-m64"
]
},
"relocation-model": "static",
"relro-level": "full",
"stack-probes": true,
"target-c-int-width": "32",
"target-endian": "little",
"target-pointer-width": "64",
"vendor": "unknown"
}
3 changes: 2 additions & 1 deletion rust/kernel/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,8 @@ fn main() {

let kernel_args = prepare_cflags(&cflags, &kernel_dir);

let target = env::var("TARGET").unwrap();
// TODO: pass the proper triple to bindgen
let target = "x86_64-linux-kernel";

let mut builder = bindgen::Builder::default()
.use_core()
Expand Down

0 comments on commit 096dd7c

Please sign in to comment.