Option to relax relocation diffs

Ignores differences in relocation targets. (Address, name, etc)

Resolves #34
This commit is contained in:
Luke Street 2024-01-22 00:14:03 -07:00
parent 02f521a528
commit e88a58ba39
5 changed files with 40 additions and 9 deletions

View File

@ -110,6 +110,8 @@ pub struct AppConfig {
pub code_alg: DiffAlg, pub code_alg: DiffAlg,
#[serde(default)] #[serde(default)]
pub data_alg: DiffAlg, pub data_alg: DiffAlg,
#[serde(default)]
pub relax_reloc_diffs: bool,
#[serde(skip)] #[serde(skip)]
pub objects: Vec<ProjectObject>, pub objects: Vec<ProjectObject>,
@ -147,6 +149,7 @@ impl Default for AppConfig {
recent_projects: vec![], recent_projects: vec![],
code_alg: Default::default(), code_alg: Default::default(),
data_alg: Default::default(), data_alg: Default::default(),
relax_reloc_diffs: false,
objects: vec![], objects: vec![],
object_nodes: vec![], object_nodes: vec![],
watcher_change: false, watcher_change: false,
@ -492,6 +495,15 @@ impl eframe::App for App {
&mut diff_state.symbol_state.show_hidden_symbols, &mut diff_state.symbol_state.show_hidden_symbols,
"Show hidden symbols", "Show hidden symbols",
); );
if ui
.checkbox(&mut config.relax_reloc_diffs, "Relax relocation diffs")
.on_hover_text(
"Ignores differences in relocation targets. (Address, name, etc)",
)
.changed()
{
config.queue_reload = true;
}
}); });
}); });
}); });

View File

