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}\").as_bytes_with_nul() 137 }} else {{ 138 ::kernel::c_str!(\"{module_name}.{param_name}\") 139 .as_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 params: Option<Vec<Parameter>>, 209 } 210 211 #[derive(Debug)] 212 struct Parameter { 213 name: String, 214 ptype: String, 215 default: String, 216 description: String, 217 } 218 219 fn expect_params(it: &mut token_stream::IntoIter) -> Vec<Parameter> { 220 let params = expect_group(it); 221 assert_eq!(params.delimiter(), Delimiter::Brace); 222 let mut it = params.stream().into_iter(); 223 let mut parsed = Vec::new(); 224 225 loop { 226 let param_name = match it.next() { 227 Some(TokenTree::Ident(ident)) => ident.to_string(), 228 Some(_) => panic!("Expected Ident or end"), 229 None => break, 230 }; 231 232 assert_eq!(expect_punct(&mut it), ':'); 233 let param_type = expect_ident(&mut it); 234 let group = expect_group(&mut it); 235 assert_eq!(group.delimiter(), Delimiter::Brace); 236 assert_eq!(expect_punct(&mut it), ','); 237 238 let mut param_it = group.stream().into_iter(); 239 let param_default = expect_param_default(&mut param_it); 240 let param_description = expect_string_field(&mut param_it, "description"); 241 expect_end(&mut param_it); 242 243 parsed.push(Parameter { 244 name: param_name, 245 ptype: param_type, 246 default: param_default, 247 description: param_description, 248 }) 249 } 250 251 parsed 252 } 253 254 impl ModuleInfo { 255 fn parse(it: &mut token_stream::IntoIter) -> Self { 256 let mut info = ModuleInfo::default(); 257 258 const EXPECTED_KEYS: &[&str] = &[ 259 "type", 260 "name", 261 "authors", 262 "description", 263 "license", 264 "alias", 265 "firmware", 266 "params", 267 ]; 268 const REQUIRED_KEYS: &[&str] = &["type", "name", "license"]; 269 let mut seen_keys = Vec::new(); 270 271 loop { 272 let key = match it.next() { 273 Some(TokenTree::Ident(ident)) => ident.to_string(), 274 Some(_) => panic!("Expected Ident or end"), 275 None => break, 276 }; 277 278 if seen_keys.contains(&key) { 279 panic!("Duplicated key \"{key}\". Keys can only be specified once."); 280 } 281 282 assert_eq!(expect_punct(it), ':'); 283 284 match key.as_str() { 285 "type" => info.type_ = expect_ident(it), 286 "name" => info.name = expect_string_ascii(it), 287 "authors" => info.authors = Some(expect_string_array(it)), 288 "description" => info.description = Some(expect_string(it)), 289 "license" => info.license = expect_string_ascii(it), 290 "alias" => info.alias = Some(expect_string_array(it)), 291 "firmware" => info.firmware = Some(expect_string_array(it)), 292 "params" => info.params = Some(expect_params(it)), 293 _ => panic!("Unknown key \"{key}\". Valid keys are: {EXPECTED_KEYS:?}."), 294 } 295 296 assert_eq!(expect_punct(it), ','); 297 298 seen_keys.push(key); 299 } 300 301 expect_end(it); 302 303 for key in REQUIRED_KEYS { 304 if !seen_keys.iter().any(|e| e == key) { 305 panic!("Missing required key \"{key}\"."); 306 } 307 } 308 309 let mut ordered_keys: Vec<&str> = Vec::new(); 310 for key in EXPECTED_KEYS { 311 if seen_keys.iter().any(|e| e == key) { 312 ordered_keys.push(key); 313 } 314 } 315 316 if seen_keys != ordered_keys { 317 panic!("Keys are not ordered as expected. Order them like: {ordered_keys:?}."); 318 } 319 320 info 321 } 322 } 323 324 pub(crate) fn module(ts: TokenStream) -> TokenStream { 325 let mut it = ts.into_iter(); 326 327 let info = ModuleInfo::parse(&mut it); 328 329 // Rust does not allow hyphens in identifiers, use underscore instead. 330 let ident = info.name.replace('-', "_"); 331 let mut modinfo = ModInfoBuilder::new(ident.as_ref()); 332 if let Some(authors) = &info.authors { 333 for author in authors { 334 modinfo.emit("author", author); 335 } 336 } 337 if let Some(description) = &info.description { 338 modinfo.emit("description", description); 339 } 340 modinfo.emit("license", &info.license); 341 if let Some(aliases) = &info.alias { 342 for alias in aliases { 343 modinfo.emit("alias", alias); 344 } 345 } 346 if let Some(firmware) = &info.firmware { 347 for fw in firmware { 348 modinfo.emit("firmware", fw); 349 } 350 } 351 352 // Built-in modules also export the `file` modinfo string. 353 let file = 354 std::env::var("RUST_MODFILE").expect("Unable to fetch RUST_MODFILE environmental variable"); 355 modinfo.emit_only_builtin("file", &file, false); 356 357 modinfo.emit_params(&info); 358 359 format!( 360 " 361 /// The module name. 362 /// 363 /// Used by the printing macros, e.g. [`info!`]. 364 const __LOG_PREFIX: &[u8] = b\"{name}\\0\"; 365 366 // SAFETY: `__this_module` is constructed by the kernel at load time and will not be 367 // freed until the module is unloaded. 368 #[cfg(MODULE)] 369 static THIS_MODULE: ::kernel::ThisModule = unsafe {{ 370 extern \"C\" {{ 371 static __this_module: ::kernel::types::Opaque<::kernel::bindings::module>; 372 }} 373 374 ::kernel::ThisModule::from_ptr(__this_module.get()) 375 }}; 376 #[cfg(not(MODULE))] 377 static THIS_MODULE: ::kernel::ThisModule = unsafe {{ 378 ::kernel::ThisModule::from_ptr(::core::ptr::null_mut()) 379 }}; 380 381 /// The `LocalModule` type is the type of the module created by `module!`, 382 /// `module_pci_driver!`, `module_platform_driver!`, etc. 383 type LocalModule = {type_}; 384 385 impl ::kernel::ModuleMetadata for {type_} {{ 386 const NAME: &'static ::kernel::str::CStr = ::kernel::c_str!(\"{name}\"); 387 }} 388 389 // Double nested modules, since then nobody can access the public items inside. 390 mod __module_init {{ 391 mod __module_init {{ 392 use super::super::{type_}; 393 use pin_init::PinInit; 394 395 /// The \"Rust loadable module\" mark. 396 // 397 // This may be best done another way later on, e.g. as a new modinfo 398 // key or a new section. For the moment, keep it simple. 399 #[cfg(MODULE)] 400 #[doc(hidden)] 401 #[used(compiler)] 402 static __IS_RUST_MODULE: () = (); 403 404 static mut __MOD: ::core::mem::MaybeUninit<{type_}> = 405 ::core::mem::MaybeUninit::uninit(); 406 407 // Loadable modules need to export the `{{init,cleanup}}_module` identifiers. 408 /// # Safety 409 /// 410 /// This function must not be called after module initialization, because it may be 411 /// freed after that completes. 412 #[cfg(MODULE)] 413 #[doc(hidden)] 414 #[no_mangle] 415 #[link_section = \".init.text\"] 416 pub unsafe extern \"C\" fn init_module() -> ::kernel::ffi::c_int {{ 417 // SAFETY: This function is inaccessible to the outside due to the double 418 // module wrapping it. It is called exactly once by the C side via its 419 // unique name. 420 unsafe {{ __init() }} 421 }} 422 423 #[cfg(MODULE)] 424 #[doc(hidden)] 425 #[used(compiler)] 426 #[link_section = \".init.data\"] 427 static __UNIQUE_ID___addressable_init_module: unsafe extern \"C\" fn() -> i32 = init_module; 428 429 #[cfg(MODULE)] 430 #[doc(hidden)] 431 #[no_mangle] 432 #[link_section = \".exit.text\"] 433 pub extern \"C\" fn cleanup_module() {{ 434 // SAFETY: 435 // - This function is inaccessible to the outside due to the double 436 // module wrapping it. It is called exactly once by the C side via its 437 // unique name, 438 // - furthermore it is only called after `init_module` has returned `0` 439 // (which delegates to `__init`). 440 unsafe {{ __exit() }} 441 }} 442 443 #[cfg(MODULE)] 444 #[doc(hidden)] 445 #[used(compiler)] 446 #[link_section = \".exit.data\"] 447 static __UNIQUE_ID___addressable_cleanup_module: extern \"C\" fn() = cleanup_module; 448 449 // Built-in modules are initialized through an initcall pointer 450 // and the identifiers need to be unique. 451 #[cfg(not(MODULE))] 452 #[cfg(not(CONFIG_HAVE_ARCH_PREL32_RELOCATIONS))] 453 #[doc(hidden)] 454 #[link_section = \"{initcall_section}\"] 455 #[used(compiler)] 456 pub static __{ident}_initcall: extern \"C\" fn() -> 457 ::kernel::ffi::c_int = __{ident}_init; 458 459 #[cfg(not(MODULE))] 460 #[cfg(CONFIG_HAVE_ARCH_PREL32_RELOCATIONS)] 461 ::core::arch::global_asm!( 462 r#\".section \"{initcall_section}\", \"a\" 463 __{ident}_initcall: 464 .long __{ident}_init - . 465 .previous 466 \"# 467 ); 468 469 #[cfg(not(MODULE))] 470 #[doc(hidden)] 471 #[no_mangle] 472 pub extern \"C\" fn __{ident}_init() -> ::kernel::ffi::c_int {{ 473 // SAFETY: This function is inaccessible to the outside due to the double 474 // module wrapping it. It is called exactly once by the C side via its 475 // placement above in the initcall section. 476 unsafe {{ __init() }} 477 }} 478 479 #[cfg(not(MODULE))] 480 #[doc(hidden)] 481 #[no_mangle] 482 pub extern \"C\" fn __{ident}_exit() {{ 483 // SAFETY: 484 // - This function is inaccessible to the outside due to the double 485 // module wrapping it. It is called exactly once by the C side via its 486 // unique name, 487 // - furthermore it is only called after `__{ident}_init` has 488 // returned `0` (which delegates to `__init`). 489 unsafe {{ __exit() }} 490 }} 491 492 /// # Safety 493 /// 494 /// This function must only be called once. 495 unsafe fn __init() -> ::kernel::ffi::c_int {{ 496 let initer = 497 <{type_} as ::kernel::InPlaceModule>::init(&super::super::THIS_MODULE); 498 // SAFETY: No data race, since `__MOD` can only be accessed by this module 499 // and there only `__init` and `__exit` access it. These functions are only 500 // called once and `__exit` cannot be called before or during `__init`. 501 match unsafe {{ initer.__pinned_init(__MOD.as_mut_ptr()) }} {{ 502 Ok(m) => 0, 503 Err(e) => e.to_errno(), 504 }} 505 }} 506 507 /// # Safety 508 /// 509 /// This function must 510 /// - only be called once, 511 /// - be called after `__init` has been called and returned `0`. 512 unsafe fn __exit() {{ 513 // SAFETY: No data race, since `__MOD` can only be accessed by this module 514 // and there only `__init` and `__exit` access it. These functions are only 515 // called once and `__init` was already called. 516 unsafe {{ 517 // Invokes `drop()` on `__MOD`, which should be used for cleanup. 518 __MOD.assume_init_drop(); 519 }} 520 }} 521 {modinfo} 522 }} 523 }} 524 mod module_parameters {{ 525 {params} 526 }} 527 ", 528 type_ = info.type_, 529 name = info.name, 530 ident = ident, 531 modinfo = modinfo.buffer, 532 params = modinfo.param_buffer, 533 initcall_section = ".initcall6.init" 534 ) 535 .parse() 536 .expect("Error parsing formatted string into token stream.") 537 } 538