From 868c3ab2a17e6d93061803205f75ab53e075b608 Mon Sep 17 00:00:00 2001 From: Anghelo Carvajal Date: Tue, 2 Sep 2025 15:05:00 -0400 Subject: [PATCH 01/10] 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 --- objdiff-cli/src/cmd/report.rs | 10 ++++------ objdiff-core/src/arch/mips.rs | 11 ++++++----- objdiff-core/src/arch/mod.rs | 14 +++++++------- objdiff-core/src/jobs/objdiff.rs | 12 ++++++------ objdiff-core/src/obj/mod.rs | 8 ++++++++ objdiff-core/src/obj/read.rs | 14 ++++++-------- 6 files changed, 37 insertions(+), 32 deletions(-) diff --git a/objdiff-cli/src/cmd/report.rs b/objdiff-cli/src/cmd/report.rs index a07ef216..355dfb80 100644 --- a/objdiff-cli/src/cmd/report.rs +++ b/objdiff-cli/src/cmd/report.rs @@ -4,12 +4,10 @@ use anyhow::{Context, Result, bail}; use argp::FromArgs; use objdiff_core::{ bindings::report::{ - ChangeItem, ChangeItemInfo, ChangeUnit, Changes, ChangesInput, Measures, REPORT_VERSION, - Report, ReportCategory, ReportItem, ReportItemMetadata, ReportUnit, ReportUnitMetadata, + ChangeItem, ChangeItemInfo, ChangeUnit, Changes, ChangesInput, Measures, Report, ReportCategory, ReportItem, ReportItemMetadata, ReportUnit, ReportUnitMetadata, REPORT_VERSION }, config::path::platform_path, - diff, obj, - obj::{SectionKind, SymbolFlag}, + diff, obj::{self, DiffSide, SectionKind, SymbolFlag}, }; use prost::Message; use rayon::iter::{IntoParallelRefIterator, ParallelIterator}; @@ -177,14 +175,14 @@ fn report_object( .target_path .as_ref() .map(|p| { - obj::read::read(p.as_ref(), diff_config).with_context(|| format!("Failed to open {p}")) + obj::read::read(p.as_ref(), diff_config, DiffSide::Target).with_context(|| format!("Failed to open {p}")) }) .transpose()?; let base = object .base_path .as_ref() .map(|p| { - obj::read::read(p.as_ref(), diff_config).with_context(|| format!("Failed to open {p}")) + obj::read::read(p.as_ref(), diff_config, DiffSide::Base).with_context(|| format!("Failed to open {p}")) }) .transpose()?; let result = diff --git a/objdiff-core/src/arch/mips.rs b/objdiff-core/src/arch/mips.rs index b9dc191e..28a8985e 100644 --- a/objdiff-core/src/arch/mips.rs +++ b/objdiff-core/src/arch/mips.rs @@ -12,10 +12,9 @@ use rabbitizer::{ use crate::{ arch::{Arch, RelocationOverride, RelocationOverrideTarget}, - diff::{DiffObjConfig, MipsAbi, MipsInstrCategory, display::InstructionPart}, + diff::{display::InstructionPart, DiffObjConfig, MipsAbi, MipsInstrCategory}, obj::{ - InstructionArg, InstructionArgValue, InstructionRef, Relocation, RelocationFlags, - ResolvedInstructionRef, ResolvedRelocation, Section, Symbol, SymbolFlag, SymbolFlagSet, + DiffSide, InstructionArg, InstructionArgValue, InstructionRef, Relocation, RelocationFlags, ResolvedInstructionRef, ResolvedRelocation, Section, Symbol, SymbolFlag, SymbolFlagSet }, }; @@ -27,6 +26,7 @@ pub struct ArchMips { pub ri_gp_value: i32, pub paired_relocations: Vec>, pub ignored_symbols: BTreeSet, + pub diff_side: DiffSide, } const EF_MIPS_ABI: u32 = 0x0000F000; @@ -38,7 +38,7 @@ const EF_MIPS_MACH_5900: u32 = 0x00920000; const R_MIPS15_S3: u32 = 119; impl ArchMips { - pub fn new(object: &object::File) -> Result { + pub fn new(object: &object::File, diff_side: DiffSide) -> Result { let mut abi = Abi::O32; let mut isa_extension = None; match object.flags() { @@ -124,7 +124,7 @@ impl ArchMips { let Ok(name) = obj_symbol.name() else { continue }; if let Some(prefix) = name.strip_suffix(".NON_MATCHING") { ignored_symbols.insert(obj_symbol.index().0); - if let Some(target_symbol) = object.symbol_by_name(prefix) { + if diff_side == DiffSide::Base && let Some(target_symbol) = object.symbol_by_name(prefix) { ignored_symbols.insert(target_symbol.index().0); } } @@ -137,6 +137,7 @@ impl ArchMips { ri_gp_value, paired_relocations, ignored_symbols, + diff_side, }) } diff --git a/objdiff-core/src/arch/mod.rs b/objdiff-core/src/arch/mod.rs index 514b398a..60300e53 100644 --- a/objdiff-core/src/arch/mod.rs +++ b/objdiff-core/src/arch/mod.rs @@ -17,13 +17,10 @@ use object::Endian as _; use crate::{ diff::{ - DiffObjConfig, - display::{ContextItem, HoverItem, InstructionPart}, + display::{ContextItem, HoverItem, InstructionPart}, DiffObjConfig }, obj::{ - FlowAnalysisResult, InstructionArg, InstructionRef, Object, ParsedInstruction, Relocation, - RelocationFlags, ResolvedInstructionRef, ResolvedSymbol, Section, Symbol, SymbolFlagSet, - SymbolKind, + DiffSide, FlowAnalysisResult, InstructionArg, InstructionRef, Object, ParsedInstruction, Relocation, RelocationFlags, ResolvedInstructionRef, ResolvedSymbol, Section, Symbol, SymbolFlagSet, SymbolKind }, util::ReallySigned, }; @@ -418,15 +415,18 @@ pub trait Arch: Any + Debug + Send + Sync { } } -pub fn new_arch(object: &object::File) -> Result> { +pub fn new_arch(object: &object::File, diff_side: DiffSide) -> Result> { use object::Object as _; + // Avoid unused warnings on non-mips builds + let _ = diff_side; + Ok(match object.architecture() { #[cfg(feature = "ppc")] object::Architecture::PowerPc | object::Architecture::PowerPc64 => { Box::new(ppc::ArchPpc::new(object)?) } #[cfg(feature = "mips")] - object::Architecture::Mips => Box::new(mips::ArchMips::new(object)?), + object::Architecture::Mips => Box::new(mips::ArchMips::new(object, diff_side)?), #[cfg(feature = "x86")] object::Architecture::I386 | object::Architecture::X86_64 => { Box::new(x86::ArchX86::new(object)?) diff --git a/objdiff-core/src/jobs/objdiff.rs b/objdiff-core/src/jobs/objdiff.rs index b91965f9..d82dec7a 100644 --- a/objdiff-core/src/jobs/objdiff.rs +++ b/objdiff-core/src/jobs/objdiff.rs @@ -5,10 +5,10 @@ use time::OffsetDateTime; use typed_path::Utf8PlatformPathBuf; use crate::{ - build::{BuildConfig, BuildStatus, run_make}, - diff::{DiffObjConfig, MappingConfig, ObjectDiff, diff_objs}, - jobs::{Job, JobContext, JobResult, JobState, start_job, update_status}, - obj::{Object, read}, + build::{run_make, BuildConfig, BuildStatus}, + diff::{diff_objs, DiffObjConfig, MappingConfig, ObjectDiff}, + jobs::{start_job, update_status, Job, JobContext, JobResult, JobState}, + obj::{read, DiffSide, Object}, }; pub struct ObjDiffConfig { @@ -117,7 +117,7 @@ fn run_build( &cancel, )?; step_idx += 1; - match read::read(target_path.as_ref(), &config.diff_obj_config) { + match read::read(target_path.as_ref(), &config.diff_obj_config, DiffSide::Target) { Ok(obj) => Some(obj), Err(e) => { first_status = BuildStatus { @@ -141,7 +141,7 @@ fn run_build( Some(base_path) if second_status.success => { update_status(context, format!("Loading base {base_path}"), step_idx, total, &cancel)?; step_idx += 1; - match read::read(base_path.as_ref(), &config.diff_obj_config) { + match read::read(base_path.as_ref(), &config.diff_obj_config, DiffSide::Base) { Ok(obj) => Some(obj), Err(e) => { second_status = BuildStatus { diff --git a/objdiff-core/src/obj/mod.rs b/objdiff-core/src/obj/mod.rs index 96a6df4a..d7a6ab2f 100644 --- a/objdiff-core/src/obj/mod.rs +++ b/objdiff-core/src/obj/mod.rs @@ -437,3 +437,11 @@ impl Default for ResolvedInstructionRef<'_> { } } } + +#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub enum DiffSide { + /// The target/expected side of the diff. + Target, + /// The base side of the diff. + Base, +} diff --git a/objdiff-core/src/obj/read.rs b/objdiff-core/src/obj/read.rs index 71ed0525..bba90b2f 100644 --- a/objdiff-core/src/obj/read.rs +++ b/objdiff-core/src/obj/read.rs @@ -11,12 +11,10 @@ use anyhow::{Context, Result, anyhow, bail, ensure}; use object::{Object as _, ObjectSection as _, ObjectSymbol as _}; use crate::{ - arch::{Arch, RelocationOverride, RelocationOverrideTarget, new_arch}, + arch::{new_arch, Arch, RelocationOverride, RelocationOverrideTarget}, diff::DiffObjConfig, obj::{ - FlowAnalysisResult, Object, Relocation, RelocationFlags, Section, SectionData, SectionFlag, - SectionKind, Symbol, SymbolFlag, SymbolKind, - split_meta::{SPLITMETA_SECTION, SplitMeta}, + split_meta::{SplitMeta, SPLITMETA_SECTION}, DiffSide, FlowAnalysisResult, Object, Relocation, RelocationFlags, Section, SectionData, SectionFlag, SectionKind, Symbol, SymbolFlag, SymbolKind }, util::{align_data_slice_to, align_u64_to, read_u16, read_u32}, }; @@ -925,21 +923,21 @@ fn do_combine_sections( } #[cfg(feature = "std")] -pub fn read(obj_path: &std::path::Path, config: &DiffObjConfig) -> Result { +pub fn read(obj_path: &std::path::Path, config: &DiffObjConfig, diff_side: DiffSide) -> Result { let (data, timestamp) = { let file = std::fs::File::open(obj_path)?; let timestamp = filetime::FileTime::from_last_modification_time(&file.metadata()?); (unsafe { memmap2::Mmap::map(&file) }?, timestamp) }; - let mut obj = parse(&data, config)?; + let mut obj = parse(&data, config, diff_side)?; obj.path = Some(obj_path.to_path_buf()); obj.timestamp = Some(timestamp); Ok(obj) } -pub fn parse(data: &[u8], config: &DiffObjConfig) -> Result { +pub fn parse(data: &[u8], config: &DiffObjConfig, diff_side: DiffSide) -> Result { let obj_file = object::File::parse(data)?; - let mut arch = new_arch(&obj_file)?; + let mut arch = new_arch(&obj_file, diff_side)?; let split_meta = parse_split_meta(&obj_file)?; let (mut sections, section_indices) = map_sections(arch.as_ref(), &obj_file, split_meta.as_ref())?; From e7e1ec0c40ef5afe7c80ba87033f72c8b892bc46 Mon Sep 17 00:00:00 2001 From: Anghelo Carvajal Date: Tue, 2 Sep 2025 15:10:41 -0400 Subject: [PATCH 02/10] fmt --- objdiff-cli/src/cmd/report.rs | 12 ++++++++---- objdiff-core/src/arch/mips.rs | 9 ++++++--- objdiff-core/src/arch/mod.rs | 7 +++++-- objdiff-core/src/jobs/objdiff.rs | 8 ++++---- objdiff-core/src/obj/read.rs | 12 +++++++++--- 5 files changed, 32 insertions(+), 16 deletions(-) diff --git a/objdiff-cli/src/cmd/report.rs b/objdiff-cli/src/cmd/report.rs index 355dfb80..79913439 100644 --- a/objdiff-cli/src/cmd/report.rs +++ b/objdiff-cli/src/cmd/report.rs @@ -4,10 +4,12 @@ use anyhow::{Context, Result, bail}; use argp::FromArgs; use objdiff_core::{ bindings::report::{ - ChangeItem, ChangeItemInfo, ChangeUnit, Changes, ChangesInput, Measures, Report, ReportCategory, ReportItem, ReportItemMetadata, ReportUnit, ReportUnitMetadata, REPORT_VERSION + ChangeItem, ChangeItemInfo, ChangeUnit, Changes, ChangesInput, Measures, REPORT_VERSION, + Report, ReportCategory, ReportItem, ReportItemMetadata, ReportUnit, ReportUnitMetadata, }, config::path::platform_path, - diff, obj::{self, DiffSide, SectionKind, SymbolFlag}, + diff, + obj::{self, DiffSide, SectionKind, SymbolFlag}, }; use prost::Message; use rayon::iter::{IntoParallelRefIterator, ParallelIterator}; @@ -175,14 +177,16 @@ fn report_object( .target_path .as_ref() .map(|p| { - obj::read::read(p.as_ref(), diff_config, DiffSide::Target).with_context(|| format!("Failed to open {p}")) + obj::read::read(p.as_ref(), diff_config, DiffSide::Target) + .with_context(|| format!("Failed to open {p}")) }) .transpose()?; let base = object .base_path .as_ref() .map(|p| { - obj::read::read(p.as_ref(), diff_config, DiffSide::Base).with_context(|| format!("Failed to open {p}")) + obj::read::read(p.as_ref(), diff_config, DiffSide::Base) + .with_context(|| format!("Failed to open {p}")) }) .transpose()?; let result = diff --git a/objdiff-core/src/arch/mips.rs b/objdiff-core/src/arch/mips.rs index 28a8985e..938aec15 100644 --- a/objdiff-core/src/arch/mips.rs +++ b/objdiff-core/src/arch/mips.rs @@ -12,9 +12,10 @@ use rabbitizer::{ use crate::{ arch::{Arch, RelocationOverride, RelocationOverrideTarget}, - diff::{display::InstructionPart, DiffObjConfig, MipsAbi, MipsInstrCategory}, + diff::{DiffObjConfig, MipsAbi, MipsInstrCategory, display::InstructionPart}, obj::{ - DiffSide, InstructionArg, InstructionArgValue, InstructionRef, Relocation, RelocationFlags, ResolvedInstructionRef, ResolvedRelocation, Section, Symbol, SymbolFlag, SymbolFlagSet + DiffSide, InstructionArg, InstructionArgValue, InstructionRef, Relocation, RelocationFlags, + ResolvedInstructionRef, ResolvedRelocation, Section, Symbol, SymbolFlag, SymbolFlagSet, }, }; @@ -124,7 +125,9 @@ impl ArchMips { let Ok(name) = obj_symbol.name() else { continue }; if let Some(prefix) = name.strip_suffix(".NON_MATCHING") { ignored_symbols.insert(obj_symbol.index().0); - if diff_side == DiffSide::Base && let Some(target_symbol) = object.symbol_by_name(prefix) { + if diff_side == DiffSide::Base + && let Some(target_symbol) = object.symbol_by_name(prefix) + { ignored_symbols.insert(target_symbol.index().0); } } diff --git a/objdiff-core/src/arch/mod.rs b/objdiff-core/src/arch/mod.rs index 60300e53..42104db8 100644 --- a/objdiff-core/src/arch/mod.rs +++ b/objdiff-core/src/arch/mod.rs @@ -17,10 +17,13 @@ use object::Endian as _; use crate::{ diff::{ - display::{ContextItem, HoverItem, InstructionPart}, DiffObjConfig + DiffObjConfig, + display::{ContextItem, HoverItem, InstructionPart}, }, obj::{ - DiffSide, FlowAnalysisResult, InstructionArg, InstructionRef, Object, ParsedInstruction, Relocation, RelocationFlags, ResolvedInstructionRef, ResolvedSymbol, Section, Symbol, SymbolFlagSet, SymbolKind + DiffSide, FlowAnalysisResult, InstructionArg, InstructionRef, Object, ParsedInstruction, + Relocation, RelocationFlags, ResolvedInstructionRef, ResolvedSymbol, Section, Symbol, + SymbolFlagSet, SymbolKind, }, util::ReallySigned, }; diff --git a/objdiff-core/src/jobs/objdiff.rs b/objdiff-core/src/jobs/objdiff.rs index d82dec7a..f245873d 100644 --- a/objdiff-core/src/jobs/objdiff.rs +++ b/objdiff-core/src/jobs/objdiff.rs @@ -5,10 +5,10 @@ use time::OffsetDateTime; use typed_path::Utf8PlatformPathBuf; use crate::{ - build::{run_make, BuildConfig, BuildStatus}, - diff::{diff_objs, DiffObjConfig, MappingConfig, ObjectDiff}, - jobs::{start_job, update_status, Job, JobContext, JobResult, JobState}, - obj::{read, DiffSide, Object}, + build::{BuildConfig, BuildStatus, run_make}, + diff::{DiffObjConfig, MappingConfig, ObjectDiff, diff_objs}, + jobs::{Job, JobContext, JobResult, JobState, start_job, update_status}, + obj::{DiffSide, Object, read}, }; pub struct ObjDiffConfig { diff --git a/objdiff-core/src/obj/read.rs b/objdiff-core/src/obj/read.rs index bba90b2f..cd2a0d7d 100644 --- a/objdiff-core/src/obj/read.rs +++ b/objdiff-core/src/obj/read.rs @@ -11,10 +11,12 @@ use anyhow::{Context, Result, anyhow, bail, ensure}; use object::{Object as _, ObjectSection as _, ObjectSymbol as _}; use crate::{ - arch::{new_arch, Arch, RelocationOverride, RelocationOverrideTarget}, + arch::{Arch, RelocationOverride, RelocationOverrideTarget, new_arch}, diff::DiffObjConfig, obj::{ - split_meta::{SplitMeta, SPLITMETA_SECTION}, DiffSide, FlowAnalysisResult, Object, Relocation, RelocationFlags, Section, SectionData, SectionFlag, SectionKind, Symbol, SymbolFlag, SymbolKind + DiffSide, FlowAnalysisResult, Object, Relocation, RelocationFlags, Section, SectionData, + SectionFlag, SectionKind, Symbol, SymbolFlag, SymbolKind, + split_meta::{SPLITMETA_SECTION, SplitMeta}, }, util::{align_data_slice_to, align_u64_to, read_u16, read_u32}, }; @@ -923,7 +925,11 @@ fn do_combine_sections( } #[cfg(feature = "std")] -pub fn read(obj_path: &std::path::Path, config: &DiffObjConfig, diff_side: DiffSide) -> Result { +pub fn read( + obj_path: &std::path::Path, + config: &DiffObjConfig, + diff_side: DiffSide, +) -> Result { let (data, timestamp) = { let file = std::fs::File::open(obj_path)?; let timestamp = filetime::FileTime::from_last_modification_time(&file.metadata()?); From b3c092ff53eb9940f997eee5c06d09c3628a9fc1 Mon Sep 17 00:00:00 2001 From: Anghelo Carvajal Date: Tue, 2 Sep 2025 15:23:56 -0400 Subject: [PATCH 03/10] comment --- objdiff-core/src/arch/mips.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/objdiff-core/src/arch/mips.rs b/objdiff-core/src/arch/mips.rs index 938aec15..12bc4fe5 100644 --- a/objdiff-core/src/arch/mips.rs +++ b/objdiff-core/src/arch/mips.rs @@ -125,6 +125,8 @@ impl ArchMips { let Ok(name) = obj_symbol.name() else { continue }; if let Some(prefix) = name.strip_suffix(".NON_MATCHING") { 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) { From c99fdc2759847708b78acf58f78fbae0da19cab9 Mon Sep 17 00:00:00 2001 From: Anghelo Carvajal Date: Tue, 2 Sep 2025 15:41:36 -0400 Subject: [PATCH 04/10] tests --- objdiff-core/tests/arch_arm.rs | 6 +++--- objdiff-core/tests/arch_mips.rs | 8 ++++---- objdiff-core/tests/arch_ppc.rs | 12 ++++++------ objdiff-core/tests/arch_x86.rs | 12 ++++++------ .../tests/snapshots/arch_mips__read_mips.snap | 2 ++ 5 files changed, 21 insertions(+), 19 deletions(-) diff --git a/objdiff-core/tests/arch_arm.rs b/objdiff-core/tests/arch_arm.rs index bfdd30c8..c187aae8 100644 --- a/objdiff-core/tests/arch_arm.rs +++ b/objdiff-core/tests/arch_arm.rs @@ -6,7 +6,7 @@ mod common; #[cfg(feature = "arm")] fn read_arm() { let diff_config = diff::DiffObjConfig { ..Default::default() }; - let obj = obj::read::parse(include_object!("data/arm/LinkStateItem.o"), &diff_config).unwrap(); + let obj = obj::read::parse(include_object!("data/arm/LinkStateItem.o"), &diff_config, obj::DiffSide::Base).unwrap(); insta::assert_debug_snapshot!(obj); let symbol_idx = obj.symbols.iter().position(|s| s.name == "_ZN13LinkStateItem12OnStateLeaveEi").unwrap(); @@ -20,7 +20,7 @@ fn read_arm() { #[cfg(feature = "arm")] fn read_thumb() { let diff_config = diff::DiffObjConfig { ..Default::default() }; - let obj = obj::read::parse(include_object!("data/arm/thumb.o"), &diff_config).unwrap(); + let obj = obj::read::parse(include_object!("data/arm/thumb.o"), &diff_config, obj::DiffSide::Base).unwrap(); insta::assert_debug_snapshot!(obj); let symbol_idx = obj .symbols @@ -37,7 +37,7 @@ fn read_thumb() { #[cfg(feature = "arm")] fn combine_text_sections() { let diff_config = diff::DiffObjConfig { combine_text_sections: true, ..Default::default() }; - let obj = obj::read::parse(include_object!("data/arm/enemy300.o"), &diff_config).unwrap(); + let obj = obj::read::parse(include_object!("data/arm/enemy300.o"), &diff_config, obj::DiffSide::Base).unwrap(); let symbol_idx = obj.symbols.iter().position(|s| s.name == "Enemy300Draw").unwrap(); let diff = diff::code::no_diff_code(&obj, symbol_idx, &diff_config).unwrap(); insta::assert_debug_snapshot!(diff.instruction_rows); diff --git a/objdiff-core/tests/arch_mips.rs b/objdiff-core/tests/arch_mips.rs index 220cc15f..6a6b828f 100644 --- a/objdiff-core/tests/arch_mips.rs +++ b/objdiff-core/tests/arch_mips.rs @@ -6,7 +6,7 @@ mod common; #[cfg(feature = "mips")] fn read_mips() { let diff_config = diff::DiffObjConfig { mips_register_prefix: true, ..Default::default() }; - let obj = obj::read::parse(include_object!("data/mips/main.c.o"), &diff_config).unwrap(); + let obj = obj::read::parse(include_object!("data/mips/main.c.o"), &diff_config, obj::DiffSide::Base).unwrap(); insta::assert_debug_snapshot!(obj); let symbol_idx = obj.symbols.iter().position(|s| s.name == "ControlEntry").unwrap(); let diff = diff::code::no_diff_code(&obj, symbol_idx, &diff_config).unwrap(); @@ -19,9 +19,9 @@ fn read_mips() { #[cfg(feature = "mips")] fn cross_endian_diff() { let diff_config = diff::DiffObjConfig::default(); - let obj_be = obj::read::parse(include_object!("data/mips/code_be.o"), &diff_config).unwrap(); + let obj_be = obj::read::parse(include_object!("data/mips/code_be.o"), &diff_config, obj::DiffSide::Base).unwrap(); assert_eq!(obj_be.endianness, object::Endianness::Big); - let obj_le = obj::read::parse(include_object!("data/mips/code_le.o"), &diff_config).unwrap(); + let obj_le = obj::read::parse(include_object!("data/mips/code_le.o"), &diff_config, obj::DiffSide::Base).unwrap(); assert_eq!(obj_le.endianness, object::Endianness::Little); let left_symbol_idx = obj_be.symbols.iter().position(|s| s.name == "func_00000000").unwrap(); let right_symbol_idx = @@ -42,6 +42,6 @@ fn cross_endian_diff() { #[cfg(feature = "mips")] fn filter_non_matching() { let diff_config = diff::DiffObjConfig::default(); - let obj = obj::read::parse(include_object!("data/mips/vw_main.c.o"), &diff_config).unwrap(); + let obj = obj::read::parse(include_object!("data/mips/vw_main.c.o"), &diff_config, obj::DiffSide::Base).unwrap(); insta::assert_debug_snapshot!(obj.symbols); } diff --git a/objdiff-core/tests/arch_ppc.rs b/objdiff-core/tests/arch_ppc.rs index 7e5ad803..c295f7a0 100644 --- a/objdiff-core/tests/arch_ppc.rs +++ b/objdiff-core/tests/arch_ppc.rs @@ -10,7 +10,7 @@ mod common; #[cfg(feature = "ppc")] fn read_ppc() { let diff_config = diff::DiffObjConfig::default(); - let obj = obj::read::parse(include_object!("data/ppc/IObj.o"), &diff_config).unwrap(); + let obj = obj::read::parse(include_object!("data/ppc/IObj.o"), &diff_config, obj::DiffSide::Base).unwrap(); insta::assert_debug_snapshot!(obj); let symbol_idx = obj.symbols.iter().position(|s| s.name == "Type2Text__10SObjectTagFUi").unwrap(); @@ -24,7 +24,7 @@ fn read_ppc() { #[cfg(feature = "ppc")] fn read_dwarf1_line_info() { let diff_config = diff::DiffObjConfig::default(); - let obj = obj::read::parse(include_object!("data/ppc/m_Do_hostIO.o"), &diff_config).unwrap(); + let obj = obj::read::parse(include_object!("data/ppc/m_Do_hostIO.o"), &diff_config, obj::DiffSide::Base).unwrap(); let line_infos = obj .sections .iter() @@ -38,7 +38,7 @@ fn read_dwarf1_line_info() { #[cfg(feature = "ppc")] fn read_extab() { let diff_config = diff::DiffObjConfig::default(); - let obj = obj::read::parse(include_object!("data/ppc/NMWException.o"), &diff_config).unwrap(); + let obj = obj::read::parse(include_object!("data/ppc/NMWException.o"), &diff_config, obj::DiffSide::Base).unwrap(); insta::assert_debug_snapshot!(obj); } @@ -48,10 +48,10 @@ fn diff_ppc() { let diff_config = diff::DiffObjConfig::default(); let mapping_config = diff::MappingConfig::default(); let target_obj = - obj::read::parse(include_object!("data/ppc/CDamageVulnerability_target.o"), &diff_config) + obj::read::parse(include_object!("data/ppc/CDamageVulnerability_target.o"), &diff_config, obj::DiffSide::Target) .unwrap(); let base_obj = - obj::read::parse(include_object!("data/ppc/CDamageVulnerability_base.o"), &diff_config) + obj::read::parse(include_object!("data/ppc/CDamageVulnerability_base.o"), &diff_config, obj::DiffSide::Base) .unwrap(); let diff = diff::diff_objs(Some(&target_obj), Some(&base_obj), None, &diff_config, &mapping_config) @@ -90,7 +90,7 @@ fn diff_ppc() { #[cfg(feature = "ppc")] fn read_vmx128_coff() { let diff_config = diff::DiffObjConfig { combine_data_sections: true, ..Default::default() }; - let obj = obj::read::parse(include_object!("data/ppc/vmx128.obj"), &diff_config).unwrap(); + let obj = obj::read::parse(include_object!("data/ppc/vmx128.obj"), &diff_config, obj::DiffSide::Base).unwrap(); insta::assert_debug_snapshot!(obj); let symbol_idx = obj.symbols.iter().position(|s| s.name == "?FloatingPointExample@@YAXXZ").unwrap(); diff --git a/objdiff-core/tests/arch_x86.rs b/objdiff-core/tests/arch_x86.rs index f13c0323..351875e7 100644 --- a/objdiff-core/tests/arch_x86.rs +++ b/objdiff-core/tests/arch_x86.rs @@ -6,7 +6,7 @@ mod common; #[cfg(feature = "x86")] fn read_x86() { let diff_config = diff::DiffObjConfig::default(); - let obj = obj::read::parse(include_object!("data/x86/staticdebug.obj"), &diff_config).unwrap(); + let obj = obj::read::parse(include_object!("data/x86/staticdebug.obj"), &diff_config, obj::DiffSide::Base).unwrap(); insta::assert_debug_snapshot!(obj); let symbol_idx = obj.symbols.iter().position(|s| s.name == "?PrintThing@@YAXXZ").unwrap(); let diff = diff::code::no_diff_code(&obj, symbol_idx, &diff_config).unwrap(); @@ -23,7 +23,7 @@ fn read_x86_combine_sections() { combine_text_sections: true, ..Default::default() }; - let obj = obj::read::parse(include_object!("data/x86/rtest.obj"), &diff_config).unwrap(); + let obj = obj::read::parse(include_object!("data/x86/rtest.obj"), &diff_config, obj::DiffSide::Base).unwrap(); insta::assert_debug_snapshot!(obj.sections); } @@ -31,7 +31,7 @@ fn read_x86_combine_sections() { #[cfg(feature = "x86")] fn read_x86_64() { let diff_config = diff::DiffObjConfig::default(); - let obj = obj::read::parse(include_object!("data/x86_64/vs2022.o"), &diff_config).unwrap(); + let obj = obj::read::parse(include_object!("data/x86_64/vs2022.o"), &diff_config, obj::DiffSide::Base).unwrap(); insta::assert_debug_snapshot!(obj); let symbol_idx = obj.symbols.iter().position(|s| s.name == "?Dot@Vector@@QEAAMPEAU1@@Z").unwrap(); @@ -45,7 +45,7 @@ fn read_x86_64() { #[cfg(feature = "x86")] fn display_section_ordering() { let diff_config = diff::DiffObjConfig::default(); - let obj = obj::read::parse(include_object!("data/x86/basenode.obj"), &diff_config).unwrap(); + let obj = obj::read::parse(include_object!("data/x86/basenode.obj"), &diff_config, obj::DiffSide::Base).unwrap(); let obj_diff = diff::diff_objs(Some(&obj), None, None, &diff_config, &diff::MappingConfig::default()) .unwrap() @@ -60,7 +60,7 @@ fn display_section_ordering() { #[cfg(feature = "x86")] fn read_x86_jumptable() { let diff_config = diff::DiffObjConfig::default(); - let obj = obj::read::parse(include_object!("data/x86/jumptable.o"), &diff_config).unwrap(); + let obj = obj::read::parse(include_object!("data/x86/jumptable.o"), &diff_config, obj::DiffSide::Base).unwrap(); insta::assert_debug_snapshot!(obj); let symbol_idx = obj.symbols.iter().position(|s| s.name == "?test@@YAHH@Z").unwrap(); let diff = diff::code::no_diff_code(&obj, symbol_idx, &diff_config).unwrap(); @@ -74,6 +74,6 @@ fn read_x86_jumptable() { #[cfg(feature = "x86")] fn read_x86_local_labels() { let diff_config = diff::DiffObjConfig::default(); - let obj = obj::read::parse(include_object!("data/x86/local_labels.obj"), &diff_config).unwrap(); + let obj = obj::read::parse(include_object!("data/x86/local_labels.obj"), &diff_config, obj::DiffSide::Base).unwrap(); insta::assert_debug_snapshot!(obj); } diff --git a/objdiff-core/tests/snapshots/arch_mips__read_mips.snap b/objdiff-core/tests/snapshots/arch_mips__read_mips.snap index b67679a7..4eeebfa9 100644 --- a/objdiff-core/tests/snapshots/arch_mips__read_mips.snap +++ b/objdiff-core/tests/snapshots/arch_mips__read_mips.snap @@ -1,5 +1,6 @@ --- source: objdiff-core/tests/arch_mips.rs +assertion_line: 10 expression: obj --- Object { @@ -51,6 +52,7 @@ Object { {}, ], ignored_symbols: {}, + diff_side: Base, }, endianness: Little, symbols: [ From d711775b73da6e10bef46b478a46ac4907d96085 Mon Sep 17 00:00:00 2001 From: Anghelo Carvajal Date: Tue, 2 Sep 2025 15:43:48 -0400 Subject: [PATCH 05/10] fmt tests --- objdiff-core/tests/arch_arm.rs | 15 ++++++++++--- objdiff-core/tests/arch_mips.rs | 19 ++++++++++++---- objdiff-core/tests/arch_ppc.rs | 40 ++++++++++++++++++++++++--------- objdiff-core/tests/arch_x86.rs | 39 +++++++++++++++++++++++++++----- 4 files changed, 90 insertions(+), 23 deletions(-) diff --git a/objdiff-core/tests/arch_arm.rs b/objdiff-core/tests/arch_arm.rs index c187aae8..5e51f1b6 100644 --- a/objdiff-core/tests/arch_arm.rs +++ b/objdiff-core/tests/arch_arm.rs @@ -6,7 +6,12 @@ mod common; #[cfg(feature = "arm")] fn read_arm() { let diff_config = diff::DiffObjConfig { ..Default::default() }; - let obj = obj::read::parse(include_object!("data/arm/LinkStateItem.o"), &diff_config, obj::DiffSide::Base).unwrap(); + let obj = obj::read::parse( + include_object!("data/arm/LinkStateItem.o"), + &diff_config, + obj::DiffSide::Base, + ) + .unwrap(); insta::assert_debug_snapshot!(obj); let symbol_idx = obj.symbols.iter().position(|s| s.name == "_ZN13LinkStateItem12OnStateLeaveEi").unwrap(); @@ -20,7 +25,9 @@ fn read_arm() { #[cfg(feature = "arm")] fn read_thumb() { let diff_config = diff::DiffObjConfig { ..Default::default() }; - let obj = obj::read::parse(include_object!("data/arm/thumb.o"), &diff_config, obj::DiffSide::Base).unwrap(); + let obj = + obj::read::parse(include_object!("data/arm/thumb.o"), &diff_config, obj::DiffSide::Base) + .unwrap(); insta::assert_debug_snapshot!(obj); let symbol_idx = obj .symbols @@ -37,7 +44,9 @@ fn read_thumb() { #[cfg(feature = "arm")] fn combine_text_sections() { let diff_config = diff::DiffObjConfig { combine_text_sections: true, ..Default::default() }; - let obj = obj::read::parse(include_object!("data/arm/enemy300.o"), &diff_config, obj::DiffSide::Base).unwrap(); + let obj = + obj::read::parse(include_object!("data/arm/enemy300.o"), &diff_config, obj::DiffSide::Base) + .unwrap(); let symbol_idx = obj.symbols.iter().position(|s| s.name == "Enemy300Draw").unwrap(); let diff = diff::code::no_diff_code(&obj, symbol_idx, &diff_config).unwrap(); insta::assert_debug_snapshot!(diff.instruction_rows); diff --git a/objdiff-core/tests/arch_mips.rs b/objdiff-core/tests/arch_mips.rs index 6a6b828f..86f61909 100644 --- a/objdiff-core/tests/arch_mips.rs +++ b/objdiff-core/tests/arch_mips.rs @@ -6,7 +6,9 @@ mod common; #[cfg(feature = "mips")] fn read_mips() { let diff_config = diff::DiffObjConfig { mips_register_prefix: true, ..Default::default() }; - let obj = obj::read::parse(include_object!("data/mips/main.c.o"), &diff_config, obj::DiffSide::Base).unwrap(); + let obj = + obj::read::parse(include_object!("data/mips/main.c.o"), &diff_config, obj::DiffSide::Base) + .unwrap(); insta::assert_debug_snapshot!(obj); let symbol_idx = obj.symbols.iter().position(|s| s.name == "ControlEntry").unwrap(); let diff = diff::code::no_diff_code(&obj, symbol_idx, &diff_config).unwrap(); @@ -19,9 +21,13 @@ fn read_mips() { #[cfg(feature = "mips")] fn cross_endian_diff() { let diff_config = diff::DiffObjConfig::default(); - let obj_be = obj::read::parse(include_object!("data/mips/code_be.o"), &diff_config, obj::DiffSide::Base).unwrap(); + let obj_be = + obj::read::parse(include_object!("data/mips/code_be.o"), &diff_config, obj::DiffSide::Base) + .unwrap(); assert_eq!(obj_be.endianness, object::Endianness::Big); - let obj_le = obj::read::parse(include_object!("data/mips/code_le.o"), &diff_config, obj::DiffSide::Base).unwrap(); + let obj_le = + obj::read::parse(include_object!("data/mips/code_le.o"), &diff_config, obj::DiffSide::Base) + .unwrap(); assert_eq!(obj_le.endianness, object::Endianness::Little); let left_symbol_idx = obj_be.symbols.iter().position(|s| s.name == "func_00000000").unwrap(); let right_symbol_idx = @@ -42,6 +48,11 @@ fn cross_endian_diff() { #[cfg(feature = "mips")] fn filter_non_matching() { let diff_config = diff::DiffObjConfig::default(); - let obj = obj::read::parse(include_object!("data/mips/vw_main.c.o"), &diff_config, obj::DiffSide::Base).unwrap(); + let obj = obj::read::parse( + include_object!("data/mips/vw_main.c.o"), + &diff_config, + obj::DiffSide::Base, + ) + .unwrap(); insta::assert_debug_snapshot!(obj.symbols); } diff --git a/objdiff-core/tests/arch_ppc.rs b/objdiff-core/tests/arch_ppc.rs index c295f7a0..6d6b0860 100644 --- a/objdiff-core/tests/arch_ppc.rs +++ b/objdiff-core/tests/arch_ppc.rs @@ -10,7 +10,9 @@ mod common; #[cfg(feature = "ppc")] fn read_ppc() { let diff_config = diff::DiffObjConfig::default(); - let obj = obj::read::parse(include_object!("data/ppc/IObj.o"), &diff_config, obj::DiffSide::Base).unwrap(); + let obj = + obj::read::parse(include_object!("data/ppc/IObj.o"), &diff_config, obj::DiffSide::Base) + .unwrap(); insta::assert_debug_snapshot!(obj); let symbol_idx = obj.symbols.iter().position(|s| s.name == "Type2Text__10SObjectTagFUi").unwrap(); @@ -24,7 +26,12 @@ fn read_ppc() { #[cfg(feature = "ppc")] fn read_dwarf1_line_info() { let diff_config = diff::DiffObjConfig::default(); - let obj = obj::read::parse(include_object!("data/ppc/m_Do_hostIO.o"), &diff_config, obj::DiffSide::Base).unwrap(); + let obj = obj::read::parse( + include_object!("data/ppc/m_Do_hostIO.o"), + &diff_config, + obj::DiffSide::Base, + ) + .unwrap(); let line_infos = obj .sections .iter() @@ -38,7 +45,12 @@ fn read_dwarf1_line_info() { #[cfg(feature = "ppc")] fn read_extab() { let diff_config = diff::DiffObjConfig::default(); - let obj = obj::read::parse(include_object!("data/ppc/NMWException.o"), &diff_config, obj::DiffSide::Base).unwrap(); + let obj = obj::read::parse( + include_object!("data/ppc/NMWException.o"), + &diff_config, + obj::DiffSide::Base, + ) + .unwrap(); insta::assert_debug_snapshot!(obj); } @@ -47,12 +59,18 @@ fn read_extab() { fn diff_ppc() { let diff_config = diff::DiffObjConfig::default(); let mapping_config = diff::MappingConfig::default(); - let target_obj = - obj::read::parse(include_object!("data/ppc/CDamageVulnerability_target.o"), &diff_config, obj::DiffSide::Target) - .unwrap(); - let base_obj = - obj::read::parse(include_object!("data/ppc/CDamageVulnerability_base.o"), &diff_config, obj::DiffSide::Base) - .unwrap(); + let target_obj = obj::read::parse( + include_object!("data/ppc/CDamageVulnerability_target.o"), + &diff_config, + obj::DiffSide::Target, + ) + .unwrap(); + let base_obj = obj::read::parse( + include_object!("data/ppc/CDamageVulnerability_base.o"), + &diff_config, + obj::DiffSide::Base, + ) + .unwrap(); let diff = diff::diff_objs(Some(&target_obj), Some(&base_obj), None, &diff_config, &mapping_config) .unwrap(); @@ -90,7 +108,9 @@ fn diff_ppc() { #[cfg(feature = "ppc")] fn read_vmx128_coff() { let diff_config = diff::DiffObjConfig { combine_data_sections: true, ..Default::default() }; - let obj = obj::read::parse(include_object!("data/ppc/vmx128.obj"), &diff_config, obj::DiffSide::Base).unwrap(); + let obj = + obj::read::parse(include_object!("data/ppc/vmx128.obj"), &diff_config, obj::DiffSide::Base) + .unwrap(); insta::assert_debug_snapshot!(obj); let symbol_idx = obj.symbols.iter().position(|s| s.name == "?FloatingPointExample@@YAXXZ").unwrap(); diff --git a/objdiff-core/tests/arch_x86.rs b/objdiff-core/tests/arch_x86.rs index 351875e7..c3174c38 100644 --- a/objdiff-core/tests/arch_x86.rs +++ b/objdiff-core/tests/arch_x86.rs @@ -6,7 +6,12 @@ mod common; #[cfg(feature = "x86")] fn read_x86() { let diff_config = diff::DiffObjConfig::default(); - let obj = obj::read::parse(include_object!("data/x86/staticdebug.obj"), &diff_config, obj::DiffSide::Base).unwrap(); + let obj = obj::read::parse( + include_object!("data/x86/staticdebug.obj"), + &diff_config, + obj::DiffSide::Base, + ) + .unwrap(); insta::assert_debug_snapshot!(obj); let symbol_idx = obj.symbols.iter().position(|s| s.name == "?PrintThing@@YAXXZ").unwrap(); let diff = diff::code::no_diff_code(&obj, symbol_idx, &diff_config).unwrap(); @@ -23,7 +28,9 @@ fn read_x86_combine_sections() { combine_text_sections: true, ..Default::default() }; - let obj = obj::read::parse(include_object!("data/x86/rtest.obj"), &diff_config, obj::DiffSide::Base).unwrap(); + let obj = + obj::read::parse(include_object!("data/x86/rtest.obj"), &diff_config, obj::DiffSide::Base) + .unwrap(); insta::assert_debug_snapshot!(obj.sections); } @@ -31,7 +38,12 @@ fn read_x86_combine_sections() { #[cfg(feature = "x86")] fn read_x86_64() { let diff_config = diff::DiffObjConfig::default(); - let obj = obj::read::parse(include_object!("data/x86_64/vs2022.o"), &diff_config, obj::DiffSide::Base).unwrap(); + let obj = obj::read::parse( + include_object!("data/x86_64/vs2022.o"), + &diff_config, + obj::DiffSide::Base, + ) + .unwrap(); insta::assert_debug_snapshot!(obj); let symbol_idx = obj.symbols.iter().position(|s| s.name == "?Dot@Vector@@QEAAMPEAU1@@Z").unwrap(); @@ -45,7 +57,12 @@ fn read_x86_64() { #[cfg(feature = "x86")] fn display_section_ordering() { let diff_config = diff::DiffObjConfig::default(); - let obj = obj::read::parse(include_object!("data/x86/basenode.obj"), &diff_config, obj::DiffSide::Base).unwrap(); + let obj = obj::read::parse( + include_object!("data/x86/basenode.obj"), + &diff_config, + obj::DiffSide::Base, + ) + .unwrap(); let obj_diff = diff::diff_objs(Some(&obj), None, None, &diff_config, &diff::MappingConfig::default()) .unwrap() @@ -60,7 +77,12 @@ fn display_section_ordering() { #[cfg(feature = "x86")] fn read_x86_jumptable() { let diff_config = diff::DiffObjConfig::default(); - let obj = obj::read::parse(include_object!("data/x86/jumptable.o"), &diff_config, obj::DiffSide::Base).unwrap(); + let obj = obj::read::parse( + include_object!("data/x86/jumptable.o"), + &diff_config, + obj::DiffSide::Base, + ) + .unwrap(); insta::assert_debug_snapshot!(obj); let symbol_idx = obj.symbols.iter().position(|s| s.name == "?test@@YAHH@Z").unwrap(); let diff = diff::code::no_diff_code(&obj, symbol_idx, &diff_config).unwrap(); @@ -74,6 +96,11 @@ fn read_x86_jumptable() { #[cfg(feature = "x86")] fn read_x86_local_labels() { let diff_config = diff::DiffObjConfig::default(); - let obj = obj::read::parse(include_object!("data/x86/local_labels.obj"), &diff_config, obj::DiffSide::Base).unwrap(); + let obj = obj::read::parse( + include_object!("data/x86/local_labels.obj"), + &diff_config, + obj::DiffSide::Base, + ) + .unwrap(); insta::assert_debug_snapshot!(obj); } From 2b9224885063eda02262eb8d4a45e7c5f6077777 Mon Sep 17 00:00:00 2001 From: Anghelo Carvajal Date: Tue, 2 Sep 2025 16:17:59 -0400 Subject: [PATCH 06/10] maybe this could fix wasm? --- objdiff-wasm/src/api.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/objdiff-wasm/src/api.rs b/objdiff-wasm/src/api.rs index 54ad53cb..aae86f74 100644 --- a/objdiff-wasm/src/api.rs +++ b/objdiff-wasm/src/api.rs @@ -9,7 +9,7 @@ use alloc::{ }; use core::cell::RefCell; -use objdiff_core::{diff, obj}; +use objdiff_core::{diff, obj::{self, DiffSide}}; use regex::{Regex, RegexBuilder}; use xxhash_rust::xxh3::xxh3_64; @@ -471,7 +471,7 @@ unsafe impl Sync for ObjectCache {} static OBJECT_CACHE: ObjectCache = ObjectCache::new(); impl GuestObject for ResourceObject { - fn parse(data: Vec, diff_config: DiffConfigBorrow) -> Result { + fn parse(data: Vec, diff_config: DiffConfigBorrow, diff_side: DiffSide) -> Result { let hash = xxh3_64(&data); let mut cached = None; OBJECT_CACHE.borrow_mut().retain(|c| { @@ -487,7 +487,7 @@ impl GuestObject for ResourceObject { return Ok(Object::new(ResourceObject(obj, hash))); } let diff_config = diff_config.get::().0.borrow(); - let obj = Rc::new(obj::read::parse(&data, &diff_config).map_err(|e| e.to_string())?); + let obj = Rc::new(obj::read::parse(&data, &diff_config, diff_side).map_err(|e| e.to_string())?); OBJECT_CACHE.borrow_mut().push(CachedObject(Rc::downgrade(&obj), hash)); Ok(Object::new(ResourceObject(obj, hash))) } From 18836480405c8152934248861b046f76c792c5cc Mon Sep 17 00:00:00 2001 From: Anghelo Carvajal Date: Tue, 2 Sep 2025 16:42:01 -0400 Subject: [PATCH 07/10] Fix wasm? --- objdiff-wasm/src/api.rs | 24 +++++++++++++++++++++--- objdiff-wasm/wit/objdiff.wit | 6 ++++++ 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/objdiff-wasm/src/api.rs b/objdiff-wasm/src/api.rs index aae86f74..69a5d515 100644 --- a/objdiff-wasm/src/api.rs +++ b/objdiff-wasm/src/api.rs @@ -9,7 +9,10 @@ use alloc::{ }; use core::cell::RefCell; -use objdiff_core::{diff, obj::{self, DiffSide}}; +use objdiff_core::{ + diff, + obj, +}; use regex::{Regex, RegexBuilder}; use xxhash_rust::xxh3::xxh3_64; @@ -27,6 +30,7 @@ use exports::objdiff::core::{ DiffConfigBorrow, DiffResult, Guest as GuestDiff, GuestDiffConfig, GuestObject, GuestObjectDiff, MappingConfig, Object, ObjectBorrow, ObjectDiff, ObjectDiffBorrow, SymbolFlags, SymbolInfo, SymbolKind, SymbolRef, + DiffSide, }, display::{ ContextItem, ContextItemCopy, ContextItemNavigate, DiffText, DiffTextColor, DiffTextOpcode, @@ -470,8 +474,21 @@ unsafe impl Sync for ObjectCache {} static OBJECT_CACHE: ObjectCache = ObjectCache::new(); +impl From for objdiff_core::obj::DiffSide { + fn from(value: DiffSide) -> Self { + match value { + DiffSide::Target => Self::Target, + DiffSide::Base => Self::Base, + } + } +} + impl GuestObject for ResourceObject { - fn parse(data: Vec, diff_config: DiffConfigBorrow, diff_side: DiffSide) -> Result { + fn parse( + data: Vec, + diff_config: DiffConfigBorrow, + diff_side: DiffSide, + ) -> Result { let hash = xxh3_64(&data); let mut cached = None; OBJECT_CACHE.borrow_mut().retain(|c| { @@ -487,7 +504,8 @@ impl GuestObject for ResourceObject { return Ok(Object::new(ResourceObject(obj, hash))); } let diff_config = diff_config.get::().0.borrow(); - let obj = Rc::new(obj::read::parse(&data, &diff_config, diff_side).map_err(|e| e.to_string())?); + let obj = + Rc::new(obj::read::parse(&data, &diff_config, diff_side.into()).map_err(|e| e.to_string())?); OBJECT_CACHE.borrow_mut().push(CachedObject(Rc::downgrade(&obj), hash)); Ok(Object::new(ResourceObject(obj, hash))) } diff --git a/objdiff-wasm/wit/objdiff.wit b/objdiff-wasm/wit/objdiff.wit index 31b781e3..3ec4b515 100644 --- a/objdiff-wasm/wit/objdiff.wit +++ b/objdiff-wasm/wit/objdiff.wit @@ -19,6 +19,7 @@ interface diff { parse: static func( data: list, config: borrow, + side: diff-side, ) -> result; hash: func() -> u64; @@ -80,6 +81,11 @@ interface diff { config: borrow, mapping: mapping-config, ) -> result; + + enum diff-side { + target, + base, + } } interface display { From 1ddd46ab7fc8dc8a2c7881af7cbcddb664a2cbed Mon Sep 17 00:00:00 2001 From: Anghelo Carvajal Date: Tue, 2 Sep 2025 16:43:01 -0400 Subject: [PATCH 08/10] fmt --- objdiff-wasm/src/api.rs | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/objdiff-wasm/src/api.rs b/objdiff-wasm/src/api.rs index 69a5d515..75dd2353 100644 --- a/objdiff-wasm/src/api.rs +++ b/objdiff-wasm/src/api.rs @@ -9,10 +9,7 @@ use alloc::{ }; use core::cell::RefCell; -use objdiff_core::{ - diff, - obj, -}; +use objdiff_core::{diff, obj}; use regex::{Regex, RegexBuilder}; use xxhash_rust::xxh3::xxh3_64; @@ -27,10 +24,9 @@ wit_bindgen::generate!({ use exports::objdiff::core::{ diff::{ - DiffConfigBorrow, DiffResult, Guest as GuestDiff, GuestDiffConfig, GuestObject, + DiffConfigBorrow, DiffResult, DiffSide, Guest as GuestDiff, GuestDiffConfig, GuestObject, GuestObjectDiff, MappingConfig, Object, ObjectBorrow, ObjectDiff, ObjectDiffBorrow, SymbolFlags, SymbolInfo, SymbolKind, SymbolRef, - DiffSide, }, display::{ ContextItem, ContextItemCopy, ContextItemNavigate, DiffText, DiffTextColor, DiffTextOpcode, @@ -504,8 +500,9 @@ impl GuestObject for ResourceObject { return Ok(Object::new(ResourceObject(obj, hash))); } let diff_config = diff_config.get::().0.borrow(); - let obj = - Rc::new(obj::read::parse(&data, &diff_config, diff_side.into()).map_err(|e| e.to_string())?); + let obj = Rc::new( + obj::read::parse(&data, &diff_config, diff_side.into()).map_err(|e| e.to_string())?, + ); OBJECT_CACHE.borrow_mut().push(CachedObject(Rc::downgrade(&obj), hash)); Ok(Object::new(ResourceObject(obj, hash))) } From 71bd6ab6c370407b4dff252987507cfdac0d044e Mon Sep 17 00:00:00 2001 From: Anghelo Carvajal Date: Tue, 2 Sep 2025 17:02:53 -0400 Subject: [PATCH 09/10] Move `DiffSide` to `diff` mod --- objdiff-cli/src/cmd/report.rs | 6 +++--- objdiff-core/src/arch/mips.rs | 4 ++-- objdiff-core/src/arch/mod.rs | 8 ++++---- objdiff-core/src/diff/mod.rs | 8 ++++++++ objdiff-core/src/jobs/objdiff.rs | 4 ++-- objdiff-core/src/obj/mod.rs | 8 -------- objdiff-core/src/obj/read.rs | 6 +++--- objdiff-core/tests/arch_arm.rs | 13 ++++++++----- objdiff-core/tests/arch_mips.rs | 22 ++++++++++++++-------- objdiff-core/tests/arch_ppc.rs | 19 +++++++++++-------- objdiff-core/tests/arch_x86.rs | 12 ++++++------ objdiff-wasm/src/api.rs | 2 +- 12 files changed, 62 insertions(+), 50 deletions(-) diff --git a/objdiff-cli/src/cmd/report.rs b/objdiff-cli/src/cmd/report.rs index 79913439..df7822c7 100644 --- a/objdiff-cli/src/cmd/report.rs +++ b/objdiff-cli/src/cmd/report.rs @@ -9,7 +9,7 @@ use objdiff_core::{ }, config::path::platform_path, diff, - obj::{self, DiffSide, SectionKind, SymbolFlag}, + obj::{self, SectionKind, SymbolFlag}, }; use prost::Message; use rayon::iter::{IntoParallelRefIterator, ParallelIterator}; @@ -177,7 +177,7 @@ fn report_object( .target_path .as_ref() .map(|p| { - obj::read::read(p.as_ref(), diff_config, DiffSide::Target) + obj::read::read(p.as_ref(), diff_config, diff::DiffSide::Target) .with_context(|| format!("Failed to open {p}")) }) .transpose()?; @@ -185,7 +185,7 @@ fn report_object( .base_path .as_ref() .map(|p| { - obj::read::read(p.as_ref(), diff_config, DiffSide::Base) + obj::read::read(p.as_ref(), diff_config, diff::DiffSide::Base) .with_context(|| format!("Failed to open {p}")) }) .transpose()?; diff --git a/objdiff-core/src/arch/mips.rs b/objdiff-core/src/arch/mips.rs index 12bc4fe5..51a34b04 100644 --- a/objdiff-core/src/arch/mips.rs +++ b/objdiff-core/src/arch/mips.rs @@ -12,9 +12,9 @@ use rabbitizer::{ use crate::{ arch::{Arch, RelocationOverride, RelocationOverrideTarget}, - diff::{DiffObjConfig, MipsAbi, MipsInstrCategory, display::InstructionPart}, + diff::{DiffObjConfig, DiffSide, MipsAbi, MipsInstrCategory, display::InstructionPart}, obj::{ - DiffSide, InstructionArg, InstructionArgValue, InstructionRef, Relocation, RelocationFlags, + InstructionArg, InstructionArgValue, InstructionRef, Relocation, RelocationFlags, ResolvedInstructionRef, ResolvedRelocation, Section, Symbol, SymbolFlag, SymbolFlagSet, }, }; diff --git a/objdiff-core/src/arch/mod.rs b/objdiff-core/src/arch/mod.rs index 42104db8..5d7286f3 100644 --- a/objdiff-core/src/arch/mod.rs +++ b/objdiff-core/src/arch/mod.rs @@ -17,13 +17,13 @@ use object::Endian as _; use crate::{ diff::{ - DiffObjConfig, + DiffObjConfig, DiffSide, display::{ContextItem, HoverItem, InstructionPart}, }, obj::{ - DiffSide, FlowAnalysisResult, InstructionArg, InstructionRef, Object, ParsedInstruction, - Relocation, RelocationFlags, ResolvedInstructionRef, ResolvedSymbol, Section, Symbol, - SymbolFlagSet, SymbolKind, + FlowAnalysisResult, InstructionArg, InstructionRef, Object, ParsedInstruction, Relocation, + RelocationFlags, ResolvedInstructionRef, ResolvedSymbol, Section, Symbol, SymbolFlagSet, + SymbolKind, }, util::ReallySigned, }; diff --git a/objdiff-core/src/diff/mod.rs b/objdiff-core/src/diff/mod.rs index c7a66885..7f954f2f 100644 --- a/objdiff-core/src/diff/mod.rs +++ b/objdiff-core/src/diff/mod.rs @@ -807,3 +807,11 @@ fn find_section( s.kind == section_kind && s.name == name && !matches.iter().any(|m| m.right == Some(i)) }) } + +#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub enum DiffSide { + /// The target/expected side of the diff. + Target, + /// The base side of the diff. + Base, +} diff --git a/objdiff-core/src/jobs/objdiff.rs b/objdiff-core/src/jobs/objdiff.rs index f245873d..595ba187 100644 --- a/objdiff-core/src/jobs/objdiff.rs +++ b/objdiff-core/src/jobs/objdiff.rs @@ -6,9 +6,9 @@ use typed_path::Utf8PlatformPathBuf; use crate::{ build::{BuildConfig, BuildStatus, run_make}, - diff::{DiffObjConfig, MappingConfig, ObjectDiff, diff_objs}, + diff::{DiffObjConfig, DiffSide, MappingConfig, ObjectDiff, diff_objs}, jobs::{Job, JobContext, JobResult, JobState, start_job, update_status}, - obj::{DiffSide, Object, read}, + obj::{Object, read}, }; pub struct ObjDiffConfig { diff --git a/objdiff-core/src/obj/mod.rs b/objdiff-core/src/obj/mod.rs index d7a6ab2f..96a6df4a 100644 --- a/objdiff-core/src/obj/mod.rs +++ b/objdiff-core/src/obj/mod.rs @@ -437,11 +437,3 @@ impl Default for ResolvedInstructionRef<'_> { } } } - -#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] -pub enum DiffSide { - /// The target/expected side of the diff. - Target, - /// The base side of the diff. - Base, -} diff --git a/objdiff-core/src/obj/read.rs b/objdiff-core/src/obj/read.rs index cd2a0d7d..798cf9f3 100644 --- a/objdiff-core/src/obj/read.rs +++ b/objdiff-core/src/obj/read.rs @@ -12,10 +12,10 @@ use object::{Object as _, ObjectSection as _, ObjectSymbol as _}; use crate::{ arch::{Arch, RelocationOverride, RelocationOverrideTarget, new_arch}, - diff::DiffObjConfig, + diff::{DiffObjConfig, DiffSide}, obj::{ - DiffSide, FlowAnalysisResult, Object, Relocation, RelocationFlags, Section, SectionData, - SectionFlag, SectionKind, Symbol, SymbolFlag, SymbolKind, + FlowAnalysisResult, Object, Relocation, RelocationFlags, Section, SectionData, SectionFlag, + SectionKind, Symbol, SymbolFlag, SymbolKind, split_meta::{SPLITMETA_SECTION, SplitMeta}, }, util::{align_data_slice_to, align_u64_to, read_u16, read_u32}, diff --git a/objdiff-core/tests/arch_arm.rs b/objdiff-core/tests/arch_arm.rs index 5e51f1b6..887a5829 100644 --- a/objdiff-core/tests/arch_arm.rs +++ b/objdiff-core/tests/arch_arm.rs @@ -9,7 +9,7 @@ fn read_arm() { let obj = obj::read::parse( include_object!("data/arm/LinkStateItem.o"), &diff_config, - obj::DiffSide::Base, + diff::DiffSide::Base, ) .unwrap(); insta::assert_debug_snapshot!(obj); @@ -26,7 +26,7 @@ fn read_arm() { fn read_thumb() { let diff_config = diff::DiffObjConfig { ..Default::default() }; let obj = - obj::read::parse(include_object!("data/arm/thumb.o"), &diff_config, obj::DiffSide::Base) + obj::read::parse(include_object!("data/arm/thumb.o"), &diff_config, diff::DiffSide::Base) .unwrap(); insta::assert_debug_snapshot!(obj); let symbol_idx = obj @@ -44,9 +44,12 @@ fn read_thumb() { #[cfg(feature = "arm")] fn combine_text_sections() { let diff_config = diff::DiffObjConfig { combine_text_sections: true, ..Default::default() }; - let obj = - obj::read::parse(include_object!("data/arm/enemy300.o"), &diff_config, obj::DiffSide::Base) - .unwrap(); + let obj = obj::read::parse( + include_object!("data/arm/enemy300.o"), + &diff_config, + diff::DiffSide::Base, + ) + .unwrap(); let symbol_idx = obj.symbols.iter().position(|s| s.name == "Enemy300Draw").unwrap(); let diff = diff::code::no_diff_code(&obj, symbol_idx, &diff_config).unwrap(); insta::assert_debug_snapshot!(diff.instruction_rows); diff --git a/objdiff-core/tests/arch_mips.rs b/objdiff-core/tests/arch_mips.rs index 86f61909..a72f532f 100644 --- a/objdiff-core/tests/arch_mips.rs +++ b/objdiff-core/tests/arch_mips.rs @@ -7,7 +7,7 @@ mod common; fn read_mips() { let diff_config = diff::DiffObjConfig { mips_register_prefix: true, ..Default::default() }; let obj = - obj::read::parse(include_object!("data/mips/main.c.o"), &diff_config, obj::DiffSide::Base) + obj::read::parse(include_object!("data/mips/main.c.o"), &diff_config, diff::DiffSide::Base) .unwrap(); insta::assert_debug_snapshot!(obj); let symbol_idx = obj.symbols.iter().position(|s| s.name == "ControlEntry").unwrap(); @@ -21,13 +21,19 @@ fn read_mips() { #[cfg(feature = "mips")] fn cross_endian_diff() { let diff_config = diff::DiffObjConfig::default(); - let obj_be = - obj::read::parse(include_object!("data/mips/code_be.o"), &diff_config, obj::DiffSide::Base) - .unwrap(); + let obj_be = obj::read::parse( + include_object!("data/mips/code_be.o"), + &diff_config, + diff::DiffSide::Base, + ) + .unwrap(); assert_eq!(obj_be.endianness, object::Endianness::Big); - let obj_le = - obj::read::parse(include_object!("data/mips/code_le.o"), &diff_config, obj::DiffSide::Base) - .unwrap(); + let obj_le = obj::read::parse( + include_object!("data/mips/code_le.o"), + &diff_config, + diff::DiffSide::Base, + ) + .unwrap(); assert_eq!(obj_le.endianness, object::Endianness::Little); let left_symbol_idx = obj_be.symbols.iter().position(|s| s.name == "func_00000000").unwrap(); let right_symbol_idx = @@ -51,7 +57,7 @@ fn filter_non_matching() { let obj = obj::read::parse( include_object!("data/mips/vw_main.c.o"), &diff_config, - obj::DiffSide::Base, + diff::DiffSide::Base, ) .unwrap(); insta::assert_debug_snapshot!(obj.symbols); diff --git a/objdiff-core/tests/arch_ppc.rs b/objdiff-core/tests/arch_ppc.rs index 6d6b0860..78aaaea9 100644 --- a/objdiff-core/tests/arch_ppc.rs +++ b/objdiff-core/tests/arch_ppc.rs @@ -11,7 +11,7 @@ mod common; fn read_ppc() { let diff_config = diff::DiffObjConfig::default(); let obj = - obj::read::parse(include_object!("data/ppc/IObj.o"), &diff_config, obj::DiffSide::Base) + obj::read::parse(include_object!("data/ppc/IObj.o"), &diff_config, diff::DiffSide::Base) .unwrap(); insta::assert_debug_snapshot!(obj); let symbol_idx = @@ -29,7 +29,7 @@ fn read_dwarf1_line_info() { let obj = obj::read::parse( include_object!("data/ppc/m_Do_hostIO.o"), &diff_config, - obj::DiffSide::Base, + diff::DiffSide::Base, ) .unwrap(); let line_infos = obj @@ -48,7 +48,7 @@ fn read_extab() { let obj = obj::read::parse( include_object!("data/ppc/NMWException.o"), &diff_config, - obj::DiffSide::Base, + diff::DiffSide::Base, ) .unwrap(); insta::assert_debug_snapshot!(obj); @@ -62,13 +62,13 @@ fn diff_ppc() { let target_obj = obj::read::parse( include_object!("data/ppc/CDamageVulnerability_target.o"), &diff_config, - obj::DiffSide::Target, + diff::DiffSide::Target, ) .unwrap(); let base_obj = obj::read::parse( include_object!("data/ppc/CDamageVulnerability_base.o"), &diff_config, - obj::DiffSide::Base, + diff::DiffSide::Base, ) .unwrap(); let diff = @@ -108,9 +108,12 @@ fn diff_ppc() { #[cfg(feature = "ppc")] fn read_vmx128_coff() { let diff_config = diff::DiffObjConfig { combine_data_sections: true, ..Default::default() }; - let obj = - obj::read::parse(include_object!("data/ppc/vmx128.obj"), &diff_config, obj::DiffSide::Base) - .unwrap(); + let obj = obj::read::parse( + include_object!("data/ppc/vmx128.obj"), + &diff_config, + diff::DiffSide::Base, + ) + .unwrap(); insta::assert_debug_snapshot!(obj); let symbol_idx = obj.symbols.iter().position(|s| s.name == "?FloatingPointExample@@YAXXZ").unwrap(); diff --git a/objdiff-core/tests/arch_x86.rs b/objdiff-core/tests/arch_x86.rs index c3174c38..cfd776e6 100644 --- a/objdiff-core/tests/arch_x86.rs +++ b/objdiff-core/tests/arch_x86.rs @@ -9,7 +9,7 @@ fn read_x86() { let obj = obj::read::parse( include_object!("data/x86/staticdebug.obj"), &diff_config, - obj::DiffSide::Base, + diff::DiffSide::Base, ) .unwrap(); insta::assert_debug_snapshot!(obj); @@ -29,7 +29,7 @@ fn read_x86_combine_sections() { ..Default::default() }; let obj = - obj::read::parse(include_object!("data/x86/rtest.obj"), &diff_config, obj::DiffSide::Base) + obj::read::parse(include_object!("data/x86/rtest.obj"), &diff_config, diff::DiffSide::Base) .unwrap(); insta::assert_debug_snapshot!(obj.sections); } @@ -41,7 +41,7 @@ fn read_x86_64() { let obj = obj::read::parse( include_object!("data/x86_64/vs2022.o"), &diff_config, - obj::DiffSide::Base, + diff::DiffSide::Base, ) .unwrap(); insta::assert_debug_snapshot!(obj); @@ -60,7 +60,7 @@ fn display_section_ordering() { let obj = obj::read::parse( include_object!("data/x86/basenode.obj"), &diff_config, - obj::DiffSide::Base, + diff::DiffSide::Base, ) .unwrap(); let obj_diff = @@ -80,7 +80,7 @@ fn read_x86_jumptable() { let obj = obj::read::parse( include_object!("data/x86/jumptable.o"), &diff_config, - obj::DiffSide::Base, + diff::DiffSide::Base, ) .unwrap(); insta::assert_debug_snapshot!(obj); @@ -99,7 +99,7 @@ fn read_x86_local_labels() { let obj = obj::read::parse( include_object!("data/x86/local_labels.obj"), &diff_config, - obj::DiffSide::Base, + diff::DiffSide::Base, ) .unwrap(); insta::assert_debug_snapshot!(obj); diff --git a/objdiff-wasm/src/api.rs b/objdiff-wasm/src/api.rs index 75dd2353..a3f515c4 100644 --- a/objdiff-wasm/src/api.rs +++ b/objdiff-wasm/src/api.rs @@ -470,7 +470,7 @@ unsafe impl Sync for ObjectCache {} static OBJECT_CACHE: ObjectCache = ObjectCache::new(); -impl From for objdiff_core::obj::DiffSide { +impl From for objdiff_core::diff::DiffSide { fn from(value: DiffSide) -> Self { match value { DiffSide::Target => Self::Target, From b920d179cbd6a8fccbcff8a23d9923c904cf8358 Mon Sep 17 00:00:00 2001 From: Anghelo Carvajal Date: Tue, 2 Sep 2025 17:03:39 -0400 Subject: [PATCH 10/10] Update the stuff the advisories CI told me to --- Cargo.lock | 50 ++++++++++++++------------------------------------ 1 file changed, 14 insertions(+), 36 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9cfa9448..063a9a83 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1898,8 +1898,8 @@ dependencies = [ "aho-corasick", "bstr", "log", - "regex-automata 0.4.9", - "regex-syntax 0.8.5", + "regex-automata", + "regex-syntax", "serde", ] @@ -2832,11 +2832,11 @@ dependencies = [ [[package]] name = "matchers" -version = "0.1.0" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +checksum = "d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9" dependencies = [ - "regex-automata 0.1.10", + "regex-automata", ] [[package]] @@ -3092,12 +3092,11 @@ checksum = "5e0826a989adedc2a244799e823aece04662b66609d96af8dff7ac6df9a8925d" [[package]] name = "nu-ansi-term" -version = "0.46.0" +version = "0.50.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +checksum = "d4a28e057d01f97e61255210fcff094d74ed0466038633e95017f5beb68e4399" dependencies = [ - "overload", - "winapi", + "windows-sys 0.52.0", ] [[package]] @@ -3684,12 +3683,6 @@ dependencies = [ "pin-project-lite", ] -[[package]] -name = "overload" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" - [[package]] name = "owned_ttf_parser" version = "0.25.1" @@ -4312,17 +4305,8 @@ checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.4.9", - "regex-syntax 0.8.5", -] - -[[package]] -name = "regex-automata" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" -dependencies = [ - "regex-syntax 0.6.29", + "regex-automata", + "regex-syntax", ] [[package]] @@ -4333,15 +4317,9 @@ checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.8.5", + "regex-syntax", ] -[[package]] -name = "regex-syntax" -version = "0.6.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" - [[package]] name = "regex-syntax" version = "0.8.5" @@ -5563,14 +5541,14 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.19" +version = "0.3.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008" +checksum = "2054a14f5307d601f88daf0553e1cbf472acc4f2c51afab632431cdcd72124d5" dependencies = [ "matchers", "nu-ansi-term", "once_cell", - "regex", + "regex-automata", "sharded-slab", "smallvec", "thread_local",