mirror of https://github.com/encounter/objdiff.git
Diff cleanup & fixes
This commit is contained in:
parent
3c74b89f15
commit
4dfc28fc68
|
@ -18,10 +18,10 @@ use objdiff_core::{
|
||||||
diff,
|
diff,
|
||||||
diff::{
|
diff::{
|
||||||
display::{display_diff, DiffText, HighlightKind},
|
display::{display_diff, DiffText, HighlightKind},
|
||||||
DiffObjsResult, ObjDiff, ObjInsDiffKind, ObjSymbolDiff, SymbolRef,
|
DiffObjsResult, ObjDiff, ObjInsDiffKind, ObjSymbolDiff,
|
||||||
},
|
},
|
||||||
obj,
|
obj,
|
||||||
obj::{ObjInfo, ObjSectionKind, ObjSymbol},
|
obj::{ObjInfo, ObjSectionKind, ObjSymbol, SymbolRef},
|
||||||
};
|
};
|
||||||
use ratatui::{
|
use ratatui::{
|
||||||
prelude::*,
|
prelude::*,
|
||||||
|
@ -221,20 +221,14 @@ pub fn run(args: Args) -> Result<()> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn get_symbol(obj: Option<&ObjInfo>, sym: Option<SymbolRef>) -> Option<&ObjSymbol> {
|
fn get_symbol(obj: Option<&ObjInfo>, sym: Option<SymbolRef>) -> Option<&ObjSymbol> {
|
||||||
if let (Some(obj), Some(sym)) = (obj, sym) {
|
Some(obj?.section_symbol(sym?).1)
|
||||||
obj.sections.get(sym.section_idx).and_then(|s| s.symbols.get(sym.symbol_idx))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_diff_symbol(obj: Option<&ObjDiff>, sym: Option<SymbolRef>) -> Option<&ObjSymbolDiff> {
|
#[inline]
|
||||||
if let (Some(obj), Some(sym)) = (obj, sym) {
|
fn get_symbol_diff(obj: Option<&ObjDiff>, sym: Option<SymbolRef>) -> Option<&ObjSymbolDiff> {
|
||||||
Some(obj.symbol_diff(sym))
|
Some(obj?.symbol_diff(sym?))
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_function(obj: &ObjInfo, name: &str) -> Option<SymbolRef> {
|
fn find_function(obj: &ObjInfo, name: &str) -> Option<SymbolRef> {
|
||||||
|
@ -336,7 +330,7 @@ impl FunctionDiffUi {
|
||||||
f.render_widget(line_l, header_chunks[0]);
|
f.render_widget(line_l, header_chunks[0]);
|
||||||
|
|
||||||
let mut line_r = Line::default();
|
let mut line_r = Line::default();
|
||||||
if let Some(percent) = get_diff_symbol(self.diff_result.right.as_ref(), self.right_sym)
|
if let Some(percent) = get_symbol_diff(self.diff_result.right.as_ref(), self.right_sym)
|
||||||
.and_then(|s| s.match_percent)
|
.and_then(|s| s.match_percent)
|
||||||
{
|
{
|
||||||
line_r.spans.push(Span::styled(
|
line_r.spans.push(Span::styled(
|
||||||
|
@ -360,7 +354,7 @@ impl FunctionDiffUi {
|
||||||
let mut max_width = 0;
|
let mut max_width = 0;
|
||||||
if let (Some(symbol), Some(symbol_diff)) = (
|
if let (Some(symbol), Some(symbol_diff)) = (
|
||||||
get_symbol(self.left_obj.as_ref(), self.left_sym),
|
get_symbol(self.left_obj.as_ref(), self.left_sym),
|
||||||
get_diff_symbol(self.diff_result.left.as_ref(), self.left_sym),
|
get_symbol_diff(self.diff_result.left.as_ref(), self.left_sym),
|
||||||
) {
|
) {
|
||||||
let mut text = Text::default();
|
let mut text = Text::default();
|
||||||
let rect = content_chunks[0].inner(&Margin::new(0, 1));
|
let rect = content_chunks[0].inner(&Margin::new(0, 1));
|
||||||
|
@ -382,7 +376,7 @@ impl FunctionDiffUi {
|
||||||
let mut margin_text = None;
|
let mut margin_text = None;
|
||||||
if let (Some(symbol), Some(symbol_diff)) = (
|
if let (Some(symbol), Some(symbol_diff)) = (
|
||||||
get_symbol(self.right_obj.as_ref(), self.right_sym),
|
get_symbol(self.right_obj.as_ref(), self.right_sym),
|
||||||
get_diff_symbol(self.diff_result.right.as_ref(), self.right_sym),
|
get_symbol_diff(self.diff_result.right.as_ref(), self.right_sym),
|
||||||
) {
|
) {
|
||||||
let mut text = Text::default();
|
let mut text = Text::default();
|
||||||
let rect = content_chunks[2].inner(&Margin::new(0, 1));
|
let rect = content_chunks[2].inner(&Margin::new(0, 1));
|
||||||
|
@ -410,7 +404,7 @@ impl FunctionDiffUi {
|
||||||
if self.three_way {
|
if self.three_way {
|
||||||
if let (Some(symbol), Some(symbol_diff)) = (
|
if let (Some(symbol), Some(symbol_diff)) = (
|
||||||
get_symbol(self.prev_obj.as_ref(), self.prev_sym),
|
get_symbol(self.prev_obj.as_ref(), self.prev_sym),
|
||||||
get_diff_symbol(self.diff_result.prev.as_ref(), self.prev_sym),
|
get_symbol_diff(self.diff_result.prev.as_ref(), self.prev_sym),
|
||||||
) {
|
) {
|
||||||
let mut text = Text::default();
|
let mut text = Text::default();
|
||||||
let rect = content_chunks[4].inner(&Margin::new(0, 1));
|
let rect = content_chunks[4].inner(&Margin::new(0, 1));
|
||||||
|
@ -838,8 +832,8 @@ impl FunctionDiffUi {
|
||||||
let right_sym = base.as_ref().and_then(|o| find_function(o, &self.symbol_name));
|
let right_sym = base.as_ref().and_then(|o| find_function(o, &self.symbol_name));
|
||||||
let prev_sym = prev.as_ref().and_then(|o| find_function(o, &self.symbol_name));
|
let prev_sym = prev.as_ref().and_then(|o| find_function(o, &self.symbol_name));
|
||||||
self.num_rows = match (
|
self.num_rows = match (
|
||||||
get_diff_symbol(result.left.as_ref(), left_sym),
|
get_symbol_diff(result.left.as_ref(), left_sym),
|
||||||
get_diff_symbol(result.right.as_ref(), right_sym),
|
get_symbol_diff(result.right.as_ref(), right_sym),
|
||||||
) {
|
) {
|
||||||
(Some(l), Some(r)) => l.instructions.len().max(r.instructions.len()),
|
(Some(l), Some(r)) => l.instructions.len().max(r.instructions.len()),
|
||||||
(Some(l), None) => l.instructions.len(),
|
(Some(l), None) => l.instructions.len(),
|
||||||
|
|
|
@ -10,10 +10,10 @@ use similar::{capture_diff_slices_deadline, Algorithm};
|
||||||
use crate::{
|
use crate::{
|
||||||
arch::ProcessCodeResult,
|
arch::ProcessCodeResult,
|
||||||
diff::{
|
diff::{
|
||||||
get_symbol, DiffObjConfig, ObjInsArgDiff, ObjInsBranchFrom, ObjInsBranchTo, ObjInsDiff,
|
DiffObjConfig, ObjInsArgDiff, ObjInsBranchFrom, ObjInsBranchTo, ObjInsDiff, ObjInsDiffKind,
|
||||||
ObjInsDiffKind, ObjSymbolDiff, SymbolRef,
|
ObjSymbolDiff,
|
||||||
},
|
},
|
||||||
obj::{ObjInfo, ObjInsArg, ObjReloc, ObjSymbol, ObjSymbolFlags},
|
obj::{ObjInfo, ObjInsArg, ObjReloc, ObjSymbol, ObjSymbolFlags, SymbolRef},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn no_diff_code(
|
pub fn no_diff_code(
|
||||||
|
@ -21,8 +21,7 @@ pub fn no_diff_code(
|
||||||
symbol_ref: SymbolRef,
|
symbol_ref: SymbolRef,
|
||||||
config: &DiffObjConfig,
|
config: &DiffObjConfig,
|
||||||
) -> Result<ObjSymbolDiff> {
|
) -> Result<ObjSymbolDiff> {
|
||||||
let section = &obj.sections[symbol_ref.section_idx];
|
let (section, symbol) = obj.section_symbol(symbol_ref);
|
||||||
let symbol = §ion.symbols[symbol_ref.symbol_idx];
|
|
||||||
let code = §ion.data
|
let code = §ion.data
|
||||||
[symbol.section_address as usize..(symbol.section_address + symbol.size) as usize];
|
[symbol.section_address as usize..(symbol.section_address + symbol.size) as usize];
|
||||||
let out = obj.arch.process_code(
|
let out = obj.arch.process_code(
|
||||||
|
@ -48,8 +47,8 @@ pub fn diff_code(
|
||||||
right_symbol_ref: SymbolRef,
|
right_symbol_ref: SymbolRef,
|
||||||
config: &DiffObjConfig,
|
config: &DiffObjConfig,
|
||||||
) -> Result<(ObjSymbolDiff, ObjSymbolDiff)> {
|
) -> Result<(ObjSymbolDiff, ObjSymbolDiff)> {
|
||||||
let (left_section, left_symbol) = get_symbol(left_obj, left_symbol_ref);
|
let (left_section, left_symbol) = left_obj.section_symbol(left_symbol_ref);
|
||||||
let (right_section, right_symbol) = get_symbol(right_obj, right_symbol_ref);
|
let (right_section, right_symbol) = right_obj.section_symbol(right_symbol_ref);
|
||||||
let left_code = &left_section.data[left_symbol.section_address as usize
|
let left_code = &left_section.data[left_symbol.section_address as usize
|
||||||
..(left_symbol.section_address + left_symbol.size) as usize];
|
..(left_symbol.section_address + left_symbol.size) as usize];
|
||||||
let right_code = &right_section.data[right_symbol.section_address as usize
|
let right_code = &right_section.data[right_symbol.section_address as usize
|
||||||
|
|
|
@ -7,9 +7,10 @@ use anyhow::Result;
|
||||||
use similar::{capture_diff_slices_deadline, Algorithm};
|
use similar::{capture_diff_slices_deadline, Algorithm};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
diff::{get_symbol, ObjDataDiff, ObjDataDiffKind, ObjSectionDiff, ObjSymbolDiff, SymbolRef},
|
diff::{ ObjDataDiff, ObjDataDiffKind, ObjSectionDiff, ObjSymbolDiff},
|
||||||
obj::{ObjInfo, ObjSection},
|
obj::{ObjInfo, ObjSection},
|
||||||
};
|
};
|
||||||
|
use crate::obj::SymbolRef;
|
||||||
|
|
||||||
pub fn diff_bss_symbol(
|
pub fn diff_bss_symbol(
|
||||||
left_obj: &ObjInfo,
|
left_obj: &ObjInfo,
|
||||||
|
@ -17,8 +18,8 @@ pub fn diff_bss_symbol(
|
||||||
left_symbol_ref: SymbolRef,
|
left_symbol_ref: SymbolRef,
|
||||||
right_symbol_ref: SymbolRef,
|
right_symbol_ref: SymbolRef,
|
||||||
) -> Result<(ObjSymbolDiff, ObjSymbolDiff)> {
|
) -> Result<(ObjSymbolDiff, ObjSymbolDiff)> {
|
||||||
let (_, left_symbol) = get_symbol(left_obj, left_symbol_ref);
|
let (_, left_symbol) = left_obj.section_symbol(left_symbol_ref);
|
||||||
let (_, right_symbol) = get_symbol(right_obj, right_symbol_ref);
|
let (_, right_symbol) = right_obj.section_symbol(right_symbol_ref);
|
||||||
let percent = if left_symbol.size == right_symbol.size { 100.0 } else { 50.0 };
|
let percent = if left_symbol.size == right_symbol.size { 100.0 } else { 50.0 };
|
||||||
Ok((
|
Ok((
|
||||||
ObjSymbolDiff {
|
ObjSymbolDiff {
|
||||||
|
|
|
@ -2,6 +2,8 @@ mod code;
|
||||||
mod data;
|
mod data;
|
||||||
pub mod display;
|
pub mod display;
|
||||||
|
|
||||||
|
use std::collections::HashSet;
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -9,7 +11,7 @@ use crate::{
|
||||||
code::{diff_code, no_diff_code},
|
code::{diff_code, no_diff_code},
|
||||||
data::{diff_bss_symbol, diff_data, no_diff_bss_symbol},
|
data::{diff_bss_symbol, diff_data, no_diff_bss_symbol},
|
||||||
},
|
},
|
||||||
obj::{ObjInfo, ObjIns, ObjSection, ObjSectionKind, ObjSymbol},
|
obj::{ObjInfo, ObjIns, ObjSectionKind, SymbolRef},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, Default, Eq, PartialEq, serde::Deserialize, serde::Serialize)]
|
#[derive(Debug, Copy, Clone, Default, Eq, PartialEq, serde::Deserialize, serde::Serialize)]
|
||||||
|
@ -313,19 +315,6 @@ pub fn diff_objs(
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
|
||||||
pub struct SymbolRef {
|
|
||||||
pub section_idx: usize,
|
|
||||||
pub symbol_idx: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn get_symbol(obj: &ObjInfo, ref_: SymbolRef) -> (&ObjSection, &ObjSymbol) {
|
|
||||||
let section = &obj.sections[ref_.section_idx];
|
|
||||||
let symbol = §ion.symbols[ref_.symbol_idx];
|
|
||||||
(section, symbol)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Eq, PartialEq)]
|
#[derive(Copy, Clone, Eq, PartialEq)]
|
||||||
struct SymbolMatch {
|
struct SymbolMatch {
|
||||||
left: Option<SymbolRef>,
|
left: Option<SymbolRef>,
|
||||||
|
@ -348,7 +337,7 @@ fn matching_symbols(
|
||||||
prev: Option<&ObjInfo>,
|
prev: Option<&ObjInfo>,
|
||||||
) -> Result<Vec<SymbolMatch>> {
|
) -> Result<Vec<SymbolMatch>> {
|
||||||
let mut matches = Vec::new();
|
let mut matches = Vec::new();
|
||||||
let mut right_used = Vec::new();
|
let mut right_used = HashSet::new();
|
||||||
if let Some(left) = left {
|
if let Some(left) = left {
|
||||||
for (section_idx, section) in left.sections.iter().enumerate() {
|
for (section_idx, section) in left.sections.iter().enumerate() {
|
||||||
for (symbol_idx, symbol) in section.symbols.iter().enumerate() {
|
for (symbol_idx, symbol) in section.symbols.iter().enumerate() {
|
||||||
|
@ -360,7 +349,7 @@ fn matching_symbols(
|
||||||
};
|
};
|
||||||
matches.push(symbol_match);
|
matches.push(symbol_match);
|
||||||
if let Some(right) = symbol_match.right {
|
if let Some(right) = symbol_match.right {
|
||||||
right_used.push(right);
|
right_used.insert(right);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -369,7 +358,7 @@ fn matching_symbols(
|
||||||
for (section_idx, section) in right.sections.iter().enumerate() {
|
for (section_idx, section) in right.sections.iter().enumerate() {
|
||||||
for (symbol_idx, symbol) in section.symbols.iter().enumerate() {
|
for (symbol_idx, symbol) in section.symbols.iter().enumerate() {
|
||||||
let symbol_ref = SymbolRef { section_idx, symbol_idx };
|
let symbol_ref = SymbolRef { section_idx, symbol_idx };
|
||||||
if right_used.binary_search(&symbol_ref).is_ok() {
|
if right_used.contains(&symbol_ref) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
matches.push(SymbolMatch {
|
matches.push(SymbolMatch {
|
||||||
|
|
|
@ -139,3 +139,17 @@ pub struct ObjReloc {
|
||||||
pub target: ObjSymbol,
|
pub target: ObjSymbol,
|
||||||
pub target_section: Option<String>,
|
pub target_section: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
|
pub struct SymbolRef {
|
||||||
|
pub section_idx: usize,
|
||||||
|
pub symbol_idx: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ObjInfo {
|
||||||
|
pub fn section_symbol(&self, symbol_ref: SymbolRef) -> (&ObjSection, &ObjSymbol) {
|
||||||
|
let section = &self.sections[symbol_ref.section_idx];
|
||||||
|
let symbol = §ion.symbols[symbol_ref.symbol_idx];
|
||||||
|
(section, symbol)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -6,9 +6,9 @@ use objdiff_core::{
|
||||||
arch::ObjArch,
|
arch::ObjArch,
|
||||||
diff::{
|
diff::{
|
||||||
display::{display_diff, DiffText, HighlightKind},
|
display::{display_diff, DiffText, HighlightKind},
|
||||||
get_symbol, ObjDiff, ObjInsDiff, ObjInsDiffKind, SymbolRef,
|
ObjDiff, ObjInsDiff, ObjInsDiffKind,
|
||||||
},
|
},
|
||||||
obj::{ObjInfo, ObjIns, ObjInsArg, ObjInsArgValue, ObjSection, ObjSymbol},
|
obj::{ObjInfo, ObjIns, ObjInsArg, ObjInsArgValue, ObjSection, ObjSymbol, SymbolRef},
|
||||||
};
|
};
|
||||||
use time::format_description;
|
use time::format_description;
|
||||||
|
|
||||||
|
@ -249,9 +249,8 @@ fn asm_col_ui(
|
||||||
appearance: &Appearance,
|
appearance: &Appearance,
|
||||||
ins_view_state: &mut FunctionViewState,
|
ins_view_state: &mut FunctionViewState,
|
||||||
) {
|
) {
|
||||||
let (section, symbol) = get_symbol(&obj.0, symbol_ref);
|
let (section, symbol) = obj.0.section_symbol(symbol_ref);
|
||||||
let ins_diff = &obj.1.sections[symbol_ref.section_idx].symbols[symbol_ref.symbol_idx]
|
let ins_diff = &obj.1.symbol_diff(symbol_ref).instructions[row.index()];
|
||||||
.instructions[row.index()];
|
|
||||||
let (_, response) = row.col(|ui| {
|
let (_, response) = row.col(|ui| {
|
||||||
asm_row_ui(ui, ins_diff, symbol, appearance, ins_view_state);
|
asm_row_ui(ui, ins_diff, symbol, appearance, ins_view_state);
|
||||||
});
|
});
|
||||||
|
@ -279,20 +278,18 @@ fn asm_table_ui(
|
||||||
let left_symbol = left_obj.and_then(|(obj, _)| find_symbol(obj, selected_symbol));
|
let left_symbol = left_obj.and_then(|(obj, _)| find_symbol(obj, selected_symbol));
|
||||||
let right_symbol = right_obj.and_then(|(obj, _)| find_symbol(obj, selected_symbol));
|
let right_symbol = right_obj.and_then(|(obj, _)| find_symbol(obj, selected_symbol));
|
||||||
let instructions_len = match (left_symbol, right_symbol) {
|
let instructions_len = match (left_symbol, right_symbol) {
|
||||||
(Some(left_symbol_ref), Some(_)) => left_obj.unwrap().1.sections
|
(Some(left_symbol_ref), Some(right_symbol_ref)) => {
|
||||||
[left_symbol_ref.section_idx]
|
let left_len = left_obj.unwrap().1.symbol_diff(left_symbol_ref).instructions.len();
|
||||||
.symbols[left_symbol_ref.symbol_idx]
|
let right_len = right_obj.unwrap().1.symbol_diff(right_symbol_ref).instructions.len();
|
||||||
.instructions
|
debug_assert_eq!(left_len, right_len);
|
||||||
.len(),
|
left_len
|
||||||
(Some(left_symbol_ref), None) => left_obj.unwrap().1.sections[left_symbol_ref.section_idx]
|
}
|
||||||
.symbols[left_symbol_ref.symbol_idx]
|
(Some(left_symbol_ref), None) => {
|
||||||
.instructions
|
left_obj.unwrap().1.symbol_diff(left_symbol_ref).instructions.len()
|
||||||
.len(),
|
}
|
||||||
(None, Some(right_symbol_ref)) => right_obj.unwrap().1.sections
|
(None, Some(right_symbol_ref)) => {
|
||||||
[right_symbol_ref.section_idx]
|
right_obj.unwrap().1.symbol_diff(right_symbol_ref).instructions.len()
|
||||||
.symbols[right_symbol_ref.symbol_idx]
|
}
|
||||||
.instructions
|
|
||||||
.len(),
|
|
||||||
(None, None) => return None,
|
(None, None) => return None,
|
||||||
};
|
};
|
||||||
table.body(|body| {
|
table.body(|body| {
|
||||||
|
|
Loading…
Reference in New Issue