mirror of
https://github.com/encounter/objdiff.git
synced 2026-07-10 12:18:36 -07:00
Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3cebee6766 | |||
| ab0538e9a4 | |||
| b643265809 | |||
| 7a65e07e9b | |||
| 3c4092b965 | |||
| 0f599bea2b | |||
| 9927fc35b6 | |||
| 16fb6a491f | |||
| 2541aef71a | |||
| 7ad1f95bf7 | |||
| 66c879a95d | |||
| d53c358d2f | |||
| f24c017545 |
@@ -62,7 +62,7 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
checks:
|
||||
- advisories
|
||||
# - advisories
|
||||
- bans licenses sources
|
||||
# Prevent new advisories from failing CI
|
||||
continue-on-error: ${{ matrix.checks == 'advisories' }}
|
||||
|
||||
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.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"argp",
|
||||
@@ -3514,7 +3514,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "objdiff-core"
|
||||
version = "3.6.0"
|
||||
version = "3.7.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"arm-attr",
|
||||
@@ -3570,7 +3570,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "objdiff-gui"
|
||||
version = "3.6.0"
|
||||
version = "3.7.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"argp",
|
||||
@@ -3608,7 +3608,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "objdiff-wasm"
|
||||
version = "3.6.0"
|
||||
version = "3.7.1"
|
||||
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.1"
|
||||
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.
@@ -162,7 +162,7 @@ impl ArchArm {
|
||||
}
|
||||
|
||||
impl Arch for ArchArm {
|
||||
fn post_init(&mut self, sections: &[Section], symbols: &[Symbol]) {
|
||||
fn post_init(&mut self, sections: &[Section], symbols: &[Symbol], _symbol_indices: &[usize]) {
|
||||
self.disasm_modes = Self::get_mapping_symbols(sections, symbols);
|
||||
}
|
||||
|
||||
@@ -224,7 +224,9 @@ impl Arch for ArchArm {
|
||||
}
|
||||
|
||||
// Check how many bytes we can/should read
|
||||
let num_code_bytes = if data.len() >= 4 {
|
||||
let bytes_until_next_mapping =
|
||||
next_mapping.map(|m| (m.address - address) as usize).unwrap_or(usize::MAX);
|
||||
let num_code_bytes = if data.len() >= 4 && bytes_until_next_mapping >= 4 {
|
||||
if mode == unarm::ParseMode::Data && address & 3 != 0 {
|
||||
// 32-bit .word value should be aligned on a 4-byte boundary, otherwise use .hword
|
||||
2
|
||||
@@ -366,6 +368,22 @@ impl Arch for ArchArm {
|
||||
(imm22 << 1) << 9 >> 9
|
||||
}
|
||||
|
||||
// Thumb unconditional branch (B, 11-bit offset)
|
||||
elf::R_ARM_THM_PC11 => {
|
||||
let data = section_data[address..address + 2].try_into()?;
|
||||
let insn = self.endianness.read_u16_bytes(data) as i32;
|
||||
let imm11 = insn & 0x7ff;
|
||||
(imm11 << 1) << 20 >> 20
|
||||
}
|
||||
|
||||
// Thumb conditional branch (B<cond>, 8-bit offset)
|
||||
elf::R_ARM_THM_PC9 => {
|
||||
let data = section_data[address..address + 2].try_into()?;
|
||||
let insn = self.endianness.read_u16_bytes(data) as i32;
|
||||
let imm8 = insn & 0xff;
|
||||
(imm8 << 1) << 23 >> 23
|
||||
}
|
||||
|
||||
// Data
|
||||
elf::R_ARM_ABS32 => {
|
||||
let data = section_data[address..address + 4].try_into()?;
|
||||
@@ -399,6 +417,8 @@ impl Arch for ArchArm {
|
||||
elf::R_ARM_PC24 => Some("R_ARM_PC24"),
|
||||
elf::R_ARM_XPC25 => Some("R_ARM_XPC25"),
|
||||
elf::R_ARM_CALL => Some("R_ARM_CALL"),
|
||||
elf::R_ARM_THM_PC11 => Some("R_ARM_THM_PC11"),
|
||||
elf::R_ARM_THM_PC9 => Some("R_ARM_THM_PC9"),
|
||||
_ => None,
|
||||
},
|
||||
_ => None,
|
||||
@@ -418,6 +438,8 @@ impl Arch for ArchArm {
|
||||
elf::R_ARM_PC24 => 4,
|
||||
elf::R_ARM_XPC25 => 4,
|
||||
elf::R_ARM_CALL => 4,
|
||||
elf::R_ARM_THM_PC11 => 2,
|
||||
elf::R_ARM_THM_PC9 => 2,
|
||||
_ => 1,
|
||||
},
|
||||
_ => 1,
|
||||
@@ -544,7 +566,9 @@ impl unarm::FormatIns for ArgsFormatter<'_> {
|
||||
| RelocationFlags::Elf(elf::R_ARM_THM_PC22)
|
||||
| RelocationFlags::Elf(elf::R_ARM_PC24)
|
||||
| RelocationFlags::Elf(elf::R_ARM_XPC25)
|
||||
| RelocationFlags::Elf(elf::R_ARM_CALL) => {
|
||||
| RelocationFlags::Elf(elf::R_ARM_CALL)
|
||||
| RelocationFlags::Elf(elf::R_ARM_THM_PC11)
|
||||
| RelocationFlags::Elf(elf::R_ARM_THM_PC9) => {
|
||||
return self.write(InstructionPart::reloc());
|
||||
}
|
||||
_ => {}
|
||||
|
||||
@@ -340,7 +340,8 @@ impl dyn Arch {
|
||||
|
||||
pub trait Arch: Any + Debug + Send + Sync {
|
||||
/// Finishes arch-specific initialization that must be done after sections have been combined.
|
||||
fn post_init(&mut self, _sections: &[Section], _symbols: &[Symbol]) {}
|
||||
fn post_init(&mut self, _sections: &[Section], _symbols: &[Symbol], _symbol_indices: &[usize]) {
|
||||
}
|
||||
|
||||
/// Generate a list of instructions references (offset, size, opcode) from the given code.
|
||||
///
|
||||
|
||||
@@ -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:?}")),
|
||||
},
|
||||
@@ -472,12 +472,27 @@ impl Arch for ArchPpc {
|
||||
}
|
||||
Ok(next_address.saturating_sub(symbol.address))
|
||||
}
|
||||
|
||||
fn post_init(&mut self, _sections: &[Section], _symbols: &[Symbol], symbol_indices: &[usize]) {
|
||||
// Change the indices used as keys from the original symbol indices to the new symbol array indices
|
||||
self.extab = Self::convert_extab_map_indices(self, symbol_indices);
|
||||
}
|
||||
}
|
||||
|
||||
impl ArchPpc {
|
||||
pub fn extab_for_symbol(&self, symbol_index: usize) -> Option<&ExceptionInfo> {
|
||||
self.extab.as_ref()?.get(&symbol_index)
|
||||
}
|
||||
|
||||
pub fn convert_extab_map_indices(
|
||||
&self,
|
||||
symbol_indices: &[usize],
|
||||
) -> Option<BTreeMap<usize, ExceptionInfo>> {
|
||||
let new_map: BTreeMap<usize, ExceptionInfo> =
|
||||
self.extab.as_ref()?.iter().map(|e| (symbol_indices[*e.0 + 1], e.1.clone())).collect();
|
||||
|
||||
Some(new_map)
|
||||
}
|
||||
}
|
||||
|
||||
fn zero_reloc(code: u32, reloc: &Relocation) -> u32 {
|
||||
|
||||
@@ -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);
|
||||
@@ -1064,7 +1089,7 @@ pub fn parse(data: &[u8], config: &DiffObjConfig, diff_side: DiffSide) -> Result
|
||||
combine_sections(&mut sections, &mut symbols, config)?;
|
||||
}
|
||||
add_section_symbols(§ions, &mut symbols);
|
||||
arch.post_init(§ions, &symbols);
|
||||
arch.post_init(§ions, &symbols, &symbol_indices);
|
||||
let mut obj = Object {
|
||||
arch,
|
||||
endianness: obj_file.endianness(),
|
||||
|
||||
@@ -57,6 +57,31 @@ fn combine_text_sections() {
|
||||
insta::assert_snapshot!(output);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(feature = "arm")]
|
||||
fn thumb_short_data_mapping() {
|
||||
// When a .2byte directive is used in Thumb code, the assembler emits
|
||||
// $d/$t mapping symbols for a 2-byte data region. The disassembler must
|
||||
// not read 4 bytes as a .word when the next mapping symbol limits the
|
||||
// data region to 2 bytes.
|
||||
let diff_config = diff::DiffObjConfig::default();
|
||||
let obj = obj::read::parse(
|
||||
include_object!("data/arm/code_1_vblank.o"),
|
||||
&diff_config,
|
||||
diff::DiffSide::Base,
|
||||
)
|
||||
.unwrap();
|
||||
let symbol_idx = obj.symbols.iter().position(|s| s.name == "VBlankDMA_Level1").unwrap();
|
||||
let diff = diff::code::no_diff_code(&obj, symbol_idx, &diff_config).unwrap();
|
||||
let output = common::display_diff(&obj, &diff, symbol_idx, &diff_config);
|
||||
// .2byte data followed by Thumb code must not be merged into a 4-byte .word
|
||||
assert!(
|
||||
!output.contains(".word"),
|
||||
"2-byte data regions should not be decoded as 4-byte .word values.\n\
|
||||
The disassembler must respect mapping symbol boundaries."
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(feature = "arm")]
|
||||
fn trim_trailing_hword() {
|
||||
|
||||
Binary file not shown.
@@ -9,7 +9,7 @@ Object {
|
||||
),
|
||||
extab: Some(
|
||||
{
|
||||
10: ExceptionInfo {
|
||||
1: ExceptionInfo {
|
||||
eti_symbol: ExtabSymbolRef {
|
||||
original_index: 5,
|
||||
name: "@31",
|
||||
@@ -35,7 +35,7 @@ Object {
|
||||
},
|
||||
dtors: [],
|
||||
},
|
||||
11: ExceptionInfo {
|
||||
2: ExceptionInfo {
|
||||
eti_symbol: ExtabSymbolRef {
|
||||
original_index: 7,
|
||||
name: "@52",
|
||||
@@ -95,7 +95,7 @@ Object {
|
||||
},
|
||||
],
|
||||
},
|
||||
12: ExceptionInfo {
|
||||
3: ExceptionInfo {
|
||||
eti_symbol: ExtabSymbolRef {
|
||||
original_index: 9,
|
||||
name: "@60",
|
||||
|
||||
@@ -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.1",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "objdiff-wasm",
|
||||
"version": "3.6.0",
|
||||
"version": "3.7.1",
|
||||
"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.1",
|
||||
"description": "A local diffing tool for decompilation projects.",
|
||||
"author": {
|
||||
"name": "Luke Street",
|
||||
|
||||
@@ -572,7 +572,7 @@ impl GuestDiffConfig for ResourceDiffConfig {
|
||||
}
|
||||
}
|
||||
|
||||
struct CachedObject(Weak<obj::Object>, u64);
|
||||
struct CachedObject(Weak<obj::Object>, u64, diff::DiffSide);
|
||||
|
||||
struct ObjectCache(RefCell<Vec<CachedObject>>);
|
||||
|
||||
@@ -608,12 +608,13 @@ impl GuestObject for ResourceObject {
|
||||
diff_side: DiffSide,
|
||||
) -> Result<Object, String> {
|
||||
let hash = xxh3_64(&data);
|
||||
let core_diff_side: objdiff_core::diff::DiffSide = diff_side.into();
|
||||
let mut cached = None;
|
||||
OBJECT_CACHE.borrow_mut().retain(|c| {
|
||||
if c.0.strong_count() == 0 {
|
||||
return false;
|
||||
}
|
||||
if c.1 == hash {
|
||||
if c.1 == hash && c.2 == core_diff_side {
|
||||
cached = c.0.upgrade();
|
||||
}
|
||||
true
|
||||
@@ -623,9 +624,9 @@ impl GuestObject for ResourceObject {
|
||||
}
|
||||
let diff_config = diff_config.get::<ResourceDiffConfig>().0.borrow();
|
||||
let obj = Rc::new(
|
||||
obj::read::parse(&data, &diff_config, diff_side.into()).map_err(|e| e.to_string())?,
|
||||
obj::read::parse(&data, &diff_config, core_diff_side).map_err(|e| e.to_string())?,
|
||||
);
|
||||
OBJECT_CACHE.borrow_mut().push(CachedObject(Rc::downgrade(&obj), hash));
|
||||
OBJECT_CACHE.borrow_mut().push(CachedObject(Rc::downgrade(&obj), hash, core_diff_side));
|
||||
Ok(Object::new(ResourceObject(obj, hash)))
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user