Compare commits

..

2 Commits

Author SHA1 Message Date
LagoLunatic dc46914428 Merge reloc and fake_pool_reloc fields of ObjIns 2024-12-03 19:13:58 -05:00
LagoLunatic 042fa9ef9e Move hack to resolve placeholder symbol into process_code_symbol 2024-12-03 18:59:42 -05:00
8 changed files with 49 additions and 57 deletions

View File

@ -216,7 +216,6 @@ impl ObjArch for ObjArchArm {
mnemonic: Cow::Borrowed(parsed_ins.mnemonic), mnemonic: Cow::Borrowed(parsed_ins.mnemonic),
args, args,
reloc, reloc,
fake_pool_reloc: None,
branch_dest, branch_dest,
line, line,
formatted: parsed_ins.display(display_options).to_string(), formatted: parsed_ins.display(display_options).to_string(),

View File

@ -59,7 +59,6 @@ impl ObjArch for ObjArchArm64 {
mnemonic: Cow::Borrowed("<invalid>"), mnemonic: Cow::Borrowed("<invalid>"),
args: vec![], args: vec![],
reloc: None, reloc: None,
fake_pool_reloc: None,
branch_dest: None, branch_dest: None,
line: None, line: None,
formatted: "".to_string(), formatted: "".to_string(),
@ -122,7 +121,6 @@ impl ObjArch for ObjArchArm64 {
mnemonic: Cow::Borrowed(mnemonic), mnemonic: Cow::Borrowed(mnemonic),
args, args,
reloc, reloc,
fake_pool_reloc: None,
branch_dest, branch_dest,
line, line,
formatted: ins.to_string(), formatted: ins.to_string(),

View File

@ -205,7 +205,6 @@ impl ObjArch for ObjArchMips {
mnemonic: Cow::Borrowed(mnemonic), mnemonic: Cow::Borrowed(mnemonic),
args, args,
reloc: reloc.cloned(), reloc: reloc.cloned(),
fake_pool_reloc: None,
branch_dest, branch_dest,
line, line,
formatted, formatted,

View File

@ -150,8 +150,7 @@ impl ObjArch for ObjArchPpc {
size: 4, size: 4,
mnemonic: Cow::Borrowed(simplified.mnemonic), mnemonic: Cow::Borrowed(simplified.mnemonic),
args, args,
reloc: reloc.cloned(), reloc: reloc.or(fake_pool_reloc_for_addr.get(&cur_addr)).cloned(),
fake_pool_reloc: fake_pool_reloc_for_addr.get(&cur_addr).cloned(),
op: ins.op as u16, op: ins.op as u16,
branch_dest, branch_dest,
line, line,
@ -195,12 +194,7 @@ impl ObjArch for ObjArchPpc {
} }
fn guess_data_type(&self, instruction: &ObjIns) -> Option<super::DataType> { fn guess_data_type(&self, instruction: &ObjIns) -> Option<super::DataType> {
if instruction if instruction.reloc.as_ref().is_some_and(|r| r.target.name.starts_with("@stringBase")) {
.reloc
.as_ref()
.or(instruction.fake_pool_reloc.as_ref())
.is_some_and(|r| r.target.name.starts_with("@stringBase"))
{
return Some(DataType::String); return Some(DataType::String);
} }
@ -211,10 +205,8 @@ impl ObjArch for ObjArchPpc {
// Assume that any addi instruction that references a local symbol is loading a string. // 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 // 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). // 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. // But not all strings are in the @stringBase pool, so the condition above that checks
// And even those that are would be missed by the target.name.starts_with("@stringBase") // the target symbol name would miss some.
// hack above for fake pooled relocations, as they have an empty string placeholder for
// the target symbol name.
Some(DataType::String) Some(DataType::String)
} else { } else {
None None

View File

@ -54,7 +54,6 @@ impl ObjArch for ObjArchX86 {
mnemonic: Cow::Borrowed("<invalid>"), mnemonic: Cow::Borrowed("<invalid>"),
args: vec![], args: vec![],
reloc: None, reloc: None,
fake_pool_reloc: None,
branch_dest: None, branch_dest: None,
line: None, line: None,
formatted: String::new(), formatted: String::new(),
@ -80,7 +79,6 @@ impl ObjArch for ObjArchX86 {
mnemonic: Cow::Borrowed("<invalid>"), mnemonic: Cow::Borrowed("<invalid>"),
args: vec![], args: vec![],
reloc: reloc.cloned(), reloc: reloc.cloned(),
fake_pool_reloc: None,
branch_dest: None, branch_dest: None,
line, line,
formatted: String::new(), formatted: String::new(),

View File

@ -9,7 +9,7 @@ use crate::{
DiffObjConfig, ObjInsArgDiff, ObjInsBranchFrom, ObjInsBranchTo, ObjInsDiff, ObjInsDiffKind, DiffObjConfig, ObjInsArgDiff, ObjInsBranchFrom, ObjInsBranchTo, ObjInsDiff, ObjInsDiffKind,
ObjSymbolDiff, ObjSymbolDiff,
}, },
obj::{ObjInfo, ObjInsArg, ObjReloc, ObjSymbolFlags, SymbolRef}, obj::{ObjInfo, ObjInsArg, ObjReloc, ObjSection, ObjSymbol, ObjSymbolFlags, SymbolRef},
}; };
pub fn process_code_symbol( 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 section = section.ok_or_else(|| anyhow!("Code symbol section not found"))?;
let code = &section.data let code = &section.data
[symbol.section_address as usize..(symbol.section_address + symbol.size) as usize]; [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, symbol.address,
code, code,
section.orig_index, section.orig_index,
&section.relocations, &section.relocations,
&section.line_info, &section.line_info,
config, config,
) )?;
for inst in res.insts.iter_mut() {
if let Some(reloc) = &mut inst.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<ObjSymbolDiff> { pub fn no_diff_code(out: &ProcessCodeResult, symbol_ref: SymbolRef) -> Result<ObjSymbolDiff> {
@ -369,3 +385,16 @@ fn compare_ins(
} }
Ok(result) Ok(result)
} }
fn find_symbol_matching_fake_symbol_in_sections(
fake_symbol: &ObjSymbol,
sections: &[ObjSection],
) -> Option<ObjSymbol> {
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())
}

View File

@ -106,7 +106,6 @@ pub struct ObjIns {
pub mnemonic: Cow<'static, str>, pub mnemonic: Cow<'static, str>,
pub args: Vec<ObjInsArg>, pub args: Vec<ObjInsArg>,
pub reloc: Option<ObjReloc>, pub reloc: Option<ObjReloc>,
pub fake_pool_reloc: Option<ObjReloc>,
pub branch_dest: Option<u64>, pub branch_dest: Option<u64>,
/// Line number /// Line number
pub line: Option<u32>, pub line: Option<u32>,

View File

@ -74,19 +74,6 @@ impl FunctionViewState {
} }
} }
fn find_symbol_matching_fake_symbol_in_sections(
fake_symbol: &ObjSymbol,
sections: &[ObjSection],
) -> Option<ObjSymbol> {
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( fn ins_hover_ui(
ui: &mut egui::Ui, ui: &mut egui::Ui,
obj: &ObjInfo, obj: &ObjInfo,
@ -131,30 +118,18 @@ fn ins_hover_ui(
} }
} }
if let Some(reloc) = ins.reloc.as_ref().or(ins.fake_pool_reloc.as_ref()) { if let Some(reloc) = &ins.reloc {
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))); ui.label(format!("Relocation type: {}", obj.arch.display_reloc(reloc.flags)));
let addend_str = match addend.cmp(&0i64) { let addend_str = match reloc.addend.cmp(&0i64) {
Ordering::Greater => format!("+{:x}", addend), Ordering::Greater => format!("+{:x}", reloc.addend),
Ordering::Less => format!("-{:x}", -addend), Ordering::Less => format!("-{:x}", -reloc.addend),
_ => "".to_string(), _ => "".to_string(),
}; };
ui.colored_label( ui.colored_label(
appearance.highlight_color, 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) = if let Some(section) =
obj.sections.iter().find(|s| s.orig_index == orig_section_index) obj.sections.iter().find(|s| s.orig_index == orig_section_index)
{ {
@ -165,12 +140,15 @@ fn ins_hover_ui(
} }
ui.colored_label( ui.colored_label(
appearance.highlight_color, 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)); ui.colored_label(
if addend >= 0 && target.bytes.len() > addend as usize { 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| { 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); ui.colored_label(appearance.highlight_color, s);
} }