mirror of https://github.com/encounter/objdiff.git
Diff data symbols & improve symbol match logic
This commit is contained in:
parent
854dc9e4f5
commit
22a24f37f5
|
@ -1,6 +1,6 @@
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
|
||||||
use anyhow::{bail, Result};
|
use anyhow::{anyhow, bail, Result};
|
||||||
use object::{elf, Endian, Endianness, File, Object, Relocation, RelocationFlags};
|
use object::{elf, Endian, Endianness, File, Object, Relocation, RelocationFlags};
|
||||||
use rabbitizer::{config, Abi, InstrCategory, Instruction, OperandType};
|
use rabbitizer::{config, Abi, InstrCategory, Instruction, OperandType};
|
||||||
|
|
||||||
|
@ -35,6 +35,7 @@ impl ObjArch for ObjArchMips {
|
||||||
config: &DiffObjConfig,
|
config: &DiffObjConfig,
|
||||||
) -> Result<ProcessCodeResult> {
|
) -> Result<ProcessCodeResult> {
|
||||||
let (section, symbol) = obj.section_symbol(symbol_ref);
|
let (section, symbol) = obj.section_symbol(symbol_ref);
|
||||||
|
let section = section.ok_or_else(|| anyhow!("Code symbol section not found"))?;
|
||||||
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];
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
|
||||||
use anyhow::{bail, Result};
|
use anyhow::{anyhow, bail, Result};
|
||||||
use object::{elf, File, Relocation, RelocationFlags};
|
use object::{elf, File, Relocation, RelocationFlags};
|
||||||
use ppc750cl::{Argument, InsIter, GPR};
|
use ppc750cl::{Argument, InsIter, GPR};
|
||||||
|
|
||||||
|
@ -36,6 +36,7 @@ impl ObjArch for ObjArchPpc {
|
||||||
config: &DiffObjConfig,
|
config: &DiffObjConfig,
|
||||||
) -> Result<ProcessCodeResult> {
|
) -> Result<ProcessCodeResult> {
|
||||||
let (section, symbol) = obj.section_symbol(symbol_ref);
|
let (section, symbol) = obj.section_symbol(symbol_ref);
|
||||||
|
let section = section.ok_or_else(|| anyhow!("Code symbol section not found"))?;
|
||||||
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];
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,7 @@ impl ObjArch for ObjArchX86 {
|
||||||
config: &DiffObjConfig,
|
config: &DiffObjConfig,
|
||||||
) -> Result<ProcessCodeResult> {
|
) -> Result<ProcessCodeResult> {
|
||||||
let (section, symbol) = obj.section_symbol(symbol_ref);
|
let (section, symbol) = obj.section_symbol(symbol_ref);
|
||||||
|
let section = section.ok_or_else(|| anyhow!("Code symbol section not found"))?;
|
||||||
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];
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@ pub fn no_diff_code(
|
||||||
diff.push(ObjInsDiff { ins: Some(i), kind: ObjInsDiffKind::None, ..Default::default() });
|
diff.push(ObjInsDiff { ins: Some(i), kind: ObjInsDiffKind::None, ..Default::default() });
|
||||||
}
|
}
|
||||||
resolve_branches(&mut diff);
|
resolve_branches(&mut diff);
|
||||||
Ok(ObjSymbolDiff { diff_symbol: None, instructions: diff, match_percent: None })
|
Ok(ObjSymbolDiff { symbol_ref, diff_symbol: None, instructions: diff, match_percent: None })
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn diff_code(
|
pub fn diff_code(
|
||||||
|
@ -66,11 +66,13 @@ pub fn diff_code(
|
||||||
|
|
||||||
Ok((
|
Ok((
|
||||||
ObjSymbolDiff {
|
ObjSymbolDiff {
|
||||||
|
symbol_ref: left_symbol_ref,
|
||||||
diff_symbol: Some(right_symbol_ref),
|
diff_symbol: Some(right_symbol_ref),
|
||||||
instructions: left_diff,
|
instructions: left_diff,
|
||||||
match_percent: Some(percent),
|
match_percent: Some(percent),
|
||||||
},
|
},
|
||||||
ObjSymbolDiff {
|
ObjSymbolDiff {
|
||||||
|
symbol_ref: right_symbol_ref,
|
||||||
diff_symbol: Some(left_symbol_ref),
|
diff_symbol: Some(left_symbol_ref),
|
||||||
instructions: right_diff,
|
instructions: right_diff,
|
||||||
match_percent: Some(percent),
|
match_percent: Some(percent),
|
||||||
|
|
|
@ -3,8 +3,8 @@ use std::{
|
||||||
time::{Duration, Instant},
|
time::{Duration, Instant},
|
||||||
};
|
};
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::{anyhow, Result};
|
||||||
use similar::{capture_diff_slices_deadline, Algorithm};
|
use similar::{capture_diff_slices_deadline, get_diff_ratio, Algorithm};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
diff::{ObjDataDiff, ObjDataDiffKind, ObjSectionDiff, ObjSymbolDiff},
|
diff::{ObjDataDiff, ObjDataDiffKind, ObjSectionDiff, ObjSymbolDiff},
|
||||||
|
@ -22,11 +22,13 @@ pub fn diff_bss_symbol(
|
||||||
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 {
|
||||||
|
symbol_ref: left_symbol_ref,
|
||||||
diff_symbol: Some(right_symbol_ref),
|
diff_symbol: Some(right_symbol_ref),
|
||||||
instructions: vec![],
|
instructions: vec![],
|
||||||
match_percent: Some(percent),
|
match_percent: Some(percent),
|
||||||
},
|
},
|
||||||
ObjSymbolDiff {
|
ObjSymbolDiff {
|
||||||
|
symbol_ref: right_symbol_ref,
|
||||||
diff_symbol: Some(left_symbol_ref),
|
diff_symbol: Some(left_symbol_ref),
|
||||||
instructions: vec![],
|
instructions: vec![],
|
||||||
match_percent: Some(percent),
|
match_percent: Some(percent),
|
||||||
|
@ -34,8 +36,8 @@ pub fn diff_bss_symbol(
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn no_diff_bss_symbol(_obj: &ObjInfo, _symbol_ref: SymbolRef) -> ObjSymbolDiff {
|
pub fn no_diff_symbol(_obj: &ObjInfo, symbol_ref: SymbolRef) -> ObjSymbolDiff {
|
||||||
ObjSymbolDiff { diff_symbol: None, instructions: vec![], match_percent: Some(0.0) }
|
ObjSymbolDiff { symbol_ref, diff_symbol: None, instructions: vec![], match_percent: None }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn diff_data(
|
pub fn diff_data(
|
||||||
|
@ -45,6 +47,7 @@ pub fn diff_data(
|
||||||
let deadline = Instant::now() + Duration::from_secs(5);
|
let deadline = Instant::now() + Duration::from_secs(5);
|
||||||
let ops =
|
let ops =
|
||||||
capture_diff_slices_deadline(Algorithm::Patience, &left.data, &right.data, Some(deadline));
|
capture_diff_slices_deadline(Algorithm::Patience, &left.data, &right.data, Some(deadline));
|
||||||
|
let match_percent = get_diff_ratio(&ops, left.data.len(), right.data.len()) * 100.0;
|
||||||
|
|
||||||
let mut left_diff = Vec::<ObjDataDiff>::new();
|
let mut left_diff = Vec::<ObjDataDiff>::new();
|
||||||
let mut right_diff = Vec::<ObjDataDiff>::new();
|
let mut right_diff = Vec::<ObjDataDiff>::new();
|
||||||
|
@ -118,14 +121,50 @@ pub fn diff_data(
|
||||||
ObjSectionDiff {
|
ObjSectionDiff {
|
||||||
symbols: vec![],
|
symbols: vec![],
|
||||||
data_diff: left_diff,
|
data_diff: left_diff,
|
||||||
// TODO
|
match_percent: Some(match_percent),
|
||||||
match_percent: None,
|
|
||||||
},
|
},
|
||||||
ObjSectionDiff {
|
ObjSectionDiff {
|
||||||
symbols: vec![],
|
symbols: vec![],
|
||||||
data_diff: right_diff,
|
data_diff: right_diff,
|
||||||
// TODO
|
match_percent: Some(match_percent),
|
||||||
match_percent: None,
|
},
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn diff_data_symbol(
|
||||||
|
left_obj: &ObjInfo,
|
||||||
|
right_obj: &ObjInfo,
|
||||||
|
left_symbol_ref: SymbolRef,
|
||||||
|
right_symbol_ref: SymbolRef,
|
||||||
|
) -> Result<(ObjSymbolDiff, ObjSymbolDiff)> {
|
||||||
|
let (left_section, left_symbol) = left_obj.section_symbol(left_symbol_ref);
|
||||||
|
let (right_section, right_symbol) = right_obj.section_symbol(right_symbol_ref);
|
||||||
|
|
||||||
|
let left_section = left_section.ok_or_else(|| anyhow!("Data symbol section not found"))?;
|
||||||
|
let right_section = right_section.ok_or_else(|| anyhow!("Data symbol section not found"))?;
|
||||||
|
|
||||||
|
let left_data = &left_section.data[left_symbol.section_address as usize
|
||||||
|
..(left_symbol.section_address + left_symbol.size) as usize];
|
||||||
|
let right_data = &right_section.data[right_symbol.section_address as usize
|
||||||
|
..(right_symbol.section_address + right_symbol.size) as usize];
|
||||||
|
|
||||||
|
let deadline = Instant::now() + Duration::from_secs(5);
|
||||||
|
let ops =
|
||||||
|
capture_diff_slices_deadline(Algorithm::Patience, left_data, right_data, Some(deadline));
|
||||||
|
let match_percent = get_diff_ratio(&ops, left_data.len(), right_data.len()) * 100.0;
|
||||||
|
|
||||||
|
Ok((
|
||||||
|
ObjSymbolDiff {
|
||||||
|
symbol_ref: left_symbol_ref,
|
||||||
|
diff_symbol: Some(right_symbol_ref),
|
||||||
|
instructions: vec![],
|
||||||
|
match_percent: Some(match_percent),
|
||||||
|
},
|
||||||
|
ObjSymbolDiff {
|
||||||
|
symbol_ref: right_symbol_ref,
|
||||||
|
diff_symbol: Some(left_symbol_ref),
|
||||||
|
instructions: vec![],
|
||||||
|
match_percent: Some(match_percent),
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,3 @@
|
||||||
mod code;
|
|
||||||
mod data;
|
|
||||||
pub mod display;
|
|
||||||
|
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
|
@ -9,11 +5,15 @@ use anyhow::Result;
|
||||||
use crate::{
|
use crate::{
|
||||||
diff::{
|
diff::{
|
||||||
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, diff_data_symbol, no_diff_symbol},
|
||||||
},
|
},
|
||||||
obj::{ObjInfo, ObjIns, ObjSectionKind, SymbolRef},
|
obj::{ObjInfo, ObjIns, ObjSection, ObjSectionKind, ObjSymbol, SymbolRef},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
mod code;
|
||||||
|
mod data;
|
||||||
|
pub mod display;
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, Default, Eq, PartialEq, serde::Deserialize, serde::Serialize)]
|
#[derive(Debug, Copy, Clone, Default, Eq, PartialEq, serde::Deserialize, serde::Serialize)]
|
||||||
pub enum X86Formatter {
|
pub enum X86Formatter {
|
||||||
#[default]
|
#[default]
|
||||||
|
@ -62,6 +62,7 @@ impl ObjSectionDiff {
|
||||||
|
|
||||||
#[derive(Debug, Clone, Default)]
|
#[derive(Debug, Clone, Default)]
|
||||||
pub struct ObjSymbolDiff {
|
pub struct ObjSymbolDiff {
|
||||||
|
pub symbol_ref: SymbolRef,
|
||||||
pub diff_symbol: Option<SymbolRef>,
|
pub diff_symbol: Option<SymbolRef>,
|
||||||
pub instructions: Vec<ObjInsDiff>,
|
pub instructions: Vec<ObjInsDiff>,
|
||||||
pub match_percent: Option<f32>,
|
pub match_percent: Option<f32>,
|
||||||
|
@ -142,10 +143,11 @@ impl ObjDiff {
|
||||||
sections: Vec::with_capacity(obj.sections.len()),
|
sections: Vec::with_capacity(obj.sections.len()),
|
||||||
common: Vec::with_capacity(obj.common.len()),
|
common: Vec::with_capacity(obj.common.len()),
|
||||||
};
|
};
|
||||||
for section in &obj.sections {
|
for (section_idx, section) in obj.sections.iter().enumerate() {
|
||||||
let mut symbols = Vec::with_capacity(section.symbols.len());
|
let mut symbols = Vec::with_capacity(section.symbols.len());
|
||||||
for _ in §ion.symbols {
|
for (symbol_idx, _) in section.symbols.iter().enumerate() {
|
||||||
symbols.push(ObjSymbolDiff {
|
symbols.push(ObjSymbolDiff {
|
||||||
|
symbol_ref: SymbolRef { section_idx, symbol_idx },
|
||||||
diff_symbol: None,
|
diff_symbol: None,
|
||||||
instructions: vec![],
|
instructions: vec![],
|
||||||
match_percent: None,
|
match_percent: None,
|
||||||
|
@ -162,8 +164,9 @@ impl ObjDiff {
|
||||||
match_percent: None,
|
match_percent: None,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
for _ in &obj.common {
|
for (symbol_idx, _) in obj.common.iter().enumerate() {
|
||||||
result.common.push(ObjSymbolDiff {
|
result.common.push(ObjSymbolDiff {
|
||||||
|
symbol_ref: SymbolRef { section_idx: obj.sections.len(), symbol_idx },
|
||||||
diff_symbol: None,
|
diff_symbol: None,
|
||||||
instructions: vec![],
|
instructions: vec![],
|
||||||
match_percent: None,
|
match_percent: None,
|
||||||
|
@ -184,13 +187,21 @@ impl ObjDiff {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn symbol_diff(&self, symbol_ref: SymbolRef) -> &ObjSymbolDiff {
|
pub fn symbol_diff(&self, symbol_ref: SymbolRef) -> &ObjSymbolDiff {
|
||||||
|
if symbol_ref.section_idx == self.sections.len() {
|
||||||
|
&self.common[symbol_ref.symbol_idx]
|
||||||
|
} else {
|
||||||
&self.section_diff(symbol_ref.section_idx).symbols[symbol_ref.symbol_idx]
|
&self.section_diff(symbol_ref.section_idx).symbols[symbol_ref.symbol_idx]
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn symbol_diff_mut(&mut self, symbol_ref: SymbolRef) -> &mut ObjSymbolDiff {
|
pub fn symbol_diff_mut(&mut self, symbol_ref: SymbolRef) -> &mut ObjSymbolDiff {
|
||||||
|
if symbol_ref.section_idx == self.sections.len() {
|
||||||
|
&mut self.common[symbol_ref.symbol_idx]
|
||||||
|
} else {
|
||||||
&mut self.section_diff_mut(symbol_ref.section_idx).symbols[symbol_ref.symbol_idx]
|
&mut self.section_diff_mut(symbol_ref.section_idx).symbols[symbol_ref.symbol_idx]
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
|
@ -247,7 +258,14 @@ pub fn diff_objs(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ObjSectionKind::Data => {
|
ObjSectionKind::Data => {
|
||||||
// TODO diff data symbol
|
let (left_diff, right_diff) = diff_data_symbol(
|
||||||
|
left_obj,
|
||||||
|
right_obj,
|
||||||
|
left_symbol_ref,
|
||||||
|
right_symbol_ref,
|
||||||
|
)?;
|
||||||
|
*left_out.symbol_diff_mut(left_symbol_ref) = left_diff;
|
||||||
|
*right_out.symbol_diff_mut(right_symbol_ref) = right_diff;
|
||||||
}
|
}
|
||||||
ObjSectionKind::Bss => {
|
ObjSectionKind::Bss => {
|
||||||
let (left_diff, right_diff) = diff_bss_symbol(
|
let (left_diff, right_diff) = diff_bss_symbol(
|
||||||
|
@ -268,10 +286,9 @@ pub fn diff_objs(
|
||||||
*left_out.symbol_diff_mut(left_symbol_ref) =
|
*left_out.symbol_diff_mut(left_symbol_ref) =
|
||||||
no_diff_code(left_obj, left_symbol_ref, config)?;
|
no_diff_code(left_obj, left_symbol_ref, config)?;
|
||||||
}
|
}
|
||||||
ObjSectionKind::Data => {}
|
ObjSectionKind::Data | ObjSectionKind::Bss => {
|
||||||
ObjSectionKind::Bss => {
|
|
||||||
*left_out.symbol_diff_mut(left_symbol_ref) =
|
*left_out.symbol_diff_mut(left_symbol_ref) =
|
||||||
no_diff_bss_symbol(left_obj, left_symbol_ref);
|
no_diff_symbol(left_obj, left_symbol_ref);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -282,10 +299,9 @@ pub fn diff_objs(
|
||||||
*right_out.symbol_diff_mut(right_symbol_ref) =
|
*right_out.symbol_diff_mut(right_symbol_ref) =
|
||||||
no_diff_code(right_obj, right_symbol_ref, config)?;
|
no_diff_code(right_obj, right_symbol_ref, config)?;
|
||||||
}
|
}
|
||||||
ObjSectionKind::Data => {}
|
ObjSectionKind::Data | ObjSectionKind::Bss => {
|
||||||
ObjSectionKind::Bss => {
|
|
||||||
*right_out.symbol_diff_mut(right_symbol_ref) =
|
*right_out.symbol_diff_mut(right_symbol_ref) =
|
||||||
no_diff_bss_symbol(right_obj, right_symbol_ref);
|
no_diff_symbol(right_obj, right_symbol_ref);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -357,8 +373,8 @@ fn matching_symbols(
|
||||||
for (symbol_idx, symbol) in section.symbols.iter().enumerate() {
|
for (symbol_idx, symbol) in section.symbols.iter().enumerate() {
|
||||||
let symbol_match = SymbolMatch {
|
let symbol_match = SymbolMatch {
|
||||||
left: Some(SymbolRef { section_idx, symbol_idx }),
|
left: Some(SymbolRef { section_idx, symbol_idx }),
|
||||||
right: find_symbol(right, &symbol.name, section.kind),
|
right: find_symbol(right, symbol, section),
|
||||||
prev: find_symbol(prev, &symbol.name, section.kind),
|
prev: find_symbol(prev, symbol, section),
|
||||||
section_kind: section.kind,
|
section_kind: section.kind,
|
||||||
};
|
};
|
||||||
matches.push(symbol_match);
|
matches.push(symbol_match);
|
||||||
|
@ -367,6 +383,18 @@ fn matching_symbols(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (symbol_idx, symbol) in left.common.iter().enumerate() {
|
||||||
|
let symbol_match = SymbolMatch {
|
||||||
|
left: Some(SymbolRef { section_idx: left.sections.len(), symbol_idx }),
|
||||||
|
right: find_common_symbol(right, symbol),
|
||||||
|
prev: find_common_symbol(prev, symbol),
|
||||||
|
section_kind: ObjSectionKind::Bss,
|
||||||
|
};
|
||||||
|
matches.push(symbol_match);
|
||||||
|
if let Some(right) = symbol_match.right {
|
||||||
|
right_used.insert(right);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if let Some(right) = right {
|
if let Some(right) = right {
|
||||||
for (section_idx, section) in right.sections.iter().enumerate() {
|
for (section_idx, section) in right.sections.iter().enumerate() {
|
||||||
|
@ -378,30 +406,69 @@ fn matching_symbols(
|
||||||
matches.push(SymbolMatch {
|
matches.push(SymbolMatch {
|
||||||
left: None,
|
left: None,
|
||||||
right: Some(symbol_ref),
|
right: Some(symbol_ref),
|
||||||
prev: find_symbol(prev, &symbol.name, section.kind),
|
prev: find_symbol(prev, symbol, section),
|
||||||
section_kind: section.kind,
|
section_kind: section.kind,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (symbol_idx, symbol) in right.common.iter().enumerate() {
|
||||||
|
let symbol_ref = SymbolRef { section_idx: right.sections.len(), symbol_idx };
|
||||||
|
if right_used.contains(&symbol_ref) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
matches.push(SymbolMatch {
|
||||||
|
left: None,
|
||||||
|
right: Some(symbol_ref),
|
||||||
|
prev: find_common_symbol(prev, symbol),
|
||||||
|
section_kind: ObjSectionKind::Bss,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Ok(matches)
|
Ok(matches)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_symbol(
|
fn find_symbol(
|
||||||
obj: Option<&ObjInfo>,
|
obj: Option<&ObjInfo>,
|
||||||
name: &str,
|
in_symbol: &ObjSymbol,
|
||||||
section_kind: ObjSectionKind,
|
in_section: &ObjSection,
|
||||||
) -> Option<SymbolRef> {
|
) -> Option<SymbolRef> {
|
||||||
for (section_idx, section) in obj?.sections.iter().enumerate() {
|
let obj = obj?;
|
||||||
if section.kind != section_kind {
|
// Try to find an exact name match
|
||||||
|
for (section_idx, section) in obj.sections.iter().enumerate() {
|
||||||
|
if section.kind != in_section.kind {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let symbol_idx = match section.symbols.iter().position(|symbol| symbol.name == name) {
|
if let Some(symbol_idx) =
|
||||||
Some(symbol_idx) => symbol_idx,
|
section.symbols.iter().position(|symbol| symbol.name == in_symbol.name)
|
||||||
None => continue,
|
{
|
||||||
};
|
|
||||||
return Some(SymbolRef { section_idx, symbol_idx });
|
return Some(SymbolRef { section_idx, symbol_idx });
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
// Match compiler-generated symbols against each other (e.g. @251 -> @60)
|
||||||
|
// If they are at the same address in the same section
|
||||||
|
if in_symbol.name.starts_with('@')
|
||||||
|
&& matches!(in_section.kind, ObjSectionKind::Data | ObjSectionKind::Bss)
|
||||||
|
{
|
||||||
|
if let Some((section_idx, section)) =
|
||||||
|
obj.sections.iter().enumerate().find(|(_, s)| s.name == in_section.name)
|
||||||
|
{
|
||||||
|
if let Some(symbol_idx) = section.symbols.iter().position(|symbol| {
|
||||||
|
symbol.address == in_symbol.address && symbol.name.starts_with('@')
|
||||||
|
}) {
|
||||||
|
return Some(SymbolRef { section_idx, symbol_idx });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
fn find_common_symbol(obj: Option<&ObjInfo>, in_symbol: &ObjSymbol) -> Option<SymbolRef> {
|
||||||
|
let obj = obj?;
|
||||||
|
for (symbol_idx, symbol) in obj.common.iter().enumerate() {
|
||||||
|
if symbol.name == in_symbol.name {
|
||||||
|
return Some(SymbolRef { section_idx: obj.sections.len(), symbol_idx });
|
||||||
|
}
|
||||||
|
}
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -142,16 +142,20 @@ pub struct ObjReloc {
|
||||||
pub target_section: Option<String>,
|
pub target_section: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
|
||||||
pub struct SymbolRef {
|
pub struct SymbolRef {
|
||||||
pub section_idx: usize,
|
pub section_idx: usize,
|
||||||
pub symbol_idx: usize,
|
pub symbol_idx: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ObjInfo {
|
impl ObjInfo {
|
||||||
pub fn section_symbol(&self, symbol_ref: SymbolRef) -> (&ObjSection, &ObjSymbol) {
|
pub fn section_symbol(&self, symbol_ref: SymbolRef) -> (Option<&ObjSection>, &ObjSymbol) {
|
||||||
|
if symbol_ref.section_idx == self.sections.len() {
|
||||||
|
let symbol = &self.common[symbol_ref.symbol_idx];
|
||||||
|
return (None, symbol);
|
||||||
|
}
|
||||||
let section = &self.sections[symbol_ref.section_idx];
|
let section = &self.sections[symbol_ref.section_idx];
|
||||||
let symbol = §ion.symbols[symbol_ref.symbol_idx];
|
let symbol = §ion.symbols[symbol_ref.symbol_idx];
|
||||||
(section, symbol)
|
(Some(section), symbol)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -282,6 +282,7 @@ fn asm_col_ui(
|
||||||
ins_view_state: &mut FunctionViewState,
|
ins_view_state: &mut FunctionViewState,
|
||||||
) {
|
) {
|
||||||
let (section, symbol) = obj.0.section_symbol(symbol_ref);
|
let (section, symbol) = obj.0.section_symbol(symbol_ref);
|
||||||
|
let section = section.unwrap();
|
||||||
let ins_diff = &obj.1.symbol_diff(symbol_ref).instructions[row.index()];
|
let ins_diff = &obj.1.symbol_diff(symbol_ref).instructions[row.index()];
|
||||||
let response_cb = |response: Response| {
|
let response_cb = |response: Response| {
|
||||||
if let Some(ins) = &ins_diff.ins {
|
if let Some(ins) = &ins_diff.ins {
|
||||||
|
|
|
@ -7,7 +7,7 @@ use egui::{
|
||||||
use egui_extras::{Size, StripBuilder};
|
use egui_extras::{Size, StripBuilder};
|
||||||
use objdiff_core::{
|
use objdiff_core::{
|
||||||
diff::{ObjDiff, ObjSymbolDiff},
|
diff::{ObjDiff, ObjSymbolDiff},
|
||||||
obj::{ObjInfo, ObjSection, ObjSectionKind, ObjSymbol, ObjSymbolFlags},
|
obj::{ObjInfo, ObjSection, ObjSectionKind, ObjSymbol, ObjSymbolFlags, SymbolRef},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -52,7 +52,7 @@ pub struct DiffViewState {
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct SymbolViewState {
|
pub struct SymbolViewState {
|
||||||
pub highlighted_symbol: Option<String>,
|
pub highlighted_symbol: (Option<SymbolRef>, Option<SymbolRef>),
|
||||||
pub selected_symbol: Option<SymbolRefByName>,
|
pub selected_symbol: Option<SymbolRefByName>,
|
||||||
pub reverse_fn_order: bool,
|
pub reverse_fn_order: bool,
|
||||||
pub disable_reverse_fn_order: bool,
|
pub disable_reverse_fn_order: bool,
|
||||||
|
@ -184,6 +184,7 @@ fn symbol_ui(
|
||||||
section: Option<&ObjSection>,
|
section: Option<&ObjSection>,
|
||||||
state: &mut SymbolViewState,
|
state: &mut SymbolViewState,
|
||||||
appearance: &Appearance,
|
appearance: &Appearance,
|
||||||
|
left: bool,
|
||||||
) -> Option<View> {
|
) -> Option<View> {
|
||||||
if symbol.flags.0.contains(ObjSymbolFlags::Hidden) && !state.show_hidden_symbols {
|
if symbol.flags.0.contains(ObjSymbolFlags::Hidden) && !state.show_hidden_symbols {
|
||||||
return None;
|
return None;
|
||||||
|
@ -193,8 +194,10 @@ fn symbol_ui(
|
||||||
let name: &str =
|
let name: &str =
|
||||||
if let Some(demangled) = &symbol.demangled_name { demangled } else { &symbol.name };
|
if let Some(demangled) = &symbol.demangled_name { demangled } else { &symbol.name };
|
||||||
let mut selected = false;
|
let mut selected = false;
|
||||||
if let Some(sym) = &state.highlighted_symbol {
|
if let Some(sym_ref) =
|
||||||
selected = sym == &symbol.name;
|
if left { state.highlighted_symbol.0 } else { state.highlighted_symbol.1 }
|
||||||
|
{
|
||||||
|
selected = symbol_diff.symbol_ref == sym_ref;
|
||||||
}
|
}
|
||||||
write_text("[", appearance.text_color, &mut job, appearance.code_font.clone());
|
write_text("[", appearance.text_color, &mut job, appearance.code_font.clone());
|
||||||
if symbol.flags.0.contains(ObjSymbolFlags::Common) {
|
if symbol.flags.0.contains(ObjSymbolFlags::Common) {
|
||||||
|
@ -245,7 +248,15 @@ fn symbol_ui(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if response.hovered() {
|
} else if response.hovered() {
|
||||||
state.highlighted_symbol = Some(symbol.name.clone());
|
state.highlighted_symbol = if let Some(diff_symbol) = symbol_diff.diff_symbol {
|
||||||
|
if left {
|
||||||
|
(Some(symbol_diff.symbol_ref), Some(diff_symbol))
|
||||||
|
} else {
|
||||||
|
(Some(diff_symbol), Some(symbol_diff.symbol_ref))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
(None, None)
|
||||||
|
};
|
||||||
}
|
}
|
||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
|
@ -267,6 +278,7 @@ fn symbol_list_ui(
|
||||||
state: &mut SymbolViewState,
|
state: &mut SymbolViewState,
|
||||||
lower_search: &str,
|
lower_search: &str,
|
||||||
appearance: &Appearance,
|
appearance: &Appearance,
|
||||||
|
left: bool,
|
||||||
) -> Option<View> {
|
) -> Option<View> {
|
||||||
let mut ret = None;
|
let mut ret = None;
|
||||||
ScrollArea::both().auto_shrink([false, false]).show(ui, |ui| {
|
ScrollArea::both().auto_shrink([false, false]).show(ui, |ui| {
|
||||||
|
@ -277,7 +289,15 @@ fn symbol_list_ui(
|
||||||
if !obj.0.common.is_empty() {
|
if !obj.0.common.is_empty() {
|
||||||
CollapsingHeader::new(".comm").default_open(true).show(ui, |ui| {
|
CollapsingHeader::new(".comm").default_open(true).show(ui, |ui| {
|
||||||
for (symbol, symbol_diff) in obj.0.common.iter().zip(&obj.1.common) {
|
for (symbol, symbol_diff) in obj.0.common.iter().zip(&obj.1.common) {
|
||||||
ret = ret.or(symbol_ui(ui, symbol, symbol_diff, None, state, appearance));
|
ret = ret.or(symbol_ui(
|
||||||
|
ui,
|
||||||
|
symbol,
|
||||||
|
symbol_diff,
|
||||||
|
None,
|
||||||
|
state,
|
||||||
|
appearance,
|
||||||
|
left,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -301,6 +321,7 @@ fn symbol_list_ui(
|
||||||
Some(section),
|
Some(section),
|
||||||
state,
|
state,
|
||||||
appearance,
|
appearance,
|
||||||
|
left,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -317,6 +338,7 @@ fn symbol_list_ui(
|
||||||
Some(section),
|
Some(section),
|
||||||
state,
|
state,
|
||||||
appearance,
|
appearance,
|
||||||
|
left,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -447,6 +469,7 @@ pub fn symbol_diff_ui(ui: &mut Ui, state: &mut DiffViewState, appearance: &Appea
|
||||||
symbol_state,
|
symbol_state,
|
||||||
&lower_search,
|
&lower_search,
|
||||||
appearance,
|
appearance,
|
||||||
|
true,
|
||||||
));
|
));
|
||||||
} else {
|
} else {
|
||||||
missing_obj_ui(ui, appearance);
|
missing_obj_ui(ui, appearance);
|
||||||
|
@ -466,6 +489,7 @@ pub fn symbol_diff_ui(ui: &mut Ui, state: &mut DiffViewState, appearance: &Appea
|
||||||
symbol_state,
|
symbol_state,
|
||||||
&lower_search,
|
&lower_search,
|
||||||
appearance,
|
appearance,
|
||||||
|
false,
|
||||||
));
|
));
|
||||||
} else {
|
} else {
|
||||||
missing_obj_ui(ui, appearance);
|
missing_obj_ui(ui, appearance);
|
||||||
|
|
Loading…
Reference in New Issue