xref: /linux/rust/macros/module.rs (revision c578ad703ae9a219aa4bdd13343cf5254541c5e3)
1 // SPDX-License-Identifier: GPL-2.0
2 
3 use std::fmt::Write;
4 
5 use proc_macro2::{
6     Literal,
7     TokenStream, //
8 };
9 use quote::ToTokens;
10 use syn::{
11     braced,
12     bracketed,
13     ext::IdentExt,
14     parse::{
15         Parse,
16         ParseStream, //
17     },
18     punctuated::Punctuated,
19     Error,
20     Expr,
21     Ident,
22     LitStr,
23     Result,
24     Token, //
25 };
26 
27 use crate::helpers::*;
28 
29 struct ModInfoBuilder<'a> {
30     module: &'a str,
31     counter: usize,
32     buffer: String,
33     param_buffer: String,
34 }
35 
36 impl<'a> ModInfoBuilder<'a> {
37     fn new(module: &'a str) -> Self {
38         ModInfoBuilder {
39             module,
40             counter: 0,
41             buffer: String::new(),
42             param_buffer: String::new(),
43         }
44     }
45 
46     fn emit_base(&mut self, field: &str, content: &str, builtin: bool, param: bool) {
47         let string = if builtin {
48             // Built-in modules prefix their modinfo strings by `module.`.
49             format!(
50                 "{module}.{field}={content}\0",
51                 module = self.module,
52                 field = field,
53                 content = content
54             )
55         } else {
56             // Loadable modules' modinfo strings go as-is.
57             format!("{field}={content}\0")
58         };
59 
60         let buffer = if param {
61             &mut self.param_buffer
62         } else {
63             &mut self.buffer
64         };
65 
66         write!(
67             buffer,
68             "
69                 {cfg}
70                 #[doc(hidden)]
71                 #[cfg_attr(not(target_os = \"macos\"), link_section = \".modinfo\")]
72                 #[used(compiler)]
73                 pub static __{module}_{counter}: [u8; {length}] = *{string};
74             ",
75             cfg = if builtin {
76                 "#[cfg(not(MODULE))]"
77             } else {
78                 "#[cfg(MODULE)]"
79             },
80             module = self.module.to_uppercase(),
81             counter = self.counter,
82             length = string.len(),
83             string = Literal::byte_string(string.as_bytes()),
84         )
85         .unwrap();
86 
87         self.counter += 1;
88     }
89 
90     fn emit_only_builtin(&mut self, field: &str, content: &str, param: bool) {
91         self.emit_base(field, content, true, param)
92     }
93 
94     fn emit_only_loadable(&mut self, field: &str, content: &str, param: bool) {
95         self.emit_base(field, content, false, param)
96     }
97 
98     fn emit(&mut self, field: &str, content: &str) {
99         self.emit_internal(field, content, false);
100     }
101 
102     fn emit_internal(&mut self, field: &str, content: &str, param: bool) {
103         self.emit_only_builtin(field, content, param);
104         self.emit_only_loadable(field, content, param);
105     }
106 
107     fn emit_param(&mut self, field: &str, param: &str, content: &str) {
108         let content = format!("{param}:{content}", param = param, content = content);
109         self.emit_internal(field, &content, true);
110     }
111 
112     fn emit_params(&mut self, info: &ModuleInfo) {
113         let Some(params) = &info.params else {
114             return;
115         };
116 
117         for param in params {
118             let param_name_str = param.name.to_string();
119             let param_type_str = param.ptype.to_string();
120             let param_default = param.default.to_token_stream().to_string();
121 
122             let ops = param_ops_path(&param_type_str);
123 
124             // Note: The spelling of these fields is dictated by the user space
125             // tool `modinfo`.
126             self.emit_param("parmtype", &param_name_str, &param_type_str);
127             self.emit_param("parm", &param_name_str, &param.description.value());
128 
129             write!(
130                 self.param_buffer,
131                 "
132                 pub(crate) static {param_name_str}:
133                     ::kernel::module_param::ModuleParamAccess<{param_type_str}> =
134                         ::kernel::module_param::ModuleParamAccess::new({param_default});
135 
136                 const _: () = {{
137                     #[link_section = \"__param\"]
138                     #[used]
139                     static __{module_name}_{param_name_str}_struct:
140                         ::kernel::module_param::KernelParam =
141                         ::kernel::module_param::KernelParam::new(
142                             ::kernel::bindings::kernel_param {{
143                                 name: if ::core::cfg!(MODULE) {{
144                                     ::kernel::c_str!(\"{param_name_str}\").to_bytes_with_nul()
145                                 }} else {{
146                                     ::kernel::c_str!(\"{module_name}.{param_name_str}\")
147                                         .to_bytes_with_nul()
148                                 }}.as_ptr(),
149                                 // SAFETY: `__this_module` is constructed by the kernel at load
150                                 // time and will not be freed until the module is unloaded.
151                                 #[cfg(MODULE)]
152                                 mod_: unsafe {{
153                                     core::ptr::from_ref(&::kernel::bindings::__this_module)
154                                         .cast_mut()
155                                 }},
156                                 #[cfg(not(MODULE))]
157                                 mod_: ::core::ptr::null_mut(),
158                                 ops: core::ptr::from_ref(&{ops}),
159                                 perm: 0, // Will not appear in sysfs
160                                 level: -1,
161                                 flags: 0,
162                                 __bindgen_anon_1: ::kernel::bindings::kernel_param__bindgen_ty_1 {{
163                                     arg: {param_name_str}.as_void_ptr()
164                                 }},
165                             }}
166                         );
167                 }};
168                 ",
169                 module_name = info.name.value(),
170                 ops = ops,
171             )
172             .unwrap();
173         }
174     }
175 }
176 
177 fn param_ops_path(param_type: &str) -> &'static str {
178     match param_type {
179         "i8" => "::kernel::module_param::PARAM_OPS_I8",
180         "u8" => "::kernel::module_param::PARAM_OPS_U8",
181         "i16" => "::kernel::module_param::PARAM_OPS_I16",
182         "u16" => "::kernel::module_param::PARAM_OPS_U16",
183         "i32" => "::kernel::module_param::PARAM_OPS_I32",
184         "u32" => "::kernel::module_param::PARAM_OPS_U32",
185         "i64" => "::kernel::module_param::PARAM_OPS_I64",
186         "u64" => "::kernel::module_param::PARAM_OPS_U64",
187         "isize" => "::kernel::module_param::PARAM_OPS_ISIZE",
188         "usize" => "::kernel::module_param::PARAM_OPS_USIZE",
189         t => panic!("Unsupported parameter type {}", t),
190     }
191 }
192 
193 /// Parse fields that are required to use a specific order.
194 ///
195 /// As fields must follow a specific order, we *could* just parse fields one by one by peeking.
196 /// However the error message generated when implementing that way is not very friendly.
197 ///
198 /// So instead we parse fields in an arbitrary order, but only enforce the ordering after parsing,
199 /// and if the wrong order is used, the proper order is communicated to the user with error message.
200 ///
201 /// Usage looks like this:
202 /// ```ignore
203 /// parse_ordered_fields! {
204 ///     from input;
205 ///
206 ///     // This will extract "foo: <field>" into a variable named "foo".
207 ///     // The variable will have type `Option<_>`.
208 ///     foo => <expression that parses the field>,
209 ///
210 ///     // If you need the variable name to be different than the key name.
211 ///     // This extracts "baz: <field>" into a variable named "bar".
212 ///     // You might want this if "baz" is a keyword.
213 ///     baz as bar => <expression that parse the field>,
214 ///
215 ///     // You can mark a key as required, and the variable will no longer be `Option`.
216 ///     // foobar will be of type `Expr` instead of `Option<Expr>`.
217 ///     foobar [required] => input.parse::<Expr>()?,
218 /// }
219 /// ```
220 macro_rules! parse_ordered_fields {
221     (@gen
222         [$input:expr]
223         [$([$name:ident; $key:ident; $parser:expr])*]
224         [$([$req_name:ident; $req_key:ident])*]
225     ) => {
226         $(let mut $name = None;)*
227 
228         const EXPECTED_KEYS: &[&str] = &[$(stringify!($key),)*];
229         const REQUIRED_KEYS: &[&str] = &[$(stringify!($req_key),)*];
230 
231         let span = $input.span();
232         let mut seen_keys = Vec::new();
233 
234         while !$input.is_empty() {
235             let key = $input.call(Ident::parse_any)?;
236 
237             if seen_keys.contains(&key) {
238                 Err(Error::new_spanned(
239                     &key,
240                     format!(r#"duplicated key "{key}". Keys can only be specified once."#),
241                 ))?
242             }
243 
244             $input.parse::<Token![:]>()?;
245 
246             match &*key.to_string() {
247                 $(
248                     stringify!($key) => $name = Some($parser),
249                 )*
250                 _ => {
251                     Err(Error::new_spanned(
252                         &key,
253                         format!(r#"unknown key "{key}". Valid keys are: {EXPECTED_KEYS:?}."#),
254                     ))?
255                 }
256             }
257 
258             $input.parse::<Token![,]>()?;
259             seen_keys.push(key);
260         }
261 
262         for key in REQUIRED_KEYS {
263             if !seen_keys.iter().any(|e| e == key) {
264                 Err(Error::new(span, format!(r#"missing required key "{key}""#)))?
265             }
266         }
267 
268         let mut ordered_keys: Vec<&str> = Vec::new();
269         for key in EXPECTED_KEYS {
270             if seen_keys.iter().any(|e| e == key) {
271                 ordered_keys.push(key);
272             }
273         }
274 
275         if seen_keys != ordered_keys {
276             Err(Error::new(
277                 span,
278                 format!(r#"keys are not ordered as expected. Order them like: {ordered_keys:?}."#),
279             ))?
280         }
281 
282         $(let $req_name = $req_name.expect("required field");)*
283     };
284 
285     // Handle required fields.
286     (@gen
287         [$input:expr] [$($tok:tt)*] [$($req:tt)*]
288         $key:ident as $name:ident [required] => $parser:expr,
289         $($rest:tt)*
290     ) => {
291         parse_ordered_fields!(
292             @gen [$input] [$($tok)* [$name; $key; $parser]] [$($req)* [$name; $key]] $($rest)*
293         )
294     };
295     (@gen
296         [$input:expr] [$($tok:tt)*] [$($req:tt)*]
297         $name:ident [required] => $parser:expr,
298         $($rest:tt)*
299     ) => {
300         parse_ordered_fields!(
301             @gen [$input] [$($tok)* [$name; $name; $parser]] [$($req)* [$name; $name]] $($rest)*
302         )
303     };
304 
305     // Handle optional fields.
306     (@gen
307         [$input:expr] [$($tok:tt)*] [$($req:tt)*]
308         $key:ident as $name:ident => $parser:expr,
309         $($rest:tt)*
310     ) => {
311         parse_ordered_fields!(
312             @gen [$input] [$($tok)* [$name; $key; $parser]] [$($req)*] $($rest)*
313         )
314     };
315     (@gen
316         [$input:expr] [$($tok:tt)*] [$($req:tt)*]
317         $name:ident => $parser:expr,
318         $($rest:tt)*
319     ) => {
320         parse_ordered_fields!(
321             @gen [$input] [$($tok)* [$name; $name; $parser]] [$($req)*] $($rest)*
322         )
323     };
324 
325     (from $input:expr; $($tok:tt)*) => {
326         parse_ordered_fields!(@gen [$input] [] [] $($tok)*)
327     }
328 }
329 
330 struct Parameter {
331     name: Ident,
332     ptype: Ident,
333     default: Expr,
334     description: LitStr,
335 }
336 
337 impl Parse for Parameter {
338     fn parse(input: ParseStream<'_>) -> Result<Self> {
339         let name = input.parse()?;
340         input.parse::<Token![:]>()?;
341         let ptype = input.parse()?;
342 
343         let fields;
344         braced!(fields in input);
345 
346         parse_ordered_fields! {
347             from fields;
348             default [required] => fields.parse()?,
349             description [required] => fields.parse()?,
350         }
351 
352         Ok(Self {
353             name,
354             ptype,
355             default,
356             description,
357         })
358     }
359 }
360 
361 pub(crate) struct ModuleInfo {
362     type_: Ident,
363     license: AsciiLitStr,
364     name: AsciiLitStr,
365     authors: Option<Punctuated<AsciiLitStr, Token![,]>>,
366     description: Option<LitStr>,
367     alias: Option<Punctuated<AsciiLitStr, Token![,]>>,
368     firmware: Option<Punctuated<AsciiLitStr, Token![,]>>,
369     imports_ns: Option<Punctuated<AsciiLitStr, Token![,]>>,
370     params: Option<Punctuated<Parameter, Token![,]>>,
371 }
372 
373 impl Parse for ModuleInfo {
374     fn parse(input: ParseStream<'_>) -> Result<Self> {
375         parse_ordered_fields!(
376             from input;
377             type as type_ [required] => input.parse()?,
378             name [required] => input.parse()?,
379             authors => {
380                 let list;
381                 bracketed!(list in input);
382                 Punctuated::parse_terminated(&list)?
383             },
384             description => input.parse()?,
385             license [required] => input.parse()?,
386             alias => {
387                 let list;
388                 bracketed!(list in input);
389                 Punctuated::parse_terminated(&list)?
390             },
391             firmware => {
392                 let list;
393                 bracketed!(list in input);
394                 Punctuated::parse_terminated(&list)?
395             },
396             imports_ns => {
397                 let list;
398                 bracketed!(list in input);
399                 Punctuated::parse_terminated(&list)?
400             },
401             params => {
402                 let list;
403                 braced!(list in input);
404                 Punctuated::parse_terminated(&list)?
405             },
406         );
407 
408         Ok(ModuleInfo {
409             type_,
410             license,
411             name,
412             authors,
413             description,
414             alias,
415             firmware,
416             imports_ns,
417             params,
418         })
419     }
420 }
421 
422 pub(crate) fn module(info: ModuleInfo) -> Result<TokenStream> {
423     // Rust does not allow hyphens in identifiers, use underscore instead.
424     let ident = info.name.value().replace('-', "_");
425     let mut modinfo = ModInfoBuilder::new(ident.as_ref());
426     if let Some(authors) = &info.authors {
427         for author in authors {
428             modinfo.emit("author", &author.value());
429         }
430     }
431     if let Some(description) = &info.description {
432         modinfo.emit("description", &description.value());
433     }
434     modinfo.emit("license", &info.license.value());
435     if let Some(aliases) = &info.alias {
436         for alias in aliases {
437             modinfo.emit("alias", &alias.value());
438         }
439     }
440     if let Some(firmware) = &info.firmware {
441         for fw in firmware {
442             modinfo.emit("firmware", &fw.value());
443         }
444     }
445     if let Some(imports) = &info.imports_ns {
446         for ns in imports {
447             modinfo.emit("import_ns", &ns.value());
448         }
449     }
450 
451     // Built-in modules also export the `file` modinfo string.
452     let file =
453         std::env::var("RUST_MODFILE").expect("Unable to fetch RUST_MODFILE environmental variable");
454     modinfo.emit_only_builtin("file", &file, false);
455 
456     modinfo.emit_params(&info);
457 
458     Ok(format!(
459         "
460             /// The module name.
461             ///
462             /// Used by the printing macros, e.g. [`info!`].
463             const __LOG_PREFIX: &[u8] = b\"{name}\\0\";
464 
465             // SAFETY: `__this_module` is constructed by the kernel at load time and will not be
466             // freed until the module is unloaded.
467             #[cfg(MODULE)]
468             static THIS_MODULE: ::kernel::ThisModule = unsafe {{
469                 extern \"C\" {{
470                     static __this_module: ::kernel::types::Opaque<::kernel::bindings::module>;
471                 }}
472 
473                 ::kernel::ThisModule::from_ptr(__this_module.get())
474             }};
475             #[cfg(not(MODULE))]
476             static THIS_MODULE: ::kernel::ThisModule = unsafe {{
477                 ::kernel::ThisModule::from_ptr(::core::ptr::null_mut())
478             }};
479 
480             /// The `LocalModule` type is the type of the module created by `module!`,
481             /// `module_pci_driver!`, `module_platform_driver!`, etc.
482             type LocalModule = {type_};
483 
484             impl ::kernel::ModuleMetadata for {type_} {{
485                 const NAME: &'static ::kernel::str::CStr = c\"{name}\";
486             }}
487 
488             // Double nested modules, since then nobody can access the public items inside.
489             mod __module_init {{
490                 mod __module_init {{
491                     use super::super::{type_};
492                     use pin_init::PinInit;
493 
494                     /// The \"Rust loadable module\" mark.
495                     //
496                     // This may be best done another way later on, e.g. as a new modinfo
497                     // key or a new section. For the moment, keep it simple.
498                     #[cfg(MODULE)]
499                     #[doc(hidden)]
500                     #[used(compiler)]
501                     static __IS_RUST_MODULE: () = ();
502 
503                     static mut __MOD: ::core::mem::MaybeUninit<{type_}> =
504                         ::core::mem::MaybeUninit::uninit();
505 
506                     // Loadable modules need to export the `{{init,cleanup}}_module` identifiers.
507                     /// # Safety
508                     ///
509                     /// This function must not be called after module initialization, because it may be
510                     /// freed after that completes.
511                     #[cfg(MODULE)]
512                     #[doc(hidden)]
513                     #[no_mangle]
514                     #[link_section = \".init.text\"]
515                     pub unsafe extern \"C\" fn init_module() -> ::kernel::ffi::c_int {{
516                         // SAFETY: This function is inaccessible to the outside due to the double
517                         // module wrapping it. It is called exactly once by the C side via its
518                         // unique name.
519                         unsafe {{ __init() }}
520                     }}
521 
522                     #[cfg(MODULE)]
523                     #[doc(hidden)]
524                     #[used(compiler)]
525                     #[link_section = \".init.data\"]
526                     static __UNIQUE_ID___addressable_init_module: unsafe extern \"C\" fn() -> i32 = init_module;
527 
528                     #[cfg(MODULE)]
529                     #[doc(hidden)]
530                     #[no_mangle]
531                     #[link_section = \".exit.text\"]
532                     pub extern \"C\" fn cleanup_module() {{
533                         // SAFETY:
534                         // - This function is inaccessible to the outside due to the double
535                         //   module wrapping it. It is called exactly once by the C side via its
536                         //   unique name,
537                         // - furthermore it is only called after `init_module` has returned `0`
538                         //   (which delegates to `__init`).
539                         unsafe {{ __exit() }}
540                     }}
541 
542                     #[cfg(MODULE)]
543                     #[doc(hidden)]
544                     #[used(compiler)]
545                     #[link_section = \".exit.data\"]
546                     static __UNIQUE_ID___addressable_cleanup_module: extern \"C\" fn() = cleanup_module;
547 
548                     // Built-in modules are initialized through an initcall pointer
549                     // and the identifiers need to be unique.
550                     #[cfg(not(MODULE))]
551                     #[cfg(not(CONFIG_HAVE_ARCH_PREL32_RELOCATIONS))]
552                     #[doc(hidden)]
553                     #[link_section = \"{initcall_section}\"]
554                     #[used(compiler)]
555                     pub static __{ident}_initcall: extern \"C\" fn() ->
556                         ::kernel::ffi::c_int = __{ident}_init;
557 
558                     #[cfg(not(MODULE))]
559                     #[cfg(CONFIG_HAVE_ARCH_PREL32_RELOCATIONS)]
560                     ::core::arch::global_asm!(
561                         r#\".section \"{initcall_section}\", \"a\"
562                         __{ident}_initcall:
563                             .long   __{ident}_init - .
564                             .previous
565                         \"#
566                     );
567 
568                     #[cfg(not(MODULE))]
569                     #[doc(hidden)]
570                     #[no_mangle]
571                     pub extern \"C\" fn __{ident}_init() -> ::kernel::ffi::c_int {{
572                         // SAFETY: This function is inaccessible to the outside due to the double
573                         // module wrapping it. It is called exactly once by the C side via its
574                         // placement above in the initcall section.
575                         unsafe {{ __init() }}
576                     }}
577 
578                     #[cfg(not(MODULE))]
579                     #[doc(hidden)]
580                     #[no_mangle]
581                     pub extern \"C\" fn __{ident}_exit() {{
582                         // SAFETY:
583                         // - This function is inaccessible to the outside due to the double
584                         //   module wrapping it. It is called exactly once by the C side via its
585                         //   unique name,
586                         // - furthermore it is only called after `__{ident}_init` has
587                         //   returned `0` (which delegates to `__init`).
588                         unsafe {{ __exit() }}
589                     }}
590 
591                     /// # Safety
592                     ///
593                     /// This function must only be called once.
594                     unsafe fn __init() -> ::kernel::ffi::c_int {{
595                         let initer =
596                             <{type_} as ::kernel::InPlaceModule>::init(&super::super::THIS_MODULE);
597                         // SAFETY: No data race, since `__MOD` can only be accessed by this module
598                         // and there only `__init` and `__exit` access it. These functions are only
599                         // called once and `__exit` cannot be called before or during `__init`.
600                         match unsafe {{ initer.__pinned_init(__MOD.as_mut_ptr()) }} {{
601                             Ok(m) => 0,
602                             Err(e) => e.to_errno(),
603                         }}
604                     }}
605 
606                     /// # Safety
607                     ///
608                     /// This function must
609                     /// - only be called once,
610                     /// - be called after `__init` has been called and returned `0`.
611                     unsafe fn __exit() {{
612                         // SAFETY: No data race, since `__MOD` can only be accessed by this module
613                         // and there only `__init` and `__exit` access it. These functions are only
614                         // called once and `__init` was already called.
615                         unsafe {{
616                             // Invokes `drop()` on `__MOD`, which should be used for cleanup.
617                             __MOD.assume_init_drop();
618                         }}
619                     }}
620                     {modinfo}
621                 }}
622             }}
623             mod module_parameters {{
624                 {params}
625             }}
626         ",
627         type_ = info.type_,
628         name = info.name.value(),
629         ident = ident,
630         modinfo = modinfo.buffer,
631         params = modinfo.param_buffer,
632         initcall_section = ".initcall6.init"
633     )
634     .parse()
635     .expect("Error parsing formatted string into token stream."))
636 }
637