Skip to content

Commit e254af5

Browse files
committed
Support bss and text section diffing
Display section diff % in symbols view
1 parent 320efcb commit e254af5

File tree

3 files changed

+94
-8
lines changed

3 files changed

+94
-8
lines changed

objdiff-core/src/diff/data.rs

Lines changed: 50 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,27 @@ use crate::{
1111
obj::{ObjInfo, ObjSection, SymbolRef},
1212
};
1313

14+
/// Compare the addresses and sizes of each symbol in the BSS sections.
15+
pub fn diff_bss_section(
16+
left: &ObjSection,
17+
right: &ObjSection,
18+
) -> Result<(ObjSectionDiff, ObjSectionDiff)> {
19+
let deadline = Instant::now() + Duration::from_secs(5);
20+
let left_sizes = left.symbols.iter().map(|s| (s.section_address, s.size)).collect::<Vec<_>>();
21+
let right_sizes = right.symbols.iter().map(|s| (s.section_address, s.size)).collect::<Vec<_>>();
22+
let ops = capture_diff_slices_deadline(
23+
Algorithm::Patience,
24+
&left_sizes,
25+
&right_sizes,
26+
Some(deadline),
27+
);
28+
let match_percent = get_diff_ratio(&ops, left_sizes.len(), right_sizes.len()) * 100.0;
29+
Ok((
30+
ObjSectionDiff { symbols: vec![], data_diff: vec![], match_percent: Some(match_percent) },
31+
ObjSectionDiff { symbols: vec![], data_diff: vec![], match_percent: Some(match_percent) },
32+
))
33+
}
34+
1435
pub fn diff_bss_symbol(
1536
left_obj: &ObjInfo,
1637
right_obj: &ObjInfo,
@@ -40,14 +61,19 @@ pub fn no_diff_symbol(_obj: &ObjInfo, symbol_ref: SymbolRef) -> ObjSymbolDiff {
4061
ObjSymbolDiff { symbol_ref, diff_symbol: None, instructions: vec![], match_percent: None }
4162
}
4263

43-
pub fn diff_data(
64+
/// Compare the data sections of two object files.
65+
pub fn diff_data_section(
4466
left: &ObjSection,
4567
right: &ObjSection,
4668
) -> Result<(ObjSectionDiff, ObjSectionDiff)> {
4769
let deadline = Instant::now() + Duration::from_secs(5);
70+
let left_max = left.symbols.iter().map(|s| s.section_address + s.size).max().unwrap_or(0);
71+
let right_max = right.symbols.iter().map(|s| s.section_address + s.size).max().unwrap_or(0);
72+
let left_data = &left.data[..left_max as usize];
73+
let right_data = &right.data[..right_max as usize];
4874
let ops =
49-
capture_diff_slices_deadline(Algorithm::Patience, &left.data, &right.data, Some(deadline));
50-
let match_percent = get_diff_ratio(&ops, left.data.len(), right.data.len()) * 100.0;
75+
capture_diff_slices_deadline(Algorithm::Patience, left_data, right_data, Some(deadline));
76+
let match_percent = get_diff_ratio(&ops, left_data.len(), right_data.len()) * 100.0;
5177

5278
let mut left_diff = Vec::<ObjDataDiff>::new();
5379
let mut right_diff = Vec::<ObjDataDiff>::new();
@@ -168,3 +194,24 @@ pub fn diff_data_symbol(
168194
},
169195
))
170196
}
197+
198+
/// Compare the text sections of two object files.
199+
/// This essentially adds up the match percentage of each symbol in the text section.
200+
pub fn diff_text_section(
201+
left: &ObjSection,
202+
_right: &ObjSection,
203+
left_diff: &ObjSectionDiff,
204+
_right_diff: &ObjSectionDiff,
205+
) -> Result<(ObjSectionDiff, ObjSectionDiff)> {
206+
let match_percent = left
207+
.symbols
208+
.iter()
209+
.zip(left_diff.symbols.iter())
210+
.map(|(s, d)| d.match_percent.unwrap_or(0.0) * s.size as f32)
211+
.sum::<f32>()
212+
/ left.size as f32;
213+
Ok((
214+
ObjSectionDiff { symbols: vec![], data_diff: vec![], match_percent: Some(match_percent) },
215+
ObjSectionDiff { symbols: vec![], data_diff: vec![], match_percent: Some(match_percent) },
216+
))
217+
}

