Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 9 additions & 8 deletions objdiff-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ any-arch = [
"dep:regex",
"dep:similar",
"dep:syn",
"dep:encoding_rs"
"dep:encoding_rs",
"demangler",
]
bindings = [
"dep:prost",
Expand Down Expand Up @@ -88,38 +89,37 @@ std = [
]
mips = [
"any-arch",
"dep:cpp_demangle",
"dep:cwdemangle",
"dep:rabbitizer",
]
ppc = [
"any-arch",
"dep:cwdemangle",
"dep:cwextab",
"dep:powerpc",
"dep:rlwinmdec",
]
x86 = [
"any-arch",
"dep:cpp_demangle",
"dep:iced-x86",
"dep:msvc-demangler",
]
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"]
Expand Down Expand Up @@ -157,6 +157,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 }
Expand Down
32 changes: 32 additions & 0 deletions objdiff-core/config-schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": "itanium",
"name": "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",
Expand Down Expand Up @@ -259,6 +290,7 @@
"name": "General",
"properties": [
"functionRelocDiffs",
"demangler",
"spaceBetweenArgs",
"combineDataSections",
"combineTextSections"
Expand Down
13 changes: 1 addition & 12 deletions objdiff-core/src/arch/arm.rs
Original file line number Diff line number Diff line change
@@ -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};
Expand Down Expand Up @@ -409,12 +404,6 @@ impl Arch for ArchArm {
}
}

fn demangle(&self, name: &str) -> Option<String> {
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 {
Expand Down
12 changes: 1 addition & 11 deletions objdiff-core/src/arch/arm64.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -108,12 +104,6 @@ impl Arch for ArchArm64 {
Ok(())
}

fn demangle(&self, name: &str) -> Option<String> {
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 {
Expand Down
9 changes: 1 addition & 8 deletions objdiff-core/src/arch/mips.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use alloc::{
collections::{BTreeMap, BTreeSet},
string::{String, ToString},
string::ToString,
vec::Vec,
};

Expand Down Expand Up @@ -304,13 +304,6 @@ impl Arch for ArchMips {
}
}

fn demangle(&self, name: &str) -> Option<String> {
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 {
Expand Down
2 changes: 0 additions & 2 deletions objdiff-core/src/arch/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -371,8 +371,6 @@ pub trait Arch: Any + Debug + Send + Sync {
Ok(None)
}

fn demangle(&self, _name: &str) -> Option<String> { None }

fn reloc_name(&self, _flags: RelocationFlags) -> Option<&'static str> { None }

fn data_reloc_size(&self, flags: RelocationFlags) -> usize;
Expand Down
12 changes: 0 additions & 12 deletions objdiff-core/src/arch/ppc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -308,18 +308,6 @@ impl Arch for ArchPpc {
}
}

fn demangle(&self, mut name: &str) -> Option<String> {
if name.starts_with('?') {
msvc_demangler::demangle(name, msvc_demangler::DemangleFlags::llvm()).ok()
} else {
name = name.trim_start_matches('.');
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's keep this . trimming logic

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From what I can see only ppc has this trimming logic.

Do you want to always trim . when the demangler is not msvc? Or should it be only be applied to specific demanglers (cpp_demangle, cwdemangle, etc) ?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can just add it for itanium/gnuv2

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gotcha.

btw, I'm a bit curious, do you have an example a mangled symbol like this? I would like to take an small look at it.
It is okay if you don't have any, don't worry much about it.

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 {
Expand Down
8 changes: 1 addition & 7 deletions objdiff-core/src/arch/superh/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use alloc::{collections::BTreeMap, format, string::String, vec, vec::Vec};
use alloc::{collections::BTreeMap, format, vec, vec::Vec};

use anyhow::Result;
use object::elf;
Expand Down Expand Up @@ -132,12 +132,6 @@ impl Arch for ArchSuperH {
Ok(())
}

fn demangle(&self, name: &str) -> Option<String> {
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 {
Expand Down
12 changes: 1 addition & 11 deletions objdiff-core/src/arch/x86.rs
Original file line number Diff line number Diff line change
@@ -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};
Expand Down Expand Up @@ -300,16 +300,6 @@ impl Arch for ArchX86 {
Ok(Some(RelocationOverride { target: RelocationOverrideTarget::Keep, addend }))
}

fn demangle(&self, name: &str) -> Option<String> {
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())
}
}

fn reloc_name(&self, flags: RelocationFlags) -> Option<&'static str> {
match self.arch {
Architecture::X86 => match flags {
Expand Down
48 changes: 48 additions & 0 deletions objdiff-core/src/diff/demangler.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
use alloc::string::String;

use crate::diff::Demangler;

#[cfg(feature = "demangler")]
impl Demangler {
pub fn demangle(&self, name: &str) -> Option<String> {
match self {
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::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_itanium(name))
}
}
}
}

fn demangle_codewarrior(name: &str) -> Option<String> {
cwdemangle::demangle(name, &cwdemangle::DemangleOptions::default())
}

fn demangle_msvc(name: &str) -> Option<String> {
msvc_demangler::demangle(name, msvc_demangler::DemangleFlags::llvm()).ok()
}

fn demangle_itanium(name: &str) -> Option<String> {
cpp_demangle::Symbol::new(name)
.ok()
.and_then(|s| s.demangle(&cpp_demangle::DemangleOptions::default()).ok())
}

fn demangle_gnu_v2(name: &str) -> Option<String> {
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<String> { None }
}
1 change: 1 addition & 0 deletions objdiff-core/src/diff/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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"));
Expand Down
16 changes: 12 additions & 4 deletions objdiff-core/src/obj/read.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ fn map_symbol(
symbol: &object::Symbol,
section_indices: &[usize],
split_meta: Option<&SplitMeta>,
config: &DiffObjConfig,
) -> Result<Symbol> {
let mut name = symbol.name().context("Failed to process symbol name")?.to_string();
let mut size = symbol.size();
Expand Down Expand Up @@ -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())
Expand All @@ -116,6 +117,7 @@ fn map_symbols(
sections: &[Section],
section_indices: &[usize],
split_meta: Option<&SplitMeta>,
config: &DiffObjConfig,
) -> Result<(Vec<Symbol>, Vec<usize>)> {
let symbol_count = obj_file.symbols().count();
let mut symbols = Vec::<Symbol>::with_capacity(symbol_count + obj_file.sections().count());
Expand All @@ -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);
}
Expand Down Expand Up @@ -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, &sections, &section_indices, split_meta.as_ref())?;
let (mut symbols, symbol_indices) = map_symbols(
arch.as_ref(),
&obj_file,
&sections,
&section_indices,
split_meta.as_ref(),
config,
)?;
map_relocations(arch.as_ref(), &obj_file, &mut sections, &section_indices, &symbol_indices)?;
parse_line_info(&obj_file, &mut sections, &section_indices, data)?;
if config.combine_data_sections || config.combine_text_sections {
Expand Down
Loading
Loading