mirror of https://github.com/encounter/objdiff.git
Option to relax relocation diffs
Ignores differences in relocation targets. (Address, name, etc) Resolves #34
This commit is contained in:
parent
02f521a528
commit
e88a58ba39
12
src/app.rs
12
src/app.rs
|
@ -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;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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)?;
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
Loading…
Reference in New Issue