1 // SPDX-License-Identifier: GPL-2.0 2 3 //! Printing facilities. 4 //! 5 //! C header: [`include/linux/printk.h`](../../../../include/linux/printk.h) 6 //! 7 //! Reference: <https://www.kernel.org/doc/html/latest/core-api/printk-basics.html> 8 9 use core::{ 10 ffi::{c_char, c_void}, 11 fmt, 12 }; 13 14 use crate::str::RawFormatter; 15 16 #[cfg(CONFIG_PRINTK)] 17 use crate::bindings; 18 19 // Called from `vsprintf` with format specifier `%pA`. 20 #[no_mangle] 21 unsafe fn rust_fmt_argument(buf: *mut c_char, end: *mut c_char, ptr: *const c_void) -> *mut c_char { 22 use fmt::Write; 23 // SAFETY: The C contract guarantees that `buf` is valid if it's less than `end`. 24 let mut w = unsafe { RawFormatter::from_ptrs(buf.cast(), end.cast()) }; 25 let _ = w.write_fmt(unsafe { *(ptr as *const fmt::Arguments<'_>) }); 26 w.pos().cast() 27 } 28 29 /// Format strings. 30 /// 31 /// Public but hidden since it should only be used from public macros. 32 #[doc(hidden)] 33 pub mod format_strings { 34 use crate::bindings; 35 36 /// The length we copy from the `KERN_*` kernel prefixes. 37 const LENGTH_PREFIX: usize = 2; 38 39 /// The length of the fixed format strings. 40 pub const LENGTH: usize = 10; 41 42 /// Generates a fixed format string for the kernel's [`_printk`]. 43 /// 44 /// The format string is always the same for a given level, i.e. for a 45 /// given `prefix`, which are the kernel's `KERN_*` constants. 46 /// 47 /// [`_printk`]: ../../../../include/linux/printk.h 48 const fn generate(is_cont: bool, prefix: &[u8; 3]) -> [u8; LENGTH] { 49 // Ensure the `KERN_*` macros are what we expect. 50 assert!(prefix[0] == b'\x01'); 51 if is_cont { 52 assert!(prefix[1] == b'c'); 53 } else { 54 assert!(prefix[1] >= b'0' && prefix[1] <= b'7'); 55 } 56 assert!(prefix[2] == b'\x00'); 57 58 let suffix: &[u8; LENGTH - LENGTH_PREFIX] = if is_cont { 59 b"%pA\0\0\0\0\0" 60 } else { 61 b"%s: %pA\0" 62 }; 63 64 [ 65 prefix[0], prefix[1], suffix[0], suffix[1], suffix[2], suffix[3], suffix[4], suffix[5], 66 suffix[6], suffix[7], 67 ] 68 } 69 70 // Generate the format strings at compile-time. 71 // 72 // This avoids the compiler generating the contents on the fly in the stack. 73 // 74 // Furthermore, `static` instead of `const` is used to share the strings 75 // for all the kernel. 76 pub static EMERG: [u8; LENGTH] = generate(false, bindings::KERN_EMERG); 77 pub static ALERT: [u8; LENGTH] = generate(false, bindings::KERN_ALERT); 78 pub static CRIT: [u8; LENGTH] = generate(false, bindings::KERN_CRIT); 79 pub static ERR: [u8; LENGTH] = generate(false, bindings::KERN_ERR); 80 pub static WARNING: [u8; LENGTH] = generate(false, bindings::KERN_WARNING); 81 pub static NOTICE: [u8; LENGTH] = generate(false, bindings::KERN_NOTICE); 82 pub static INFO: [u8; LENGTH] = generate(false, bindings::KERN_INFO); 83 pub static DEBUG: [u8; LENGTH] = generate(false, bindings::KERN_DEBUG); 84 } 85 86 /// Prints a message via the kernel's [`_printk`]. 87 /// 88 /// Public but hidden since it should only be used from public macros. 89 /// 90 /// # Safety 91 /// 92 /// The format string must be one of the ones in [`format_strings`], and 93 /// the module name must be null-terminated. 94 /// 95 /// [`_printk`]: ../../../../include/linux/_printk.h 96 #[doc(hidden)] 97 #[cfg_attr(not(CONFIG_PRINTK), allow(unused_variables))] 98 pub unsafe fn call_printk( 99 format_string: &[u8; format_strings::LENGTH], 100 module_name: &[u8], 101 args: fmt::Arguments<'_>, 102 ) { 103 // `_printk` does not seem to fail in any path. 104 #[cfg(CONFIG_PRINTK)] 105 unsafe { 106 bindings::_printk( 107 format_string.as_ptr() as _, 108 module_name.as_ptr(), 109 &args as *const _ as *const c_void, 110 ); 111 } 112 } 113 114 /// Performs formatting and forwards the string to [`call_printk`]. 115 /// 116 /// Public but hidden since it should only be used from public macros. 117 #[doc(hidden)] 118 #[cfg(not(testlib))] 119 #[macro_export] 120 #[allow(clippy::crate_in_macro_def)] 121 macro_rules! print_macro ( 122 // The non-continuation cases (most of them, e.g. `INFO`). 123 ($format_string:path, $($arg:tt)+) => ( 124 // SAFETY: This hidden macro should only be called by the documented 125 // printing macros which ensure the format string is one of the fixed 126 // ones. All `__LOG_PREFIX`s are null-terminated as they are generated 127 // by the `module!` proc macro or fixed values defined in a kernel 128 // crate. 129 unsafe { 130 $crate::print::call_printk( 131 &$format_string, 132 crate::__LOG_PREFIX, 133 format_args!($($arg)+), 134 ); 135 } 136 ); 137 ); 138 139 /// Stub for doctests 140 #[cfg(testlib)] 141 #[macro_export] 142 macro_rules! print_macro ( 143 ($format_string:path, $e:expr, $($arg:tt)+) => ( 144 () 145 ); 146 ); 147 148 // We could use a macro to generate these macros. However, doing so ends 149 // up being a bit ugly: it requires the dollar token trick to escape `$` as 150 // well as playing with the `doc` attribute. Furthermore, they cannot be easily 151 // imported in the prelude due to [1]. So, for the moment, we just write them 152 // manually, like in the C side; while keeping most of the logic in another 153 // macro, i.e. [`print_macro`]. 154 // 155 // [1]: https://github.com/rust-lang/rust/issues/52234 156 157 /// Prints an emergency-level message (level 0). 158 /// 159 /// Use this level if the system is unusable. 160 /// 161 /// Equivalent to the kernel's [`pr_emerg`] macro. 162 /// 163 /// Mimics the interface of [`std::print!`]. See [`core::fmt`] and 164 /// `alloc::format!` for information about the formatting syntax. 165 /// 166 /// [`pr_emerg`]: https://www.kernel.org/doc/html/latest/core-api/printk-basics.html#c.pr_emerg 167 /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html 168 /// 169 /// # Examples 170 /// 171 /// ``` 172 /// pr_emerg!("hello {}\n", "there"); 173 /// ``` 174 #[macro_export] 175 macro_rules! pr_emerg ( 176 ($($arg:tt)*) => ( 177 $crate::print_macro!($crate::print::format_strings::EMERG, $($arg)*) 178 ) 179 ); 180 181 /// Prints an alert-level message (level 1). 182 /// 183 /// Use this level if action must be taken immediately. 184 /// 185 /// Equivalent to the kernel's [`pr_alert`] macro. 186 /// 187 /// Mimics the interface of [`std::print!`]. See [`core::fmt`] and 188 /// `alloc::format!` for information about the formatting syntax. 189 /// 190 /// [`pr_alert`]: https://www.kernel.org/doc/html/latest/core-api/printk-basics.html#c.pr_alert 191 /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html 192 /// 193 /// # Examples 194 /// 195 /// ``` 196 /// pr_alert!("hello {}\n", "there"); 197 /// ``` 198 #[macro_export] 199 macro_rules! pr_alert ( 200 ($($arg:tt)*) => ( 201 $crate::print_macro!($crate::print::format_strings::ALERT, $($arg)*) 202 ) 203 ); 204 205 /// Prints a critical-level message (level 2). 206 /// 207 /// Use this level for critical conditions. 208 /// 209 /// Equivalent to the kernel's [`pr_crit`] macro. 210 /// 211 /// Mimics the interface of [`std::print!`]. See [`core::fmt`] and 212 /// `alloc::format!` for information about the formatting syntax. 213 /// 214 /// [`pr_crit`]: https://www.kernel.org/doc/html/latest/core-api/printk-basics.html#c.pr_crit 215 /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html 216 /// 217 /// # Examples 218 /// 219 /// ``` 220 /// pr_crit!("hello {}\n", "there"); 221 /// ``` 222 #[macro_export] 223 macro_rules! pr_crit ( 224 ($($arg:tt)*) => ( 225 $crate::print_macro!($crate::print::format_strings::CRIT, $($arg)*) 226 ) 227 ); 228 229 /// Prints an error-level message (level 3). 230 /// 231 /// Use this level for error conditions. 232 /// 233 /// Equivalent to the kernel's [`pr_err`] macro. 234 /// 235 /// Mimics the interface of [`std::print!`]. See [`core::fmt`] and 236 /// `alloc::format!` for information about the formatting syntax. 237 /// 238 /// [`pr_err`]: https://www.kernel.org/doc/html/latest/core-api/printk-basics.html#c.pr_err 239 /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html 240 /// 241 /// # Examples 242 /// 243 /// ``` 244 /// pr_err!("hello {}\n", "there"); 245 /// ``` 246 #[macro_export] 247 macro_rules! pr_err ( 248 ($($arg:tt)*) => ( 249 $crate::print_macro!($crate::print::format_strings::ERR, $($arg)*) 250 ) 251 ); 252 253 /// Prints a warning-level message (level 4). 254 /// 255 /// Use this level for warning conditions. 256 /// 257 /// Equivalent to the kernel's [`pr_warn`] macro. 258 /// 259 /// Mimics the interface of [`std::print!`]. See [`core::fmt`] and 260 /// `alloc::format!` for information about the formatting syntax. 261 /// 262 /// [`pr_warn`]: https://www.kernel.org/doc/html/latest/core-api/printk-basics.html#c.pr_warn 263 /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html 264 /// 265 /// # Examples 266 /// 267 /// ``` 268 /// pr_warn!("hello {}\n", "there"); 269 /// ``` 270 #[macro_export] 271 macro_rules! pr_warn ( 272 ($($arg:tt)*) => ( 273 $crate::print_macro!($crate::print::format_strings::WARNING, $($arg)*) 274 ) 275 ); 276 277 /// Prints a notice-level message (level 5). 278 /// 279 /// Use this level for normal but significant conditions. 280 /// 281 /// Equivalent to the kernel's [`pr_notice`] macro. 282 /// 283 /// Mimics the interface of [`std::print!`]. See [`core::fmt`] and 284 /// `alloc::format!` for information about the formatting syntax. 285 /// 286 /// [`pr_notice`]: https://www.kernel.org/doc/html/latest/core-api/printk-basics.html#c.pr_notice 287 /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html 288 /// 289 /// # Examples 290 /// 291 /// ``` 292 /// pr_notice!("hello {}\n", "there"); 293 /// ``` 294 #[macro_export] 295 macro_rules! pr_notice ( 296 ($($arg:tt)*) => ( 297 $crate::print_macro!($crate::print::format_strings::NOTICE, $($arg)*) 298 ) 299 ); 300 301 /// Prints an info-level message (level 6). 302 /// 303 /// Use this level for informational messages. 304 /// 305 /// Equivalent to the kernel's [`pr_info`] macro. 306 /// 307 /// Mimics the interface of [`std::print!`]. See [`core::fmt`] and 308 /// `alloc::format!` for information about the formatting syntax. 309 /// 310 /// [`pr_info`]: https://www.kernel.org/doc/html/latest/core-api/printk-basics.html#c.pr_info 311 /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html 312 /// 313 /// # Examples 314 /// 315 /// ``` 316 /// pr_info!("hello {}\n", "there"); 317 /// ``` 318 #[macro_export] 319 #[doc(alias = "print")] 320 macro_rules! pr_info ( 321 ($($arg:tt)*) => ( 322 $crate::print_macro!($crate::print::format_strings::INFO, $($arg)*) 323 ) 324 ); 325 326 /// Prints a debug-level message (level 7). 327 /// 328 /// Use this level for debug messages. 329 /// 330 /// Equivalent to the kernel's [`pr_debug`] macro, except that it doesn't support dynamic debug 331 /// yet. 332 /// 333 /// Mimics the interface of [`std::print!`]. See [`core::fmt`] and 334 /// `alloc::format!` for information about the formatting syntax. 335 /// 336 /// [`pr_debug`]: https://www.kernel.org/doc/html/latest/core-api/printk-basics.html#c.pr_debug 337 /// [`std::print!`]: https://doc.rust-lang.org/std/macro.print.html 338 /// 339 /// # Examples 340 /// 341 /// ``` 342 /// pr_debug!("hello {}\n", "there"); 343 /// ``` 344 #[macro_export] 345 #[doc(alias = "print")] 346 macro_rules! pr_debug ( 347 ($($arg:tt)*) => ( 348 if cfg!(debug_assertions) { 349 $crate::print_macro!($crate::print::format_strings::DEBUG, $($arg)*) 350 } 351 ) 352 ); 353