module.rs 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. // SPDX-License-Identifier: GPL-2.0
  2. use crate::helpers::*;
  3. use proc_macro::{token_stream, Literal, TokenStream, TokenTree};
  4. use std::fmt::Write;
  5. struct ModInfoBuilder<'a> {
  6. module: &'a str,
  7. counter: usize,
  8. buffer: String,
  9. }
  10. impl<'a> ModInfoBuilder<'a> {
  11. fn new(module: &'a str) -> Self {
  12. ModInfoBuilder {
  13. module,
  14. counter: 0,
  15. buffer: String::new(),
  16. }
  17. }
  18. fn emit_base(&mut self, field: &str, content: &str, builtin: bool) {
  19. let string = if builtin {
  20. // Built-in modules prefix their modinfo strings by `module.`.
  21. format!(
  22. "{module}.{field}={content}\0",
  23. module = self.module,
  24. field = field,
  25. content = content
  26. )
  27. } else {
  28. // Loadable modules' modinfo strings go as-is.
  29. format!("{field}={content}\0", field = field, content = content)
  30. };
  31. write!(
  32. &mut self.buffer,
  33. "
  34. {cfg}
  35. #[doc(hidden)]
  36. #[link_section = \".modinfo\"]
  37. #[used]
  38. pub static __{module}_{counter}: [u8; {length}] = *{string};
  39. ",
  40. cfg = if builtin {
  41. "#[cfg(not(MODULE))]"
  42. } else {
  43. "#[cfg(MODULE)]"
  44. },
  45. module = self.module.to_uppercase(),
  46. counter = self.counter,
  47. length = string.len(),
  48. string = Literal::byte_string(string.as_bytes()),
  49. )
  50. .unwrap();
  51. self.counter += 1;
  52. }
  53. fn emit_only_builtin(&mut self, field: &str, content: &str) {
  54. self.emit_base(field, content, true)
  55. }
  56. fn emit_only_loadable(&mut self, field: &str, content: &str) {
  57. self.emit_base(field, content, false)
  58. }
  59. fn emit(&mut self, field: &str, content: &str) {
  60. self.emit_only_builtin(field, content);
  61. self.emit_only_loadable(field, content);
  62. }
  63. }
  64. #[derive(Debug, Default)]
  65. struct ModuleInfo {
  66. type_: String,
  67. license: String,
  68. name: String,
  69. author: Option<String>,
  70. description: Option<String>,
  71. alias: Option<String>,
  72. }
  73. impl ModuleInfo {
  74. fn parse(it: &mut token_stream::IntoIter) -> Self {
  75. let mut info = ModuleInfo::default();
  76. const EXPECTED_KEYS: &[&str] =
  77. &["type", "name", "author", "description", "license", "alias"];
  78. const REQUIRED_KEYS: &[&str] = &["type", "name", "license"];
  79. let mut seen_keys = Vec::new();
  80. loop {
  81. let key = match it.next() {
  82. Some(TokenTree::Ident(ident)) => ident.to_string(),
  83. Some(_) => panic!("Expected Ident or end"),
  84. None => break,
  85. };
  86. if seen_keys.contains(&key) {
  87. panic!(
  88. "Duplicated key \"{}\". Keys can only be specified once.",
  89. key
  90. );
  91. }
  92. assert_eq!(expect_punct(it), ':');
  93. match key.as_str() {
  94. "type" => info.type_ = expect_ident(it),
  95. "name" => info.name = expect_byte_string(it),
  96. "author" => info.author = Some(expect_byte_string(it)),
  97. "description" => info.description = Some(expect_byte_string(it)),
  98. "license" => info.license = expect_byte_string(it),
  99. "alias" => info.alias = Some(expect_byte_string(it)),
  100. _ => panic!(
  101. "Unknown key \"{}\". Valid keys are: {:?}.",
  102. key, EXPECTED_KEYS
  103. ),
  104. }
  105. assert_eq!(expect_punct(it), ',');
  106. seen_keys.push(key);
  107. }
  108. expect_end(it);
  109. for key in REQUIRED_KEYS {
  110. if !seen_keys.iter().any(|e| e == key) {
  111. panic!("Missing required key \"{}\".", key);
  112. }
  113. }
  114. let mut ordered_keys: Vec<&str> = Vec::new();
  115. for key in EXPECTED_KEYS {
  116. if seen_keys.iter().any(|e| e == key) {
  117. ordered_keys.push(key);
  118. }
  119. }
  120. if seen_keys != ordered_keys {
  121. panic!(
  122. "Keys are not ordered as expected. Order them like: {:?}.",
  123. ordered_keys
  124. );
  125. }
  126. info
  127. }
  128. }
  129. pub(crate) fn module(ts: TokenStream) -> TokenStream {
  130. let mut it = ts.into_iter();
  131. let info = ModuleInfo::parse(&mut it);
  132. let mut modinfo = ModInfoBuilder::new(info.name.as_ref());
  133. if let Some(author) = info.author {
  134. modinfo.emit("author", &author);
  135. }
  136. if let Some(description) = info.description {
  137. modinfo.emit("description", &description);
  138. }
  139. modinfo.emit("license", &info.license);
  140. if let Some(alias) = info.alias {
  141. modinfo.emit("alias", &alias);
  142. }
  143. // Built-in modules also export the `file` modinfo string.
  144. let file =
  145. std::env::var("RUST_MODFILE").expect("Unable to fetch RUST_MODFILE environmental variable");
  146. modinfo.emit_only_builtin("file", &file);
  147. format!(
  148. "
  149. /// The module name.
  150. ///
  151. /// Used by the printing macros, e.g. [`info!`].
  152. const __LOG_PREFIX: &[u8] = b\"{name}\\0\";
  153. /// The \"Rust loadable module\" mark, for `scripts/is_rust_module.sh`.
  154. //
  155. // This may be best done another way later on, e.g. as a new modinfo
  156. // key or a new section. For the moment, keep it simple.
  157. #[cfg(MODULE)]
  158. #[doc(hidden)]
  159. #[used]
  160. static __IS_RUST_MODULE: () = ();
  161. static mut __MOD: Option<{type_}> = None;
  162. // SAFETY: `__this_module` is constructed by the kernel at load time and will not be
  163. // freed until the module is unloaded.
  164. #[cfg(MODULE)]
  165. static THIS_MODULE: kernel::ThisModule = unsafe {{
  166. kernel::ThisModule::from_ptr(&kernel::bindings::__this_module as *const _ as *mut _)
  167. }};
  168. #[cfg(not(MODULE))]
  169. static THIS_MODULE: kernel::ThisModule = unsafe {{
  170. kernel::ThisModule::from_ptr(core::ptr::null_mut())
  171. }};
  172. // Loadable modules need to export the `{{init,cleanup}}_module` identifiers.
  173. #[cfg(MODULE)]
  174. #[doc(hidden)]
  175. #[no_mangle]
  176. pub extern \"C\" fn init_module() -> core::ffi::c_int {{
  177. __init()
  178. }}
  179. #[cfg(MODULE)]
  180. #[doc(hidden)]
  181. #[no_mangle]
  182. pub extern \"C\" fn cleanup_module() {{
  183. __exit()
  184. }}
  185. // Built-in modules are initialized through an initcall pointer
  186. // and the identifiers need to be unique.
  187. #[cfg(not(MODULE))]
  188. #[cfg(not(CONFIG_HAVE_ARCH_PREL32_RELOCATIONS))]
  189. #[doc(hidden)]
  190. #[link_section = \"{initcall_section}\"]
  191. #[used]
  192. pub static __{name}_initcall: extern \"C\" fn() -> core::ffi::c_int = __{name}_init;
  193. #[cfg(not(MODULE))]
  194. #[cfg(CONFIG_HAVE_ARCH_PREL32_RELOCATIONS)]
  195. core::arch::global_asm!(
  196. r#\".section \"{initcall_section}\", \"a\"
  197. __{name}_initcall:
  198. .long __{name}_init - .
  199. .previous
  200. \"#
  201. );
  202. #[cfg(not(MODULE))]
  203. #[doc(hidden)]
  204. #[no_mangle]
  205. pub extern \"C\" fn __{name}_init() -> core::ffi::c_int {{
  206. __init()
  207. }}
  208. #[cfg(not(MODULE))]
  209. #[doc(hidden)]
  210. #[no_mangle]
  211. pub extern \"C\" fn __{name}_exit() {{
  212. __exit()
  213. }}
  214. fn __init() -> core::ffi::c_int {{
  215. match <{type_} as kernel::Module>::init(&THIS_MODULE) {{
  216. Ok(m) => {{
  217. unsafe {{
  218. __MOD = Some(m);
  219. }}
  220. return 0;
  221. }}
  222. Err(e) => {{
  223. return e.to_kernel_errno();
  224. }}
  225. }}
  226. }}
  227. fn __exit() {{
  228. unsafe {{
  229. // Invokes `drop()` on `__MOD`, which should be used for cleanup.
  230. __MOD = None;
  231. }}
  232. }}
  233. {modinfo}
  234. ",
  235. type_ = info.type_,
  236. name = info.name,
  237. modinfo = modinfo.buffer,
  238. initcall_section = ".initcall6.init"
  239. )
  240. .parse()
  241. .expect("Error parsing formatted string into token stream.")
  242. }