diff --git a/objdiff-core/src/arch/arm.rs b/objdiff-core/src/arch/arm.rs index 2126608..279cecb 100644 --- a/objdiff-core/src/arch/arm.rs +++ b/objdiff-core/src/arch/arm.rs @@ -113,7 +113,6 @@ impl ObjArch for ObjArchArm { relocations: &[ObjReloc], line_info: &BTreeMap, config: &DiffObjConfig, - _sections: &[ObjSection], ) -> Result { let start_addr = address as u32; let end_addr = start_addr + code.len() as u32; diff --git a/objdiff-core/src/arch/arm64.rs b/objdiff-core/src/arch/arm64.rs index b803252..ae78f8a 100644 --- a/objdiff-core/src/arch/arm64.rs +++ b/objdiff-core/src/arch/arm64.rs @@ -29,7 +29,6 @@ impl ObjArch for ObjArchArm64 { relocations: &[ObjReloc], line_info: &BTreeMap, config: &DiffObjConfig, - _sections: &[ObjSection], ) -> Result { let start_address = address; let end_address = address + code.len() as u64; diff --git a/objdiff-core/src/arch/mips.rs b/objdiff-core/src/arch/mips.rs index 754d119..c2c28d1 100644 --- a/objdiff-core/src/arch/mips.rs +++ b/objdiff-core/src/arch/mips.rs @@ -87,7 +87,6 @@ impl ObjArch for ObjArchMips { relocations: &[ObjReloc], line_info: &BTreeMap, config: &DiffObjConfig, - _sections: &[ObjSection], ) -> Result { let _guard = RABBITIZER_MUTEX.lock().map_err(|e| anyhow!("Failed to lock mutex: {e}"))?; configure_rabbitizer(match config.mips_abi { diff --git a/objdiff-core/src/arch/mod.rs b/objdiff-core/src/arch/mod.rs index 5fc2d01..82579dd 100644 --- a/objdiff-core/src/arch/mod.rs +++ b/objdiff-core/src/arch/mod.rs @@ -126,7 +126,6 @@ impl DataType { } pub trait ObjArch: Send + Sync { - #[expect(clippy::too_many_arguments)] fn process_code( &self, address: u64, @@ -135,7 +134,6 @@ pub trait ObjArch: Send + Sync { relocations: &[ObjReloc], line_info: &BTreeMap, config: &DiffObjConfig, - sections: &[ObjSection], ) -> Result; fn implcit_addend( diff --git a/objdiff-core/src/arch/ppc.rs b/objdiff-core/src/arch/ppc.rs index a14852a..7d90db9 100644 --- a/objdiff-core/src/arch/ppc.rs +++ b/objdiff-core/src/arch/ppc.rs @@ -48,13 +48,12 @@ impl ObjArch for ObjArchPpc { relocations: &[ObjReloc], line_info: &BTreeMap, config: &DiffObjConfig, - sections: &[ObjSection], ) -> Result { let ins_count = code.len() / 4; let mut ops = Vec::::with_capacity(ins_count); let mut insts = Vec::::with_capacity(ins_count); let fake_pool_reloc_for_addr = - generate_fake_pool_reloc_for_addr_mapping(address, code, relocations, sections); + generate_fake_pool_reloc_for_addr_mapping(address, code, relocations); for (cur_addr, mut ins) in InsIter::new(code, address as u32) { let reloc = relocations.iter().find(|r| (r.address as u32 & !3) == cur_addr); if let Some(reloc) = reloc { @@ -453,26 +452,38 @@ fn get_offset_and_addr_gpr_for_possible_pool_reference( // there isn't really a relocation here, as copying the pool relocation's type wouldn't make sense. // Also, if this instruction is accessing the middle of a symbol instead of the start, we add an // addend to indicate that. -fn make_fake_pool_reloc( - offset: i16, - cur_addr: u32, - pool_reloc: &ObjReloc, - sections: &[ObjSection], -) -> Option { +fn make_fake_pool_reloc(offset: i16, cur_addr: u32, pool_reloc: &ObjReloc) -> Option { let offset_from_pool = pool_reloc.addend + offset as i64; let target_address = pool_reloc.target.address.checked_add_signed(offset_from_pool)?; let orig_section_index = pool_reloc.target.orig_section_index?; - let section = sections.iter().find(|s| s.orig_index == orig_section_index)?; - let target_symbol = section - .symbols - .iter() - .find(|s| s.size > 0 && (s.address..s.address + s.size).contains(&target_address))?; - let addend = (target_address - target_symbol.address) as i64; + // We also need to create a fake target symbol to go inside our fake relocation. + // This is because we don't have access to list of all symbols in this section, so we can't find + // the real symbol yet. Instead we make a placeholder that has the correct `orig_section_index` + // and `address` fields, and then later on when this information is displayed to the user, we + // can find the real symbol by searching through the object's section's symbols for one that + // contains this address. + let fake_target_symbol = ObjSymbol { + name: "".to_string(), + demangled_name: None, + address: target_address, + section_address: 0, + size: 0, + size_known: false, + kind: Default::default(), + flags: Default::default(), + orig_section_index: Some(orig_section_index), + virtual_address: None, + original_index: None, + bytes: vec![], + }; + // The addend is also fake because we don't know yet if the `target_address` here is the exact + // start of the symbol or if it's in the middle of it. + let fake_addend = 0; Some(ObjReloc { flags: RelocationFlags::Elf { r_type: elf::R_PPC_NONE }, address: cur_addr as u64, - target: target_symbol.clone(), - addend, + target: fake_target_symbol, + addend: fake_addend, }) } @@ -491,7 +502,6 @@ fn generate_fake_pool_reloc_for_addr_mapping( address: u64, code: &[u8], relocations: &[ObjReloc], - sections: &[ObjSection], ) -> HashMap { let mut active_pool_relocs = HashMap::new(); let mut pool_reloc_for_addr = HashMap::new(); @@ -538,9 +548,7 @@ fn generate_fake_pool_reloc_for_addr_mapping( // This instruction doesn't have a real relocation, so it may be a reference to one of // the already-loaded pools. if let Some(pool_reloc) = active_pool_relocs.get(&addr_src_gpr.0) { - if let Some(fake_pool_reloc) = - make_fake_pool_reloc(offset, cur_addr, pool_reloc, sections) - { + if let Some(fake_pool_reloc) = make_fake_pool_reloc(offset, cur_addr, pool_reloc) { pool_reloc_for_addr.insert(cur_addr, fake_pool_reloc); } if let Some(addr_dst_gpr) = addr_dst_gpr { diff --git a/objdiff-core/src/arch/x86.rs b/objdiff-core/src/arch/x86.rs index a92e09f..33c6675 100644 --- a/objdiff-core/src/arch/x86.rs +++ b/objdiff-core/src/arch/x86.rs @@ -34,7 +34,6 @@ impl ObjArch for ObjArchX86 { relocations: &[ObjReloc], line_info: &BTreeMap, config: &DiffObjConfig, - _sections: &[ObjSection], ) -> Result { let mut result = ProcessCodeResult { ops: Vec::new(), insts: Vec::new() }; let mut decoder = Decoder::with_ip(self.bits, code, address, DecoderOptions::NONE); diff --git a/objdiff-core/src/diff/code.rs b/objdiff-core/src/diff/code.rs index 9e2fb88..3d3273a 100644 --- a/objdiff-core/src/diff/code.rs +++ b/objdiff-core/src/diff/code.rs @@ -28,7 +28,6 @@ pub fn process_code_symbol( §ion.relocations, §ion.line_info, config, - &obj.sections, ) } diff --git a/objdiff-gui/src/views/function_diff.rs b/objdiff-gui/src/views/function_diff.rs index d555065..5f2d165 100644 --- a/objdiff-gui/src/views/function_diff.rs +++ b/objdiff-gui/src/views/function_diff.rs @@ -74,6 +74,19 @@ impl FunctionViewState { } } +fn find_symbol_matching_fake_symbol_in_sections( + fake_symbol: &ObjSymbol, + sections: &[ObjSection], +) -> Option { + let orig_section_index = fake_symbol.orig_section_index?; + let section = sections.iter().find(|s| s.orig_index == orig_section_index)?; + let real_symbol = section + .symbols + .iter() + .find(|s| s.size > 0 && (s.address..s.address + s.size).contains(&fake_symbol.address))?; + Some(real_symbol.clone()) +} + fn ins_hover_ui( ui: &mut egui::Ui, obj: &ObjInfo, @@ -119,17 +132,29 @@ fn ins_hover_ui( } if let Some(reloc) = ins.reloc.as_ref().or(ins.fake_pool_reloc.as_ref()) { + let mut target = reloc.target.clone(); + let mut addend = reloc.addend; + if target.size == 0 && target.name.is_empty() { + // Fake target symbol we added as a placeholder. We need to find the real one. + if let Some(real_target) = + find_symbol_matching_fake_symbol_in_sections(&target, &obj.sections) + { + target = real_target; + addend = (reloc.target.address - target.address) as i64; + } + } + ui.label(format!("Relocation type: {}", obj.arch.display_reloc(reloc.flags))); - let addend_str = match reloc.addend.cmp(&0i64) { - Ordering::Greater => format!("+{:x}", reloc.addend), - Ordering::Less => format!("-{:x}", -reloc.addend), + let addend_str = match addend.cmp(&0i64) { + Ordering::Greater => format!("+{:x}", addend), + Ordering::Less => format!("-{:x}", -addend), _ => "".to_string(), }; ui.colored_label( appearance.highlight_color, - format!("Name: {}{}", reloc.target.name, addend_str), + format!("Name: {}{}", target.name, addend_str), ); - if let Some(orig_section_index) = reloc.target.orig_section_index { + if let Some(orig_section_index) = target.orig_section_index { if let Some(section) = obj.sections.iter().find(|s| s.orig_index == orig_section_index) { @@ -140,15 +165,12 @@ fn ins_hover_ui( } ui.colored_label( appearance.highlight_color, - format!("Address: {:x}{}", reloc.target.address, addend_str), + format!("Address: {:x}{}", target.address, addend_str), ); - ui.colored_label( - appearance.highlight_color, - format!("Size: {:x}", reloc.target.size), - ); - if reloc.addend >= 0 && reloc.target.bytes.len() > reloc.addend as usize { + ui.colored_label(appearance.highlight_color, format!("Size: {:x}", target.size)); + if addend >= 0 && target.bytes.len() > addend as usize { if let Some(s) = obj.arch.guess_data_type(ins).and_then(|ty| { - obj.arch.display_data_type(ty, &reloc.target.bytes[reloc.addend as usize..]) + obj.arch.display_data_type(ty, &target.bytes[addend as usize..]) }) { ui.colored_label(appearance.highlight_color, s); }