at v6.8-rc4 12 kB view raw
1// SPDX-License-Identifier: GPL-2.0 2 3//! Crate for all kernel procedural macros. 4 5#[macro_use] 6mod quote; 7mod concat_idents; 8mod helpers; 9mod module; 10mod paste; 11mod pin_data; 12mod pinned_drop; 13mod vtable; 14mod zeroable; 15 16use proc_macro::TokenStream; 17 18/// Declares a kernel module. 19/// 20/// The `type` argument should be a type which implements the [`Module`] 21/// trait. Also accepts various forms of kernel metadata. 22/// 23/// C header: [`include/linux/moduleparam.h`](srctree/include/linux/moduleparam.h) 24/// 25/// [`Module`]: ../kernel/trait.Module.html 26/// 27/// # Examples 28/// 29/// ```ignore 30/// use kernel::prelude::*; 31/// 32/// module!{ 33/// type: MyModule, 34/// name: "my_kernel_module", 35/// author: "Rust for Linux Contributors", 36/// description: "My very own kernel module!", 37/// license: "GPL", 38/// params: { 39/// my_i32: i32 { 40/// default: 42, 41/// permissions: 0o000, 42/// description: "Example of i32", 43/// }, 44/// writeable_i32: i32 { 45/// default: 42, 46/// permissions: 0o644, 47/// description: "Example of i32", 48/// }, 49/// }, 50/// } 51/// 52/// struct MyModule; 53/// 54/// impl kernel::Module for MyModule { 55/// fn init() -> Result<Self> { 56/// // If the parameter is writeable, then the kparam lock must be 57/// // taken to read the parameter: 58/// { 59/// let lock = THIS_MODULE.kernel_param_lock(); 60/// pr_info!("i32 param is: {}\n", writeable_i32.read(&lock)); 61/// } 62/// // If the parameter is read only, it can be read without locking 63/// // the kernel parameters: 64/// pr_info!("i32 param is: {}\n", my_i32.read()); 65/// Ok(Self) 66/// } 67/// } 68/// ``` 69/// 70/// # Supported argument types 71/// - `type`: type which implements the [`Module`] trait (required). 72/// - `name`: byte array of the name of the kernel module (required). 73/// - `author`: byte array of the author of the kernel module. 74/// - `description`: byte array of the description of the kernel module. 75/// - `license`: byte array of the license of the kernel module (required). 76/// - `alias`: byte array of alias name of the kernel module. 77#[proc_macro] 78pub fn module(ts: TokenStream) -> TokenStream { 79 module::module(ts) 80} 81 82/// Declares or implements a vtable trait. 83/// 84/// Linux's use of pure vtables is very close to Rust traits, but they differ 85/// in how unimplemented functions are represented. In Rust, traits can provide 86/// default implementation for all non-required methods (and the default 87/// implementation could just return `Error::EINVAL`); Linux typically use C 88/// `NULL` pointers to represent these functions. 89/// 90/// This attribute closes that gap. A trait can be annotated with the 91/// `#[vtable]` attribute. Implementers of the trait will then also have to 92/// annotate the trait with `#[vtable]`. This attribute generates a `HAS_*` 93/// associated constant bool for each method in the trait that is set to true if 94/// the implementer has overridden the associated method. 95/// 96/// For a trait method to be optional, it must have a default implementation. 97/// This is also the case for traits annotated with `#[vtable]`, but in this 98/// case the default implementation will never be executed. The reason for this 99/// is that the functions will be called through function pointers installed in 100/// C side vtables. When an optional method is not implemented on a `#[vtable]` 101/// trait, a NULL entry is installed in the vtable. Thus the default 102/// implementation is never called. Since these traits are not designed to be 103/// used on the Rust side, it should not be possible to call the default 104/// implementation. This is done to ensure that we call the vtable methods 105/// through the C vtable, and not through the Rust vtable. Therefore, the 106/// default implementation should call `kernel::build_error`, which prevents 107/// calls to this function at compile time: 108/// 109/// ```compile_fail 110/// # use kernel::error::VTABLE_DEFAULT_ERROR; 111/// kernel::build_error(VTABLE_DEFAULT_ERROR) 112/// ``` 113/// 114/// Note that you might need to import [`kernel::error::VTABLE_DEFAULT_ERROR`]. 115/// 116/// This macro should not be used when all functions are required. 117/// 118/// # Examples 119/// 120/// ```ignore 121/// use kernel::error::VTABLE_DEFAULT_ERROR; 122/// use kernel::prelude::*; 123/// 124/// // Declares a `#[vtable]` trait 125/// #[vtable] 126/// pub trait Operations: Send + Sync + Sized { 127/// fn foo(&self) -> Result<()> { 128/// kernel::build_error(VTABLE_DEFAULT_ERROR) 129/// } 130/// 131/// fn bar(&self) -> Result<()> { 132/// kernel::build_error(VTABLE_DEFAULT_ERROR) 133/// } 134/// } 135/// 136/// struct Foo; 137/// 138/// // Implements the `#[vtable]` trait 139/// #[vtable] 140/// impl Operations for Foo { 141/// fn foo(&self) -> Result<()> { 142/// # Err(EINVAL) 143/// // ... 144/// } 145/// } 146/// 147/// assert_eq!(<Foo as Operations>::HAS_FOO, true); 148/// assert_eq!(<Foo as Operations>::HAS_BAR, false); 149/// ``` 150/// 151/// [`kernel::error::VTABLE_DEFAULT_ERROR`]: ../kernel/error/constant.VTABLE_DEFAULT_ERROR.html 152#[proc_macro_attribute] 153pub fn vtable(attr: TokenStream, ts: TokenStream) -> TokenStream { 154 vtable::vtable(attr, ts) 155} 156 157/// Concatenate two identifiers. 158/// 159/// This is useful in macros that need to declare or reference items with names 160/// starting with a fixed prefix and ending in a user specified name. The resulting 161/// identifier has the span of the second argument. 162/// 163/// # Examples 164/// 165/// ```ignore 166/// use kernel::macro::concat_idents; 167/// 168/// macro_rules! pub_no_prefix { 169/// ($prefix:ident, $($newname:ident),+) => { 170/// $(pub(crate) const $newname: u32 = kernel::macros::concat_idents!($prefix, $newname);)+ 171/// }; 172/// } 173/// 174/// pub_no_prefix!( 175/// binder_driver_return_protocol_, 176/// BR_OK, 177/// BR_ERROR, 178/// BR_TRANSACTION, 179/// BR_REPLY, 180/// BR_DEAD_REPLY, 181/// BR_TRANSACTION_COMPLETE, 182/// BR_INCREFS, 183/// BR_ACQUIRE, 184/// BR_RELEASE, 185/// BR_DECREFS, 186/// BR_NOOP, 187/// BR_SPAWN_LOOPER, 188/// BR_DEAD_BINDER, 189/// BR_CLEAR_DEATH_NOTIFICATION_DONE, 190/// BR_FAILED_REPLY 191/// ); 192/// 193/// assert_eq!(BR_OK, binder_driver_return_protocol_BR_OK); 194/// ``` 195#[proc_macro] 196pub fn concat_idents(ts: TokenStream) -> TokenStream { 197 concat_idents::concat_idents(ts) 198} 199 200/// Used to specify the pinning information of the fields of a struct. 201/// 202/// This is somewhat similar in purpose as 203/// [pin-project-lite](https://crates.io/crates/pin-project-lite). 204/// Place this macro on a struct definition and then `#[pin]` in front of the attributes of each 205/// field you want to structurally pin. 206/// 207/// This macro enables the use of the [`pin_init!`] macro. When pin-initializing a `struct`, 208/// then `#[pin]` directs the type of initializer that is required. 209/// 210/// If your `struct` implements `Drop`, then you need to add `PinnedDrop` as arguments to this 211/// macro, and change your `Drop` implementation to `PinnedDrop` annotated with 212/// `#[`[`macro@pinned_drop`]`]`, since dropping pinned values requires extra care. 213/// 214/// # Examples 215/// 216/// ```rust,ignore 217/// #[pin_data] 218/// struct DriverData { 219/// #[pin] 220/// queue: Mutex<Vec<Command>>, 221/// buf: Box<[u8; 1024 * 1024]>, 222/// } 223/// ``` 224/// 225/// ```rust,ignore 226/// #[pin_data(PinnedDrop)] 227/// struct DriverData { 228/// #[pin] 229/// queue: Mutex<Vec<Command>>, 230/// buf: Box<[u8; 1024 * 1024]>, 231/// raw_info: *mut Info, 232/// } 233/// 234/// #[pinned_drop] 235/// impl PinnedDrop for DriverData { 236/// fn drop(self: Pin<&mut Self>) { 237/// unsafe { bindings::destroy_info(self.raw_info) }; 238/// } 239/// } 240/// ``` 241/// 242/// [`pin_init!`]: ../kernel/macro.pin_init.html 243// ^ cannot use direct link, since `kernel` is not a dependency of `macros`. 244#[proc_macro_attribute] 245pub fn pin_data(inner: TokenStream, item: TokenStream) -> TokenStream { 246 pin_data::pin_data(inner, item) 247} 248 249/// Used to implement `PinnedDrop` safely. 250/// 251/// Only works on structs that are annotated via `#[`[`macro@pin_data`]`]`. 252/// 253/// # Examples 254/// 255/// ```rust,ignore 256/// #[pin_data(PinnedDrop)] 257/// struct DriverData { 258/// #[pin] 259/// queue: Mutex<Vec<Command>>, 260/// buf: Box<[u8; 1024 * 1024]>, 261/// raw_info: *mut Info, 262/// } 263/// 264/// #[pinned_drop] 265/// impl PinnedDrop for DriverData { 266/// fn drop(self: Pin<&mut Self>) { 267/// unsafe { bindings::destroy_info(self.raw_info) }; 268/// } 269/// } 270/// ``` 271#[proc_macro_attribute] 272pub fn pinned_drop(args: TokenStream, input: TokenStream) -> TokenStream { 273 pinned_drop::pinned_drop(args, input) 274} 275 276/// Paste identifiers together. 277/// 278/// Within the `paste!` macro, identifiers inside `[<` and `>]` are concatenated together to form a 279/// single identifier. 280/// 281/// This is similar to the [`paste`] crate, but with pasting feature limited to identifiers and 282/// literals (lifetimes and documentation strings are not supported). There is a difference in 283/// supported modifiers as well. 284/// 285/// # Example 286/// 287/// ```ignore 288/// use kernel::macro::paste; 289/// 290/// macro_rules! pub_no_prefix { 291/// ($prefix:ident, $($newname:ident),+) => { 292/// paste! { 293/// $(pub(crate) const $newname: u32 = [<$prefix $newname>];)+ 294/// } 295/// }; 296/// } 297/// 298/// pub_no_prefix!( 299/// binder_driver_return_protocol_, 300/// BR_OK, 301/// BR_ERROR, 302/// BR_TRANSACTION, 303/// BR_REPLY, 304/// BR_DEAD_REPLY, 305/// BR_TRANSACTION_COMPLETE, 306/// BR_INCREFS, 307/// BR_ACQUIRE, 308/// BR_RELEASE, 309/// BR_DECREFS, 310/// BR_NOOP, 311/// BR_SPAWN_LOOPER, 312/// BR_DEAD_BINDER, 313/// BR_CLEAR_DEATH_NOTIFICATION_DONE, 314/// BR_FAILED_REPLY 315/// ); 316/// 317/// assert_eq!(BR_OK, binder_driver_return_protocol_BR_OK); 318/// ``` 319/// 320/// # Modifiers 321/// 322/// For each identifier, it is possible to attach one or multiple modifiers to 323/// it. 324/// 325/// Currently supported modifiers are: 326/// * `span`: change the span of concatenated identifier to the span of the specified token. By 327/// default the span of the `[< >]` group is used. 328/// * `lower`: change the identifier to lower case. 329/// * `upper`: change the identifier to upper case. 330/// 331/// ```ignore 332/// use kernel::macro::paste; 333/// 334/// macro_rules! pub_no_prefix { 335/// ($prefix:ident, $($newname:ident),+) => { 336/// kernel::macros::paste! { 337/// $(pub(crate) const fn [<$newname:lower:span>]: u32 = [<$prefix $newname:span>];)+ 338/// } 339/// }; 340/// } 341/// 342/// pub_no_prefix!( 343/// binder_driver_return_protocol_, 344/// BR_OK, 345/// BR_ERROR, 346/// BR_TRANSACTION, 347/// BR_REPLY, 348/// BR_DEAD_REPLY, 349/// BR_TRANSACTION_COMPLETE, 350/// BR_INCREFS, 351/// BR_ACQUIRE, 352/// BR_RELEASE, 353/// BR_DECREFS, 354/// BR_NOOP, 355/// BR_SPAWN_LOOPER, 356/// BR_DEAD_BINDER, 357/// BR_CLEAR_DEATH_NOTIFICATION_DONE, 358/// BR_FAILED_REPLY 359/// ); 360/// 361/// assert_eq!(br_ok(), binder_driver_return_protocol_BR_OK); 362/// ``` 363/// 364/// # Literals 365/// 366/// Literals can also be concatenated with other identifiers: 367/// 368/// ```ignore 369/// macro_rules! create_numbered_fn { 370/// ($name:literal, $val:literal) => { 371/// kernel::macros::paste! { 372/// fn [<some_ $name _fn $val>]() -> u32 { $val } 373/// } 374/// }; 375/// } 376/// 377/// create_numbered_fn!("foo", 100); 378/// 379/// assert_eq!(some_foo_fn100(), 100) 380/// ``` 381/// 382/// [`paste`]: https://docs.rs/paste/ 383#[proc_macro] 384pub fn paste(input: TokenStream) -> TokenStream { 385 let mut tokens = input.into_iter().collect(); 386 paste::expand(&mut tokens); 387 tokens.into_iter().collect() 388} 389 390/// Derives the [`Zeroable`] trait for the given struct. 391/// 392/// This can only be used for structs where every field implements the [`Zeroable`] trait. 393/// 394/// # Examples 395/// 396/// ```rust,ignore 397/// #[derive(Zeroable)] 398/// pub struct DriverData { 399/// id: i64, 400/// buf_ptr: *mut u8, 401/// len: usize, 402/// } 403/// ``` 404#[proc_macro_derive(Zeroable)] 405pub fn derive_zeroable(input: TokenStream) -> TokenStream { 406 zeroable::derive(input) 407}