diff --git a/Makefile b/Makefile index 997996f765f922..8307664d39015b 100644 --- a/Makefile +++ b/Makefile @@ -521,7 +521,7 @@ KBUILD_RUSTCFLAGS_KERNEL := KBUILD_CARGOFLAGS_KERNEL := KBUILD_AFLAGS_MODULE := -DMODULE KBUILD_CFLAGS_MODULE := -DMODULE -KBUILD_RUSTCFLAGS_MODULE := --cfg module +KBUILD_RUSTCFLAGS_MODULE := --cfg MODULE KBUILD_CARGOFLAGS_MODULE := KBUILD_LDFLAGS_MODULE := export KBUILD_LDS_MODULE := $(srctree)/scripts/module-common.lds diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 7b7d07d1eade45..7101ac64bb209d 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -148,7 +148,7 @@ config X86 select HAVE_ARCH_MMAP_RND_BITS if MMU select HAVE_ARCH_MMAP_RND_COMPAT_BITS if MMU && COMPAT select HAVE_ARCH_COMPAT_MMAP_BASES if MMU && COMPAT - #select HAVE_ARCH_PREL32_RELOCATIONS TODO: see the `kernel_module` macro + select HAVE_ARCH_PREL32_RELOCATIONS select HAVE_ARCH_SECCOMP_FILTER select HAVE_ARCH_THREAD_STRUCT_WHITELIST select HAVE_ARCH_STACKLEAK diff --git a/drivers/char/rust_example/src/lib.rs b/drivers/char/rust_example/src/lib.rs index 9f542d6929dba2..56562b840d9c77 100644 --- a/drivers/char/rust_example/src/lib.rs +++ b/drivers/char/rust_example/src/lib.rs @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 #![no_std] +#![feature(global_asm)] use kernel::prelude::*; @@ -11,7 +12,7 @@ struct RustExample { impl KernelModule for RustExample { fn init() -> KernelResult { println!("Rust Example (init)"); - println!("Am I built-in? {}", !cfg!(module)); + println!("Am I built-in? {}", !cfg!(MODULE)); Ok(RustExample { message: "on the heap!".to_owned(), }) diff --git a/rust/kernel/src/lib.rs b/rust/kernel/src/lib.rs index 1022e8b00d25d1..18d553c094ffaf 100644 --- a/rust/kernel/src/lib.rs +++ b/rust/kernel/src/lib.rs @@ -53,13 +53,23 @@ macro_rules! kernel_module { // Built-in modules are initialized through an initcall pointer // - // TODO: find a proper way to emulate the C macro (`module_init`), - // including dealing with `HAVE_ARCH_PREL32_RELOCATIONS` - #[cfg(not(module))] + // TODO: should we compile a C file on the fly to avoid duplication? + #[cfg(not(MODULE))] + #[cfg(not(CONFIG_HAVE_ARCH_PREL32_RELOCATIONS))] #[link_section = ".initcall6.init"] #[used] pub static __initcall: extern "C" fn() -> $crate::c_types::c_int = init_module; + #[cfg(not(MODULE))] + #[cfg(CONFIG_HAVE_ARCH_PREL32_RELOCATIONS)] + global_asm!( + r#".section ".initcall6.init", "a" + __initcall: + .long init_module - . + .previous + "# + ); + // TODO: pass the kernel module name here to generate a unique, // helpful symbol name (the name would also useful for the `modinfo` // issue below). diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 939062f389d330..a74898ff131aee 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -229,7 +229,9 @@ c_flags = -Wp,-MMD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \ RUST_BINDGEN_CFLAGS = $(c_flags) $(KBUILD_CFLAGS_MODULE) export RUST_BINDGEN_CFLAGS -rustc_flags = $(_rustc_flags) $(modkern_rustcflags) +rustc_cfg_flags = $(shell sed -nE 's/^(CONFIG_[^=]+)=(y|m)$$/--cfg \1/p' $(srctree)/include/config/auto.conf | xargs) + +rustc_flags = $(_rustc_flags) $(modkern_rustcflags) $(rustc_cfg_flags) # Passed by cargo RUSTFLAGS = $(rustc_flags)