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