lib.rs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432
  1. // SPDX-License-Identifier: GPL-2.0
  2. //! Crate for all kernel procedural macros.
  3. // When fixdep scans this, it will find this string `CONFIG_RUSTC_VERSION_TEXT`
  4. // and thus add a dependency on `include/config/RUSTC_VERSION_TEXT`, which is
  5. // touched by Kconfig when the version string from the compiler changes.
  6. #[macro_use]
  7. mod quote;
  8. mod concat_idents;
  9. mod helpers;
  10. mod module;
  11. mod paste;
  12. mod pin_data;
  13. mod pinned_drop;
  14. mod vtable;
  15. mod zeroable;
  16. use proc_macro::TokenStream;
  17. /// Declares a kernel module.
  18. ///
  19. /// The `type` argument should be a type which implements the [`Module`]
  20. /// trait. Also accepts various forms of kernel metadata.
  21. ///
  22. /// C header: [`include/linux/moduleparam.h`](srctree/include/linux/moduleparam.h)
  23. ///
  24. /// [`Module`]: ../kernel/trait.Module.html
  25. ///
  26. /// # Examples
  27. ///
  28. /// ```ignore
  29. /// use kernel::prelude::*;
  30. ///
  31. /// module!{
  32. /// type: MyModule,
  33. /// name: "my_kernel_module",
  34. /// author: "Rust for Linux Contributors",
  35. /// description: "My very own kernel module!",
  36. /// license: "GPL",
  37. /// alias: ["alternate_module_name"],
  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. /// ## Firmware
  59. ///
  60. /// The following example shows how to declare a kernel module that needs
  61. /// to load binary firmware files. You need to specify the file names of
  62. /// the firmware in the `firmware` field. The information is embedded
  63. /// in the `modinfo` section of the kernel module. For example, a tool to
  64. /// build an initramfs uses this information to put the firmware files into
  65. /// the initramfs image.
  66. ///
  67. /// ```ignore
  68. /// use kernel::prelude::*;
  69. ///
  70. /// module!{
  71. /// type: MyDeviceDriverModule,
  72. /// name: "my_device_driver_module",
  73. /// author: "Rust for Linux Contributors",
  74. /// description: "My device driver requires firmware",
  75. /// license: "GPL",
  76. /// firmware: ["my_device_firmware1.bin", "my_device_firmware2.bin"],
  77. /// }
  78. ///
  79. /// struct MyDeviceDriverModule;
  80. ///
  81. /// impl kernel::Module for MyDeviceDriverModule {
  82. /// fn init() -> Result<Self> {
  83. /// Ok(Self)
  84. /// }
  85. /// }
  86. /// ```
  87. ///
  88. /// # Supported argument types
  89. /// - `type`: type which implements the [`Module`] trait (required).
  90. /// - `name`: ASCII string literal of the name of the kernel module (required).
  91. /// - `author`: string literal of the author of the kernel module.
  92. /// - `description`: string literal of the description of the kernel module.
  93. /// - `license`: ASCII string literal of the license of the kernel module (required).
  94. /// - `alias`: array of ASCII string literals of the alias names of the kernel module.
  95. /// - `firmware`: array of ASCII string literals of the firmware files of
  96. /// the kernel module.
  97. #[proc_macro]
  98. pub fn module(ts: TokenStream) -> TokenStream {
  99. module::module(ts)
  100. }
  101. /// Declares or implements a vtable trait.
  102. ///
  103. /// Linux's use of pure vtables is very close to Rust traits, but they differ
  104. /// in how unimplemented functions are represented. In Rust, traits can provide
  105. /// default implementation for all non-required methods (and the default
  106. /// implementation could just return `Error::EINVAL`); Linux typically use C
  107. /// `NULL` pointers to represent these functions.
  108. ///
  109. /// This attribute closes that gap. A trait can be annotated with the
  110. /// `#[vtable]` attribute. Implementers of the trait will then also have to
  111. /// annotate the trait with `#[vtable]`. This attribute generates a `HAS_*`
  112. /// associated constant bool for each method in the trait that is set to true if
  113. /// the implementer has overridden the associated method.
  114. ///
  115. /// For a trait method to be optional, it must have a default implementation.
  116. /// This is also the case for traits annotated with `#[vtable]`, but in this
  117. /// case the default implementation will never be executed. The reason for this
  118. /// is that the functions will be called through function pointers installed in
  119. /// C side vtables. When an optional method is not implemented on a `#[vtable]`
  120. /// trait, a NULL entry is installed in the vtable. Thus the default
  121. /// implementation is never called. Since these traits are not designed to be
  122. /// used on the Rust side, it should not be possible to call the default
  123. /// implementation. This is done to ensure that we call the vtable methods
  124. /// through the C vtable, and not through the Rust vtable. Therefore, the
  125. /// default implementation should call `kernel::build_error`, which prevents
  126. /// calls to this function at compile time:
  127. ///
  128. /// ```compile_fail
  129. /// # use kernel::error::VTABLE_DEFAULT_ERROR;
  130. /// kernel::build_error(VTABLE_DEFAULT_ERROR)
  131. /// ```
  132. ///
  133. /// Note that you might need to import [`kernel::error::VTABLE_DEFAULT_ERROR`].
  134. ///
  135. /// This macro should not be used when all functions are required.
  136. ///
  137. /// # Examples
  138. ///
  139. /// ```ignore
  140. /// use kernel::error::VTABLE_DEFAULT_ERROR;
  141. /// use kernel::prelude::*;
  142. ///
  143. /// // Declares a `#[vtable]` trait
  144. /// #[vtable]
  145. /// pub trait Operations: Send + Sync + Sized {
  146. /// fn foo(&self) -> Result<()> {
  147. /// kernel::build_error(VTABLE_DEFAULT_ERROR)
  148. /// }
  149. ///
  150. /// fn bar(&self) -> Result<()> {
  151. /// kernel::build_error(VTABLE_DEFAULT_ERROR)
  152. /// }
  153. /// }
  154. ///
  155. /// struct Foo;
  156. ///
  157. /// // Implements the `#[vtable]` trait
  158. /// #[vtable]
  159. /// impl Operations for Foo {
  160. /// fn foo(&self) -> Result<()> {
  161. /// # Err(EINVAL)
  162. /// // ...
  163. /// }
  164. /// }
  165. ///
  166. /// assert_eq!(<Foo as Operations>::HAS_FOO, true);
  167. /// assert_eq!(<Foo as Operations>::HAS_BAR, false);
  168. /// ```
  169. ///
  170. /// [`kernel::error::VTABLE_DEFAULT_ERROR`]: ../kernel/error/constant.VTABLE_DEFAULT_ERROR.html
  171. #[proc_macro_attribute]
  172. pub fn vtable(attr: TokenStream, ts: TokenStream) -> TokenStream {
  173. vtable::vtable(attr, ts)
  174. }
  175. /// Concatenate two identifiers.
  176. ///
  177. /// This is useful in macros that need to declare or reference items with names
  178. /// starting with a fixed prefix and ending in a user specified name. The resulting
  179. /// identifier has the span of the second argument.
  180. ///
  181. /// # Examples
  182. ///
  183. /// ```ignore
  184. /// use kernel::macro::concat_idents;
  185. ///
  186. /// macro_rules! pub_no_prefix {
  187. /// ($prefix:ident, $($newname:ident),+) => {
  188. /// $(pub(crate) const $newname: u32 = kernel::macros::concat_idents!($prefix, $newname);)+
  189. /// };
  190. /// }
  191. ///
  192. /// pub_no_prefix!(
  193. /// binder_driver_return_protocol_,
  194. /// BR_OK,
  195. /// BR_ERROR,
  196. /// BR_TRANSACTION,
  197. /// BR_REPLY,
  198. /// BR_DEAD_REPLY,
  199. /// BR_TRANSACTION_COMPLETE,
  200. /// BR_INCREFS,
  201. /// BR_ACQUIRE,
  202. /// BR_RELEASE,
  203. /// BR_DECREFS,
  204. /// BR_NOOP,
  205. /// BR_SPAWN_LOOPER,
  206. /// BR_DEAD_BINDER,
  207. /// BR_CLEAR_DEATH_NOTIFICATION_DONE,
  208. /// BR_FAILED_REPLY
  209. /// );
  210. ///
  211. /// assert_eq!(BR_OK, binder_driver_return_protocol_BR_OK);
  212. /// ```
  213. #[proc_macro]
  214. pub fn concat_idents(ts: TokenStream) -> TokenStream {
  215. concat_idents::concat_idents(ts)
  216. }
  217. /// Used to specify the pinning information of the fields of a struct.
  218. ///
  219. /// This is somewhat similar in purpose as
  220. /// [pin-project-lite](https://crates.io/crates/pin-project-lite).
  221. /// Place this macro on a struct definition and then `#[pin]` in front of the attributes of each
  222. /// field you want to structurally pin.
  223. ///
  224. /// This macro enables the use of the [`pin_init!`] macro. When pin-initializing a `struct`,
  225. /// then `#[pin]` directs the type of initializer that is required.
  226. ///
  227. /// If your `struct` implements `Drop`, then you need to add `PinnedDrop` as arguments to this
  228. /// macro, and change your `Drop` implementation to `PinnedDrop` annotated with
  229. /// `#[`[`macro@pinned_drop`]`]`, since dropping pinned values requires extra care.
  230. ///
  231. /// # Examples
  232. ///
  233. /// ```rust,ignore
  234. /// #[pin_data]
  235. /// struct DriverData {
  236. /// #[pin]
  237. /// queue: Mutex<Vec<Command>>,
  238. /// buf: Box<[u8; 1024 * 1024]>,
  239. /// }
  240. /// ```
  241. ///
  242. /// ```rust,ignore
  243. /// #[pin_data(PinnedDrop)]
  244. /// struct DriverData {
  245. /// #[pin]
  246. /// queue: Mutex<Vec<Command>>,
  247. /// buf: Box<[u8; 1024 * 1024]>,
  248. /// raw_info: *mut Info,
  249. /// }
  250. ///
  251. /// #[pinned_drop]
  252. /// impl PinnedDrop for DriverData {
  253. /// fn drop(self: Pin<&mut Self>) {
  254. /// unsafe { bindings::destroy_info(self.raw_info) };
  255. /// }
  256. /// }
  257. /// ```
  258. ///
  259. /// [`pin_init!`]: ../kernel/macro.pin_init.html
  260. // ^ cannot use direct link, since `kernel` is not a dependency of `macros`.
  261. #[proc_macro_attribute]
  262. pub fn pin_data(inner: TokenStream, item: TokenStream) -> TokenStream {
  263. pin_data::pin_data(inner, item)
  264. }
  265. /// Used to implement `PinnedDrop` safely.
  266. ///
  267. /// Only works on structs that are annotated via `#[`[`macro@pin_data`]`]`.
  268. ///
  269. /// # Examples
  270. ///
  271. /// ```rust,ignore
  272. /// #[pin_data(PinnedDrop)]
  273. /// struct DriverData {
  274. /// #[pin]
  275. /// queue: Mutex<Vec<Command>>,
  276. /// buf: Box<[u8; 1024 * 1024]>,
  277. /// raw_info: *mut Info,
  278. /// }
  279. ///
  280. /// #[pinned_drop]
  281. /// impl PinnedDrop for DriverData {
  282. /// fn drop(self: Pin<&mut Self>) {
  283. /// unsafe { bindings::destroy_info(self.raw_info) };
  284. /// }
  285. /// }
  286. /// ```
  287. #[proc_macro_attribute]
  288. pub fn pinned_drop(args: TokenStream, input: TokenStream) -> TokenStream {
  289. pinned_drop::pinned_drop(args, input)
  290. }
  291. /// Paste identifiers together.
  292. ///
  293. /// Within the `paste!` macro, identifiers inside `[<` and `>]` are concatenated together to form a
  294. /// single identifier.
  295. ///
  296. /// This is similar to the [`paste`] crate, but with pasting feature limited to identifiers and
  297. /// literals (lifetimes and documentation strings are not supported). There is a difference in
  298. /// supported modifiers as well.
  299. ///
  300. /// # Example
  301. ///
  302. /// ```ignore
  303. /// use kernel::macro::paste;
  304. ///
  305. /// macro_rules! pub_no_prefix {
  306. /// ($prefix:ident, $($newname:ident),+) => {
  307. /// paste! {
  308. /// $(pub(crate) const $newname: u32 = [<$prefix $newname>];)+
  309. /// }
  310. /// };
  311. /// }
  312. ///
  313. /// pub_no_prefix!(
  314. /// binder_driver_return_protocol_,
  315. /// BR_OK,
  316. /// BR_ERROR,
  317. /// BR_TRANSACTION,
  318. /// BR_REPLY,
  319. /// BR_DEAD_REPLY,
  320. /// BR_TRANSACTION_COMPLETE,
  321. /// BR_INCREFS,
  322. /// BR_ACQUIRE,
  323. /// BR_RELEASE,
  324. /// BR_DECREFS,
  325. /// BR_NOOP,
  326. /// BR_SPAWN_LOOPER,
  327. /// BR_DEAD_BINDER,
  328. /// BR_CLEAR_DEATH_NOTIFICATION_DONE,
  329. /// BR_FAILED_REPLY
  330. /// );
  331. ///
  332. /// assert_eq!(BR_OK, binder_driver_return_protocol_BR_OK);
  333. /// ```
  334. ///
  335. /// # Modifiers
  336. ///
  337. /// For each identifier, it is possible to attach one or multiple modifiers to
  338. /// it.
  339. ///
  340. /// Currently supported modifiers are:
  341. /// * `span`: change the span of concatenated identifier to the span of the specified token. By
  342. /// default the span of the `[< >]` group is used.
  343. /// * `lower`: change the identifier to lower case.
  344. /// * `upper`: change the identifier to upper case.
  345. ///
  346. /// ```ignore
  347. /// use kernel::macro::paste;
  348. ///
  349. /// macro_rules! pub_no_prefix {
  350. /// ($prefix:ident, $($newname:ident),+) => {
  351. /// kernel::macros::paste! {
  352. /// $(pub(crate) const fn [<$newname:lower:span>]() -> u32 { [<$prefix $newname:span>] })+
  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. /// # Literals
  380. ///
  381. /// Literals can also be concatenated with other identifiers:
  382. ///
  383. /// ```ignore
  384. /// macro_rules! create_numbered_fn {
  385. /// ($name:literal, $val:literal) => {
  386. /// kernel::macros::paste! {
  387. /// fn [<some_ $name _fn $val>]() -> u32 { $val }
  388. /// }
  389. /// };
  390. /// }
  391. ///
  392. /// create_numbered_fn!("foo", 100);
  393. ///
  394. /// assert_eq!(some_foo_fn100(), 100)
  395. /// ```
  396. ///
  397. /// [`paste`]: https://docs.rs/paste/
  398. #[proc_macro]
  399. pub fn paste(input: TokenStream) -> TokenStream {
  400. let mut tokens = input.into_iter().collect();
  401. paste::expand(&mut tokens);
  402. tokens.into_iter().collect()
  403. }
  404. /// Derives the [`Zeroable`] trait for the given struct.
  405. ///
  406. /// This can only be used for structs where every field implements the [`Zeroable`] trait.
  407. ///
  408. /// # Examples
  409. ///
  410. /// ```rust,ignore
  411. /// #[derive(Zeroable)]
  412. /// pub struct DriverData {
  413. /// id: i64,
  414. /// buf_ptr: *mut u8,
  415. /// len: usize,
  416. /// }
  417. /// ```
  418. #[proc_macro_derive(Zeroable)]
  419. pub fn derive_zeroable(input: TokenStream) -> TokenStream {
  420. zeroable::derive(input)
  421. }