// 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 helpers;18mod kunit;19mod module;20mod paste;21mod vtable;2223use proc_macro::TokenStream;2425/// Declares a kernel module.26///27/// The `type` argument should be a type which implements the [`Module`]28/// trait. Also accepts various forms of kernel metadata.29///30/// C header: [`include/linux/moduleparam.h`](srctree/include/linux/moduleparam.h)31///32/// [`Module`]: ../kernel/trait.Module.html33///34/// # Examples35///36/// ```37/// use kernel::prelude::*;38///39/// module!{40/// type: MyModule,41/// name: "my_kernel_module",42/// authors: ["Rust for Linux Contributors"],43/// description: "My very own kernel module!",44/// license: "GPL",45/// alias: ["alternate_module_name"],46/// }47///48/// struct MyModule(i32);49///50/// impl kernel::Module for MyModule {51/// fn init(_module: &'static ThisModule) -> Result<Self> {52/// let foo: i32 = 42;53/// pr_info!("I contain: {}\n", foo);54/// Ok(Self(foo))55/// }56/// }57/// # fn main() {}58/// ```59///60/// ## Firmware61///62/// The following example shows how to declare a kernel module that needs63/// to load binary firmware files. You need to specify the file names of64/// the firmware in the `firmware` field. The information is embedded65/// in the `modinfo` section of the kernel module. For example, a tool to66/// build an initramfs uses this information to put the firmware files into67/// the initramfs image.68///69/// ```70/// use kernel::prelude::*;71///72/// module!{73/// type: MyDeviceDriverModule,74/// name: "my_device_driver_module",75/// authors: ["Rust for Linux Contributors"],76/// description: "My device driver requires firmware",77/// license: "GPL",78/// firmware: ["my_device_firmware1.bin", "my_device_firmware2.bin"],79/// }80///81/// struct MyDeviceDriverModule;82///83/// impl kernel::Module for MyDeviceDriverModule {84/// fn init(_module: &'static ThisModule) -> Result<Self> {85/// Ok(Self)86/// }87/// }88/// # fn main() {}89/// ```90///91/// # Supported argument types92/// - `type`: type which implements the [`Module`] trait (required).93/// - `name`: ASCII string literal of the name of the kernel module (required).94/// - `authors`: array of ASCII string literals of the authors of the kernel module.95/// - `description`: string literal of the description of the kernel module.96/// - `license`: ASCII string literal of the license of the kernel module (required).97/// - `alias`: array of ASCII string literals of the alias names of the kernel module.98/// - `firmware`: array of ASCII string literals of the firmware files of99/// the kernel module.100#[proc_macro]101pub fn module(ts: TokenStream) -> TokenStream {102module::module(ts)103}104105/// Declares or implements a vtable trait.106///107/// Linux's use of pure vtables is very close to Rust traits, but they differ108/// in how unimplemented functions are represented. In Rust, traits can provide109/// default implementation for all non-required methods (and the default110/// implementation could just return `Error::EINVAL`); Linux typically use C111/// `NULL` pointers to represent these functions.112///113/// This attribute closes that gap. A trait can be annotated with the114/// `#[vtable]` attribute. Implementers of the trait will then also have to115/// annotate the trait with `#[vtable]`. This attribute generates a `HAS_*`116/// associated constant bool for each method in the trait that is set to true if117/// the implementer has overridden the associated method.118///119/// For a trait method to be optional, it must have a default implementation.120/// This is also the case for traits annotated with `#[vtable]`, but in this121/// case the default implementation will never be executed. The reason for this122/// is that the functions will be called through function pointers installed in123/// C side vtables. When an optional method is not implemented on a `#[vtable]`124/// trait, a NULL entry is installed in the vtable. Thus the default125/// implementation is never called. Since these traits are not designed to be126/// used on the Rust side, it should not be possible to call the default127/// implementation. This is done to ensure that we call the vtable methods128/// through the C vtable, and not through the Rust vtable. Therefore, the129/// default implementation should call `build_error!`, which prevents130/// calls to this function at compile time:131///132/// ```compile_fail133/// # // Intentionally missing `use`s to simplify `rusttest`.134/// build_error!(VTABLE_DEFAULT_ERROR)135/// ```136///137/// Note that you might need to import [`kernel::error::VTABLE_DEFAULT_ERROR`].138///139/// This macro should not be used when all functions are required.140///141/// # Examples142///143/// ```144/// use kernel::error::VTABLE_DEFAULT_ERROR;145/// use kernel::prelude::*;146///147/// // Declares a `#[vtable]` trait148/// #[vtable]149/// pub trait Operations: Send + Sync + Sized {150/// fn foo(&self) -> Result<()> {151/// build_error!(VTABLE_DEFAULT_ERROR)152/// }153///154/// fn bar(&self) -> Result<()> {155/// build_error!(VTABLE_DEFAULT_ERROR)156/// }157/// }158///159/// struct Foo;160///161/// // Implements the `#[vtable]` trait162/// #[vtable]163/// impl Operations for Foo {164/// fn foo(&self) -> Result<()> {165/// # Err(EINVAL)166/// // ...167/// }168/// }169///170/// assert_eq!(<Foo as Operations>::HAS_FOO, true);171/// assert_eq!(<Foo as Operations>::HAS_BAR, false);172/// ```173///174/// [`kernel::error::VTABLE_DEFAULT_ERROR`]: ../kernel/error/constant.VTABLE_DEFAULT_ERROR.html175#[proc_macro_attribute]176pub fn vtable(attr: TokenStream, ts: TokenStream) -> TokenStream {177vtable::vtable(attr, ts)178}179180/// Export a function so that C code can call it via a header file.181///182/// Functions exported using this macro can be called from C code using the declaration in the183/// appropriate header file. It should only be used in cases where C calls the function through a184/// header file; cases where C calls into Rust via a function pointer in a vtable (such as185/// `file_operations`) should not use this macro.186///187/// This macro has the following effect:188///189/// * Disables name mangling for this function.190/// * Verifies at compile-time that the function signature matches the declaration in the header191/// file.192///193/// You must declare the signature of the Rust function in a header file that is included by194/// `rust/bindings/bindings_helper.h`.195///196/// This macro is *not* the same as the C macros `EXPORT_SYMBOL_*`. All Rust symbols are currently197/// automatically exported with `EXPORT_SYMBOL_GPL`.198#[proc_macro_attribute]199pub fn export(attr: TokenStream, ts: TokenStream) -> TokenStream {200export::export(attr, ts)201}202203/// Concatenate two identifiers.204///205/// This is useful in macros that need to declare or reference items with names206/// starting with a fixed prefix and ending in a user specified name. The resulting207/// identifier has the span of the second argument.208///209/// # Examples210///211/// ```212/// # const binder_driver_return_protocol_BR_OK: u32 = 0;213/// # const binder_driver_return_protocol_BR_ERROR: u32 = 1;214/// # const binder_driver_return_protocol_BR_TRANSACTION: u32 = 2;215/// # const binder_driver_return_protocol_BR_REPLY: u32 = 3;216/// # const binder_driver_return_protocol_BR_DEAD_REPLY: u32 = 4;217/// # const binder_driver_return_protocol_BR_TRANSACTION_COMPLETE: u32 = 5;218/// # const binder_driver_return_protocol_BR_INCREFS: u32 = 6;219/// # const binder_driver_return_protocol_BR_ACQUIRE: u32 = 7;220/// # const binder_driver_return_protocol_BR_RELEASE: u32 = 8;221/// # const binder_driver_return_protocol_BR_DECREFS: u32 = 9;222/// # const binder_driver_return_protocol_BR_NOOP: u32 = 10;223/// # const binder_driver_return_protocol_BR_SPAWN_LOOPER: u32 = 11;224/// # const binder_driver_return_protocol_BR_DEAD_BINDER: u32 = 12;225/// # const binder_driver_return_protocol_BR_CLEAR_DEATH_NOTIFICATION_DONE: u32 = 13;226/// # const binder_driver_return_protocol_BR_FAILED_REPLY: u32 = 14;227/// use kernel::macros::concat_idents;228///229/// macro_rules! pub_no_prefix {230/// ($prefix:ident, $($newname:ident),+) => {231/// $(pub(crate) const $newname: u32 = concat_idents!($prefix, $newname);)+232/// };233/// }234///235/// pub_no_prefix!(236/// binder_driver_return_protocol_,237/// BR_OK,238/// BR_ERROR,239/// BR_TRANSACTION,240/// BR_REPLY,241/// BR_DEAD_REPLY,242/// BR_TRANSACTION_COMPLETE,243/// BR_INCREFS,244/// BR_ACQUIRE,245/// BR_RELEASE,246/// BR_DECREFS,247/// BR_NOOP,248/// BR_SPAWN_LOOPER,249/// BR_DEAD_BINDER,250/// BR_CLEAR_DEATH_NOTIFICATION_DONE,251/// BR_FAILED_REPLY252/// );253///254/// assert_eq!(BR_OK, binder_driver_return_protocol_BR_OK);255/// ```256#[proc_macro]257pub fn concat_idents(ts: TokenStream) -> TokenStream {258concat_idents::concat_idents(ts)259}260261/// Paste identifiers together.262///263/// Within the `paste!` macro, identifiers inside `[<` and `>]` are concatenated together to form a264/// single identifier.265///266/// This is similar to the [`paste`] crate, but with pasting feature limited to identifiers and267/// literals (lifetimes and documentation strings are not supported). There is a difference in268/// supported modifiers as well.269///270/// # Examples271///272/// ```273/// # const binder_driver_return_protocol_BR_OK: u32 = 0;274/// # const binder_driver_return_protocol_BR_ERROR: u32 = 1;275/// # const binder_driver_return_protocol_BR_TRANSACTION: u32 = 2;276/// # const binder_driver_return_protocol_BR_REPLY: u32 = 3;277/// # const binder_driver_return_protocol_BR_DEAD_REPLY: u32 = 4;278/// # const binder_driver_return_protocol_BR_TRANSACTION_COMPLETE: u32 = 5;279/// # const binder_driver_return_protocol_BR_INCREFS: u32 = 6;280/// # const binder_driver_return_protocol_BR_ACQUIRE: u32 = 7;281/// # const binder_driver_return_protocol_BR_RELEASE: u32 = 8;282/// # const binder_driver_return_protocol_BR_DECREFS: u32 = 9;283/// # const binder_driver_return_protocol_BR_NOOP: u32 = 10;284/// # const binder_driver_return_protocol_BR_SPAWN_LOOPER: u32 = 11;285/// # const binder_driver_return_protocol_BR_DEAD_BINDER: u32 = 12;286/// # const binder_driver_return_protocol_BR_CLEAR_DEATH_NOTIFICATION_DONE: u32 = 13;287/// # const binder_driver_return_protocol_BR_FAILED_REPLY: u32 = 14;288/// macro_rules! pub_no_prefix {289/// ($prefix:ident, $($newname:ident),+) => {290/// ::kernel::macros::paste! {291/// $(pub(crate) const $newname: u32 = [<$prefix $newname>];)+292/// }293/// };294/// }295///296/// pub_no_prefix!(297/// binder_driver_return_protocol_,298/// BR_OK,299/// BR_ERROR,300/// BR_TRANSACTION,301/// BR_REPLY,302/// BR_DEAD_REPLY,303/// BR_TRANSACTION_COMPLETE,304/// BR_INCREFS,305/// BR_ACQUIRE,306/// BR_RELEASE,307/// BR_DECREFS,308/// BR_NOOP,309/// BR_SPAWN_LOOPER,310/// BR_DEAD_BINDER,311/// BR_CLEAR_DEATH_NOTIFICATION_DONE,312/// BR_FAILED_REPLY313/// );314///315/// assert_eq!(BR_OK, binder_driver_return_protocol_BR_OK);316/// ```317///318/// # Modifiers319///320/// For each identifier, it is possible to attach one or multiple modifiers to321/// it.322///323/// Currently supported modifiers are:324/// * `span`: change the span of concatenated identifier to the span of the specified token. By325/// default the span of the `[< >]` group is used.326/// * `lower`: change the identifier to lower case.327/// * `upper`: change the identifier to upper case.328///329/// ```330/// # const binder_driver_return_protocol_BR_OK: u32 = 0;331/// # const binder_driver_return_protocol_BR_ERROR: u32 = 1;332/// # const binder_driver_return_protocol_BR_TRANSACTION: u32 = 2;333/// # const binder_driver_return_protocol_BR_REPLY: u32 = 3;334/// # const binder_driver_return_protocol_BR_DEAD_REPLY: u32 = 4;335/// # const binder_driver_return_protocol_BR_TRANSACTION_COMPLETE: u32 = 5;336/// # const binder_driver_return_protocol_BR_INCREFS: u32 = 6;337/// # const binder_driver_return_protocol_BR_ACQUIRE: u32 = 7;338/// # const binder_driver_return_protocol_BR_RELEASE: u32 = 8;339/// # const binder_driver_return_protocol_BR_DECREFS: u32 = 9;340/// # const binder_driver_return_protocol_BR_NOOP: u32 = 10;341/// # const binder_driver_return_protocol_BR_SPAWN_LOOPER: u32 = 11;342/// # const binder_driver_return_protocol_BR_DEAD_BINDER: u32 = 12;343/// # const binder_driver_return_protocol_BR_CLEAR_DEATH_NOTIFICATION_DONE: u32 = 13;344/// # const binder_driver_return_protocol_BR_FAILED_REPLY: u32 = 14;345/// macro_rules! pub_no_prefix {346/// ($prefix:ident, $($newname:ident),+) => {347/// ::kernel::macros::paste! {348/// $(pub(crate) const fn [<$newname:lower:span>]() -> u32 { [<$prefix $newname:span>] })+349/// }350/// };351/// }352///353/// pub_no_prefix!(354/// binder_driver_return_protocol_,355/// BR_OK,356/// BR_ERROR,357/// BR_TRANSACTION,358/// BR_REPLY,359/// BR_DEAD_REPLY,360/// BR_TRANSACTION_COMPLETE,361/// BR_INCREFS,362/// BR_ACQUIRE,363/// BR_RELEASE,364/// BR_DECREFS,365/// BR_NOOP,366/// BR_SPAWN_LOOPER,367/// BR_DEAD_BINDER,368/// BR_CLEAR_DEATH_NOTIFICATION_DONE,369/// BR_FAILED_REPLY370/// );371///372/// assert_eq!(br_ok(), binder_driver_return_protocol_BR_OK);373/// ```374///375/// # Literals376///377/// Literals can also be concatenated with other identifiers:378///379/// ```380/// macro_rules! create_numbered_fn {381/// ($name:literal, $val:literal) => {382/// ::kernel::macros::paste! {383/// fn [<some_ $name _fn $val>]() -> u32 { $val }384/// }385/// };386/// }387///388/// create_numbered_fn!("foo", 100);389///390/// assert_eq!(some_foo_fn100(), 100)391/// ```392///393/// [`paste`]: https://docs.rs/paste/394#[proc_macro]395pub fn paste(input: TokenStream) -> TokenStream {396let mut tokens = input.into_iter().collect();397paste::expand(&mut tokens);398tokens.into_iter().collect()399}400401/// Registers a KUnit test suite and its test cases using a user-space like syntax.402///403/// This macro should be used on modules. If `CONFIG_KUNIT` (in `.config`) is `n`, the target module404/// is ignored.405///406/// # Examples407///408/// ```ignore409/// # use kernel::prelude::*;410/// #[kunit_tests(kunit_test_suit_name)]411/// mod tests {412/// #[test]413/// fn foo() {414/// assert_eq!(1, 1);415/// }416///417/// #[test]418/// fn bar() {419/// assert_eq!(2, 2);420/// }421/// }422/// ```423#[proc_macro_attribute]424pub fn kunit_tests(attr: TokenStream, ts: TokenStream) -> TokenStream {425kunit::kunit_tests(attr, ts)426}427428429