rust: compiler_builtins: make stubs non-global
authorGary Guo <gary@garyguo.net>
Mon, 5 Dec 2022 21:50:00 +0000 (21:50 +0000)
committerMiguel Ojeda <ojeda@kernel.org>
Mon, 16 Jan 2023 20:04:34 +0000 (21:04 +0100)
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.

This patch was previously discussed on GitHub [1]. This approach was also
independently proposed by Nick Desaulniers in [2].

Link: https://github.com/Rust-for-Linux/linux/pull/779
Link: https://lore.kernel.org/lkml/CAKwvOdkc0Qhwu=gfe1+H23TnAa6jnO6A3ZCO687dH6mSrATmDA@mail.gmail.com/
Suggested-by: Nick Desaulniers <ndesaulniers@google.com>
Acked-by: Nick Desaulniers <ndesaulniers@google.com>
Signed-off-by: Gary Guo <gary@garyguo.net>
Reviewed-by: Wei Liu <wei.liu@kernel.org>
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
rust/Makefile
rust/compiler_builtins.rs

index d7621fad5b56901d8f26e18f50c4b411ce8739c6..8a521f2b642201af46ba9d1ed071c921507c8ad7 100644 (file)
@@ -360,8 +360,22 @@ 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
+
 $(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)
index f8f39a3e685514f3d49d27c185fff0f7a7a97172..43378357ece99bc2e888ab44d37f3a774094ff8d 100644 (file)
@@ -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);
             }
@@ -61,3 +61,6 @@ define_panicking_intrinsics!("`u128` should not be used", {
     __udivti3,
     __umodti3,
 });
+
+// NOTE: if you are adding a new intrinsic here, you should also add it to
+// `redirect-intrinsics` in `rust/Makefile`.