@ -10,7 +10,7 @@ use similar::{capture_diff_slices_deadline, Algorithm};
use crate::{ use crate::{
diff::{ diff::{
editops::{editops_find, LevEditType}, editops::{editops_find, LevEditType},
DiffAlg, ProcessCodeResult, DiffAlg, DiffObjConfig, ProcessCodeResult,
}, },
obj::{ obj::{
mips, ppc, ObjArchitecture, ObjInfo, ObjInsArg, ObjInsArgDiff, ObjInsBranchFrom, mips, ppc, ObjArchitecture, ObjInfo, ObjInsArg, ObjInsArgDiff, ObjInsBranchFrom,
@ -49,7 +49,7 @@ pub fn no_diff_code(
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
pub fn diff_code( pub fn diff_code(
alg: DiffAlg, config: &DiffObjConfig,
arch: ObjArchitecture, arch: ObjArchitecture,
left_data: &[u8], left_data: &[u8],
right_data: &[u8], right_data: &[u8],
@ -89,7 +89,7 @@ pub fn diff_code(
let mut left_diff = Vec::<ObjInsDiff>::new(); let mut left_diff = Vec::<ObjInsDiff>::new();
let mut right_diff = Vec::<ObjInsDiff>::new(); let mut right_diff = Vec::<ObjInsDiff>::new();
match alg { match config.code_alg {
DiffAlg::Levenshtein => { DiffAlg::Levenshtein => {
diff_instructions_lev( diff_instructions_lev(
&mut left_diff, &mut left_diff,
@ -134,7 +134,7 @@ pub fn diff_code(
let mut diff_state = InsDiffState::default(); let mut diff_state = InsDiffState::default();
for (left, right) in left_diff.iter_mut().zip(right_diff.iter_mut()) { for (left, right) in left_diff.iter_mut().zip(right_diff.iter_mut()) {
let result = compare_ins(left, right, &mut diff_state)?; let result = compare_ins(config, left, right, &mut diff_state)?;
left.kind = result.kind; left.kind = result.kind;
right.kind = result.kind; right.kind = result.kind;
left.arg_diff = result.left_args_diff; left.arg_diff = result.left_args_diff;
@ -322,13 +322,20 @@ fn address_eq(left: &ObjSymbol, right: &ObjSymbol) -> bool {
left.address as i64 + left.addend == right.address as i64 + right.addend left.address as i64 + left.addend == right.address as i64 + right.addend
} }
fn reloc_eq(left_reloc: Option<&ObjReloc>, right_reloc: Option<&ObjReloc>) -> bool { fn reloc_eq(
config: &DiffObjConfig,
left_reloc: Option<&ObjReloc>,
right_reloc: Option<&ObjReloc>,
) -> bool {
let (Some(left), Some(right)) = (left_reloc, right_reloc) else { let (Some(left), Some(right)) = (left_reloc, right_reloc) else {
return false; return false;
}; };
if left.kind != right.kind { if left.kind != right.kind {
return false; return false;
} }
if config.relax_reloc_diffs {
return true;
}
let name_matches = left.target.name == right.target.name; let name_matches = left.target.name == right.target.name;
match (&left.target_section, &right.target_section) { match (&left.target_section, &right.target_section) {
@ -346,6 +353,7 @@ fn reloc_eq(left_reloc: Option<&ObjReloc>, right_reloc: Option<&ObjReloc>) -> bo
} }
fn arg_eq( fn arg_eq(
config: &DiffObjConfig,
left: &ObjInsArg, left: &ObjInsArg,
right: &ObjInsArg, right: &ObjInsArg,
left_diff: &ObjInsDiff, left_diff: &ObjInsDiff,
@ -359,6 +367,7 @@ fn arg_eq(
ObjInsArg::Reloc => { ObjInsArg::Reloc => {
matches!(right, ObjInsArg::Reloc) matches!(right, ObjInsArg::Reloc)
&& reloc_eq( && reloc_eq(
config,
left_diff.ins.as_ref().and_then(|i| i.reloc.as_ref()), left_diff.ins.as_ref().and_then(|i| i.reloc.as_ref()),
right_diff.ins.as_ref().and_then(|i| i.reloc.as_ref()), right_diff.ins.as_ref().and_then(|i| i.reloc.as_ref()),
) )
@ -366,6 +375,7 @@ fn arg_eq(
ObjInsArg::RelocWithBase => { ObjInsArg::RelocWithBase => {
matches!(right, ObjInsArg::RelocWithBase) matches!(right, ObjInsArg::RelocWithBase)
&& reloc_eq( && reloc_eq(
config,
left_diff.ins.as_ref().and_then(|i| i.reloc.as_ref()), left_diff.ins.as_ref().and_then(|i| i.reloc.as_ref()),
right_diff.ins.as_ref().and_then(|i| i.reloc.as_ref()), right_diff.ins.as_ref().and_then(|i| i.reloc.as_ref()),
) )
@ -398,6 +408,7 @@ struct InsDiffResult {
} }
fn compare_ins( fn compare_ins(
config: &DiffObjConfig,
left: &ObjInsDiff, left: &ObjInsDiff,
right: &ObjInsDiff, right: &ObjInsDiff,
state: &mut InsDiffState, state: &mut InsDiffState,
@ -416,7 +427,7 @@ fn compare_ins(
state.diff_count += 1; state.diff_count += 1;
} }
for (a, b) in left_ins.args.iter().zip(&right_ins.args) { for (a, b) in left_ins.args.iter().zip(&right_ins.args) {
if arg_eq(a, b, left, right) { if arg_eq(config, a, b, left, right) {
result.left_args_diff.push(None); result.left_args_diff.push(None);
result.right_args_diff.push(None); result.right_args_diff.push(None);
} else { } else {

View File

@ -25,6 +25,7 @@ pub enum DiffAlg {
pub struct DiffObjConfig { pub struct DiffObjConfig {
pub code_alg: DiffAlg, pub code_alg: DiffAlg,
pub data_alg: DiffAlg, pub data_alg: DiffAlg,
pub relax_reloc_diffs: bool,
} }
pub struct ProcessCodeResult { pub struct ProcessCodeResult {
@ -51,7 +52,7 @@ pub fn diff_objs(
left_symbol.diff_symbol = Some(right_symbol.name.clone()); left_symbol.diff_symbol = Some(right_symbol.name.clone());
right_symbol.diff_symbol = Some(left_symbol.name.clone()); right_symbol.diff_symbol = Some(left_symbol.name.clone());
diff_code( diff_code(
config.code_alg, config,
left.architecture, left.architecture,
&left_section.data, &left_section.data,
&right_section.data, &right_section.data,

View File

@ -42,6 +42,7 @@ pub struct ObjDiffConfig {
pub selected_wsl_distro: Option<String>, pub selected_wsl_distro: Option<String>,
pub code_alg: DiffAlg, pub code_alg: DiffAlg,
pub data_alg: DiffAlg, pub data_alg: DiffAlg,
pub relax_reloc_diffs: bool,
} }
impl ObjDiffConfig { impl ObjDiffConfig {
@ -55,6 +56,7 @@ impl ObjDiffConfig {
selected_wsl_distro: config.selected_wsl_distro.clone(), selected_wsl_distro: config.selected_wsl_distro.clone(),
code_alg: config.code_alg, code_alg: config.code_alg,
data_alg: config.data_alg, data_alg: config.data_alg,
relax_reloc_diffs: config.relax_reloc_diffs,
} }
} }
} }
@ -225,7 +227,11 @@ fn run_build(
}; };
update_status(context, "Performing diff".to_string(), 4, total, &cancel)?; update_status(context, "Performing diff".to_string(), 4, total, &cancel)?;
let diff_config = DiffObjConfig { code_alg: config.code_alg, data_alg: config.data_alg }; let diff_config = DiffObjConfig {
code_alg: config.code_alg,
data_alg: config.data_alg,
relax_reloc_diffs: config.relax_reloc_diffs,
};
diff_objs(&diff_config, first_obj.as_mut(), second_obj.as_mut())?; diff_objs(&diff_config, first_obj.as_mut(), second_obj.as_mut())?;
update_status(context, "Complete".to_string(), total, total, &cancel)?; update_status(context, "Complete".to_string(), total, total, &cancel)?;

View File

@ -1,7 +1,7 @@
use std::mem::take; use std::mem::take;
use egui::{ use egui::{
text::LayoutJob, Align, CollapsingHeader, Color32, Layout, ScrollArea, SelectableLabel, text::LayoutJob, Align, CollapsingHeader, Color32, Id, Layout, ScrollArea, SelectableLabel,
TextEdit, Ui, Vec2, Widget, TextEdit, Ui, Vec2, Widget,
}; };
use egui_extras::{Size, StripBuilder}; use egui_extras::{Size, StripBuilder};
@ -234,6 +234,7 @@ fn symbol_list_ui(
for section in &obj.sections { for section in &obj.sections {
CollapsingHeader::new(format!("{} ({:x})", section.name, section.size)) CollapsingHeader::new(format!("{} ({:x})", section.name, section.size))
.id_source(Id::new(section.name.clone()).with(section.index))
.default_open(true) .default_open(true)
.show(ui, |ui| { .show(ui, |ui| {
if section.kind == ObjSectionKind::Code && state.reverse_fn_order { if section.kind == ObjSectionKind::Code && state.reverse_fn_order {