1 // SPDX-License-Identifier: GPL-2.0 2 3 use crate::helpers::*; 4 use proc_macro::{token_stream, Delimiter, Literal, TokenStream, TokenTree}; 5 use std::fmt::Write; 6 7 fn expect_string_array(it: &mut token_stream::IntoIter) -> Vec<String> { 8 let group = expect_group(it); 9 assert_eq!(group.delimiter(), Delimiter::Bracket); 10 let mut values = Vec::new(); 11 let mut it = group.stream().into_iter(); 12 13 while let Some(val) = try_string(&mut it) { 14 assert!(val.is_ascii(), "Expected ASCII string"); 15 values.push(val); 16 match it.next() { 17 Some(TokenTree::Punct(punct)) => assert_eq!(punct.as_char(), ','), 18 None => break, 19 _ => panic!("Expected ',' or end of array"), 20 } 21 } 22 values 23 } 24 25 struct ModInfoBuilder<'a> { 26 module: &'a str, 27 counter: usize, 28 buffer: String, 29 param_buffer: String, 30 } 31 32 impl<'a> ModInfoBuilder<'a> { 33 fn new(module: &'a str) -> Self { 34 ModInfoBuilder { 35 module, 36 counter: 0, 37 buffer: String::new(), 38 param_buffer: String::new(), 39 } 40 } 41 42 fn emit_base(&mut self, field: &str, content: &str, builtin: bool, param: bool) { 43 let string = if builtin { 44 // Built-in modules prefix their modinfo strings by `module.`. 45 format!( 46 "{module}.{field}={content}\0", 47 module = self.module, 48 field = field, 49 content = content 50 ) 51 } else { 52 // Loadable modules' modinfo strings go as-is. 53 format!("{field}={content}\0") 54 }; 55 56 let buffer = if param { 57 &mut self.param_buffer 58 } else { 59 &mut self.buffer 60 }; 61 62 write!( 63 buffer, 64 " 65 {cfg} 66 #[doc(hidden)] 67 #[cfg_attr(not(target_os = \"macos\"), link_section = \".modinfo\")] 68 #[used(compiler)] 69 pub static __{module}_{counter}: [u8; {length}] = *{string}; 70 ", 71 cfg = if builtin { 72 "#[cfg(not(MODULE))]" 73 } else { 74 "#[cfg(MODULE)]" 75 }, 76 module = self.module.to_uppercase(), 77 counter = self.counter, 78 length = string.len(), 79 string = Literal::byte_string(string.as_bytes()), 80 ) 81 .unwrap(); 82 83 self.counter += 1; 84 } 85 86 fn emit_only_builtin(&mut self, field: &str, content: &str, param: bool) { 87 self.emit_base(field, content, true, param) 88 } 89 90 fn emit_only_loadable(&mut self, field: &str, content: &str, param: bool) { 91 self.emit_base(field, content, false, param) 92 } 93 94 fn emit(&mut self, field: &str, content: &str) { 95 self.emit_internal(field, content, false); 96 } 97 98 fn emit_internal(&mut self, field: &str, content: &str, param: bool) { 99 self.emit_only_builtin(field, content, param); 100 self.emit_only_loadable(field, content, param); 101 } 102 103 fn emit_param(&mut self, field: &str, param: &str, content: &str) { 104 let content = format!("{param}:{content}", param = param, content = content); 105 self.emit_internal(field, &content, true); 106 } 107 108 fn emit_params(&mut self, info: &ModuleInfo) { 109 let Some(params) = &info.params else { 110 return; 111 }; 112 113 for param in params { 114 let ops = param_ops_path(¶m.ptype); 115 116 // Note: The spelling of these fields is dictated by the user space 117 // tool `modinfo`. 118 self.emit_param("parmtype", ¶m.name, ¶m.ptype); 119 self.emit_param("parm", ¶m.name, ¶m.description); 120 121 write!( 122 self.param_buffer, 123 " 124 pub(crate) static {param_name}: 125 ::kernel::module_param::ModuleParamAccess<{param_type}> = 126 ::kernel::module_param::ModuleParamAccess::new({param_default}); 127 128 const _: () = {{ 129 #[link_section = \"__param\"] 130 #[used] 131 static __{module_name}_{param_name}_struct: 132 ::kernel::module_param::KernelParam = 133 ::kernel::module_param::KernelParam::new( 134 ::kernel::bindings::kernel_param {{ 135 name: if ::core::cfg!(MODULE) {{ 136 ::kernel::c_str!(\"{param_name}\").to_bytes_with_nul() 137 }} else {{ 138 ::kernel::c_str!(\"{module_name}.{param_name}\") 139 .to_bytes_with_nul() 140 }}.as_ptr(), 141 // SAFETY: `__this_module` is constructed by the kernel at load 142 // time and will not be freed until the module is unloaded. 143 #[cfg(MODULE)] 144 mod_: unsafe {{ 145 core::ptr::from_ref(&::kernel::bindings::__this_module) 146 .cast_mut() 147 }}, 148 #[cfg(not(MODULE))] 149 mod_: ::core::ptr::null_mut(), 150 ops: core::ptr::from_ref(&{ops}), 151 perm: 0, // Will not appear in sysfs 152 level: -1, 153 flags: 0, 154 __bindgen_anon_1: ::kernel::bindings::kernel_param__bindgen_ty_1 {{ 155 arg: {param_name}.as_void_ptr() 156 }}, 157 }} 158 ); 159 }}; 160 ", 161 module_name = info.name, 162 param_type = param.ptype, 163 param_default = param.default, 164 param_name = param.name, 165 ops = ops, 166 ) 167 .unwrap(); 168 } 169 } 170 } 171 172 fn param_ops_path(param_type: &str) -> &'static str { 173 match param_type { 174 "i8" => "::kernel::module_param::PARAM_OPS_I8", 175 "u8" => "::kernel::module_param::PARAM_OPS_U8", 176 "i16" => "::kernel::module_param::PARAM_OPS_I16", 177 "u16" => "::kernel::module_param::PARAM_OPS_U16", 178 "i32" => "::kernel::module_param::PARAM_OPS_I32", 179 "u32" => "::kernel::module_param::PARAM_OPS_U32", 180 "i64" => "::kernel::module_param::PARAM_OPS_I64", 181 "u64" => "::kernel::module_param::PARAM_OPS_U64", 182 "isize" => "::kernel::module_param::PARAM_OPS_ISIZE", 183 "usize" => "::kernel::module_param::PARAM_OPS_USIZE", 184 t => panic!("Unsupported parameter type {}", t), 185 } 186 } 187 188 fn expect_param_default(param_it: &mut token_stream::IntoIter) -> String { 189 assert_eq!(expect_ident(param_it), "default"); 190 assert_eq!(expect_punct(param_it), ':'); 191 let sign = try_sign(param_it); 192 let default = try_literal(param_it).expect("Expected default param value"); 193 assert_eq!(expect_punct(param_it), ','); 194 let mut value = sign.map(String::from).unwrap_or_default(); 195 value.push_str(&default); 196 value 197 } 198 199 #[derive(Debug, Default)] 200 struct ModuleInfo { 201 type_: String, 202 license: String, 203 name: String, 204 authors: Option<Vec<String>>, 205 description: Option<String>, 206 alias: Option<Vec<String>>, 207 firmware: Option<Vec<String>>, 208 imports_ns: Option<Vec<String>>, 209 params: Option<Vec<Parameter>>, 210 } 211 212 #[derive(Debug)] 213 struct Parameter { 214 name: String, 215 ptype: String, 216 default: String, 217 description: String, 218 } 219 220 fn expect_params(it: &mut token_stream::IntoIter) -> Vec<Parameter> { 221 let params = expect_group(it); 222 assert_eq!(params.delimiter(), Delimiter::Brace); 223 let mut it = params.stream().into_iter(); 224 let mut parsed = Vec::new(); 225 226 loop { 227 let param_name = match it.next() { 228 Some(TokenTree::Ident(ident)) => ident.to_string(), 229 Some(_) => panic!("Expected Ident or end"), 230 None => break, 231 }; 232 233 assert_eq!(expect_punct(&mut it), ':'); 234 let param_type = expect_ident(&mut it); 235 let group = expect_group(&mut it); 236 assert_eq!(group.delimiter(), Delimiter::Brace); 237 assert_eq!(expect_punct(&mut it), ','); 238 239 let mut param_it = group.stream().into_iter(); 240 let param_default = expect_param_default(&mut param_it); 241 let param_description = expect_string_field(&mut param_it, "description"); 242 expect_end(&mut param_it); 243 244 parsed.push(Parameter { 245 name: param_name, 246 ptype: param_type, 247 default: param_default, 248 description: param_description, 249 }) 250 } 251 252 parsed 253 } 254 255 impl ModuleInfo { 256 fn parse(it: &mut token_stream::IntoIter) -> Self { 257 let mut info = ModuleInfo::default(); 258 259 const EXPECTED_KEYS: &[&str] = &[ 260 "type", 261 "name", 262 "authors", 263 "description", 264 "license", 265 "alias", 266 "firmware", 267 "imports_ns", 268 "params", 269 ]; 270 const REQUIRED_KEYS: &[&str] = &["type", "name", "license"]; 271 let mut seen_keys = Vec::new(); 272 273 loop { 274 let key = match it.next() { 275 Some(TokenTree::Ident(ident)) => ident.to_string(), 276 Some(_) => panic!("Expected Ident or end"), 277 None => break, 278 }; 279 280 if seen_keys.contains(&key) { 281 panic!("Duplicated key \"{key}\". Keys can only be specified once."); 282 } 283 284 assert_eq!(expect_punct(it), ':'); 285 286 match key.as_str() { 287 "type" => info.type_ = expect_ident(it), 288 "name" => info.name = expect_string_ascii(it), 289 "authors" => info.authors = Some(expect_string_array(it)), 290 "description" => info.description = Some(expect_string(it)), 291 "license" => info.license = expect_string_ascii(it), 292 "alias" => info.alias = Some(expect_string_array(it)), 293 "firmware" => info.firmware = Some(expect_string_array(it)), 294 "imports_ns" => info.imports_ns = Some(expect_string_array(it)), 295 "params" => info.params = Some(expect_params(it)), 296 _ => panic!("Unknown key \"{key}\". Valid keys are: {EXPECTED_KEYS:?}."), 297 } 298 299 assert_eq!(expect_punct(it), ','); 300 301 seen_keys.push(key); 302 } 303 304 expect_end(it); 305 306 for key in REQUIRED_KEYS { 307 if !seen_keys.iter().any(|e| e == key) { 308 panic!("Missing required key \"{key}\"."); 309 } 310 } 311 312 let mut ordered_keys: Vec<&str> = Vec::new(); 313 for key in EXPECTED_KEYS { 314 if seen_keys.iter().any(|e| e == key) { 315 ordered_keys.push(key); 316 } 317 } 318 319 if seen_keys != ordered_keys { 320 panic!("Keys are not ordered as expected. Order them like: {ordered_keys:?}."); 321 } 322 323 info 324 } 325 } 326 327 pub(crate) fn module(ts: TokenStream) -> TokenStream { 328 let mut it = ts.into_iter(); 329 330 let info = ModuleInfo::parse(&mut it); 331 332 // Rust does not allow hyphens in identifiers, use underscore instead. 333 let ident = info.name.replace('-', "_"); 334 let mut modinfo = ModInfoBuilder::new(ident.as_ref()); 335 if let Some(authors) = &info.authors { 336 for author in authors { 337 modinfo.emit("author", author); 338 } 339 } 340 if let Some(description) = &info.description { 341 modinfo.emit("description", description); 342 } 343 modinfo.emit("license", &info.license); 344 if let Some(aliases) = &info.alias { 345 for alias in aliases { 346 modinfo.emit("alias", alias); 347 } 348 } 349 if let Some(firmware) = &info.firmware { 350 for fw in firmware { 351 modinfo.emit("firmware", fw); 352 } 353 } 354 if let Some(imports) = &info.imports_ns { 355 for ns in imports { 356 modinfo.emit("import_ns", ns); 357 } 358 } 359 360 // Built-in modules also export the `file` modinfo string. 361 let file = 362 std::env::var("RUST_MODFILE").expect("Unable to fetch RUST_MODFILE environmental variable"); 363 modinfo.emit_only_builtin("file", &file, false); 364 365 modinfo.emit_params(&info); 366 367 format!( 368 " 369 /// The module name. 370 /// 371 /// Used by the printing macros, e.g. [`info!`]. 372 const __LOG_PREFIX: &[u8] = b\"{name}\\0\"; 373 374 // SAFETY: `__this_module` is constructed by the kernel at load time and will not be 375 // freed until the module is unloaded. 376 #[cfg(MODULE)] 377 static THIS_MODULE: ::kernel::ThisModule = unsafe {{ 378 extern \"C\" {{ 379 static __this_module: ::kernel::types::Opaque<::kernel::bindings::module>; 380 }} 381 382 ::kernel::ThisModule::from_ptr(__this_module.get()) 383 }}; 384 #[cfg(not(MODULE))] 385 static THIS_MODULE: ::kernel::ThisModule = unsafe {{ 386 ::kernel::ThisModule::from_ptr(::core::ptr::null_mut()) 387 }}; 388 389 /// The `LocalModule` type is the type of the module created by `module!`, 390 /// `module_pci_driver!`, `module_platform_driver!`, etc. 391 type LocalModule = {type_}; 392 393 impl ::kernel::ModuleMetadata for {type_} {{ 394 const NAME: &'static ::kernel::str::CStr = c\"{name}\"; 395 }} 396 397 // Double nested modules, since then nobody can access the public items inside. 398 mod __module_init {{ 399 mod __module_init {{ 400 use super::super::{type_}; 401 use pin_init::PinInit; 402 403 /// The \"Rust loadable module\" mark. 404 // 405 // This may be best done another way later on, e.g. as a new modinfo 406 // key or a new section. For the moment, keep it simple. 407 #[cfg(MODULE)] 408 #[doc(hidden)] 409 #[used(compiler)] 410 static __IS_RUST_MODULE: () = (); 411 412 static mut __MOD: ::core::mem::MaybeUninit<{type_}> = 413 ::core::mem::MaybeUninit::uninit(); 414 415 // Loadable modules need to export the `{{init,cleanup}}_module` identifiers. 416 /// # Safety 417 /// 418 /// This function must not be called after module initialization, because it may be 419 /// freed after that completes. 420 #[cfg(MODULE)] 421 #[doc(hidden)] 422 #[no_mangle] 423 #[link_section = \".init.text\"] 424 pub unsafe extern \"C\" fn init_module() -> ::kernel::ffi::c_int {{ 425 // SAFETY: This function is inaccessible to the outside due to the double 426 // module wrapping it. It is called exactly once by the C side via its 427 // unique name. 428 unsafe {{ __init() }} 429 }} 430 431 #[cfg(MODULE)] 432 #[doc(hidden)] 433 #[used(compiler)] 434 #[link_section = \".init.data\"] 435 static __UNIQUE_ID___addressable_init_module: unsafe extern \"C\" fn() -> i32 = init_module; 436 437 #[cfg(MODULE)] 438 #[doc(hidden)] 439 #[no_mangle] 440 #[link_section = \".exit.text\"] 441 pub extern \"C\" fn cleanup_module() {{ 442 // SAFETY: 443 // - This function is inaccessible to the outside due to the double 444 // module wrapping it. It is called exactly once by the C side via its 445 // unique name, 446 // - furthermore it is only called after `init_module` has returned `0` 447 // (which delegates to `__init`). 448 unsafe {{ __exit() }} 449 }} 450 451 #[cfg(MODULE)] 452 #[doc(hidden)] 453 #[used(compiler)] 454 #[link_section = \".exit.data\"] 455 static __UNIQUE_ID___addressable_cleanup_module: extern \"C\" fn() = cleanup_module; 456 457 // Built-in modules are initialized through an initcall pointer 458 // and the identifiers need to be unique. 459 #[cfg(not(MODULE))] 460 #[cfg(not(CONFIG_HAVE_ARCH_PREL32_RELOCATIONS))] 461 #[doc(hidden)] 462 #[link_section = \"{initcall_section}\"] 463 #[used(compiler)] 464 pub static __{ident}_initcall: extern \"C\" fn() -> 465 ::kernel::ffi::c_int = __{ident}_init; 466 467 #[cfg(not(MODULE))] 468 #[cfg(CONFIG_HAVE_ARCH_PREL32_RELOCATIONS)] 469 ::core::arch::global_asm!( 470 r#\".section \"{initcall_section}\", \"a\" 471 __{ident}_initcall: 472 .long __{ident}_init - . 473 .previous 474 \"# 475 ); 476 477 #[cfg(not(MODULE))] 478 #[doc(hidden)] 479 #[no_mangle] 480 pub extern \"C\" fn __{ident}_init() -> ::kernel::ffi::c_int {{ 481 // SAFETY: This function is inaccessible to the outside due to the double 482 // module wrapping it. It is called exactly once by the C side via its 483 // placement above in the initcall section. 484 unsafe {{ __init() }} 485 }} 486 487 #[cfg(not(MODULE))] 488 #[doc(hidden)] 489 #[no_mangle] 490 pub extern \"C\" fn __{ident}_exit() {{ 491 // SAFETY: 492 // - This function is inaccessible to the outside due to the double 493 // module wrapping it. It is called exactly once by the C side via its 494 // unique name, 495 // - furthermore it is only called after `__{ident}_init` has 496 // returned `0` (which delegates to `__init`). 497 unsafe {{ __exit() }} 498 }} 499 500 /// # Safety 501 /// 502 /// This function must only be called once. 503 unsafe fn __init() -> ::kernel::ffi::c_int {{ 504 let initer = 505 <{type_} as ::kernel::InPlaceModule>::init(&super::super::THIS_MODULE); 506 // SAFETY: No data race, since `__MOD` can only be accessed by this module 507 // and there only `__init` and `__exit` access it. These functions are only 508 // called once and `__exit` cannot be called before or during `__init`. 509 match unsafe {{ initer.__pinned_init(__MOD.as_mut_ptr()) }} {{ 510 Ok(m) => 0, 511 Err(e) => e.to_errno(), 512 }} 513 }} 514 515 /// # Safety 516 /// 517 /// This function must 518 /// - only be called once, 519 /// - be called after `__init` has been called and returned `0`. 520 unsafe fn __exit() {{ 521 // SAFETY: No data race, since `__MOD` can only be accessed by this module 522 // and there only `__init` and `__exit` access it. These functions are only 523 // called once and `__init` was already called. 524 unsafe {{ 525 // Invokes `drop()` on `__MOD`, which should be used for cleanup. 526 __MOD.assume_init_drop(); 527 }} 528 }} 529 {modinfo} 530 }} 531 }} 532 mod module_parameters {{ 533 {params} 534 }} 535 ", 536 type_ = info.type_, 537 name = info.name, 538 ident = ident, 539 modinfo = modinfo.buffer, 540 params = modinfo.param_buffer, 541 initcall_section = ".initcall6.init" 542 ) 543 .parse() 544 .expect("Error parsing formatted string into token stream.") 545 } 546