Skip to content

Commit e88a58b

Browse files
committed
Option to relax relocation diffs
Ignores differences in relocation targets. (Address, name, etc) Resolves #34
1 parent 02f521a commit e88a58b

File tree

5 files changed

+40
-9
lines changed

5 files changed

+40
-9
lines changed

src/app.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,8 @@ pub struct AppConfig {
110110
pub code_alg: DiffAlg,
111111
#[serde(default)]
112112
pub data_alg: DiffAlg,
113+
#[serde(default)]
114+
pub relax_reloc_diffs: bool,
113115

114116
#[serde(skip)]
115117
pub objects: Vec<ProjectObject>,
@@ -147,6 +149,7 @@ impl Default for AppConfig {
147149
recent_projects: vec![],
148150
code_alg: Default::default(),
149151
data_alg: Default::default(),
152+
relax_reloc_diffs: false,
150153
objects: vec![],
151154
object_nodes: vec![],
152155
watcher_change: false,
@@ -492,6 +495,15 @@ impl eframe::App for App {
492495
&mut diff_state.symbol_state.show_hidden_symbols,
493496
"Show hidden symbols",
494497
);
498+
if ui
499+
.checkbox(&mut config.relax_reloc_diffs, "Relax relocation diffs")
500+
.on_hover_text(
501+
"Ignores differences in relocation targets. (Address, name, etc)",
502+
)
503+
.changed()
504+
{
505+
config.queue_reload = true;
506+
}
495507
});
496508
});
497509
});

