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