diff --git a/rust/Makefile b/rust/Makefile index 6dad9a4ebcbc45..3cd3a4deec3c14 100644 --- a/rust/Makefile +++ b/rust/Makefile @@ -370,6 +370,7 @@ rust-analyzer: $(obj)/core.o: private skip_clippy = 1 $(obj)/core.o: private skip_flags = -Dunreachable_pub +$(obj)/core.o: private rustc_objcopy = --redefine-sym __aeabi_uldivmod=rust_aeabi_uldivmod $(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 329140bc0c5fb9..3759dbfe1716d5 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] @@ -51,6 +52,24 @@ define_panicking_intrinsics!("`u128` 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 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) + ); + } +}