src/diff/code.rs

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use similar::{capture_diff_slices_deadline, Algorithm};
1010
use crate::{
1111
diff::{
1212
editops::{editops_find, LevEditType},
13-
DiffAlg, ProcessCodeResult,
13+
DiffAlg, DiffObjConfig, ProcessCodeResult,
1414
},
1515
obj::{
1616
mips, ppc, ObjArchitecture, ObjInfo, ObjInsArg, ObjInsArgDiff, ObjInsBranchFrom,
@@ -49,7 +49,7 @@ pub fn no_diff_code(
4949

5050
#[allow(clippy::too_many_arguments)]
5151
pub fn diff_code(
52-
alg: DiffAlg,
52+
config: &DiffObjConfig,
5353
arch: ObjArchitecture,
5454
left_data: &[u8],
5555
right_data: &[u8],
@@ -89,7 +89,7 @@ pub fn diff_code(
8989

9090
let mut left_diff = Vec::<ObjInsDiff>::new();
9191
let mut right_diff = Vec::<ObjInsDiff>::new();
92-
match alg {
92+
match config.code_alg {
9393
DiffAlg::Levenshtein => {
9494
diff_instructions_lev(
9595
&mut left_diff,
@@ -134,7 +134,7 @@ pub fn diff_code(
134134

135135
let mut diff_state = InsDiffState::default();
136136
for (left, right) in left_diff.iter_mut().zip(right_diff.iter_mut()) {
137-
let result = compare_ins(left, right, &mut diff_state)?;
137+
let result = compare_ins(config, left, right, &mut diff_state)?;
138138
left.kind = result.kind;
139139
right.kind = result.kind;
140140
left.arg_diff = result.left_args_diff;
@@ -322,13 +322,20 @@ fn address_eq(left: &ObjSymbol, right: &ObjSymbol) -> bool {
322322
left.address as i64 + left.addend == right.address as i64 + right.addend
323323
}
324324

325-
fn reloc_eq(left_reloc: Option<&ObjReloc>, right_reloc: Option<&ObjReloc>) -> bool {
325+
fn reloc_eq(
326+
config: &DiffObjConfig,
327+
left_reloc: Option<&ObjReloc>,
328+
right_reloc: Option<&ObjReloc>,
329+
) -> bool {
326330
let (Some(left), Some(right)) = (left_reloc, right_reloc) else {
327331
return false;
328332
};
329333
if left.kind != right.kind {
330334
return false;
331335
}
336+
if config.relax_reloc_diffs {
337+
return true;
338+
}
332339

333340
let name_matches = left.target.name == right.target.name;
334341
match (&left.target_section, &right.target_section) {
@@ -346,6 +353,7 @@ fn reloc_eq(left_reloc: Option<&ObjReloc>, right_reloc: Option<&ObjReloc>) -> bo
346353
}
347354

348355
fn arg_eq(
356+
config: &DiffObjConfig,
349357
left: &ObjInsArg,
350358
right: &ObjInsArg,
351359
left_diff: &ObjInsDiff,
@@ -359,13 +367,15 @@ fn arg_eq(
359367
ObjInsArg::Reloc => {
360368
matches!(right, ObjInsArg::Reloc)
361369
&& reloc_eq(
370+
config,
362371
left_diff.ins.as_ref().and_then(|i| i.reloc.as_ref()),
363372
right_diff.ins.as_ref().and_then(|i| i.reloc.as_ref()),
364373
)
365374
}
366375
ObjInsArg::RelocWithBase => {
367376
matches!(right, ObjInsArg::RelocWithBase)
368377
&& reloc_eq(
378+
config,
369379
left_diff.ins.as_ref().and_then(|i| i.reloc.as_ref()),
370380
right_diff.ins.as_ref().and_then(|i| i.reloc.as_ref()),
371381
)
@@ -398,6 +408,7 @@ struct InsDiffResult {
398408
}
399409

400410
fn compare_ins(
411+
config: &DiffObjConfig,
401412
left: &ObjInsDiff,
402413
right: &ObjInsDiff,
403414
state: &mut InsDiffState,
@@ -416,7 +427,7 @@ fn compare_ins(
416427
state.diff_count += 1;
417428
}
418429
for (a, b) in left_ins.args.iter().zip(&right_ins.args) {
419-
if arg_eq(a, b, left, right) {
430+
if arg_eq(config, a, b, left, right) {
420431
result.left_args_diff.push(None);
421432
result.right_args_diff.push(None);
422433
} else {

src/diff/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ pub enum DiffAlg {
2525
pub struct DiffObjConfig {
2626
pub code_alg: DiffAlg,
2727
pub data_alg: DiffAlg,
28+
pub relax_reloc_diffs: bool,
2829
}
2930

3031
pub struct ProcessCodeResult {
@@ -51,7 +52,7 @@ pub fn diff_objs(
5152
left_symbol.diff_symbol = Some(right_symbol.name.clone());
5253
right_symbol.diff_symbol = Some(left_symbol.name.clone());
5354
diff_code(
54-
config.code_alg,
55+
config,
5556
left.architecture,
5657
&left_section.data,
5758
&right_section.data,

src/jobs/objdiff.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ pub struct ObjDiffConfig {
4242
pub selected_wsl_distro: Option<String>,
4343
pub code_alg: DiffAlg,
4444
pub data_alg: DiffAlg,
45+
pub relax_reloc_diffs: bool,
4546
}
4647

4748
impl ObjDiffConfig {
@@ -55,6 +56,7 @@ impl ObjDiffConfig {
5556
selected_wsl_distro: config.selected_wsl_distro.clone(),
5657
code_alg: config.code_alg,
5758
data_alg: config.data_alg,
59+
relax_reloc_diffs: config.relax_reloc_diffs,
5860
}
5961
}
6062
}
@@ -225,7 +227,11 @@ fn run_build(
225227
};
226228

227229
update_status(context, "Performing diff".to_string(), 4, total, &cancel)?;
228-
let diff_config = DiffObjConfig { code_alg: config.code_alg, data_alg: config.data_alg };
230+
let diff_config = DiffObjConfig {
231+
code_alg: config.code_alg,
232+
data_alg: config.data_alg,
233+
relax_reloc_diffs: config.relax_reloc_diffs,
234+
};
229235
diff_objs(&diff_config, first_obj.as_mut(), second_obj.as_mut())?;
230236

231237
update_status(context, "Complete".to_string(), total, total, &cancel)?;

src/views/symbol_diff.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use std::mem::take;
22

33
use egui::{
4-
text::LayoutJob, Align, CollapsingHeader, Color32, Layout, ScrollArea, SelectableLabel,
4+
text::LayoutJob, Align, CollapsingHeader, Color32, Id, Layout, ScrollArea, SelectableLabel,
55
TextEdit, Ui, Vec2, Widget,
66
};
77
use egui_extras::{Size, StripBuilder};
@@ -234,6 +234,7 @@ fn symbol_list_ui(
234234

235235
for section in &obj.sections {
236236
CollapsingHeader::new(format!("{} ({:x})", section.name, section.size))
237+
.id_source(Id::new(section.name.clone()).with(section.index))
237238
.default_open(true)
238239
.show(ui, |ui| {
239240
if section.kind == ObjSectionKind::Code && state.reverse_fn_order {

0 commit comments

Comments
 (0)