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