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(¶m_type_str); 121 122 // Note: The spelling of these fields is dictated by the user space 123 // tool `modinfo`. 124 self.emit_param("parmtype", ¶m_name_str, ¶m_type_str); 125 self.emit_param("parm", ¶m_name_str, ¶m.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 = ¶m.name; 135 let param_type = ¶m.ptype; 136 let param_default = ¶m.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