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