From 8b4decff6d9b00916e5cf8698431132fcc977dab Mon Sep 17 00:00:00 2001 From: LagoLunatic Date: Sat, 26 Apr 2025 12:23:55 -0400 Subject: [PATCH 1/2] ARM: Fix parsing of mapping symbols when "Combine text sections" is enabled --- objdiff-core/src/arch/arm.rs | 42 ++++++++++++++++++++++++------------ objdiff-core/src/arch/mod.rs | 5 ++++- objdiff-core/src/obj/read.rs | 3 ++- 3 files changed, 34 insertions(+), 16 deletions(-) diff --git a/objdiff-core/src/arch/arm.rs b/objdiff-core/src/arch/arm.rs index 92ef5773..a8f18a5f 100644 --- a/objdiff-core/src/arch/arm.rs +++ b/objdiff-core/src/arch/arm.rs @@ -15,7 +15,7 @@ use crate::{ diff::{ArmArchVersion, ArmR9Usage, DiffObjConfig, display::InstructionPart}, obj::{ InstructionRef, Relocation, RelocationFlags, ResolvedInstructionRef, ResolvedRelocation, - ScannedInstruction, SymbolFlag, SymbolFlagSet, SymbolKind, + ScannedInstruction, Section, SectionKind, Symbol, SymbolFlag, SymbolFlagSet, SymbolKind, }, }; @@ -32,7 +32,8 @@ impl ArchArm { let endianness = file.endianness(); match file { object::File::Elf32(_) => { - let disasm_modes = Self::elf_get_mapping_symbols(file); + // The disasm_modes mapping is populated later in the post_init step so that we have access to merged sections. + let disasm_modes = BTreeMap::new(); let detected_version = Self::elf_detect_arm_version(file)?; Ok(Self { disasm_modes, detected_version, endianness }) } @@ -73,18 +74,22 @@ impl ArchArm { Ok(None) } - fn elf_get_mapping_symbols(file: &object::File) -> BTreeMap> { - file.sections() - .filter(|s| s.kind() == object::SectionKind::Text) - .map(|s| { - let index = s.index(); - let mut mapping_symbols: Vec<_> = file - .symbols() - .filter(|s| s.section_index().map(|i| i == index).unwrap_or(false)) - .filter_map(|s| DisasmMode::from_symbol(&s)) + fn get_mapping_symbols( + sections: &[Section], + symbols: &[Symbol], + ) -> BTreeMap> { + sections + .iter() + .enumerate() + .filter(|(_, section)| section.kind == SectionKind::Code) + .map(|(index, _)| { + let mut mapping_symbols: Vec<_> = symbols + .iter() + .filter(|s| s.section.map(|i| i == index).unwrap_or(false)) + .filter_map(DisasmMode::from_symbol) .collect(); mapping_symbols.sort_unstable_by_key(|x| x.address); - (s.index().0 - 1, mapping_symbols) + (index, mapping_symbols) }) .collect() } @@ -178,6 +183,10 @@ impl ArchArm { } impl Arch for ArchArm { + fn post_init(&mut self, sections: &[Section], symbols: &[Symbol]) { + self.disasm_modes = Self::get_mapping_symbols(sections, symbols); + } + fn scan_instructions( &self, address: u64, @@ -441,7 +450,7 @@ impl Arch for ArchArm { fn extra_symbol_flags(&self, symbol: &object::Symbol) -> SymbolFlagSet { let mut flags = SymbolFlagSet::default(); - if DisasmMode::from_symbol(symbol).is_some() { + if DisasmMode::from_object_symbol(symbol).is_some() { flags |= SymbolFlag::Hidden; } flags @@ -455,12 +464,17 @@ struct DisasmMode { } impl DisasmMode { - fn from_symbol<'a>(sym: &object::Symbol<'a, '_, &'a [u8]>) -> Option { + fn from_object_symbol<'a>(sym: &object::Symbol<'a, '_, &'a [u8]>) -> Option { sym.name() .ok() .and_then(unarm::ParseMode::from_mapping_symbol) .map(|mapping| DisasmMode { address: sym.address() as u32, mapping }) } + + fn from_symbol(sym: &Symbol) -> Option { + unarm::ParseMode::from_mapping_symbol(&sym.name) + .map(|mapping| DisasmMode { address: sym.address as u32, mapping }) + } } fn push_args( diff --git a/objdiff-core/src/arch/mod.rs b/objdiff-core/src/arch/mod.rs index 72e05c14..ed8f2db6 100644 --- a/objdiff-core/src/arch/mod.rs +++ b/objdiff-core/src/arch/mod.rs @@ -12,7 +12,7 @@ use crate::{ }, obj::{ InstructionArg, Object, ParsedInstruction, Relocation, RelocationFlags, - ResolvedInstructionRef, ScannedInstruction, Symbol, SymbolFlagSet, SymbolKind, + ResolvedInstructionRef, ScannedInstruction, Section, Symbol, SymbolFlagSet, SymbolKind, }, util::ReallySigned, }; @@ -183,6 +183,9 @@ impl DataType { } pub trait Arch: Send + Sync + Debug { + // Finishes arch-specific initialization that must be done after sections have been combined. + fn post_init(&mut self, _sections: &[Section], _symbols: &[Symbol]) {} + /// Generate a list of instructions references (offset, size, opcode) from the given code. /// /// The opcode IDs are used to generate the initial diff. Implementations should do as little diff --git a/objdiff-core/src/obj/read.rs b/objdiff-core/src/obj/read.rs index dda2e067..21b6984b 100644 --- a/objdiff-core/src/obj/read.rs +++ b/objdiff-core/src/obj/read.rs @@ -843,7 +843,7 @@ pub fn read(obj_path: &std::path::Path, config: &DiffObjConfig) -> Result Result { let obj_file = object::File::parse(data)?; - let arch = new_arch(&obj_file)?; + let mut arch = new_arch(&obj_file)?; let split_meta = parse_split_meta(&obj_file)?; let (mut sections, section_indices) = map_sections(arch.as_ref(), &obj_file, split_meta.as_ref())?; @@ -857,6 +857,7 @@ pub fn parse(data: &[u8], config: &DiffObjConfig) -> Result { if config.combine_data_sections || config.combine_text_sections { combine_sections(&mut sections, &mut symbols, config)?; } + arch.post_init(§ions, &symbols); Ok(Object { arch, endianness: obj_file.endianness(), From 9fa7ce936f75b9ca89f70894860b8f508555aedd Mon Sep 17 00:00:00 2001 From: LagoLunatic Date: Sat, 26 Apr 2025 12:24:03 -0400 Subject: [PATCH 2/2] Add test --- objdiff-core/tests/arch_arm.rs | 16 +++++- objdiff-core/tests/data/arm/enemy300.o | Bin 0 -> 18200 bytes .../arch_arm__combine_text_sections-2.snap | 8 +++ .../arch_arm__combine_text_sections.snap | 46 ++++++++++++++++++ 4 files changed, 68 insertions(+), 2 deletions(-) create mode 100644 objdiff-core/tests/data/arm/enemy300.o create mode 100644 objdiff-core/tests/snapshots/arch_arm__combine_text_sections-2.snap create mode 100644 objdiff-core/tests/snapshots/arch_arm__combine_text_sections.snap diff --git a/objdiff-core/tests/arch_arm.rs b/objdiff-core/tests/arch_arm.rs index b742dec0..bfdd30c8 100644 --- a/objdiff-core/tests/arch_arm.rs +++ b/objdiff-core/tests/arch_arm.rs @@ -5,7 +5,7 @@ mod common; #[test] #[cfg(feature = "arm")] fn read_arm() { - let diff_config = diff::DiffObjConfig { mips_register_prefix: true, ..Default::default() }; + let diff_config = diff::DiffObjConfig { ..Default::default() }; let obj = obj::read::parse(include_object!("data/arm/LinkStateItem.o"), &diff_config).unwrap(); insta::assert_debug_snapshot!(obj); let symbol_idx = @@ -19,7 +19,7 @@ fn read_arm() { #[test] #[cfg(feature = "arm")] fn read_thumb() { - let diff_config = diff::DiffObjConfig { mips_register_prefix: true, ..Default::default() }; + let diff_config = diff::DiffObjConfig { ..Default::default() }; let obj = obj::read::parse(include_object!("data/arm/thumb.o"), &diff_config).unwrap(); insta::assert_debug_snapshot!(obj); let symbol_idx = obj @@ -32,3 +32,15 @@ fn read_thumb() { let output = common::display_diff(&obj, &diff, symbol_idx, &diff_config); insta::assert_snapshot!(output); } + +#[test] +#[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 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); + let output = common::display_diff(&obj, &diff, symbol_idx, &diff_config); + insta::assert_snapshot!(output); +} diff --git a/objdiff-core/tests/data/arm/enemy300.o b/objdiff-core/tests/data/arm/enemy300.o new file mode 100644 index 0000000000000000000000000000000000000000..376a27b58bbd7cdd80c443fe47ff116fb1a0be91 GIT binary patch literal 18200 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 XJu}s|DbKeUI{J(}B;$lm_}uU5td literal 0 HcmV?d00001 diff --git a/objdiff-core/tests/snapshots/arch_arm__combine_text_sections-2.snap b/objdiff-core/tests/snapshots/arch_arm__combine_text_sections-2.snap new file mode 100644 index 00000000..3d6c2ddf --- /dev/null +++ b/objdiff-core/tests/snapshots/arch_arm__combine_text_sections-2.snap @@ -0,0 +1,8 @@ +--- +source: objdiff-core/tests/arch_arm.rs +assertion_line: 45 +expression: output +--- +[(Line(90), Dim, 5), (Address(0), Normal, 5), (Spacing(4), Normal, 0), (Opcode("ldr", 32799), Normal, 10), (Argument(Opaque("r12")), Normal, 0), (Basic(", "), Normal, 0), (Basic("["), Normal, 0), (Argument(Opaque("pc")), Normal, 0), (Basic(", "), Normal, 0), (Basic("#"), Normal, 0), (Argument(Signed(0)), Normal, 0), (Basic("]"), Normal, 0), (Eol, Normal, 0)] +[(Line(90), Dim, 5), (Address(4), Normal, 5), (Spacing(4), Normal, 0), (Opcode("bx", 32779), Normal, 10), (Argument(Opaque("r12")), Normal, 0), (Eol, Normal, 0)] +[(Line(90), Dim, 5), (Address(8), Normal, 5), (Spacing(4), Normal, 0), (Opcode(".word", 65535), Normal, 10), (Symbol(Symbol { name: "esEnemyDraw", demangled_name: None, address: 0, size: 0, kind: Unknown, section: None, flags: FlagSet(Global), align: None, virtual_address: None }), Bright, 0), (Eol, Normal, 0)] diff --git a/objdiff-core/tests/snapshots/arch_arm__combine_text_sections.snap b/objdiff-core/tests/snapshots/arch_arm__combine_text_sections.snap new file mode 100644 index 00000000..3a6bcd4a --- /dev/null +++ b/objdiff-core/tests/snapshots/arch_arm__combine_text_sections.snap @@ -0,0 +1,46 @@ +--- +source: objdiff-core/tests/arch_arm.rs +assertion_line: 43 +expression: diff.instruction_rows +--- +[ + InstructionDiffRow { + ins_ref: Some( + InstructionRef { + address: 76, + size: 4, + opcode: 32799, + }, + ), + kind: None, + branch_from: None, + branch_to: None, + arg_diff: [], + }, + InstructionDiffRow { + ins_ref: Some( + InstructionRef { + address: 80, + size: 4, + opcode: 32779, + }, + ), + kind: None, + branch_from: None, + branch_to: None, + arg_diff: [], + }, + InstructionDiffRow { + ins_ref: Some( + InstructionRef { + address: 84, + size: 4, + opcode: 65535, + }, + ), + kind: None, + branch_from: None, + branch_to: None, + arg_diff: [], + }, +]