162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci 362306a36Sopenharmony_ci//! Crate for all kernel procedural macros. 462306a36Sopenharmony_ci 562306a36Sopenharmony_ci#[macro_use] 662306a36Sopenharmony_cimod quote; 762306a36Sopenharmony_cimod concat_idents; 862306a36Sopenharmony_cimod helpers; 962306a36Sopenharmony_cimod module; 1062306a36Sopenharmony_cimod paste; 1162306a36Sopenharmony_cimod pin_data; 1262306a36Sopenharmony_cimod pinned_drop; 1362306a36Sopenharmony_cimod vtable; 1462306a36Sopenharmony_cimod zeroable; 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_ciuse proc_macro::TokenStream; 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_ci/// Declares a kernel module. 1962306a36Sopenharmony_ci/// 2062306a36Sopenharmony_ci/// The `type` argument should be a type which implements the [`Module`] 2162306a36Sopenharmony_ci/// trait. Also accepts various forms of kernel metadata. 2262306a36Sopenharmony_ci/// 2362306a36Sopenharmony_ci/// C header: [`include/linux/moduleparam.h`](../../../include/linux/moduleparam.h) 2462306a36Sopenharmony_ci/// 2562306a36Sopenharmony_ci/// [`Module`]: ../kernel/trait.Module.html 2662306a36Sopenharmony_ci/// 2762306a36Sopenharmony_ci/// # Examples 2862306a36Sopenharmony_ci/// 2962306a36Sopenharmony_ci/// ```ignore 3062306a36Sopenharmony_ci/// use kernel::prelude::*; 3162306a36Sopenharmony_ci/// 3262306a36Sopenharmony_ci/// module!{ 3362306a36Sopenharmony_ci/// type: MyModule, 3462306a36Sopenharmony_ci/// name: "my_kernel_module", 3562306a36Sopenharmony_ci/// author: "Rust for Linux Contributors", 3662306a36Sopenharmony_ci/// description: "My very own kernel module!", 3762306a36Sopenharmony_ci/// license: "GPL", 3862306a36Sopenharmony_ci/// params: { 3962306a36Sopenharmony_ci/// my_i32: i32 { 4062306a36Sopenharmony_ci/// default: 42, 4162306a36Sopenharmony_ci/// permissions: 0o000, 4262306a36Sopenharmony_ci/// description: "Example of i32", 4362306a36Sopenharmony_ci/// }, 4462306a36Sopenharmony_ci/// writeable_i32: i32 { 4562306a36Sopenharmony_ci/// default: 42, 4662306a36Sopenharmony_ci/// permissions: 0o644, 4762306a36Sopenharmony_ci/// description: "Example of i32", 4862306a36Sopenharmony_ci/// }, 4962306a36Sopenharmony_ci/// }, 5062306a36Sopenharmony_ci/// } 5162306a36Sopenharmony_ci/// 5262306a36Sopenharmony_ci/// struct MyModule; 5362306a36Sopenharmony_ci/// 5462306a36Sopenharmony_ci/// impl kernel::Module for MyModule { 5562306a36Sopenharmony_ci/// fn init() -> Result<Self> { 5662306a36Sopenharmony_ci/// // If the parameter is writeable, then the kparam lock must be 5762306a36Sopenharmony_ci/// // taken to read the parameter: 5862306a36Sopenharmony_ci/// { 5962306a36Sopenharmony_ci/// let lock = THIS_MODULE.kernel_param_lock(); 6062306a36Sopenharmony_ci/// pr_info!("i32 param is: {}\n", writeable_i32.read(&lock)); 6162306a36Sopenharmony_ci/// } 6262306a36Sopenharmony_ci/// // If the parameter is read only, it can be read without locking 6362306a36Sopenharmony_ci/// // the kernel parameters: 6462306a36Sopenharmony_ci/// pr_info!("i32 param is: {}\n", my_i32.read()); 6562306a36Sopenharmony_ci/// Ok(Self) 6662306a36Sopenharmony_ci/// } 6762306a36Sopenharmony_ci/// } 6862306a36Sopenharmony_ci/// ``` 6962306a36Sopenharmony_ci/// 7062306a36Sopenharmony_ci/// # Supported argument types 7162306a36Sopenharmony_ci/// - `type`: type which implements the [`Module`] trait (required). 7262306a36Sopenharmony_ci/// - `name`: byte array of the name of the kernel module (required). 7362306a36Sopenharmony_ci/// - `author`: byte array of the author of the kernel module. 7462306a36Sopenharmony_ci/// - `description`: byte array of the description of the kernel module. 7562306a36Sopenharmony_ci/// - `license`: byte array of the license of the kernel module (required). 7662306a36Sopenharmony_ci/// - `alias`: byte array of alias name of the kernel module. 7762306a36Sopenharmony_ci#[proc_macro] 7862306a36Sopenharmony_cipub fn module(ts: TokenStream) -> TokenStream { 7962306a36Sopenharmony_ci module::module(ts) 8062306a36Sopenharmony_ci} 8162306a36Sopenharmony_ci 8262306a36Sopenharmony_ci/// Declares or implements a vtable trait. 8362306a36Sopenharmony_ci/// 8462306a36Sopenharmony_ci/// Linux's use of pure vtables is very close to Rust traits, but they differ 8562306a36Sopenharmony_ci/// in how unimplemented functions are represented. In Rust, traits can provide 8662306a36Sopenharmony_ci/// default implementation for all non-required methods (and the default 8762306a36Sopenharmony_ci/// implementation could just return `Error::EINVAL`); Linux typically use C 8862306a36Sopenharmony_ci/// `NULL` pointers to represent these functions. 8962306a36Sopenharmony_ci/// 9062306a36Sopenharmony_ci/// This attribute is intended to close the gap. Traits can be declared and 9162306a36Sopenharmony_ci/// implemented with the `#[vtable]` attribute, and a `HAS_*` associated constant 9262306a36Sopenharmony_ci/// will be generated for each method in the trait, indicating if the implementor 9362306a36Sopenharmony_ci/// has overridden a method. 9462306a36Sopenharmony_ci/// 9562306a36Sopenharmony_ci/// This attribute is not needed if all methods are required. 9662306a36Sopenharmony_ci/// 9762306a36Sopenharmony_ci/// # Examples 9862306a36Sopenharmony_ci/// 9962306a36Sopenharmony_ci/// ```ignore 10062306a36Sopenharmony_ci/// use kernel::prelude::*; 10162306a36Sopenharmony_ci/// 10262306a36Sopenharmony_ci/// // Declares a `#[vtable]` trait 10362306a36Sopenharmony_ci/// #[vtable] 10462306a36Sopenharmony_ci/// pub trait Operations: Send + Sync + Sized { 10562306a36Sopenharmony_ci/// fn foo(&self) -> Result<()> { 10662306a36Sopenharmony_ci/// Err(EINVAL) 10762306a36Sopenharmony_ci/// } 10862306a36Sopenharmony_ci/// 10962306a36Sopenharmony_ci/// fn bar(&self) -> Result<()> { 11062306a36Sopenharmony_ci/// Err(EINVAL) 11162306a36Sopenharmony_ci/// } 11262306a36Sopenharmony_ci/// } 11362306a36Sopenharmony_ci/// 11462306a36Sopenharmony_ci/// struct Foo; 11562306a36Sopenharmony_ci/// 11662306a36Sopenharmony_ci/// // Implements the `#[vtable]` trait 11762306a36Sopenharmony_ci/// #[vtable] 11862306a36Sopenharmony_ci/// impl Operations for Foo { 11962306a36Sopenharmony_ci/// fn foo(&self) -> Result<()> { 12062306a36Sopenharmony_ci/// # Err(EINVAL) 12162306a36Sopenharmony_ci/// // ... 12262306a36Sopenharmony_ci/// } 12362306a36Sopenharmony_ci/// } 12462306a36Sopenharmony_ci/// 12562306a36Sopenharmony_ci/// assert_eq!(<Foo as Operations>::HAS_FOO, true); 12662306a36Sopenharmony_ci/// assert_eq!(<Foo as Operations>::HAS_BAR, false); 12762306a36Sopenharmony_ci/// ``` 12862306a36Sopenharmony_ci#[proc_macro_attribute] 12962306a36Sopenharmony_cipub fn vtable(attr: TokenStream, ts: TokenStream) -> TokenStream { 13062306a36Sopenharmony_ci vtable::vtable(attr, ts) 13162306a36Sopenharmony_ci} 13262306a36Sopenharmony_ci 13362306a36Sopenharmony_ci/// Concatenate two identifiers. 13462306a36Sopenharmony_ci/// 13562306a36Sopenharmony_ci/// This is useful in macros that need to declare or reference items with names 13662306a36Sopenharmony_ci/// starting with a fixed prefix and ending in a user specified name. The resulting 13762306a36Sopenharmony_ci/// identifier has the span of the second argument. 13862306a36Sopenharmony_ci/// 13962306a36Sopenharmony_ci/// # Examples 14062306a36Sopenharmony_ci/// 14162306a36Sopenharmony_ci/// ```ignore 14262306a36Sopenharmony_ci/// use kernel::macro::concat_idents; 14362306a36Sopenharmony_ci/// 14462306a36Sopenharmony_ci/// macro_rules! pub_no_prefix { 14562306a36Sopenharmony_ci/// ($prefix:ident, $($newname:ident),+) => { 14662306a36Sopenharmony_ci/// $(pub(crate) const $newname: u32 = kernel::macros::concat_idents!($prefix, $newname);)+ 14762306a36Sopenharmony_ci/// }; 14862306a36Sopenharmony_ci/// } 14962306a36Sopenharmony_ci/// 15062306a36Sopenharmony_ci/// pub_no_prefix!( 15162306a36Sopenharmony_ci/// binder_driver_return_protocol_, 15262306a36Sopenharmony_ci/// BR_OK, 15362306a36Sopenharmony_ci/// BR_ERROR, 15462306a36Sopenharmony_ci/// BR_TRANSACTION, 15562306a36Sopenharmony_ci/// BR_REPLY, 15662306a36Sopenharmony_ci/// BR_DEAD_REPLY, 15762306a36Sopenharmony_ci/// BR_TRANSACTION_COMPLETE, 15862306a36Sopenharmony_ci/// BR_INCREFS, 15962306a36Sopenharmony_ci/// BR_ACQUIRE, 16062306a36Sopenharmony_ci/// BR_RELEASE, 16162306a36Sopenharmony_ci/// BR_DECREFS, 16262306a36Sopenharmony_ci/// BR_NOOP, 16362306a36Sopenharmony_ci/// BR_SPAWN_LOOPER, 16462306a36Sopenharmony_ci/// BR_DEAD_BINDER, 16562306a36Sopenharmony_ci/// BR_CLEAR_DEATH_NOTIFICATION_DONE, 16662306a36Sopenharmony_ci/// BR_FAILED_REPLY 16762306a36Sopenharmony_ci/// ); 16862306a36Sopenharmony_ci/// 16962306a36Sopenharmony_ci/// assert_eq!(BR_OK, binder_driver_return_protocol_BR_OK); 17062306a36Sopenharmony_ci/// ``` 17162306a36Sopenharmony_ci#[proc_macro] 17262306a36Sopenharmony_cipub fn concat_idents(ts: TokenStream) -> TokenStream { 17362306a36Sopenharmony_ci concat_idents::concat_idents(ts) 17462306a36Sopenharmony_ci} 17562306a36Sopenharmony_ci 17662306a36Sopenharmony_ci/// Used to specify the pinning information of the fields of a struct. 17762306a36Sopenharmony_ci/// 17862306a36Sopenharmony_ci/// This is somewhat similar in purpose as 17962306a36Sopenharmony_ci/// [pin-project-lite](https://crates.io/crates/pin-project-lite). 18062306a36Sopenharmony_ci/// Place this macro on a struct definition and then `#[pin]` in front of the attributes of each 18162306a36Sopenharmony_ci/// field you want to structurally pin. 18262306a36Sopenharmony_ci/// 18362306a36Sopenharmony_ci/// This macro enables the use of the [`pin_init!`] macro. When pin-initializing a `struct`, 18462306a36Sopenharmony_ci/// then `#[pin]` directs the type of initializer that is required. 18562306a36Sopenharmony_ci/// 18662306a36Sopenharmony_ci/// If your `struct` implements `Drop`, then you need to add `PinnedDrop` as arguments to this 18762306a36Sopenharmony_ci/// macro, and change your `Drop` implementation to `PinnedDrop` annotated with 18862306a36Sopenharmony_ci/// `#[`[`macro@pinned_drop`]`]`, since dropping pinned values requires extra care. 18962306a36Sopenharmony_ci/// 19062306a36Sopenharmony_ci/// # Examples 19162306a36Sopenharmony_ci/// 19262306a36Sopenharmony_ci/// ```rust,ignore 19362306a36Sopenharmony_ci/// #[pin_data] 19462306a36Sopenharmony_ci/// struct DriverData { 19562306a36Sopenharmony_ci/// #[pin] 19662306a36Sopenharmony_ci/// queue: Mutex<Vec<Command>>, 19762306a36Sopenharmony_ci/// buf: Box<[u8; 1024 * 1024]>, 19862306a36Sopenharmony_ci/// } 19962306a36Sopenharmony_ci/// ``` 20062306a36Sopenharmony_ci/// 20162306a36Sopenharmony_ci/// ```rust,ignore 20262306a36Sopenharmony_ci/// #[pin_data(PinnedDrop)] 20362306a36Sopenharmony_ci/// struct DriverData { 20462306a36Sopenharmony_ci/// #[pin] 20562306a36Sopenharmony_ci/// queue: Mutex<Vec<Command>>, 20662306a36Sopenharmony_ci/// buf: Box<[u8; 1024 * 1024]>, 20762306a36Sopenharmony_ci/// raw_info: *mut Info, 20862306a36Sopenharmony_ci/// } 20962306a36Sopenharmony_ci/// 21062306a36Sopenharmony_ci/// #[pinned_drop] 21162306a36Sopenharmony_ci/// impl PinnedDrop for DriverData { 21262306a36Sopenharmony_ci/// fn drop(self: Pin<&mut Self>) { 21362306a36Sopenharmony_ci/// unsafe { bindings::destroy_info(self.raw_info) }; 21462306a36Sopenharmony_ci/// } 21562306a36Sopenharmony_ci/// } 21662306a36Sopenharmony_ci/// ``` 21762306a36Sopenharmony_ci/// 21862306a36Sopenharmony_ci/// [`pin_init!`]: ../kernel/macro.pin_init.html 21962306a36Sopenharmony_ci// ^ cannot use direct link, since `kernel` is not a dependency of `macros`. 22062306a36Sopenharmony_ci#[proc_macro_attribute] 22162306a36Sopenharmony_cipub fn pin_data(inner: TokenStream, item: TokenStream) -> TokenStream { 22262306a36Sopenharmony_ci pin_data::pin_data(inner, item) 22362306a36Sopenharmony_ci} 22462306a36Sopenharmony_ci 22562306a36Sopenharmony_ci/// Used to implement `PinnedDrop` safely. 22662306a36Sopenharmony_ci/// 22762306a36Sopenharmony_ci/// Only works on structs that are annotated via `#[`[`macro@pin_data`]`]`. 22862306a36Sopenharmony_ci/// 22962306a36Sopenharmony_ci/// # Examples 23062306a36Sopenharmony_ci/// 23162306a36Sopenharmony_ci/// ```rust,ignore 23262306a36Sopenharmony_ci/// #[pin_data(PinnedDrop)] 23362306a36Sopenharmony_ci/// struct DriverData { 23462306a36Sopenharmony_ci/// #[pin] 23562306a36Sopenharmony_ci/// queue: Mutex<Vec<Command>>, 23662306a36Sopenharmony_ci/// buf: Box<[u8; 1024 * 1024]>, 23762306a36Sopenharmony_ci/// raw_info: *mut Info, 23862306a36Sopenharmony_ci/// } 23962306a36Sopenharmony_ci/// 24062306a36Sopenharmony_ci/// #[pinned_drop] 24162306a36Sopenharmony_ci/// impl PinnedDrop for DriverData { 24262306a36Sopenharmony_ci/// fn drop(self: Pin<&mut Self>) { 24362306a36Sopenharmony_ci/// unsafe { bindings::destroy_info(self.raw_info) }; 24462306a36Sopenharmony_ci/// } 24562306a36Sopenharmony_ci/// } 24662306a36Sopenharmony_ci/// ``` 24762306a36Sopenharmony_ci#[proc_macro_attribute] 24862306a36Sopenharmony_cipub fn pinned_drop(args: TokenStream, input: TokenStream) -> TokenStream { 24962306a36Sopenharmony_ci pinned_drop::pinned_drop(args, input) 25062306a36Sopenharmony_ci} 25162306a36Sopenharmony_ci 25262306a36Sopenharmony_ci/// Paste identifiers together. 25362306a36Sopenharmony_ci/// 25462306a36Sopenharmony_ci/// Within the `paste!` macro, identifiers inside `[<` and `>]` are concatenated together to form a 25562306a36Sopenharmony_ci/// single identifier. 25662306a36Sopenharmony_ci/// 25762306a36Sopenharmony_ci/// This is similar to the [`paste`] crate, but with pasting feature limited to identifiers 25862306a36Sopenharmony_ci/// (literals, lifetimes and documentation strings are not supported). There is a difference in 25962306a36Sopenharmony_ci/// supported modifiers as well. 26062306a36Sopenharmony_ci/// 26162306a36Sopenharmony_ci/// # Example 26262306a36Sopenharmony_ci/// 26362306a36Sopenharmony_ci/// ```ignore 26462306a36Sopenharmony_ci/// use kernel::macro::paste; 26562306a36Sopenharmony_ci/// 26662306a36Sopenharmony_ci/// macro_rules! pub_no_prefix { 26762306a36Sopenharmony_ci/// ($prefix:ident, $($newname:ident),+) => { 26862306a36Sopenharmony_ci/// paste! { 26962306a36Sopenharmony_ci/// $(pub(crate) const $newname: u32 = [<$prefix $newname>];)+ 27062306a36Sopenharmony_ci/// } 27162306a36Sopenharmony_ci/// }; 27262306a36Sopenharmony_ci/// } 27362306a36Sopenharmony_ci/// 27462306a36Sopenharmony_ci/// pub_no_prefix!( 27562306a36Sopenharmony_ci/// binder_driver_return_protocol_, 27662306a36Sopenharmony_ci/// BR_OK, 27762306a36Sopenharmony_ci/// BR_ERROR, 27862306a36Sopenharmony_ci/// BR_TRANSACTION, 27962306a36Sopenharmony_ci/// BR_REPLY, 28062306a36Sopenharmony_ci/// BR_DEAD_REPLY, 28162306a36Sopenharmony_ci/// BR_TRANSACTION_COMPLETE, 28262306a36Sopenharmony_ci/// BR_INCREFS, 28362306a36Sopenharmony_ci/// BR_ACQUIRE, 28462306a36Sopenharmony_ci/// BR_RELEASE, 28562306a36Sopenharmony_ci/// BR_DECREFS, 28662306a36Sopenharmony_ci/// BR_NOOP, 28762306a36Sopenharmony_ci/// BR_SPAWN_LOOPER, 28862306a36Sopenharmony_ci/// BR_DEAD_BINDER, 28962306a36Sopenharmony_ci/// BR_CLEAR_DEATH_NOTIFICATION_DONE, 29062306a36Sopenharmony_ci/// BR_FAILED_REPLY 29162306a36Sopenharmony_ci/// ); 29262306a36Sopenharmony_ci/// 29362306a36Sopenharmony_ci/// assert_eq!(BR_OK, binder_driver_return_protocol_BR_OK); 29462306a36Sopenharmony_ci/// ``` 29562306a36Sopenharmony_ci/// 29662306a36Sopenharmony_ci/// # Modifiers 29762306a36Sopenharmony_ci/// 29862306a36Sopenharmony_ci/// For each identifier, it is possible to attach one or multiple modifiers to 29962306a36Sopenharmony_ci/// it. 30062306a36Sopenharmony_ci/// 30162306a36Sopenharmony_ci/// Currently supported modifiers are: 30262306a36Sopenharmony_ci/// * `span`: change the span of concatenated identifier to the span of the specified token. By 30362306a36Sopenharmony_ci/// default the span of the `[< >]` group is used. 30462306a36Sopenharmony_ci/// * `lower`: change the identifier to lower case. 30562306a36Sopenharmony_ci/// * `upper`: change the identifier to upper case. 30662306a36Sopenharmony_ci/// 30762306a36Sopenharmony_ci/// ```ignore 30862306a36Sopenharmony_ci/// use kernel::macro::paste; 30962306a36Sopenharmony_ci/// 31062306a36Sopenharmony_ci/// macro_rules! pub_no_prefix { 31162306a36Sopenharmony_ci/// ($prefix:ident, $($newname:ident),+) => { 31262306a36Sopenharmony_ci/// kernel::macros::paste! { 31362306a36Sopenharmony_ci/// $(pub(crate) const fn [<$newname:lower:span>]: u32 = [<$prefix $newname:span>];)+ 31462306a36Sopenharmony_ci/// } 31562306a36Sopenharmony_ci/// }; 31662306a36Sopenharmony_ci/// } 31762306a36Sopenharmony_ci/// 31862306a36Sopenharmony_ci/// pub_no_prefix!( 31962306a36Sopenharmony_ci/// binder_driver_return_protocol_, 32062306a36Sopenharmony_ci/// BR_OK, 32162306a36Sopenharmony_ci/// BR_ERROR, 32262306a36Sopenharmony_ci/// BR_TRANSACTION, 32362306a36Sopenharmony_ci/// BR_REPLY, 32462306a36Sopenharmony_ci/// BR_DEAD_REPLY, 32562306a36Sopenharmony_ci/// BR_TRANSACTION_COMPLETE, 32662306a36Sopenharmony_ci/// BR_INCREFS, 32762306a36Sopenharmony_ci/// BR_ACQUIRE, 32862306a36Sopenharmony_ci/// BR_RELEASE, 32962306a36Sopenharmony_ci/// BR_DECREFS, 33062306a36Sopenharmony_ci/// BR_NOOP, 33162306a36Sopenharmony_ci/// BR_SPAWN_LOOPER, 33262306a36Sopenharmony_ci/// BR_DEAD_BINDER, 33362306a36Sopenharmony_ci/// BR_CLEAR_DEATH_NOTIFICATION_DONE, 33462306a36Sopenharmony_ci/// BR_FAILED_REPLY 33562306a36Sopenharmony_ci/// ); 33662306a36Sopenharmony_ci/// 33762306a36Sopenharmony_ci/// assert_eq!(br_ok(), binder_driver_return_protocol_BR_OK); 33862306a36Sopenharmony_ci/// ``` 33962306a36Sopenharmony_ci/// 34062306a36Sopenharmony_ci/// [`paste`]: https://docs.rs/paste/ 34162306a36Sopenharmony_ci#[proc_macro] 34262306a36Sopenharmony_cipub fn paste(input: TokenStream) -> TokenStream { 34362306a36Sopenharmony_ci let mut tokens = input.into_iter().collect(); 34462306a36Sopenharmony_ci paste::expand(&mut tokens); 34562306a36Sopenharmony_ci tokens.into_iter().collect() 34662306a36Sopenharmony_ci} 34762306a36Sopenharmony_ci 34862306a36Sopenharmony_ci/// Derives the [`Zeroable`] trait for the given struct. 34962306a36Sopenharmony_ci/// 35062306a36Sopenharmony_ci/// This can only be used for structs where every field implements the [`Zeroable`] trait. 35162306a36Sopenharmony_ci/// 35262306a36Sopenharmony_ci/// # Examples 35362306a36Sopenharmony_ci/// 35462306a36Sopenharmony_ci/// ```rust,ignore 35562306a36Sopenharmony_ci/// #[derive(Zeroable)] 35662306a36Sopenharmony_ci/// pub struct DriverData { 35762306a36Sopenharmony_ci/// id: i64, 35862306a36Sopenharmony_ci/// buf_ptr: *mut u8, 35962306a36Sopenharmony_ci/// len: usize, 36062306a36Sopenharmony_ci/// } 36162306a36Sopenharmony_ci/// ``` 36262306a36Sopenharmony_ci#[proc_macro_derive(Zeroable)] 36362306a36Sopenharmony_cipub fn derive_zeroable(input: TokenStream) -> TokenStream { 36462306a36Sopenharmony_ci zeroable::derive(input) 36562306a36Sopenharmony_ci} 366