From 6ed07bfaf19f230fc8a5e170b88b739bd550ace6 Mon Sep 17 00:00:00 2001 From: Luke Street Date: Mon, 3 Mar 2025 17:14:32 -0700 Subject: [PATCH] MIPS relocation pairing, '$' prefix option & fixes Implements MIPS relocation pairing logic. New option for "Register '$' prefix", off by default. Fixes various regressions introduced by refactoring. Resolves #122 Resolves #156 --- objdiff-core/config-schema.json | 10 +- objdiff-core/src/arch/mips.rs | 100 +- objdiff-core/src/obj/read.rs | 114 +- objdiff-core/tests/arch_mips.rs | 19 + objdiff-core/tests/data/mips/main.c.o | Bin 0 -> 5516 bytes .../snapshots/arch_mips__read_mips-2.snap | 640 ++++++++ .../snapshots/arch_mips__read_mips-3.snap | 50 + .../tests/snapshots/arch_mips__read_mips.snap | 1456 +++++++++++++++++ objdiff-gui/src/app_config.rs | 2 +- objdiff-wasm/package.json | 4 +- 10 files changed, 2333 insertions(+), 62 deletions(-) create mode 100644 objdiff-core/tests/arch_mips.rs create mode 100644 objdiff-core/tests/data/mips/main.c.o create mode 100644 objdiff-core/tests/snapshots/arch_mips__read_mips-2.snap create mode 100644 objdiff-core/tests/snapshots/arch_mips__read_mips-3.snap create mode 100644 objdiff-core/tests/snapshots/arch_mips__read_mips.snap diff --git a/objdiff-core/config-schema.json b/objdiff-core/config-schema.json index 1ac8be5..f46c730 100644 --- a/objdiff-core/config-schema.json +++ b/objdiff-core/config-schema.json @@ -187,6 +187,13 @@ } ] }, + { + "id": "mips.registerPrefix", + "type": "boolean", + "default": false, + "name": "Register '$' prefix", + "description": "Display MIPS register names with a '$' prefix." + }, { "id": "x86.formatter", "type": "choice", @@ -242,7 +249,8 @@ "name": "MIPS", "properties": [ "mips.abi", - "mips.instrCategory" + "mips.instrCategory", + "mips.registerPrefix" ] }, { diff --git a/objdiff-core/src/arch/mips.rs b/objdiff-core/src/arch/mips.rs index 612552e..3c4728e 100644 --- a/objdiff-core/src/arch/mips.rs +++ b/objdiff-core/src/arch/mips.rs @@ -1,4 +1,4 @@ -use alloc::{string::ToString, vec::Vec}; +use alloc::{collections::BTreeMap, string::ToString, vec::Vec}; use core::ops::Range; use anyhow::{bail, Result}; @@ -25,6 +25,7 @@ pub struct ArchMips { pub abi: Abi, pub isa_extension: Option, pub ri_gp_value: i32, + pub paired_relocations: Vec>, } const EF_MIPS_ABI: u32 = 0x0000F000; @@ -64,16 +65,60 @@ impl ArchMips { // Parse the ri_gp_value stored in .reginfo to be able to correctly // calculate R_MIPS_GPREL16 relocations later. The value is stored - // 0x14 bytes into .reginfo (on 32 bit platforms) + // 0x14 bytes into .reginfo (on 32-bit platforms) + let endianness = object.endianness(); let ri_gp_value = object .section_by_name(".reginfo") .and_then(|section| section.data().ok()) .and_then(|data| data.get(0x14..0x18)) .and_then(|s| s.try_into().ok()) - .map(|bytes| object.endianness().read_i32_bytes(bytes)) + .map(|bytes| endianness.read_i32_bytes(bytes)) .unwrap_or(0); - Ok(Self { endianness: object.endianness(), abi, isa_extension, ri_gp_value }) + // Parse all relocations to pair R_MIPS_HI16 and R_MIPS_LO16. Since the instructions only + // have 16-bit immediate fields, the 32-bit addend is split across the two relocations. + // R_MIPS_LO16 relocations without an immediately preceding R_MIPS_HI16 use the last seen + // R_MIPS_HI16 addend. + // See https://refspecs.linuxfoundation.org/elf/mipsabi.pdf pages 4-17 and 4-18 + let mut paired_relocations = Vec::with_capacity(object.sections().count() + 1); + for obj_section in object.sections() { + let data = obj_section.data()?; + let mut last_hi = None; + let mut last_hi_addend = 0; + let mut addends = BTreeMap::new(); + for (addr, reloc) in obj_section.relocations() { + if !reloc.has_implicit_addend() { + continue; + } + match reloc.flags() { + object::RelocationFlags::Elf { r_type: elf::R_MIPS_HI16 } => { + let code = data[addr as usize..addr as usize + 4].try_into()?; + let addend = ((endianness.read_u32_bytes(code) & 0x0000FFFF) << 16) as i32; + last_hi = Some(addr); + last_hi_addend = addend; + } + object::RelocationFlags::Elf { r_type: elf::R_MIPS_LO16 } => { + let code = data[addr as usize..addr as usize + 4].try_into()?; + let addend = (endianness.read_u32_bytes(code) & 0x0000FFFF) as i16 as i32; + let full_addend = (last_hi_addend + addend) as i64; + if let Some(hi_addr) = last_hi.take() { + addends.insert(hi_addr, full_addend); + } + addends.insert(addr, full_addend); + } + _ => { + last_hi = None; + } + } + } + let section_index = obj_section.index().0; + if section_index >= paired_relocations.len() { + paired_relocations.resize_with(section_index + 1, BTreeMap::new); + } + paired_relocations[section_index] = addends; + } + + Ok(Self { endianness, abi, isa_extension, ri_gp_value, paired_relocations }) } fn instruction_flags(&self, diff_config: &DiffObjConfig) -> rabbitizer::InstructionFlags { @@ -127,18 +172,16 @@ impl Arch for ArchMips { diff_config: &DiffObjConfig, ) -> Result> { let instruction_flags = self.instruction_flags(diff_config); - let start_address = address; let mut ops = Vec::::with_capacity(code.len() / 4); - let mut cur_addr = start_address as u32; + let mut cur_addr = address as u32; for chunk in code.chunks_exact(4) { let code = self.endianness.read_u32_bytes(chunk.try_into()?); - let vram = Vram::new(cur_addr); - let instruction = rabbitizer::Instruction::new(code, vram, instruction_flags); + let instruction = + rabbitizer::Instruction::new(code, Vram::new(cur_addr), instruction_flags); let opcode = instruction.opcode() as u16; - let branch_dest = - instruction.get_branch_offset_generic().map(|o| (vram + o).inner() as u64); + let branch_dest = instruction.get_branch_vram_generic().map(|v| v.inner() as u64); ops.push(ScannedInstruction { - ins_ref: InstructionRef { address, size: 4, opcode }, + ins_ref: InstructionRef { address: cur_addr as u64, size: 4, opcode }, branch_dest, }); cur_addr += 4; @@ -164,6 +207,7 @@ impl Arch for ArchMips { function_range, resolved.section_index, &display_flags, + diff_config, cb, )?; Ok(()) @@ -177,6 +221,17 @@ impl Arch for ArchMips { reloc: &object::Relocation, flags: RelocationFlags, ) -> Result { + // Check for paired R_MIPS_HI16 and R_MIPS_LO16 relocations. + if let RelocationFlags::Elf(elf::R_MIPS_HI16 | elf::R_MIPS_LO16) = flags { + if let Some(addend) = self + .paired_relocations + .get(section.index().0) + .and_then(|m| m.get(&address).copied()) + { + return Ok(addend); + } + } + let data = section.data()?; let code = data[address as usize..address as usize + 4].try_into()?; let addend = self.endianness.read_u32_bytes(code); @@ -246,6 +301,7 @@ fn push_args( function_range: Range, section_index: usize, display_flags: &rabbitizer::InstructionDisplayFlags, + diff_config: &DiffObjConfig, mut arg_cb: impl FnMut(InstructionPart) -> Result<()>, ) -> Result<()> { let operands = instruction.valued_operands_iter(); @@ -305,9 +361,14 @@ fn push_args( })))?; } arg_cb(InstructionPart::basic("("))?; - arg_cb(InstructionPart::opaque( - base.either_name(instruction.flags().abi(), display_flags.named_gpr()), - ))?; + let mut value = + base.either_name(instruction.flags().abi(), display_flags.named_gpr()); + if !diff_config.mips_register_prefix { + if let Some(trimmed) = value.strip_prefix('$') { + value = trimmed; + } + } + arg_cb(InstructionPart::opaque(value))?; arg_cb(InstructionPart::basic(")"))?; } // ValuedOperand::r5900_immediate15(..) => match relocation { @@ -321,9 +382,14 @@ fn push_args( // } // }, _ => { - arg_cb(InstructionPart::opaque( - op.display(instruction, display_flags, None::<&str>).to_string(), - ))?; + let value = op.display(instruction, display_flags, None::<&str>).to_string(); + if !diff_config.mips_register_prefix { + if let Some(value) = value.strip_prefix('$') { + arg_cb(InstructionPart::opaque(value))?; + continue; + } + } + arg_cb(InstructionPart::opaque(value))?; } } } diff --git a/objdiff-core/src/obj/read.rs b/objdiff-core/src/obj/read.rs index 9639f5d..b8c064b 100644 --- a/objdiff-core/src/obj/read.rs +++ b/objdiff-core/src/obj/read.rs @@ -263,7 +263,7 @@ const LOW_PRIORITY_SYMBOLS: &[&str] = fn best_symbol<'r, 'data, 'file>( symbols: &'r [object::Symbol<'data, 'file>], address: u64, -) -> Option { +) -> Option<(object::SymbolIndex, u64)> { let mut closest_symbol_index = match symbols.binary_search_by_key(&address, |s| s.address()) { Ok(index) => Some(index), Err(index) => index.checked_sub(1), @@ -297,18 +297,31 @@ fn best_symbol<'r, 'data, 'file>( best_symbol = Some(symbol); } } - best_symbol.map(|s| s.index()) + best_symbol.map(|s| (s.index(), s.address())) } -fn map_relocations( +fn map_section_relocations( arch: &dyn Arch, obj_file: &object::File, obj_section: &object::Section, symbol_indices: &[usize], + ordered_symbols: &[Vec], ) -> Result> { let mut relocations = Vec::::with_capacity(obj_section.relocations().count()); - let mut ordered_symbols = None; for (address, reloc) in obj_section.relocations() { + let flags = match reloc.flags() { + object::RelocationFlags::Elf { r_type } => RelocationFlags::Elf(r_type), + object::RelocationFlags::Coff { typ } => RelocationFlags::Coff(typ), + flags => { + bail!("Unhandled relocation flags: {:?}", flags); + } + }; + // TODO validate reloc here? + let mut addend = if reloc.has_implicit_addend() { + arch.implcit_addend(obj_file, obj_section, address, &reloc, flags)? + } else { + reloc.addend() + }; let target_symbol = match reloc.target() { object::RelocationTarget::Symbol(idx) => { if idx.0 == u32::MAX as usize { @@ -323,24 +336,16 @@ fn map_relocations( { let section_index = section_symbol.section_index().context("Section symbol without section")?; - let ordered_symbols = ordered_symbols.get_or_insert_with(|| { - let mut vec = obj_file - .symbols() - .filter(|s| { - s.section_index() == Some(section_index) - && s.kind() != object::SymbolKind::Section - }) - .collect::>(); - vec.sort_by(|a, b| { - a.address().cmp(&b.address()).then(a.size().cmp(&b.size())) - }); - vec - }); - best_symbol( - ordered_symbols, - section_symbol.address().wrapping_add_signed(reloc.addend()), - ) - .unwrap_or(idx) + let target_address = section_symbol.address().wrapping_add_signed(addend); + if let Some((new_idx, addr)) = ordered_symbols + .get(section_index.0) + .and_then(|symbols| best_symbol(symbols, target_address)) + { + addend = target_address.wrapping_sub(addr) as i64; + new_idx + } else { + idx + } } else { idx }; @@ -359,24 +364,55 @@ fn map_relocations( } _ => bail!("Unhandled relocation target: {:?}", reloc.target()), }; - let flags = match reloc.flags() { - object::RelocationFlags::Elf { r_type } => RelocationFlags::Elf(r_type), - object::RelocationFlags::Coff { typ } => RelocationFlags::Coff(typ), - flags => { - bail!("Unhandled relocation flags: {:?}", flags); - } - }; - // TODO validate reloc here? - let addend = if reloc.has_implicit_addend() { - arch.implcit_addend(obj_file, obj_section, address, &reloc, flags)? - } else { - reloc.addend() - }; relocations.push(Relocation { address, flags, target_symbol, addend }); } + relocations.sort_by_key(|r| r.address); Ok(relocations) } +fn map_relocations( + arch: &dyn Arch, + obj_file: &object::File, + sections: &mut [Section], + section_indices: &[usize], + symbol_indices: &[usize], +) -> Result<()> { + // Generate a list of symbols for each section + let mut ordered_symbols = + Vec::>::with_capacity(obj_file.sections().count() + 1); + for symbol in obj_file.symbols() { + let Some(section_index) = symbol.section_index() else { + continue; + }; + if symbol.kind() == object::SymbolKind::Section { + continue; + } + if section_index.0 >= ordered_symbols.len() { + ordered_symbols.resize_with(section_index.0 + 1, Vec::new); + } + ordered_symbols[section_index.0].push(symbol); + } + // Sort symbols by address and size + for vec in &mut ordered_symbols { + vec.sort_by(|a, b| a.address().cmp(&b.address()).then(a.size().cmp(&b.size()))); + } + // Map relocations for each section. Section-relative relocations use the ordered symbols list + // to find a better target symbol, if available. + for obj_section in obj_file.sections() { + let section = &mut sections[section_indices[obj_section.index().0]]; + if section.kind != SectionKind::Unknown { + section.relocations = map_section_relocations( + arch, + obj_file, + &obj_section, + symbol_indices, + &ordered_symbols, + )?; + } + } + Ok(()) +} + fn parse_line_info( obj_file: &object::File, sections: &mut [Section], @@ -767,13 +803,7 @@ pub fn parse(data: &[u8], config: &DiffObjConfig) -> Result { map_sections(arch.as_ref(), &obj_file, split_meta.as_ref())?; let (mut symbols, symbol_indices) = map_symbols(arch.as_ref(), &obj_file, §ions, §ion_indices, split_meta.as_ref())?; - for obj_section in obj_file.sections() { - let section = &mut sections[section_indices[obj_section.index().0]]; - if section.kind != SectionKind::Unknown { - section.relocations = - map_relocations(arch.as_ref(), &obj_file, &obj_section, &symbol_indices)?; - } - } + map_relocations(arch.as_ref(), &obj_file, &mut sections, §ion_indices, &symbol_indices)?; parse_line_info(&obj_file, &mut sections, §ion_indices, data)?; if config.combine_data_sections || config.combine_text_sections { combine_sections(&mut sections, &mut symbols, config)?; diff --git a/objdiff-core/tests/arch_mips.rs b/objdiff-core/tests/arch_mips.rs new file mode 100644 index 0000000..252d49d --- /dev/null +++ b/objdiff-core/tests/arch_mips.rs @@ -0,0 +1,19 @@ +use objdiff_core::{diff, obj}; + +mod common; + +#[test] +#[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(); + 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(); + 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/mips/main.c.o b/objdiff-core/tests/data/mips/main.c.o new file mode 100644 index 0000000000000000000000000000000000000000..714d2d9adecee84067cca7c49484f201882d398a GIT binary patch literal 5516 zcmeI0L2O({8OJ|+H;F@&un7eP+R!bS)Gc`HM5c17LF;(!*uq;cw$=C$;XLnqc9!h! zTi#ncb}8V1k#cC&6mj5Cq)2cm2&pMlq6bioluA7yKq5#SkWvsJ4jfw2LlBhZ|DQLr zUVjlJ7j7MC_dmby`)1~Q^XARY+pmsIjdyi*i7Q>wBikgh`96`Z{5P|MCZJFD%RWZ8twV>%DEqpPcFW$I z(oMM0k_`1tt}Vay^%pyHW#T9%cjm3{h4FS=+yCY(*L&pE z>xk*e2-k&(TOa)!8(2|XBgtI%U%V`ZtxG1CiLK{e%>9=!`ps;!-KY)f8bZ{sd=pSO)kEd}Yr*L$E>3AXHk4yQ#*(0S;$(E0@^*Zwe_w)8_cEz{RR z5!thG)2NFQ$)b8h?lb-*M&uRPIAp?Ix3u9U>NZ*Av8&xCwejX1jN_iy&tBf1%yD$i zo68&~Q2(H1xmnOeZrz-4CKdC2maD z*~6&mae6g~s@}Rxh0Ec1C5oFeS7}y*Tc;u}2eXwW&d^MwETB=Jz#8l`!D1LTC&Py2 z+4XvPn-~b12t4QK#f)P*jt&j=zx-E(#Bn;t61)E&3W;;4#fO*(8(aI1z00Av1M{k9VK(? zXdG**qiHc*tpv_j4C*V+XI9t3f)Rc#G`z^GEqKv#Sx#U&d9QeHcKTL1{M^|n*l{I^ zVJ2*P%^+Fr$$r85v^8*_xwRxuN&DHjHDKF<=Z)}QXR(~M{PP=$KW~}OIZH7Sx$suv ze*&DxXT-*TUirVM_=4g~iodJ)$BM5i{-xq;VD3fSe^~yUNITyfir-PZ-)=na`tDKO zuXsf9l;Ts0zo7U@#ZN1KUh(%8|3vXs#lKPf2gPqGZYkc6J)6bN$GwUlR6GQB`#jry zTKNm$0_<+R%qjmFF!y}tZz%r-#c|-Do*6qiIXicp!%5kX!rH*6PESsk_?amkA1vf1 zizgpDX55m*io})hc+IOzt;}zM#zC|y((rs^s8$wZANJUMi$t!HbaUJ9l=+3<4ojI| z=uXBVprfR=f6oA7*+G`7A(Pp+9l}C4WuvbBe#G_+`bfDgKq>--4Md&lJq}FUtS6;(seX zVAnRy%=cc!ImIUw7ZuMdKBxFgil0&Z9mPLT{EFh&6kk*PN5y|vEcV%P*MC6q5ycNF zehkcKn`bx9|D(#E2N&RT>!qapr@?%-oxiI5Usn9?VeH+*m^tXW1J|7%#{N&|F#chX z-j96)x(C~D9~lRzEOZz66VTnzK`8x0&@?uh0s432eUE-<9!kG?77ixwhH3npa0d1? z{s%cr#b6EU`$g8EyFMWD6m&OqgLe2YQo)xkzfL_Y@@pzy#C}KpkjO8f9RK%Fj{jHM z?-994MLZs5N#mk=s7J6jQqle}^~1P6>V3ElY8KZG<@F9idA&oHhb`x!jGM4_o{1P& zvUcv9Y=7F?&sh6eYp+^+!`j!Z{V8kTu=b1A&NCDHzhv#-ru}}A=V^ythNeFv@eCc&{03~*-!w_1=MP83NQf~+A& zS9)v(OURs3@|Le=u!a%GcN4bfKF?T8t>NVD1oPj~7hJ|i#gv-(+r?pOnOlQxSlAzz zu`3*x{3t${{&w8!h|GI&7b8J7gu<%g|gM_e!VlFl=mi~A3g CCE3IP literal 0 HcmV?d00001 diff --git a/objdiff-core/tests/snapshots/arch_mips__read_mips-2.snap b/objdiff-core/tests/snapshots/arch_mips__read_mips-2.snap new file mode 100644 index 0000000..40f8098 --- /dev/null +++ b/objdiff-core/tests/snapshots/arch_mips__read_mips-2.snap @@ -0,0 +1,640 @@ +--- +source: objdiff-core/tests/arch_mips.rs +expression: diff.instruction_rows +--- +[ + InstructionDiffRow { + ins_ref: Some( + InstructionRef { + address: 0, + size: 4, + opcode: 12, + }, + ), + kind: None, + branch_from: None, + branch_to: None, + arg_diff: [], + }, + InstructionDiffRow { + ins_ref: Some( + InstructionRef { + address: 4, + size: 4, + opcode: 44, + }, + ), + kind: None, + branch_from: None, + branch_to: None, + arg_diff: [], + }, + InstructionDiffRow { + ins_ref: Some( + InstructionRef { + address: 8, + size: 4, + opcode: 44, + }, + ), + kind: None, + branch_from: None, + branch_to: None, + arg_diff: [], + }, + InstructionDiffRow { + ins_ref: Some( + InstructionRef { + address: 12, + size: 4, + opcode: 44, + }, + ), + kind: None, + branch_from: None, + branch_to: None, + arg_diff: [], + }, + InstructionDiffRow { + ins_ref: Some( + InstructionRef { + address: 16, + size: 4, + opcode: 44, + }, + ), + kind: None, + branch_from: None, + branch_to: None, + arg_diff: [], + }, + InstructionDiffRow { + ins_ref: Some( + InstructionRef { + address: 20, + size: 4, + opcode: 2, + }, + ), + kind: None, + branch_from: None, + branch_to: None, + arg_diff: [], + }, + InstructionDiffRow { + ins_ref: Some( + InstructionRef { + address: 24, + size: 4, + opcode: 113, + }, + ), + kind: None, + branch_from: None, + branch_to: None, + arg_diff: [], + }, + InstructionDiffRow { + ins_ref: Some( + InstructionRef { + address: 28, + size: 4, + opcode: 26, + }, + ), + kind: None, + branch_from: None, + branch_to: None, + arg_diff: [], + }, + InstructionDiffRow { + ins_ref: Some( + InstructionRef { + address: 32, + size: 4, + opcode: 20, + }, + ), + kind: None, + branch_from: None, + branch_to: None, + arg_diff: [], + }, + InstructionDiffRow { + ins_ref: Some( + InstructionRef { + address: 36, + size: 4, + opcode: 97, + }, + ), + kind: None, + branch_from: None, + branch_to: None, + arg_diff: [], + }, + InstructionDiffRow { + ins_ref: Some( + InstructionRef { + address: 40, + size: 4, + opcode: 2, + }, + ), + kind: None, + branch_from: None, + branch_to: None, + arg_diff: [], + }, + InstructionDiffRow { + ins_ref: Some( + InstructionRef { + address: 44, + size: 4, + opcode: 12, + }, + ), + kind: None, + branch_from: None, + branch_to: None, + arg_diff: [], + }, + InstructionDiffRow { + ins_ref: Some( + InstructionRef { + address: 48, + size: 4, + opcode: 20, + }, + ), + kind: None, + branch_from: None, + branch_to: None, + arg_diff: [], + }, + InstructionDiffRow { + ins_ref: Some( + InstructionRef { + address: 52, + size: 4, + opcode: 26, + }, + ), + kind: None, + branch_from: None, + branch_to: None, + arg_diff: [], + }, + InstructionDiffRow { + ins_ref: Some( + InstructionRef { + address: 56, + size: 4, + opcode: 2, + }, + ), + kind: None, + branch_from: None, + branch_to: None, + arg_diff: [], + }, + InstructionDiffRow { + ins_ref: Some( + InstructionRef { + address: 60, + size: 4, + opcode: 12, + }, + ), + kind: None, + branch_from: None, + branch_to: None, + arg_diff: [], + }, + InstructionDiffRow { + ins_ref: Some( + InstructionRef { + address: 64, + size: 4, + opcode: 26, + }, + ), + kind: None, + branch_from: None, + branch_to: None, + arg_diff: [], + }, + InstructionDiffRow { + ins_ref: Some( + InstructionRef { + address: 68, + size: 4, + opcode: 97, + }, + ), + kind: None, + branch_from: None, + branch_to: None, + arg_diff: [], + }, + InstructionDiffRow { + ins_ref: Some( + InstructionRef { + address: 72, + size: 4, + opcode: 2, + }, + ), + kind: None, + branch_from: None, + branch_to: None, + arg_diff: [], + }, + InstructionDiffRow { + ins_ref: Some( + InstructionRef { + address: 76, + size: 4, + opcode: 97, + }, + ), + kind: None, + branch_from: None, + branch_to: None, + arg_diff: [], + }, + InstructionDiffRow { + ins_ref: Some( + InstructionRef { + address: 80, + size: 4, + opcode: 2, + }, + ), + kind: None, + branch_from: Some( + InstructionBranchFrom { + ins_idx: [ + 22, + ], + branch_idx: 0, + }, + ), + branch_to: None, + arg_diff: [], + }, + InstructionDiffRow { + ins_ref: Some( + InstructionRef { + address: 84, + size: 4, + opcode: 97, + }, + ), + kind: None, + branch_from: None, + branch_to: None, + arg_diff: [], + }, + InstructionDiffRow { + ins_ref: Some( + InstructionRef { + address: 88, + size: 4, + opcode: 56, + }, + ), + kind: None, + branch_from: None, + branch_to: Some( + InstructionBranchTo { + ins_idx: 20, + branch_idx: 0, + }, + ), + arg_diff: [], + }, + InstructionDiffRow { + ins_ref: Some( + InstructionRef { + address: 92, + size: 4, + opcode: 113, + }, + ), + kind: None, + branch_from: None, + branch_to: None, + arg_diff: [], + }, + InstructionDiffRow { + ins_ref: Some( + InstructionRef { + address: 96, + size: 4, + opcode: 2, + }, + ), + kind: None, + branch_from: None, + branch_to: None, + arg_diff: [], + }, + InstructionDiffRow { + ins_ref: Some( + InstructionRef { + address: 100, + size: 4, + opcode: 20, + }, + ), + kind: None, + branch_from: None, + branch_to: None, + arg_diff: [], + }, + InstructionDiffRow { + ins_ref: Some( + InstructionRef { + address: 104, + size: 4, + opcode: 2, + }, + ), + kind: None, + branch_from: None, + branch_to: None, + arg_diff: [], + }, + InstructionDiffRow { + ins_ref: Some( + InstructionRef { + address: 108, + size: 4, + opcode: 12, + }, + ), + kind: None, + branch_from: None, + branch_to: None, + arg_diff: [], + }, + InstructionDiffRow { + ins_ref: Some( + InstructionRef { + address: 112, + size: 4, + opcode: 2, + }, + ), + kind: None, + branch_from: None, + branch_to: None, + arg_diff: [], + }, + InstructionDiffRow { + ins_ref: Some( + InstructionRef { + address: 116, + size: 4, + opcode: 16, + }, + ), + kind: None, + branch_from: None, + branch_to: None, + arg_diff: [], + }, + InstructionDiffRow { + ins_ref: Some( + InstructionRef { + address: 120, + size: 4, + opcode: 20, + }, + ), + kind: None, + branch_from: None, + branch_to: None, + arg_diff: [], + }, + InstructionDiffRow { + ins_ref: Some( + InstructionRef { + address: 124, + size: 4, + opcode: 12, + }, + ), + kind: None, + branch_from: None, + branch_to: None, + arg_diff: [], + }, + InstructionDiffRow { + ins_ref: Some( + InstructionRef { + address: 128, + size: 4, + opcode: 2, + }, + ), + kind: None, + branch_from: Some( + InstructionBranchFrom { + ins_idx: [ + 36, + 38, + 44, + ], + branch_idx: 1, + }, + ), + branch_to: None, + arg_diff: [], + }, + InstructionDiffRow { + ins_ref: Some( + InstructionRef { + address: 132, + size: 4, + opcode: 12, + }, + ), + kind: None, + branch_from: None, + branch_to: None, + arg_diff: [], + }, + InstructionDiffRow { + ins_ref: Some( + InstructionRef { + address: 136, + size: 4, + opcode: 2, + }, + ), + kind: None, + branch_from: None, + branch_to: None, + arg_diff: [], + }, + InstructionDiffRow { + ins_ref: Some( + InstructionRef { + address: 140, + size: 4, + opcode: 113, + }, + ), + kind: None, + branch_from: None, + branch_to: None, + arg_diff: [], + }, + InstructionDiffRow { + ins_ref: Some( + InstructionRef { + address: 144, + size: 4, + opcode: 55, + }, + ), + kind: None, + branch_from: None, + branch_to: Some( + InstructionBranchTo { + ins_idx: 32, + branch_idx: 1, + }, + ), + arg_diff: [], + }, + InstructionDiffRow { + ins_ref: Some( + InstructionRef { + address: 148, + size: 4, + opcode: 90, + }, + ), + kind: None, + branch_from: None, + branch_to: None, + arg_diff: [], + }, + InstructionDiffRow { + ins_ref: Some( + InstructionRef { + address: 152, + size: 4, + opcode: 3, + }, + ), + kind: None, + branch_from: None, + branch_to: Some( + InstructionBranchTo { + ins_idx: 32, + branch_idx: 1, + }, + ), + arg_diff: [], + }, + InstructionDiffRow { + ins_ref: Some( + InstructionRef { + address: 156, + size: 4, + opcode: 113, + }, + ), + kind: None, + branch_from: None, + branch_to: None, + arg_diff: [], + }, + InstructionDiffRow { + ins_ref: Some( + InstructionRef { + address: 160, + size: 4, + opcode: 2, + }, + ), + kind: None, + branch_from: None, + branch_to: None, + arg_diff: [], + }, + InstructionDiffRow { + ins_ref: Some( + InstructionRef { + address: 164, + size: 4, + opcode: 60, + }, + ), + kind: None, + branch_from: None, + branch_to: None, + arg_diff: [], + }, + InstructionDiffRow { + ins_ref: Some( + InstructionRef { + address: 168, + size: 4, + opcode: 77, + }, + ), + kind: None, + branch_from: None, + branch_to: None, + arg_diff: [], + }, + InstructionDiffRow { + ins_ref: Some( + InstructionRef { + address: 172, + size: 4, + opcode: 113, + }, + ), + kind: None, + branch_from: None, + branch_to: None, + arg_diff: [], + }, + InstructionDiffRow { + ins_ref: Some( + InstructionRef { + address: 176, + size: 4, + opcode: 54, + }, + ), + kind: None, + branch_from: None, + branch_to: Some( + InstructionBranchTo { + ins_idx: 32, + branch_idx: 1, + }, + ), + arg_diff: [], + }, + InstructionDiffRow { + ins_ref: Some( + InstructionRef { + address: 180, + size: 4, + opcode: 113, + }, + ), + kind: None, + branch_from: None, + branch_to: None, + arg_diff: [], + }, +] diff --git a/objdiff-core/tests/snapshots/arch_mips__read_mips-3.snap b/objdiff-core/tests/snapshots/arch_mips__read_mips-3.snap new file mode 100644 index 0000000..7e9faad --- /dev/null +++ b/objdiff-core/tests/snapshots/arch_mips__read_mips-3.snap @@ -0,0 +1,50 @@ +--- +source: objdiff-core/tests/arch_mips.rs +expression: output +--- +[(Address(0), Normal, 5), (Spacing(4), Normal, 0), (Opcode("addiu", 12), Normal, 10), (Argument(Opaque("$sp")), Normal, 0), (Basic(", "), Normal, 0), (Argument(Opaque("$sp")), Normal, 0), (Basic(", "), Normal, 0), (Argument(Signed(-32)), Normal, 0), (Eol, Normal, 0)] +[(Address(4), Normal, 5), (Spacing(4), Normal, 0), (Opcode("sd", 44), Normal, 10), (Argument(Opaque("$s0")), Normal, 0), (Basic(", "), Normal, 0), (Argument(Signed(0)), Normal, 0), (Basic("("), Normal, 0), (Argument(Opaque("$sp")), Normal, 0), (Basic(")"), Normal, 0), (Eol, Normal, 0)] +[(Address(8), Normal, 5), (Spacing(4), Normal, 0), (Opcode("sd", 44), Normal, 10), (Argument(Opaque("$s1")), Normal, 0), (Basic(", "), Normal, 0), (Argument(Signed(8)), Normal, 0), (Basic("("), Normal, 0), (Argument(Opaque("$sp")), Normal, 0), (Basic(")"), Normal, 0), (Eol, Normal, 0)] +[(Address(12), Normal, 5), (Spacing(4), Normal, 0), (Opcode("sd", 44), Normal, 10), (Argument(Opaque("$s2")), Normal, 0), (Basic(", "), Normal, 0), (Argument(Signed(16)), Normal, 0), (Basic("("), Normal, 0), (Argument(Opaque("$sp")), Normal, 0), (Basic(")"), Normal, 0), (Eol, Normal, 0)] +[(Address(16), Normal, 5), (Spacing(4), Normal, 0), (Opcode("sd", 44), Normal, 10), (Argument(Opaque("$ra")), Normal, 0), (Basic(", "), Normal, 0), (Argument(Signed(24)), Normal, 0), (Basic("("), Normal, 0), (Argument(Opaque("$sp")), Normal, 0), (Basic(")"), Normal, 0), (Eol, Normal, 0)] +[(Address(20), Normal, 5), (Spacing(4), Normal, 0), (Opcode("jal", 2), Normal, 10), (Symbol(Symbol { name: "xglSleep", demangled_name: None, address: 0, size: 0, kind: Unknown, section: None, flags: FlagSet(Global), align: None, virtual_address: None }), Bright, 0), (Eol, Normal, 0)] +[(Address(24), Normal, 5), (Spacing(4), Normal, 0), (Opcode("nop", 113), Normal, 10), (Eol, Normal, 0)] +[(Address(28), Normal, 5), (Spacing(4), Normal, 0), (Opcode("lw", 26), Normal, 10), (Argument(Opaque("$a1")), Normal, 0), (Basic(", "), Normal, 0), (Basic("%gp_rel("), Normal, 0), (Symbol(Symbol { name: "WorkEnd", demangled_name: None, address: 64, size: 4, kind: Object, section: Some(8), flags: FlagSet(Global), align: None, virtual_address: None }), Bright, 0), (Basic(")"), Normal, 0), (Basic("("), Normal, 0), (Argument(Opaque("$gp")), Normal, 0), (Basic(")"), Normal, 0), (Eol, Normal, 0)] +[(Address(32), Normal, 5), (Spacing(4), Normal, 0), (Opcode("lui", 20), Normal, 10), (Argument(Opaque("$a0")), Normal, 0), (Basic(", "), Normal, 0), (Basic("%hi("), Normal, 0), (Symbol(Symbol { name: "[.sdata]", demangled_name: None, address: 0, size: 64, kind: Section, section: Some(8), flags: FlagSet(Local), align: None, virtual_address: None }), Bright, 0), (Basic(")"), Normal, 0), (Eol, Normal, 0)] +[(Address(36), Normal, 5), (Spacing(4), Normal, 0), (Opcode("daddu", 97), Normal, 10), (Argument(Opaque("$a2")), Normal, 0), (Basic(", "), Normal, 0), (Argument(Opaque("$zero")), Normal, 0), (Basic(", "), Normal, 0), (Argument(Opaque("$zero")), Normal, 0), (Eol, Normal, 0)] +[(Address(40), Normal, 5), (Spacing(4), Normal, 0), (Opcode("jal", 2), Normal, 10), (Symbol(Symbol { name: "xglSoundLoadEffect", demangled_name: None, address: 0, size: 0, kind: Unknown, section: None, flags: FlagSet(Global), align: None, virtual_address: None }), Bright, 0), (Eol, Normal, 0)] +[(Address(44), Normal, 5), (Spacing(4), Normal, 0), (Opcode("addiu", 12), Normal, 10), (Argument(Opaque("$a0")), Normal, 0), (Basic(", "), Normal, 0), (Argument(Opaque("$a0")), Normal, 0), (Basic(", "), Normal, 0), (Basic("%lo("), Normal, 0), (Symbol(Symbol { name: "[.sdata]", demangled_name: None, address: 0, size: 64, kind: Section, section: Some(8), flags: FlagSet(Local), align: None, virtual_address: None }), Bright, 0), (Basic(")"), Normal, 0), (Eol, Normal, 0)] +[(Address(48), Normal, 5), (Spacing(4), Normal, 0), (Opcode("lui", 20), Normal, 10), (Argument(Opaque("$a0")), Normal, 0), (Basic(", "), Normal, 0), (Basic("%hi("), Normal, 0), (Symbol(Symbol { name: "PacketBottomNewVu1DropMicroCode", demangled_name: None, address: 0, size: 12, kind: Object, section: Some(7), flags: FlagSet(Global), align: None, virtual_address: None }), Bright, 0), (Basic(")"), Normal, 0), (Eol, Normal, 0)] +[(Address(52), Normal, 5), (Spacing(4), Normal, 0), (Opcode("lw", 26), Normal, 10), (Argument(Opaque("$a1")), Normal, 0), (Basic(", "), Normal, 0), (Basic("%gp_rel("), Normal, 0), (Symbol(Symbol { name: "WorkEnd", demangled_name: None, address: 64, size: 4, kind: Object, section: Some(8), flags: FlagSet(Global), align: None, virtual_address: None }), Bright, 0), (Basic(")"), Normal, 0), (Basic("("), Normal, 0), (Argument(Opaque("$gp")), Normal, 0), (Basic(")"), Normal, 0), (Eol, Normal, 0)] +[(Address(56), Normal, 5), (Spacing(4), Normal, 0), (Opcode("jal", 2), Normal, 10), (Symbol(Symbol { name: "xglSoundLoadSwd", demangled_name: None, address: 0, size: 0, kind: Unknown, section: None, flags: FlagSet(Global), align: None, virtual_address: None }), Bright, 0), (Eol, Normal, 0)] +[(Address(60), Normal, 5), (Spacing(4), Normal, 0), (Opcode("addiu", 12), Normal, 10), (Argument(Opaque("$a0")), Normal, 0), (Basic(", "), Normal, 0), (Argument(Opaque("$a0")), Normal, 0), (Basic(", "), Normal, 0), (Basic("%lo("), Normal, 0), (Symbol(Symbol { name: "PacketBottomNewVu1DropMicroCode", demangled_name: None, address: 0, size: 12, kind: Object, section: Some(7), flags: FlagSet(Global), align: None, virtual_address: None }), Bright, 0), (Basic(")"), Normal, 0), (Eol, Normal, 0)] +[(Address(64), Normal, 5), (Spacing(4), Normal, 0), (Opcode("lw", 26), Normal, 10), (Argument(Opaque("$a0")), Normal, 0), (Basic(", "), Normal, 0), (Basic("%gp_rel("), Normal, 0), (Symbol(Symbol { name: "WorkEnd", demangled_name: None, address: 64, size: 4, kind: Object, section: Some(8), flags: FlagSet(Global), align: None, virtual_address: None }), Bright, 0), (Basic(")"), Normal, 0), (Basic("("), Normal, 0), (Argument(Opaque("$gp")), Normal, 0), (Basic(")"), Normal, 0), (Eol, Normal, 0)] +[(Address(68), Normal, 5), (Spacing(4), Normal, 0), (Opcode("daddu", 97), Normal, 10), (Argument(Opaque("$a1")), Normal, 0), (Basic(", "), Normal, 0), (Argument(Opaque("$zero")), Normal, 0), (Basic(", "), Normal, 0), (Argument(Opaque("$zero")), Normal, 0), (Eol, Normal, 0)] +[(Address(72), Normal, 5), (Spacing(4), Normal, 0), (Opcode("jal", 2), Normal, 10), (Symbol(Symbol { name: "SsdAddWaveData", demangled_name: None, address: 0, size: 0, kind: Unknown, section: None, flags: FlagSet(Global), align: None, virtual_address: None }), Bright, 0), (Eol, Normal, 0)] +[(Address(76), Normal, 5), (Spacing(4), Normal, 0), (Opcode("daddu", 97), Normal, 10), (Argument(Opaque("$a2")), Normal, 0), (Basic(", "), Normal, 0), (Argument(Opaque("$zero")), Normal, 0), (Basic(", "), Normal, 0), (Argument(Opaque("$zero")), Normal, 0), (Eol, Normal, 0)] +[(Address(80), Normal, 5), (Basic(" ~> "), Rotating(0), 0), (Opcode("jal", 2), Normal, 10), (Symbol(Symbol { name: "SsdSpuDmaCompleted", demangled_name: None, address: 0, size: 0, kind: Unknown, section: None, flags: FlagSet(Global), align: None, virtual_address: None }), Bright, 0), (Eol, Normal, 0)] +[(Address(84), Normal, 5), (Spacing(4), Normal, 0), (Opcode("daddu", 97), Normal, 10), (Argument(Opaque("$a0")), Normal, 0), (Basic(", "), Normal, 0), (Argument(Opaque("$zero")), Normal, 0), (Basic(", "), Normal, 0), (Argument(Opaque("$zero")), Normal, 0), (Eol, Normal, 0)] +[(Address(88), Normal, 5), (Spacing(4), Normal, 0), (Opcode("bnez", 56), Normal, 10), (Argument(Opaque("$v0")), Normal, 0), (Basic(", "), Normal, 0), (BranchDest(80), Normal, 0), (Basic(" ~>"), Rotating(0), 0), (Eol, Normal, 0)] +[(Address(92), Normal, 5), (Spacing(4), Normal, 0), (Opcode("nop", 113), Normal, 10), (Eol, Normal, 0)] +[(Address(96), Normal, 5), (Spacing(4), Normal, 0), (Opcode("jal", 2), Normal, 10), (Symbol(Symbol { name: "xglRenderDispOn", demangled_name: None, address: 0, size: 0, kind: Unknown, section: None, flags: FlagSet(Global), align: None, virtual_address: None }), Bright, 0), (Eol, Normal, 0)] +[(Address(100), Normal, 5), (Spacing(4), Normal, 0), (Opcode("lui", 20), Normal, 10), (Argument(Opaque("$s1")), Normal, 0), (Basic(", "), Normal, 0), (Argument(Unsigned(255)), Normal, 0), (Eol, Normal, 0)] +[(Address(104), Normal, 5), (Spacing(4), Normal, 0), (Opcode("jal", 2), Normal, 10), (Symbol(Symbol { name: "xglCdLoadOverlay", demangled_name: None, address: 0, size: 0, kind: Unknown, section: None, flags: FlagSet(Global), align: None, virtual_address: None }), Bright, 0), (Eol, Normal, 0)] +[(Address(108), Normal, 5), (Spacing(4), Normal, 0), (Opcode("addiu", 12), Normal, 10), (Argument(Opaque("$a0")), Normal, 0), (Basic(", "), Normal, 0), (Argument(Opaque("$zero")), Normal, 0), (Basic(", "), Normal, 0), (Argument(Signed(2)), Normal, 0), (Eol, Normal, 0)] +[(Address(112), Normal, 5), (Spacing(4), Normal, 0), (Opcode("jal", 2), Normal, 10), (Symbol(Symbol { name: "LogoFirst", demangled_name: None, address: 0, size: 0, kind: Unknown, section: None, flags: FlagSet(Global), align: None, virtual_address: None }), Bright, 0), (Eol, Normal, 0)] +[(Address(116), Normal, 5), (Spacing(4), Normal, 0), (Opcode("ori", 16), Normal, 10), (Argument(Opaque("$s1")), Normal, 0), (Basic(", "), Normal, 0), (Argument(Opaque("$s1")), Normal, 0), (Basic(", "), Normal, 0), (Argument(Unsigned(65535)), Normal, 0), (Eol, Normal, 0)] +[(Address(120), Normal, 5), (Spacing(4), Normal, 0), (Opcode("lui", 20), Normal, 10), (Argument(Opaque("$v0")), Normal, 0), (Basic(", "), Normal, 0), (Basic("%hi("), Normal, 0), (Symbol(Symbol { name: "Title", demangled_name: None, address: 0, size: 0, kind: Unknown, section: None, flags: FlagSet(Global), align: None, virtual_address: None }), Bright, 0), (Basic(")"), Normal, 0), (Eol, Normal, 0)] +[(Address(124), Normal, 5), (Spacing(4), Normal, 0), (Opcode("addiu", 12), Normal, 10), (Argument(Opaque("$s2")), Normal, 0), (Basic(", "), Normal, 0), (Argument(Opaque("$v0")), Normal, 0), (Basic(", "), Normal, 0), (Basic("%lo("), Normal, 0), (Symbol(Symbol { name: "Title", demangled_name: None, address: 0, size: 0, kind: Unknown, section: None, flags: FlagSet(Global), align: None, virtual_address: None }), Bright, 0), (Basic(")"), Normal, 0), (Eol, Normal, 0)] +[(Address(128), Normal, 5), (Basic(" ~> "), Rotating(1), 0), (Opcode("jal", 2), Normal, 10), (Symbol(Symbol { name: "xglCdLoadOverlay", demangled_name: None, address: 0, size: 0, kind: Unknown, section: None, flags: FlagSet(Global), align: None, virtual_address: None }), Bright, 0), (Eol, Normal, 0)] +[(Address(132), Normal, 5), (Spacing(4), Normal, 0), (Opcode("addiu", 12), Normal, 10), (Argument(Opaque("$a0")), Normal, 0), (Basic(", "), Normal, 0), (Argument(Opaque("$zero")), Normal, 0), (Basic(", "), Normal, 0), (Argument(Signed(2)), Normal, 0), (Eol, Normal, 0)] +[(Address(136), Normal, 5), (Spacing(4), Normal, 0), (Opcode("jal", 2), Normal, 10), (Symbol(Symbol { name: "Title", demangled_name: None, address: 0, size: 0, kind: Unknown, section: None, flags: FlagSet(Global), align: None, virtual_address: None }), Bright, 0), (Eol, Normal, 0)] +[(Address(140), Normal, 5), (Spacing(4), Normal, 0), (Opcode("nop", 113), Normal, 10), (Eol, Normal, 0)] +[(Address(144), Normal, 5), (Spacing(4), Normal, 0), (Opcode("beqz", 55), Normal, 10), (Argument(Opaque("$v0")), Normal, 0), (Basic(", "), Normal, 0), (BranchDest(128), Normal, 0), (Basic(" ~>"), Rotating(1), 0), (Eol, Normal, 0)] +[(Address(148), Normal, 5), (Spacing(4), Normal, 0), (Opcode("and", 90), Normal, 10), (Argument(Opaque("$s0")), Normal, 0), (Basic(", "), Normal, 0), (Argument(Opaque("$v0")), Normal, 0), (Basic(", "), Normal, 0), (Argument(Opaque("$s1")), Normal, 0), (Eol, Normal, 0)] +[(Address(152), Normal, 5), (Spacing(4), Normal, 0), (Opcode("beq", 3), Normal, 10), (Argument(Opaque("$s0")), Normal, 0), (Basic(", "), Normal, 0), (Argument(Opaque("$s2")), Normal, 0), (Basic(", "), Normal, 0), (BranchDest(128), Normal, 0), (Basic(" ~>"), Rotating(1), 0), (Eol, Normal, 0)] +[(Address(156), Normal, 5), (Spacing(4), Normal, 0), (Opcode("nop", 113), Normal, 10), (Eol, Normal, 0)] +[(Address(160), Normal, 5), (Spacing(4), Normal, 0), (Opcode("jal", 2), Normal, 10), (Symbol(Symbol { name: "xglCdLoadOverlay", demangled_name: None, address: 0, size: 0, kind: Unknown, section: None, flags: FlagSet(Global), align: None, virtual_address: None }), Bright, 0), (Eol, Normal, 0)] +[(Address(164), Normal, 5), (Spacing(4), Normal, 0), (Opcode("srl", 60), Normal, 10), (Argument(Opaque("$a0")), Normal, 0), (Basic(", "), Normal, 0), (Argument(Opaque("$v0")), Normal, 0), (Basic(", "), Normal, 0), (Argument(Opaque("24")), Normal, 0), (Eol, Normal, 0)] +[(Address(168), Normal, 5), (Spacing(4), Normal, 0), (Opcode("jalr", 77), Normal, 10), (Argument(Opaque("$s0")), Normal, 0), (Eol, Normal, 0)] +[(Address(172), Normal, 5), (Spacing(4), Normal, 0), (Opcode("nop", 113), Normal, 10), (Eol, Normal, 0)] +[(Address(176), Normal, 5), (Spacing(4), Normal, 0), (Opcode("b", 54), Normal, 10), (BranchDest(128), Normal, 0), (Basic(" ~>"), Rotating(1), 0), (Eol, Normal, 0)] +[(Address(180), Normal, 5), (Spacing(4), Normal, 0), (Opcode("nop", 113), Normal, 10), (Eol, Normal, 0)] diff --git a/objdiff-core/tests/snapshots/arch_mips__read_mips.snap b/objdiff-core/tests/snapshots/arch_mips__read_mips.snap new file mode 100644 index 0000000..c50bac1 --- /dev/null +++ b/objdiff-core/tests/snapshots/arch_mips__read_mips.snap @@ -0,0 +1,1456 @@ +--- +source: objdiff-core/tests/arch_mips.rs +expression: obj +--- +Object { + arch: ArchMips { + endianness: Little, + abi: N32, + isa_extension: Some( + R5900EE, + ), + ri_gp_value: 16384, + paired_relocations: [ + {}, + { + 32: 0, + 44: 0, + 48: 0, + 60: 0, + 120: 0, + 124: 0, + 204: 16, + 220: 16, + 296: 8, + 308: 8, + 312: 16, + 316: 16, + 328: 24, + 332: 24, + 344: 32, + 348: 32, + 360: 40, + 364: 40, + 376: 48, + 380: 48, + 392: 56, + 396: 56, + 408: 0, + 412: 0, + }, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + {}, + ], + }, + endianness: Little, + symbols: [ + Symbol { + name: "[.text]", + demangled_name: None, + address: 0, + size: 0, + kind: Section, + section: Some( + 0, + ), + flags: FlagSet(Local), + align: None, + virtual_address: None, + }, + Symbol { + name: "[.data]", + demangled_name: None, + address: 0, + size: 0, + kind: Section, + section: Some( + 2, + ), + flags: FlagSet(Local), + align: None, + virtual_address: None, + }, + Symbol { + name: "[.bss]", + demangled_name: None, + address: 0, + size: 0, + kind: Section, + section: Some( + 3, + ), + flags: FlagSet(Local), + align: None, + virtual_address: None, + }, + Symbol { + name: "[.mdebug.eabi64]", + demangled_name: None, + address: 0, + size: 0, + kind: Section, + section: Some( + 6, + ), + flags: FlagSet(Local), + align: None, + virtual_address: None, + }, + Symbol { + name: "[.sdata]", + demangled_name: None, + address: 0, + size: 64, + kind: Section, + section: Some( + 8, + ), + flags: FlagSet(Local), + align: None, + virtual_address: None, + }, + Symbol { + name: "[.rodata]", + demangled_name: None, + address: 0, + size: 0, + kind: Section, + section: Some( + 7, + ), + flags: FlagSet(Local), + align: None, + virtual_address: None, + }, + Symbol { + name: "[.reginfo]", + demangled_name: None, + address: 0, + size: 24, + kind: Section, + section: Some( + 4, + ), + flags: FlagSet(Local), + align: None, + virtual_address: None, + }, + Symbol { + name: "[.mdebug]", + demangled_name: None, + address: 0, + size: 1932, + kind: Section, + section: Some( + 5, + ), + flags: FlagSet(Local), + align: None, + virtual_address: None, + }, + Symbol { + name: "gcc2_compiled.", + demangled_name: None, + address: 0, + size: 0, + kind: Unknown, + section: Some( + 0, + ), + flags: FlagSet(Local), + align: None, + virtual_address: None, + }, + Symbol { + name: "__gnu_compiled_c", + demangled_name: None, + address: 0, + size: 0, + kind: Unknown, + section: Some( + 0, + ), + flags: FlagSet(Local), + align: None, + virtual_address: None, + }, + Symbol { + name: "PacketBottomNewVu1DropMicroCode", + demangled_name: None, + address: 0, + size: 12, + kind: Object, + section: Some( + 7, + ), + flags: FlagSet(Global), + align: None, + virtual_address: None, + }, + Symbol { + name: "ControlEntry", + demangled_name: None, + address: 0, + size: 184, + kind: Function, + section: Some( + 0, + ), + flags: FlagSet(Global), + align: None, + virtual_address: None, + }, + Symbol { + name: "xglSleep", + demangled_name: None, + address: 0, + size: 0, + kind: Unknown, + section: None, + flags: FlagSet(Global), + align: None, + virtual_address: None, + }, + Symbol { + name: "WorkEnd", + demangled_name: None, + address: 64, + size: 4, + kind: Object, + section: Some( + 8, + ), + flags: FlagSet(Global), + align: None, + virtual_address: None, + }, + Symbol { + name: "xglSoundLoadEffect", + demangled_name: None, + address: 0, + size: 0, + kind: Unknown, + section: None, + flags: FlagSet(Global), + align: None, + virtual_address: None, + }, + Symbol { + name: "xglSoundLoadSwd", + demangled_name: None, + address: 0, + size: 0, + kind: Unknown, + section: None, + flags: FlagSet(Global), + align: None, + virtual_address: None, + }, + Symbol { + name: "SsdAddWaveData", + demangled_name: None, + address: 0, + size: 0, + kind: Unknown, + section: None, + flags: FlagSet(Global), + align: None, + virtual_address: None, + }, + Symbol { + name: "SsdSpuDmaCompleted", + demangled_name: None, + address: 0, + size: 0, + kind: Unknown, + section: None, + flags: FlagSet(Global), + align: None, + virtual_address: None, + }, + Symbol { + name: "xglRenderDispOn", + demangled_name: None, + address: 0, + size: 0, + kind: Unknown, + section: None, + flags: FlagSet(Global), + align: None, + virtual_address: None, + }, + Symbol { + name: "xglCdLoadOverlay", + demangled_name: None, + address: 0, + size: 0, + kind: Unknown, + section: None, + flags: FlagSet(Global), + align: None, + virtual_address: None, + }, + Symbol { + name: "LogoFirst", + demangled_name: None, + address: 0, + size: 0, + kind: Unknown, + section: None, + flags: FlagSet(Global), + align: None, + virtual_address: None, + }, + Symbol { + name: "Title", + demangled_name: None, + address: 0, + size: 0, + kind: Unknown, + section: None, + flags: FlagSet(Global), + align: None, + virtual_address: None, + }, + Symbol { + name: "InitializeSystem", + demangled_name: None, + address: 184, + size: 356, + kind: Function, + section: Some( + 0, + ), + flags: FlagSet(Global), + align: None, + virtual_address: None, + }, + Symbol { + name: "sceSifInitRpc", + demangled_name: None, + address: 0, + size: 0, + kind: Unknown, + section: None, + flags: FlagSet(Global), + align: None, + virtual_address: None, + }, + Symbol { + name: "sceCdInit", + demangled_name: None, + address: 0, + size: 0, + kind: Unknown, + section: None, + flags: FlagSet(Global), + align: None, + virtual_address: None, + }, + Symbol { + name: "sceSifRebootIop", + demangled_name: None, + address: 0, + size: 0, + kind: Unknown, + section: None, + flags: FlagSet(Global), + align: None, + virtual_address: None, + }, + Symbol { + name: "sceSifSyncIop", + demangled_name: None, + address: 0, + size: 0, + kind: Unknown, + section: None, + flags: FlagSet(Global), + align: None, + virtual_address: None, + }, + Symbol { + name: "sceSifInitIopHeap", + demangled_name: None, + address: 0, + size: 0, + kind: Unknown, + section: None, + flags: FlagSet(Global), + align: None, + virtual_address: None, + }, + Symbol { + name: "sceSifLoadFileReset", + demangled_name: None, + address: 0, + size: 0, + kind: Unknown, + section: None, + flags: FlagSet(Global), + align: None, + virtual_address: None, + }, + Symbol { + name: "sceCdMmode", + demangled_name: None, + address: 0, + size: 0, + kind: Unknown, + section: None, + flags: FlagSet(Global), + align: None, + virtual_address: None, + }, + Symbol { + name: "sceFsReset", + demangled_name: None, + address: 0, + size: 0, + kind: Unknown, + section: None, + flags: FlagSet(Global), + align: None, + virtual_address: None, + }, + Symbol { + name: "xglCdSifLoadModule", + demangled_name: None, + address: 0, + size: 0, + kind: Unknown, + section: None, + flags: FlagSet(Global), + align: None, + virtual_address: None, + }, + Symbol { + name: "xglCdPowerOffCB", + demangled_name: None, + address: 0, + size: 0, + kind: Unknown, + section: None, + flags: FlagSet(Global), + align: None, + virtual_address: None, + }, + Symbol { + name: "sceCdPOffCallback", + demangled_name: None, + address: 0, + size: 0, + kind: Unknown, + section: None, + flags: FlagSet(Global), + align: None, + virtual_address: None, + }, + Symbol { + name: "xglSoundInitial", + demangled_name: None, + address: 0, + size: 0, + kind: Unknown, + section: None, + flags: FlagSet(Global), + align: None, + virtual_address: None, + }, + Symbol { + name: "xglCdInitial", + demangled_name: None, + address: 0, + size: 0, + kind: Unknown, + section: None, + flags: FlagSet(Global), + align: None, + virtual_address: None, + }, + Symbol { + name: "xglPadInitial", + demangled_name: None, + address: 0, + size: 0, + kind: Unknown, + section: None, + flags: FlagSet(Global), + align: None, + virtual_address: None, + }, + Symbol { + name: "xglMcInitial", + demangled_name: None, + address: 0, + size: 0, + kind: Unknown, + section: None, + flags: FlagSet(Global), + align: None, + virtual_address: None, + }, + Symbol { + name: "xglTaskInitial", + demangled_name: None, + address: 0, + size: 0, + kind: Unknown, + section: None, + flags: FlagSet(Global), + align: None, + virtual_address: None, + }, + Symbol { + name: "xglDmaInitial", + demangled_name: None, + address: 0, + size: 0, + kind: Unknown, + section: None, + flags: FlagSet(Global), + align: None, + virtual_address: None, + }, + Symbol { + name: "xglGeometryInit", + demangled_name: None, + address: 0, + size: 0, + kind: Unknown, + section: None, + flags: FlagSet(Global), + align: None, + virtual_address: None, + }, + Symbol { + name: "xglPacketInit", + demangled_name: None, + address: 0, + size: 0, + kind: Unknown, + section: None, + flags: FlagSet(Global), + align: None, + virtual_address: None, + }, + Symbol { + name: "xglRenderInit", + demangled_name: None, + address: 0, + size: 0, + kind: Unknown, + section: None, + flags: FlagSet(Global), + align: None, + virtual_address: None, + }, + Symbol { + name: "xglFontInitial", + demangled_name: None, + address: 0, + size: 0, + kind: Unknown, + section: None, + flags: FlagSet(Global), + align: None, + virtual_address: None, + }, + Symbol { + name: "xglMovieInit", + demangled_name: None, + address: 0, + size: 0, + kind: Unknown, + section: None, + flags: FlagSet(Global), + align: None, + virtual_address: None, + }, + Symbol { + name: "xglMenuInitial", + demangled_name: None, + address: 0, + size: 0, + kind: Unknown, + section: None, + flags: FlagSet(Global), + align: None, + virtual_address: None, + }, + Symbol { + name: "main", + demangled_name: None, + address: 544, + size: 88, + kind: Function, + section: Some( + 0, + ), + flags: FlagSet(Global), + align: None, + virtual_address: None, + }, + Symbol { + name: "__main", + demangled_name: None, + address: 0, + size: 0, + kind: Unknown, + section: None, + flags: FlagSet(Global), + align: None, + virtual_address: None, + }, + Symbol { + name: "main_param_argc", + demangled_name: None, + address: 68, + size: 4, + kind: Object, + section: Some( + 8, + ), + flags: FlagSet(Global), + align: None, + virtual_address: None, + }, + Symbol { + name: "BootDisplay", + demangled_name: None, + address: 0, + size: 0, + kind: Unknown, + section: None, + flags: FlagSet(Global), + align: None, + virtual_address: None, + }, + Symbol { + name: "main_param_argv", + demangled_name: None, + address: 72, + size: 4, + kind: Object, + section: Some( + 8, + ), + flags: FlagSet(Global), + align: None, + virtual_address: None, + }, + Symbol { + name: "xglThreadInitial", + demangled_name: None, + address: 0, + size: 0, + kind: Unknown, + section: None, + flags: FlagSet(Global), + align: None, + virtual_address: None, + }, + Symbol { + name: "xglThreadRotate", + demangled_name: None, + address: 0, + size: 0, + kind: Unknown, + section: None, + flags: FlagSet(Global), + align: None, + virtual_address: None, + }, + ], + sections: [ + Section { + id: ".text-0", + name: ".text", + address: 0, + size: 632, + kind: Code, + data: SectionData( + 632, + ), + flags: FlagSet(), + relocations: [ + Relocation { + flags: Elf( + 4, + ), + address: 20, + target_symbol: 12, + addend: 0, + }, + Relocation { + flags: Elf( + 7, + ), + address: 28, + target_symbol: 13, + addend: 0, + }, + Relocation { + flags: Elf( + 5, + ), + address: 32, + target_symbol: 4, + addend: 0, + }, + Relocation { + flags: Elf( + 4, + ), + address: 40, + target_symbol: 14, + addend: 0, + }, + Relocation { + flags: Elf( + 6, + ), + address: 44, + target_symbol: 4, + addend: 0, + }, + Relocation { + flags: Elf( + 5, + ), + address: 48, + target_symbol: 10, + addend: 0, + }, + Relocation { + flags: Elf( + 7, + ), + address: 52, + target_symbol: 13, + addend: 0, + }, + Relocation { + flags: Elf( + 4, + ), + address: 56, + target_symbol: 15, + addend: 0, + }, + Relocation { + flags: Elf( + 6, + ), + address: 60, + target_symbol: 10, + addend: 0, + }, + Relocation { + flags: Elf( + 7, + ), + address: 64, + target_symbol: 13, + addend: 0, + }, + Relocation { + flags: Elf( + 4, + ), + address: 72, + target_symbol: 16, + addend: 0, + }, + Relocation { + flags: Elf( + 4, + ), + address: 80, + target_symbol: 17, + addend: 0, + }, + Relocation { + flags: Elf( + 4, + ), + address: 96, + target_symbol: 18, + addend: 0, + }, + Relocation { + flags: Elf( + 4, + ), + address: 104, + target_symbol: 19, + addend: 0, + }, + Relocation { + flags: Elf( + 4, + ), + address: 112, + target_symbol: 20, + addend: 0, + }, + Relocation { + flags: Elf( + 5, + ), + address: 120, + target_symbol: 21, + addend: 0, + }, + Relocation { + flags: Elf( + 6, + ), + address: 124, + target_symbol: 21, + addend: 0, + }, + Relocation { + flags: Elf( + 4, + ), + address: 128, + target_symbol: 19, + addend: 0, + }, + Relocation { + flags: Elf( + 4, + ), + address: 136, + target_symbol: 21, + addend: 0, + }, + Relocation { + flags: Elf( + 4, + ), + address: 160, + target_symbol: 19, + addend: 0, + }, + Relocation { + flags: Elf( + 4, + ), + address: 200, + target_symbol: 23, + addend: 0, + }, + Relocation { + flags: Elf( + 5, + ), + address: 204, + target_symbol: 5, + addend: 16, + }, + Relocation { + flags: Elf( + 4, + ), + address: 208, + target_symbol: 24, + addend: 0, + }, + Relocation { + flags: Elf( + 4, + ), + address: 216, + target_symbol: 25, + addend: 0, + }, + Relocation { + flags: Elf( + 6, + ), + address: 220, + target_symbol: 5, + addend: 16, + }, + Relocation { + flags: Elf( + 4, + ), + address: 232, + target_symbol: 26, + addend: 0, + }, + Relocation { + flags: Elf( + 4, + ), + address: 248, + target_symbol: 23, + addend: 0, + }, + Relocation { + flags: Elf( + 4, + ), + address: 256, + target_symbol: 27, + addend: 0, + }, + Relocation { + flags: Elf( + 4, + ), + address: 264, + target_symbol: 28, + addend: 0, + }, + Relocation { + flags: Elf( + 4, + ), + address: 272, + target_symbol: 24, + addend: 0, + }, + Relocation { + flags: Elf( + 4, + ), + address: 280, + target_symbol: 29, + addend: 0, + }, + Relocation { + flags: Elf( + 4, + ), + address: 288, + target_symbol: 30, + addend: 0, + }, + Relocation { + flags: Elf( + 5, + ), + address: 296, + target_symbol: 4, + addend: 8, + }, + Relocation { + flags: Elf( + 4, + ), + address: 304, + target_symbol: 31, + addend: 0, + }, + Relocation { + flags: Elf( + 6, + ), + address: 308, + target_symbol: 4, + addend: 8, + }, + Relocation { + flags: Elf( + 5, + ), + address: 312, + target_symbol: 4, + addend: 16, + }, + Relocation { + flags: Elf( + 6, + ), + address: 316, + target_symbol: 4, + addend: 16, + }, + Relocation { + flags: Elf( + 4, + ), + address: 320, + target_symbol: 31, + addend: 0, + }, + Relocation { + flags: Elf( + 5, + ), + address: 328, + target_symbol: 4, + addend: 24, + }, + Relocation { + flags: Elf( + 6, + ), + address: 332, + target_symbol: 4, + addend: 24, + }, + Relocation { + flags: Elf( + 4, + ), + address: 336, + target_symbol: 31, + addend: 0, + }, + Relocation { + flags: Elf( + 5, + ), + address: 344, + target_symbol: 4, + addend: 32, + }, + Relocation { + flags: Elf( + 6, + ), + address: 348, + target_symbol: 4, + addend: 32, + }, + Relocation { + flags: Elf( + 4, + ), + address: 352, + target_symbol: 31, + addend: 0, + }, + Relocation { + flags: Elf( + 5, + ), + address: 360, + target_symbol: 4, + addend: 40, + }, + Relocation { + flags: Elf( + 6, + ), + address: 364, + target_symbol: 4, + addend: 40, + }, + Relocation { + flags: Elf( + 4, + ), + address: 368, + target_symbol: 31, + addend: 0, + }, + Relocation { + flags: Elf( + 5, + ), + address: 376, + target_symbol: 4, + addend: 48, + }, + Relocation { + flags: Elf( + 6, + ), + address: 380, + target_symbol: 4, + addend: 48, + }, + Relocation { + flags: Elf( + 4, + ), + address: 384, + target_symbol: 31, + addend: 0, + }, + Relocation { + flags: Elf( + 5, + ), + address: 392, + target_symbol: 4, + addend: 56, + }, + Relocation { + flags: Elf( + 6, + ), + address: 396, + target_symbol: 4, + addend: 56, + }, + Relocation { + flags: Elf( + 4, + ), + address: 400, + target_symbol: 31, + addend: 0, + }, + Relocation { + flags: Elf( + 5, + ), + address: 408, + target_symbol: 32, + addend: 0, + }, + Relocation { + flags: Elf( + 6, + ), + address: 412, + target_symbol: 32, + addend: 0, + }, + Relocation { + flags: Elf( + 4, + ), + address: 416, + target_symbol: 33, + addend: 0, + }, + Relocation { + flags: Elf( + 4, + ), + address: 428, + target_symbol: 34, + addend: 0, + }, + Relocation { + flags: Elf( + 7, + ), + address: 432, + target_symbol: 13, + addend: 0, + }, + Relocation { + flags: Elf( + 4, + ), + address: 436, + target_symbol: 35, + addend: 0, + }, + Relocation { + flags: Elf( + 4, + ), + address: 444, + target_symbol: 36, + addend: 0, + }, + Relocation { + flags: Elf( + 4, + ), + address: 452, + target_symbol: 37, + addend: 0, + }, + Relocation { + flags: Elf( + 4, + ), + address: 468, + target_symbol: 38, + addend: 0, + }, + Relocation { + flags: Elf( + 4, + ), + address: 476, + target_symbol: 39, + addend: 0, + }, + Relocation { + flags: Elf( + 4, + ), + address: 484, + target_symbol: 40, + addend: 0, + }, + Relocation { + flags: Elf( + 4, + ), + address: 492, + target_symbol: 41, + addend: 0, + }, + Relocation { + flags: Elf( + 4, + ), + address: 500, + target_symbol: 42, + addend: 0, + }, + Relocation { + flags: Elf( + 4, + ), + address: 508, + target_symbol: 43, + addend: 0, + }, + Relocation { + flags: Elf( + 4, + ), + address: 516, + target_symbol: 44, + addend: 0, + }, + Relocation { + flags: Elf( + 4, + ), + address: 532, + target_symbol: 45, + addend: 0, + }, + Relocation { + flags: Elf( + 4, + ), + address: 564, + target_symbol: 47, + addend: 0, + }, + Relocation { + flags: Elf( + 7, + ), + address: 572, + target_symbol: 48, + addend: 0, + }, + Relocation { + flags: Elf( + 4, + ), + address: 576, + target_symbol: 49, + addend: 0, + }, + Relocation { + flags: Elf( + 7, + ), + address: 580, + target_symbol: 50, + addend: 0, + }, + Relocation { + flags: Elf( + 4, + ), + address: 584, + target_symbol: 22, + addend: 0, + }, + Relocation { + flags: Elf( + 4, + ), + address: 592, + target_symbol: 51, + addend: 0, + }, + Relocation { + flags: Elf( + 4, + ), + address: 600, + target_symbol: 52, + addend: 0, + }, + ], + line_info: {}, + virtual_address: None, + }, + Section { + id: ".rel.text-0", + name: ".rel.text", + address: 0, + size: 608, + kind: Unknown, + data: SectionData( + 0, + ), + flags: FlagSet(), + relocations: [], + line_info: {}, + virtual_address: None, + }, + Section { + id: ".data-0", + name: ".data", + address: 0, + size: 0, + kind: Data, + data: SectionData( + 0, + ), + flags: FlagSet(), + relocations: [], + line_info: {}, + virtual_address: None, + }, + Section { + id: ".bss-0", + name: ".bss", + address: 0, + size: 0, + kind: Bss, + data: SectionData( + 0, + ), + flags: FlagSet(), + relocations: [], + line_info: {}, + virtual_address: None, + }, + Section { + id: ".reginfo-0", + name: ".reginfo", + address: 0, + size: 24, + kind: Unknown, + data: SectionData( + 0, + ), + flags: FlagSet(), + relocations: [], + line_info: {}, + virtual_address: None, + }, + Section { + id: ".mdebug-0", + name: ".mdebug", + address: 0, + size: 1932, + kind: Unknown, + data: SectionData( + 0, + ), + flags: FlagSet(), + relocations: [], + line_info: {}, + virtual_address: None, + }, + Section { + id: ".mdebug.eabi64-0", + name: ".mdebug.eabi64", + address: 0, + size: 0, + kind: Unknown, + data: SectionData( + 0, + ), + flags: FlagSet(), + relocations: [], + line_info: {}, + virtual_address: None, + }, + Section { + id: ".rodata-0", + name: ".rodata", + address: 0, + size: 43, + kind: Data, + data: SectionData( + 43, + ), + flags: FlagSet(), + relocations: [], + line_info: {}, + virtual_address: None, + }, + Section { + id: ".sdata-0", + name: ".sdata", + address: 0, + size: 76, + kind: Data, + data: SectionData( + 76, + ), + flags: FlagSet(), + relocations: [], + line_info: {}, + virtual_address: None, + }, + Section { + id: ".symtab-0", + name: ".symtab", + address: 0, + size: 864, + kind: Unknown, + data: SectionData( + 0, + ), + flags: FlagSet(), + relocations: [], + line_info: {}, + virtual_address: None, + }, + Section { + id: ".strtab-0", + name: ".strtab", + address: 0, + size: 653, + kind: Unknown, + data: SectionData( + 0, + ), + flags: FlagSet(), + relocations: [], + line_info: {}, + virtual_address: None, + }, + Section { + id: ".shstrtab-0", + name: ".shstrtab", + address: 0, + size: 95, + kind: Unknown, + data: SectionData( + 0, + ), + flags: FlagSet(), + relocations: [], + line_info: {}, + virtual_address: None, + }, + ], + split_meta: None, + path: None, + timestamp: None, +} diff --git a/objdiff-gui/src/app_config.rs b/objdiff-gui/src/app_config.rs index 257b2bb..91d667c 100644 --- a/objdiff-gui/src/app_config.rs +++ b/objdiff-gui/src/app_config.rs @@ -273,7 +273,6 @@ impl DiffObjConfigV1 { }, space_between_args: self.space_between_args, combine_data_sections: self.combine_data_sections, - combine_text_sections: false, x86_formatter: self.x86_formatter, mips_abi: self.mips_abi, mips_instr_category: self.mips_instr_category, @@ -284,6 +283,7 @@ impl DiffObjConfigV1 { arm_sl_usage: self.arm_sl_usage, arm_fp_usage: self.arm_fp_usage, arm_ip_usage: self.arm_ip_usage, + ..Default::default() } } } diff --git a/objdiff-wasm/package.json b/objdiff-wasm/package.json index 5493126..f4d2e62 100644 --- a/objdiff-wasm/package.json +++ b/objdiff-wasm/package.json @@ -12,7 +12,9 @@ "type": "git", "url": "git+https://github.com/encounter/objdiff.git" }, - "files": ["dist/*"], + "files": [ + "dist/*" + ], "main": "dist/objdiff.js", "types": "dist/objdiff.d.ts", "scripts": {