From 06053ff729f4d44d750c53c5bdc48049989a8925 Mon Sep 17 00:00:00 2001 From: Anghelo Carvajal Date: Thu, 18 Sep 2025 19:22:34 -0300 Subject: [PATCH 1/8] [MIPS] Use gnuv2_demangle for better demangling --- Cargo.lock | 7 +++++++ objdiff-core/Cargo.toml | 2 ++ objdiff-core/src/arch/mips.rs | 10 +++++++--- 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index dd9a5b8..a91c47f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2020,6 +2020,12 @@ dependencies = [ "gl_generator", ] +[[package]] +name = "gnuv2_demangle" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73012a2b235359cdf9e71e153da760f7268a4ad1e2c86fa3a70dca2113015695" + [[package]] name = "gpu-alloc" version = "0.6.0" @@ -3504,6 +3510,7 @@ dependencies = [ "flagset", "gimli 0.32.0", "globset", + "gnuv2_demangle", "heck", "iced-x86", "insta", diff --git a/objdiff-core/Cargo.toml b/objdiff-core/Cargo.toml index 52acf71..fb6797d 100644 --- a/objdiff-core/Cargo.toml +++ b/objdiff-core/Cargo.toml @@ -91,6 +91,7 @@ mips = [ "dep:cpp_demangle", "dep:cwdemangle", "dep:rabbitizer", + "dep:gnuv2_demangle", ] ppc = [ "any-arch", @@ -157,6 +158,7 @@ rlwinmdec = { version = "1.1", optional = true } # mips rabbitizer = { version = "2.0.0-alpha.4", default-features = false, features = ["all_extensions"], optional = true } +gnuv2_demangle ={ version = "0.1.0", optional = true } # x86 cpp_demangle = { version = "0.4", default-features = false, features = ["alloc"], optional = true } diff --git a/objdiff-core/src/arch/mips.rs b/objdiff-core/src/arch/mips.rs index 134e2f1..09bb6ea 100644 --- a/objdiff-core/src/arch/mips.rs +++ b/objdiff-core/src/arch/mips.rs @@ -305,10 +305,14 @@ impl Arch for ArchMips { } fn demangle(&self, name: &str) -> Option { - cpp_demangle::Symbol::new(name) + gnuv2_demangle::demangle(name, &gnuv2_demangle::DemangleConfig::new_no_cfilt_mimics()) .ok() - .and_then(|s| s.demangle(&cpp_demangle::DemangleOptions::default()).ok()) - .or_else(|| cwdemangle::demangle(name, &cwdemangle::DemangleOptions::default())) + .or_else(|| { + cpp_demangle::Symbol::new(name) + .ok() + .and_then(|s| s.demangle(&cpp_demangle::DemangleOptions::default()).ok()) + .or_else(|| cwdemangle::demangle(name, &cwdemangle::DemangleOptions::default())) + }) } fn reloc_name(&self, flags: RelocationFlags) -> Option<&'static str> { From 7620f53e16acea4fea637b18de5277282918c9ca Mon Sep 17 00:00:00 2001 From: Anghelo Carvajal Date: Sat, 20 Sep 2025 11:25:37 -0300 Subject: [PATCH 2/8] Add gnuv2_demangle to x86 --- objdiff-core/Cargo.toml | 1 + objdiff-core/src/arch/x86.rs | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/objdiff-core/Cargo.toml b/objdiff-core/Cargo.toml index fb6797d..672b5c4 100644 --- a/objdiff-core/Cargo.toml +++ b/objdiff-core/Cargo.toml @@ -105,6 +105,7 @@ x86 = [ "dep:cpp_demangle", "dep:iced-x86", "dep:msvc-demangler", + "dep:gnuv2_demangle", ] arm = [ "any-arch", diff --git a/objdiff-core/src/arch/x86.rs b/objdiff-core/src/arch/x86.rs index ab5ffec..1ac3f1d 100644 --- a/objdiff-core/src/arch/x86.rs +++ b/objdiff-core/src/arch/x86.rs @@ -307,6 +307,13 @@ impl Arch for ArchX86 { cpp_demangle::Symbol::new(name) .ok() .and_then(|s| s.demangle(&cpp_demangle::DemangleOptions::default()).ok()) + .or_else(|| { + gnuv2_demangle::demangle( + name, + &gnuv2_demangle::DemangleConfig::new_no_cfilt_mimics(), + ) + .ok() + }) } } From 213a9a0edf17caa801a246eda10607a45882056e Mon Sep 17 00:00:00 2001 From: Anghelo Carvajal Date: Sat, 20 Sep 2025 17:31:22 -0300 Subject: [PATCH 3/8] Arch independent demanglers --- objdiff-core/Cargo.toml | 18 +++++------ objdiff-core/config-schema.json | 32 ++++++++++++++++++++ objdiff-core/src/arch/arm.rs | 13 +------- objdiff-core/src/arch/arm64.rs | 12 +------- objdiff-core/src/arch/mips.rs | 13 +------- objdiff-core/src/arch/mod.rs | 2 -- objdiff-core/src/arch/ppc/mod.rs | 12 -------- objdiff-core/src/arch/superh/mod.rs | 8 +---- objdiff-core/src/arch/x86.rs | 19 +----------- objdiff-core/src/diff/demangler.rs | 46 +++++++++++++++++++++++++++++ objdiff-core/src/diff/mod.rs | 1 + objdiff-core/src/obj/read.rs | 16 +++++++--- 12 files changed, 104 insertions(+), 88 deletions(-) create mode 100644 objdiff-core/src/diff/demangler.rs diff --git a/objdiff-core/Cargo.toml b/objdiff-core/Cargo.toml index 672b5c4..9104200 100644 --- a/objdiff-core/Cargo.toml +++ b/objdiff-core/Cargo.toml @@ -41,7 +41,8 @@ any-arch = [ "dep:regex", "dep:similar", "dep:syn", - "dep:encoding_rs" + "dep:encoding_rs", + "demangler", ] bindings = [ "dep:prost", @@ -88,40 +89,37 @@ std = [ ] mips = [ "any-arch", - "dep:cpp_demangle", - "dep:cwdemangle", "dep:rabbitizer", - "dep:gnuv2_demangle", ] ppc = [ "any-arch", - "dep:cwdemangle", "dep:cwextab", "dep:powerpc", "dep:rlwinmdec", ] x86 = [ "any-arch", - "dep:cpp_demangle", "dep:iced-x86", - "dep:msvc-demangler", - "dep:gnuv2_demangle", ] arm = [ "any-arch", "dep:arm-attr", - "dep:cpp_demangle", "dep:unarm", ] arm64 = [ "any-arch", - "dep:cpp_demangle", "dep:yaxpeax-arch", "dep:yaxpeax-arm", ] superh = [ "any-arch", ] +demangler = [ + "dep:cpp_demangle", + "dep:cwdemangle", + "dep:gnuv2_demangle", + "dep:msvc-demangler", +] [package.metadata.docs.rs] features = ["all"] diff --git a/objdiff-core/config-schema.json b/objdiff-core/config-schema.json index 9dd46d3..6261104 100644 --- a/objdiff-core/config-schema.json +++ b/objdiff-core/config-schema.json @@ -25,6 +25,37 @@ } ] }, + { + "id": "demangler", + "type": "choice", + "default": "auto", + "name": "Demangler", + "description": "Which demangler should be used to demangle each symbol.", + "items": [ + { + "value": "auto", + "name": "Auto", + "description": "Try to automatically guess the mangling format." + }, + { + "value": "codewarrior", + "name": "CodeWarrior" + }, + { + "value": "msvc", + "name": "MSVC" + }, + { + "value": "gnu_modern", + "name": "GNU g++ (Itanium)" + }, + { + "value": "gnu_v2", + "name": "GNU g++ (V2)", + "description": "Use the old GNU mangling ABI. Used up to g++ 2.9.x" + } + ] + }, { "id": "analyzeDataFlow", "type": "boolean", @@ -259,6 +290,7 @@ "name": "General", "properties": [ "functionRelocDiffs", + "demangler", "spaceBetweenArgs", "combineDataSections", "combineTextSections" diff --git a/objdiff-core/src/arch/arm.rs b/objdiff-core/src/arch/arm.rs index 4397336..fc67d10 100644 --- a/objdiff-core/src/arch/arm.rs +++ b/objdiff-core/src/arch/arm.rs @@ -1,9 +1,4 @@ -use alloc::{ - collections::BTreeMap, - format, - string::{String, ToString}, - vec::Vec, -}; +use alloc::{collections::BTreeMap, format, string::ToString, vec::Vec}; use anyhow::{Result, bail}; use arm_attr::{BuildAttrs, enums::CpuArch, tag::Tag}; @@ -409,12 +404,6 @@ impl Arch for ArchArm { } } - fn demangle(&self, name: &str) -> Option { - 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> { match flags { RelocationFlags::Elf(r_type) => match r_type { diff --git a/objdiff-core/src/arch/arm64.rs b/objdiff-core/src/arch/arm64.rs index e9d9a63..891a105 100644 --- a/objdiff-core/src/arch/arm64.rs +++ b/objdiff-core/src/arch/arm64.rs @@ -1,8 +1,4 @@ -use alloc::{ - format, - string::{String, ToString}, - vec::Vec, -}; +use alloc::{format, string::ToString, vec::Vec}; use core::cmp::Ordering; use anyhow::Result; @@ -108,12 +104,6 @@ impl Arch for ArchArm64 { Ok(()) } - fn demangle(&self, name: &str) -> Option { - 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> { match flags { RelocationFlags::Elf(r_type) => match r_type { diff --git a/objdiff-core/src/arch/mips.rs b/objdiff-core/src/arch/mips.rs index 09bb6ea..d38fc2d 100644 --- a/objdiff-core/src/arch/mips.rs +++ b/objdiff-core/src/arch/mips.rs @@ -1,6 +1,6 @@ use alloc::{ collections::{BTreeMap, BTreeSet}, - string::{String, ToString}, + string::ToString, vec::Vec, }; @@ -304,17 +304,6 @@ impl Arch for ArchMips { } } - fn demangle(&self, name: &str) -> Option { - gnuv2_demangle::demangle(name, &gnuv2_demangle::DemangleConfig::new_no_cfilt_mimics()) - .ok() - .or_else(|| { - cpp_demangle::Symbol::new(name) - .ok() - .and_then(|s| s.demangle(&cpp_demangle::DemangleOptions::default()).ok()) - .or_else(|| cwdemangle::demangle(name, &cwdemangle::DemangleOptions::default())) - }) - } - fn reloc_name(&self, flags: RelocationFlags) -> Option<&'static str> { match flags { RelocationFlags::Elf(r_type) => match r_type { diff --git a/objdiff-core/src/arch/mod.rs b/objdiff-core/src/arch/mod.rs index 3505ea9..601847d 100644 --- a/objdiff-core/src/arch/mod.rs +++ b/objdiff-core/src/arch/mod.rs @@ -371,8 +371,6 @@ pub trait Arch: Any + Debug + Send + Sync { Ok(None) } - fn demangle(&self, _name: &str) -> Option { None } - fn reloc_name(&self, _flags: RelocationFlags) -> Option<&'static str> { None } fn data_reloc_size(&self, flags: RelocationFlags) -> usize; diff --git a/objdiff-core/src/arch/ppc/mod.rs b/objdiff-core/src/arch/ppc/mod.rs index c23ba95..31ca501 100644 --- a/objdiff-core/src/arch/ppc/mod.rs +++ b/objdiff-core/src/arch/ppc/mod.rs @@ -308,18 +308,6 @@ impl Arch for ArchPpc { } } - fn demangle(&self, mut name: &str) -> Option { - if name.starts_with('?') { - msvc_demangler::demangle(name, msvc_demangler::DemangleFlags::llvm()).ok() - } else { - name = name.trim_start_matches('.'); - cpp_demangle::Symbol::new(name) - .ok() - .and_then(|s| s.demangle(&cpp_demangle::DemangleOptions::default()).ok()) - .or_else(|| cwdemangle::demangle(name, &cwdemangle::DemangleOptions::default())) - } - } - fn reloc_name(&self, flags: RelocationFlags) -> Option<&'static str> { match flags { RelocationFlags::Elf(r_type) => match r_type { diff --git a/objdiff-core/src/arch/superh/mod.rs b/objdiff-core/src/arch/superh/mod.rs index 39fc453..2da8845 100644 --- a/objdiff-core/src/arch/superh/mod.rs +++ b/objdiff-core/src/arch/superh/mod.rs @@ -1,4 +1,4 @@ -use alloc::{collections::BTreeMap, format, string::String, vec, vec::Vec}; +use alloc::{collections::BTreeMap, format, vec::Vec}; use anyhow::Result; use object::elf; @@ -132,12 +132,6 @@ impl Arch for ArchSuperH { Ok(()) } - fn demangle(&self, name: &str) -> Option { - 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> { match flags { RelocationFlags::Elf(r_type) => match r_type { diff --git a/objdiff-core/src/arch/x86.rs b/objdiff-core/src/arch/x86.rs index 1ac3f1d..0e4bee1 100644 --- a/objdiff-core/src/arch/x86.rs +++ b/objdiff-core/src/arch/x86.rs @@ -1,4 +1,4 @@ -use alloc::{boxed::Box, format, string::String, vec::Vec}; +use alloc::{boxed::Box, format, vec::Vec}; use core::cmp::Ordering; use anyhow::{Context, Result, anyhow, bail}; @@ -300,23 +300,6 @@ impl Arch for ArchX86 { Ok(Some(RelocationOverride { target: RelocationOverrideTarget::Keep, addend })) } - 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()) - .or_else(|| { - gnuv2_demangle::demangle( - name, - &gnuv2_demangle::DemangleConfig::new_no_cfilt_mimics(), - ) - .ok() - }) - } - } - fn reloc_name(&self, flags: RelocationFlags) -> Option<&'static str> { match self.arch { Architecture::X86 => match flags { diff --git a/objdiff-core/src/diff/demangler.rs b/objdiff-core/src/diff/demangler.rs new file mode 100644 index 0000000..780ece9 --- /dev/null +++ b/objdiff-core/src/diff/demangler.rs @@ -0,0 +1,46 @@ +use crate::diff::Demangler; + +#[cfg(feature = "demangler")] +impl Demangler { + pub fn demangle(&self, name: &str) -> Option { + match self { + Demangler::Codewarrior => Self::demangle_codewarrior(name), + Demangler::Msvc => Self::demangle_msvc(name), + Demangler::GnuModern => Self::demangle_gnu_modern(name), + Demangler::GnuV2 => Self::demangle_gnu_v2(name), + Demangler::Auto => { + // Try to guess + if name.starts_with('?') { + Self::demangle_msvc(name) + } else { + Self::demangle_codewarrior(name) + .or_else(|| Self::demangle_gnu_v2(name)) + .or_else(|| Self::demangle_gnu_modern(name)) + } + } + } + } + + fn demangle_codewarrior(name: &str) -> Option { + cwdemangle::demangle(name, &cwdemangle::DemangleOptions::default()) + } + + fn demangle_msvc(name: &str) -> Option { + msvc_demangler::demangle(name, msvc_demangler::DemangleFlags::llvm()).ok() + } + + fn demangle_gnu_modern(name: &str) -> Option { + cpp_demangle::Symbol::new(name) + .ok() + .and_then(|s| s.demangle(&cpp_demangle::DemangleOptions::default()).ok()) + } + + fn demangle_gnu_v2(name: &str) -> Option { + gnuv2_demangle::demangle(name, &gnuv2_demangle::DemangleConfig::new_no_cfilt_mimics()).ok() + } +} + +#[cfg(not(feature = "demangler"))] +impl Demangler { + pub fn demangle(&self, _name: &str) -> Option { None } +} diff --git a/objdiff-core/src/diff/mod.rs b/objdiff-core/src/diff/mod.rs index 26cc7aa..efbe2c2 100644 --- a/objdiff-core/src/diff/mod.rs +++ b/objdiff-core/src/diff/mod.rs @@ -22,6 +22,7 @@ use crate::{ pub mod code; pub mod data; +pub mod demangler; pub mod display; include!(concat!(env!("OUT_DIR"), "/config.gen.rs")); diff --git a/objdiff-core/src/obj/read.rs b/objdiff-core/src/obj/read.rs index 2bb6ad1..2dea685 100644 --- a/objdiff-core/src/obj/read.rs +++ b/objdiff-core/src/obj/read.rs @@ -41,6 +41,7 @@ fn map_symbol( symbol: &object::Symbol, section_indices: &[usize], split_meta: Option<&SplitMeta>, + config: &DiffObjConfig, ) -> Result { let mut name = symbol.name().context("Failed to process symbol name")?.to_string(); let mut size = symbol.size(); @@ -90,7 +91,7 @@ fn map_symbol( _ => SymbolKind::Unknown, }; let address = arch.symbol_address(symbol.address(), kind); - let demangled_name = arch.demangle(&name); + let demangled_name = config.demangler.demangle(&name); // Find the virtual address for the symbol if available let virtual_address = split_meta .and_then(|m| m.virtual_addresses.as_ref()) @@ -116,6 +117,7 @@ fn map_symbols( sections: &[Section], section_indices: &[usize], split_meta: Option<&SplitMeta>, + config: &DiffObjConfig, ) -> Result<(Vec, Vec)> { let symbol_count = obj_file.symbols().count(); let mut symbols = Vec::::with_capacity(symbol_count + obj_file.sections().count()); @@ -124,7 +126,7 @@ fn map_symbols( if symbol_indices.len() <= obj_symbol.index().0 { symbol_indices.resize(obj_symbol.index().0 + 1, usize::MAX); } - let symbol = map_symbol(arch, obj_file, &obj_symbol, section_indices, split_meta)?; + let symbol = map_symbol(arch, obj_file, &obj_symbol, section_indices, split_meta, config)?; symbol_indices[obj_symbol.index().0] = symbols.len(); symbols.push(symbol); } @@ -997,8 +999,14 @@ pub fn parse(data: &[u8], config: &DiffObjConfig, diff_side: DiffSide) -> Result let split_meta = parse_split_meta(&obj_file)?; let (mut sections, section_indices) = map_sections(arch.as_ref(), &obj_file, split_meta.as_ref())?; - let (mut symbols, symbol_indices) = - map_symbols(arch.as_ref(), &obj_file, §ions, §ion_indices, split_meta.as_ref())?; + let (mut symbols, symbol_indices) = map_symbols( + arch.as_ref(), + &obj_file, + §ions, + §ion_indices, + split_meta.as_ref(), + config, + )?; map_relocations(arch.as_ref(), &obj_file, &mut sections, §ion_indices, &symbol_indices)?; parse_line_info(&obj_file, &mut sections, §ion_indices, data)?; if config.combine_data_sections || config.combine_text_sections { From cf61d2e5a4eee03d9ba195619825790127517880 Mon Sep 17 00:00:00 2001 From: Anghelo Carvajal Date: Sat, 20 Sep 2025 17:54:33 -0300 Subject: [PATCH 4/8] Use new demangling logic on the "Demangle..." popup --- objdiff-gui/src/app.rs | 6 ++++-- objdiff-gui/src/views/demangle.rs | 4 +++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/objdiff-gui/src/app.rs b/objdiff-gui/src/app.rs index b0552a5..54dfc91 100644 --- a/objdiff-gui/src/app.rs +++ b/objdiff-gui/src/app.rs @@ -20,7 +20,7 @@ use objdiff_core::{ default_ignore_patterns, default_watch_patterns, path::platform_path_serde_option, save_project_config, }, - diff::DiffObjConfig, + diff::{Demangler, DiffObjConfig}, jobs::{Job, JobQueue, JobResult}, }; use time::UtcOffset; @@ -811,7 +811,9 @@ impl eframe::App for App { project_window(ctx, state, show_project_config, config_state, appearance); appearance_window(ctx, show_appearance_config, appearance); - demangle_window(ctx, show_demangle, demangle_state, appearance); + let demangler = + state.read().map(|state| state.config.diff_obj_config.demangler).unwrap_or_default(); + demangle_window(ctx, show_demangle, demangle_state, appearance, demangler); rlwinm_decode_window(ctx, show_rlwinm_decode, rlwinm_decode_state, appearance); arch_config_window(ctx, state, show_arch_config, appearance); debug_window(ctx, show_debug, frame_history, appearance); diff --git a/objdiff-gui/src/views/demangle.rs b/objdiff-gui/src/views/demangle.rs index c00f1c4..b8b2698 100644 --- a/objdiff-gui/src/views/demangle.rs +++ b/objdiff-gui/src/views/demangle.rs @@ -1,4 +1,5 @@ use egui::TextStyle; +use objdiff_core::diff::Demangler; use crate::views::appearance::Appearance; @@ -12,11 +13,12 @@ pub fn demangle_window( show: &mut bool, state: &mut DemangleViewState, appearance: &Appearance, + demangler: Demangler, ) { egui::Window::new("Demangle").open(show).show(ctx, |ui| { ui.text_edit_singleline(&mut state.text); ui.add_space(10.0); - if let Some(demangled) = cwdemangle::demangle(&state.text, &Default::default()) { + if let Some(demangled) = demangler.demangle(&state.text) { ui.scope(|ui| { ui.style_mut().override_text_style = Some(TextStyle::Monospace); ui.colored_label(appearance.replace_color, &demangled); From 680fe94352a039b0014d7cecbc958c688ff3376d Mon Sep 17 00:00:00 2001 From: Anghelo Carvajal Date: Sat, 20 Sep 2025 18:01:13 -0300 Subject: [PATCH 5/8] Fixes --- objdiff-core/src/arch/superh/mod.rs | 2 +- objdiff-core/src/diff/demangler.rs | 2 ++ objdiff-gui/src/app.rs | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/objdiff-core/src/arch/superh/mod.rs b/objdiff-core/src/arch/superh/mod.rs index 2da8845..fe5ba9c 100644 --- a/objdiff-core/src/arch/superh/mod.rs +++ b/objdiff-core/src/arch/superh/mod.rs @@ -1,4 +1,4 @@ -use alloc::{collections::BTreeMap, format, vec::Vec}; +use alloc::{collections::BTreeMap, format, vec, vec::Vec}; use anyhow::Result; use object::elf; diff --git a/objdiff-core/src/diff/demangler.rs b/objdiff-core/src/diff/demangler.rs index 780ece9..eb489c6 100644 --- a/objdiff-core/src/diff/demangler.rs +++ b/objdiff-core/src/diff/demangler.rs @@ -1,3 +1,5 @@ +use alloc::string::String; + use crate::diff::Demangler; #[cfg(feature = "demangler")] diff --git a/objdiff-gui/src/app.rs b/objdiff-gui/src/app.rs index 54dfc91..5baa71c 100644 --- a/objdiff-gui/src/app.rs +++ b/objdiff-gui/src/app.rs @@ -20,7 +20,7 @@ use objdiff_core::{ default_ignore_patterns, default_watch_patterns, path::platform_path_serde_option, save_project_config, }, - diff::{Demangler, DiffObjConfig}, + diff::DiffObjConfig, jobs::{Job, JobQueue, JobResult}, }; use time::UtcOffset; From 194137355efb50f66538bd005e60f3dc76500d86 Mon Sep 17 00:00:00 2001 From: Anghelo Carvajal Date: Sat, 20 Sep 2025 19:51:22 -0300 Subject: [PATCH 6/8] Rename to itanium --- objdiff-core/config-schema.json | 4 ++-- objdiff-core/src/diff/demangler.rs | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/objdiff-core/config-schema.json b/objdiff-core/config-schema.json index 6261104..70f658d 100644 --- a/objdiff-core/config-schema.json +++ b/objdiff-core/config-schema.json @@ -46,8 +46,8 @@ "name": "MSVC" }, { - "value": "gnu_modern", - "name": "GNU g++ (Itanium)" + "value": "itanium", + "name": "Itanium" }, { "value": "gnu_v2", diff --git a/objdiff-core/src/diff/demangler.rs b/objdiff-core/src/diff/demangler.rs index eb489c6..95e440c 100644 --- a/objdiff-core/src/diff/demangler.rs +++ b/objdiff-core/src/diff/demangler.rs @@ -8,7 +8,7 @@ impl Demangler { match self { Demangler::Codewarrior => Self::demangle_codewarrior(name), Demangler::Msvc => Self::demangle_msvc(name), - Demangler::GnuModern => Self::demangle_gnu_modern(name), + Demangler::Itanium => Self::demangle_itanium(name), Demangler::GnuV2 => Self::demangle_gnu_v2(name), Demangler::Auto => { // Try to guess @@ -17,7 +17,7 @@ impl Demangler { } else { Self::demangle_codewarrior(name) .or_else(|| Self::demangle_gnu_v2(name)) - .or_else(|| Self::demangle_gnu_modern(name)) + .or_else(|| Self::demangle_itanium(name)) } } } @@ -31,7 +31,7 @@ impl Demangler { msvc_demangler::demangle(name, msvc_demangler::DemangleFlags::llvm()).ok() } - fn demangle_gnu_modern(name: &str) -> Option { + fn demangle_itanium(name: &str) -> Option { cpp_demangle::Symbol::new(name) .ok() .and_then(|s| s.demangle(&cpp_demangle::DemangleOptions::default()).ok()) From 7e3619e9447519cb9cc668c24d62cdd0ef692fbc Mon Sep 17 00:00:00 2001 From: Anghelo Carvajal Date: Sat, 20 Sep 2025 20:16:26 -0300 Subject: [PATCH 7/8] Allow selecting the demangler on the "Demangle" popup --- objdiff-gui/src/app.rs | 4 +--- objdiff-gui/src/views/demangle.rs | 14 +++++++++++--- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/objdiff-gui/src/app.rs b/objdiff-gui/src/app.rs index 5baa71c..b0552a5 100644 --- a/objdiff-gui/src/app.rs +++ b/objdiff-gui/src/app.rs @@ -811,9 +811,7 @@ impl eframe::App for App { project_window(ctx, state, show_project_config, config_state, appearance); appearance_window(ctx, show_appearance_config, appearance); - let demangler = - state.read().map(|state| state.config.diff_obj_config.demangler).unwrap_or_default(); - demangle_window(ctx, show_demangle, demangle_state, appearance, demangler); + demangle_window(ctx, show_demangle, demangle_state, appearance); rlwinm_decode_window(ctx, show_rlwinm_decode, rlwinm_decode_state, appearance); arch_config_window(ctx, state, show_arch_config, appearance); debug_window(ctx, show_debug, frame_history, appearance); diff --git a/objdiff-gui/src/views/demangle.rs b/objdiff-gui/src/views/demangle.rs index b8b2698..31a4788 100644 --- a/objdiff-gui/src/views/demangle.rs +++ b/objdiff-gui/src/views/demangle.rs @@ -1,11 +1,12 @@ use egui::TextStyle; -use objdiff_core::diff::Demangler; +use objdiff_core::diff::{ConfigEnum, Demangler}; use crate::views::appearance::Appearance; #[derive(Default)] pub struct DemangleViewState { pub text: String, + pub demangler: Demangler, } pub fn demangle_window( @@ -13,12 +14,19 @@ pub fn demangle_window( show: &mut bool, state: &mut DemangleViewState, appearance: &Appearance, - demangler: Demangler, ) { egui::Window::new("Demangle").open(show).show(ctx, |ui| { + egui::ComboBox::from_label("Demangler") + .selected_text(state.demangler.name().to_string()) + .show_ui(ui, |ui| { + for demangler in Demangler::variants() { + ui.selectable_value(&mut state.demangler, *demangler, demangler.name()); + } + }); + ui.separator(); ui.text_edit_singleline(&mut state.text); ui.add_space(10.0); - if let Some(demangled) = demangler.demangle(&state.text) { + if let Some(demangled) = state.demangler.demangle(&state.text) { ui.scope(|ui| { ui.style_mut().override_text_style = Some(TextStyle::Monospace); ui.colored_label(appearance.replace_color, &demangled); From 6c9f241ab79a9675c4ad16a3805d7db3b1833fb7 Mon Sep 17 00:00:00 2001 From: Anghelo Carvajal Date: Mon, 22 Sep 2025 16:44:01 -0300 Subject: [PATCH 8/8] Address review --- objdiff-core/Cargo.toml | 10 ++++++---- objdiff-core/config-schema.json | 4 ++-- objdiff-core/src/diff/demangler.rs | 8 +++++--- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/objdiff-core/Cargo.toml b/objdiff-core/Cargo.toml index 9104200..eb91ad8 100644 --- a/objdiff-core/Cargo.toml +++ b/objdiff-core/Cargo.toml @@ -150,19 +150,15 @@ gimli = { git = "https://github.com/gimli-rs/gimli", rev = "7335f00e7c39fd501511 typed-arena = { version = "2.0", default-features = false, optional = true } # ppc -cwdemangle = { version = "1.0", optional = true } cwextab = { version = "1.1", optional = true } powerpc = { version = "0.4", optional = true } rlwinmdec = { version = "1.1", optional = true } # mips rabbitizer = { version = "2.0.0-alpha.4", default-features = false, features = ["all_extensions"], optional = true } -gnuv2_demangle ={ version = "0.1.0", optional = true } # x86 -cpp_demangle = { version = "0.4", default-features = false, features = ["alloc"], optional = true } iced-x86 = { version = "1.21", default-features = false, features = ["decoder", "intel", "gas", "masm", "nasm", "exhaustive_enums", "no_std"], optional = true } -msvc-demangler = { version = "0.11", optional = true } # arm unarm = { version = "1.9", optional = true } @@ -180,6 +176,12 @@ tempfile = { version = "3.20", optional = true } time = { version = "0.3", optional = true } encoding_rs = { version = "0.8.35", optional = true } +# demangler +cpp_demangle = { version = "0.4", optional = true, default-features = false, features = ["alloc"] } +cwdemangle = { version = "1.0", optional = true } +gnuv2_demangle = { version = "0.1.0", optional = true } +msvc-demangler = { version = "0.11", optional = true } + [target.'cfg(windows)'.dependencies] winapi = { version = "0.3", optional = true, features = ["winbase"] } diff --git a/objdiff-core/config-schema.json b/objdiff-core/config-schema.json index 70f658d..792b3c8 100644 --- a/objdiff-core/config-schema.json +++ b/objdiff-core/config-schema.json @@ -50,8 +50,8 @@ "name": "Itanium" }, { - "value": "gnu_v2", - "name": "GNU g++ (V2)", + "value": "gnu_legacy", + "name": "GNU g++ (Legacy)", "description": "Use the old GNU mangling ABI. Used up to g++ 2.9.x" } ] diff --git a/objdiff-core/src/diff/demangler.rs b/objdiff-core/src/diff/demangler.rs index 95e440c..5bfbb90 100644 --- a/objdiff-core/src/diff/demangler.rs +++ b/objdiff-core/src/diff/demangler.rs @@ -9,14 +9,14 @@ impl Demangler { Demangler::Codewarrior => Self::demangle_codewarrior(name), Demangler::Msvc => Self::demangle_msvc(name), Demangler::Itanium => Self::demangle_itanium(name), - Demangler::GnuV2 => Self::demangle_gnu_v2(name), + Demangler::GnuLegacy => Self::demangle_gnu_legacy(name), Demangler::Auto => { // Try to guess if name.starts_with('?') { Self::demangle_msvc(name) } else { Self::demangle_codewarrior(name) - .or_else(|| Self::demangle_gnu_v2(name)) + .or_else(|| Self::demangle_gnu_legacy(name)) .or_else(|| Self::demangle_itanium(name)) } } @@ -32,12 +32,14 @@ impl Demangler { } fn demangle_itanium(name: &str) -> Option { + let name = name.trim_start_matches('.'); cpp_demangle::Symbol::new(name) .ok() .and_then(|s| s.demangle(&cpp_demangle::DemangleOptions::default()).ok()) } - fn demangle_gnu_v2(name: &str) -> Option { + fn demangle_gnu_legacy(name: &str) -> Option { + let name = name.trim_start_matches('.'); gnuv2_demangle::demangle(name, &gnuv2_demangle::DemangleConfig::new_no_cfilt_mimics()).ok() } }