// SPDX-License-Identifier: GPL-2.012//! Crate for all kernel procedural macros.34// When fixdep scans this, it will find this string `CONFIG_RUSTC_VERSION_TEXT`5// and thus add a dependency on `include/config/RUSTC_VERSION_TEXT`, which is6// touched by Kconfig when the version string from the compiler changes.78// Stable since Rust 1.88.0 under a different name, `proc_macro_span_file`,9// which was added in Rust 1.88.0. This is why `cfg_attr` is used here, i.e.10// to avoid depending on the full `proc_macro_span` on Rust >= 1.88.0.11#![cfg_attr(not(CONFIG_RUSTC_HAS_SPAN_FILE), feature(proc_macro_span))]1213#[macro_use]14mod quote;15mod concat_idents;16mod export;17mod fmt;18mod helpers;19mod kunit;20mod module;21mod paste;22mod vtable;2324use proc_macro::TokenStream;2526/// Declares a kernel module.27///28/// The `type` argument should be a type which implements the [`Module`]29/// trait. Also accepts various forms of kernel metadata.30///31/// The `params` field describe module parameters. Each entry has the form32///33/// ```ignore34/// parameter_name: type {35/// default: default_value,36/// description: "Description",37/// }38/// ```39///40/// `type` may be one of41///42/// - [`i8`]43/// - [`u8`]44/// - [`i8`]45/// - [`u8`]46/// - [`i16`]47/// - [`u16`]48/// - [`i32`]49/// - [`u32`]50/// - [`i64`]51/// - [`u64`]52/// - [`isize`]53/// - [`usize`]54///55/// C header: [`include/linux/moduleparam.h`](srctree/include/linux/moduleparam.h)56///57/// [`Module`]: ../kernel/trait.Module.html58///59/// # Examples60///61/// ```ignore62/// use kernel::prelude::*;63///64/// module!{65/// type: MyModule,66/// name: "my_kernel_module",67/// authors: ["Rust for Linux Contributors"],68/// description: "My very own kernel module!",69/// license: "GPL",70/// alias: ["alternate_module_name"],71/// params: {72/// my_parameter: i64 {73/// default: 1,74/// description: "This parameter has a default of 1",75/// },76/// },77/// }78///79/// struct MyModule(i32);80///81/// impl kernel::Module for MyModule {82/// fn init(_module: &'static ThisModule) -> Result<Self> {83/// let foo: i32 = 42;84/// pr_info!("I contain: {}\n", foo);85/// pr_info!("i32 param is: {}\n", module_parameters::my_parameter.read());86/// Ok(Self(foo))87/// }88/// }89/// # fn main() {}90/// ```91///92/// ## Firmware93///94/// The following example shows how to declare a kernel module that needs95/// to load binary firmware files. You need to specify the file names of96/// the firmware in the `firmware` field. The information is embedded97/// in the `modinfo` section of the kernel module. For example, a tool to98/// build an initramfs uses this information to put the firmware files into99/// the initramfs image.100///101/// ```102/// use kernel::prelude::*;103///104/// module!{105/// type: MyDeviceDriverModule,106/// name: "my_device_driver_module",107/// authors: ["Rust for Linux Contributors"],108/// description: "My device driver requires firmware",109/// license: "GPL",110/// firmware: ["my_device_firmware1.bin", "my_device_firmware2.bin"],111/// }112///113/// struct MyDeviceDriverModule;114///115/// impl kernel::Module for MyDeviceDriverModule {116/// fn init(_module: &'static ThisModule) -> Result<Self> {117/// Ok(Self)118/// }119/// }120/// # fn main() {}121/// ```122///123/// # Supported argument types124/// - `type`: type which implements the [`Module`] trait (required).125/// - `name`: ASCII string literal of the name of the kernel module (required).126/// - `authors`: array of ASCII string literals of the authors of the kernel module.127/// - `description`: string literal of the description of the kernel module.128/// - `license`: ASCII string literal of the license of the kernel module (required).129/// - `alias`: array of ASCII string literals of the alias names of the kernel module.130/// - `firmware`: array of ASCII string literals of the firmware files of131/// the kernel module.132#[proc_macro]133pub fn module(ts: TokenStream) -> TokenStream {134module::module(ts)135}136137/// Declares or implements a vtable trait.138///139/// Linux's use of pure vtables is very close to Rust traits, but they differ140/// in how unimplemented functions are represented. In Rust, traits can provide141/// default implementation for all non-required methods (and the default142/// implementation could just return `Error::EINVAL`); Linux typically use C143/// `NULL` pointers to represent these functions.144///145/// This attribute closes that gap. A trait can be annotated with the146/// `#[vtable]` attribute. Implementers of the trait will then also have to147/// annotate the trait with `#[vtable]`. This attribute generates a `HAS_*`148/// associated constant bool for each method in the trait that is set to true if149/// the implementer has overridden the associated method.150///151/// For a trait method to be optional, it must have a default implementation.152/// This is also the case for traits annotated with `#[vtable]`, but in this153/// case the default implementation will never be executed. The reason for this154/// is that the functions will be called through function pointers installed in155/// C side vtables. When an optional method is not implemented on a `#[vtable]`156/// trait, a NULL entry is installed in the vtable. Thus the default157/// implementation is never called. Since these traits are not designed to be158/// used on the Rust side, it should not be possible to call the default159/// implementation. This is done to ensure that we call the vtable methods160/// through the C vtable, and not through the Rust vtable. Therefore, the161/// default implementation should call `build_error!`, which prevents162/// calls to this function at compile time:163///164/// ```compile_fail165/// # // Intentionally missing `use`s to simplify `rusttest`.166/// build_error!(VTABLE_DEFAULT_ERROR)167/// ```168///169/// Note that you might need to import [`kernel::error::VTABLE_DEFAULT_ERROR`].170///171/// This macro should not be used when all functions are required.172///173/// # Examples174///175/// ```176/// use kernel::error::VTABLE_DEFAULT_ERROR;177/// use kernel::prelude::*;178///179/// // Declares a `#[vtable]` trait180/// #[vtable]181/// pub trait Operations: Send + Sync + Sized {182/// fn foo(&self) -> Result<()> {183/// build_error!(VTABLE_DEFAULT_ERROR)184/// }185///186/// fn bar(&self) -> Result<()> {187/// build_error!(VTABLE_DEFAULT_ERROR)188/// }189/// }190///191/// struct Foo;192///193/// // Implements the `#[vtable]` trait194/// #[vtable]195/// impl Operations for Foo {196/// fn foo(&self) -> Result<()> {197/// # Err(EINVAL)198/// // ...199/// }200/// }201///202/// assert_eq!(<Foo as Operations>::HAS_FOO, true);203/// assert_eq!(<Foo as Operations>::HAS_BAR, false);204/// ```205///206/// [`kernel::error::VTABLE_DEFAULT_ERROR`]: ../kernel/error/constant.VTABLE_DEFAULT_ERROR.html207#[proc_macro_attribute]208pub fn vtable(attr: TokenStream, ts: TokenStream) -> TokenStream {209vtable::vtable(attr, ts)210}211212/// Export a function so that C code can call it via a header file.213///214/// Functions exported using this macro can be called from C code using the declaration in the215/// appropriate header file. It should only be used in cases where C calls the function through a216/// header file; cases where C calls into Rust via a function pointer in a vtable (such as217/// `file_operations`) should not use this macro.218///219/// This macro has the following effect:220///221/// * Disables name mangling for this function.222/// * Verifies at compile-time that the function signature matches the declaration in the header223/// file.224///225/// You must declare the signature of the Rust function in a header file that is included by226/// `rust/bindings/bindings_helper.h`.227///228/// This macro is *not* the same as the C macros `EXPORT_SYMBOL_*`. All Rust symbols are currently229/// automatically exported with `EXPORT_SYMBOL_GPL`.230#[proc_macro_attribute]231pub fn export(attr: TokenStream, ts: TokenStream) -> TokenStream {232export::export(attr, ts)233}234235/// Like [`core::format_args!`], but automatically wraps arguments in [`kernel::fmt::Adapter`].236///237/// This macro allows generating `fmt::Arguments` while ensuring that each argument is wrapped with238/// `::kernel::fmt::Adapter`, which customizes formatting behavior for kernel logging.239///240/// Named arguments used in the format string (e.g. `{foo}`) are detected and resolved from local241/// bindings. All positional and named arguments are automatically wrapped.242///243/// This macro is an implementation detail of other kernel logging macros like [`pr_info!`] and244/// should not typically be used directly.245///246/// [`kernel::fmt::Adapter`]: ../kernel/fmt/struct.Adapter.html247/// [`pr_info!`]: ../kernel/macro.pr_info.html248#[proc_macro]249pub fn fmt(input: TokenStream) -> TokenStream {250fmt::fmt(input)251}252253/// Concatenate two identifiers.254///255/// This is useful in macros that need to declare or reference items with names256/// starting with a fixed prefix and ending in a user specified name. The resulting257/// identifier has the span of the second argument.258///259/// # Examples260///261/// ```262/// # const binder_driver_return_protocol_BR_OK: u32 = 0;263/// # const binder_driver_return_protocol_BR_ERROR: u32 = 1;264/// # const binder_driver_return_protocol_BR_TRANSACTION: u32 = 2;265/// # const binder_driver_return_protocol_BR_REPLY: u32 = 3;266/// # const binder_driver_return_protocol_BR_DEAD_REPLY: u32 = 4;267/// # const binder_driver_return_protocol_BR_TRANSACTION_COMPLETE: u32 = 5;268/// # const binder_driver_return_protocol_BR_INCREFS: u32 = 6;269/// # const binder_driver_return_protocol_BR_ACQUIRE: u32 = 7;270/// # const binder_driver_return_protocol_BR_RELEASE: u32 = 8;271/// # const binder_driver_return_protocol_BR_DECREFS: u32 = 9;272/// # const binder_driver_return_protocol_BR_NOOP: u32 = 10;273/// # const binder_driver_return_protocol_BR_SPAWN_LOOPER: u32 = 11;274/// # const binder_driver_return_protocol_BR_DEAD_BINDER: u32 = 12;275/// # const binder_driver_return_protocol_BR_CLEAR_DEATH_NOTIFICATION_DONE: u32 = 13;276/// # const binder_driver_return_protocol_BR_FAILED_REPLY: u32 = 14;277/// use kernel::macros::concat_idents;278///279/// macro_rules! pub_no_prefix {280/// ($prefix:ident, $($newname:ident),+) => {281/// $(pub(crate) const $newname: u32 = concat_idents!($prefix, $newname);)+282/// };283/// }284///285/// pub_no_prefix!(286/// binder_driver_return_protocol_,287/// BR_OK,288/// BR_ERROR,289/// BR_TRANSACTION,290/// BR_REPLY,291/// BR_DEAD_REPLY,292/// BR_TRANSACTION_COMPLETE,293/// BR_INCREFS,294/// BR_ACQUIRE,295/// BR_RELEASE,296/// BR_DECREFS,297/// BR_NOOP,298/// BR_SPAWN_LOOPER,299/// BR_DEAD_BINDER,300/// BR_CLEAR_DEATH_NOTIFICATION_DONE,301/// BR_FAILED_REPLY302/// );303///304/// assert_eq!(BR_OK, binder_driver_return_protocol_BR_OK);305/// ```306#[proc_macro]307pub fn concat_idents(ts: TokenStream) -> TokenStream {308concat_idents::concat_idents(ts)309}310311/// Paste identifiers together.312///313/// Within the `paste!` macro, identifiers inside `[<` and `>]` are concatenated together to form a314/// single identifier.315///316/// This is similar to the [`paste`] crate, but with pasting feature limited to identifiers and317/// literals (lifetimes and documentation strings are not supported). There is a difference in318/// supported modifiers as well.319///320/// # Examples321///322/// ```323/// # const binder_driver_return_protocol_BR_OK: u32 = 0;324/// # const binder_driver_return_protocol_BR_ERROR: u32 = 1;325/// # const binder_driver_return_protocol_BR_TRANSACTION: u32 = 2;326/// # const binder_driver_return_protocol_BR_REPLY: u32 = 3;327/// # const binder_driver_return_protocol_BR_DEAD_REPLY: u32 = 4;328/// # const binder_driver_return_protocol_BR_TRANSACTION_COMPLETE: u32 = 5;329/// # const binder_driver_return_protocol_BR_INCREFS: u32 = 6;330/// # const binder_driver_return_protocol_BR_ACQUIRE: u32 = 7;331/// # const binder_driver_return_protocol_BR_RELEASE: u32 = 8;332/// # const binder_driver_return_protocol_BR_DECREFS: u32 = 9;333/// # const binder_driver_return_protocol_BR_NOOP: u32 = 10;334/// # const binder_driver_return_protocol_BR_SPAWN_LOOPER: u32 = 11;335/// # const binder_driver_return_protocol_BR_DEAD_BINDER: u32 = 12;336/// # const binder_driver_return_protocol_BR_CLEAR_DEATH_NOTIFICATION_DONE: u32 = 13;337/// # const binder_driver_return_protocol_BR_FAILED_REPLY: u32 = 14;338/// macro_rules! pub_no_prefix {339/// ($prefix:ident, $($newname:ident),+) => {340/// ::kernel::macros::paste! {341/// $(pub(crate) const $newname: u32 = [<$prefix $newname>];)+342/// }343/// };344/// }345///346/// pub_no_prefix!(347/// binder_driver_return_protocol_,348/// BR_OK,349/// BR_ERROR,350/// BR_TRANSACTION,351/// BR_REPLY,352/// BR_DEAD_REPLY,353/// BR_TRANSACTION_COMPLETE,354/// BR_INCREFS,355/// BR_ACQUIRE,356/// BR_RELEASE,357/// BR_DECREFS,358/// BR_NOOP,359/// BR_SPAWN_LOOPER,360/// BR_DEAD_BINDER,361/// BR_CLEAR_DEATH_NOTIFICATION_DONE,362/// BR_FAILED_REPLY363/// );364///365/// assert_eq!(BR_OK, binder_driver_return_protocol_BR_OK);366/// ```367///368/// # Modifiers369///370/// For each identifier, it is possible to attach one or multiple modifiers to371/// it.372///373/// Currently supported modifiers are:374/// * `span`: change the span of concatenated identifier to the span of the specified token. By375/// default the span of the `[< >]` group is used.376/// * `lower`: change the identifier to lower case.377/// * `upper`: change the identifier to upper case.378///379/// ```380/// # const binder_driver_return_protocol_BR_OK: u32 = 0;381/// # const binder_driver_return_protocol_BR_ERROR: u32 = 1;382/// # const binder_driver_return_protocol_BR_TRANSACTION: u32 = 2;383/// # const binder_driver_return_protocol_BR_REPLY: u32 = 3;384/// # const binder_driver_return_protocol_BR_DEAD_REPLY: u32 = 4;385/// # const binder_driver_return_protocol_BR_TRANSACTION_COMPLETE: u32 = 5;386/// # const binder_driver_return_protocol_BR_INCREFS: u32 = 6;387/// # const binder_driver_return_protocol_BR_ACQUIRE: u32 = 7;388/// # const binder_driver_return_protocol_BR_RELEASE: u32 = 8;389/// # const binder_driver_return_protocol_BR_DECREFS: u32 = 9;390/// # const binder_driver_return_protocol_BR_NOOP: u32 = 10;391/// # const binder_driver_return_protocol_BR_SPAWN_LOOPER: u32 = 11;392/// # const binder_driver_return_protocol_BR_DEAD_BINDER: u32 = 12;393/// # const binder_driver_return_protocol_BR_CLEAR_DEATH_NOTIFICATION_DONE: u32 = 13;394/// # const binder_driver_return_protocol_BR_FAILED_REPLY: u32 = 14;395/// macro_rules! pub_no_prefix {396/// ($prefix:ident, $($newname:ident),+) => {397/// ::kernel::macros::paste! {398/// $(pub(crate) const fn [<$newname:lower:span>]() -> u32 { [<$prefix $newname:span>] })+399/// }400/// };401/// }402///403/// pub_no_prefix!(404/// binder_driver_return_protocol_,405/// BR_OK,406/// BR_ERROR,407/// BR_TRANSACTION,408/// BR_REPLY,409/// BR_DEAD_REPLY,410/// BR_TRANSACTION_COMPLETE,411/// BR_INCREFS,412/// BR_ACQUIRE,413/// BR_RELEASE,414/// BR_DECREFS,415/// BR_NOOP,416/// BR_SPAWN_LOOPER,417/// BR_DEAD_BINDER,418/// BR_CLEAR_DEATH_NOTIFICATION_DONE,419/// BR_FAILED_REPLY420/// );421///422/// assert_eq!(br_ok(), binder_driver_return_protocol_BR_OK);423/// ```424///425/// # Literals426///427/// Literals can also be concatenated with other identifiers:428///429/// ```430/// macro_rules! create_numbered_fn {431/// ($name:literal, $val:literal) => {432/// ::kernel::macros::paste! {433/// fn [<some_ $name _fn $val>]() -> u32 { $val }434/// }435/// };436/// }437///438/// create_numbered_fn!("foo", 100);439///440/// assert_eq!(some_foo_fn100(), 100)441/// ```442///443/// [`paste`]: https://docs.rs/paste/444#[proc_macro]445pub fn paste(input: TokenStream) -> TokenStream {446let mut tokens = input.into_iter().collect();447paste::expand(&mut tokens);448tokens.into_iter().collect()449}450451/// Registers a KUnit test suite and its test cases using a user-space like syntax.452///453/// This macro should be used on modules. If `CONFIG_KUNIT` (in `.config`) is `n`, the target module454/// is ignored.455///456/// # Examples457///458/// ```ignore459/// # use kernel::prelude::*;460/// #[kunit_tests(kunit_test_suit_name)]461/// mod tests {462/// #[test]463/// fn foo() {464/// assert_eq!(1, 1);465/// }466///467/// #[test]468/// fn bar() {469/// assert_eq!(2, 2);470/// }471/// }472/// ```473#[proc_macro_attribute]474pub fn kunit_tests(attr: TokenStream, ts: TokenStream) -> TokenStream {475kunit::kunit_tests(attr, ts)476}477478479