diff --git a/objdiff-core/src/arch/ppc.rs b/objdiff-core/src/arch/ppc.rs index ec9bb13..7e49267 100644 --- a/objdiff-core/src/arch/ppc.rs +++ b/objdiff-core/src/arch/ppc.rs @@ -211,10 +211,8 @@ impl ObjArch for ObjArchPpc { // Assume that any addi instruction that references a local symbol is loading a string. // This hack is not ideal and results in tons of false positives where it will show // garbage strings (e.g. misinterpreting arrays, float literals, etc). - // But there isn't much other choice as not all strings are in the @stringBase pool. - // And even those that are would be missed by the target.name.starts_with("@stringBase") - // hack above for fake pooled relocations, as they have an empty string placeholder for - // the target symbol name. + // But not all strings are in the @stringBase pool, so the condition above that checks + // the target symbol name would miss some. Some(DataType::String) } else { None diff --git a/objdiff-core/src/diff/code.rs b/objdiff-core/src/diff/code.rs index 3d3273a..b5c0fad 100644 --- a/objdiff-core/src/diff/code.rs +++ b/objdiff-core/src/diff/code.rs @@ -9,7 +9,7 @@ use crate::{ DiffObjConfig, ObjInsArgDiff, ObjInsBranchFrom, ObjInsBranchTo, ObjInsDiff, ObjInsDiffKind, ObjSymbolDiff, }, - obj::{ObjInfo, ObjInsArg, ObjReloc, ObjSymbolFlags, SymbolRef}, + obj::{ObjInfo, ObjInsArg, ObjReloc, ObjSection, ObjSymbol, ObjSymbolFlags, SymbolRef}, }; pub fn process_code_symbol( @@ -21,14 +21,30 @@ pub fn process_code_symbol( let section = section.ok_or_else(|| anyhow!("Code symbol section not found"))?; let code = §ion.data [symbol.section_address as usize..(symbol.section_address + symbol.size) as usize]; - obj.arch.process_code( + let mut res = obj.arch.process_code( symbol.address, code, section.orig_index, §ion.relocations, §ion.line_info, config, - ) + )?; + + for inst in res.insts.iter_mut() { + if let Some(reloc) = &mut inst.fake_pool_reloc { + if reloc.target.size == 0 && reloc.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(&reloc.target, &obj.sections) + { + reloc.addend = (reloc.target.address - real_target.address) as i64; + reloc.target = real_target; + } + } + } + } + + Ok(res) } pub fn no_diff_code(out: &ProcessCodeResult, symbol_ref: SymbolRef) -> Result { @@ -369,3 +385,16 @@ fn compare_ins( } Ok(result) } + +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()) +} diff --git a/objdiff-gui/src/views/function_diff.rs b/objdiff-gui/src/views/function_diff.rs index 5f2d165..d555065 100644 --- a/objdiff-gui/src/views/function_diff.rs +++ b/objdiff-gui/src/views/function_diff.rs @@ -74,19 +74,6 @@ 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, @@ -132,29 +119,17 @@ 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 addend.cmp(&0i64) { - Ordering::Greater => format!("+{:x}", addend), - Ordering::Less => format!("-{:x}", -addend), + let addend_str = match reloc.addend.cmp(&0i64) { + Ordering::Greater => format!("+{:x}", reloc.addend), + Ordering::Less => format!("-{:x}", -reloc.addend), _ => "".to_string(), }; ui.colored_label( appearance.highlight_color, - format!("Name: {}{}", target.name, addend_str), + format!("Name: {}{}", reloc.target.name, addend_str), ); - if let Some(orig_section_index) = target.orig_section_index { + if let Some(orig_section_index) = reloc.target.orig_section_index { if let Some(section) = obj.sections.iter().find(|s| s.orig_index == orig_section_index) { @@ -165,12 +140,15 @@ fn ins_hover_ui( } ui.colored_label( appearance.highlight_color, - format!("Address: {:x}{}", target.address, addend_str), + format!("Address: {:x}{}", reloc.target.address, addend_str), ); - ui.colored_label(appearance.highlight_color, format!("Size: {:x}", target.size)); - if addend >= 0 && target.bytes.len() > addend as usize { + ui.colored_label( + appearance.highlight_color, + format!("Size: {:x}", reloc.target.size), + ); + if reloc.addend >= 0 && reloc.target.bytes.len() > reloc.addend as usize { if let Some(s) = obj.arch.guess_data_type(ins).and_then(|ty| { - obj.arch.display_data_type(ty, &target.bytes[addend as usize..]) + obj.arch.display_data_type(ty, &reloc.target.bytes[reloc.addend as usize..]) }) { ui.colored_label(appearance.highlight_color, s); }