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