From 2d98d378bb716edd93c0c2d652c5d8a83fe40f01 Mon Sep 17 00:00:00 2001 From: Gary Guo Date: Thu, 26 May 2022 16:04:12 +0100 Subject: [PATCH 1/2] rust: make compiler-builtin stubs non-global Currently we define a number of stubs for compiler-builtin intrinsics that compiled libcore generates. The defined stubs are weak so they will not conflict with genuine implementation of these intrinsics, but their effect is global and will cause non-libcore code that accidently generate these intrinsics calls compile and bug on runtime. Instead of defining a stub that can affect all code, this patch uses objcopy's `--redefine-sym` flag to redirect these calls (from libcore only) to a prefixed version (e.g. redirect `__multi3` to `__rust_multi3`), so we can define panciking stubs that are only visible to libcore. Signed-off-by: Gary Guo --- rust/Makefile | 21 +++++++++++++++++++++ rust/compiler_builtins.rs | 2 +- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/rust/Makefile b/rust/Makefile index bfe16bcd9bf98f..a58c0b0ade176c 100644 --- a/rust/Makefile +++ b/rust/Makefile @@ -392,8 +392,29 @@ rust-analyzer: $(Q)$(srctree)/scripts/generate_rust_analyzer.py $(srctree) $(objtree) \ $(RUST_LIB_SRC) > $(objtree)/rust-project.json +redirect-intrinsics = \ + __eqsf2 __gesf2 __lesf2 __nesf2 __unordsf2 \ + __unorddf2 \ + __muloti4 __multi3 \ + __udivmodti4 __udivti3 __umodti3 + +ifneq ($(or $(CONFIG_ARM64),$(and $(CONFIG_RISCV),$(CONFIG_64BIT))),) + # These intrinsics are defined for ARM64 and RISCV64 + redirect-intrinsics += \ + __ashrti3 \ + __ashlti3 __lshrti3 +endif + +ifdef CONFIG_ARM + redirect-intrinsics += \ + __aeabi_fcmpeq __aeabi_fcmpun \ + __aeabi_dcmpun \ + __aeabi_uldivmod +endif + $(obj)/core.o: private skip_clippy = 1 $(obj)/core.o: private skip_flags = -Dunreachable_pub +$(obj)/core.o: private rustc_objcopy = $(foreach sym,$(redirect-intrinsics),--redefine-sym $(sym)=__rust$(sym)) $(obj)/core.o: private rustc_target_flags = $(core-cfgs) $(obj)/core.o: $(RUST_LIB_SRC)/core/src/lib.rs $(obj)/target.json FORCE $(call if_changed_dep,rustc_library) diff --git a/rust/compiler_builtins.rs b/rust/compiler_builtins.rs index e57011b7c3daf2..59e70aea99cdd9 100644 --- a/rust/compiler_builtins.rs +++ b/rust/compiler_builtins.rs @@ -28,7 +28,7 @@ macro_rules! define_panicking_intrinsics( ($reason: tt, { $($ident: ident, )* }) => { $( #[doc(hidden)] - #[no_mangle] + #[export_name = concat!("__rust", stringify!($ident))] pub extern "C" fn $ident() { panic!($reason); } From 17ea9670a2e050b4c65e5d34d322a4f1fd915a66 Mon Sep 17 00:00:00 2001 From: Gary Guo Date: Thu, 27 Oct 2022 04:59:44 +0100 Subject: [PATCH 2/2] rust: replace `__aeabi_uldivmod` stub with actual implementation Rust's libcore genuinely needs 64-bit division for formatting, but we can't change these to use kernel's division routine; so `__aeabi_uldivmod` calls will be generated. Instead of redirecting these calls to a panicking stub, forward them to `div64_u64_rem`. Signed-off-by: Gary Guo --- rust/compiler_builtins.rs | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/rust/compiler_builtins.rs b/rust/compiler_builtins.rs index 59e70aea99cdd9..4e3f5a4ff655c9 100644 --- a/rust/compiler_builtins.rs +++ b/rust/compiler_builtins.rs @@ -20,6 +20,7 @@ //! [`compiler-rt`]: https://compiler-rt.llvm.org/ #![feature(compiler_builtins)] +#![feature(naked_functions)] #![compiler_builtins] #![no_builtins] #![no_std] @@ -74,6 +75,24 @@ define_panicking_intrinsics!("`f64` should not be used", { }); #[cfg(target_arch = "arm")] -define_panicking_intrinsics!("`u64` division/modulo should not be used", { - __aeabi_uldivmod, -}); +#[doc(hidden)] +#[naked] +#[no_mangle] +pub unsafe extern "C" fn __rust__aeabi_uldivmod() { + // Adapted from compiler-rt: + // https://github.com/llvm/llvm-project/blob/a80e65e00ada7a9c16acf17a5fd40b4f12ced3a8/compiler-rt/lib/builtins/arm/aeabi_uldivmod.S + unsafe { + core::arch::asm!( + "push {{r6, lr}}", + "sub sp, sp, #16", + "add r6, sp, #8", + "str r6, [sp]", + "bl div64_u64_rem", + "ldr r2, [sp, #8]", + "ldr r3, [sp, #12]", + "add sp, sp, #16", + "pop {{r6, pc}}", + options(noreturn) + ); + } +}