xref: /linux/rust/macros/lib.rs (revision 7db28abbea0f7dc1ec4fdfdc149db5fbd9e4c994)
1 // SPDX-License-Identifier: GPL-2.0
2 
3 //! Crate for all kernel procedural macros.
4 
5 // When fixdep scans this, it will find this string `CONFIG_RUSTC_VERSION_TEXT`
6 // and thus add a dependency on `include/config/RUSTC_VERSION_TEXT`, which is
7 // touched by Kconfig when the version string from the compiler changes.
8 
9 // Stable since Rust 1.87.0.
10 #![feature(extract_if)]
11 //
12 // Stable since Rust 1.88.0 under a different name, `proc_macro_span_file`,
13 // which was added in Rust 1.88.0. This is why `cfg_attr` is used here, i.e.
14 // to avoid depending on the full `proc_macro_span` on Rust >= 1.88.0.
15 #![cfg_attr(not(CONFIG_RUSTC_HAS_SPAN_FILE), feature(proc_macro_span))]
16 
17 mod concat_idents;
18 mod export;
19 mod fmt;
20 mod for_lt;
21 mod helpers;
22 mod kunit;
23 mod module;
24 mod paste;
25 mod vtable;
26 
27 use proc_macro::TokenStream;
28 
29 use syn::parse_macro_input;
30 
31 /// Declares a kernel module.
32 ///
33 /// The `type` argument should be a type which implements the [`Module`]
34 /// trait. Also accepts various forms of kernel metadata.
35 ///
36 /// The `params` field describe module parameters. Each entry has the form
37 ///
38 /// ```ignore
39 /// parameter_name: type {
40 ///     default: default_value,
41 ///     description: "Description",
42 /// }
43 /// ```
44 ///
45 /// `type` may be one of
46 ///
47 /// - [`i8`]
48 /// - [`u8`]
49 /// - [`i8`]
50 /// - [`u8`]
51 /// - [`i16`]
52 /// - [`u16`]
53 /// - [`i32`]
54 /// - [`u32`]
55 /// - [`i64`]
56 /// - [`u64`]
57 /// - [`isize`]
58 /// - [`usize`]
59 /// - [`bool`]
60 ///
61 /// C header: [`include/linux/moduleparam.h`](srctree/include/linux/moduleparam.h)
62 ///
63 /// [`Module`]: ../kernel/trait.Module.html
64 ///
65 /// # Examples
66 ///
67 /// ```ignore
68 /// use kernel::prelude::*;
69 ///
70 /// module!{
71 ///     type: MyModule,
72 ///     name: "my_kernel_module",
73 ///     authors: ["Rust for Linux Contributors"],
74 ///     description: "My very own kernel module!",
75 ///     license: "GPL",
76 ///     alias: ["alternate_module_name"],
77 ///     params: {
78 ///         my_parameter: i64 {
79 ///             default: 1,
80 ///             description: "This parameter has a default of 1",
81 ///         },
82 ///     },
83 /// }
84 ///
85 /// struct MyModule(i32);
86 ///
87 /// impl kernel::Module for MyModule {
88 ///     fn init(_module: &'static ThisModule) -> Result<Self> {
89 ///         let foo: i32 = 42;
90 ///         pr_info!("I contain:  {}\n", foo);
91 ///         pr_info!("i32 param is:  {}\n", module_parameters::my_parameter.read());
92 ///         Ok(Self(foo))
93 ///     }
94 /// }
95 /// # fn main() {}
96 /// ```
97 ///
98 /// ## Firmware
99 ///
100 /// The following example shows how to declare a kernel module that needs
101 /// to load binary firmware files. You need to specify the file names of
102 /// the firmware in the `firmware` field. The information is embedded
103 /// in the `modinfo` section of the kernel module. For example, a tool to
104 /// build an initramfs uses this information to put the firmware files into
105 /// the initramfs image.
106 ///
107 /// ```
108 /// use kernel::prelude::*;
109 ///
110 /// module!{
111 ///     type: MyDeviceDriverModule,
112 ///     name: "my_device_driver_module",
113 ///     authors: ["Rust for Linux Contributors"],
114 ///     description: "My device driver requires firmware",
115 ///     license: "GPL",
116 ///     firmware: ["my_device_firmware1.bin", "my_device_firmware2.bin"],
117 /// }
118 ///
119 /// struct MyDeviceDriverModule;
120 ///
121 /// impl kernel::Module for MyDeviceDriverModule {
122 ///     fn init(_module: &'static ThisModule) -> Result<Self> {
123 ///         Ok(Self)
124 ///     }
125 /// }
126 /// # fn main() {}
127 /// ```
128 ///
129 /// # Supported argument types
130 ///   - `type`: type which implements the [`Module`] trait (required).
131 ///   - `name`: ASCII string literal of the name of the kernel module (required).
132 ///   - `authors`: array of ASCII string literals of the authors of the kernel module.
133 ///   - `description`: string literal of the description of the kernel module.
134 ///   - `license`: ASCII string literal of the license of the kernel module (required).
135 ///   - `alias`: array of ASCII string literals of the alias names of the kernel module.
136 ///   - `firmware`: array of ASCII string literals of the firmware files of
137 ///     the kernel module.
138 #[proc_macro]
139 pub fn module(input: TokenStream) -> TokenStream {
140     module::module(parse_macro_input!(input))
141         .unwrap_or_else(|e| e.into_compile_error())
142         .into()
143 }
144 
145 /// Declares or implements a vtable trait.
146 ///
147 /// Linux's use of pure vtables is very close to Rust traits, but they differ
148 /// in how unimplemented functions are represented. In Rust, traits can provide
149 /// default implementation for all non-required methods (and the default
150 /// implementation could just return `Error::EINVAL`); Linux typically use C
151 /// `NULL` pointers to represent these functions.
152 ///
153 /// This attribute closes that gap. A trait can be annotated with the
154 /// `#[vtable]` attribute. Implementers of the trait will then also have to
155 /// annotate the trait with `#[vtable]`. This attribute generates a `HAS_*`
156 /// associated constant bool for each method in the trait that is set to true if
157 /// the implementer has overridden the associated method.
158 ///
159 /// For a trait method to be optional, it must have a default implementation.
160 /// This is also the case for traits annotated with `#[vtable]`, but in this
161 /// case the default implementation will never be executed. The reason for this
162 /// is that the functions will be called through function pointers installed in
163 /// C side vtables. When an optional method is not implemented on a `#[vtable]`
164 /// trait, a `NULL` entry is installed in the vtable. Thus the default
165 /// implementation is never called. Since these traits are not designed to be
166 /// used on the Rust side, it should not be possible to call the default
167 /// implementation. This is done to ensure that we call the vtable methods
168 /// through the C vtable, and not through the Rust vtable. Therefore, the
169 /// default implementation should call `build_error!`, which prevents
170 /// calls to this function at compile time:
171 ///
172 /// ```compile_fail
173 /// # // Intentionally missing `use`s to simplify `rusttest`.
174 /// build_error!(VTABLE_DEFAULT_ERROR)
175 /// ```
176 ///
177 /// Note that you might need to import [`kernel::error::VTABLE_DEFAULT_ERROR`].
178 ///
179 /// This macro should not be used when all functions are required.
180 ///
181 /// Additionally, this macro automatically handles the `OwnerModule`
182 /// associated type: on the trait side, `type OwnerModule: ModuleMetadata;`
183 /// is added as a required associated type if not already defined; on the
184 /// impl side, `type OwnerModule = LocalModule;` is automatically inserted
185 /// if not explicitly defined.
186 ///
187 /// # Examples
188 ///
189 /// ```
190 /// use kernel::error::VTABLE_DEFAULT_ERROR;
191 /// use kernel::prelude::*;
192 ///
193 /// # struct LocalModule;
194 /// # impl kernel::ModuleMetadata for LocalModule {
195 /// #     const NAME: &'static kernel::str::CStr = c"vtable_doctest";
196 /// #
197 /// #     // SAFETY: This doctest runs on the host: there is no `THIS_MODULE`.
198 /// #     const THIS_MODULE: kernel::ThisModule = unsafe {
199 /// #         kernel::ThisModule::from_ptr(core::ptr::null_mut())
200 /// #     };
201 /// # }
202 /// #
203 /// # fn main() {
204 /// // Declares a `#[vtable]` trait
205 /// #[vtable]
206 /// pub trait Operations: Send + Sync + Sized {
207 ///     fn foo(&self) -> Result<()> {
208 ///         build_error!(VTABLE_DEFAULT_ERROR)
209 ///     }
210 ///
211 ///     fn bar(&self) -> Result<()> {
212 ///         build_error!(VTABLE_DEFAULT_ERROR)
213 ///     }
214 /// }
215 ///
216 /// struct Foo;
217 ///
218 /// // Implements the `#[vtable]` trait
219 /// #[vtable]
220 /// impl Operations for Foo {
221 ///     fn foo(&self) -> Result<()> {
222 /// #        Err(EINVAL)
223 ///         // ...
224 ///     }
225 /// }
226 ///
227 /// assert_eq!(<Foo as Operations>::HAS_FOO, true);
228 /// assert_eq!(<Foo as Operations>::HAS_BAR, false);
229 /// # }
230 /// ```
231 ///
232 /// [`kernel::error::VTABLE_DEFAULT_ERROR`]: ../kernel/error/constant.VTABLE_DEFAULT_ERROR.html
233 #[proc_macro_attribute]
234 pub fn vtable(attr: TokenStream, input: TokenStream) -> TokenStream {
235     parse_macro_input!(attr as syn::parse::Nothing);
236     vtable::vtable(parse_macro_input!(input))
237         .unwrap_or_else(|e| e.into_compile_error())
238         .into()
239 }
240 
241 /// Export a function so that C code can call it via a header file.
242 ///
243 /// Functions exported using this macro can be called from C code using the declaration in the
244 /// appropriate header file. It should only be used in cases where C calls the function through a
245 /// header file; cases where C calls into Rust via a function pointer in a vtable (such as
246 /// `file_operations`) should not use this macro.
247 ///
248 /// This macro has the following effect:
249 ///
250 /// * Disables name mangling for this function.
251 /// * Verifies at compile-time that the function signature matches the declaration in the header
252 ///   file.
253 ///
254 /// You must declare the signature of the Rust function in a header file that is included by
255 /// `rust/bindings/bindings_helper.h`.
256 ///
257 /// This macro is *not* the same as the C macros `EXPORT_SYMBOL_*`. All Rust symbols are currently
258 /// automatically exported with `EXPORT_SYMBOL_GPL`.
259 #[proc_macro_attribute]
260 pub fn export(attr: TokenStream, input: TokenStream) -> TokenStream {
261     parse_macro_input!(attr as syn::parse::Nothing);
262     export::export(parse_macro_input!(input)).into()
263 }
264 
265 /// Like [`core::format_args!`], but automatically wraps arguments in [`kernel::fmt::Adapter`].
266 ///
267 /// This macro allows generating `fmt::Arguments` while ensuring that each argument is wrapped with
268 /// `::kernel::fmt::Adapter`, which customizes formatting behavior for kernel logging.
269 ///
270 /// Named arguments used in the format string (e.g. `{foo}`) are detected and resolved from local
271 /// bindings. All positional and named arguments are automatically wrapped.
272 ///
273 /// This macro is an implementation detail of other kernel logging macros like [`pr_info!`] and
274 /// should not typically be used directly.
275 ///
276 /// [`kernel::fmt::Adapter`]: ../kernel/fmt/struct.Adapter.html
277 /// [`pr_info!`]: ../kernel/macro.pr_info.html
278 #[proc_macro]
279 pub fn fmt(input: TokenStream) -> TokenStream {
280     fmt::fmt(input.into()).into()
281 }
282 
283 /// Concatenate two identifiers.
284 ///
285 /// This is useful in macros that need to declare or reference items with names
286 /// starting with a fixed prefix and ending in a user specified name. The resulting
287 /// identifier has the span of the second argument.
288 ///
289 /// # Examples
290 ///
291 /// ```
292 /// # const binder_driver_return_protocol_BR_OK: u32 = 0;
293 /// # const binder_driver_return_protocol_BR_ERROR: u32 = 1;
294 /// # const binder_driver_return_protocol_BR_TRANSACTION: u32 = 2;
295 /// # const binder_driver_return_protocol_BR_REPLY: u32 = 3;
296 /// # const binder_driver_return_protocol_BR_DEAD_REPLY: u32 = 4;
297 /// # const binder_driver_return_protocol_BR_TRANSACTION_COMPLETE: u32 = 5;
298 /// # const binder_driver_return_protocol_BR_INCREFS: u32 = 6;
299 /// # const binder_driver_return_protocol_BR_ACQUIRE: u32 = 7;
300 /// # const binder_driver_return_protocol_BR_RELEASE: u32 = 8;
301 /// # const binder_driver_return_protocol_BR_DECREFS: u32 = 9;
302 /// # const binder_driver_return_protocol_BR_NOOP: u32 = 10;
303 /// # const binder_driver_return_protocol_BR_SPAWN_LOOPER: u32 = 11;
304 /// # const binder_driver_return_protocol_BR_DEAD_BINDER: u32 = 12;
305 /// # const binder_driver_return_protocol_BR_CLEAR_DEATH_NOTIFICATION_DONE: u32 = 13;
306 /// # const binder_driver_return_protocol_BR_FAILED_REPLY: u32 = 14;
307 /// use kernel::macros::concat_idents;
308 ///
309 /// macro_rules! pub_no_prefix {
310 ///     ($prefix:ident, $($newname:ident),+) => {
311 ///         $(pub(crate) const $newname: u32 = concat_idents!($prefix, $newname);)+
312 ///     };
313 /// }
314 ///
315 /// pub_no_prefix!(
316 ///     binder_driver_return_protocol_,
317 ///     BR_OK,
318 ///     BR_ERROR,
319 ///     BR_TRANSACTION,
320 ///     BR_REPLY,
321 ///     BR_DEAD_REPLY,
322 ///     BR_TRANSACTION_COMPLETE,
323 ///     BR_INCREFS,
324 ///     BR_ACQUIRE,
325 ///     BR_RELEASE,
326 ///     BR_DECREFS,
327 ///     BR_NOOP,
328 ///     BR_SPAWN_LOOPER,
329 ///     BR_DEAD_BINDER,
330 ///     BR_CLEAR_DEATH_NOTIFICATION_DONE,
331 ///     BR_FAILED_REPLY
332 /// );
333 ///
334 /// assert_eq!(BR_OK, binder_driver_return_protocol_BR_OK);
335 /// ```
336 #[proc_macro]
337 pub fn concat_idents(input: TokenStream) -> TokenStream {
338     concat_idents::concat_idents(parse_macro_input!(input)).into()
339 }
340 
341 /// Paste identifiers together.
342 ///
343 /// Within the `paste!` macro, identifiers inside `[<` and `>]` are concatenated together to form a
344 /// single identifier.
345 ///
346 /// This is similar to the [`paste`] crate, but with pasting feature limited to identifiers and
347 /// literals (lifetimes and documentation strings are not supported). There is a difference in
348 /// supported modifiers as well.
349 ///
350 /// # Examples
351 ///
352 /// ```
353 /// # const binder_driver_return_protocol_BR_OK: u32 = 0;
354 /// # const binder_driver_return_protocol_BR_ERROR: u32 = 1;
355 /// # const binder_driver_return_protocol_BR_TRANSACTION: u32 = 2;
356 /// # const binder_driver_return_protocol_BR_REPLY: u32 = 3;
357 /// # const binder_driver_return_protocol_BR_DEAD_REPLY: u32 = 4;
358 /// # const binder_driver_return_protocol_BR_TRANSACTION_COMPLETE: u32 = 5;
359 /// # const binder_driver_return_protocol_BR_INCREFS: u32 = 6;
360 /// # const binder_driver_return_protocol_BR_ACQUIRE: u32 = 7;
361 /// # const binder_driver_return_protocol_BR_RELEASE: u32 = 8;
362 /// # const binder_driver_return_protocol_BR_DECREFS: u32 = 9;
363 /// # const binder_driver_return_protocol_BR_NOOP: u32 = 10;
364 /// # const binder_driver_return_protocol_BR_SPAWN_LOOPER: u32 = 11;
365 /// # const binder_driver_return_protocol_BR_DEAD_BINDER: u32 = 12;
366 /// # const binder_driver_return_protocol_BR_CLEAR_DEATH_NOTIFICATION_DONE: u32 = 13;
367 /// # const binder_driver_return_protocol_BR_FAILED_REPLY: u32 = 14;
368 /// macro_rules! pub_no_prefix {
369 ///     ($prefix:ident, $($newname:ident),+) => {
370 ///         ::kernel::macros::paste! {
371 ///             $(pub(crate) const $newname: u32 = [<$prefix $newname>];)+
372 ///         }
373 ///     };
374 /// }
375 ///
376 /// pub_no_prefix!(
377 ///     binder_driver_return_protocol_,
378 ///     BR_OK,
379 ///     BR_ERROR,
380 ///     BR_TRANSACTION,
381 ///     BR_REPLY,
382 ///     BR_DEAD_REPLY,
383 ///     BR_TRANSACTION_COMPLETE,
384 ///     BR_INCREFS,
385 ///     BR_ACQUIRE,
386 ///     BR_RELEASE,
387 ///     BR_DECREFS,
388 ///     BR_NOOP,
389 ///     BR_SPAWN_LOOPER,
390 ///     BR_DEAD_BINDER,
391 ///     BR_CLEAR_DEATH_NOTIFICATION_DONE,
392 ///     BR_FAILED_REPLY
393 /// );
394 ///
395 /// assert_eq!(BR_OK, binder_driver_return_protocol_BR_OK);
396 /// ```
397 ///
398 /// # Modifiers
399 ///
400 /// For each identifier, it is possible to attach one or multiple modifiers to
401 /// it.
402 ///
403 /// Currently supported modifiers are:
404 /// * `span`: change the span of concatenated identifier to the span of the specified token. By
405 ///   default the span of the `[< >]` group is used.
406 /// * `lower`: change the identifier to lower case.
407 /// * `upper`: change the identifier to upper case.
408 ///
409 /// ```
410 /// # const binder_driver_return_protocol_BR_OK: u32 = 0;
411 /// # const binder_driver_return_protocol_BR_ERROR: u32 = 1;
412 /// # const binder_driver_return_protocol_BR_TRANSACTION: u32 = 2;
413 /// # const binder_driver_return_protocol_BR_REPLY: u32 = 3;
414 /// # const binder_driver_return_protocol_BR_DEAD_REPLY: u32 = 4;
415 /// # const binder_driver_return_protocol_BR_TRANSACTION_COMPLETE: u32 = 5;
416 /// # const binder_driver_return_protocol_BR_INCREFS: u32 = 6;
417 /// # const binder_driver_return_protocol_BR_ACQUIRE: u32 = 7;
418 /// # const binder_driver_return_protocol_BR_RELEASE: u32 = 8;
419 /// # const binder_driver_return_protocol_BR_DECREFS: u32 = 9;
420 /// # const binder_driver_return_protocol_BR_NOOP: u32 = 10;
421 /// # const binder_driver_return_protocol_BR_SPAWN_LOOPER: u32 = 11;
422 /// # const binder_driver_return_protocol_BR_DEAD_BINDER: u32 = 12;
423 /// # const binder_driver_return_protocol_BR_CLEAR_DEATH_NOTIFICATION_DONE: u32 = 13;
424 /// # const binder_driver_return_protocol_BR_FAILED_REPLY: u32 = 14;
425 /// macro_rules! pub_no_prefix {
426 ///     ($prefix:ident, $($newname:ident),+) => {
427 ///         ::kernel::macros::paste! {
428 ///             $(pub(crate) const fn [<$newname:lower:span>]() -> u32 { [<$prefix $newname:span>] })+
429 ///         }
430 ///     };
431 /// }
432 ///
433 /// pub_no_prefix!(
434 ///     binder_driver_return_protocol_,
435 ///     BR_OK,
436 ///     BR_ERROR,
437 ///     BR_TRANSACTION,
438 ///     BR_REPLY,
439 ///     BR_DEAD_REPLY,
440 ///     BR_TRANSACTION_COMPLETE,
441 ///     BR_INCREFS,
442 ///     BR_ACQUIRE,
443 ///     BR_RELEASE,
444 ///     BR_DECREFS,
445 ///     BR_NOOP,
446 ///     BR_SPAWN_LOOPER,
447 ///     BR_DEAD_BINDER,
448 ///     BR_CLEAR_DEATH_NOTIFICATION_DONE,
449 ///     BR_FAILED_REPLY
450 /// );
451 ///
452 /// assert_eq!(br_ok(), binder_driver_return_protocol_BR_OK);
453 /// ```
454 ///
455 /// # Literals
456 ///
457 /// Literals can also be concatenated with other identifiers:
458 ///
459 /// ```
460 /// macro_rules! create_numbered_fn {
461 ///     ($name:literal, $val:literal) => {
462 ///         ::kernel::macros::paste! {
463 ///             fn [<some_ $name _fn $val>]() -> u32 { $val }
464 ///         }
465 ///     };
466 /// }
467 ///
468 /// create_numbered_fn!("foo", 100);
469 ///
470 /// assert_eq!(some_foo_fn100(), 100)
471 /// ```
472 ///
473 /// [`paste`]: https://docs.rs/paste/
474 #[proc_macro]
475 pub fn paste(input: TokenStream) -> TokenStream {
476     let mut tokens = proc_macro2::TokenStream::from(input).into_iter().collect();
477     paste::expand(&mut tokens);
478     tokens
479         .into_iter()
480         .collect::<proc_macro2::TokenStream>()
481         .into()
482 }
483 
484 /// Registers a KUnit test suite and its test cases using a user-space like syntax.
485 ///
486 /// This macro should be used on modules. If `CONFIG_KUNIT` (in `.config`) is `n`, the target module
487 /// is ignored.
488 ///
489 /// # Examples
490 ///
491 /// ```ignore
492 /// # use kernel::prelude::*;
493 /// #[kunit_tests(kunit_test_suit_name)]
494 /// mod tests {
495 ///     #[test]
496 ///     fn foo() {
497 ///         assert_eq!(1, 1);
498 ///     }
499 ///
500 ///     #[test]
501 ///     fn bar() {
502 ///         assert_eq!(2, 2);
503 ///     }
504 /// }
505 /// ```
506 #[proc_macro_attribute]
507 pub fn kunit_tests(attr: TokenStream, input: TokenStream) -> TokenStream {
508     kunit::kunit_tests(parse_macro_input!(attr), parse_macro_input!(input))
509         .unwrap_or_else(|e| e.into_compile_error())
510         .into()
511 }
512 
513 /// Obtain a type that implements [`ForLt`] for the given higher-ranked type.
514 ///
515 /// Please refer to the documentation of the [`ForLt`] trait.
516 ///
517 /// [`ForLt`]: trait.ForLt.html
518 #[proc_macro]
519 #[allow(non_snake_case)]
520 pub fn ForLt(input: TokenStream) -> TokenStream {
521     for_lt::for_lt(parse_macro_input!(input)).into()
522 }
523 
524 /// Obtain a type that implements [`CovariantForLt`] (and [`ForLt`]) for the given higher-ranked
525 /// type.
526 ///
527 /// Unlike [`ForLt!`], this macro additionally proves that the type is covariant over the lifetime,
528 /// providing a safe [`CovariantForLt::cast_ref`] method.
529 ///
530 /// Please refer to the documentation of the [`CovariantForLt`] trait.
531 ///
532 /// [`CovariantForLt`]: trait.CovariantForLt.html
533 /// [`CovariantForLt::cast_ref`]: trait.CovariantForLt.html#method.cast_ref
534 /// [`ForLt`]: trait.ForLt.html
535 #[proc_macro]
536 #[allow(non_snake_case)]
537 pub fn CovariantForLt(input: TokenStream) -> TokenStream {
538     for_lt::covariant_for_lt(parse_macro_input!(input)).into()
539 }
540