diff options
| author | Michael Krasnitski <michael.krasnitski@gmail.com> | 2023-01-06 14:13:55 -0500 |
|---|---|---|
| committer | Kyle Martin <krm504@nyu.edu> | 2023-01-10 00:11:27 -0500 |
| commit | 7eb2b8fc3bd39324a74e02652c8f678073947812 (patch) | |
| tree | 45fb2d86ce5241163e09df0fb03baec9d0d2f210 /rust/src | |
| parent | aa1e35b055feea170e421cc375b79eed2d46dad2 (diff) | |
Move `logger` module into its own file
Diffstat (limited to 'rust/src')
| -rw-r--r-- | rust/src/lib.rs | 141 | ||||
| -rw-r--r-- | rust/src/logger.rs | 137 |
2 files changed, 138 insertions, 140 deletions
diff --git a/rust/src/lib.rs b/rust/src/lib.rs index ca876a1c..81520189 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -151,6 +151,7 @@ pub mod headless; pub mod interaction; pub mod linearview; pub mod llil; +pub mod logger; pub mod metadata; pub mod platform; pub mod rc; @@ -190,146 +191,6 @@ pub use binaryninjacore_sys::BNEndianness as Endianness; const BN_FULL_CONFIDENCE: u8 = 255; const BN_INVALID_EXPR: usize = usize::MAX; -pub mod logger { - use std::os::raw::{c_char, c_void}; - - use log; - - use crate::string::BnStr; - - pub use binaryninjacore_sys::BNLogLevel as Level; - use binaryninjacore_sys::{BNLogListener, BNUpdateLogListeners}; - - struct Logger; - static LOGGER: Logger = Logger; - - impl log::Log for Logger { - fn enabled(&self, _metadata: &log::Metadata) -> bool { - true - } - - fn log(&self, record: &log::Record) { - use self::Level::*; - use binaryninjacore_sys::BNLog; - use log::Level; - use std::ffi::CString; - - let level = match record.level() { - Level::Error => ErrorLog, - Level::Warn => WarningLog, - Level::Info => InfoLog, - Level::Debug | Level::Trace => DebugLog, - }; - - if let Ok(msg) = CString::new(format!("{}", record.args())) { - unsafe { - BNLog(0, level, std::ptr::null(), 0, msg.as_ptr()); - } - }; - } - - fn flush(&self) {} - } - - /// Uses BinaryNinja's logging functionality as the sink for - /// Rust's `log` crate. - pub fn init(filter: log::LevelFilter) -> Result<(), log::SetLoggerError> { - log::set_max_level(filter); - log::set_logger(&LOGGER) - } - - pub trait LogListener: 'static + Sync { - fn log(&self, session: usize, level: Level, msg: &BnStr, logger_name: &BnStr, tid: usize); - fn level(&self) -> Level; - fn close(&self) {} - } - - pub struct LogGuard<L: LogListener> { - ctxt: *mut L, - } - - impl<L: LogListener> Drop for LogGuard<L> { - fn drop(&mut self) { - use binaryninjacore_sys::BNUnregisterLogListener; - - let mut bn_obj = BNLogListener { - context: self.ctxt as *mut _, - log: Some(cb_log::<L>), - close: Some(cb_close::<L>), - getLogLevel: Some(cb_level::<L>), - }; - - unsafe { - BNUnregisterLogListener(&mut bn_obj); - BNUpdateLogListeners(); - - let _listener = Box::from_raw(self.ctxt); - } - } - } - - pub fn register_listener<L: LogListener>(listener: L) -> LogGuard<L> { - use binaryninjacore_sys::BNRegisterLogListener; - - let raw = Box::into_raw(Box::new(listener)); - let mut bn_obj = BNLogListener { - context: raw as *mut _, - log: Some(cb_log::<L>), - close: Some(cb_close::<L>), - getLogLevel: Some(cb_level::<L>), - }; - - unsafe { - BNRegisterLogListener(&mut bn_obj); - BNUpdateLogListeners(); - } - - LogGuard { ctxt: raw } - } - - extern "C" fn cb_log<L>( - ctxt: *mut c_void, - session: usize, - level: Level, - msg: *const c_char, - logger_name: *const c_char, - tid: usize, - ) where - L: LogListener, - { - ffi_wrap!("LogListener::log", unsafe { - let listener = &*(ctxt as *const L); - listener.log( - session, - level, - BnStr::from_raw(msg), - BnStr::from_raw(logger_name), - tid, - ); - }) - } - - extern "C" fn cb_close<L>(ctxt: *mut c_void) - where - L: LogListener, - { - ffi_wrap!("LogListener::close", unsafe { - let listener = &*(ctxt as *const L); - listener.close(); - }) - } - - extern "C" fn cb_level<L>(ctxt: *mut c_void) -> Level - where - L: LogListener, - { - ffi_wrap!("LogListener::log", unsafe { - let listener = &*(ctxt as *const L); - listener.level() - }) - } -} - fn open_binary_file( metadata: &mut filemetadata::FileMetadata, is_bndb: bool, diff --git a/rust/src/logger.rs b/rust/src/logger.rs new file mode 100644 index 00000000..2b067892 --- /dev/null +++ b/rust/src/logger.rs @@ -0,0 +1,137 @@ +use std::os::raw::{c_char, c_void}; + +use log; + +use crate::string::BnStr; + +pub use binaryninjacore_sys::BNLogLevel as Level; +use binaryninjacore_sys::{BNLogListener, BNUpdateLogListeners}; + +struct Logger; +static LOGGER: Logger = Logger; + +impl log::Log for Logger { + fn enabled(&self, _metadata: &log::Metadata) -> bool { + true + } + + fn log(&self, record: &log::Record) { + use self::Level::*; + use binaryninjacore_sys::BNLog; + use log::Level; + use std::ffi::CString; + + let level = match record.level() { + Level::Error => ErrorLog, + Level::Warn => WarningLog, + Level::Info => InfoLog, + Level::Debug | Level::Trace => DebugLog, + }; + + if let Ok(msg) = CString::new(format!("{}", record.args())) { + unsafe { + BNLog(0, level, std::ptr::null(), 0, msg.as_ptr()); + } + }; + } + + fn flush(&self) {} +} + +/// Uses BinaryNinja's logging functionality as the sink for +/// Rust's `log` crate. +pub fn init(filter: log::LevelFilter) -> Result<(), log::SetLoggerError> { + log::set_max_level(filter); + log::set_logger(&LOGGER) +} + +pub trait LogListener: 'static + Sync { + fn log(&self, session: usize, level: Level, msg: &BnStr, logger_name: &BnStr, tid: usize); + fn level(&self) -> Level; + fn close(&self) {} +} + +pub struct LogGuard<L: LogListener> { + ctxt: *mut L, +} + +impl<L: LogListener> Drop for LogGuard<L> { + fn drop(&mut self) { + use binaryninjacore_sys::BNUnregisterLogListener; + + let mut bn_obj = BNLogListener { + context: self.ctxt as *mut _, + log: Some(cb_log::<L>), + close: Some(cb_close::<L>), + getLogLevel: Some(cb_level::<L>), + }; + + unsafe { + BNUnregisterLogListener(&mut bn_obj); + BNUpdateLogListeners(); + + let _listener = Box::from_raw(self.ctxt); + } + } +} + +pub fn register_listener<L: LogListener>(listener: L) -> LogGuard<L> { + use binaryninjacore_sys::BNRegisterLogListener; + + let raw = Box::into_raw(Box::new(listener)); + let mut bn_obj = BNLogListener { + context: raw as *mut _, + log: Some(cb_log::<L>), + close: Some(cb_close::<L>), + getLogLevel: Some(cb_level::<L>), + }; + + unsafe { + BNRegisterLogListener(&mut bn_obj); + BNUpdateLogListeners(); + } + + LogGuard { ctxt: raw } +} + +extern "C" fn cb_log<L>( + ctxt: *mut c_void, + session: usize, + level: Level, + msg: *const c_char, + logger_name: *const c_char, + tid: usize, +) where + L: LogListener, +{ + ffi_wrap!("LogListener::log", unsafe { + let listener = &*(ctxt as *const L); + listener.log( + session, + level, + BnStr::from_raw(msg), + BnStr::from_raw(logger_name), + tid, + ); + }) +} + +extern "C" fn cb_close<L>(ctxt: *mut c_void) +where + L: LogListener, +{ + ffi_wrap!("LogListener::close", unsafe { + let listener = &*(ctxt as *const L); + listener.close(); + }) +} + +extern "C" fn cb_level<L>(ctxt: *mut c_void) -> Level +where + L: LogListener, +{ + ffi_wrap!("LogListener::log", unsafe { + let listener = &*(ctxt as *const L); + listener.level() + }) +} |
