1 // SPDX-License-Identifier: GPL-2.0 2 3 //! Crate for all kernel procedural macros. 4 5 #[macro_use] 6 mod quote; 7 mod concat_idents; 8 mod helpers; 9 mod module; 10 mod pin_data; 11 mod pinned_drop; 12 mod vtable; 13 14 use proc_macro::TokenStream; 15 16 /// Declares a kernel module. 17 /// 18 /// The `type` argument should be a type which implements the [`Module`] 19 /// trait. Also accepts various forms of kernel metadata. 20 /// 21 /// C header: [`include/linux/moduleparam.h`](../../../include/linux/moduleparam.h) 22 /// 23 /// [`Module`]: ../kernel/trait.Module.html 24 /// 25 /// # Examples 26 /// 27 /// ```ignore 28 /// use kernel::prelude::*; 29 /// 30 /// module!{ 31 /// type: MyModule, 32 /// name: "my_kernel_module", 33 /// author: "Rust for Linux Contributors", 34 /// description: "My very own kernel module!", 35 /// license: "GPL", 36 /// params: { 37 /// my_i32: i32 { 38 /// default: 42, 39 /// permissions: 0o000, 40 /// description: "Example of i32", 41 /// }, 42 /// writeable_i32: i32 { 43 /// default: 42, 44 /// permissions: 0o644, 45 /// description: "Example of i32", 46 /// }, 47 /// }, 48 /// } 49 /// 50 /// struct MyModule; 51 /// 52 /// impl kernel::Module for MyModule { 53 /// fn init() -> Result<Self> { 54 /// // If the parameter is writeable, then the kparam lock must be 55 /// // taken to read the parameter: 56 /// { 57 /// let lock = THIS_MODULE.kernel_param_lock(); 58 /// pr_info!("i32 param is: {}\n", writeable_i32.read(&lock)); 59 /// } 60 /// // If the parameter is read only, it can be read without locking 61 /// // the kernel parameters: 62 /// pr_info!("i32 param is: {}\n", my_i32.read()); 63 /// Ok(Self) 64 /// } 65 /// } 66 /// ``` 67 /// 68 /// # Supported argument types 69 /// - `type`: type which implements the [`Module`] trait (required). 70 /// - `name`: byte array of the name of the kernel module (required). 71 /// - `author`: byte array of the author of the kernel module. 72 /// - `description`: byte array of the description of the kernel module. 73 /// - `license`: byte array of the license of the kernel module (required). 74 /// - `alias`: byte array of alias name of the kernel module. 75 #[proc_macro] 76 pub fn module(ts: TokenStream) -> TokenStream { 77 module::module(ts) 78 } 79 80 /// Declares or implements a vtable trait. 81 /// 82 /// Linux's use of pure vtables is very close to Rust traits, but they differ 83 /// in how unimplemented functions are represented. In Rust, traits can provide 84 /// default implementation for all non-required methods (and the default 85 /// implementation could just return `Error::EINVAL`); Linux typically use C 86 /// `NULL` pointers to represent these functions. 87 /// 88 /// This attribute is intended to close the gap. Traits can be declared and 89 /// implemented with the `#[vtable]` attribute, and a `HAS_*` associated constant 90 /// will be generated for each method in the trait, indicating if the implementor 91 /// has overridden a method. 92 /// 93 /// This attribute is not needed if all methods are required. 94 /// 95 /// # Examples 96 /// 97 /// ```ignore 98 /// use kernel::prelude::*; 99 /// 100 /// // Declares a `#[vtable]` trait 101 /// #[vtable] 102 /// pub trait Operations: Send + Sync + Sized { 103 /// fn foo(&self) -> Result<()> { 104 /// Err(EINVAL) 105 /// } 106 /// 107 /// fn bar(&self) -> Result<()> { 108 /// Err(EINVAL) 109 /// } 110 /// } 111 /// 112 /// struct Foo; 113 /// 114 /// // Implements the `#[vtable]` trait 115 /// #[vtable] 116 /// impl Operations for Foo { 117 /// fn foo(&self) -> Result<()> { 118 /// # Err(EINVAL) 119 /// // ... 120 /// } 121 /// } 122 /// 123 /// assert_eq!(<Foo as Operations>::HAS_FOO, true); 124 /// assert_eq!(<Foo as Operations>::HAS_BAR, false); 125 /// ``` 126 #[proc_macro_attribute] 127 pub fn vtable(attr: TokenStream, ts: TokenStream) -> TokenStream { 128 vtable::vtable(attr, ts) 129 } 130 131 /// Concatenate two identifiers. 132 /// 133 /// This is useful in macros that need to declare or reference items with names 134 /// starting with a fixed prefix and ending in a user specified name. The resulting 135 /// identifier has the span of the second argument. 136 /// 137 /// # Examples 138 /// 139 /// ```ignore 140 /// use kernel::macro::concat_idents; 141 /// 142 /// macro_rules! pub_no_prefix { 143 /// ($prefix:ident, $($newname:ident),+) => { 144 /// $(pub(crate) const $newname: u32 = kernel::macros::concat_idents!($prefix, $newname);)+ 145 /// }; 146 /// } 147 /// 148 /// pub_no_prefix!( 149 /// binder_driver_return_protocol_, 150 /// BR_OK, 151 /// BR_ERROR, 152 /// BR_TRANSACTION, 153 /// BR_REPLY, 154 /// BR_DEAD_REPLY, 155 /// BR_TRANSACTION_COMPLETE, 156 /// BR_INCREFS, 157 /// BR_ACQUIRE, 158 /// BR_RELEASE, 159 /// BR_DECREFS, 160 /// BR_NOOP, 161 /// BR_SPAWN_LOOPER, 162 /// BR_DEAD_BINDER, 163 /// BR_CLEAR_DEATH_NOTIFICATION_DONE, 164 /// BR_FAILED_REPLY 165 /// ); 166 /// 167 /// assert_eq!(BR_OK, binder_driver_return_protocol_BR_OK); 168 /// ``` 169 #[proc_macro] 170 pub fn concat_idents(ts: TokenStream) -> TokenStream { 171 concat_idents::concat_idents(ts) 172 } 173 174 /// Used to specify the pinning information of the fields of a struct. 175 /// 176 /// This is somewhat similar in purpose as 177 /// [pin-project-lite](https://crates.io/crates/pin-project-lite). 178 /// Place this macro on a struct definition and then `#[pin]` in front of the attributes of each 179 /// field you want to structurally pin. 180 /// 181 /// This macro enables the use of the [`pin_init!`] macro. When pin-initializing a `struct`, 182 /// then `#[pin]` directs the type of initializer that is required. 183 /// 184 /// If your `struct` implements `Drop`, then you need to add `PinnedDrop` as arguments to this 185 /// macro, and change your `Drop` implementation to `PinnedDrop` annotated with 186 /// `#[`[`macro@pinned_drop`]`]`, since dropping pinned values requires extra care. 187 /// 188 /// # Examples 189 /// 190 /// ```rust,ignore 191 /// #[pin_data] 192 /// struct DriverData { 193 /// #[pin] 194 /// queue: Mutex<Vec<Command>>, 195 /// buf: Box<[u8; 1024 * 1024]>, 196 /// } 197 /// ``` 198 /// 199 /// ```rust,ignore 200 /// #[pin_data(PinnedDrop)] 201 /// struct DriverData { 202 /// #[pin] 203 /// queue: Mutex<Vec<Command>>, 204 /// buf: Box<[u8; 1024 * 1024]>, 205 /// raw_info: *mut Info, 206 /// } 207 /// 208 /// #[pinned_drop] 209 /// impl PinnedDrop for DriverData { 210 /// fn drop(self: Pin<&mut Self>) { 211 /// unsafe { bindings::destroy_info(self.raw_info) }; 212 /// } 213 /// } 214 /// ``` 215 /// 216 /// [`pin_init!`]: ../kernel/macro.pin_init.html 217 // ^ cannot use direct link, since `kernel` is not a dependency of `macros`. 218 #[proc_macro_attribute] 219 pub fn pin_data(inner: TokenStream, item: TokenStream) -> TokenStream { 220 pin_data::pin_data(inner, item) 221 } 222 223 /// Used to implement `PinnedDrop` safely. 224 /// 225 /// Only works on structs that are annotated via `#[`[`macro@pin_data`]`]`. 226 /// 227 /// # Examples 228 /// 229 /// ```rust,ignore 230 /// #[pin_data(PinnedDrop)] 231 /// struct DriverData { 232 /// #[pin] 233 /// queue: Mutex<Vec<Command>>, 234 /// buf: Box<[u8; 1024 * 1024]>, 235 /// raw_info: *mut Info, 236 /// } 237 /// 238 /// #[pinned_drop] 239 /// impl PinnedDrop for DriverData { 240 /// fn drop(self: Pin<&mut Self>) { 241 /// unsafe { bindings::destroy_info(self.raw_info) }; 242 /// } 243 /// } 244 /// ``` 245 #[proc_macro_attribute] 246 pub fn pinned_drop(args: TokenStream, input: TokenStream) -> TokenStream { 247 pinned_drop::pinned_drop(args, input) 248 } 249