From: Miguel Ojeda <[email protected]>
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 our own crate.
We also need a helpers C source file to contain some forwarders
to C macros and inlined functions. For the moment, we only need it
to call the `BUG()` macro, but we will be adding more later.
This also allows us to build `core` from Rust's standard library.
Co-developed-by: Alex Gaynor <[email protected]>
Signed-off-by: Alex Gaynor <[email protected]>
Co-developed-by: Geoffrey Thomas <[email protected]>
Signed-off-by: Geoffrey Thomas <[email protected]>
Co-developed-by: Finn Behrens <[email protected]>
Signed-off-by: Finn Behrens <[email protected]>
Co-developed-by: Adam Bratschi-Kaye <[email protected]>
Signed-off-by: Adam Bratschi-Kaye <[email protected]>
Co-developed-by: Wedson Almeida Filho <[email protected]>
Signed-off-by: Wedson Almeida Filho <[email protected]>
Signed-off-by: Miguel Ojeda <[email protected]>
---
rust/Makefile | 3 +
rust/compiler_builtins.rs | 146 ++++++++++++++++++++++++++++++++++++++
rust/helpers.c | 8 +++
3 files changed, 157 insertions(+)
create mode 100644 rust/compiler_builtins.rs
create mode 100644 rust/helpers.c
diff --git a/rust/Makefile b/rust/Makefile
index ba4b13e4fc7f..5b96462b4fef 100644
--- a/rust/Makefile
+++ b/rust/Makefile
@@ -1,5 +1,8 @@
# SPDX-License-Identifier: GPL-2.0
+obj-$(CONFIG_RUST) += core.o compiler_builtins.o helpers.o
+extra-$(CONFIG_RUST) += exports_core_generated.h
+
RUSTDOC = rustdoc
quiet_cmd_rustdoc = RUSTDOC $<
diff --git a/rust/compiler_builtins.rs b/rust/compiler_builtins.rs
new file mode 100644
index 000000000000..01f2d905e15f
--- /dev/null
+++ b/rust/compiler_builtins.rs
@@ -0,0 +1,146 @@
+// 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 floating-point functionality which we should not be compiling
+//! in. For the moment, we define them to [`panic!`] at runtime for simplicity.
+//! These are actually a superset of the ones we actually need to define,
+//! but it seems simpler to ban entire categories at once. In the future,
+//! we might be able to remove all this by providing our own custom [`core`]
+//! etc., or perhaps [`core`] itself might provide `cfg` options to disable
+//! enough functionality to avoid requiring some of these.
+//!
+//! 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]
+#![deny(clippy::complexity)]
+#![deny(clippy::correctness)]
+#![deny(clippy::perf)]
+#![deny(clippy::style)]
+
+macro_rules! define_panicking_intrinsics(
+ ($reason: tt, { $($ident: ident, )* }) => {
+ $(
+ #[doc(hidden)]
+ #[no_mangle]
+ pub extern "C" fn $ident() {
+ panic!($reason);
+ }
+ )*
+ }
+);
+
+define_panicking_intrinsics!("non-inline stack probes should not be used", {
+ __rust_probestack,
+});
+
+define_panicking_intrinsics!("`f32` should not be used", {
+ __addsf3,
+ __addsf3vfp,
+ __divsf3,
+ __divsf3vfp,
+ __eqsf2,
+ __eqsf2vfp,
+ __fixsfdi,
+ __fixsfsi,
+ __fixsfti,
+ __fixunssfdi,
+ __fixunssfsi,
+ __fixunssfti,
+ __floatdisf,
+ __floatsisf,
+ __floattisf,
+ __floatundisf,
+ __floatunsisf,
+ __floatuntisf,
+ __gesf2,
+ __gesf2vfp,
+ __gtsf2,
+ __gtsf2vfp,
+ __lesf2,
+ __lesf2vfp,
+ __ltsf2,
+ __ltsf2vfp,
+ __mulsf3,
+ __mulsf3vfp,
+ __nesf2,
+ __nesf2vfp,
+ __powisf2,
+ __subsf3,
+ __subsf3vfp,
+ __unordsf2,
+});
+
+define_panicking_intrinsics!("`f64` should not be used", {
+ __adddf3,
+ __adddf3vfp,
+ __divdf3,
+ __divdf3vfp,
+ __eqdf2,
+ __eqdf2vfp,
+ __fixdfdi,
+ __fixdfsi,
+ __fixdfti,
+ __fixunsdfdi,
+ __fixunsdfsi,
+ __fixunsdfti,
+ __floatdidf,
+ __floatsidf,
+ __floattidf,
+ __floatundidf,
+ __floatunsidf,
+ __floatuntidf,
+ __gedf2,
+ __gedf2vfp,
+ __gtdf2,
+ __gtdf2vfp,
+ __ledf2,
+ __ledf2vfp,
+ __ltdf2,
+ __ltdf2vfp,
+ __muldf3,
+ __muldf3vfp,
+ __nedf2,
+ __nedf2vfp,
+ __powidf2,
+ __subdf3,
+ __subdf3vfp,
+ __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,
+});
+
+extern "C" {
+ fn rust_helper_BUG() -> !;
+}
+
+#[panic_handler]
+fn panic(_info: &core::panic::PanicInfo) -> ! {
+ unsafe {
+ rust_helper_BUG();
+ }
+}
diff --git a/rust/helpers.c b/rust/helpers.c
new file mode 100644
index 000000000000..5c2346dd379b
--- /dev/null
+++ b/rust/helpers.c
@@ -0,0 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/bug.h>
+
+void rust_helper_BUG(void)
+{
+ BUG();
+}
--
2.17.1
On Wed, Apr 14, 2021 at 9:19 PM Linus Torvalds
<[email protected]> wrote:
>
> Not being a Rust person, I can only guess based on random pattern
> matching, but this _looks_ like these "panicking intrinsics" panic at
> run-time (by calling BUG()).
Your pattern matching works well :)
> Is there some way these things could cause built-time link errors
> instead, so that if somebody uses 128-bit shifts, or floating point
> ops in the rust code, they show up as build failures, not as run-time
> ones?
Yes, we should definitely make this a compile-time error if possible!
This was the easy way out for the moment.
In general, there are some things that are currently unneeded from the
Rust standard library. When we get to remove those, many of those
intrinsics should go away, and then we can leave it as a link error.
Cheers,
Miguel
On Wed, Apr 14, 2021 at 11:46 AM <[email protected]> wrote:
>
> We also need a helpers C source file to contain some forwarders
> to C macros and inlined functions. For the moment, we only need it
> to call the `BUG()` macro, but we will be adding more later.
Not being a Rust person, I can only guess based on random pattern
matching, but this _looks_ like these "panicking intrinsics" panic at
run-time (by calling BUG()).
Is there some way these things could cause built-time link errors
instead, so that if somebody uses 128-bit shifts, or floating point
ops in the rust code, they show up as build failures, not as run-time
ones?
Hmm?
Linus