summaryrefslogtreecommitdiff
path: root/rust/src
diff options
context:
space:
mode:
authorGlenn Smith <glenn@vector35.com>2022-09-14 16:12:10 -0400
committerGlenn Smith <glenn@vector35.com>2022-09-29 21:02:23 -0400
commit273f6c483d7e36aa00287cf212990d54730c1845 (patch)
tree5e44abdeea714c58719284e2a984927c9418e64f /rust/src
parentc168d90ead13075b927a8d0737c21b1a7c4fa0ff (diff)
[Rust API] Fancier Debug impl for Type
Impl definitely not controversial and in no way will get me flamed for taking on a dependency
Diffstat (limited to 'rust/src')
-rw-r--r--rust/src/types.rs61
1 files changed, 54 insertions, 7 deletions
diff --git a/rust/src/types.rs b/rust/src/types.rs
index 90f595ed..790faca5 100644
--- a/rust/src/types.rs
+++ b/rust/src/types.rs
@@ -17,16 +17,21 @@
// TODO : Test the get_enumeration and get_structure methods
use binaryninjacore_sys::*;
+use lazy_static::lazy_static;
use std::borrow::Cow;
use std::ffi::CStr;
use std::fmt::{Debug, Display, Formatter};
use std::hash::{Hash, Hasher};
use std::iter::{zip, IntoIterator};
use std::os::raw::c_char;
+use std::sync::Mutex;
use std::{fmt, mem, ptr, result, slice};
use crate::architecture::{Architecture, CoreArchitecture};
+use crate::binaryview::BinaryView;
use crate::callingconvention::CallingConvention;
+use crate::disassembly::InstructionTextToken;
+use crate::filemetadata::FileMetadata;
use crate::string::{raw_to_string, BnStr, BnStrCompatible, BnString};
use crate::rc::*;
@@ -1177,15 +1182,57 @@ impl fmt::Display for Type {
}
}
+lazy_static! {
+ static ref TYPE_DEBUG_BV: Mutex<Option<Ref<BinaryView>>> =
+ Mutex::new(BinaryView::from_data(&FileMetadata::new(), &[]).ok());
+}
+
impl fmt::Debug for Type {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(f, "{}", unsafe {
- BnString::from_raw(BNGetTypeString(
- self.handle,
- ptr::null_mut(),
- BNTokenEscapingType::NoTokenEscapingType,
- ))
- })
+ if let Ok(lock) = TYPE_DEBUG_BV.lock() {
+ if let Some(bv) = &*lock {
+ let mut count: usize = 0;
+ let lines: *mut BNTypeDefinitionLine = unsafe {
+ BNGetTypeLines(
+ self.handle,
+ bv.handle,
+ "".as_ptr() as *const c_char,
+ 80,
+ false,
+ BNTokenEscapingType::NoTokenEscapingType,
+ &mut count as *mut usize,
+ )
+ };
+
+ if lines.is_null() {
+ return Err(fmt::Error);
+ }
+
+ let line_slice: &[BNTypeDefinitionLine] =
+ unsafe { slice::from_raw_parts(lines, count) };
+
+ for (i, line) in line_slice.iter().enumerate() {
+ if i > 0 {
+ write!(f, "\n")?;
+ }
+
+ let tokens: &[BNInstructionTextToken] =
+ unsafe { slice::from_raw_parts(line.tokens, line.count) };
+
+ for token in tokens {
+ let text: *const c_char = token.text;
+ let str = unsafe { CStr::from_ptr(text) };
+ write!(f, "{}", str.to_string_lossy())?;
+ }
+ }
+
+ unsafe {
+ BNFreeTypeDefinitionLineList(lines, count);
+ }
+ return Ok(());
+ }
+ }
+ Err(fmt::Error)
}
}