mirror of https://github.com/encounter/objdiff.git
Compare commits
No commits in common. "dc46914428b86e9bb388c300556094b7f3afb2be" and "a51a5ac93f47b5f5211ba486df4fb5e039567ed5" have entirely different histories.
dc46914428
...
a51a5ac93f
|
@ -216,6 +216,7 @@ 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(),
|
||||||
|
|
|
@ -59,6 +59,7 @@ 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(),
|
||||||
|
@ -121,6 +122,7 @@ 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(),
|
||||||
|
|
|
@ -205,6 +205,7 @@ 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,
|
||||||
|
|
|
@ -150,7 +150,8 @@ impl ObjArch for ObjArchPpc {
|
||||||
size: 4,
|
size: 4,
|
||||||
mnemonic: Cow::Borrowed(simplified.mnemonic),
|
mnemonic: Cow::Borrowed(simplified.mnemonic),
|
||||||
args,
|
args,
|
||||||
reloc: reloc.or(fake_pool_reloc_for_addr.get(&cur_addr)).cloned(),
|
reloc: reloc.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,
|
||||||
|
@ -194,7 +195,12 @@ 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.reloc.as_ref().is_some_and(|r| r.target.name.starts_with("@stringBase")) {
|
if instruction
|
||||||
|
.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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -205,8 +211,10 @@ 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 not all strings are in the @stringBase pool, so the condition above that checks
|
// But there isn't much other choice as not all strings are in the @stringBase pool.
|
||||||
// the target symbol name would miss some.
|
// 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.
|
||||||
Some(DataType::String)
|
Some(DataType::String)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
|
|
@ -54,6 +54,7 @@ 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(),
|
||||||
|
@ -79,6 +80,7 @@ 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(),
|
||||||
|
|
|
@ -9,7 +9,7 @@ use crate::{
|
||||||
DiffObjConfig, ObjInsArgDiff, ObjInsBranchFrom, ObjInsBranchTo, ObjInsDiff, ObjInsDiffKind,
|
DiffObjConfig, ObjInsArgDiff, ObjInsBranchFrom, ObjInsBranchTo, ObjInsDiff, ObjInsDiffKind,
|
||||||
ObjSymbolDiff,
|
ObjSymbolDiff,
|
||||||
},
|
},
|
||||||
obj::{ObjInfo, ObjInsArg, ObjReloc, ObjSection, ObjSymbol, ObjSymbolFlags, SymbolRef},
|
obj::{ObjInfo, ObjInsArg, ObjReloc, ObjSymbolFlags, SymbolRef},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn process_code_symbol(
|
pub fn process_code_symbol(
|
||||||
|
@ -21,30 +21,14 @@ 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 = §ion.data
|
let code = §ion.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];
|
||||||
let mut res = obj.arch.process_code(
|
obj.arch.process_code(
|
||||||
symbol.address,
|
symbol.address,
|
||||||
code,
|
code,
|
||||||
section.orig_index,
|
section.orig_index,
|
||||||
§ion.relocations,
|
§ion.relocations,
|
||||||
§ion.line_info,
|
§ion.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> {
|
||||||
|
@ -385,16 +369,3 @@ 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())
|
|
||||||
}
|
|
||||||
|
|
|
@ -106,6 +106,7 @@ 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>,
|
||||||
|
|
|
@ -74,6 +74,19 @@ 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,
|
||||||
|
@ -118,18 +131,30 @@ fn ins_hover_ui(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(reloc) = &ins.reloc {
|
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)));
|
ui.label(format!("Relocation type: {}", obj.arch.display_reloc(reloc.flags)));
|
||||||
let addend_str = match reloc.addend.cmp(&0i64) {
|
let addend_str = match addend.cmp(&0i64) {
|
||||||
Ordering::Greater => format!("+{:x}", reloc.addend),
|
Ordering::Greater => format!("+{:x}", addend),
|
||||||
Ordering::Less => format!("-{:x}", -reloc.addend),
|
Ordering::Less => format!("-{:x}", -addend),
|
||||||
_ => "".to_string(),
|
_ => "".to_string(),
|
||||||
};
|
};
|
||||||
ui.colored_label(
|
ui.colored_label(
|
||||||
appearance.highlight_color,
|
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) =
|
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)
|
||||||
{
|
{
|
||||||
|
@ -140,15 +165,12 @@ fn ins_hover_ui(
|
||||||
}
|
}
|
||||||
ui.colored_label(
|
ui.colored_label(
|
||||||
appearance.highlight_color,
|
appearance.highlight_color,
|
||||||
format!("Address: {:x}{}", reloc.target.address, addend_str),
|
format!("Address: {:x}{}", target.address, addend_str),
|
||||||
);
|
);
|
||||||
ui.colored_label(
|
ui.colored_label(appearance.highlight_color, format!("Size: {:x}", target.size));
|
||||||
appearance.highlight_color,
|
if addend >= 0 && target.bytes.len() > addend as usize {
|
||||||
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, &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);
|
ui.colored_label(appearance.highlight_color, s);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue