11fbde52bSMiguel Ojeda // SPDX-License-Identifier: GPL-2.0
21fbde52bSMiguel Ojeda
31fbde52bSMiguel Ojeda //! Crate for all kernel procedural macros.
41fbde52bSMiguel Ojeda
570a21e54SGary Guo #[macro_use]
670a21e54SGary Guo mod quote;
760f18c22SBjörn Roy Baron mod concat_idents;
81fbde52bSMiguel Ojeda mod helpers;
91fbde52bSMiguel Ojeda mod module;
10823d4737SGary Guo mod paste;
11fc6c6baaSBenno Lossin mod pin_data;
12d0fdc396SBenno Lossin mod pinned_drop;
13b44becc5SGary Guo mod vtable;
14071cedc8SBenno Lossin mod zeroable;
151fbde52bSMiguel Ojeda
161fbde52bSMiguel Ojeda use proc_macro::TokenStream;
171fbde52bSMiguel Ojeda
181fbde52bSMiguel Ojeda /// Declares a kernel module.
191fbde52bSMiguel Ojeda ///
201fbde52bSMiguel Ojeda /// The `type` argument should be a type which implements the [`Module`]
211fbde52bSMiguel Ojeda /// trait. Also accepts various forms of kernel metadata.
221fbde52bSMiguel Ojeda ///
231fbde52bSMiguel Ojeda /// C header: [`include/linux/moduleparam.h`](../../../include/linux/moduleparam.h)
241fbde52bSMiguel Ojeda ///
251fbde52bSMiguel Ojeda /// [`Module`]: ../kernel/trait.Module.html
261fbde52bSMiguel Ojeda ///
271fbde52bSMiguel Ojeda /// # Examples
281fbde52bSMiguel Ojeda ///
291fbde52bSMiguel Ojeda /// ```ignore
301fbde52bSMiguel Ojeda /// use kernel::prelude::*;
311fbde52bSMiguel Ojeda ///
321fbde52bSMiguel Ojeda /// module!{
331fbde52bSMiguel Ojeda /// type: MyModule,
34b13c9880SGary Guo /// name: "my_kernel_module",
35b13c9880SGary Guo /// author: "Rust for Linux Contributors",
36b13c9880SGary Guo /// description: "My very own kernel module!",
37b13c9880SGary Guo /// license: "GPL",
381fbde52bSMiguel Ojeda /// }
391fbde52bSMiguel Ojeda ///
401fbde52bSMiguel Ojeda /// struct MyModule;
411fbde52bSMiguel Ojeda ///
421fbde52bSMiguel Ojeda /// impl kernel::Module for MyModule {
431fbde52bSMiguel Ojeda /// fn init() -> Result<Self> {
441fbde52bSMiguel Ojeda /// // If the parameter is writeable, then the kparam lock must be
451fbde52bSMiguel Ojeda /// // taken to read the parameter:
461fbde52bSMiguel Ojeda /// {
471fbde52bSMiguel Ojeda /// let lock = THIS_MODULE.kernel_param_lock();
481fbde52bSMiguel Ojeda /// pr_info!("i32 param is: {}\n", writeable_i32.read(&lock));
491fbde52bSMiguel Ojeda /// }
501fbde52bSMiguel Ojeda /// // If the parameter is read only, it can be read without locking
511fbde52bSMiguel Ojeda /// // the kernel parameters:
521fbde52bSMiguel Ojeda /// pr_info!("i32 param is: {}\n", my_i32.read());
531fbde52bSMiguel Ojeda /// Ok(Self)
541fbde52bSMiguel Ojeda /// }
551fbde52bSMiguel Ojeda /// }
561fbde52bSMiguel Ojeda /// ```
571fbde52bSMiguel Ojeda ///
581fbde52bSMiguel Ojeda /// # Supported argument types
591fbde52bSMiguel Ojeda /// - `type`: type which implements the [`Module`] trait (required).
601fbde52bSMiguel Ojeda /// - `name`: byte array of the name of the kernel module (required).
611fbde52bSMiguel Ojeda /// - `author`: byte array of the author of the kernel module.
621fbde52bSMiguel Ojeda /// - `description`: byte array of the description of the kernel module.
631fbde52bSMiguel Ojeda /// - `license`: byte array of the license of the kernel module (required).
641fbde52bSMiguel Ojeda /// - `alias`: byte array of alias name of the kernel module.
651fbde52bSMiguel Ojeda #[proc_macro]
module(ts: TokenStream) -> TokenStream661fbde52bSMiguel Ojeda pub fn module(ts: TokenStream) -> TokenStream {
671fbde52bSMiguel Ojeda module::module(ts)
681fbde52bSMiguel Ojeda }
6960f18c22SBjörn Roy Baron
70b44becc5SGary Guo /// Declares or implements a vtable trait.
71b44becc5SGary Guo ///
72b44becc5SGary Guo /// Linux's use of pure vtables is very close to Rust traits, but they differ
73b44becc5SGary Guo /// in how unimplemented functions are represented. In Rust, traits can provide
74b44becc5SGary Guo /// default implementation for all non-required methods (and the default
75b44becc5SGary Guo /// implementation could just return `Error::EINVAL`); Linux typically use C
76b44becc5SGary Guo /// `NULL` pointers to represent these functions.
77b44becc5SGary Guo ///
78b44becc5SGary Guo /// This attribute is intended to close the gap. Traits can be declared and
79b44becc5SGary Guo /// implemented with the `#[vtable]` attribute, and a `HAS_*` associated constant
80b44becc5SGary Guo /// will be generated for each method in the trait, indicating if the implementor
81b44becc5SGary Guo /// has overridden a method.
82b44becc5SGary Guo ///
83b44becc5SGary Guo /// This attribute is not needed if all methods are required.
84b44becc5SGary Guo ///
85b44becc5SGary Guo /// # Examples
86b44becc5SGary Guo ///
87b44becc5SGary Guo /// ```ignore
88b44becc5SGary Guo /// use kernel::prelude::*;
89b44becc5SGary Guo ///
90b44becc5SGary Guo /// // Declares a `#[vtable]` trait
91b44becc5SGary Guo /// #[vtable]
92b44becc5SGary Guo /// pub trait Operations: Send + Sync + Sized {
93b44becc5SGary Guo /// fn foo(&self) -> Result<()> {
94b44becc5SGary Guo /// Err(EINVAL)
95b44becc5SGary Guo /// }
96b44becc5SGary Guo ///
97b44becc5SGary Guo /// fn bar(&self) -> Result<()> {
98b44becc5SGary Guo /// Err(EINVAL)
99b44becc5SGary Guo /// }
100b44becc5SGary Guo /// }
101b44becc5SGary Guo ///
102b44becc5SGary Guo /// struct Foo;
103b44becc5SGary Guo ///
104b44becc5SGary Guo /// // Implements the `#[vtable]` trait
105b44becc5SGary Guo /// #[vtable]
106b44becc5SGary Guo /// impl Operations for Foo {
107b44becc5SGary Guo /// fn foo(&self) -> Result<()> {
108b44becc5SGary Guo /// # Err(EINVAL)
109b44becc5SGary Guo /// // ...
110b44becc5SGary Guo /// }
111b44becc5SGary Guo /// }
112b44becc5SGary Guo ///
113b44becc5SGary Guo /// assert_eq!(<Foo as Operations>::HAS_FOO, true);
114b44becc5SGary Guo /// assert_eq!(<Foo as Operations>::HAS_BAR, false);
115b44becc5SGary Guo /// ```
116b44becc5SGary Guo #[proc_macro_attribute]
vtable(attr: TokenStream, ts: TokenStream) -> TokenStream117b44becc5SGary Guo pub fn vtable(attr: TokenStream, ts: TokenStream) -> TokenStream {
118b44becc5SGary Guo vtable::vtable(attr, ts)
119b44becc5SGary Guo }
120b44becc5SGary Guo
12160f18c22SBjörn Roy Baron /// Concatenate two identifiers.
12260f18c22SBjörn Roy Baron ///
12360f18c22SBjörn Roy Baron /// This is useful in macros that need to declare or reference items with names
12460f18c22SBjörn Roy Baron /// starting with a fixed prefix and ending in a user specified name. The resulting
12560f18c22SBjörn Roy Baron /// identifier has the span of the second argument.
12660f18c22SBjörn Roy Baron ///
12760f18c22SBjörn Roy Baron /// # Examples
12860f18c22SBjörn Roy Baron ///
12960f18c22SBjörn Roy Baron /// ```ignore
13060f18c22SBjörn Roy Baron /// use kernel::macro::concat_idents;
13160f18c22SBjörn Roy Baron ///
13260f18c22SBjörn Roy Baron /// macro_rules! pub_no_prefix {
13360f18c22SBjörn Roy Baron /// ($prefix:ident, $($newname:ident),+) => {
13460f18c22SBjörn Roy Baron /// $(pub(crate) const $newname: u32 = kernel::macros::concat_idents!($prefix, $newname);)+
13560f18c22SBjörn Roy Baron /// };
13660f18c22SBjörn Roy Baron /// }
13760f18c22SBjörn Roy Baron ///
13860f18c22SBjörn Roy Baron /// pub_no_prefix!(
13960f18c22SBjörn Roy Baron /// binder_driver_return_protocol_,
14060f18c22SBjörn Roy Baron /// BR_OK,
14160f18c22SBjörn Roy Baron /// BR_ERROR,
14260f18c22SBjörn Roy Baron /// BR_TRANSACTION,
14360f18c22SBjörn Roy Baron /// BR_REPLY,
14460f18c22SBjörn Roy Baron /// BR_DEAD_REPLY,
14560f18c22SBjörn Roy Baron /// BR_TRANSACTION_COMPLETE,
14660f18c22SBjörn Roy Baron /// BR_INCREFS,
14760f18c22SBjörn Roy Baron /// BR_ACQUIRE,
14860f18c22SBjörn Roy Baron /// BR_RELEASE,
14960f18c22SBjörn Roy Baron /// BR_DECREFS,
15060f18c22SBjörn Roy Baron /// BR_NOOP,
15160f18c22SBjörn Roy Baron /// BR_SPAWN_LOOPER,
15260f18c22SBjörn Roy Baron /// BR_DEAD_BINDER,
15360f18c22SBjörn Roy Baron /// BR_CLEAR_DEATH_NOTIFICATION_DONE,
15460f18c22SBjörn Roy Baron /// BR_FAILED_REPLY
15560f18c22SBjörn Roy Baron /// );
15660f18c22SBjörn Roy Baron ///
15760f18c22SBjörn Roy Baron /// assert_eq!(BR_OK, binder_driver_return_protocol_BR_OK);
15860f18c22SBjörn Roy Baron /// ```
15960f18c22SBjörn Roy Baron #[proc_macro]
concat_idents(ts: TokenStream) -> TokenStream16060f18c22SBjörn Roy Baron pub fn concat_idents(ts: TokenStream) -> TokenStream {
16160f18c22SBjörn Roy Baron concat_idents::concat_idents(ts)
16260f18c22SBjörn Roy Baron }
163fc6c6baaSBenno Lossin
164fc6c6baaSBenno Lossin /// Used to specify the pinning information of the fields of a struct.
165fc6c6baaSBenno Lossin ///
166fc6c6baaSBenno Lossin /// This is somewhat similar in purpose as
167fc6c6baaSBenno Lossin /// [pin-project-lite](https://crates.io/crates/pin-project-lite).
168fc6c6baaSBenno Lossin /// Place this macro on a struct definition and then `#[pin]` in front of the attributes of each
169fc6c6baaSBenno Lossin /// field you want to structurally pin.
170fc6c6baaSBenno Lossin ///
171fc6c6baaSBenno Lossin /// This macro enables the use of the [`pin_init!`] macro. When pin-initializing a `struct`,
172fc6c6baaSBenno Lossin /// then `#[pin]` directs the type of initializer that is required.
173fc6c6baaSBenno Lossin ///
174d0fdc396SBenno Lossin /// If your `struct` implements `Drop`, then you need to add `PinnedDrop` as arguments to this
175d0fdc396SBenno Lossin /// macro, and change your `Drop` implementation to `PinnedDrop` annotated with
176d0fdc396SBenno Lossin /// `#[`[`macro@pinned_drop`]`]`, since dropping pinned values requires extra care.
177d0fdc396SBenno Lossin ///
178fc6c6baaSBenno Lossin /// # Examples
179fc6c6baaSBenno Lossin ///
180fc6c6baaSBenno Lossin /// ```rust,ignore
181fc6c6baaSBenno Lossin /// #[pin_data]
182fc6c6baaSBenno Lossin /// struct DriverData {
183fc6c6baaSBenno Lossin /// #[pin]
184fc6c6baaSBenno Lossin /// queue: Mutex<Vec<Command>>,
185fc6c6baaSBenno Lossin /// buf: Box<[u8; 1024 * 1024]>,
186fc6c6baaSBenno Lossin /// }
187fc6c6baaSBenno Lossin /// ```
188fc6c6baaSBenno Lossin ///
189d0fdc396SBenno Lossin /// ```rust,ignore
190d0fdc396SBenno Lossin /// #[pin_data(PinnedDrop)]
191d0fdc396SBenno Lossin /// struct DriverData {
192d0fdc396SBenno Lossin /// #[pin]
193d0fdc396SBenno Lossin /// queue: Mutex<Vec<Command>>,
194d0fdc396SBenno Lossin /// buf: Box<[u8; 1024 * 1024]>,
195d0fdc396SBenno Lossin /// raw_info: *mut Info,
196d0fdc396SBenno Lossin /// }
197d0fdc396SBenno Lossin ///
198d0fdc396SBenno Lossin /// #[pinned_drop]
199d0fdc396SBenno Lossin /// impl PinnedDrop for DriverData {
200d0fdc396SBenno Lossin /// fn drop(self: Pin<&mut Self>) {
201d0fdc396SBenno Lossin /// unsafe { bindings::destroy_info(self.raw_info) };
202d0fdc396SBenno Lossin /// }
203d0fdc396SBenno Lossin /// }
204d0fdc396SBenno Lossin /// ```
205d0fdc396SBenno Lossin ///
206fc6c6baaSBenno Lossin /// [`pin_init!`]: ../kernel/macro.pin_init.html
207fc6c6baaSBenno Lossin // ^ cannot use direct link, since `kernel` is not a dependency of `macros`.
208fc6c6baaSBenno Lossin #[proc_macro_attribute]
pin_data(inner: TokenStream, item: TokenStream) -> TokenStream209fc6c6baaSBenno Lossin pub fn pin_data(inner: TokenStream, item: TokenStream) -> TokenStream {
210fc6c6baaSBenno Lossin pin_data::pin_data(inner, item)
211fc6c6baaSBenno Lossin }
212d0fdc396SBenno Lossin
213d0fdc396SBenno Lossin /// Used to implement `PinnedDrop` safely.
214d0fdc396SBenno Lossin ///
215d0fdc396SBenno Lossin /// Only works on structs that are annotated via `#[`[`macro@pin_data`]`]`.
216d0fdc396SBenno Lossin ///
217d0fdc396SBenno Lossin /// # Examples
218d0fdc396SBenno Lossin ///
219d0fdc396SBenno Lossin /// ```rust,ignore
220d0fdc396SBenno Lossin /// #[pin_data(PinnedDrop)]
221d0fdc396SBenno Lossin /// struct DriverData {
222d0fdc396SBenno Lossin /// #[pin]
223d0fdc396SBenno Lossin /// queue: Mutex<Vec<Command>>,
224d0fdc396SBenno Lossin /// buf: Box<[u8; 1024 * 1024]>,
225d0fdc396SBenno Lossin /// raw_info: *mut Info,
226d0fdc396SBenno Lossin /// }
227d0fdc396SBenno Lossin ///
228d0fdc396SBenno Lossin /// #[pinned_drop]
229d0fdc396SBenno Lossin /// impl PinnedDrop for DriverData {
230d0fdc396SBenno Lossin /// fn drop(self: Pin<&mut Self>) {
231d0fdc396SBenno Lossin /// unsafe { bindings::destroy_info(self.raw_info) };
232d0fdc396SBenno Lossin /// }
233d0fdc396SBenno Lossin /// }
234d0fdc396SBenno Lossin /// ```
235d0fdc396SBenno Lossin #[proc_macro_attribute]
pinned_drop(args: TokenStream, input: TokenStream) -> TokenStream236d0fdc396SBenno Lossin pub fn pinned_drop(args: TokenStream, input: TokenStream) -> TokenStream {
237d0fdc396SBenno Lossin pinned_drop::pinned_drop(args, input)
238d0fdc396SBenno Lossin }
239823d4737SGary Guo
240823d4737SGary Guo /// Paste identifiers together.
241823d4737SGary Guo ///
242823d4737SGary Guo /// Within the `paste!` macro, identifiers inside `[<` and `>]` are concatenated together to form a
243823d4737SGary Guo /// single identifier.
244823d4737SGary Guo ///
245823d4737SGary Guo /// This is similar to the [`paste`] crate, but with pasting feature limited to identifiers
246823d4737SGary Guo /// (literals, lifetimes and documentation strings are not supported). There is a difference in
247823d4737SGary Guo /// supported modifiers as well.
248823d4737SGary Guo ///
249823d4737SGary Guo /// # Example
250823d4737SGary Guo ///
251823d4737SGary Guo /// ```ignore
252823d4737SGary Guo /// use kernel::macro::paste;
253823d4737SGary Guo ///
254823d4737SGary Guo /// macro_rules! pub_no_prefix {
255823d4737SGary Guo /// ($prefix:ident, $($newname:ident),+) => {
256823d4737SGary Guo /// paste! {
257823d4737SGary Guo /// $(pub(crate) const $newname: u32 = [<$prefix $newname>];)+
258823d4737SGary Guo /// }
259823d4737SGary Guo /// };
260823d4737SGary Guo /// }
261823d4737SGary Guo ///
262823d4737SGary Guo /// pub_no_prefix!(
263823d4737SGary Guo /// binder_driver_return_protocol_,
264823d4737SGary Guo /// BR_OK,
265823d4737SGary Guo /// BR_ERROR,
266823d4737SGary Guo /// BR_TRANSACTION,
267823d4737SGary Guo /// BR_REPLY,
268823d4737SGary Guo /// BR_DEAD_REPLY,
269823d4737SGary Guo /// BR_TRANSACTION_COMPLETE,
270823d4737SGary Guo /// BR_INCREFS,
271823d4737SGary Guo /// BR_ACQUIRE,
272823d4737SGary Guo /// BR_RELEASE,
273823d4737SGary Guo /// BR_DECREFS,
274823d4737SGary Guo /// BR_NOOP,
275823d4737SGary Guo /// BR_SPAWN_LOOPER,
276823d4737SGary Guo /// BR_DEAD_BINDER,
277823d4737SGary Guo /// BR_CLEAR_DEATH_NOTIFICATION_DONE,
278823d4737SGary Guo /// BR_FAILED_REPLY
279823d4737SGary Guo /// );
280823d4737SGary Guo ///
281823d4737SGary Guo /// assert_eq!(BR_OK, binder_driver_return_protocol_BR_OK);
282823d4737SGary Guo /// ```
283823d4737SGary Guo ///
284823d4737SGary Guo /// # Modifiers
285823d4737SGary Guo ///
286823d4737SGary Guo /// For each identifier, it is possible to attach one or multiple modifiers to
287823d4737SGary Guo /// it.
288823d4737SGary Guo ///
289823d4737SGary Guo /// Currently supported modifiers are:
290823d4737SGary Guo /// * `span`: change the span of concatenated identifier to the span of the specified token. By
291823d4737SGary Guo /// default the span of the `[< >]` group is used.
292823d4737SGary Guo /// * `lower`: change the identifier to lower case.
293823d4737SGary Guo /// * `upper`: change the identifier to upper case.
294823d4737SGary Guo ///
295823d4737SGary Guo /// ```ignore
296823d4737SGary Guo /// use kernel::macro::paste;
297823d4737SGary Guo ///
298823d4737SGary Guo /// macro_rules! pub_no_prefix {
299823d4737SGary Guo /// ($prefix:ident, $($newname:ident),+) => {
300823d4737SGary Guo /// kernel::macros::paste! {
301*b7c4121aSPaolo Bonzini /// $(pub(crate) const fn [<$newname:lower:span>]() -> u32 { [<$prefix $newname:span>] })+
302823d4737SGary Guo /// }
303823d4737SGary Guo /// };
304823d4737SGary Guo /// }
305823d4737SGary Guo ///
306823d4737SGary Guo /// pub_no_prefix!(
307823d4737SGary Guo /// binder_driver_return_protocol_,
308823d4737SGary Guo /// BR_OK,
309823d4737SGary Guo /// BR_ERROR,
310823d4737SGary Guo /// BR_TRANSACTION,
311823d4737SGary Guo /// BR_REPLY,
312823d4737SGary Guo /// BR_DEAD_REPLY,
313823d4737SGary Guo /// BR_TRANSACTION_COMPLETE,
314823d4737SGary Guo /// BR_INCREFS,
315823d4737SGary Guo /// BR_ACQUIRE,
316823d4737SGary Guo /// BR_RELEASE,
317823d4737SGary Guo /// BR_DECREFS,
318823d4737SGary Guo /// BR_NOOP,
319823d4737SGary Guo /// BR_SPAWN_LOOPER,
320823d4737SGary Guo /// BR_DEAD_BINDER,
321823d4737SGary Guo /// BR_CLEAR_DEATH_NOTIFICATION_DONE,
322823d4737SGary Guo /// BR_FAILED_REPLY
323823d4737SGary Guo /// );
324823d4737SGary Guo ///
325823d4737SGary Guo /// assert_eq!(br_ok(), binder_driver_return_protocol_BR_OK);
326823d4737SGary Guo /// ```
327823d4737SGary Guo ///
328823d4737SGary Guo /// [`paste`]: https://docs.rs/paste/
329823d4737SGary Guo #[proc_macro]
paste(input: TokenStream) -> TokenStream330823d4737SGary Guo pub fn paste(input: TokenStream) -> TokenStream {
331823d4737SGary Guo let mut tokens = input.into_iter().collect();
332823d4737SGary Guo paste::expand(&mut tokens);
333823d4737SGary Guo tokens.into_iter().collect()
334823d4737SGary Guo }
335071cedc8SBenno Lossin
336071cedc8SBenno Lossin /// Derives the [`Zeroable`] trait for the given struct.
337071cedc8SBenno Lossin ///
338071cedc8SBenno Lossin /// This can only be used for structs where every field implements the [`Zeroable`] trait.
339071cedc8SBenno Lossin ///
340071cedc8SBenno Lossin /// # Examples
341071cedc8SBenno Lossin ///
342071cedc8SBenno Lossin /// ```rust,ignore
343071cedc8SBenno Lossin /// #[derive(Zeroable)]
344071cedc8SBenno Lossin /// pub struct DriverData {
345071cedc8SBenno Lossin /// id: i64,
346071cedc8SBenno Lossin /// buf_ptr: *mut u8,
347071cedc8SBenno Lossin /// len: usize,
348071cedc8SBenno Lossin /// }
349071cedc8SBenno Lossin /// ```
350071cedc8SBenno Lossin #[proc_macro_derive(Zeroable)]
derive_zeroable(input: TokenStream) -> TokenStream351071cedc8SBenno Lossin pub fn derive_zeroable(input: TokenStream) -> TokenStream {
352071cedc8SBenno Lossin zeroable::derive(input)
353071cedc8SBenno Lossin }
354