rust/kernel/print.rs

Source file repositories/reference/linux-study-clean/rust/kernel/print.rs

File Facts

System
Linux kernel
Corpus path
rust/kernel/print.rs
Extension
.rs
Size
17790 bytes
Lines
579
Domain
Rust Kernel Layer
Bucket
Rust API Membrane
Inferred role
Rust Kernel Layer: implementation source
Status
source implementation candidate

Why This File Exists

Rust-side wrappers and abstractions around kernel C APIs, ownership contracts, allocation, synchronization, and module integration.

Dependency Surface

Detected Declarations

Annotated Snippet

pub fn call_printk_cont(args: fmt::Arguments<'_>) {
    // `_printk` does not seem to fail in any path.
    //
    // SAFETY: The format string is fixed.
    #[cfg(CONFIG_PRINTK)]
    unsafe {
        bindings::_printk(
            format_strings::CONT.as_ptr(),
            core::ptr::from_ref(&args).cast::<c_void>(),
        );
    }
}

/// Performs formatting and forwards the string to [`call_printk`].
///
/// Public but hidden since it should only be used from public macros.
#[doc(hidden)]
#[cfg(not(testlib))]
#[macro_export]
#[expect(clippy::crate_in_macro_def)]
macro_rules! print_macro (
    // The non-continuation cases (most of them, e.g. `INFO`).
    ($format_string:path, false, $($arg:tt)+) => (
        // To remain sound, `arg`s must be expanded outside the `unsafe` block.
        // Typically one would use a `let` binding for that; however, `format_args!`
        // takes borrows on the arguments, but does not extend the scope of temporaries.
        // Therefore, a `match` expression is used to keep them around, since
        // the scrutinee is kept until the end of the `match`.
        match $crate::prelude::fmt!($($arg)+) {
            // SAFETY: This hidden macro should only be called by the documented
            // printing macros which ensure the format string is one of the fixed
            // ones. All `__LOG_PREFIX`s are null-terminated as they are generated
            // by the `module!` proc macro or fixed values defined in a kernel
            // crate.
            args => unsafe {
                $crate::print::call_printk(
                    &$format_string,
                    crate::__LOG_PREFIX,
                    args,
                );
            }
        }
    );

    // The `CONT` case.
    ($format_string:path, true, $($arg:tt)+) => (
        $crate::print::call_printk_cont(
            $crate::prelude::fmt!($($arg)+),
        );
    );
);

/// Stub for doctests
#[cfg(testlib)]
#[macro_export]
macro_rules! print_macro (
    ($format_string:path, $e:expr, $($arg:tt)+) => (
        ()
    );
);

// We could use a macro to generate these macros. However, doing so ends
// up being a bit ugly: it requires the dollar token trick to escape `$` as
// well as playing with the `doc` attribute. Furthermore, they cannot be easily
// imported in the prelude due to [1]. So, for the moment, we just write them
// manually, like in the C side; while keeping most of the logic in another
// macro, i.e. [`print_macro`].
//
// [1]: https://github.com/rust-lang/rust/issues/52234

/// Prints an emergency-level message (level 0).
///
/// Use this level if the system is unusable.
///
/// Equivalent to the kernel's [`pr_emerg`] macro.
///
/// Mimics the interface of [`std::print!`]. See [`core::fmt`] and
/// [`std::format!`] for information about the formatting syntax.
///
/// [`pr_emerg`]: https://docs.kernel.org/core-api/printk-basics.html#c.pr_emerg
/// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html
/// [`std::format!`]: https://doc.rust-lang.org/std/macro.format.html
///
/// # Examples
///
/// ```
/// pr_emerg!("hello {}\n", "there");
/// ```
#[macro_export]
macro_rules! pr_emerg (

Annotation

Implementation Notes