at v6.2 4.9 kB view raw
1// SPDX-License-Identifier: GPL-2.0 2 3//! Crate for all kernel procedural macros. 4 5mod concat_idents; 6mod helpers; 7mod module; 8mod vtable; 9 10use proc_macro::TokenStream; 11 12/// Declares a kernel module. 13/// 14/// The `type` argument should be a type which implements the [`Module`] 15/// trait. Also accepts various forms of kernel metadata. 16/// 17/// C header: [`include/linux/moduleparam.h`](../../../include/linux/moduleparam.h) 18/// 19/// [`Module`]: ../kernel/trait.Module.html 20/// 21/// # Examples 22/// 23/// ```ignore 24/// use kernel::prelude::*; 25/// 26/// module!{ 27/// type: MyModule, 28/// name: "my_kernel_module", 29/// author: "Rust for Linux Contributors", 30/// description: "My very own kernel module!", 31/// license: "GPL", 32/// params: { 33/// my_i32: i32 { 34/// default: 42, 35/// permissions: 0o000, 36/// description: "Example of i32", 37/// }, 38/// writeable_i32: i32 { 39/// default: 42, 40/// permissions: 0o644, 41/// description: "Example of i32", 42/// }, 43/// }, 44/// } 45/// 46/// struct MyModule; 47/// 48/// impl kernel::Module for MyModule { 49/// fn init() -> Result<Self> { 50/// // If the parameter is writeable, then the kparam lock must be 51/// // taken to read the parameter: 52/// { 53/// let lock = THIS_MODULE.kernel_param_lock(); 54/// pr_info!("i32 param is: {}\n", writeable_i32.read(&lock)); 55/// } 56/// // If the parameter is read only, it can be read without locking 57/// // the kernel parameters: 58/// pr_info!("i32 param is: {}\n", my_i32.read()); 59/// Ok(Self) 60/// } 61/// } 62/// ``` 63/// 64/// # Supported argument types 65/// - `type`: type which implements the [`Module`] trait (required). 66/// - `name`: byte array of the name of the kernel module (required). 67/// - `author`: byte array of the author of the kernel module. 68/// - `description`: byte array of the description of the kernel module. 69/// - `license`: byte array of the license of the kernel module (required). 70/// - `alias`: byte array of alias name of the kernel module. 71#[proc_macro] 72pub fn module(ts: TokenStream) -> TokenStream { 73 module::module(ts) 74} 75 76/// Declares or implements a vtable trait. 77/// 78/// Linux's use of pure vtables is very close to Rust traits, but they differ 79/// in how unimplemented functions are represented. In Rust, traits can provide 80/// default implementation for all non-required methods (and the default 81/// implementation could just return `Error::EINVAL`); Linux typically use C 82/// `NULL` pointers to represent these functions. 83/// 84/// This attribute is intended to close the gap. Traits can be declared and 85/// implemented with the `#[vtable]` attribute, and a `HAS_*` associated constant 86/// will be generated for each method in the trait, indicating if the implementor 87/// has overridden a method. 88/// 89/// This attribute is not needed if all methods are required. 90/// 91/// # Examples 92/// 93/// ```ignore 94/// use kernel::prelude::*; 95/// 96/// // Declares a `#[vtable]` trait 97/// #[vtable] 98/// pub trait Operations: Send + Sync + Sized { 99/// fn foo(&self) -> Result<()> { 100/// Err(EINVAL) 101/// } 102/// 103/// fn bar(&self) -> Result<()> { 104/// Err(EINVAL) 105/// } 106/// } 107/// 108/// struct Foo; 109/// 110/// // Implements the `#[vtable]` trait 111/// #[vtable] 112/// impl Operations for Foo { 113/// fn foo(&self) -> Result<()> { 114/// # Err(EINVAL) 115/// // ... 116/// } 117/// } 118/// 119/// assert_eq!(<Foo as Operations>::HAS_FOO, true); 120/// assert_eq!(<Foo as Operations>::HAS_BAR, false); 121/// ``` 122#[proc_macro_attribute] 123pub fn vtable(attr: TokenStream, ts: TokenStream) -> TokenStream { 124 vtable::vtable(attr, ts) 125} 126 127/// Concatenate two identifiers. 128/// 129/// This is useful in macros that need to declare or reference items with names 130/// starting with a fixed prefix and ending in a user specified name. The resulting 131/// identifier has the span of the second argument. 132/// 133/// # Examples 134/// 135/// ```ignore 136/// use kernel::macro::concat_idents; 137/// 138/// macro_rules! pub_no_prefix { 139/// ($prefix:ident, $($newname:ident),+) => { 140/// $(pub(crate) const $newname: u32 = kernel::macros::concat_idents!($prefix, $newname);)+ 141/// }; 142/// } 143/// 144/// pub_no_prefix!( 145/// binder_driver_return_protocol_, 146/// BR_OK, 147/// BR_ERROR, 148/// BR_TRANSACTION, 149/// BR_REPLY, 150/// BR_DEAD_REPLY, 151/// BR_TRANSACTION_COMPLETE, 152/// BR_INCREFS, 153/// BR_ACQUIRE, 154/// BR_RELEASE, 155/// BR_DECREFS, 156/// BR_NOOP, 157/// BR_SPAWN_LOOPER, 158/// BR_DEAD_BINDER, 159/// BR_CLEAR_DEATH_NOTIFICATION_DONE, 160/// BR_FAILED_REPLY 161/// ); 162/// 163/// assert_eq!(BR_OK, binder_driver_return_protocol_BR_OK); 164/// ``` 165#[proc_macro] 166pub fn concat_idents(ts: TokenStream) -> TokenStream { 167 concat_idents::concat_idents(ts) 168}