Skip to main content

macros/
lib.rs

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