2023-11-21 11:48:18 -05:00
|
|
|
use std::{
|
|
|
|
|
cmp::{max, min, Ordering},
|
|
|
|
|
time::{Duration, Instant},
|
|
|
|
|
};
|
|
|
|
|
|
2024-02-27 21:18:42 -07:00
|
|
|
use anyhow::Result;
|
2023-11-21 11:48:18 -05:00
|
|
|
use similar::{capture_diff_slices_deadline, Algorithm};
|
|
|
|
|
|
2024-03-18 18:10:18 -06:00
|
|
|
use crate::{
|
|
|
|
|
diff::{get_symbol, ObjDataDiff, ObjDataDiffKind, ObjSectionDiff, ObjSymbolDiff, SymbolRef},
|
|
|
|
|
obj::{ObjInfo, ObjSection},
|
|
|
|
|
};
|
2023-11-21 11:48:18 -05:00
|
|
|
|
2024-03-18 18:10:18 -06:00
|
|
|
pub fn diff_bss_symbol(
|
|
|
|
|
left_obj: &ObjInfo,
|
|
|
|
|
right_obj: &ObjInfo,
|
|
|
|
|
left_symbol_ref: SymbolRef,
|
|
|
|
|
right_symbol_ref: SymbolRef,
|
|
|
|
|
) -> Result<(ObjSymbolDiff, ObjSymbolDiff)> {
|
|
|
|
|
let (_, left_symbol) = get_symbol(left_obj, left_symbol_ref);
|
|
|
|
|
let (_, right_symbol) = get_symbol(right_obj, right_symbol_ref);
|
|
|
|
|
let percent = if left_symbol.size == right_symbol.size { 100.0 } else { 50.0 };
|
|
|
|
|
Ok((
|
|
|
|
|
ObjSymbolDiff {
|
|
|
|
|
diff_symbol: Some(right_symbol_ref),
|
|
|
|
|
instructions: vec![],
|
|
|
|
|
match_percent: Some(percent),
|
|
|
|
|
},
|
|
|
|
|
ObjSymbolDiff {
|
|
|
|
|
diff_symbol: Some(left_symbol_ref),
|
|
|
|
|
instructions: vec![],
|
|
|
|
|
match_percent: Some(percent),
|
|
|
|
|
},
|
|
|
|
|
))
|
2023-11-21 11:48:18 -05:00
|
|
|
}
|
|
|
|
|
|
2024-03-18 18:10:18 -06:00
|
|
|
pub fn no_diff_bss_symbol(_obj: &ObjInfo, _symbol_ref: SymbolRef) -> ObjSymbolDiff {
|
|
|
|
|
ObjSymbolDiff { diff_symbol: None, instructions: vec![], match_percent: Some(0.0) }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn diff_data(
|
|
|
|
|
left: &ObjSection,
|
|
|
|
|
right: &ObjSection,
|
|
|
|
|
) -> Result<(ObjSectionDiff, ObjSectionDiff)> {
|
2023-11-21 11:48:18 -05:00
|
|
|
let deadline = Instant::now() + Duration::from_secs(5);
|
2024-02-27 21:18:42 -07:00
|
|
|
let ops =
|
|
|
|
|
capture_diff_slices_deadline(Algorithm::Patience, &left.data, &right.data, Some(deadline));
|
2023-11-21 11:48:18 -05:00
|
|
|
|
|
|
|
|
let mut left_diff = Vec::<ObjDataDiff>::new();
|
|
|
|
|
let mut right_diff = Vec::<ObjDataDiff>::new();
|
|
|
|
|
for op in ops {
|
|
|
|
|
let (tag, left_range, right_range) = op.as_tag_tuple();
|
|
|
|
|
let left_len = left_range.len();
|
|
|
|
|
let right_len = right_range.len();
|
|
|
|
|
let mut len = max(left_len, right_len);
|
|
|
|
|
let kind = match tag {
|
|
|
|
|
similar::DiffTag::Equal => ObjDataDiffKind::None,
|
|
|
|
|
similar::DiffTag::Delete => ObjDataDiffKind::Delete,
|
|
|
|
|
similar::DiffTag::Insert => ObjDataDiffKind::Insert,
|
|
|
|
|
similar::DiffTag::Replace => {
|
|
|
|
|
// Ensure replacements are equal length
|
|
|
|
|
len = min(left_len, right_len);
|
|
|
|
|
ObjDataDiffKind::Replace
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
let left_data = &left.data[left_range];
|
|
|
|
|
let right_data = &right.data[right_range];
|
|
|
|
|
left_diff.push(ObjDataDiff {
|
|
|
|
|
data: left_data[..min(len, left_data.len())].to_vec(),
|
|
|
|
|
kind,
|
|
|
|
|
len,
|
|
|
|
|
..Default::default()
|
|
|
|
|
});
|
|
|
|
|
right_diff.push(ObjDataDiff {
|
|
|
|
|
data: right_data[..min(len, right_data.len())].to_vec(),
|
|
|
|
|
kind,
|
|
|
|
|
len,
|
|
|
|
|
..Default::default()
|
|
|
|
|
});
|
|
|
|
|
if kind == ObjDataDiffKind::Replace {
|
|
|
|
|
match left_len.cmp(&right_len) {
|
|
|
|
|
Ordering::Less => {
|
|
|
|
|
let len = right_len - left_len;
|
|
|
|
|
left_diff.push(ObjDataDiff {
|
|
|
|
|
data: vec![],
|
|
|
|
|
kind: ObjDataDiffKind::Insert,
|
|
|
|
|
len,
|
|
|
|
|
..Default::default()
|
|
|
|
|
});
|
|
|
|
|
right_diff.push(ObjDataDiff {
|
|
|
|
|
data: right_data[left_len..right_len].to_vec(),
|
|
|
|
|
kind: ObjDataDiffKind::Insert,
|
|
|
|
|
len,
|
|
|
|
|
..Default::default()
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
Ordering::Greater => {
|
|
|
|
|
let len = left_len - right_len;
|
|
|
|
|
left_diff.push(ObjDataDiff {
|
|
|
|
|
data: left_data[right_len..left_len].to_vec(),
|
|
|
|
|
kind: ObjDataDiffKind::Delete,
|
|
|
|
|
len,
|
|
|
|
|
..Default::default()
|
|
|
|
|
});
|
|
|
|
|
right_diff.push(ObjDataDiff {
|
|
|
|
|
data: vec![],
|
|
|
|
|
kind: ObjDataDiffKind::Delete,
|
|
|
|
|
len,
|
|
|
|
|
..Default::default()
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
Ordering::Equal => {}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-18 18:10:18 -06:00
|
|
|
Ok((
|
|
|
|
|
ObjSectionDiff {
|
|
|
|
|
symbols: vec![],
|
|
|
|
|
data_diff: left_diff,
|
|
|
|
|
// TODO
|
|
|
|
|
match_percent: None,
|
|
|
|
|
},
|
|
|
|
|
ObjSectionDiff {
|
|
|
|
|
symbols: vec![],
|
|
|
|
|
data_diff: right_diff,
|
|
|
|
|
// TODO
|
|
|
|
|
match_percent: None,
|
|
|
|
|
},
|
|
|
|
|
))
|
2023-11-21 11:48:18 -05:00
|
|
|
}
|