Skip to content

Commit d53c358

Browse files
authored
automatically match MSVC symbols in anonymous namespaces (#325)
* automatically match MSVC symbols in anonymous namespaces * tweak logic for detecting anonymous MSVC symbols * fix package format * address feedback * lazylock the regex * formatting * use once_cell instead * formatting * remove regex
1 parent f24c017 commit d53c358

File tree

1 file changed

+21
-0
lines changed

1 file changed

+21
-0
lines changed

objdiff-core/src/obj/read.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ fn map_section_kind(section: &object::Section) -> SectionKind {
4040
/// e.g. symbol$1234 and symbol$2345 will both be replaced with symbol$0000 internally.
4141
fn get_normalized_symbol_name(name: &str) -> Option<String> {
4242
const DUMMY_UNIQUE_ID: &str = "0000";
43+
const DUMMY_UNIQUE_MSVC_ID: &str = "00000000";
4344
if let Some((prefix, suffix)) = name.split_once("@class$")
4445
&& let Some(idx) = suffix.chars().position(|c| !c.is_numeric())
4546
&& idx > 0
@@ -59,6 +60,26 @@ fn get_normalized_symbol_name(name: &str) -> Option<String> {
5960
{
6061
// Match GCC symbol.1234 against symbol.2345
6162
Some(format!("{prefix}.{DUMMY_UNIQUE_ID}"))
63+
} else if name.starts_with('?') {
64+
// Match MSVC anonymous class symbol names, ignoring the unique ID.
65+
// e.g. ?CheckContextOr@?A0x24773155@@YA_NPBVDataArray@@@Z
66+
// and: ?CheckContextOr@?A0xddf6240c@@YA_NPBVDataArray@@@Z
67+
let mut name_str = String::from(name);
68+
let anon_indices: Vec<usize> = name_str.match_indices("?A0x").map(|(idx, _)| idx).collect();
69+
if !anon_indices.is_empty() {
70+
for idx in anon_indices {
71+
// the str sequence we're looking for is: ?A0xXXXXXXXX@@
72+
if u32::from_str_radix(&name_str[idx + 4..idx + 12], 16).is_ok()
73+
&& &name_str[idx + 12..idx + 14] == "@@"
74+
{
75+
// if the two above checks passed, we're good to replace the hash
76+
name_str.replace_range(idx + 4..idx + 12, DUMMY_UNIQUE_MSVC_ID);
77+
}
78+
}
79+
Some(name_str)
80+
} else {
81+
None
82+
}
6283
} else {
6384
None
6485
}

0 commit comments

Comments
 (0)