diff --git a/objdiff-core/src/arch/mod.rs b/objdiff-core/src/arch/mod.rs index eb0029e6..fa41a744 100644 --- a/objdiff-core/src/arch/mod.rs +++ b/objdiff-core/src/arch/mod.rs @@ -20,8 +20,8 @@ use crate::{ }, obj::{ FlowAnalysisResult, InstructionArg, InstructionRef, Object, ParsedInstruction, Relocation, - RelocationFlags, ResolvedInstructionRef, ResolvedSymbol, Section, Symbol, SymbolFlagSet, - SymbolKind, + RelocationFlags, ResolvedInstructionRef, ResolvedRelocation, ResolvedSymbol, Section, + Symbol, SymbolFlagSet, SymbolKind, }, util::ReallySigned, }; @@ -464,12 +464,17 @@ pub trait Arch: Any + Debug + Send + Sync { fn guess_data_type( &self, - _resolved: ResolvedInstructionRef, + _ins: Option, + _reloc: Option, _bytes: &[u8], ) -> Option { None } + fn guess_ins_data_type(&self, ins: ResolvedInstructionRef, bytes: &[u8]) -> Option { + self.guess_data_type(Some(ins), ins.relocation, bytes) + } + fn symbol_hover(&self, _obj: &Object, _symbol_index: usize) -> Vec { Vec::new() } fn symbol_context(&self, _obj: &Object, _symbol_index: usize) -> Vec { Vec::new() } diff --git a/objdiff-core/src/arch/ppc/mod.rs b/objdiff-core/src/arch/ppc/mod.rs index 0cefda20..e60731e4 100644 --- a/objdiff-core/src/arch/ppc/mod.rs +++ b/objdiff-core/src/arch/ppc/mod.rs @@ -357,8 +357,13 @@ impl Arch for ArchPpc { } } - fn guess_data_type(&self, resolved: ResolvedInstructionRef, bytes: &[u8]) -> Option { - if resolved.relocation.is_some_and(|r| { + fn guess_data_type( + &self, + ins: Option, + reloc: Option, + bytes: &[u8], + ) -> Option { + if reloc.is_some_and(|r| { r.symbol.name.starts_with("@stringBase") || r.symbol.name.starts_with("@wstringBase") || r.symbol.name.starts_with("$SG") @@ -367,10 +372,12 @@ impl Arch for ArchPpc { // Compiler-generated symbol name for a string or a pool of strings. return Some(DataType::String); } - let opcode = powerpc::Opcode::from(resolved.ins_ref.opcode); - if let Some(ty) = flow_analysis::guess_data_type_from_load_store_inst_op(opcode) { - // Numeric type. - return Some(ty); + if let Some(ins) = ins { + let opcode = powerpc::Opcode::from(ins.ins_ref.opcode); + if let Some(ty) = flow_analysis::guess_data_type_from_load_store_inst_op(opcode) { + // Numeric type. + return Some(ty); + } } if bytes.len() >= 2 && bytes.iter().position(|&c| c == b'\0') == Some(bytes.len() - 1) { // It may be an unpooled string if the symbol contains exactly one null byte at the end of the symbol. diff --git a/objdiff-core/src/diff/display.rs b/objdiff-core/src/diff/display.rs index d5c7920e..8844c1a9 100644 --- a/objdiff-core/src/diff/display.rs +++ b/objdiff-core/src/diff/display.rs @@ -499,18 +499,16 @@ pub fn relocation_context( ) -> Vec { let mut out = Vec::new(); out.append(&mut symbol_context(obj, reloc.relocation.target_symbol)); - if let Some(ins) = ins { - let mut literals = display_ins_data_literals(obj, ins); - literals.retain(|lit_info| !lit_info.hidden(diff_config)); - if !literals.is_empty() { - out.push(ContextItem::Separator); - for lit_info in literals { - out.push(ContextItem::Copy { - value: lit_info.literal, - label: lit_info.label_override, - copy_string: lit_info.copy_string, - }); - } + let mut literals = display_data_literals(obj, ins, Some(reloc)); + literals.retain(|lit_info| !lit_info.hidden(diff_config)); + if !literals.is_empty() { + out.push(ContextItem::Separator); + for lit_info in literals { + out.push(ContextItem::Copy { + value: lit_info.literal, + label: lit_info.label_override, + copy_string: lit_info.copy_string, + }); } } out @@ -563,6 +561,7 @@ pub fn data_row_context(obj: &Object, diff_row: &DataDiffRow) -> Vec, + reloc: Option, ) -> Vec { - let Some(reloc) = resolved.relocation else { + let Some(reloc) = reloc else { return Vec::new(); }; if reloc.relocation.addend < 0 || reloc.relocation.addend as u64 >= reloc.symbol.size { @@ -902,7 +902,14 @@ pub fn display_ins_data_literals( }; let bytes = &data[reloc.relocation.addend as usize..]; obj.arch - .guess_data_type(resolved, bytes) + .guess_data_type(resolved, Some(reloc), bytes) .map(|ty| ty.display_literals(obj.endianness, bytes)) .unwrap_or_default() } + +pub fn display_ins_data_literals( + obj: &Object, + resolved: ResolvedInstructionRef, +) -> Vec { + display_data_literals(obj, Some(resolved), resolved.relocation) +}