diff --git a/objdiff-core/src/diff/data.rs b/objdiff-core/src/diff/data.rs index 73b9175..cfaabb8 100644 --- a/objdiff-core/src/diff/data.rs +++ b/objdiff-core/src/diff/data.rs @@ -36,9 +36,23 @@ pub fn diff_bss_symbol( } pub fn symbol_name_matches(left_name: &str, right_name: &str) -> bool { - // Match Metrowerks symbol$1234 against symbol$2345 - // and GCC symbol.1234 against symbol.2345 - if let Some((prefix, suffix)) = left_name.split_once(['$', '.']) { + if let Some((left_prefix, left_suffix)) = left_name.split_once("@class$") + && let Some((right_prefix, right_suffix)) = right_name.split_once("@class$") + { + // Match Metrowerks anonymous class symbol names, ignoring the unique ID. + // e.g. __dt__Q29dCamera_c23@class$3665d_camera_cppFv + if left_prefix == right_prefix + && let Some(left_idx) = left_suffix.chars().position(|c| !c.is_numeric()) + && let Some(right_idx) = right_suffix.chars().position(|c| !c.is_numeric()) + { + // e.g. d_camera_cppFv (after the unique ID) + left_suffix[left_idx..] == right_suffix[right_idx..] + } else { + false + } + } else if let Some((prefix, suffix)) = left_name.split_once(['$', '.']) { + // Match Metrowerks symbol$1234 against symbol$2345 + // and GCC symbol.1234 against symbol.2345 if !suffix.chars().all(char::is_numeric) { return false; } diff --git a/objdiff-core/src/diff/mod.rs b/objdiff-core/src/diff/mod.rs index efbe2c2..2cbf7ab 100644 --- a/objdiff-core/src/diff/mod.rs +++ b/objdiff-core/src/diff/mod.rs @@ -7,6 +7,7 @@ use alloc::{ use core::{num::NonZeroU32, ops::Range}; use anyhow::Result; +use itertools::Itertools; use crate::{ diff::{ @@ -766,11 +767,15 @@ fn find_symbol( return Some(symbol_idx); } - if let Some((symbol_idx, _)) = unmatched_symbols(obj, used).find(|&(_, symbol)| { - symbol_name_matches(&in_symbol.name, &symbol.name) - && symbol_section_kind(obj, symbol) == section_kind - && symbol_section(obj, symbol).is_some_and(|(name, _)| name == section_name) - }) { + if let Some((symbol_idx, _)) = unmatched_symbols(obj, used) + .filter(|&(_, symbol)| { + symbol_name_matches(&in_symbol.name, &symbol.name) + && symbol_section_kind(obj, symbol) == section_kind + && symbol_section(obj, symbol).is_some_and(|(name, _)| name == section_name) + }) + .sorted_unstable_by_key(|&(_, symbol)| (symbol.section, symbol.address)) + .next() + { return Some(symbol_idx); }