From 9c4c6b806806867f46d4a8e7e5f7673e010ddc23 Mon Sep 17 00:00:00 2001 From: Thomas Lamb Date: Mon, 19 Oct 2026 01:16:39 -0400 Subject: [PATCH] Fix MIPS NON_MATCHING symbols when undefined symbol shadows ignored name When a base object contains an undefined symbol with the same name as a NON_MATCHING-marked function, object.symbol_by_name could return that undefined symbol instead of the defined function. This left the placeholder unignored and erroneously reported as matched. --- objdiff-core/src/arch/mips.rs | 11 +++++--- objdiff-core/tests/arch_mips.rs | 26 ++++++++++++++++++ .../tests/data/mips/non_matching_undef.o | Bin 0 -> 936 bytes 3 files changed, 33 insertions(+), 4 deletions(-) create mode 100644 objdiff-core/tests/data/mips/non_matching_undef.o diff --git a/objdiff-core/src/arch/mips.rs b/objdiff-core/src/arch/mips.rs index 72687d9f..98d7fa81 100644 --- a/objdiff-core/src/arch/mips.rs +++ b/objdiff-core/src/arch/mips.rs @@ -130,10 +130,13 @@ impl ArchMips { ignored_symbols.insert(obj_symbol.index().0); // Only remove the prefixless symbols if we are on the Base side of the diff, // to allow diffing against target objects that contain `.NON_MATCHING` markers. - if diff_side == DiffSide::Base - && let Some(target_symbol) = object.symbol_by_name(prefix) - { - ignored_symbols.insert(target_symbol.index().0); + if diff_side == DiffSide::Base { + for candidate in object.symbols() { + let Ok(candidate_name) = candidate.name() else { continue }; + if candidate_name == prefix { + ignored_symbols.insert(candidate.index().0); + } + } } } } diff --git a/objdiff-core/tests/arch_mips.rs b/objdiff-core/tests/arch_mips.rs index 79ae0083..a81d4ae5 100644 --- a/objdiff-core/tests/arch_mips.rs +++ b/objdiff-core/tests/arch_mips.rs @@ -127,3 +127,29 @@ fn ee_gcc_mdebug_line_numbers() { assert_eq!(text_section.line_info.get(&144), Some(&13)); assert_eq!(text_section.line_info.len(), 10); } + +#[test] +#[cfg(feature = "mips")] +fn filter_non_matching_with_undef_symbol() { + let diff_config = diff::DiffObjConfig::default(); + let obj = obj::read::parse( + include_object!("data/mips/non_matching_undef.o"), + &diff_config, + diff::DiffSide::Base, + ) + .unwrap(); + + let defined_foo = obj + .symbols + .iter() + .find(|s| s.name == "foo" && s.section.is_some()) + .expect("defined foo symbol present"); + assert!( + defined_foo.flags.contains(obj::SymbolFlag::Ignored), + "defined foo symbol should be ignored when a same-named undefined symbol exists" + ); + + let marker = + obj.symbols.iter().find(|s| s.name == "foo.NON_MATCHING").expect("marker symbol present"); + assert!(marker.flags.contains(obj::SymbolFlag::Ignored)); +} diff --git a/objdiff-core/tests/data/mips/non_matching_undef.o b/objdiff-core/tests/data/mips/non_matching_undef.o new file mode 100644 index 0000000000000000000000000000000000000000..351e7f52ceea52bdbdafbfe1824be314758039e4 GIT binary patch literal 936 zcmZuvO-sW-5S^see&C_?DnbMgwTDnpZyqYa+JcFKqTWJU;s-RQqyhD$c=8{3_2{ub zK|F~+$g?xaj2(j$HZ$+-+nL?jeb_tb8HNF322^2=06q~I@Y2}I1T9#Cl1TscHD>GR zOHhF|#?=hhe{&OFh6ViQ*1&L;VLo4jZH1eF*@r;_7jX=BbUO;tsZSWg(Pc34HLp43 zZSTE1G1r5O!9Qs|IBOtD5>qwApkte1IbZ4j^WNjSs z)(Ahcj@C*$XdS)VkEiw*y3C$YKyOntl5Yn&o$poUtK>_wee^M=8nVAP*0BU6pNE95 XJ7b;H5Zx*2grgkqsxIx5jLz``#C%i? literal 0 HcmV?d00001