linux/rust/compiler_builtins.rs
Gary Guo cb7d9defda rust: compiler_builtins: make 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.

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 [1]
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>
2023-01-16 21:04:34 +01:00

67 lines
1.9 KiB
Rust

// SPDX-License-Identifier: GPL-2.0
//! Our own `compiler_builtins`.
//!
//! Rust provides [`compiler_builtins`] as a port of LLVM's [`compiler-rt`].
//! Since we do not need the vast majority of them, we avoid the dependency
//! by providing this file.
//!
//! At the moment, some builtins are required that should not be. For instance,
//! [`core`] has 128-bit integers functionality which we should not be compiling
//! in. We will work with upstream [`core`] to provide feature flags to disable
//! the parts we do not need. For the moment, we define them to [`panic!`] at
//! runtime for simplicity to catch mistakes, instead of performing surgery
//! on `core.o`.
//!
//! In any case, all these symbols are weakened to ensure we do not override
//! those that may be provided by the rest of the kernel.
//!
//! [`compiler_builtins`]: https://github.com/rust-lang/compiler-builtins
//! [`compiler-rt`]: https://compiler-rt.llvm.org/
#![feature(compiler_builtins)]
#![compiler_builtins]
#![no_builtins]
#![no_std]
macro_rules! define_panicking_intrinsics(
($reason: tt, { $($ident: ident, )* }) => {
$(
#[doc(hidden)]
#[export_name = concat!("__rust", stringify!($ident))]
pub extern "C" fn $ident() {
panic!($reason);
}
)*
}
);
define_panicking_intrinsics!("`f32` should not be used", {
__eqsf2,
__gesf2,
__lesf2,
__nesf2,
__unordsf2,
});
define_panicking_intrinsics!("`f64` should not be used", {
__unorddf2,
});
define_panicking_intrinsics!("`i128` should not be used", {
__ashrti3,
__muloti4,
__multi3,
});
define_panicking_intrinsics!("`u128` should not be used", {
__ashlti3,
__lshrti3,
__udivmodti4,
__udivti3,
__umodti3,
});
// NOTE: if you are adding a new intrinsic here, you should also add it to
// `redirect-intrinsics` in `rust/Makefile`.