diff --git a/Cargo.lock b/Cargo.lock index 306b957..0d7178e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3507,6 +3507,7 @@ dependencies = [ "typed-path", "unarm", "winapi", + "windows-sys 0.61.0", "yaxpeax-arch", "yaxpeax-arm", ] @@ -6281,6 +6282,12 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" +[[package]] +name = "windows-link" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45e46c0661abb7180e7b9c281db115305d49ca1709ab8242adf09666d2173c65" + [[package]] name = "windows-result" version = "0.2.0" @@ -6360,6 +6367,15 @@ dependencies = [ "windows-targets 0.53.3", ] +[[package]] +name = "windows-sys" +version = "0.61.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e201184e40b2ede64bc2ea34968b28e33622acdbbf37104f0e4a33f7abe657aa" +dependencies = [ + "windows-link 0.2.0", +] + [[package]] name = "windows-targets" version = "0.42.2" @@ -6412,7 +6428,7 @@ version = "0.53.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91" dependencies = [ - "windows-link", + "windows-link 0.1.3", "windows_aarch64_gnullvm 0.53.0", "windows_aarch64_msvc 0.53.0", "windows_i686_gnu 0.53.0", diff --git a/objdiff-core/Cargo.toml b/objdiff-core/Cargo.toml index 52acf71..2f8998e 100644 --- a/objdiff-core/Cargo.toml +++ b/objdiff-core/Cargo.toml @@ -181,6 +181,7 @@ encoding_rs = { version = "0.8.35", optional = true } [target.'cfg(windows)'.dependencies] winapi = { version = "0.3", optional = true, features = ["winbase"] } +windows-sys = { version = "0.61", optional = true, features = ["Win32_System_Diagnostics_Debug"] } # For Linux static binaries, use rustls [target.'cfg(target_os = "linux")'.dependencies] diff --git a/objdiff-core/src/arch/x86.rs b/objdiff-core/src/arch/x86.rs index 7b0bf58..70df4d8 100644 --- a/objdiff-core/src/arch/x86.rs +++ b/objdiff-core/src/arch/x86.rs @@ -304,12 +304,35 @@ impl Arch for ArchX86 { fn demangle(&self, name: &str) -> Option { if name.starts_with('?') { - msvc_demangler::demangle(name, msvc_demangler::DemangleFlags::llvm()).ok() - } else { - cpp_demangle::Symbol::new(name) - .ok() - .and_then(|s| s.demangle(&cpp_demangle::DemangleOptions::default()).ok()) + #[cfg(target_os = "windows")] + { + use std::ffi::{CStr, CString}; + + use windows_sys::Win32::System::Diagnostics::Debug::UnDecorateSymbolName; + + let cstr = CString::new(name).ok()?; + let mut buffer = vec![0u8; 1024]; + + unsafe { + let len = UnDecorateSymbolName( + cstr.as_ptr() as windows_sys::core::PCSTR, + buffer.as_mut_ptr() as windows_sys::core::PSTR, + buffer.len() as u32, + 0, // UNDNAME_COMPLETE + ); + if len > 0 { + let result = + CStr::from_ptr(buffer.as_ptr() as *const i8).to_str().ok()?.to_string(); + return Some(result); + } + } + } + return msvc_demangler::demangle(name, msvc_demangler::DemangleFlags::llvm()).ok(); } + + cpp_demangle::Symbol::new(name) + .ok() + .and_then(|s| s.demangle(&cpp_demangle::DemangleOptions::default()).ok()) } fn reloc_name(&self, flags: RelocationFlags) -> Option<&'static str> {