summaryrefslogtreecommitdiff
path: root/rust/src/demangle.rs
diff options
context:
space:
mode:
authorMason Reed <mason@vector35.com>2024-04-24 18:33:11 -0400
committerMason Reed <mason@vector35.com>2024-05-03 11:25:32 -0400
commit80201094d494278493e2e08f6adc7c2b4c5b0ad6 (patch)
treef770620e12d5b8c21155c2a67b3d66e34816b2ed /rust/src/demangle.rs
parent92a468d7566de31e6867a77c5cf1c64e33792109 (diff)
Expose LLVM demangler
Diffstat (limited to 'rust/src/demangle.rs')
-rw-r--r--rust/src/demangle.rs43
1 files changed, 43 insertions, 0 deletions
diff --git a/rust/src/demangle.rs b/rust/src/demangle.rs
index 3756ea06..1b940ff9 100644
--- a/rust/src/demangle.rs
+++ b/rust/src/demangle.rs
@@ -26,6 +26,49 @@ use crate::rc::*;
pub type Result<R> = result::Result<R, ()>;
+pub fn demangle_llvm<S: BnStrCompatible>(
+ mangled_name: S,
+ simplify: bool,
+) -> Result<Vec<String>> {
+ let mangled_name_bwn = mangled_name.into_bytes_with_nul();
+ let mangled_name_ptr = mangled_name_bwn.as_ref();
+ let mut out_name: *mut *mut std::os::raw::c_char = unsafe { std::mem::zeroed() };
+ let mut out_size: usize = 0;
+ let res = unsafe {
+ BNDemangleLLVM(
+ mangled_name_ptr.as_ptr() as *const c_char,
+ &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_llvm: failed to parse mangled name");
+ return Err(());
+ }
+ };
+ return Ok(vec![cstr.to_string_lossy().into_owned()]);
+ }
+
+ if out_name.is_null() {
+ log::error!("demangle_llvm: out_name is NULL");
+ return Err(());
+ }
+
+ let names = unsafe { ArrayGuard::<BnString>::new(out_name, out_size, ()) }
+ .iter()
+ .map(str::to_string)
+ .collect();
+
+ unsafe { BNFreeDemangledName(&mut out_name, out_size) };
+
+ Ok(names)
+}
+
pub fn demangle_gnu3<S: BnStrCompatible>(
arch: &CoreArchitecture,
mangled_name: S,