summaryrefslogtreecommitdiff
path: root/rust/src
diff options
context:
space:
mode:
authorKyleMiles <krm504@nyu.edu>2022-02-14 19:18:37 -0500
committerKyleMiles <krm504@nyu.edu>2022-02-14 19:23:30 -0500
commit80f3ca9e22b40a92f3f671d1a840ec1c11674e4a (patch)
tree642fc482b413275802f4d2d986f01de685194263 /rust/src
parent2845ba6208ce3c29998a48df5073ed15a11ead77 (diff)
rust: add demangle helpers for gnu3 and ms
Co-authored-by: EliseZeroTwo <mail@elise.moe>
Diffstat (limited to 'rust/src')
-rw-r--r--rust/src/demangle.rs121
-rw-r--r--rust/src/lib.rs1
2 files changed, 122 insertions, 0 deletions
diff --git a/rust/src/demangle.rs b/rust/src/demangle.rs
new file mode 100644
index 00000000..ccc3d2de
--- /dev/null
+++ b/rust/src/demangle.rs
@@ -0,0 +1,121 @@
+use binaryninjacore_sys::*;
+use std::{ffi::CStr, result};
+
+use crate::architecture::CoreArchitecture;
+use crate::string::{BnStrCompatible, BnString};
+use crate::types::Type;
+
+use crate::rc::*;
+
+pub type Result<R> = result::Result<R, ()>;
+
+pub fn demangle_gnu3<S: BnStrCompatible>(
+ arch: &CoreArchitecture,
+ mangled_name: S,
+ simplify: bool,
+) -> Result<(Option<Ref<Type>>, Vec<String>)> {
+ let mangled_name_bwn = mangled_name.as_bytes_with_nul();
+ let mangled_name_ptr = mangled_name_bwn.as_ref();
+ let mut out_type: *mut BNType = unsafe { std::mem::zeroed() };
+ let mut out_name: *mut *mut std::os::raw::c_char = unsafe { std::mem::zeroed() };
+ let mut out_size: usize = 0;
+ let res = unsafe {
+ BNDemangleGNU3(
+ arch.0,
+ mangled_name_ptr.as_ptr() as *const i8,
+ &mut out_type,
+ &mut out_name,
+ &mut out_size,
+ simplify,
+ )
+ };
+
+ if !res || out_size == 0 {
+ let cstr = match CStr::from_bytes_with_nul(mangled_name_ptr) {
+ Ok(cstr) => cstr,
+ Err(_) => {
+ log::error!("demangle_gnu3: failed to parse mangled name");
+ return Err(());
+ }
+ };
+ return Ok((None, vec![cstr.to_string_lossy().into_owned()]));
+ }
+
+ let out_type = match out_type.is_null() {
+ true => {
+ log::debug!("demangle_gnu3: out_type is NULL");
+ None
+ }
+ false => Some(unsafe { Type::ref_from_raw(out_type) }),
+ };
+
+ if out_name.is_null() {
+ log::error!("demangle_gnu3: out_name is NULL");
+ return Err(());
+ }
+
+ let names = unsafe { ArrayGuard::<BnString>::new(out_name, out_size, ()) }
+ .iter()
+ .map(|name| name.to_string())
+ .collect();
+
+ unsafe { BNFreeDemangledName(&mut out_name, out_size) };
+
+ Ok((out_type, names))
+}
+
+pub fn demangle_ms<S: BnStrCompatible>(
+ arch: &CoreArchitecture,
+ mangled_name: S,
+ simplify: bool,
+) -> Result<(Option<Ref<Type>>, Vec<String>)> {
+ let mangled_name_bwn = mangled_name.as_bytes_with_nul();
+ let mangled_name_ptr = mangled_name_bwn.as_ref();
+
+ let mut out_type: *mut BNType = unsafe { std::mem::zeroed() };
+ let mut out_name: *mut *mut std::os::raw::c_char = unsafe { std::mem::zeroed() };
+ let mut out_size: usize = 0;
+ let res = unsafe {
+ BNDemangleMS(
+ arch.0,
+ mangled_name_ptr.as_ptr() as *const i8,
+ &mut out_type,
+ &mut out_name,
+ &mut out_size,
+ simplify,
+ )
+ };
+
+ if !res || out_size == 0 {
+ let cstr = match CStr::from_bytes_with_nul(mangled_name_ptr) {
+ Ok(cstr) => cstr,
+ Err(_) => {
+ log::error!("demangle_ms: failed to parse mangled name");
+ return Err(());
+ }
+ };
+ return Ok((None, vec![cstr.to_string_lossy().into_owned()]));
+ }
+
+ let out_type = match out_type.is_null() {
+ true => {
+ log::debug!("demangle_ms: out_type is NULL");
+ None
+ }
+ false => Some(unsafe { Type::ref_from_raw(out_type) }),
+ };
+
+ if out_name.is_null() {
+ log::error!("demangle_ms: out_name is NULL");
+ return Err(());
+ }
+
+ let names = unsafe { ArrayGuard::<BnString>::new(out_name, out_size, ()) }
+ .iter()
+ .map(|name| name.to_string())
+ .collect();
+
+ unsafe { BNFreeDemangledName(&mut out_name, out_size) };
+
+ Ok((out_type, names))
+}
diff --git a/rust/src/lib.rs b/rust/src/lib.rs
index 9c18d91d..966f3ff2 100644
--- a/rust/src/lib.rs
+++ b/rust/src/lib.rs
@@ -48,6 +48,7 @@ pub mod custombinaryview;
pub mod databuffer;
pub mod datavariable;
pub mod debuginfo;
+pub mod demangle;
pub mod disassembly;
pub mod fileaccessor;
pub mod filemetadata;