mirror of
https://github.com/encounter/objdiff.git
synced 2026-07-10 12:18:36 -07:00
Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0f599bea2b | |||
| 9927fc35b6 | |||
| 16fb6a491f | |||
| 2541aef71a | |||
| 7ad1f95bf7 | |||
| 66c879a95d | |||
| d53c358d2f | |||
| f24c017545 |
Generated
+15
-15
@@ -598,9 +598,9 @@ checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495"
|
||||
|
||||
[[package]]
|
||||
name = "bytes"
|
||||
version = "1.11.0"
|
||||
version = "1.11.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3"
|
||||
checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33"
|
||||
|
||||
[[package]]
|
||||
name = "calloop"
|
||||
@@ -3157,9 +3157,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "num-conv"
|
||||
version = "0.1.0"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9"
|
||||
checksum = "cf97ec579c3c42f953ef76dbf8d55ac91fb219dde70e49aa4a6b7d74e9919050"
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
@@ -3491,7 +3491,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "objdiff-cli"
|
||||
version = "3.6.0"
|
||||
version = "3.7.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"argp",
|
||||
@@ -3514,7 +3514,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "objdiff-core"
|
||||
version = "3.6.0"
|
||||
version = "3.7.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"arm-attr",
|
||||
@@ -3570,7 +3570,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "objdiff-gui"
|
||||
version = "3.6.0"
|
||||
version = "3.7.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"argp",
|
||||
@@ -3608,7 +3608,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "objdiff-wasm"
|
||||
version = "3.6.0"
|
||||
version = "3.7.0"
|
||||
dependencies = [
|
||||
"log",
|
||||
"objdiff-core",
|
||||
@@ -5327,9 +5327,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "time"
|
||||
version = "0.3.44"
|
||||
version = "0.3.47"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "91e7d9e3bb61134e77bde20dd4825b97c010155709965fedf0f49bb138e52a9d"
|
||||
checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c"
|
||||
dependencies = [
|
||||
"deranged",
|
||||
"itoa",
|
||||
@@ -5337,22 +5337,22 @@ dependencies = [
|
||||
"num-conv",
|
||||
"num_threads",
|
||||
"powerfmt",
|
||||
"serde",
|
||||
"serde_core",
|
||||
"time-core",
|
||||
"time-macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "time-core"
|
||||
version = "0.1.6"
|
||||
version = "0.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "40868e7c1d2f0b8d73e4a8c7f0ff63af4f6d19be117e90bd73eb1d62cf831c6b"
|
||||
checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca"
|
||||
|
||||
[[package]]
|
||||
name = "time-macros"
|
||||
version = "0.2.24"
|
||||
version = "0.2.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "30cfb0125f12d9c277f35663a0a33f8c30190f4e4574868a330595412d34ebf3"
|
||||
checksum = "2e70e4c5a0e0a8a4823ad65dfe1a6930e4f4d756dcd9dd7939022b5e8c501215"
|
||||
dependencies = [
|
||||
"num-conv",
|
||||
"time-core",
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@ default-members = [
|
||||
resolver = "3"
|
||||
|
||||
[workspace.package]
|
||||
version = "3.6.0"
|
||||
version = "3.7.0"
|
||||
authors = ["Luke Street <luke@street.dev>"]
|
||||
edition = "2024"
|
||||
license = "MIT OR Apache-2.0"
|
||||
|
||||
@@ -39,7 +39,8 @@ message DiffSymbol {
|
||||
optional string demangled_name = 2;
|
||||
uint64 address = 3;
|
||||
uint64 size = 4;
|
||||
uint32 flags = 5;
|
||||
DiffSymbolFlags flags = 5;
|
||||
DiffSymbolKind kind = 10;
|
||||
// The symbol index in the _other_ object that this symbol was diffed against
|
||||
optional uint32 target_symbol = 6;
|
||||
optional float match_percent = 7;
|
||||
@@ -49,14 +50,22 @@ message DiffSymbol {
|
||||
repeated DiffDataSegment data_diff = 9;
|
||||
}
|
||||
|
||||
// Symbol visibility flags (bitmask)
|
||||
enum DiffSymbolFlag {
|
||||
SYMBOL_NONE = 0;
|
||||
SYMBOL_GLOBAL = 1;
|
||||
SYMBOL_LOCAL = 2;
|
||||
SYMBOL_WEAK = 4;
|
||||
SYMBOL_COMMON = 8;
|
||||
SYMBOL_HIDDEN = 16;
|
||||
enum DiffSymbolKind {
|
||||
SYMBOL_UNKNOWN = 0;
|
||||
SYMBOL_FUNCTION = 1;
|
||||
SYMBOL_OBJECT = 2;
|
||||
SYMBOL_SECTION = 3;
|
||||
}
|
||||
|
||||
// Symbol flags
|
||||
message DiffSymbolFlags {
|
||||
bool global = 1;
|
||||
bool local = 2;
|
||||
bool weak = 3;
|
||||
bool common = 4;
|
||||
bool hidden = 5;
|
||||
bool ignored = 6;
|
||||
bool size_inferred = 7;
|
||||
}
|
||||
|
||||
// A single instruction diff row
|
||||
|
||||
Binary file not shown.
@@ -238,9 +238,9 @@ impl Arch for ArchPpc {
|
||||
addend: 0,
|
||||
})),
|
||||
|(_, reloc)| match reloc.target() {
|
||||
object::RelocationTarget::Symbol(index) => Ok(Some(RelocationOverride {
|
||||
object::RelocationTarget::Symbol(_) => Ok(Some(RelocationOverride {
|
||||
target: RelocationOverrideTarget::Keep,
|
||||
addend: index.0 as u16 as i16 as i64,
|
||||
addend: 0,
|
||||
})),
|
||||
target => Err(anyhow!("Unsupported IMAGE_REL_PPC_PAIR target {target:?}")),
|
||||
},
|
||||
|
||||
@@ -43,9 +43,6 @@ impl DiffObject {
|
||||
let mut symbols = Vec::with_capacity(obj.symbols.len());
|
||||
for (symbol_idx, symbol) in obj.symbols.iter().enumerate() {
|
||||
let symbol_diff = &diff.symbols[symbol_idx];
|
||||
if symbol.size == 0 || symbol.flags.contains(SymbolFlag::Ignored) {
|
||||
continue;
|
||||
}
|
||||
symbols.push(DiffSymbol::new(obj, symbol_idx, symbol, symbol_diff, diff_config)?);
|
||||
}
|
||||
|
||||
@@ -112,6 +109,7 @@ impl DiffSymbol {
|
||||
address: symbol.address,
|
||||
size: symbol.size,
|
||||
flags: symbol_flags(&symbol.flags),
|
||||
kind: DiffSymbolKind::from(symbol.kind) as i32,
|
||||
// Diff information
|
||||
target_symbol: symbol_diff.target_symbol.map(|i| i as u32),
|
||||
match_percent: symbol_diff.match_percent,
|
||||
@@ -121,24 +119,27 @@ impl DiffSymbol {
|
||||
}
|
||||
}
|
||||
|
||||
fn symbol_flags(flags: &obj::SymbolFlagSet) -> u32 {
|
||||
let mut result = 0u32;
|
||||
if flags.contains(SymbolFlag::Global) {
|
||||
result |= DiffSymbolFlag::SymbolGlobal as u32;
|
||||
impl From<obj::SymbolKind> for DiffSymbolKind {
|
||||
fn from(value: obj::SymbolKind) -> Self {
|
||||
match value {
|
||||
obj::SymbolKind::Unknown => DiffSymbolKind::SymbolUnknown,
|
||||
obj::SymbolKind::Function => DiffSymbolKind::SymbolFunction,
|
||||
obj::SymbolKind::Object => DiffSymbolKind::SymbolObject,
|
||||
obj::SymbolKind::Section => DiffSymbolKind::SymbolSection,
|
||||
}
|
||||
}
|
||||
if flags.contains(SymbolFlag::Local) {
|
||||
result |= DiffSymbolFlag::SymbolLocal as u32;
|
||||
}
|
||||
if flags.contains(SymbolFlag::Weak) {
|
||||
result |= DiffSymbolFlag::SymbolWeak as u32;
|
||||
}
|
||||
if flags.contains(SymbolFlag::Common) {
|
||||
result |= DiffSymbolFlag::SymbolCommon as u32;
|
||||
}
|
||||
if flags.contains(SymbolFlag::Hidden) {
|
||||
result |= DiffSymbolFlag::SymbolHidden as u32;
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
fn symbol_flags(flags: &obj::SymbolFlagSet) -> Option<DiffSymbolFlags> {
|
||||
Some(DiffSymbolFlags {
|
||||
global: flags.contains(SymbolFlag::Global),
|
||||
local: flags.contains(SymbolFlag::Local),
|
||||
weak: flags.contains(SymbolFlag::Weak),
|
||||
common: flags.contains(SymbolFlag::Common),
|
||||
hidden: flags.contains(SymbolFlag::Hidden),
|
||||
ignored: flags.contains(SymbolFlag::Ignored),
|
||||
size_inferred: flags.contains(SymbolFlag::SizeInferred),
|
||||
})
|
||||
}
|
||||
|
||||
impl DiffInstructionRow {
|
||||
|
||||
@@ -5,6 +5,7 @@ use typed_path::{Utf8PlatformPathBuf, Utf8UnixPathBuf};
|
||||
|
||||
use crate::{
|
||||
build::{BuildConfig, BuildStatus, run_make},
|
||||
diff::Demangler,
|
||||
jobs::{Job, JobContext, JobResult, JobState, start_job, update_status},
|
||||
};
|
||||
|
||||
@@ -21,6 +22,7 @@ pub struct CreateScratchConfig {
|
||||
pub function_name: String,
|
||||
pub target_obj: Utf8PlatformPathBuf,
|
||||
pub preset_id: Option<u32>,
|
||||
pub demangler: Demangler,
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Clone)]
|
||||
@@ -74,7 +76,14 @@ fn run_create_scratch(
|
||||
.text("diff_label", config.function_name.clone())
|
||||
.text("diff_flags", diff_flags)
|
||||
.text("context", context.unwrap_or_default())
|
||||
.text("source_code", "// Move related code from Context tab to here");
|
||||
.text("source_code", "// Move related code from Context tab to here")
|
||||
.text(
|
||||
"name",
|
||||
config
|
||||
.demangler
|
||||
.demangle(&config.function_name)
|
||||
.unwrap_or_else(|| config.function_name.clone()),
|
||||
);
|
||||
if let Some(preset) = config.preset_id {
|
||||
form = form.text("preset", preset.to_string());
|
||||
}
|
||||
|
||||
@@ -40,6 +40,7 @@ fn map_section_kind(section: &object::Section) -> SectionKind {
|
||||
/// e.g. symbol$1234 and symbol$2345 will both be replaced with symbol$0000 internally.
|
||||
fn get_normalized_symbol_name(name: &str) -> Option<String> {
|
||||
const DUMMY_UNIQUE_ID: &str = "0000";
|
||||
const DUMMY_UNIQUE_MSVC_ID: &str = "00000000";
|
||||
if let Some((prefix, suffix)) = name.split_once("@class$")
|
||||
&& let Some(idx) = suffix.chars().position(|c| !c.is_numeric())
|
||||
&& idx > 0
|
||||
@@ -59,6 +60,26 @@ fn get_normalized_symbol_name(name: &str) -> Option<String> {
|
||||
{
|
||||
// Match GCC symbol.1234 against symbol.2345
|
||||
Some(format!("{prefix}.{DUMMY_UNIQUE_ID}"))
|
||||
} else if name.starts_with('?') {
|
||||
// Match MSVC anonymous class symbol names, ignoring the unique ID.
|
||||
// e.g. ?CheckContextOr@?A0x24773155@@YA_NPBVDataArray@@@Z
|
||||
// and: ?CheckContextOr@?A0xddf6240c@@YA_NPBVDataArray@@@Z
|
||||
let mut name_str = String::from(name);
|
||||
let anon_indices: Vec<usize> = name_str.match_indices("?A0x").map(|(idx, _)| idx).collect();
|
||||
if !anon_indices.is_empty() {
|
||||
for idx in anon_indices {
|
||||
// the str sequence we're looking for is: ?A0xXXXXXXXX@@
|
||||
if u32::from_str_radix(&name_str[idx + 4..idx + 12], 16).is_ok()
|
||||
&& &name_str[idx + 12..idx + 14] == "@@"
|
||||
{
|
||||
// if the two above checks passed, we're good to replace the hash
|
||||
name_str.replace_range(idx + 4..idx + 12, DUMMY_UNIQUE_MSVC_ID);
|
||||
}
|
||||
}
|
||||
Some(name_str)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
@@ -874,8 +895,12 @@ fn combine_sections(
|
||||
let mut data_sections = BTreeMap::<String, Vec<usize>>::new();
|
||||
let mut text_sections = BTreeMap::<String, Vec<usize>>::new();
|
||||
for (i, section) in sections.iter().enumerate() {
|
||||
let base_name =
|
||||
if let Some(i) = section.name.rfind('$') { §ion.name[..i] } else { §ion.name };
|
||||
let base_name = section
|
||||
.name
|
||||
.get(1..)
|
||||
.and_then(|s| s.rfind(['$', '.']))
|
||||
.and_then(|i| section.name.get(..i + 1))
|
||||
.unwrap_or(§ion.name);
|
||||
match section.kind {
|
||||
SectionKind::Data | SectionKind::Bss => {
|
||||
data_sections.entry(base_name.to_string()).or_default().push(i);
|
||||
|
||||
@@ -75,6 +75,7 @@ fn create_scratch_config(
|
||||
function_name,
|
||||
target_obj: target_path.clone(),
|
||||
preset_id: scratch_config.preset_id,
|
||||
demangler: state.effective_diff_config().demangler,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
Generated
+2
-2
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "objdiff-wasm",
|
||||
"version": "3.6.0",
|
||||
"version": "3.7.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "objdiff-wasm",
|
||||
"version": "3.6.0",
|
||||
"version": "3.7.0",
|
||||
"license": "MIT OR Apache-2.0",
|
||||
"devDependencies": {
|
||||
"@biomejs/biome": "^1.9.3",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "objdiff-wasm",
|
||||
"version": "3.6.0",
|
||||
"version": "3.7.0",
|
||||
"description": "A local diffing tool for decompilation projects.",
|
||||
"author": {
|
||||
"name": "Luke Street",
|
||||
|
||||
Reference in New Issue
Block a user