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