Diff schema updates & WASM updates

This commit is contained in:
Luke Street 2024-12-17 21:18:45 -07:00
parent b0c5431ac5
commit c45f4bbc99
8 changed files with 60 additions and 22 deletions

View File

@ -21,9 +21,9 @@ enum SymbolFlag {
SYMBOL_NONE = 0;
SYMBOL_GLOBAL = 1;
SYMBOL_LOCAL = 2;
SYMBOL_WEAK = 3;
SYMBOL_COMMON = 4;
SYMBOL_HIDDEN = 5;
SYMBOL_WEAK = 4;
SYMBOL_COMMON = 8;
SYMBOL_HIDDEN = 16;
}
// A single parsed instruction
@ -122,10 +122,17 @@ message InstructionBranchTo {
uint32 branch_index = 2;
}
message FunctionDiff {
message SymbolRef {
optional uint32 section_index = 1;
uint32 symbol_index = 2;
}
message SymbolDiff {
Symbol symbol = 1;
repeated InstructionDiff instructions = 2;
optional float match_percent = 3;
// The symbol ref in the _other_ object that this symbol was diffed against
optional SymbolRef target = 5;
}
message DataDiff {
@ -140,7 +147,7 @@ message SectionDiff {
SectionKind kind = 2;
uint64 size = 3;
uint64 address = 4;
repeated FunctionDiff functions = 5;
repeated SymbolDiff symbols = 5;
repeated DataDiff data = 6;
optional float match_percent = 7;
}

View File

@ -4,6 +4,7 @@ use crate::{
ObjDataDiff, ObjDataDiffKind, ObjDiff, ObjInsArgDiff, ObjInsBranchFrom, ObjInsBranchTo,
ObjInsDiff, ObjInsDiffKind, ObjSectionDiff, ObjSymbolDiff,
},
obj,
obj::{
ObjInfo, ObjIns, ObjInsArg, ObjInsArgValue, ObjReloc, ObjSectionKind, ObjSymbol,
ObjSymbolFlagSet, ObjSymbolFlags,
@ -39,14 +40,14 @@ impl ObjectDiff {
impl SectionDiff {
pub fn new(obj: &ObjInfo, section_index: usize, section_diff: &ObjSectionDiff) -> Self {
let section = &obj.sections[section_index];
let functions = section_diff.symbols.iter().map(|d| FunctionDiff::new(obj, d)).collect();
let symbols = section_diff.symbols.iter().map(|d| SymbolDiff::new(obj, d)).collect();
let data = section_diff.data_diff.iter().map(|d| DataDiff::new(obj, d)).collect();
Self {
name: section.name.to_string(),
kind: SectionKind::from(section.kind) as i32,
size: section.size,
address: section.address,
functions,
symbols,
data,
match_percent: section_diff.match_percent,
}
@ -64,13 +65,22 @@ impl From<ObjSectionKind> for SectionKind {
}
}
impl FunctionDiff {
impl From<obj::SymbolRef> for SymbolRef {
fn from(value: obj::SymbolRef) -> Self {
Self {
section_index: if value.section_idx == obj::SECTION_COMMON {
None
} else {
Some(value.section_idx as u32)
},
symbol_index: value.symbol_idx as u32,
}
}
}
impl SymbolDiff {
pub fn new(object: &ObjInfo, symbol_diff: &ObjSymbolDiff) -> Self {
let (_section, symbol) = object.section_symbol(symbol_diff.symbol_ref);
// let diff_symbol = symbol_diff.diff_symbol.map(|symbol_ref| {
// let (_section, symbol) = object.section_symbol(symbol_ref);
// Symbol::from(symbol)
// });
let instructions = symbol_diff
.instructions
.iter()
@ -78,9 +88,9 @@ impl FunctionDiff {
.collect();
Self {
symbol: Some(Symbol::new(symbol)),
// diff_symbol,
instructions,
match_percent: symbol_diff.match_percent,
target: symbol_diff.target_symbol.map(SymbolRef::from),
}
}
}
@ -110,7 +120,7 @@ impl Symbol {
fn symbol_flags(value: ObjSymbolFlagSet) -> u32 {
let mut flags = 0u32;
if value.0.contains(ObjSymbolFlags::Global) {
flags |= SymbolFlag::SymbolNone as u32;
flags |= SymbolFlag::SymbolGlobal as u32;
}
if value.0.contains(ObjSymbolFlags::Local) {
flags |= SymbolFlag::SymbolLocal as u32;

View File

@ -6,11 +6,11 @@ use std::{
};
use anyhow::{anyhow, Context, Result};
use bimap::BiBTreeMap;
use filetime::FileTime;
use globset::{Glob, GlobSet, GlobSetBuilder};
#[derive(Default, Clone, serde::Serialize, serde::Deserialize)]
#[cfg_attr(feature = "wasm", derive(tsify_next::Tsify), tsify(from_wasm_abi))]
pub struct ProjectConfig {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub min_version: Option<String>,
@ -55,6 +55,7 @@ impl ProjectConfig {
}
#[derive(Default, Clone, serde::Serialize, serde::Deserialize)]
#[cfg_attr(feature = "wasm", derive(tsify_next::Tsify), tsify(from_wasm_abi))]
pub struct ProjectObject {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
@ -78,9 +79,15 @@ pub struct ProjectObject {
pub symbol_mappings: Option<SymbolMappings>,
}
pub type SymbolMappings = BiBTreeMap<String, String>;
#[cfg(feature = "wasm")]
#[tsify_next::declare]
pub type SymbolMappings = std::collections::BTreeMap<String, String>;
#[cfg(not(feature = "wasm"))]
pub type SymbolMappings = bimap::BiBTreeMap<String, String>;
#[derive(Default, Clone, serde::Serialize, serde::Deserialize)]
#[cfg_attr(feature = "wasm", derive(tsify_next::Tsify), tsify(from_wasm_abi))]
pub struct ProjectObjectMetadata {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub complete: Option<bool>,
@ -95,6 +102,7 @@ pub struct ProjectObjectMetadata {
}
#[derive(Default, Clone, serde::Serialize, serde::Deserialize)]
#[cfg_attr(feature = "wasm", derive(tsify_next::Tsify), tsify(from_wasm_abi))]
pub struct ProjectProgressCategory {
#[serde(default)]
pub id: String,
@ -154,6 +162,7 @@ impl ProjectObject {
}
#[derive(Default, Clone, Eq, PartialEq, serde::Deserialize, serde::Serialize)]
#[cfg_attr(feature = "wasm", derive(tsify_next::Tsify), tsify(from_wasm_abi))]
pub struct ScratchConfig {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub platform: Option<String>,

View File

@ -155,8 +155,7 @@ pub enum ArmR9Usage {
const fn default_true() -> bool { true }
#[derive(Debug, Clone, Eq, PartialEq, serde::Deserialize, serde::Serialize)]
#[cfg_attr(feature = "wasm", derive(tsify_next::Tsify))]
#[cfg_attr(feature = "wasm", tsify(from_wasm_abi))]
#[cfg_attr(feature = "wasm", derive(tsify_next::Tsify), tsify(from_wasm_abi))]
#[serde(default)]
pub struct DiffObjConfig {
pub relax_reloc_diffs: bool,
@ -637,6 +636,7 @@ struct SectionMatch {
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, Default, serde::Deserialize, serde::Serialize)]
#[cfg_attr(feature = "wasm", derive(tsify_next::Tsify), tsify(from_wasm_abi))]
pub struct MappingConfig {
/// Manual symbol mappings
pub mappings: SymbolMappings,

View File

@ -1,6 +1,6 @@
{
"name": "objdiff-wasm",
"version": "2.0.0",
"version": "2.5.0",
"description": "A local diffing tool for decompilation projects.",
"author": {
"name": "Luke Street",
@ -21,7 +21,7 @@
"build": "tsup",
"build:all": "npm run build:wasm && npm run build:proto && npm run build",
"build:proto": "protoc --ts_out=gen --ts_opt add_pb_suffix,eslint_disable,ts_nocheck,use_proto_field_name --proto_path=../objdiff-core/protos ../objdiff-core/protos/*.proto",
"build:wasm": "cd ../objdiff-core && wasm-pack build --out-dir ../objdiff-wasm/pkg --target web -- --features arm,dwarf,ppc,x86,wasm"
"build:wasm": "cd ../objdiff-core && wasm-pack build --out-dir ../objdiff-wasm/pkg --target web -- --features arm,arm64,dwarf,config,ppc,x86,wasm"
},
"dependencies": {
"@protobuf-ts/runtime": "^2.9.4"

View File

@ -194,12 +194,17 @@ export function displayDiff(diff: InstructionDiff, baseAddr: bigint, cb: (text:
cb({type: 'spacing', count: 4});
}
cb({type: 'opcode', mnemonic: ins.mnemonic, opcode: ins.opcode});
let arg_diff_idx = 0; // non-PlainText argument index
for (let i = 0; i < ins.arguments.length; i++) {
if (i === 0) {
cb({type: 'spacing', count: 1});
}
const arg = ins.arguments[i].value;
const diff_index = diff.arg_diff[i]?.diff_index;
let diff_index: number | undefined;
if (arg.oneofKind !== 'plain_text') {
diff_index = diff.arg_diff[arg_diff_idx]?.diff_index;
arg_diff_idx++;
}
switch (arg.oneofKind) {
case "plain_text":
cb({type: 'basic', text: arg.plain_text, diff_index});

View File

@ -73,12 +73,19 @@ self.onmessage = (event: MessageEvent<InMessage>) => {
const result = await handler(data as never);
const end = performance.now();
console.debug(`Worker message ${data.messageId} took ${end - start}ms`);
let transfer: Transferable[] = [];
if (result instanceof Uint8Array) {
console.log("Transferring!", result.byteLength);
transfer = [result.buffer];
} else {
console.log("Didn't transfer", typeof result);
}
self.postMessage({
type: 'result',
result: result,
error: null,
messageId,
} as OutMessage);
} as OutMessage, {transfer});
} else {
throw new Error(`No handler for ${data.type}`);
}