Skip to content

Commit 6fb4bb8

Browse files
authored
[MIPS] Fix symbols being filtered out from target side of diff if target object contains .NON_MATCHING markers (#250)
* Fix filtering out symbols from the target side that have a symbol with the same name and a `.NON_MATCHING` suffix. - Target side: Show all the symbols except the `.NON_MATCHING` ones. - Base side: Ignore all the `.NON_MATCHING` symbols and also ignore the ones with the same name without the suffix * fmt * comment * tests * fmt tests * maybe this could fix wasm? * Fix wasm? * fmt * Move `DiffSide` to `diff` mod * Update the stuff the advisories CI told me to
1 parent a138dfa commit 6fb4bb8

File tree

13 files changed

+169
-44
lines changed

13 files changed

+169
-44
lines changed

objdiff-cli/src/cmd/report.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ use objdiff_core::{
88
Report, ReportCategory, ReportItem, ReportItemMetadata, ReportUnit, ReportUnitMetadata,
99
},
1010
config::path::platform_path,
11-
diff, obj,
12-
obj::{SectionKind, SymbolFlag},
11+
diff,
12+
obj::{self, SectionKind, SymbolFlag},
1313
};
1414
use prost::Message;
1515
use rayon::iter::{IntoParallelRefIterator, ParallelIterator};
@@ -177,14 +177,16 @@ fn report_object(
177177
.target_path
178178
.as_ref()
179179
.map(|p| {
180-
obj::read::read(p.as_ref(), diff_config).with_context(|| format!("Failed to open {p}"))
180+
obj::read::read(p.as_ref(), diff_config, diff::DiffSide::Target)
181+
.with_context(|| format!("Failed to open {p}"))
181182
})
182183
.transpose()?;
183184
let base = object
184185
.base_path
185186
.as_ref()
186187
.map(|p| {
187-
obj::read::read(p.as_ref(), diff_config).with_context(|| format!("Failed to open {p}"))
188+
obj::read::read(p.as_ref(), diff_config, diff::DiffSide::Base)
189+
.with_context(|| format!("Failed to open {p}"))
188190
})
189191
.transpose()?;
190192
let result =

objdiff-core/src/arch/mips.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use rabbitizer::{
1212

1313
use crate::{
1414
arch::{Arch, RelocationOverride, RelocationOverrideTarget},
15-
diff::{DiffObjConfig, MipsAbi, MipsInstrCategory, display::InstructionPart},
15+
diff::{DiffObjConfig, DiffSide, MipsAbi, MipsInstrCategory, display::InstructionPart},
1616
obj::{
1717
InstructionArg, InstructionArgValue, InstructionRef, Relocation, RelocationFlags,
1818
ResolvedInstructionRef, ResolvedRelocation, Section, Symbol, SymbolFlag, SymbolFlagSet,
@@ -27,6 +27,7 @@ pub struct ArchMips {
2727
pub ri_gp_value: i32,
2828
pub paired_relocations: Vec<BTreeMap<u64, i64>>,
2929
pub ignored_symbols: BTreeSet<usize>,
30+
pub diff_side: DiffSide,
3031
}
3132

3233
const EF_MIPS_ABI: u32 = 0x0000F000;
@@ -38,7 +39,7 @@ const EF_MIPS_MACH_5900: u32 = 0x00920000;
3839
const R_MIPS15_S3: u32 = 119;
3940

4041
impl ArchMips {
41-
pub fn new(object: &object::File) -> Result<Self> {
42+
pub fn new(object: &object::File, diff_side: DiffSide) -> Result<Self> {
4243
let mut abi = Abi::O32;
4344
let mut isa_extension = None;
4445
match object.flags() {
@@ -124,7 +125,11 @@ impl ArchMips {
124125
let Ok(name) = obj_symbol.name() else { continue };
125126
if let Some(prefix) = name.strip_suffix(".NON_MATCHING") {
126127
ignored_symbols.insert(obj_symbol.index().0);
127-
if let Some(target_symbol) = object.symbol_by_name(prefix) {
128+
// Only remove the prefixless symbols if we are on the Base side of the diff,
129+
// to allow diffing against target objects that contain `.NON_MATCHING` markers.
130+
if diff_side == DiffSide::Base
131+
&& let Some(target_symbol) = object.symbol_by_name(prefix)
132+
{
128133
ignored_symbols.insert(target_symbol.index().0);
129134
}
130135
}
@@ -137,6 +142,7 @@ impl ArchMips {
137142
ri_gp_value,
138143
paired_relocations,
139144
ignored_symbols,
145+
diff_side,
140146
})
141147
}
142148

objdiff-core/src/arch/mod.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use object::Endian as _;
1717

1818
use crate::{
1919
diff::{
20-
DiffObjConfig,
20+
DiffObjConfig, DiffSide,
2121
display::{ContextItem, HoverItem, InstructionPart},
2222
},
2323
obj::{
@@ -418,15 +418,18 @@ pub trait Arch: Any + Debug + Send + Sync {
418418
}
419419
}
420420

421-
pub fn new_arch(object: &object::File) -> Result<Box<dyn Arch>> {
421+
pub fn new_arch(object: &object::File, diff_side: DiffSide) -> Result<Box<dyn Arch>> {
422422
use object::Object as _;
423+
// Avoid unused warnings on non-mips builds
424+
let _ = diff_side;
425+
423426
Ok(match object.architecture() {
424427
#[cfg(feature = "ppc")]
425428
object::Architecture::PowerPc | object::Architecture::PowerPc64 => {
426429
Box::new(ppc::ArchPpc::new(object)?)
427430
}
428431
#[cfg(feature = "mips")]
429-
object::Architecture::Mips => Box::new(mips::ArchMips::new(object)?),
432+
object::Architecture::Mips => Box::new(mips::ArchMips::new(object, diff_side)?),
430433
#[cfg(feature = "x86")]
431434
object::Architecture::I386 | object::Architecture::X86_64 => {
432435
Box::new(x86::ArchX86::new(object)?)

objdiff-core/src/diff/mod.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -807,3 +807,11 @@ fn find_section(
807807
s.kind == section_kind && s.name == name && !matches.iter().any(|m| m.right == Some(i))
808808
})
809809
}
810+
811+
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
812+
pub enum DiffSide {
813+
/// The target/expected side of the diff.
814+
Target,
815+
/// The base side of the diff.
816+
Base,
817+
}

objdiff-core/src/jobs/objdiff.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use typed_path::Utf8PlatformPathBuf;
66

77
use crate::{
88
build::{BuildConfig, BuildStatus, run_make},
9-
diff::{DiffObjConfig, MappingConfig, ObjectDiff, diff_objs},
9+
diff::{DiffObjConfig, DiffSide, MappingConfig, ObjectDiff, diff_objs},
1010
jobs::{Job, JobContext, JobResult, JobState, start_job, update_status},
1111
obj::{Object, read},
1212
};
@@ -117,7 +117,7 @@ fn run_build(
117117
&cancel,
118118
)?;
119119
step_idx += 1;
120-
match read::read(target_path.as_ref(), &config.diff_obj_config) {
120+
match read::read(target_path.as_ref(), &config.diff_obj_config, DiffSide::Target) {
121121
Ok(obj) => Some(obj),
122122
Err(e) => {
123123
first_status = BuildStatus {
@@ -141,7 +141,7 @@ fn run_build(
141141
Some(base_path) if second_status.success => {
142142
update_status(context, format!("Loading base {base_path}"), step_idx, total, &cancel)?;
143143
step_idx += 1;
144-
match read::read(base_path.as_ref(), &config.diff_obj_config) {
144+
match read::read(base_path.as_ref(), &config.diff_obj_config, DiffSide::Base) {
145145
Ok(obj) => Some(obj),
146146
Err(e) => {
147147
second_status = BuildStatus {

objdiff-core/src/obj/read.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use object::{Object as _, ObjectSection as _, ObjectSymbol as _};
1212

1313
use crate::{
1414
arch::{Arch, RelocationOverride, RelocationOverrideTarget, new_arch},
15-
diff::DiffObjConfig,
15+
diff::{DiffObjConfig, DiffSide},
1616
obj::{
1717
FlowAnalysisResult, Object, Relocation, RelocationFlags, Section, SectionData, SectionFlag,
1818
SectionKind, Symbol, SymbolFlag, SymbolKind,
@@ -925,21 +925,25 @@ fn do_combine_sections(
925925
}
926926

927927
#[cfg(feature = "std")]
928-
pub fn read(obj_path: &std::path::Path, config: &DiffObjConfig) -> Result<Object> {
928+
pub fn read(
929+
obj_path: &std::path::Path,
930+
config: &DiffObjConfig,
931+
diff_side: DiffSide,
932+
) -> Result<Object> {
929933
let (data, timestamp) = {
930934
let file = std::fs::File::open(obj_path)?;
931935
let timestamp = filetime::FileTime::from_last_modification_time(&file.metadata()?);
932936
(unsafe { memmap2::Mmap::map(&file) }?, timestamp)
933937
};
934-
let mut obj = parse(&data, config)?;
938+
let mut obj = parse(&data, config, diff_side)?;
935939
obj.path = Some(obj_path.to_path_buf());
936940
obj.timestamp = Some(timestamp);
937941
Ok(obj)
938942
}
939943

940-
pub fn parse(data: &[u8], config: &DiffObjConfig) -> Result<Object> {
944+
pub fn parse(data: &[u8], config: &DiffObjConfig, diff_side: DiffSide) -> Result<Object> {
941945
let obj_file = object::File::parse(data)?;
942-
let mut arch = new_arch(&obj_file)?;
946+
let mut arch = new_arch(&obj_file, diff_side)?;
943947
let split_meta = parse_split_meta(&obj_file)?;
944948
let (mut sections, section_indices) =
945949
map_sections(arch.as_ref(), &obj_file, split_meta.as_ref())?;

objdiff-core/tests/arch_arm.rs

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,12 @@ mod common;
66
#[cfg(feature = "arm")]
77
fn read_arm() {
88
let diff_config = diff::DiffObjConfig { ..Default::default() };
9-
let obj = obj::read::parse(include_object!("data/arm/LinkStateItem.o"), &diff_config).unwrap();
9+
let obj = obj::read::parse(
10+
include_object!("data/arm/LinkStateItem.o"),
11+
&diff_config,
12+
diff::DiffSide::Base,
13+
)
14+
.unwrap();
1015
insta::assert_debug_snapshot!(obj);
1116
let symbol_idx =
1217
obj.symbols.iter().position(|s| s.name == "_ZN13LinkStateItem12OnStateLeaveEi").unwrap();
@@ -20,7 +25,9 @@ fn read_arm() {
2025
#[cfg(feature = "arm")]
2126
fn read_thumb() {
2227
let diff_config = diff::DiffObjConfig { ..Default::default() };
23-
let obj = obj::read::parse(include_object!("data/arm/thumb.o"), &diff_config).unwrap();
28+
let obj =
29+
obj::read::parse(include_object!("data/arm/thumb.o"), &diff_config, diff::DiffSide::Base)
30+
.unwrap();
2431
insta::assert_debug_snapshot!(obj);
2532
let symbol_idx = obj
2633
.symbols
@@ -37,7 +44,12 @@ fn read_thumb() {
3744
#[cfg(feature = "arm")]
3845
fn combine_text_sections() {
3946
let diff_config = diff::DiffObjConfig { combine_text_sections: true, ..Default::default() };
40-
let obj = obj::read::parse(include_object!("data/arm/enemy300.o"), &diff_config).unwrap();
47+
let obj = obj::read::parse(
48+
include_object!("data/arm/enemy300.o"),
49+
&diff_config,
50+
diff::DiffSide::Base,
51+
)
52+
.unwrap();
4153
let symbol_idx = obj.symbols.iter().position(|s| s.name == "Enemy300Draw").unwrap();
4254
let diff = diff::code::no_diff_code(&obj, symbol_idx, &diff_config).unwrap();
4355
insta::assert_debug_snapshot!(diff.instruction_rows);

objdiff-core/tests/arch_mips.rs

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ mod common;
66
#[cfg(feature = "mips")]
77
fn read_mips() {
88
let diff_config = diff::DiffObjConfig { mips_register_prefix: true, ..Default::default() };
9-
let obj = obj::read::parse(include_object!("data/mips/main.c.o"), &diff_config).unwrap();
9+
let obj =
10+
obj::read::parse(include_object!("data/mips/main.c.o"), &diff_config, diff::DiffSide::Base)
11+
.unwrap();
1012
insta::assert_debug_snapshot!(obj);
1113
let symbol_idx = obj.symbols.iter().position(|s| s.name == "ControlEntry").unwrap();
1214
let diff = diff::code::no_diff_code(&obj, symbol_idx, &diff_config).unwrap();
@@ -19,9 +21,19 @@ fn read_mips() {
1921
#[cfg(feature = "mips")]
2022
fn cross_endian_diff() {
2123
let diff_config = diff::DiffObjConfig::default();
22-
let obj_be = obj::read::parse(include_object!("data/mips/code_be.o"), &diff_config).unwrap();
24+
let obj_be = obj::read::parse(
25+
include_object!("data/mips/code_be.o"),
26+
&diff_config,
27+
diff::DiffSide::Base,
28+
)
29+
.unwrap();
2330
assert_eq!(obj_be.endianness, object::Endianness::Big);
24-
let obj_le = obj::read::parse(include_object!("data/mips/code_le.o"), &diff_config).unwrap();
31+
let obj_le = obj::read::parse(
32+
include_object!("data/mips/code_le.o"),
33+
&diff_config,
34+
diff::DiffSide::Base,
35+
)
36+
.unwrap();
2537
assert_eq!(obj_le.endianness, object::Endianness::Little);
2638
let left_symbol_idx = obj_be.symbols.iter().position(|s| s.name == "func_00000000").unwrap();
2739
let right_symbol_idx =
@@ -42,6 +54,11 @@ fn cross_endian_diff() {
4254
#[cfg(feature = "mips")]
4355
fn filter_non_matching() {
4456
let diff_config = diff::DiffObjConfig::default();
45-
let obj = obj::read::parse(include_object!("data/mips/vw_main.c.o"), &diff_config).unwrap();
57+
let obj = obj::read::parse(
58+
include_object!("data/mips/vw_main.c.o"),
59+
&diff_config,
60+
diff::DiffSide::Base,
61+
)
62+
.unwrap();
4663
insta::assert_debug_snapshot!(obj.symbols);
4764
}

objdiff-core/tests/arch_ppc.rs

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@ mod common;
1010
#[cfg(feature = "ppc")]
1111
fn read_ppc() {
1212
let diff_config = diff::DiffObjConfig::default();
13-
let obj = obj::read::parse(include_object!("data/ppc/IObj.o"), &diff_config).unwrap();
13+
let obj =
14+
obj::read::parse(include_object!("data/ppc/IObj.o"), &diff_config, diff::DiffSide::Base)
15+
.unwrap();
1416
insta::assert_debug_snapshot!(obj);
1517
let symbol_idx =
1618
obj.symbols.iter().position(|s| s.name == "Type2Text__10SObjectTagFUi").unwrap();
@@ -24,7 +26,12 @@ fn read_ppc() {
2426
#[cfg(feature = "ppc")]
2527
fn read_dwarf1_line_info() {
2628
let diff_config = diff::DiffObjConfig::default();
27-
let obj = obj::read::parse(include_object!("data/ppc/m_Do_hostIO.o"), &diff_config).unwrap();
29+
let obj = obj::read::parse(
30+
include_object!("data/ppc/m_Do_hostIO.o"),
31+
&diff_config,
32+
diff::DiffSide::Base,
33+
)
34+
.unwrap();
2835
let line_infos = obj
2936
.sections
3037
.iter()
@@ -38,7 +45,12 @@ fn read_dwarf1_line_info() {
3845
#[cfg(feature = "ppc")]
3946
fn read_extab() {
4047
let diff_config = diff::DiffObjConfig::default();
41-
let obj = obj::read::parse(include_object!("data/ppc/NMWException.o"), &diff_config).unwrap();
48+
let obj = obj::read::parse(
49+
include_object!("data/ppc/NMWException.o"),
50+
&diff_config,
51+
diff::DiffSide::Base,
52+
)
53+
.unwrap();
4254
insta::assert_debug_snapshot!(obj);
4355
}
4456

@@ -47,12 +59,18 @@ fn read_extab() {
4759
fn diff_ppc() {
4860
let diff_config = diff::DiffObjConfig::default();
4961
let mapping_config = diff::MappingConfig::default();
50-
let target_obj =
51-
obj::read::parse(include_object!("data/ppc/CDamageVulnerability_target.o"), &diff_config)
52-
.unwrap();
53-
let base_obj =
54-
obj::read::parse(include_object!("data/ppc/CDamageVulnerability_base.o"), &diff_config)
55-
.unwrap();
62+
let target_obj = obj::read::parse(
63+
include_object!("data/ppc/CDamageVulnerability_target.o"),
64+
&diff_config,
65+
diff::DiffSide::Target,
66+
)
67+
.unwrap();
68+
let base_obj = obj::read::parse(
69+
include_object!("data/ppc/CDamageVulnerability_base.o"),
70+
&diff_config,
71+
diff::DiffSide::Base,
72+
)
73+
.unwrap();
5674
let diff =
5775
diff::diff_objs(Some(&target_obj), Some(&base_obj), None, &diff_config, &mapping_config)
5876
.unwrap();
@@ -90,7 +108,12 @@ fn diff_ppc() {
90108
#[cfg(feature = "ppc")]
91109
fn read_vmx128_coff() {
92110
let diff_config = diff::DiffObjConfig { combine_data_sections: true, ..Default::default() };
93-
let obj = obj::read::parse(include_object!("data/ppc/vmx128.obj"), &diff_config).unwrap();
111+
let obj = obj::read::parse(
112+
include_object!("data/ppc/vmx128.obj"),
113+
&diff_config,
114+
diff::DiffSide::Base,
115+
)
116+
.unwrap();
94117
insta::assert_debug_snapshot!(obj);
95118
let symbol_idx =
96119
obj.symbols.iter().position(|s| s.name == "?FloatingPointExample@@YAXXZ").unwrap();

0 commit comments

Comments
 (0)