diff --git a/objdiff-core/src/obj/read.rs b/objdiff-core/src/obj/read.rs index a8aa1dd..e41e46d 100644 --- a/objdiff-core/src/obj/read.rs +++ b/objdiff-core/src/obj/read.rs @@ -10,6 +10,7 @@ use core::{cmp::Ordering, num::NonZeroU64}; use anyhow::{Context, Result, anyhow, bail, ensure}; use object::{Object as _, ObjectSection as _, ObjectSymbol as _}; +use regex::Regex; use crate::{ arch::{Arch, RelocationOverride, RelocationOverrideTarget, new_arch}, @@ -40,6 +41,7 @@ fn map_section_kind(section: &object::Section) -> SectionKind { /// e.g. symbol$1234 and symbol$2345 will both be replaced with symbol$0000 internally. fn get_normalized_symbol_name(name: &str) -> Option { const DUMMY_UNIQUE_ID: &str = "0000"; + const DUMMY_UNIQUE_MSVC_ID: &str = "00000000"; if let Some((prefix, suffix)) = name.split_once("@class$") && let Some(idx) = suffix.chars().position(|c| !c.is_numeric()) && idx > 0 @@ -59,6 +61,16 @@ fn get_normalized_symbol_name(name: &str) -> Option { { // Match GCC symbol.1234 against symbol.2345 Some(format!("{prefix}.{DUMMY_UNIQUE_ID}")) + } else if name.starts_with('?') { + // Match MSVC anonymous class symbol names, ignoring the unique ID. + // e.g. ?CheckContextOr@?A0x24773155@@YA_NPBVDataArray@@@Z + // and: ?CheckContextOr@?A0xddf6240c@@YA_NPBVDataArray@@@Z + let re = Regex::new(r"\?A0x[0-9A-Fa-f]{8}@@").unwrap(); + if re.is_match(name) { + Some(re.replace_all(name, format!("?A0x{DUMMY_UNIQUE_MSVC_ID}@@")).to_string()) + } else { + None + } } else { None }