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