From: "Gary Guo" <gary@garyguo.net>
To: "FUJITA Tomonori" <tomo@flapping.org>, <ojeda@kernel.org>
Cc: <a.hindborg@kernel.org>, <acourbot@nvidia.com>,
<aliceryhl@google.com>, <bjorn3_gh@protonmail.com>,
<boqun@kernel.org>, <dakr@kernel.org>,
<daniel.almeida@collabora.com>, <gary@garyguo.net>,
<lossin@kernel.org>, <tamird@kernel.org>, <tmgross@umich.edu>,
<work@onurozkan.dev>, <rust-for-linux@vger.kernel.org>,
"FUJITA Tomonori" <fujita.tomonori@gmail.com>
Subject: Re: [PATCH v1] rust: compiler_builtins: Fix silent trap in prohibited intrinsics
Date: Fri, 02 Oct 2026 11:06:25 +0100 [thread overview]
Message-ID: <DLU9OHS5VLBN.27ZL2Z15IGB78@garyguo.net> (raw)
In-Reply-To: <20261002014739.2566289-1-tomo@flapping.org>
On Fri Oct 2, 2026 at 2:47 AM BST, FUJITA Tomonori wrote:
> From: FUJITA Tomonori <fujita.tomonori@gmail.com>
>
> When core calls one of the stubs for builtins that should not be used,
> the stub runs a trap instruction that prints no message, and the Oops
> shows a wrong name. For example, when __rust__udivti3() is called on
> x86_64, the Oops shows:
>
> Oops: invalid opcode: 0000 [#1] SMP
> RIP: 0010:__rust__adddf3+0x0/0x10
>
> The stubs call panic!(), but since Rust 1.79, rustc does not allow code
> in a `#![compiler_builtins]` crate to link to functions in other crates,
> and it silently turns such calls that do not return into a trap [1]. In
> addition, all the stubs have the same code, so LLVM merges them into one
> function.
>
> Replace panic!() with _printk() and BUG(), as the panic handler in the
> kernel crate does. These are C functions, and rustc allows calls to
> them. Each stub passes its own name to _printk(), so the stubs are no
> longer merged:
>
> __udivti3 called: `u128` should not be used
> kernel BUG at rust/helpers/bug.c:7!
>
> Link: https://github.com/rust-lang/rust/pull/122580 [1]
> Assisted-by: LLM
> Signed-off-by: FUJITA Tomonori <fujita.tomonori@gmail.com>
> ---
> Another option to fix this is moving the stubs to a normal crate (not
> `#![compiler_builtins]`), so that panic!() works as usual.
I think we should do this.
Best,
Gary
> ---
> rust/compiler_builtins.rs | 39 ++++++++++++++++++++++++++++++++++++---
> 1 file changed, 36 insertions(+), 3 deletions(-)
>
> diff --git a/rust/compiler_builtins.rs b/rust/compiler_builtins.rs
> index fc6b54636dd5..9416ca4c23f5 100644
> --- a/rust/compiler_builtins.rs
> +++ b/rust/compiler_builtins.rs
> @@ -9,8 +9,8 @@
> //! 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
> +//! the parts we do not need. For the moment, we define them to print an error
> +//! and call `BUG()` at runtime to catch mistakes, instead of performing surgery
> //! on `core.o`.
> //!
> //! In any case, all these symbols are weakened to ensure we do not override
> @@ -25,13 +25,46 @@
> #![no_builtins]
> #![no_std]
>
> +unsafe extern "C" {
> + #[cfg(CONFIG_PRINTK)]
> + fn _printk(fmt: *const u8, ...) -> core::ffi::c_int;
> + fn rust_helper_BUG() -> !;
> +}
> +
> +// In a `#![compiler_builtins]` crate, code cannot link to functions in other
> +// crates. `rustc` rejects such calls, except that it silently turns the ones
> +// that do not return (e.g. `panic!`) into a trap.
> +#[cold]
> +#[inline(never)]
> +#[cfg_attr(not(CONFIG_PRINTK), allow(unused_variables))]
> +fn intrinsic_called(name: &str, reason: &str) -> ! {
> + #[cfg(CONFIG_PRINTK)]
> + // SAFETY: The format string is NUL-terminated. Each `%.*s` takes a
> + // `c_int` length and a pointer. `name.as_ptr()` is valid for reads of
> + // `name.len()` bytes, and so is `reason.as_ptr()` for `reason.len()`
> + // bytes.
> + unsafe {
> + _printk(
> + // "\x010" is `KERN_EMERG`.
> + c"\x010%.*s called: %.*s\n".to_bytes_with_nul().as_ptr(),
> + name.len() as core::ffi::c_int,
> + name.as_ptr(),
> + reason.len() as core::ffi::c_int,
> + reason.as_ptr(),
> + )
> + };
> +
> + // SAFETY: FFI call.
> + unsafe { rust_helper_BUG() }
> +}
> +
> macro_rules! define_panicking_intrinsics(
> ($reason: tt, { $($ident: ident, )* }) => {
> $(
> #[doc(hidden)]
> #[export_name = concat!("__rust", stringify!($ident))]
> pub extern "C" fn $ident() {
> - panic!($reason);
> + intrinsic_called(stringify!($ident), $reason)
> }
> )*
> }
>
> base-commit: c82c75ae11fae66cf070562f9b5241a4663f30cb
prev parent reply other threads:[~2026-10-02 10:06 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-02 1:47 [PATCH v1] rust: compiler_builtins: Fix silent trap in prohibited intrinsics FUJITA Tomonori
2026-10-02 10:06 ` Gary Guo [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=DLU9OHS5VLBN.27ZL2Z15IGB78@garyguo.net \
--to=gary@garyguo.net \
--cc=a.hindborg@kernel.org \
--cc=acourbot@nvidia.com \
--cc=aliceryhl@google.com \
--cc=bjorn3_gh@protonmail.com \
--cc=boqun@kernel.org \
--cc=dakr@kernel.org \
--cc=daniel.almeida@collabora.com \
--cc=fujita.tomonori@gmail.com \
--cc=lossin@kernel.org \
--cc=ojeda@kernel.org \
--cc=rust-for-linux@vger.kernel.org \
--cc=tamird@kernel.org \
--cc=tmgross@umich.edu \
--cc=tomo@flapping.org \
--cc=work@onurozkan.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox