mirror of
https://github.com/encounter/objdiff.git
synced 2025-12-16 08:27:04 +00:00
Compare commits
5 Commits
v3.0.0-bet
...
v3.0.0-bet
| Author | SHA1 | Date | |
|---|---|---|---|
| dab79d96a1 | |||
| a57e5db983 | |||
|
|
d0afd3b83e | ||
|
|
a367af612b | ||
|
|
22052ea10b |
8
Cargo.lock
generated
8
Cargo.lock
generated
@@ -3373,7 +3373,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "objdiff-cli"
|
name = "objdiff-cli"
|
||||||
version = "3.0.0-beta.8"
|
version = "3.0.0-beta.9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"argp",
|
"argp",
|
||||||
@@ -3396,7 +3396,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "objdiff-core"
|
name = "objdiff-core"
|
||||||
version = "3.0.0-beta.8"
|
version = "3.0.0-beta.9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"arm-attr",
|
"arm-attr",
|
||||||
@@ -3450,7 +3450,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "objdiff-gui"
|
name = "objdiff-gui"
|
||||||
version = "3.0.0-beta.8"
|
version = "3.0.0-beta.9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
@@ -3486,7 +3486,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "objdiff-wasm"
|
name = "objdiff-wasm"
|
||||||
version = "3.0.0-beta.8"
|
version = "3.0.0-beta.9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"log",
|
"log",
|
||||||
"objdiff-core",
|
"objdiff-core",
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ strip = "debuginfo"
|
|||||||
codegen-units = 1
|
codegen-units = 1
|
||||||
|
|
||||||
[workspace.package]
|
[workspace.package]
|
||||||
version = "3.0.0-beta.8"
|
version = "3.0.0-beta.9"
|
||||||
authors = ["Luke Street <luke@street.dev>"]
|
authors = ["Luke Street <luke@street.dev>"]
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
license = "MIT OR Apache-2.0"
|
license = "MIT OR Apache-2.0"
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ any-arch = [
|
|||||||
"dep:regex",
|
"dep:regex",
|
||||||
"dep:similar",
|
"dep:similar",
|
||||||
"dep:syn",
|
"dep:syn",
|
||||||
|
"dep:encoding_rs"
|
||||||
]
|
]
|
||||||
bindings = [
|
bindings = [
|
||||||
"dep:prost",
|
"dep:prost",
|
||||||
@@ -171,7 +172,7 @@ notify-debouncer-full = { version = "0.5.0", optional = true }
|
|||||||
shell-escape = { version = "0.1", optional = true }
|
shell-escape = { version = "0.1", optional = true }
|
||||||
tempfile = { version = "3.19", optional = true }
|
tempfile = { version = "3.19", optional = true }
|
||||||
time = { version = "0.3", optional = true }
|
time = { version = "0.3", optional = true }
|
||||||
encoding_rs = "0.8.35"
|
encoding_rs = { version = "0.8.35", optional = true }
|
||||||
|
|
||||||
[target.'cfg(windows)'.dependencies]
|
[target.'cfg(windows)'.dependencies]
|
||||||
winapi = { version = "0.3", optional = true }
|
winapi = { version = "0.3", optional = true }
|
||||||
|
|||||||
@@ -147,14 +147,20 @@ pub(crate) fn data_row_ui(
|
|||||||
cur_addr += diff.len;
|
cur_addr += diff.len;
|
||||||
} else {
|
} else {
|
||||||
for byte in &diff.data {
|
for byte in &diff.data {
|
||||||
|
let mut byte_text = format!("{byte:02x} ");
|
||||||
let mut byte_color = base_color;
|
let mut byte_color = base_color;
|
||||||
if let Some(reloc_diff) = reloc_diffs.iter().find(|reloc_diff| {
|
if let Some(reloc_diff) = reloc_diffs
|
||||||
reloc_diff.kind != DataDiffKind::None
|
.iter()
|
||||||
&& reloc_diff.range.contains(&cur_addr_actual)
|
.find(|reloc_diff| reloc_diff.range.contains(&cur_addr_actual))
|
||||||
}) {
|
{
|
||||||
byte_color = get_color_for_diff_kind(reloc_diff.kind, appearance);
|
if *byte == 0 {
|
||||||
|
// Display 00 data bytes with a relocation as ?? instead.
|
||||||
|
byte_text = "?? ".to_string();
|
||||||
|
}
|
||||||
|
if reloc_diff.kind != DataDiffKind::None {
|
||||||
|
byte_color = get_color_for_diff_kind(reloc_diff.kind, appearance);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
let byte_text = format!("{byte:02x} ");
|
|
||||||
write_text(byte_text.as_str(), byte_color, &mut job, appearance.code_font.clone());
|
write_text(byte_text.as_str(), byte_color, &mut job, appearance.code_font.clone());
|
||||||
cur_addr += 1;
|
cur_addr += 1;
|
||||||
cur_addr_actual += 1;
|
cur_addr_actual += 1;
|
||||||
|
|||||||
@@ -499,6 +499,7 @@ pub fn diff_view_ui(
|
|||||||
(state.current_view, left_ctx.obj, right_ctx.obj, left_ctx.section, right_ctx.section)
|
(state.current_view, left_ctx.obj, right_ctx.obj, left_ctx.section, right_ctx.section)
|
||||||
{
|
{
|
||||||
// Joint diff view
|
// Joint diff view
|
||||||
|
hotkeys::check_scroll_hotkeys(ui, true);
|
||||||
let left_total_bytes =
|
let left_total_bytes =
|
||||||
left_section_diff.data_diff.iter().fold(0usize, |accum, item| accum + item.len);
|
left_section_diff.data_diff.iter().fold(0usize, |accum, item| accum + item.len);
|
||||||
let right_total_bytes =
|
let right_total_bytes =
|
||||||
|
|||||||
4
objdiff-wasm/package-lock.json
generated
4
objdiff-wasm/package-lock.json
generated
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "objdiff-wasm",
|
"name": "objdiff-wasm",
|
||||||
"version": "3.0.0-beta.8",
|
"version": "3.0.0-beta.9",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "objdiff-wasm",
|
"name": "objdiff-wasm",
|
||||||
"version": "3.0.0-beta.8",
|
"version": "3.0.0-beta.9",
|
||||||
"license": "MIT OR Apache-2.0",
|
"license": "MIT OR Apache-2.0",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@biomejs/biome": "^1.9.3",
|
"@biomejs/biome": "^1.9.3",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "objdiff-wasm",
|
"name": "objdiff-wasm",
|
||||||
"version": "3.0.0-beta.8",
|
"version": "3.0.0-beta.9",
|
||||||
"description": "A local diffing tool for decompilation projects.",
|
"description": "A local diffing tool for decompilation projects.",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "Luke Street",
|
"name": "Luke Street",
|
||||||
|
|||||||
@@ -24,14 +24,14 @@ wit_bindgen::generate!({
|
|||||||
use exports::objdiff::core::{
|
use exports::objdiff::core::{
|
||||||
diff::{
|
diff::{
|
||||||
DiffConfigBorrow, DiffResult, Guest as GuestDiff, GuestDiffConfig, GuestObject,
|
DiffConfigBorrow, DiffResult, Guest as GuestDiff, GuestDiffConfig, GuestObject,
|
||||||
GuestObjectDiff, Object, ObjectBorrow, ObjectDiff, ObjectDiffBorrow,
|
GuestObjectDiff, MappingConfig, Object, ObjectBorrow, ObjectDiff, ObjectDiffBorrow,
|
||||||
|
SymbolFlags, SymbolInfo, SymbolKind, SymbolRef,
|
||||||
},
|
},
|
||||||
display::{
|
display::{
|
||||||
ContextItem, ContextItemCopy, ContextItemNavigate, DiffText, DiffTextColor, DiffTextOpcode,
|
ContextItem, ContextItemCopy, ContextItemNavigate, DiffText, DiffTextColor, DiffTextOpcode,
|
||||||
DiffTextSegment, DiffTextSymbol, DisplayConfig, Guest as GuestDisplay, HoverItem,
|
DiffTextSegment, DiffTextSymbol, DisplayConfig, Guest as GuestDisplay, HoverItem,
|
||||||
HoverItemColor, HoverItemText, InstructionDiffKind, InstructionDiffRow, SectionDisplay,
|
HoverItemColor, HoverItemText, InstructionDiffKind, InstructionDiffRow, SectionDisplay,
|
||||||
SectionDisplaySymbol, SymbolDisplay, SymbolFilter, SymbolFlags, SymbolKind,
|
SymbolDisplay, SymbolFilter, SymbolNavigationKind,
|
||||||
SymbolNavigationKind, SymbolRef,
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -59,15 +59,17 @@ impl GuestDiff for Component {
|
|||||||
left: Option<ObjectBorrow>,
|
left: Option<ObjectBorrow>,
|
||||||
right: Option<ObjectBorrow>,
|
right: Option<ObjectBorrow>,
|
||||||
diff_config: DiffConfigBorrow,
|
diff_config: DiffConfigBorrow,
|
||||||
|
mapping_config: MappingConfig,
|
||||||
) -> Result<DiffResult, String> {
|
) -> Result<DiffResult, String> {
|
||||||
let diff_config = diff_config.get::<ResourceDiffConfig>().0.borrow();
|
let diff_config = diff_config.get::<ResourceDiffConfig>().0.borrow();
|
||||||
|
let mapping_config = diff::MappingConfig::from(mapping_config);
|
||||||
log::debug!("Running diff with config: {:?}", diff_config);
|
log::debug!("Running diff with config: {:?}", diff_config);
|
||||||
let result = diff::diff_objs(
|
let result = diff::diff_objs(
|
||||||
left.as_ref().map(|o| o.get::<ResourceObject>().0.as_ref()),
|
left.as_ref().map(|o| o.get::<ResourceObject>().0.as_ref()),
|
||||||
right.as_ref().map(|o| o.get::<ResourceObject>().0.as_ref()),
|
right.as_ref().map(|o| o.get::<ResourceObject>().0.as_ref()),
|
||||||
None,
|
None,
|
||||||
&diff_config,
|
&diff_config,
|
||||||
&diff::MappingConfig::default(),
|
&mapping_config,
|
||||||
)
|
)
|
||||||
.map_err(|e| e.to_string())?;
|
.map_err(|e| e.to_string())?;
|
||||||
Ok(DiffResult {
|
Ok(DiffResult {
|
||||||
@@ -134,48 +136,47 @@ impl GuestDisplay for Component {
|
|||||||
name: d.name,
|
name: d.name,
|
||||||
size: d.size,
|
size: d.size,
|
||||||
match_percent: d.match_percent,
|
match_percent: d.match_percent,
|
||||||
symbols: d
|
symbols: d.symbols.into_iter().map(to_symbol_ref).collect(),
|
||||||
.symbols
|
|
||||||
.into_iter()
|
|
||||||
.map(|s| SectionDisplaySymbol {
|
|
||||||
symbol: s.symbol as SymbolRef,
|
|
||||||
is_mapping_symbol: s.is_mapping_symbol,
|
|
||||||
})
|
|
||||||
.collect(),
|
|
||||||
})
|
})
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn display_symbol(
|
fn display_symbol(diff: ObjectDiffBorrow, symbol_ref: SymbolRef) -> SymbolDisplay {
|
||||||
diff: ObjectDiffBorrow,
|
|
||||||
symbol_display: SectionDisplaySymbol,
|
|
||||||
) -> SymbolDisplay {
|
|
||||||
let obj_diff = diff.get::<ResourceObjectDiff>();
|
let obj_diff = diff.get::<ResourceObjectDiff>();
|
||||||
let obj = obj_diff.0.as_ref();
|
let obj = obj_diff.0.as_ref();
|
||||||
let obj_diff = &obj_diff.1;
|
let obj_diff = &obj_diff.1;
|
||||||
let symbol_idx = symbol_display.symbol as usize;
|
let symbol_display = from_symbol_ref(symbol_ref);
|
||||||
let Some(symbol) = obj.symbols.get(symbol_idx) else {
|
let Some(symbol) = obj.symbols.get(symbol_display.symbol) else {
|
||||||
return SymbolDisplay { name: "<unknown>".to_string(), ..Default::default() };
|
return SymbolDisplay {
|
||||||
|
info: SymbolInfo { name: "<unknown>".to_string(), ..Default::default() },
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
};
|
};
|
||||||
let symbol_diff = if symbol_display.is_mapping_symbol {
|
let symbol_diff = if symbol_display.is_mapping_symbol {
|
||||||
obj_diff
|
obj_diff
|
||||||
.mapping_symbols
|
.mapping_symbols
|
||||||
.iter()
|
.iter()
|
||||||
.find(|s| s.symbol_index == symbol_idx)
|
.find(|s| s.symbol_index == symbol_display.symbol)
|
||||||
.map(|s| &s.symbol_diff)
|
.map(|s| &s.symbol_diff)
|
||||||
} else {
|
} else {
|
||||||
obj_diff.symbols.get(symbol_idx)
|
obj_diff.symbols.get(symbol_display.symbol)
|
||||||
};
|
};
|
||||||
SymbolDisplay {
|
SymbolDisplay {
|
||||||
name: symbol.name.clone(),
|
info: SymbolInfo {
|
||||||
demangled_name: symbol.demangled_name.clone(),
|
id: to_symbol_ref(symbol_display),
|
||||||
address: symbol.address,
|
name: symbol.name.clone(),
|
||||||
size: symbol.size,
|
demangled_name: symbol.demangled_name.clone(),
|
||||||
kind: SymbolKind::from(symbol.kind),
|
address: symbol.address,
|
||||||
section: symbol.section.map(|s| s as u32),
|
size: symbol.size,
|
||||||
flags: SymbolFlags::from(symbol.flags),
|
kind: SymbolKind::from(symbol.kind),
|
||||||
align: symbol.align.map(|a| a.get()),
|
section: symbol.section.map(|s| s as u32),
|
||||||
virtual_address: symbol.virtual_address,
|
section_name: symbol
|
||||||
|
.section
|
||||||
|
.and_then(|s| obj.sections.get(s).map(|sec| sec.name.clone())),
|
||||||
|
flags: SymbolFlags::from(symbol.flags),
|
||||||
|
align: symbol.align.map(|a| a.get()),
|
||||||
|
virtual_address: symbol.virtual_address,
|
||||||
|
},
|
||||||
target_symbol: symbol_diff.and_then(|sd| sd.target_symbol.map(|s| s as u32)),
|
target_symbol: symbol_diff.and_then(|sd| sd.target_symbol.map(|s| s as u32)),
|
||||||
match_percent: symbol_diff.and_then(|sd| sd.match_percent),
|
match_percent: symbol_diff.and_then(|sd| sd.match_percent),
|
||||||
diff_score: symbol_diff.and_then(|sd| sd.diff_score),
|
diff_score: symbol_diff.and_then(|sd| sd.diff_score),
|
||||||
@@ -185,22 +186,22 @@ impl GuestDisplay for Component {
|
|||||||
|
|
||||||
fn display_instruction_row(
|
fn display_instruction_row(
|
||||||
diff: ObjectDiffBorrow,
|
diff: ObjectDiffBorrow,
|
||||||
symbol_display: SectionDisplaySymbol,
|
symbol_ref: SymbolRef,
|
||||||
row_index: u32,
|
row_index: u32,
|
||||||
diff_config: DiffConfigBorrow,
|
diff_config: DiffConfigBorrow,
|
||||||
) -> InstructionDiffRow {
|
) -> InstructionDiffRow {
|
||||||
let obj_diff = diff.get::<ResourceObjectDiff>();
|
let obj_diff = diff.get::<ResourceObjectDiff>();
|
||||||
let obj = obj_diff.0.as_ref();
|
let obj = obj_diff.0.as_ref();
|
||||||
let obj_diff = &obj_diff.1;
|
let obj_diff = &obj_diff.1;
|
||||||
let symbol_idx = symbol_display.symbol as usize;
|
let symbol_display = from_symbol_ref(symbol_ref);
|
||||||
let symbol_diff = if symbol_display.is_mapping_symbol {
|
let symbol_diff = if symbol_display.is_mapping_symbol {
|
||||||
obj_diff
|
obj_diff
|
||||||
.mapping_symbols
|
.mapping_symbols
|
||||||
.iter()
|
.iter()
|
||||||
.find(|s| s.symbol_index == symbol_idx)
|
.find(|s| s.symbol_index == symbol_display.symbol)
|
||||||
.map(|s| &s.symbol_diff)
|
.map(|s| &s.symbol_diff)
|
||||||
} else {
|
} else {
|
||||||
obj_diff.symbols.get(symbol_idx)
|
obj_diff.symbols.get(symbol_display.symbol)
|
||||||
};
|
};
|
||||||
let Some(row) = symbol_diff.and_then(|sd| sd.instruction_rows.get(row_index as usize))
|
let Some(row) = symbol_diff.and_then(|sd| sd.instruction_rows.get(row_index as usize))
|
||||||
else {
|
else {
|
||||||
@@ -208,7 +209,7 @@ impl GuestDisplay for Component {
|
|||||||
};
|
};
|
||||||
let diff_config = diff_config.get::<ResourceDiffConfig>().0.borrow();
|
let diff_config = diff_config.get::<ResourceDiffConfig>().0.borrow();
|
||||||
let mut segments = Vec::with_capacity(16);
|
let mut segments = Vec::with_capacity(16);
|
||||||
diff::display::display_row(obj, symbol_idx, row, &diff_config, |segment| {
|
diff::display::display_row(obj, symbol_display.symbol, row, &diff_config, |segment| {
|
||||||
segments.push(DiffTextSegment::from(segment));
|
segments.push(DiffTextSegment::from(segment));
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
@@ -216,26 +217,22 @@ impl GuestDisplay for Component {
|
|||||||
InstructionDiffRow { segments, diff_kind: InstructionDiffKind::from(row.kind) }
|
InstructionDiffRow { segments, diff_kind: InstructionDiffKind::from(row.kind) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn symbol_context(
|
fn symbol_context(diff: ObjectDiffBorrow, symbol_ref: SymbolRef) -> Vec<ContextItem> {
|
||||||
diff: ObjectDiffBorrow,
|
|
||||||
symbol_display: SectionDisplaySymbol,
|
|
||||||
) -> Vec<ContextItem> {
|
|
||||||
let obj_diff = diff.get::<ResourceObjectDiff>();
|
let obj_diff = diff.get::<ResourceObjectDiff>();
|
||||||
let obj = obj_diff.0.as_ref();
|
let obj = obj_diff.0.as_ref();
|
||||||
|
let symbol_display = from_symbol_ref(symbol_ref);
|
||||||
diff::display::symbol_context(obj, symbol_display.symbol as usize)
|
diff::display::symbol_context(obj, symbol_display.symbol as usize)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|item| ContextItem::from(item))
|
.map(|item| ContextItem::from(item))
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn symbol_hover(
|
fn symbol_hover(diff: ObjectDiffBorrow, symbol_ref: SymbolRef) -> Vec<HoverItem> {
|
||||||
diff: ObjectDiffBorrow,
|
|
||||||
symbol_display: SectionDisplaySymbol,
|
|
||||||
) -> Vec<HoverItem> {
|
|
||||||
let obj_diff = diff.get::<ResourceObjectDiff>();
|
let obj_diff = diff.get::<ResourceObjectDiff>();
|
||||||
let obj = obj_diff.0.as_ref();
|
let obj = obj_diff.0.as_ref();
|
||||||
let addend = 0; // TODO
|
let addend = 0; // TODO
|
||||||
let override_color = None; // TODO: colorize replaced/deleted/inserted relocations
|
let override_color = None; // TODO: colorize replaced/deleted/inserted relocations
|
||||||
|
let symbol_display = from_symbol_ref(symbol_ref);
|
||||||
diff::display::symbol_hover(obj, symbol_display.symbol as usize, addend, override_color)
|
diff::display::symbol_hover(obj, symbol_display.symbol as usize, addend, override_color)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|item| HoverItem::from(item))
|
.map(|item| HoverItem::from(item))
|
||||||
@@ -244,22 +241,22 @@ impl GuestDisplay for Component {
|
|||||||
|
|
||||||
fn instruction_context(
|
fn instruction_context(
|
||||||
diff: ObjectDiffBorrow,
|
diff: ObjectDiffBorrow,
|
||||||
symbol_display: SectionDisplaySymbol,
|
symbol_ref: SymbolRef,
|
||||||
row_index: u32,
|
row_index: u32,
|
||||||
diff_config: DiffConfigBorrow,
|
diff_config: DiffConfigBorrow,
|
||||||
) -> Vec<ContextItem> {
|
) -> Vec<ContextItem> {
|
||||||
let obj_diff = diff.get::<ResourceObjectDiff>();
|
let obj_diff = diff.get::<ResourceObjectDiff>();
|
||||||
let obj = obj_diff.0.as_ref();
|
let obj = obj_diff.0.as_ref();
|
||||||
let obj_diff = &obj_diff.1;
|
let obj_diff = &obj_diff.1;
|
||||||
let symbol_idx = symbol_display.symbol as usize;
|
let symbol_display = from_symbol_ref(symbol_ref);
|
||||||
let symbol_diff = if symbol_display.is_mapping_symbol {
|
let symbol_diff = if symbol_display.is_mapping_symbol {
|
||||||
obj_diff
|
obj_diff
|
||||||
.mapping_symbols
|
.mapping_symbols
|
||||||
.iter()
|
.iter()
|
||||||
.find(|s| s.symbol_index == symbol_idx)
|
.find(|s| s.symbol_index == symbol_display.symbol)
|
||||||
.map(|s| &s.symbol_diff)
|
.map(|s| &s.symbol_diff)
|
||||||
} else {
|
} else {
|
||||||
obj_diff.symbols.get(symbol_idx)
|
obj_diff.symbols.get(symbol_display.symbol)
|
||||||
};
|
};
|
||||||
let Some(ins_ref) = symbol_diff
|
let Some(ins_ref) = symbol_diff
|
||||||
.and_then(|sd| sd.instruction_rows.get(row_index as usize))
|
.and_then(|sd| sd.instruction_rows.get(row_index as usize))
|
||||||
@@ -268,7 +265,7 @@ impl GuestDisplay for Component {
|
|||||||
return Vec::new();
|
return Vec::new();
|
||||||
};
|
};
|
||||||
let diff_config = diff_config.get::<ResourceDiffConfig>().0.borrow();
|
let diff_config = diff_config.get::<ResourceDiffConfig>().0.borrow();
|
||||||
let Some(resolved) = obj.resolve_instruction_ref(symbol_idx, ins_ref) else {
|
let Some(resolved) = obj.resolve_instruction_ref(symbol_display.symbol, ins_ref) else {
|
||||||
return vec![ContextItem::Copy(ContextItemCopy {
|
return vec![ContextItem::Copy(ContextItemCopy {
|
||||||
value: "Failed to resolve instruction".to_string(),
|
value: "Failed to resolve instruction".to_string(),
|
||||||
label: Some("error".to_string()),
|
label: Some("error".to_string()),
|
||||||
@@ -291,22 +288,22 @@ impl GuestDisplay for Component {
|
|||||||
|
|
||||||
fn instruction_hover(
|
fn instruction_hover(
|
||||||
diff: ObjectDiffBorrow,
|
diff: ObjectDiffBorrow,
|
||||||
symbol_display: SectionDisplaySymbol,
|
symbol_ref: SymbolRef,
|
||||||
row_index: u32,
|
row_index: u32,
|
||||||
diff_config: DiffConfigBorrow,
|
diff_config: DiffConfigBorrow,
|
||||||
) -> Vec<HoverItem> {
|
) -> Vec<HoverItem> {
|
||||||
let obj_diff = diff.get::<ResourceObjectDiff>();
|
let obj_diff = diff.get::<ResourceObjectDiff>();
|
||||||
let obj = obj_diff.0.as_ref();
|
let obj = obj_diff.0.as_ref();
|
||||||
let obj_diff = &obj_diff.1;
|
let obj_diff = &obj_diff.1;
|
||||||
let symbol_idx = symbol_display.symbol as usize;
|
let symbol_display = from_symbol_ref(symbol_ref);
|
||||||
let symbol_diff = if symbol_display.is_mapping_symbol {
|
let symbol_diff = if symbol_display.is_mapping_symbol {
|
||||||
obj_diff
|
obj_diff
|
||||||
.mapping_symbols
|
.mapping_symbols
|
||||||
.iter()
|
.iter()
|
||||||
.find(|s| s.symbol_index == symbol_idx)
|
.find(|s| s.symbol_index == symbol_display.symbol)
|
||||||
.map(|s| &s.symbol_diff)
|
.map(|s| &s.symbol_diff)
|
||||||
} else {
|
} else {
|
||||||
obj_diff.symbols.get(symbol_idx)
|
obj_diff.symbols.get(symbol_display.symbol)
|
||||||
};
|
};
|
||||||
let Some(ins_ref) = symbol_diff
|
let Some(ins_ref) = symbol_diff
|
||||||
.and_then(|sd| sd.instruction_rows.get(row_index as usize))
|
.and_then(|sd| sd.instruction_rows.get(row_index as usize))
|
||||||
@@ -315,7 +312,7 @@ impl GuestDisplay for Component {
|
|||||||
return Vec::new();
|
return Vec::new();
|
||||||
};
|
};
|
||||||
let diff_config = diff_config.get::<ResourceDiffConfig>().0.borrow();
|
let diff_config = diff_config.get::<ResourceDiffConfig>().0.borrow();
|
||||||
let Some(resolved) = obj.resolve_instruction_ref(symbol_idx, ins_ref) else {
|
let Some(resolved) = obj.resolve_instruction_ref(symbol_display.symbol, ins_ref) else {
|
||||||
return vec![HoverItem::Text(HoverItemText {
|
return vec![HoverItem::Text(HoverItemText {
|
||||||
label: "Error".to_string(),
|
label: "Error".to_string(),
|
||||||
value: "Failed to resolve instruction".to_string(),
|
value: "Failed to resolve instruction".to_string(),
|
||||||
@@ -497,20 +494,56 @@ impl GuestObject for ResourceObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl GuestObjectDiff for ResourceObjectDiff {
|
impl GuestObjectDiff for ResourceObjectDiff {
|
||||||
fn find_symbol(&self, name: String, section_name: Option<String>) -> Option<SymbolRef> {
|
fn find_symbol(&self, name: String, section_name: Option<String>) -> Option<SymbolInfo> {
|
||||||
let obj = self.0.as_ref();
|
let obj = self.0.as_ref();
|
||||||
obj.symbols
|
let symbol_idx = obj.symbols.iter().position(|s| {
|
||||||
.iter()
|
s.name == name
|
||||||
.position(|s| {
|
&& match section_name.as_deref() {
|
||||||
s.name == name
|
Some(section_name) => {
|
||||||
&& match section_name.as_deref() {
|
s.section.is_some_and(|n| obj.sections[n].name == section_name)
|
||||||
Some(section_name) => {
|
|
||||||
s.section.is_some_and(|n| obj.sections[n].name == section_name)
|
|
||||||
}
|
|
||||||
None => true,
|
|
||||||
}
|
}
|
||||||
})
|
None => true,
|
||||||
.map(|i| i as SymbolRef)
|
}
|
||||||
|
})?;
|
||||||
|
let symbol = obj.symbols.get(symbol_idx)?;
|
||||||
|
Some(SymbolInfo {
|
||||||
|
id: symbol_idx as SymbolRef,
|
||||||
|
name: symbol.name.clone(),
|
||||||
|
demangled_name: symbol.demangled_name.clone(),
|
||||||
|
address: symbol.address,
|
||||||
|
size: symbol.size,
|
||||||
|
kind: SymbolKind::from(symbol.kind),
|
||||||
|
section: symbol.section.map(|s| s as u32),
|
||||||
|
section_name: symbol
|
||||||
|
.section
|
||||||
|
.and_then(|s| obj.sections.get(s).map(|sec| sec.name.clone())),
|
||||||
|
flags: SymbolFlags::from(symbol.flags),
|
||||||
|
align: symbol.align.map(|a| a.get()),
|
||||||
|
virtual_address: symbol.virtual_address,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_symbol(&self, symbol_ref: SymbolRef) -> Option<SymbolInfo> {
|
||||||
|
let obj = self.0.as_ref();
|
||||||
|
let symbol_display = from_symbol_ref(symbol_ref);
|
||||||
|
let Some(symbol) = obj.symbols.get(symbol_display.symbol) else {
|
||||||
|
return None;
|
||||||
|
};
|
||||||
|
Some(SymbolInfo {
|
||||||
|
id: to_symbol_ref(symbol_display),
|
||||||
|
name: symbol.name.clone(),
|
||||||
|
demangled_name: symbol.demangled_name.clone(),
|
||||||
|
address: symbol.address,
|
||||||
|
size: symbol.size,
|
||||||
|
kind: SymbolKind::from(symbol.kind),
|
||||||
|
section: symbol.section.map(|s| s as u32),
|
||||||
|
section_name: symbol
|
||||||
|
.section
|
||||||
|
.and_then(|s| obj.sections.get(s).map(|sec| sec.name.clone())),
|
||||||
|
flags: SymbolFlags::from(symbol.flags),
|
||||||
|
align: symbol.align.map(|a| a.get()),
|
||||||
|
virtual_address: symbol.virtual_address,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -580,18 +613,28 @@ impl Default for SymbolFlags {
|
|||||||
fn default() -> Self { Self::empty() }
|
fn default() -> Self { Self::empty() }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for SymbolDisplay {
|
impl Default for SymbolInfo {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
id: u32::MAX,
|
||||||
name: Default::default(),
|
name: Default::default(),
|
||||||
demangled_name: Default::default(),
|
demangled_name: Default::default(),
|
||||||
address: Default::default(),
|
address: Default::default(),
|
||||||
size: Default::default(),
|
size: Default::default(),
|
||||||
kind: Default::default(),
|
kind: Default::default(),
|
||||||
section: Default::default(),
|
section: Default::default(),
|
||||||
|
section_name: Default::default(),
|
||||||
flags: Default::default(),
|
flags: Default::default(),
|
||||||
align: Default::default(),
|
align: Default::default(),
|
||||||
virtual_address: Default::default(),
|
virtual_address: Default::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for SymbolDisplay {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
info: Default::default(),
|
||||||
target_symbol: Default::default(),
|
target_symbol: Default::default(),
|
||||||
match_percent: Default::default(),
|
match_percent: Default::default(),
|
||||||
diff_score: Default::default(),
|
diff_score: Default::default(),
|
||||||
@@ -600,4 +643,30 @@ impl Default for SymbolDisplay {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<MappingConfig> for diff::MappingConfig {
|
||||||
|
fn from(config: MappingConfig) -> Self {
|
||||||
|
Self {
|
||||||
|
mappings: config.mappings.into_iter().collect(),
|
||||||
|
selecting_left: config.selecting_left,
|
||||||
|
selecting_right: config.selecting_right,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn from_symbol_ref(symbol_ref: SymbolRef) -> diff::display::SectionDisplaySymbol {
|
||||||
|
diff::display::SectionDisplaySymbol {
|
||||||
|
symbol: (symbol_ref & !(1 << 31)) as usize,
|
||||||
|
is_mapping_symbol: (symbol_ref & (1 << 31)) != 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn to_symbol_ref(display_symbol: diff::display::SectionDisplaySymbol) -> SymbolRef {
|
||||||
|
if display_symbol.is_mapping_symbol {
|
||||||
|
// Use the highest bit to indicate a mapping symbol
|
||||||
|
display_symbol.symbol as u32 | (1 << 31)
|
||||||
|
} else {
|
||||||
|
display_symbol.symbol as u32
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export!(Component);
|
export!(Component);
|
||||||
|
|||||||
@@ -24,58 +24,8 @@ interface diff {
|
|||||||
hash: func() -> u64;
|
hash: func() -> u64;
|
||||||
}
|
}
|
||||||
|
|
||||||
resource object-diff {
|
|
||||||
find-symbol: func(
|
|
||||||
name: string,
|
|
||||||
section-name: option<string>
|
|
||||||
) -> option<u32>;
|
|
||||||
}
|
|
||||||
|
|
||||||
record diff-result {
|
|
||||||
left: option<object-diff>,
|
|
||||||
right: option<object-diff>,
|
|
||||||
}
|
|
||||||
|
|
||||||
run-diff: func(
|
|
||||||
left: option<borrow<object>>,
|
|
||||||
right: option<borrow<object>>,
|
|
||||||
config: borrow<diff-config>,
|
|
||||||
) -> result<diff-result, string>;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface display {
|
|
||||||
use diff.{
|
|
||||||
object,
|
|
||||||
object-diff,
|
|
||||||
diff-config
|
|
||||||
};
|
|
||||||
|
|
||||||
type symbol-ref = u32;
|
type symbol-ref = u32;
|
||||||
|
|
||||||
record display-config {
|
|
||||||
show-hidden-symbols: bool,
|
|
||||||
show-mapped-symbols: bool,
|
|
||||||
reverse-fn-order: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
record symbol-filter {
|
|
||||||
regex: option<string>,
|
|
||||||
mapping: option<symbol-ref>,
|
|
||||||
}
|
|
||||||
|
|
||||||
record section-display-symbol {
|
|
||||||
symbol: symbol-ref,
|
|
||||||
is-mapping-symbol: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
record section-display {
|
|
||||||
id: string,
|
|
||||||
name: string,
|
|
||||||
size: u64,
|
|
||||||
match-percent: option<f32>,
|
|
||||||
symbols: list<section-display-symbol>,
|
|
||||||
}
|
|
||||||
|
|
||||||
enum symbol-kind {
|
enum symbol-kind {
|
||||||
unknown,
|
unknown,
|
||||||
function,
|
function,
|
||||||
@@ -94,17 +44,74 @@ interface display {
|
|||||||
ignored,
|
ignored,
|
||||||
}
|
}
|
||||||
|
|
||||||
record symbol-display {
|
record symbol-info {
|
||||||
|
id: symbol-ref,
|
||||||
name: string,
|
name: string,
|
||||||
demangled-name: option<string>,
|
demangled-name: option<string>,
|
||||||
address: u64,
|
address: u64,
|
||||||
size: u64,
|
size: u64,
|
||||||
kind: symbol-kind,
|
kind: symbol-kind,
|
||||||
section: option<u32>,
|
section: option<u32>,
|
||||||
|
section-name: option<string>,
|
||||||
%flags: symbol-flags,
|
%flags: symbol-flags,
|
||||||
align: option<u32>,
|
align: option<u32>,
|
||||||
virtual-address: option<u64>,
|
virtual-address: option<u64>,
|
||||||
|
}
|
||||||
|
|
||||||
|
resource object-diff {
|
||||||
|
find-symbol: func(
|
||||||
|
name: string,
|
||||||
|
section-name: option<string>
|
||||||
|
) -> option<symbol-info>;
|
||||||
|
|
||||||
|
get-symbol: func(
|
||||||
|
id: u32
|
||||||
|
) -> option<symbol-info>;
|
||||||
|
}
|
||||||
|
|
||||||
|
record diff-result {
|
||||||
|
left: option<object-diff>,
|
||||||
|
right: option<object-diff>,
|
||||||
|
}
|
||||||
|
|
||||||
|
run-diff: func(
|
||||||
|
left: option<borrow<object>>,
|
||||||
|
right: option<borrow<object>>,
|
||||||
|
config: borrow<diff-config>,
|
||||||
|
mapping: mapping-config,
|
||||||
|
) -> result<diff-result, string>;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface display {
|
||||||
|
use diff.{
|
||||||
|
object,
|
||||||
|
object-diff,
|
||||||
|
diff-config,
|
||||||
|
symbol-info,
|
||||||
|
symbol-ref
|
||||||
|
};
|
||||||
|
|
||||||
|
record display-config {
|
||||||
|
show-hidden-symbols: bool,
|
||||||
|
show-mapped-symbols: bool,
|
||||||
|
reverse-fn-order: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
record symbol-filter {
|
||||||
|
regex: option<string>,
|
||||||
|
mapping: option<symbol-ref>,
|
||||||
|
}
|
||||||
|
|
||||||
|
record section-display {
|
||||||
|
id: string,
|
||||||
|
name: string,
|
||||||
|
size: u64,
|
||||||
|
match-percent: option<f32>,
|
||||||
|
symbols: list<symbol-ref>,
|
||||||
|
}
|
||||||
|
|
||||||
|
record symbol-display {
|
||||||
|
info: symbol-info,
|
||||||
target-symbol: option<symbol-ref>,
|
target-symbol: option<symbol-ref>,
|
||||||
match-percent: option<f32>,
|
match-percent: option<f32>,
|
||||||
diff-score: option<tuple<u64, u64>>,
|
diff-score: option<tuple<u64, u64>>,
|
||||||
@@ -232,36 +239,36 @@ interface display {
|
|||||||
|
|
||||||
display-symbol: func(
|
display-symbol: func(
|
||||||
diff: borrow<object-diff>,
|
diff: borrow<object-diff>,
|
||||||
symbol: section-display-symbol,
|
symbol: symbol-ref,
|
||||||
) -> symbol-display;
|
) -> symbol-display;
|
||||||
|
|
||||||
display-instruction-row: func(
|
display-instruction-row: func(
|
||||||
diff: borrow<object-diff>,
|
diff: borrow<object-diff>,
|
||||||
symbol: section-display-symbol,
|
symbol: symbol-ref,
|
||||||
row-index: u32,
|
row-index: u32,
|
||||||
config: borrow<diff-config>,
|
config: borrow<diff-config>,
|
||||||
) -> instruction-diff-row;
|
) -> instruction-diff-row;
|
||||||
|
|
||||||
symbol-context: func(
|
symbol-context: func(
|
||||||
diff: borrow<object-diff>,
|
diff: borrow<object-diff>,
|
||||||
symbol: section-display-symbol,
|
symbol: symbol-ref,
|
||||||
) -> list<context-item>;
|
) -> list<context-item>;
|
||||||
|
|
||||||
symbol-hover: func(
|
symbol-hover: func(
|
||||||
diff: borrow<object-diff>,
|
diff: borrow<object-diff>,
|
||||||
symbol: section-display-symbol,
|
symbol: symbol-ref,
|
||||||
) -> list<hover-item>;
|
) -> list<hover-item>;
|
||||||
|
|
||||||
instruction-context: func(
|
instruction-context: func(
|
||||||
diff: borrow<object-diff>,
|
diff: borrow<object-diff>,
|
||||||
symbol: section-display-symbol,
|
symbol: symbol-ref,
|
||||||
row-index: u32,
|
row-index: u32,
|
||||||
config: borrow<diff-config>,
|
config: borrow<diff-config>,
|
||||||
) -> list<context-item>;
|
) -> list<context-item>;
|
||||||
|
|
||||||
instruction-hover: func(
|
instruction-hover: func(
|
||||||
diff: borrow<object-diff>,
|
diff: borrow<object-diff>,
|
||||||
symbol: section-display-symbol,
|
symbol: symbol-ref,
|
||||||
row-index: u32,
|
row-index: u32,
|
||||||
config: borrow<diff-config>,
|
config: borrow<diff-config>,
|
||||||
) -> list<hover-item>;
|
) -> list<hover-item>;
|
||||||
|
|||||||
Reference in New Issue
Block a user