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(¶m_type_str); 123 124 // Note: The spelling of these fields is dictated by the user space 125 // tool `modinfo`. 126 self.emit_param("parmtype", ¶m_name_str, ¶m_type_str); 127 self.emit_param("parm", ¶m_name_str, ¶m.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