objdiff-core/src/diff/mod.rs

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@ use anyhow::Result;
55
use crate::{
66
diff::{
77
code::{diff_code, no_diff_code},
8-
data::{diff_bss_symbol, diff_data, diff_data_symbol, no_diff_symbol},
8+
data::{
9+
diff_bss_section, diff_bss_symbol, diff_data_section, diff_data_symbol,
10+
diff_text_section, no_diff_symbol,
11+
},
912
},
1013
obj::{ObjInfo, ObjIns, ObjSection, ObjSectionKind, ObjSymbol, SymbolRef},
1114
};
@@ -324,15 +327,26 @@ pub fn diff_objs(
324327
let right_section = &right_obj.sections[right_section_idx];
325328
match section_kind {
326329
ObjSectionKind::Code => {
327-
// TODO?
330+
let left_section_diff = left_out.section_diff(left_section_idx);
331+
let right_section_diff = right_out.section_diff(right_section_idx);
332+
let (left_diff, right_diff) = diff_text_section(
333+
left_section,
334+
right_section,
335+
left_section_diff,
336+
right_section_diff,
337+
)?;
338+
left_out.section_diff_mut(left_section_idx).merge(left_diff);
339+
right_out.section_diff_mut(right_section_idx).merge(right_diff);
328340
}
329341
ObjSectionKind::Data => {
330-
let (left_diff, right_diff) = diff_data(left_section, right_section)?;
342+
let (left_diff, right_diff) = diff_data_section(left_section, right_section)?;
331343
left_out.section_diff_mut(left_section_idx).merge(left_diff);
332344
right_out.section_diff_mut(right_section_idx).merge(right_diff);
333345
}
334346
ObjSectionKind::Bss => {
335-
// TODO
347+
let (left_diff, right_diff) = diff_bss_section(left_section, right_section)?;
348+
left_out.section_diff_mut(left_section_idx).merge(left_diff);
349+
right_out.section_diff_mut(right_section_idx).merge(right_diff);
336350
}
337351
}
338352
}

objdiff-gui/src/views/symbol_diff.rs

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,32 @@ fn symbol_list_ui(
303303
}
304304

305305
for (section, section_diff) in obj.0.sections.iter().zip(&obj.1.sections) {
306-
CollapsingHeader::new(format!("{} ({:x})", section.name, section.size))
306+
let mut header = LayoutJob::simple_singleline(
307+
format!("{} ({:x})", section.name, section.size),
308+
appearance.code_font.clone(),
309+
Color32::PLACEHOLDER,
310+
);
311+
if let Some(match_percent) = section_diff.match_percent {
312+
write_text(
313+
" (",
314+
Color32::PLACEHOLDER,
315+
&mut header,
316+
appearance.code_font.clone(),
317+
);
318+
write_text(
319+
&format!("{match_percent:.0}%"),
320+
match_color_for_symbol(match_percent, appearance),
321+
&mut header,
322+
appearance.code_font.clone(),
323+
);
324+
write_text(
325+
")",
326+
Color32::PLACEHOLDER,
327+
&mut header,
328+
appearance.code_font.clone(),
329+
);
330+
}
331+
CollapsingHeader::new(header)
307332
.id_source(Id::new(section.name.clone()).with(section.orig_index))
308333
.default_open(true)
309334
.show(ui, |ui| {

0 commit comments

Comments
 (0)