at v6.18-rc2 15 kB view raw
1// SPDX-License-Identifier: GPL-2.0 2 3//! Crate for all kernel procedural macros. 4 5// When fixdep scans this, it will find this string `CONFIG_RUSTC_VERSION_TEXT` 6// and thus add a dependency on `include/config/RUSTC_VERSION_TEXT`, which is 7// touched by Kconfig when the version string from the compiler changes. 8 9// Stable since Rust 1.88.0 under a different name, `proc_macro_span_file`, 10// which was added in Rust 1.88.0. This is why `cfg_attr` is used here, i.e. 11// to avoid depending on the full `proc_macro_span` on Rust >= 1.88.0. 12#![cfg_attr(not(CONFIG_RUSTC_HAS_SPAN_FILE), feature(proc_macro_span))] 13 14#[macro_use] 15mod quote; 16mod concat_idents; 17mod export; 18mod helpers; 19mod kunit; 20mod module; 21mod paste; 22mod vtable; 23 24use proc_macro::TokenStream; 25 26/// 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/// C header: [`include/linux/moduleparam.h`](srctree/include/linux/moduleparam.h) 32/// 33/// [`Module`]: ../kernel/trait.Module.html 34/// 35/// # Examples 36/// 37/// ``` 38/// use kernel::prelude::*; 39/// 40/// module!{ 41/// type: MyModule, 42/// name: "my_kernel_module", 43/// authors: ["Rust for Linux Contributors"], 44/// description: "My very own kernel module!", 45/// license: "GPL", 46/// alias: ["alternate_module_name"], 47/// } 48/// 49/// struct MyModule(i32); 50/// 51/// impl kernel::Module for MyModule { 52/// fn init(_module: &'static ThisModule) -> Result<Self> { 53/// let foo: i32 = 42; 54/// pr_info!("I contain: {}\n", foo); 55/// Ok(Self(foo)) 56/// } 57/// } 58/// # fn main() {} 59/// ``` 60/// 61/// ## Firmware 62/// 63/// The following example shows how to declare a kernel module that needs 64/// to load binary firmware files. You need to specify the file names of 65/// the firmware in the `firmware` field. The information is embedded 66/// in the `modinfo` section of the kernel module. For example, a tool to 67/// build an initramfs uses this information to put the firmware files into 68/// the initramfs image. 69/// 70/// ``` 71/// use kernel::prelude::*; 72/// 73/// module!{ 74/// type: MyDeviceDriverModule, 75/// name: "my_device_driver_module", 76/// authors: ["Rust for Linux Contributors"], 77/// description: "My device driver requires firmware", 78/// license: "GPL", 79/// firmware: ["my_device_firmware1.bin", "my_device_firmware2.bin"], 80/// } 81/// 82/// struct MyDeviceDriverModule; 83/// 84/// impl kernel::Module for MyDeviceDriverModule { 85/// fn init(_module: &'static ThisModule) -> Result<Self> { 86/// Ok(Self) 87/// } 88/// } 89/// # fn main() {} 90/// ``` 91/// 92/// # Supported argument types 93/// - `type`: type which implements the [`Module`] trait (required). 94/// - `name`: ASCII string literal of the name of the kernel module (required). 95/// - `authors`: array of ASCII string literals of the authors of the kernel module. 96/// - `description`: string literal of the description of the kernel module. 97/// - `license`: ASCII string literal of the license of the kernel module (required). 98/// - `alias`: array of ASCII string literals of the alias names of the kernel module. 99/// - `firmware`: array of ASCII string literals of the firmware files of 100/// the kernel module. 101#[proc_macro] 102pub fn module(ts: TokenStream) -> TokenStream { 103 module::module(ts) 104} 105 106/// Declares or implements a vtable trait. 107/// 108/// Linux's use of pure vtables is very close to Rust traits, but they differ 109/// in how unimplemented functions are represented. In Rust, traits can provide 110/// default implementation for all non-required methods (and the default 111/// implementation could just return `Error::EINVAL`); Linux typically use C 112/// `NULL` pointers to represent these functions. 113/// 114/// This attribute closes that gap. A trait can be annotated with the 115/// `#[vtable]` attribute. Implementers of the trait will then also have to 116/// annotate the trait with `#[vtable]`. This attribute generates a `HAS_*` 117/// associated constant bool for each method in the trait that is set to true if 118/// the implementer has overridden the associated method. 119/// 120/// For a trait method to be optional, it must have a default implementation. 121/// This is also the case for traits annotated with `#[vtable]`, but in this 122/// case the default implementation will never be executed. The reason for this 123/// is that the functions will be called through function pointers installed in 124/// C side vtables. When an optional method is not implemented on a `#[vtable]` 125/// trait, a NULL entry is installed in the vtable. Thus the default 126/// implementation is never called. Since these traits are not designed to be 127/// used on the Rust side, it should not be possible to call the default 128/// implementation. This is done to ensure that we call the vtable methods 129/// through the C vtable, and not through the Rust vtable. Therefore, the 130/// default implementation should call `build_error!`, which prevents 131/// calls to this function at compile time: 132/// 133/// ```compile_fail 134/// # // Intentionally missing `use`s to simplify `rusttest`. 135/// build_error!(VTABLE_DEFAULT_ERROR) 136/// ``` 137/// 138/// Note that you might need to import [`kernel::error::VTABLE_DEFAULT_ERROR`]. 139/// 140/// This macro should not be used when all functions are required. 141/// 142/// # Examples 143/// 144/// ``` 145/// use kernel::error::VTABLE_DEFAULT_ERROR; 146/// use kernel::prelude::*; 147/// 148/// // Declares a `#[vtable]` trait 149/// #[vtable] 150/// pub trait Operations: Send + Sync + Sized { 151/// fn foo(&self) -> Result<()> { 152/// build_error!(VTABLE_DEFAULT_ERROR) 153/// } 154/// 155/// fn bar(&self) -> Result<()> { 156/// build_error!(VTABLE_DEFAULT_ERROR) 157/// } 158/// } 159/// 160/// struct Foo; 161/// 162/// // Implements the `#[vtable]` trait 163/// #[vtable] 164/// impl Operations for Foo { 165/// fn foo(&self) -> Result<()> { 166/// # Err(EINVAL) 167/// // ... 168/// } 169/// } 170/// 171/// assert_eq!(<Foo as Operations>::HAS_FOO, true); 172/// assert_eq!(<Foo as Operations>::HAS_BAR, false); 173/// ``` 174/// 175/// [`kernel::error::VTABLE_DEFAULT_ERROR`]: ../kernel/error/constant.VTABLE_DEFAULT_ERROR.html 176#[proc_macro_attribute] 177pub fn vtable(attr: TokenStream, ts: TokenStream) -> TokenStream { 178 vtable::vtable(attr, ts) 179} 180 181/// Export a function so that C code can call it via a header file. 182/// 183/// Functions exported using this macro can be called from C code using the declaration in the 184/// appropriate header file. It should only be used in cases where C calls the function through a 185/// header file; cases where C calls into Rust via a function pointer in a vtable (such as 186/// `file_operations`) should not use this macro. 187/// 188/// This macro has the following effect: 189/// 190/// * Disables name mangling for this function. 191/// * Verifies at compile-time that the function signature matches the declaration in the header 192/// file. 193/// 194/// You must declare the signature of the Rust function in a header file that is included by 195/// `rust/bindings/bindings_helper.h`. 196/// 197/// This macro is *not* the same as the C macros `EXPORT_SYMBOL_*`. All Rust symbols are currently 198/// automatically exported with `EXPORT_SYMBOL_GPL`. 199#[proc_macro_attribute] 200pub fn export(attr: TokenStream, ts: TokenStream) -> TokenStream { 201 export::export(attr, ts) 202} 203 204/// Concatenate two identifiers. 205/// 206/// This is useful in macros that need to declare or reference items with names 207/// starting with a fixed prefix and ending in a user specified name. The resulting 208/// identifier has the span of the second argument. 209/// 210/// # Examples 211/// 212/// ``` 213/// # const binder_driver_return_protocol_BR_OK: u32 = 0; 214/// # const binder_driver_return_protocol_BR_ERROR: u32 = 1; 215/// # const binder_driver_return_protocol_BR_TRANSACTION: u32 = 2; 216/// # const binder_driver_return_protocol_BR_REPLY: u32 = 3; 217/// # const binder_driver_return_protocol_BR_DEAD_REPLY: u32 = 4; 218/// # const binder_driver_return_protocol_BR_TRANSACTION_COMPLETE: u32 = 5; 219/// # const binder_driver_return_protocol_BR_INCREFS: u32 = 6; 220/// # const binder_driver_return_protocol_BR_ACQUIRE: u32 = 7; 221/// # const binder_driver_return_protocol_BR_RELEASE: u32 = 8; 222/// # const binder_driver_return_protocol_BR_DECREFS: u32 = 9; 223/// # const binder_driver_return_protocol_BR_NOOP: u32 = 10; 224/// # const binder_driver_return_protocol_BR_SPAWN_LOOPER: u32 = 11; 225/// # const binder_driver_return_protocol_BR_DEAD_BINDER: u32 = 12; 226/// # const binder_driver_return_protocol_BR_CLEAR_DEATH_NOTIFICATION_DONE: u32 = 13; 227/// # const binder_driver_return_protocol_BR_FAILED_REPLY: u32 = 14; 228/// use kernel::macros::concat_idents; 229/// 230/// macro_rules! pub_no_prefix { 231/// ($prefix:ident, $($newname:ident),+) => { 232/// $(pub(crate) const $newname: u32 = concat_idents!($prefix, $newname);)+ 233/// }; 234/// } 235/// 236/// pub_no_prefix!( 237/// binder_driver_return_protocol_, 238/// BR_OK, 239/// BR_ERROR, 240/// BR_TRANSACTION, 241/// BR_REPLY, 242/// BR_DEAD_REPLY, 243/// BR_TRANSACTION_COMPLETE, 244/// BR_INCREFS, 245/// BR_ACQUIRE, 246/// BR_RELEASE, 247/// BR_DECREFS, 248/// BR_NOOP, 249/// BR_SPAWN_LOOPER, 250/// BR_DEAD_BINDER, 251/// BR_CLEAR_DEATH_NOTIFICATION_DONE, 252/// BR_FAILED_REPLY 253/// ); 254/// 255/// assert_eq!(BR_OK, binder_driver_return_protocol_BR_OK); 256/// ``` 257#[proc_macro] 258pub fn concat_idents(ts: TokenStream) -> TokenStream { 259 concat_idents::concat_idents(ts) 260} 261 262/// Paste identifiers together. 263/// 264/// Within the `paste!` macro, identifiers inside `[<` and `>]` are concatenated together to form a 265/// single identifier. 266/// 267/// This is similar to the [`paste`] crate, but with pasting feature limited to identifiers and 268/// literals (lifetimes and documentation strings are not supported). There is a difference in 269/// supported modifiers as well. 270/// 271/// # Examples 272/// 273/// ``` 274/// # const binder_driver_return_protocol_BR_OK: u32 = 0; 275/// # const binder_driver_return_protocol_BR_ERROR: u32 = 1; 276/// # const binder_driver_return_protocol_BR_TRANSACTION: u32 = 2; 277/// # const binder_driver_return_protocol_BR_REPLY: u32 = 3; 278/// # const binder_driver_return_protocol_BR_DEAD_REPLY: u32 = 4; 279/// # const binder_driver_return_protocol_BR_TRANSACTION_COMPLETE: u32 = 5; 280/// # const binder_driver_return_protocol_BR_INCREFS: u32 = 6; 281/// # const binder_driver_return_protocol_BR_ACQUIRE: u32 = 7; 282/// # const binder_driver_return_protocol_BR_RELEASE: u32 = 8; 283/// # const binder_driver_return_protocol_BR_DECREFS: u32 = 9; 284/// # const binder_driver_return_protocol_BR_NOOP: u32 = 10; 285/// # const binder_driver_return_protocol_BR_SPAWN_LOOPER: u32 = 11; 286/// # const binder_driver_return_protocol_BR_DEAD_BINDER: u32 = 12; 287/// # const binder_driver_return_protocol_BR_CLEAR_DEATH_NOTIFICATION_DONE: u32 = 13; 288/// # const binder_driver_return_protocol_BR_FAILED_REPLY: u32 = 14; 289/// macro_rules! pub_no_prefix { 290/// ($prefix:ident, $($newname:ident),+) => { 291/// ::kernel::macros::paste! { 292/// $(pub(crate) const $newname: u32 = [<$prefix $newname>];)+ 293/// } 294/// }; 295/// } 296/// 297/// pub_no_prefix!( 298/// binder_driver_return_protocol_, 299/// BR_OK, 300/// BR_ERROR, 301/// BR_TRANSACTION, 302/// BR_REPLY, 303/// BR_DEAD_REPLY, 304/// BR_TRANSACTION_COMPLETE, 305/// BR_INCREFS, 306/// BR_ACQUIRE, 307/// BR_RELEASE, 308/// BR_DECREFS, 309/// BR_NOOP, 310/// BR_SPAWN_LOOPER, 311/// BR_DEAD_BINDER, 312/// BR_CLEAR_DEATH_NOTIFICATION_DONE, 313/// BR_FAILED_REPLY 314/// ); 315/// 316/// assert_eq!(BR_OK, binder_driver_return_protocol_BR_OK); 317/// ``` 318/// 319/// # Modifiers 320/// 321/// For each identifier, it is possible to attach one or multiple modifiers to 322/// it. 323/// 324/// Currently supported modifiers are: 325/// * `span`: change the span of concatenated identifier to the span of the specified token. By 326/// default the span of the `[< >]` group is used. 327/// * `lower`: change the identifier to lower case. 328/// * `upper`: change the identifier to upper case. 329/// 330/// ``` 331/// # const binder_driver_return_protocol_BR_OK: u32 = 0; 332/// # const binder_driver_return_protocol_BR_ERROR: u32 = 1; 333/// # const binder_driver_return_protocol_BR_TRANSACTION: u32 = 2; 334/// # const binder_driver_return_protocol_BR_REPLY: u32 = 3; 335/// # const binder_driver_return_protocol_BR_DEAD_REPLY: u32 = 4; 336/// # const binder_driver_return_protocol_BR_TRANSACTION_COMPLETE: u32 = 5; 337/// # const binder_driver_return_protocol_BR_INCREFS: u32 = 6; 338/// # const binder_driver_return_protocol_BR_ACQUIRE: u32 = 7; 339/// # const binder_driver_return_protocol_BR_RELEASE: u32 = 8; 340/// # const binder_driver_return_protocol_BR_DECREFS: u32 = 9; 341/// # const binder_driver_return_protocol_BR_NOOP: u32 = 10; 342/// # const binder_driver_return_protocol_BR_SPAWN_LOOPER: u32 = 11; 343/// # const binder_driver_return_protocol_BR_DEAD_BINDER: u32 = 12; 344/// # const binder_driver_return_protocol_BR_CLEAR_DEATH_NOTIFICATION_DONE: u32 = 13; 345/// # const binder_driver_return_protocol_BR_FAILED_REPLY: u32 = 14; 346/// macro_rules! pub_no_prefix { 347/// ($prefix:ident, $($newname:ident),+) => { 348/// ::kernel::macros::paste! { 349/// $(pub(crate) const fn [<$newname:lower:span>]() -> u32 { [<$prefix $newname:span>] })+ 350/// } 351/// }; 352/// } 353/// 354/// pub_no_prefix!( 355/// binder_driver_return_protocol_, 356/// BR_OK, 357/// BR_ERROR, 358/// BR_TRANSACTION, 359/// BR_REPLY, 360/// BR_DEAD_REPLY, 361/// BR_TRANSACTION_COMPLETE, 362/// BR_INCREFS, 363/// BR_ACQUIRE, 364/// BR_RELEASE, 365/// BR_DECREFS, 366/// BR_NOOP, 367/// BR_SPAWN_LOOPER, 368/// BR_DEAD_BINDER, 369/// BR_CLEAR_DEATH_NOTIFICATION_DONE, 370/// BR_FAILED_REPLY 371/// ); 372/// 373/// assert_eq!(br_ok(), binder_driver_return_protocol_BR_OK); 374/// ``` 375/// 376/// # Literals 377/// 378/// Literals can also be concatenated with other identifiers: 379/// 380/// ``` 381/// macro_rules! create_numbered_fn { 382/// ($name:literal, $val:literal) => { 383/// ::kernel::macros::paste! { 384/// fn [<some_ $name _fn $val>]() -> u32 { $val } 385/// } 386/// }; 387/// } 388/// 389/// create_numbered_fn!("foo", 100); 390/// 391/// assert_eq!(some_foo_fn100(), 100) 392/// ``` 393/// 394/// [`paste`]: https://docs.rs/paste/ 395#[proc_macro] 396pub fn paste(input: TokenStream) -> TokenStream { 397 let mut tokens = input.into_iter().collect(); 398 paste::expand(&mut tokens); 399 tokens.into_iter().collect() 400} 401 402/// Registers a KUnit test suite and its test cases using a user-space like syntax. 403/// 404/// This macro should be used on modules. If `CONFIG_KUNIT` (in `.config`) is `n`, the target module 405/// is ignored. 406/// 407/// # Examples 408/// 409/// ```ignore 410/// # use kernel::prelude::*; 411/// #[kunit_tests(kunit_test_suit_name)] 412/// mod tests { 413/// #[test] 414/// fn foo() { 415/// assert_eq!(1, 1); 416/// } 417/// 418/// #[test] 419/// fn bar() { 420/// assert_eq!(2, 2); 421/// } 422/// } 423/// ``` 424#[proc_macro_attribute] 425pub fn kunit_tests(attr: TokenStream, ts: TokenStream) -> TokenStream { 426 kunit::kunit_tests(attr, ts) 427}