1*ab810022SBernhard Beschow // Copyright 2025 Bernhard Beschow <shentey@gmail.com> 2*ab810022SBernhard Beschow // SPDX-License-Identifier: GPL-2.0-or-later 3*ab810022SBernhard Beschow 4*ab810022SBernhard Beschow //! Bindings for QEMU's logging infrastructure 5*ab810022SBernhard Beschow 6*ab810022SBernhard Beschow #[repr(u32)] 7*ab810022SBernhard Beschow /// Represents specific error categories within QEMU's logging system. 8*ab810022SBernhard Beschow /// 9*ab810022SBernhard Beschow /// The `Log` enum provides a Rust abstraction for logging errors, corresponding 10*ab810022SBernhard Beschow /// to a subset of the error categories defined in the C implementation. 11*ab810022SBernhard Beschow pub enum Log { 12*ab810022SBernhard Beschow /// Log invalid access caused by the guest. 13*ab810022SBernhard Beschow /// Corresponds to `LOG_GUEST_ERROR` in the C implementation. 14*ab810022SBernhard Beschow GuestError = crate::bindings::LOG_GUEST_ERROR, 15*ab810022SBernhard Beschow 16*ab810022SBernhard Beschow /// Log guest access of unimplemented functionality. 17*ab810022SBernhard Beschow /// Corresponds to `LOG_UNIMP` in the C implementation. 18*ab810022SBernhard Beschow Unimp = crate::bindings::LOG_UNIMP, 19*ab810022SBernhard Beschow } 20*ab810022SBernhard Beschow 21*ab810022SBernhard Beschow /// A macro to log messages conditionally based on a provided mask. 22*ab810022SBernhard Beschow /// 23*ab810022SBernhard Beschow /// The `log_mask_ln` macro checks whether the given mask matches the current 24*ab810022SBernhard Beschow /// log level and, if so, formats and logs the message. It is the Rust 25*ab810022SBernhard Beschow /// counterpart of the `qemu_log_mask()` macro in the C implementation. 26*ab810022SBernhard Beschow /// 27*ab810022SBernhard Beschow /// # Parameters 28*ab810022SBernhard Beschow /// 29*ab810022SBernhard Beschow /// - `$mask`: A log level mask. This should be a variant of the `Log` enum. 30*ab810022SBernhard Beschow /// - `$fmt`: A format string following the syntax and rules of the `format!` 31*ab810022SBernhard Beschow /// macro. It specifies the structure of the log message. 32*ab810022SBernhard Beschow /// - `$args`: Optional arguments to be interpolated into the format string. 33*ab810022SBernhard Beschow /// 34*ab810022SBernhard Beschow /// # Example 35*ab810022SBernhard Beschow /// 36*ab810022SBernhard Beschow /// ``` 37*ab810022SBernhard Beschow /// use qemu_api::{log::Log, log_mask_ln}; 38*ab810022SBernhard Beschow /// 39*ab810022SBernhard Beschow /// let error_address = 0xbad; 40*ab810022SBernhard Beschow /// log_mask_ln!(Log::GuestError, "Address 0x{error_address:x} out of range"); 41*ab810022SBernhard Beschow /// ``` 42*ab810022SBernhard Beschow /// 43*ab810022SBernhard Beschow /// It is also possible to use printf-style formatting, as well as having a 44*ab810022SBernhard Beschow /// trailing `,`: 45*ab810022SBernhard Beschow /// 46*ab810022SBernhard Beschow /// ``` 47*ab810022SBernhard Beschow /// use qemu_api::{log::Log, log_mask_ln}; 48*ab810022SBernhard Beschow /// 49*ab810022SBernhard Beschow /// let error_address = 0xbad; 50*ab810022SBernhard Beschow /// log_mask_ln!( 51*ab810022SBernhard Beschow /// Log::GuestError, 52*ab810022SBernhard Beschow /// "Address 0x{:x} out of range", 53*ab810022SBernhard Beschow /// error_address, 54*ab810022SBernhard Beschow /// ); 55*ab810022SBernhard Beschow /// ``` 56*ab810022SBernhard Beschow #[macro_export] 57*ab810022SBernhard Beschow macro_rules! log_mask_ln { 58*ab810022SBernhard Beschow ($mask:expr, $fmt:tt $($args:tt)*) => {{ 59*ab810022SBernhard Beschow // Type assertion to enforce type `Log` for $mask 60*ab810022SBernhard Beschow let _: Log = $mask; 61*ab810022SBernhard Beschow 62*ab810022SBernhard Beschow if unsafe { 63*ab810022SBernhard Beschow (::qemu_api::bindings::qemu_loglevel & ($mask as std::os::raw::c_int)) != 0 64*ab810022SBernhard Beschow } { 65*ab810022SBernhard Beschow let formatted_string = format!("{}\n", format_args!($fmt $($args)*)); 66*ab810022SBernhard Beschow let c_string = std::ffi::CString::new(formatted_string).unwrap(); 67*ab810022SBernhard Beschow 68*ab810022SBernhard Beschow unsafe { 69*ab810022SBernhard Beschow ::qemu_api::bindings::qemu_log(c_string.as_ptr()); 70*ab810022SBernhard Beschow } 71*ab810022SBernhard Beschow } 72*ab810022SBernhard Beschow }}; 73*ab810022SBernhard Beschow } 74