Skip to content

Commit b7730b3

Browse files
authored
Refactor data relocation diffing to improve accuracy and fix bugs (#157)
* Data reloc hover tooltip: Show relocation source address * Refactor data relocation diffing to improve accuracy and fix bugs
1 parent a4fdb61 commit b7730b3

File tree

5 files changed

+160
-145
lines changed

5 files changed

+160
-145
lines changed

objdiff-core/src/bindings/diff.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ impl SectionDiff {
4242
let section = &obj.sections[section_index];
4343
let symbols = section_diff.symbols.iter().map(|d| SymbolDiff::new(obj, d)).collect();
4444
let data = section_diff.data_diff.iter().map(|d| DataDiff::new(obj, d)).collect();
45+
// TODO: section_diff.reloc_diff
4546
Self {
4647
name: section.name.to_string(),
4748
kind: SectionKind::from(section.kind) as i32,

objdiff-core/src/diff/data.rs

Lines changed: 52 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use similar::{capture_diff_slices_deadline, get_diff_ratio, Algorithm};
88

99
use super::code::section_name_eq;
1010
use crate::{
11-
diff::{ObjDataDiff, ObjDataDiffKind, ObjSectionDiff, ObjSymbolDiff},
11+
diff::{ObjDataDiff, ObjDataDiffKind, ObjDataRelocDiff, ObjSectionDiff, ObjSymbolDiff},
1212
obj::{ObjInfo, ObjReloc, ObjSection, ObjSymbolFlags, SymbolRef},
1313
};
1414

@@ -103,7 +103,7 @@ fn diff_data_relocs_for_range(
103103
let right_offset = r.address as usize - right_range.start;
104104
right_offset == left_offset
105105
}) else {
106-
diffs.push((ObjDataDiffKind::Replace, Some(left_reloc.clone()), None));
106+
diffs.push((ObjDataDiffKind::Delete, Some(left_reloc.clone()), None));
107107
continue;
108108
};
109109
if reloc_eq(left_obj, right_obj, left_reloc, right_reloc) {
@@ -132,7 +132,7 @@ fn diff_data_relocs_for_range(
132132
let left_offset = r.address as usize - left_range.start;
133133
left_offset == right_offset
134134
}) else {
135-
diffs.push((ObjDataDiffKind::Replace, None, Some(right_reloc.clone())));
135+
diffs.push((ObjDataDiffKind::Insert, None, Some(right_reloc.clone())));
136136
continue;
137137
};
138138
// No need to check the cases for relocations being deleted or matching again.
@@ -176,94 +176,6 @@ pub fn diff_data_section(
176176
ObjDataDiffKind::Replace
177177
}
178178
};
179-
if kind == ObjDataDiffKind::None {
180-
let mut found_any_relocs = false;
181-
let mut left_curr_addr = left_range.start;
182-
let mut right_curr_addr = right_range.start;
183-
for (diff_kind, left_reloc, right_reloc) in diff_data_relocs_for_range(
184-
left_obj,
185-
right_obj,
186-
left,
187-
right,
188-
left_range.clone(),
189-
right_range.clone(),
190-
) {
191-
found_any_relocs = true;
192-
193-
if let Some(left_reloc) = left_reloc {
194-
let left_reloc_addr = left_reloc.address as usize;
195-
if left_reloc_addr > left_curr_addr {
196-
let len = left_reloc_addr - left_curr_addr;
197-
let left_data = &left.data[left_curr_addr..left_reloc_addr];
198-
left_diff.push(ObjDataDiff {
199-
data: left_data[..min(len, left_data.len())].to_vec(),
200-
kind: ObjDataDiffKind::None,
201-
len,
202-
..Default::default()
203-
});
204-
}
205-
let reloc_diff_len = left_obj.arch.get_reloc_byte_size(left_reloc.flags);
206-
let left_data = &left.data[left_reloc_addr..left_reloc_addr + reloc_diff_len];
207-
left_diff.push(ObjDataDiff {
208-
data: left_data[..min(reloc_diff_len, left_data.len())].to_vec(),
209-
kind: diff_kind,
210-
len: reloc_diff_len,
211-
reloc: Some(left_reloc.clone()),
212-
..Default::default()
213-
});
214-
left_curr_addr = left_reloc_addr + reloc_diff_len;
215-
}
216-
217-
if let Some(right_reloc) = right_reloc {
218-
let right_reloc_addr = right_reloc.address as usize;
219-
if right_reloc_addr > right_curr_addr {
220-
let len = right_reloc_addr - right_curr_addr;
221-
let right_data = &right.data[right_curr_addr..right_reloc_addr];
222-
right_diff.push(ObjDataDiff {
223-
data: right_data[..min(len, right_data.len())].to_vec(),
224-
kind: ObjDataDiffKind::None,
225-
len,
226-
..Default::default()
227-
});
228-
}
229-
let reloc_diff_len = right_obj.arch.get_reloc_byte_size(right_reloc.flags);
230-
let right_data =
231-
&right.data[right_reloc_addr..right_reloc_addr + reloc_diff_len];
232-
right_diff.push(ObjDataDiff {
233-
data: right_data[..min(reloc_diff_len, right_data.len())].to_vec(),
234-
kind: diff_kind,
235-
len: reloc_diff_len,
236-
reloc: Some(right_reloc.clone()),
237-
..Default::default()
238-
});
239-
right_curr_addr = right_reloc_addr + reloc_diff_len;
240-
}
241-
}
242-
243-
if found_any_relocs {
244-
if left_curr_addr < left_range.end - 1 {
245-
let len = left_range.end - left_curr_addr;
246-
let left_data = &left.data[left_curr_addr..left_range.end];
247-
left_diff.push(ObjDataDiff {
248-
data: left_data[..min(len, left_data.len())].to_vec(),
249-
kind: ObjDataDiffKind::None,
250-
len,
251-
..Default::default()
252-
});
253-
}
254-
if right_curr_addr < right_range.end - 1 {
255-
let len = right_range.end - right_curr_addr;
256-
let right_data = &right.data[right_curr_addr..right_range.end];
257-
right_diff.push(ObjDataDiff {
258-
data: right_data[..min(len, right_data.len())].to_vec(),
259-
kind: ObjDataDiffKind::None,
260-
len,
261-
..Default::default()
262-
});
263-
}
264-
continue;
265-
}
266-
}
267179
let left_data = &left.data[left_range];
268180
let right_data = &right.data[right_range];
269181
left_diff.push(ObjDataDiff {
@@ -315,12 +227,35 @@ pub fn diff_data_section(
315227
}
316228
}
317229

230+
let mut left_reloc_diffs = Vec::new();
231+
let mut right_reloc_diffs = Vec::new();
232+
for (diff_kind, left_reloc, right_reloc) in diff_data_relocs_for_range(
233+
left_obj,
234+
right_obj,
235+
left,
236+
right,
237+
0..left_max as usize,
238+
0..right_max as usize,
239+
) {
240+
if let Some(left_reloc) = left_reloc {
241+
let len = left_obj.arch.get_reloc_byte_size(left_reloc.flags);
242+
let range = left_reloc.address as usize..left_reloc.address as usize + len;
243+
left_reloc_diffs.push(ObjDataRelocDiff { reloc: left_reloc, kind: diff_kind, range });
244+
}
245+
if let Some(right_reloc) = right_reloc {
246+
let len = right_obj.arch.get_reloc_byte_size(right_reloc.flags);
247+
let range = right_reloc.address as usize..right_reloc.address as usize + len;
248+
right_reloc_diffs.push(ObjDataRelocDiff { reloc: right_reloc, kind: diff_kind, range });
249+
}
250+
}
251+
318252
let (mut left_section_diff, mut right_section_diff) =
319253
diff_generic_section(left, right, left_section_diff, right_section_diff)?;
320-
let all_left_relocs_match =
321-
left_diff.iter().all(|d| d.kind == ObjDataDiffKind::None || d.reloc.is_none());
254+
let all_left_relocs_match = left_reloc_diffs.iter().all(|d| d.kind == ObjDataDiffKind::None);
322255
left_section_diff.data_diff = left_diff;
323256
right_section_diff.data_diff = right_diff;
257+
left_section_diff.reloc_diff = left_reloc_diffs;
258+
right_section_diff.reloc_diff = right_reloc_diffs;
324259
if all_left_relocs_match {
325260
// Use the highest match percent between two options:
326261
// - Left symbols matching right symbols by name
@@ -430,8 +365,18 @@ pub fn diff_generic_section(
430365
/ left.size as f32
431366
};
432367
Ok((
433-
ObjSectionDiff { symbols: vec![], data_diff: vec![], match_percent: Some(match_percent) },
434-
ObjSectionDiff { symbols: vec![], data_diff: vec![], match_percent: Some(match_percent) },
368+
ObjSectionDiff {
369+
symbols: vec![],
370+
data_diff: vec![],
371+
reloc_diff: vec![],
372+
match_percent: Some(match_percent),
373+
},
374+
ObjSectionDiff {
375+
symbols: vec![],
376+
data_diff: vec![],
377+
reloc_diff: vec![],
378+
match_percent: Some(match_percent),
379+
},
435380
))
436381
}
437382

@@ -456,7 +401,17 @@ pub fn diff_bss_section(
456401
}
457402

458403
Ok((
459-
ObjSectionDiff { symbols: vec![], data_diff: vec![], match_percent: Some(match_percent) },
460-
ObjSectionDiff { symbols: vec![], data_diff: vec![], match_percent: Some(match_percent) },
404+
ObjSectionDiff {
405+
symbols: vec![],
406+
data_diff: vec![],
407+
reloc_diff: vec![],
408+
match_percent: Some(match_percent),
409+
},
410+
ObjSectionDiff {
411+
symbols: vec![],
412+
data_diff: vec![],
413+
reloc_diff: vec![],
414+
match_percent: Some(match_percent),
415+
},
461416
))
462417
}

objdiff-core/src/diff/mod.rs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::collections::HashSet;
1+
use std::{collections::HashSet, ops::Range};
22

33
use anyhow::Result;
44

@@ -36,13 +36,15 @@ impl DiffObjConfig {
3636
pub struct ObjSectionDiff {
3737
pub symbols: Vec<ObjSymbolDiff>,
3838
pub data_diff: Vec<ObjDataDiff>,
39+
pub reloc_diff: Vec<ObjDataRelocDiff>,
3940
pub match_percent: Option<f32>,
4041
}
4142

4243
impl ObjSectionDiff {
4344
fn merge(&mut self, other: ObjSectionDiff) {
4445
// symbols ignored
4546
self.data_diff = other.data_diff;
47+
self.reloc_diff = other.reloc_diff;
4648
self.match_percent = other.match_percent;
4749
}
4850
}
@@ -87,7 +89,13 @@ pub struct ObjDataDiff {
8789
pub kind: ObjDataDiffKind,
8890
pub len: usize,
8991
pub symbol: String,
90-
pub reloc: Option<ObjReloc>,
92+
}
93+
94+
#[derive(Debug, Clone)]
95+
pub struct ObjDataRelocDiff {
96+
pub reloc: ObjReloc,
97+
pub kind: ObjDataDiffKind,
98+
pub range: Range<usize>,
9199
}
92100

93101
#[derive(Debug, Copy, Clone, Eq, PartialEq, Default)]
@@ -156,8 +164,8 @@ impl ObjDiff {
156164
kind: ObjDataDiffKind::None,
157165
len: section.data.len(),
158166
symbol: section.name.clone(),
159-
..Default::default()
160167
}],
168+
reloc_diff: vec![],
161169
match_percent: None,
162170
});
163171
}

objdiff-core/src/obj/mod.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ flags! {
2828
HasExtra,
2929
}
3030
}
31-
#[derive(Debug, Copy, Clone, Default)]
31+
#[derive(Debug, Copy, Clone, Default, PartialEq)]
3232
pub struct ObjSymbolFlagSet(pub FlagSet<ObjSymbolFlags>);
3333

3434
#[derive(Debug, Clone)]
@@ -132,7 +132,7 @@ pub enum ObjSymbolKind {
132132
Section,
133133
}
134134

135-
#[derive(Debug, Clone)]
135+
#[derive(Debug, Clone, PartialEq)]
136136
pub struct ObjSymbol {
137137
pub name: String,
138138
pub demangled_name: Option<String>,
@@ -161,7 +161,7 @@ pub struct ObjInfo {
161161
pub split_meta: Option<SplitMeta>,
162162
}
163163

164-
#[derive(Debug, Clone)]
164+
#[derive(Debug, Clone, PartialEq)]
165165
pub struct ObjReloc {
166166
pub flags: RelocationFlags,
167167
pub address: u64,

0 commit comments

Comments
 (0)