mirror of
https://github.com/encounter/objdiff.git
synced 2025-12-21 02:39:28 +00:00
Compare commits
27 Commits
v3.0.0-bet
...
v3.0.0-bet
| Author | SHA1 | Date | |
|---|---|---|---|
| bd3ed0d5ad | |||
|
|
e638d0b17a | ||
|
|
f58616b6dd | ||
|
|
e9762e24c2 | ||
| dab79d96a1 | |||
| a57e5db983 | |||
|
|
d0afd3b83e | ||
|
|
a367af612b | ||
|
|
22052ea10b | ||
| f7c3501eae | |||
| 07ef93f16a | |||
| 8e8ab6bef8 | |||
| e865f3d598 | |||
| 2b13e9886a | |||
| 1750af736a | |||
|
|
731b604c24 | ||
| 2d643eb071 | |||
| 0c48d711c7 | |||
| 34220a8e26 | |||
| 0c9e5526d4 | |||
| 3db0727469 | |||
| 8b5bf21f38 | |||
| b77df77000 | |||
| 7e08f9715b | |||
| 3c05852d00 | |||
| a51ff44be1 | |||
| d225cac205 |
@@ -1,5 +1,4 @@
|
|||||||
[target.x86_64-pc-windows-msvc]
|
# statically link the C runtime so the executable does not depend on
|
||||||
linker = "rust-lld"
|
# that shared/dynamic library.
|
||||||
|
[target.'cfg(all(target_env = "msvc", target_os = "windows"))']
|
||||||
[target.aarch64-pc-windows-msvc]
|
rustflags = ["-C", "target-feature=+crt-static"]
|
||||||
linker = "rust-lld"
|
|
||||||
|
|||||||
689
Cargo.lock
generated
689
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -14,7 +14,7 @@ strip = "debuginfo"
|
|||||||
codegen-units = 1
|
codegen-units = 1
|
||||||
|
|
||||||
[workspace.package]
|
[workspace.package]
|
||||||
version = "3.0.0-beta.6"
|
version = "3.0.0-beta.10"
|
||||||
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"
|
||||||
|
|||||||
@@ -16,11 +16,12 @@ Features:
|
|||||||
|
|
||||||
Supports:
|
Supports:
|
||||||
|
|
||||||
- PowerPC 750CL (GameCube, Wii)
|
|
||||||
- MIPS (N64, PS1, PS2, PSP)
|
|
||||||
- x86 (COFF only at the moment)
|
|
||||||
- ARM (GBA, DS, 3DS)
|
- ARM (GBA, DS, 3DS)
|
||||||
- ARM64 (Switch, experimental)
|
- ARM64 (Switch)
|
||||||
|
- MIPS (N64, PS1, PS2, PSP)
|
||||||
|
- PowerPC (GameCube, Wii)
|
||||||
|
- SuperH (Saturn, Dreamcast)
|
||||||
|
- x86, x86_64 (PC)
|
||||||
|
|
||||||
See [Usage](#usage) for more information.
|
See [Usage](#usage) for more information.
|
||||||
|
|
||||||
|
|||||||
@@ -175,6 +175,10 @@
|
|||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"description": "If true, objdiff will run the build command with the context file as an argument to generate it.",
|
"description": "If true, objdiff will run the build command with the context file as an argument to generate it.",
|
||||||
"default": false
|
"default": false
|
||||||
|
},
|
||||||
|
"preset_id": {
|
||||||
|
"type": "number",
|
||||||
|
"description": "The decomp.me preset ID to use for the scratch.\nCompiler and flags in the config will take precedence over the preset, but the preset is useful for organizational purposes."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"required": [
|
"required": [
|
||||||
|
|||||||
@@ -103,6 +103,7 @@ allow = [
|
|||||||
"0BSD",
|
"0BSD",
|
||||||
"OFL-1.1",
|
"OFL-1.1",
|
||||||
"Ubuntu-font-1.0",
|
"Ubuntu-font-1.0",
|
||||||
|
"CDLA-Permissive-2.0",
|
||||||
]
|
]
|
||||||
# The confidence threshold for detecting a license from license text.
|
# The confidence threshold for detecting a license from license text.
|
||||||
# The higher the value, the more closely the license text must be to the
|
# The higher the value, the more closely the license text must be to the
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ supports-color = "3.0"
|
|||||||
time = { version = "0.3", features = ["formatting", "local-offset"] }
|
time = { version = "0.3", features = ["formatting", "local-offset"] }
|
||||||
tracing = "0.1"
|
tracing = "0.1"
|
||||||
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
|
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
|
||||||
typed-path = "0.10"
|
typed-path = "0.11"
|
||||||
|
|
||||||
[target.'cfg(target_env = "musl")'.dependencies]
|
[target.'cfg(target_env = "musl")'.dependencies]
|
||||||
mimalloc = "0.1"
|
mimalloc = "0.1"
|
||||||
|
|||||||
@@ -85,6 +85,9 @@ pub fn run(args: Args) -> Result<()> {
|
|||||||
fn generate(args: GenerateArgs) -> Result<()> {
|
fn generate(args: GenerateArgs) -> Result<()> {
|
||||||
let mut diff_config = diff::DiffObjConfig {
|
let mut diff_config = diff::DiffObjConfig {
|
||||||
function_reloc_diffs: diff::FunctionRelocDiffs::None,
|
function_reloc_diffs: diff::FunctionRelocDiffs::None,
|
||||||
|
combine_data_sections: true,
|
||||||
|
combine_text_sections: true,
|
||||||
|
ppc_calculate_pool_relocations: false,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
apply_config_args(&mut diff_config, &args.config)?;
|
apply_config_args(&mut diff_config, &args.config)?;
|
||||||
@@ -225,6 +228,7 @@ fn report_object(
|
|||||||
demangled_name: None,
|
demangled_name: None,
|
||||||
virtual_address: section.virtual_address,
|
virtual_address: section.virtual_address,
|
||||||
}),
|
}),
|
||||||
|
address: None,
|
||||||
});
|
});
|
||||||
|
|
||||||
match section.kind {
|
match section.kind {
|
||||||
@@ -272,6 +276,7 @@ fn report_object(
|
|||||||
demangled_name: symbol.demangled_name.clone(),
|
demangled_name: symbol.demangled_name.clone(),
|
||||||
virtual_address: symbol.virtual_address,
|
virtual_address: symbol.virtual_address,
|
||||||
}),
|
}),
|
||||||
|
address: symbol.address.checked_sub(section.address),
|
||||||
});
|
});
|
||||||
if match_percent == 100.0 {
|
if match_percent == 100.0 {
|
||||||
measures.matched_functions += 1;
|
measures.matched_functions += 1;
|
||||||
@@ -279,6 +284,16 @@ fn report_object(
|
|||||||
measures.total_functions += 1;
|
measures.total_functions += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
sections.sort_by(|a, b| a.name.cmp(&b.name));
|
||||||
|
let reverse_fn_order = object.metadata.reverse_fn_order.unwrap_or(false);
|
||||||
|
functions.sort_by(|a, b| {
|
||||||
|
if reverse_fn_order {
|
||||||
|
b.address.unwrap_or(0).cmp(&a.address.unwrap_or(0))
|
||||||
|
} else {
|
||||||
|
a.address.unwrap_or(u64::MAX).cmp(&b.address.unwrap_or(u64::MAX))
|
||||||
|
}
|
||||||
|
.then_with(|| a.size.cmp(&b.size))
|
||||||
|
});
|
||||||
if metadata.complete.unwrap_or(false) {
|
if metadata.complete.unwrap_or(false) {
|
||||||
measures.complete_code = measures.total_code;
|
measures.complete_code = measures.total_code;
|
||||||
measures.complete_data = measures.total_data;
|
measures.complete_data = measures.total_data;
|
||||||
|
|||||||
@@ -450,11 +450,11 @@ impl UiView for FunctionDiffUi {
|
|||||||
|
|
||||||
fn reload(&mut self, state: &AppState) -> Result<()> {
|
fn reload(&mut self, state: &AppState) -> Result<()> {
|
||||||
let left_sym =
|
let left_sym =
|
||||||
state.left_obj.as_ref().and_then(|(o, _)| find_function(o, &self.symbol_name));
|
state.left_obj.as_ref().and_then(|(o, _)| o.symbol_by_name(&self.symbol_name));
|
||||||
let right_sym =
|
let right_sym =
|
||||||
state.right_obj.as_ref().and_then(|(o, _)| find_function(o, &self.symbol_name));
|
state.right_obj.as_ref().and_then(|(o, _)| o.symbol_by_name(&self.symbol_name));
|
||||||
let prev_sym =
|
let prev_sym =
|
||||||
state.prev_obj.as_ref().and_then(|(o, _)| find_function(o, &self.symbol_name));
|
state.prev_obj.as_ref().and_then(|(o, _)| o.symbol_by_name(&self.symbol_name));
|
||||||
self.num_rows = match (
|
self.num_rows = match (
|
||||||
get_symbol(state.left_obj.as_ref(), left_sym),
|
get_symbol(state.left_obj.as_ref(), left_sym),
|
||||||
get_symbol(state.right_obj.as_ref(), right_sym),
|
get_symbol(state.right_obj.as_ref(), right_sym),
|
||||||
@@ -570,6 +570,7 @@ impl FunctionDiffUi {
|
|||||||
DiffTextColor::Normal => Color::Gray,
|
DiffTextColor::Normal => Color::Gray,
|
||||||
DiffTextColor::Dim => Color::DarkGray,
|
DiffTextColor::Dim => Color::DarkGray,
|
||||||
DiffTextColor::Bright => Color::White,
|
DiffTextColor::Bright => Color::White,
|
||||||
|
DiffTextColor::DataFlow => Color::LightCyan,
|
||||||
DiffTextColor::Replace => Color::Cyan,
|
DiffTextColor::Replace => Color::Cyan,
|
||||||
DiffTextColor::Delete => Color::Red,
|
DiffTextColor::Delete => Color::Red,
|
||||||
DiffTextColor::Insert => Color::Green,
|
DiffTextColor::Insert => Color::Green,
|
||||||
@@ -650,12 +651,3 @@ fn get_symbol(
|
|||||||
let sym = sym?;
|
let sym = sym?;
|
||||||
Some((obj, sym, &diff.symbols[sym]))
|
Some((obj, sym, &diff.symbols[sym]))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_function(obj: &Object, name: &str) -> Option<usize> {
|
|
||||||
for (symbol_idx, symbol) in obj.symbols.iter().enumerate() {
|
|
||||||
if symbol.name == name {
|
|
||||||
return Some(symbol_idx);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
None
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -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",
|
||||||
@@ -133,7 +134,7 @@ prost = { version = "0.13", default-features = false, features = ["prost-derive"
|
|||||||
regex = { version = "1.11", default-features = false, features = [], optional = true }
|
regex = { version = "1.11", default-features = false, features = [], optional = true }
|
||||||
serde = { version = "1.0", default-features = false, features = ["derive"], optional = true }
|
serde = { version = "1.0", default-features = false, features = ["derive"], optional = true }
|
||||||
similar = { version = "2.7", default-features = false, features = ["hashbrown"], optional = true, git = "https://github.com/encounter/similar.git", branch = "no_std" }
|
similar = { version = "2.7", default-features = false, features = ["hashbrown"], optional = true, git = "https://github.com/encounter/similar.git", branch = "no_std" }
|
||||||
typed-path = { version = "0.10", default-features = false, optional = true }
|
typed-path = { version = "0.11", default-features = false, optional = true }
|
||||||
|
|
||||||
# config
|
# config
|
||||||
globset = { version = "0.4", default-features = false, optional = true }
|
globset = { version = "0.4", default-features = false, optional = true }
|
||||||
@@ -158,7 +159,7 @@ iced-x86 = { version = "1.21", default-features = false, features = ["decoder",
|
|||||||
msvc-demangler = { version = "0.11", optional = true }
|
msvc-demangler = { version = "0.11", optional = true }
|
||||||
|
|
||||||
# arm
|
# arm
|
||||||
unarm = { version = "1.7", optional = true }
|
unarm = { version = "1.8", optional = true }
|
||||||
arm-attr = { version = "0.2", optional = true }
|
arm-attr = { version = "0.2", optional = true }
|
||||||
|
|
||||||
# arm64
|
# arm64
|
||||||
@@ -171,10 +172,10 @@ 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, features = ["winbase"] }
|
||||||
|
|
||||||
# For Linux static binaries, use rustls
|
# For Linux static binaries, use rustls
|
||||||
[target.'cfg(target_os = "linux")'.dependencies]
|
[target.'cfg(target_os = "linux")'.dependencies]
|
||||||
@@ -200,4 +201,4 @@ syn = { version = "2.0", optional = true }
|
|||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
# Enable all features for tests
|
# Enable all features for tests
|
||||||
objdiff-core = { path = ".", features = ["all"] }
|
objdiff-core = { path = ".", features = ["all"] }
|
||||||
insta = "1.42"
|
insta = "1.43"
|
||||||
|
|||||||
@@ -5,11 +5,12 @@ objdiff-core contains the core functionality of [objdiff](https://github.com/enc
|
|||||||
## Crate feature flags
|
## Crate feature flags
|
||||||
|
|
||||||
- **`all`**: Enables all main features.
|
- **`all`**: Enables all main features.
|
||||||
|
- **`bindings`**: Enables serialization and deserialization of objdiff data structures.
|
||||||
- **`config`**: Enables objdiff configuration file support.
|
- **`config`**: Enables objdiff configuration file support.
|
||||||
- **`dwarf`**: Enables extraction of line number information from DWARF debug sections.
|
- **`dwarf`**: Enables extraction of line number information from DWARF debug sections.
|
||||||
- **`mips`**: Enables the MIPS backend powered by [rabbitizer](https://github.com/Decompollaborate/rabbitizer). (Note: C library with Rust bindings)
|
|
||||||
- **`ppc`**: Enables the PowerPC backend powered by [ppc750cl](https://github.com/encounter/ppc750cl).
|
|
||||||
- **`x86`**: Enables the x86 backend powered by [iced-x86](https://crates.io/crates/iced-x86).
|
|
||||||
- **`arm`**: Enables the ARM backend powered by [unarm](https://github.com/AetiasHax/unarm).
|
|
||||||
- **`arm64`**: Enables the ARM64 backend powered by [yaxpeax-arm](https://github.com/iximeow/yaxpeax-arm).
|
- **`arm64`**: Enables the ARM64 backend powered by [yaxpeax-arm](https://github.com/iximeow/yaxpeax-arm).
|
||||||
- **`bindings`**: Enables serialization and deserialization of objdiff data structures.
|
- **`arm`**: Enables the ARM backend powered by [unarm](https://github.com/AetiasHax/unarm).
|
||||||
|
- **`mips`**: Enables the MIPS backend powered by [rabbitizer](https://github.com/Decompollaborate/rabbitizer).
|
||||||
|
- **`ppc`**: Enables the PowerPC backend powered by [ppc750cl](https://github.com/encounter/ppc750cl).
|
||||||
|
- **`superh`**: Enables the SuperH backend powered by an included disassembler.
|
||||||
|
- **`x86`**: Enables the x86 backend powered by [iced-x86](https://crates.io/crates/iced-x86).
|
||||||
|
|||||||
@@ -25,6 +25,20 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"id": "analyzeDataFlow",
|
||||||
|
"type": "boolean",
|
||||||
|
"default": false,
|
||||||
|
"name": "(Experimental) Perform data flow analysis",
|
||||||
|
"description": "Use data flow analysis to display known information about register contents where possible"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "showDataFlow",
|
||||||
|
"type": "boolean",
|
||||||
|
"default": true,
|
||||||
|
"name": "Show data flow",
|
||||||
|
"description": "Show data flow analysis results in place of register name where present"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"id": "spaceBetweenArgs",
|
"id": "spaceBetweenArgs",
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
@@ -264,7 +278,8 @@
|
|||||||
"id": "ppc",
|
"id": "ppc",
|
||||||
"name": "PowerPC",
|
"name": "PowerPC",
|
||||||
"properties": [
|
"properties": [
|
||||||
"ppc.calculatePoolRelocations"
|
"ppc.calculatePoolRelocations",
|
||||||
|
"analyzeDataFlow"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
Binary file not shown.
@@ -99,6 +99,8 @@ message ReportItem {
|
|||||||
float fuzzy_match_percent = 3;
|
float fuzzy_match_percent = 3;
|
||||||
// Extra metadata for this item
|
// Extra metadata for this item
|
||||||
optional ReportItemMetadata metadata = 4;
|
optional ReportItemMetadata metadata = 4;
|
||||||
|
// Address of the item (section-relative offset)
|
||||||
|
optional uint64 address = 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extra metadata for an item
|
// Extra metadata for an item
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ use crate::{
|
|||||||
diff::{ArmArchVersion, ArmR9Usage, DiffObjConfig, display::InstructionPart},
|
diff::{ArmArchVersion, ArmR9Usage, DiffObjConfig, display::InstructionPart},
|
||||||
obj::{
|
obj::{
|
||||||
InstructionRef, Relocation, RelocationFlags, ResolvedInstructionRef, ResolvedRelocation,
|
InstructionRef, Relocation, RelocationFlags, ResolvedInstructionRef, ResolvedRelocation,
|
||||||
ScannedInstruction, Section, SectionKind, Symbol, SymbolFlag, SymbolFlagSet, SymbolKind,
|
Section, SectionKind, Symbol, SymbolFlag, SymbolFlagSet, SymbolKind,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -187,14 +187,14 @@ impl Arch for ArchArm {
|
|||||||
self.disasm_modes = Self::get_mapping_symbols(sections, symbols);
|
self.disasm_modes = Self::get_mapping_symbols(sections, symbols);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn scan_instructions(
|
fn scan_instructions_internal(
|
||||||
&self,
|
&self,
|
||||||
address: u64,
|
address: u64,
|
||||||
code: &[u8],
|
code: &[u8],
|
||||||
section_index: usize,
|
section_index: usize,
|
||||||
_relocations: &[Relocation],
|
_relocations: &[Relocation],
|
||||||
diff_config: &DiffObjConfig,
|
diff_config: &DiffObjConfig,
|
||||||
) -> Result<Vec<ScannedInstruction>> {
|
) -> Result<Vec<InstructionRef>> {
|
||||||
let start_addr = address as u32;
|
let start_addr = address as u32;
|
||||||
let end_addr = start_addr + code.len() as u32;
|
let end_addr = start_addr + code.len() as u32;
|
||||||
|
|
||||||
@@ -219,13 +219,13 @@ impl Arch for ArchArm {
|
|||||||
let mut next_mapping = mappings_iter.next();
|
let mut next_mapping = mappings_iter.next();
|
||||||
|
|
||||||
let ins_count = code.len() / mode.instruction_size(start_addr);
|
let ins_count = code.len() / mode.instruction_size(start_addr);
|
||||||
let mut ops = Vec::<ScannedInstruction>::with_capacity(ins_count);
|
let mut ops = Vec::<InstructionRef>::with_capacity(ins_count);
|
||||||
|
|
||||||
let parse_flags = self.parse_flags(diff_config);
|
let parse_flags = self.parse_flags(diff_config);
|
||||||
|
|
||||||
let mut address = start_addr;
|
let mut address = start_addr;
|
||||||
while address < end_addr {
|
while address < end_addr {
|
||||||
while let Some(next) = next_mapping.take_if(|x| address >= x.address) {
|
while let Some(next) = next_mapping.filter(|x| address >= x.address) {
|
||||||
// Change mapping
|
// Change mapping
|
||||||
mode = next.mapping;
|
mode = next.mapping;
|
||||||
next_mapping = mappings_iter.next();
|
next_mapping = mappings_iter.next();
|
||||||
@@ -235,12 +235,10 @@ impl Arch for ArchArm {
|
|||||||
let data = &code[(address - start_addr) as usize..];
|
let data = &code[(address - start_addr) as usize..];
|
||||||
if data.len() < ins_size {
|
if data.len() < ins_size {
|
||||||
// Push the remainder as data
|
// Push the remainder as data
|
||||||
ops.push(ScannedInstruction {
|
ops.push(InstructionRef {
|
||||||
ins_ref: InstructionRef {
|
address: address as u64,
|
||||||
address: address as u64,
|
size: data.len() as u8,
|
||||||
size: data.len() as u8,
|
opcode: u16::MAX,
|
||||||
opcode: u16::MAX,
|
|
||||||
},
|
|
||||||
branch_dest: None,
|
branch_dest: None,
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
@@ -256,12 +254,10 @@ impl Arch for ArchArm {
|
|||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
// Invalid instruction size
|
// Invalid instruction size
|
||||||
ops.push(ScannedInstruction {
|
ops.push(InstructionRef {
|
||||||
ins_ref: InstructionRef {
|
address: address as u64,
|
||||||
address: address as u64,
|
size: ins_size as u8,
|
||||||
size: ins_size as u8,
|
opcode: u16::MAX,
|
||||||
opcode: u16::MAX,
|
|
||||||
},
|
|
||||||
branch_dest: None,
|
branch_dest: None,
|
||||||
});
|
});
|
||||||
address += ins_size as u32;
|
address += ins_size as u32;
|
||||||
@@ -325,8 +321,10 @@ impl Arch for ArchArm {
|
|||||||
unarm::ParseMode::Data => (u16::MAX, None),
|
unarm::ParseMode::Data => (u16::MAX, None),
|
||||||
};
|
};
|
||||||
|
|
||||||
ops.push(ScannedInstruction {
|
ops.push(InstructionRef {
|
||||||
ins_ref: InstructionRef { address: address as u64, size: ins_size as u8, opcode },
|
address: address as u64,
|
||||||
|
size: ins_size as u8,
|
||||||
|
opcode,
|
||||||
branch_dest: branch_dest.map(|x| x as u64),
|
branch_dest: branch_dest.map(|x| x as u64),
|
||||||
});
|
});
|
||||||
address += ins_size as u32;
|
address += ins_size as u32;
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ use crate::{
|
|||||||
diff::{DiffObjConfig, display::InstructionPart},
|
diff::{DiffObjConfig, display::InstructionPart},
|
||||||
obj::{
|
obj::{
|
||||||
InstructionRef, Relocation, RelocationFlags, ResolvedInstructionRef, ResolvedRelocation,
|
InstructionRef, Relocation, RelocationFlags, ResolvedInstructionRef, ResolvedRelocation,
|
||||||
ScannedInstruction,
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -30,16 +29,16 @@ impl ArchArm64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Arch for ArchArm64 {
|
impl Arch for ArchArm64 {
|
||||||
fn scan_instructions(
|
fn scan_instructions_internal(
|
||||||
&self,
|
&self,
|
||||||
address: u64,
|
address: u64,
|
||||||
code: &[u8],
|
code: &[u8],
|
||||||
_section_index: usize,
|
_section_index: usize,
|
||||||
_relocations: &[Relocation],
|
_relocations: &[Relocation],
|
||||||
_diff_config: &DiffObjConfig,
|
_diff_config: &DiffObjConfig,
|
||||||
) -> Result<Vec<ScannedInstruction>> {
|
) -> Result<Vec<InstructionRef>> {
|
||||||
let start_address = address;
|
let start_address = address;
|
||||||
let mut ops = Vec::<ScannedInstruction>::with_capacity(code.len() / 4);
|
let mut ops = Vec::<InstructionRef>::with_capacity(code.len() / 4);
|
||||||
|
|
||||||
let mut reader = U8Reader::new(code);
|
let mut reader = U8Reader::new(code);
|
||||||
let decoder = InstDecoder::default();
|
let decoder = InstDecoder::default();
|
||||||
@@ -58,8 +57,10 @@ impl Arch for ArchArm64 {
|
|||||||
DecodeError::InvalidOpcode
|
DecodeError::InvalidOpcode
|
||||||
| DecodeError::InvalidOperand
|
| DecodeError::InvalidOperand
|
||||||
| DecodeError::IncompleteDecoder => {
|
| DecodeError::IncompleteDecoder => {
|
||||||
ops.push(ScannedInstruction {
|
ops.push(InstructionRef {
|
||||||
ins_ref: InstructionRef { address, size: 4, opcode: u16::MAX },
|
address,
|
||||||
|
size: 4,
|
||||||
|
opcode: u16::MAX,
|
||||||
branch_dest: None,
|
branch_dest: None,
|
||||||
});
|
});
|
||||||
continue;
|
continue;
|
||||||
@@ -68,9 +69,9 @@ impl Arch for ArchArm64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let opcode = opcode_to_u16(ins.opcode);
|
let opcode = opcode_to_u16(ins.opcode);
|
||||||
let ins_ref = InstructionRef { address, size: 4, opcode };
|
let branch_dest =
|
||||||
let branch_dest = branch_dest(ins_ref, &code[offset as usize..offset as usize + 4]);
|
branch_dest(opcode, address, &code[offset as usize..offset as usize + 4]);
|
||||||
ops.push(ScannedInstruction { ins_ref, branch_dest });
|
ops.push(InstructionRef { address, size: 4, opcode, branch_dest });
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(ops)
|
Ok(ops)
|
||||||
@@ -163,7 +164,7 @@ impl Arch for ArchArm64 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn branch_dest(ins_ref: InstructionRef, code: &[u8]) -> Option<u64> {
|
fn branch_dest(opcode: u16, address: u64, code: &[u8]) -> Option<u64> {
|
||||||
const OPCODE_B: u16 = opcode_to_u16(Opcode::B);
|
const OPCODE_B: u16 = opcode_to_u16(Opcode::B);
|
||||||
const OPCODE_BL: u16 = opcode_to_u16(Opcode::BL);
|
const OPCODE_BL: u16 = opcode_to_u16(Opcode::BL);
|
||||||
const OPCODE_BCC: u16 = opcode_to_u16(Opcode::Bcc(0));
|
const OPCODE_BCC: u16 = opcode_to_u16(Opcode::Bcc(0));
|
||||||
@@ -173,21 +174,21 @@ fn branch_dest(ins_ref: InstructionRef, code: &[u8]) -> Option<u64> {
|
|||||||
const OPCODE_TBNZ: u16 = opcode_to_u16(Opcode::TBNZ);
|
const OPCODE_TBNZ: u16 = opcode_to_u16(Opcode::TBNZ);
|
||||||
|
|
||||||
let word = u32::from_le_bytes(code.try_into().ok()?);
|
let word = u32::from_le_bytes(code.try_into().ok()?);
|
||||||
match ins_ref.opcode {
|
match opcode {
|
||||||
OPCODE_B | OPCODE_BL => {
|
OPCODE_B | OPCODE_BL => {
|
||||||
let offset = ((word & 0x03ff_ffff) << 2) as i32;
|
let offset = ((word & 0x03ff_ffff) << 2) as i32;
|
||||||
let extended_offset = (offset << 4) >> 4;
|
let extended_offset = (offset << 4) >> 4;
|
||||||
ins_ref.address.checked_add_signed(extended_offset as i64)
|
address.checked_add_signed(extended_offset as i64)
|
||||||
}
|
}
|
||||||
OPCODE_BCC | OPCODE_CBZ | OPCODE_CBNZ => {
|
OPCODE_BCC | OPCODE_CBZ | OPCODE_CBNZ => {
|
||||||
let offset = (word as i32 & 0x00ff_ffe0) >> 3;
|
let offset = (word as i32 & 0x00ff_ffe0) >> 3;
|
||||||
let extended_offset = (offset << 11) >> 11;
|
let extended_offset = (offset << 11) >> 11;
|
||||||
ins_ref.address.checked_add_signed(extended_offset as i64)
|
address.checked_add_signed(extended_offset as i64)
|
||||||
}
|
}
|
||||||
OPCODE_TBZ | OPCODE_TBNZ => {
|
OPCODE_TBZ | OPCODE_TBNZ => {
|
||||||
let offset = (word as i32 & 0x0007_ffe0) >> 3;
|
let offset = (word as i32 & 0x0007_ffe0) >> 3;
|
||||||
let extended_offset = (offset << 16) >> 16;
|
let extended_offset = (offset << 16) >> 16;
|
||||||
ins_ref.address.checked_add_signed(extended_offset as i64)
|
address.checked_add_signed(extended_offset as i64)
|
||||||
}
|
}
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ use alloc::{
|
|||||||
string::{String, ToString},
|
string::{String, ToString},
|
||||||
vec::Vec,
|
vec::Vec,
|
||||||
};
|
};
|
||||||
use core::ops::Range;
|
|
||||||
|
|
||||||
use anyhow::{Result, bail};
|
use anyhow::{Result, bail};
|
||||||
use object::{Endian as _, Object as _, ObjectSection as _, ObjectSymbol as _, elf};
|
use object::{Endian as _, Object as _, ObjectSection as _, ObjectSymbol as _, elf};
|
||||||
@@ -19,7 +18,7 @@ use crate::{
|
|||||||
diff::{DiffObjConfig, MipsAbi, MipsInstrCategory, display::InstructionPart},
|
diff::{DiffObjConfig, MipsAbi, MipsInstrCategory, display::InstructionPart},
|
||||||
obj::{
|
obj::{
|
||||||
InstructionArg, InstructionArgValue, InstructionRef, Relocation, RelocationFlags,
|
InstructionArg, InstructionArgValue, InstructionRef, Relocation, RelocationFlags,
|
||||||
ResolvedInstructionRef, ResolvedRelocation, ScannedInstruction, SymbolFlag, SymbolFlagSet,
|
ResolvedInstructionRef, ResolvedRelocation, SymbolFlag, SymbolFlagSet,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -189,16 +188,16 @@ impl ArchMips {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Arch for ArchMips {
|
impl Arch for ArchMips {
|
||||||
fn scan_instructions(
|
fn scan_instructions_internal(
|
||||||
&self,
|
&self,
|
||||||
address: u64,
|
address: u64,
|
||||||
code: &[u8],
|
code: &[u8],
|
||||||
_section_index: usize,
|
_section_index: usize,
|
||||||
_relocations: &[Relocation],
|
_relocations: &[Relocation],
|
||||||
diff_config: &DiffObjConfig,
|
diff_config: &DiffObjConfig,
|
||||||
) -> Result<Vec<ScannedInstruction>> {
|
) -> Result<Vec<InstructionRef>> {
|
||||||
let instruction_flags = self.instruction_flags(diff_config);
|
let instruction_flags = self.instruction_flags(diff_config);
|
||||||
let mut ops = Vec::<ScannedInstruction>::with_capacity(code.len() / 4);
|
let mut ops = Vec::<InstructionRef>::with_capacity(code.len() / 4);
|
||||||
let mut cur_addr = address as u32;
|
let mut cur_addr = address as u32;
|
||||||
for chunk in code.chunks_exact(4) {
|
for chunk in code.chunks_exact(4) {
|
||||||
let code = self.endianness.read_u32_bytes(chunk.try_into()?);
|
let code = self.endianness.read_u32_bytes(chunk.try_into()?);
|
||||||
@@ -206,10 +205,7 @@ impl Arch for ArchMips {
|
|||||||
rabbitizer::Instruction::new(code, Vram::new(cur_addr), instruction_flags);
|
rabbitizer::Instruction::new(code, Vram::new(cur_addr), instruction_flags);
|
||||||
let opcode = instruction.opcode() as u16;
|
let opcode = instruction.opcode() as u16;
|
||||||
let branch_dest = instruction.get_branch_vram_generic().map(|v| v.inner() as u64);
|
let branch_dest = instruction.get_branch_vram_generic().map(|v| v.inner() as u64);
|
||||||
ops.push(ScannedInstruction {
|
ops.push(InstructionRef { address: cur_addr as u64, size: 4, opcode, branch_dest });
|
||||||
ins_ref: InstructionRef { address: cur_addr as u64, size: 4, opcode },
|
|
||||||
branch_dest,
|
|
||||||
});
|
|
||||||
cur_addr += 4;
|
cur_addr += 4;
|
||||||
}
|
}
|
||||||
Ok(ops)
|
Ok(ops)
|
||||||
@@ -225,16 +221,7 @@ impl Arch for ArchMips {
|
|||||||
let display_flags = self.instruction_display_flags(diff_config);
|
let display_flags = self.instruction_display_flags(diff_config);
|
||||||
let opcode = instruction.opcode();
|
let opcode = instruction.opcode();
|
||||||
cb(InstructionPart::opcode(opcode.name(), opcode as u16))?;
|
cb(InstructionPart::opcode(opcode.name(), opcode as u16))?;
|
||||||
let start_address = resolved.symbol.address;
|
push_args(&instruction, resolved.relocation, &display_flags, cb)?;
|
||||||
let function_range = start_address..start_address + resolved.symbol.size;
|
|
||||||
push_args(
|
|
||||||
&instruction,
|
|
||||||
resolved.relocation,
|
|
||||||
function_range,
|
|
||||||
resolved.section_index,
|
|
||||||
&display_flags,
|
|
||||||
cb,
|
|
||||||
)?;
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -338,8 +325,6 @@ impl Arch for ArchMips {
|
|||||||
fn push_args(
|
fn push_args(
|
||||||
instruction: &rabbitizer::Instruction,
|
instruction: &rabbitizer::Instruction,
|
||||||
relocation: Option<ResolvedRelocation>,
|
relocation: Option<ResolvedRelocation>,
|
||||||
function_range: Range<u64>,
|
|
||||||
section_index: usize,
|
|
||||||
display_flags: &rabbitizer::InstructionDisplayFlags,
|
display_flags: &rabbitizer::InstructionDisplayFlags,
|
||||||
mut arg_cb: impl FnMut(InstructionPart) -> Result<()>,
|
mut arg_cb: impl FnMut(InstructionPart) -> Result<()>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
@@ -362,23 +347,7 @@ fn push_args(
|
|||||||
}
|
}
|
||||||
ValuedOperand::core_label(..) | ValuedOperand::core_branch_target_label(..) => {
|
ValuedOperand::core_label(..) | ValuedOperand::core_branch_target_label(..) => {
|
||||||
if let Some(resolved) = relocation {
|
if let Some(resolved) = relocation {
|
||||||
// If the relocation target is within the current function, we can
|
push_reloc(resolved.relocation, &mut arg_cb)?;
|
||||||
// convert it into a relative branch target. Note that we check
|
|
||||||
// target_address > start_address instead of >= so that recursive
|
|
||||||
// tail calls are not considered branch targets.
|
|
||||||
let target_address =
|
|
||||||
resolved.symbol.address.checked_add_signed(resolved.relocation.addend);
|
|
||||||
if resolved.symbol.section == Some(section_index)
|
|
||||||
&& target_address.is_some_and(|addr| {
|
|
||||||
addr > function_range.start && addr < function_range.end
|
|
||||||
})
|
|
||||||
{
|
|
||||||
// TODO move this logic up a level
|
|
||||||
let target_address = target_address.unwrap();
|
|
||||||
arg_cb(InstructionPart::branch_dest(target_address))?;
|
|
||||||
} else {
|
|
||||||
push_reloc(resolved.relocation, &mut arg_cb)?;
|
|
||||||
}
|
|
||||||
} else if let Some(branch_dest) = instruction
|
} else if let Some(branch_dest) = instruction
|
||||||
.get_branch_offset_generic()
|
.get_branch_offset_generic()
|
||||||
.map(|o| (instruction.vram() + o).inner() as u64)
|
.map(|o| (instruction.vram() + o).inner() as u64)
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
use alloc::{borrow::Cow, boxed::Box, format, string::String, vec::Vec};
|
use alloc::{borrow::Cow, boxed::Box, format, string::String, vec::Vec};
|
||||||
use core::{ffi::CStr, fmt, fmt::Debug};
|
use core::{
|
||||||
|
ffi::CStr,
|
||||||
|
fmt::{self, Debug},
|
||||||
|
};
|
||||||
|
|
||||||
use anyhow::{Result, bail};
|
use anyhow::{Result, bail};
|
||||||
use encoding_rs::SHIFT_JIS;
|
use encoding_rs::SHIFT_JIS;
|
||||||
@@ -11,8 +14,9 @@ use crate::{
|
|||||||
display::{ContextItem, HoverItem, InstructionPart},
|
display::{ContextItem, HoverItem, InstructionPart},
|
||||||
},
|
},
|
||||||
obj::{
|
obj::{
|
||||||
InstructionArg, Object, ParsedInstruction, Relocation, RelocationFlags,
|
FlowAnalysisResult, InstructionArg, InstructionRef, Object, ParsedInstruction, Relocation,
|
||||||
ResolvedInstructionRef, ScannedInstruction, Section, Symbol, SymbolFlagSet, SymbolKind,
|
RelocationFlags, ResolvedInstructionRef, ResolvedSymbol, Section, Symbol, SymbolFlagSet,
|
||||||
|
SymbolKind,
|
||||||
},
|
},
|
||||||
util::ReallySigned,
|
util::ReallySigned,
|
||||||
};
|
};
|
||||||
@@ -31,6 +35,7 @@ pub mod superh;
|
|||||||
pub mod x86;
|
pub mod x86;
|
||||||
|
|
||||||
/// Represents the type of data associated with an instruction
|
/// Represents the type of data associated with an instruction
|
||||||
|
#[derive(PartialEq)]
|
||||||
pub enum DataType {
|
pub enum DataType {
|
||||||
Int8,
|
Int8,
|
||||||
Int16,
|
Int16,
|
||||||
@@ -182,46 +187,108 @@ impl DataType {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Arch: Send + Sync + Debug {
|
impl dyn Arch {
|
||||||
// Finishes arch-specific initialization that must be done after sections have been combined.
|
|
||||||
fn post_init(&mut self, _sections: &[Section], _symbols: &[Symbol]) {}
|
|
||||||
|
|
||||||
/// Generate a list of instructions references (offset, size, opcode) from the given code.
|
/// Generate a list of instructions references (offset, size, opcode) from the given code.
|
||||||
///
|
///
|
||||||
/// The opcode IDs are used to generate the initial diff. Implementations should do as little
|
/// See [`scan_instructions_internal`] for more details.
|
||||||
/// parsing as possible here: just enough to identify the base instruction opcode, size, and
|
pub fn scan_instructions(
|
||||||
/// possible branch destination (for visual representation). As needed, instructions are parsed
|
|
||||||
/// via `process_instruction` to compare their arguments.
|
|
||||||
fn scan_instructions(
|
|
||||||
&self,
|
&self,
|
||||||
address: u64,
|
resolved: ResolvedSymbol,
|
||||||
code: &[u8],
|
|
||||||
section_index: usize,
|
|
||||||
relocations: &[Relocation],
|
|
||||||
diff_config: &DiffObjConfig,
|
diff_config: &DiffObjConfig,
|
||||||
) -> Result<Vec<ScannedInstruction>>;
|
) -> Result<Vec<InstructionRef>> {
|
||||||
|
let mut result = self.scan_instructions_internal(
|
||||||
|
resolved.symbol.address,
|
||||||
|
resolved.data,
|
||||||
|
resolved.section_index,
|
||||||
|
&resolved.section.relocations,
|
||||||
|
diff_config,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let function_start = resolved.symbol.address;
|
||||||
|
let function_end = function_start + resolved.symbol.size;
|
||||||
|
|
||||||
|
// Remove any branch destinations that are outside the function range
|
||||||
|
for ins in result.iter_mut() {
|
||||||
|
if let Some(branch_dest) = ins.branch_dest {
|
||||||
|
if branch_dest < function_start || branch_dest >= function_end {
|
||||||
|
ins.branch_dest = None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Resolve relocation targets within the same function to branch destinations
|
||||||
|
let mut ins_iter = result.iter_mut().peekable();
|
||||||
|
'outer: for reloc in resolved
|
||||||
|
.section
|
||||||
|
.relocations
|
||||||
|
.iter()
|
||||||
|
.skip_while(|r| r.address < function_start)
|
||||||
|
.take_while(|r| r.address < function_end)
|
||||||
|
{
|
||||||
|
let ins = loop {
|
||||||
|
let Some(ins) = ins_iter.peek_mut() else {
|
||||||
|
break 'outer;
|
||||||
|
};
|
||||||
|
if reloc.address < ins.address {
|
||||||
|
continue 'outer;
|
||||||
|
}
|
||||||
|
let ins = ins_iter.next().unwrap();
|
||||||
|
if reloc.address >= ins.address && reloc.address < ins.address + ins.size as u64 {
|
||||||
|
break ins;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// Clear existing branch destination for instructions with relocations
|
||||||
|
ins.branch_dest = None;
|
||||||
|
let Some(target) = resolved.obj.symbols.get(reloc.target_symbol) else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
if target.section != Some(resolved.section_index) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let Some(target_address) = target.address.checked_add_signed(reloc.addend) else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
// If the target address is within the function range, set it as a branch destination
|
||||||
|
if target_address >= function_start && target_address < function_end {
|
||||||
|
ins.branch_dest = Some(target_address);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(result)
|
||||||
|
}
|
||||||
|
|
||||||
/// Parse an instruction to gather its mnemonic and arguments for more detailed comparison.
|
/// Parse an instruction to gather its mnemonic and arguments for more detailed comparison.
|
||||||
///
|
///
|
||||||
/// This is called only when we need to compare the arguments of an instruction.
|
/// This is called only when we need to compare the arguments of an instruction.
|
||||||
fn process_instruction(
|
pub fn process_instruction(
|
||||||
&self,
|
&self,
|
||||||
resolved: ResolvedInstructionRef,
|
resolved: ResolvedInstructionRef,
|
||||||
diff_config: &DiffObjConfig,
|
diff_config: &DiffObjConfig,
|
||||||
) -> Result<ParsedInstruction> {
|
) -> Result<ParsedInstruction> {
|
||||||
let mut mnemonic = None;
|
let mut mnemonic = None;
|
||||||
let mut args = Vec::with_capacity(8);
|
let mut args = Vec::with_capacity(8);
|
||||||
|
let mut relocation_emitted = false;
|
||||||
self.display_instruction(resolved, diff_config, &mut |part| {
|
self.display_instruction(resolved, diff_config, &mut |part| {
|
||||||
match part {
|
match part {
|
||||||
InstructionPart::Opcode(m, _) => mnemonic = Some(Cow::Owned(m.into_owned())),
|
InstructionPart::Opcode(m, _) => mnemonic = Some(Cow::Owned(m.into_owned())),
|
||||||
InstructionPart::Arg(arg) => args.push(arg.into_static()),
|
InstructionPart::Arg(arg) => {
|
||||||
|
if arg == InstructionArg::Reloc {
|
||||||
|
relocation_emitted = true;
|
||||||
|
// If the relocation was resolved to a branch destination, emit that instead.
|
||||||
|
if let Some(dest) = resolved.ins_ref.branch_dest {
|
||||||
|
args.push(InstructionArg::BranchDest(dest));
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
args.push(arg.into_static());
|
||||||
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
})?;
|
})?;
|
||||||
// If the instruction has a relocation, but we didn't format it in the display, add it to
|
// If the instruction has a relocation, but we didn't format it in the display, add it to
|
||||||
// the end of the arguments list.
|
// the end of the arguments list.
|
||||||
if resolved.relocation.is_some() && !args.contains(&InstructionArg::Reloc) {
|
if resolved.relocation.is_some() && !relocation_emitted {
|
||||||
args.push(InstructionArg::Reloc);
|
args.push(InstructionArg::Reloc);
|
||||||
}
|
}
|
||||||
Ok(ParsedInstruction {
|
Ok(ParsedInstruction {
|
||||||
@@ -230,6 +297,26 @@ pub trait Arch: Send + Sync + Debug {
|
|||||||
args,
|
args,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait Arch: Send + Sync + Debug {
|
||||||
|
/// Finishes arch-specific initialization that must be done after sections have been combined.
|
||||||
|
fn post_init(&mut self, _sections: &[Section], _symbols: &[Symbol]) {}
|
||||||
|
|
||||||
|
/// Generate a list of instructions references (offset, size, opcode) from the given code.
|
||||||
|
///
|
||||||
|
/// The opcode IDs are used to generate the initial diff. Implementations should do as little
|
||||||
|
/// parsing as possible here: just enough to identify the base instruction opcode, size, and
|
||||||
|
/// possible branch destination (for visual representation). As needed, instructions are parsed
|
||||||
|
/// via `process_instruction` to compare their arguments.
|
||||||
|
fn scan_instructions_internal(
|
||||||
|
&self,
|
||||||
|
address: u64,
|
||||||
|
code: &[u8],
|
||||||
|
section_index: usize,
|
||||||
|
relocations: &[Relocation],
|
||||||
|
diff_config: &DiffObjConfig,
|
||||||
|
) -> Result<Vec<InstructionRef>>;
|
||||||
|
|
||||||
/// Format an instruction for display.
|
/// Format an instruction for display.
|
||||||
///
|
///
|
||||||
@@ -253,6 +340,17 @@ pub trait Arch: Send + Sync + Debug {
|
|||||||
Vec::new()
|
Vec::new()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Perform detailed data flow analysis
|
||||||
|
fn data_flow_analysis(
|
||||||
|
&self,
|
||||||
|
_obj: &Object,
|
||||||
|
_symbol: &Symbol,
|
||||||
|
_code: &[u8],
|
||||||
|
_relocations: &[Relocation],
|
||||||
|
) -> Option<Box<dyn FlowAnalysisResult>> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
fn implcit_addend(
|
fn implcit_addend(
|
||||||
&self,
|
&self,
|
||||||
file: &object::File<'_>,
|
file: &object::File<'_>,
|
||||||
@@ -332,14 +430,14 @@ impl ArchDummy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Arch for ArchDummy {
|
impl Arch for ArchDummy {
|
||||||
fn scan_instructions(
|
fn scan_instructions_internal(
|
||||||
&self,
|
&self,
|
||||||
_address: u64,
|
_address: u64,
|
||||||
_code: &[u8],
|
_code: &[u8],
|
||||||
_section_index: usize,
|
_section_index: usize,
|
||||||
_relocations: &[Relocation],
|
_relocations: &[Relocation],
|
||||||
_diff_config: &DiffObjConfig,
|
_diff_config: &DiffObjConfig,
|
||||||
) -> Result<Vec<ScannedInstruction>> {
|
) -> Result<Vec<InstructionRef>> {
|
||||||
Ok(Vec::new())
|
Ok(Vec::new())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
642
objdiff-core/src/arch/ppc/flow_analysis.rs
Normal file
642
objdiff-core/src/arch/ppc/flow_analysis.rs
Normal file
@@ -0,0 +1,642 @@
|
|||||||
|
use alloc::{
|
||||||
|
boxed::Box,
|
||||||
|
collections::{BTreeMap, BTreeSet},
|
||||||
|
format,
|
||||||
|
string::{String, ToString},
|
||||||
|
vec::Vec,
|
||||||
|
};
|
||||||
|
use core::{
|
||||||
|
ffi::CStr,
|
||||||
|
ops::{Index, IndexMut},
|
||||||
|
};
|
||||||
|
|
||||||
|
use itertools::Itertools;
|
||||||
|
use ppc750cl::Simm;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
arch::DataType,
|
||||||
|
obj::{FlowAnalysisResult, FlowAnalysisValue, Object, Relocation, Symbol},
|
||||||
|
util::{RawDouble, RawFloat},
|
||||||
|
};
|
||||||
|
|
||||||
|
fn is_store_instruction(op: ppc750cl::Opcode) -> bool {
|
||||||
|
use ppc750cl::Opcode;
|
||||||
|
matches!(
|
||||||
|
op,
|
||||||
|
Opcode::Stbux
|
||||||
|
| Opcode::Stbx
|
||||||
|
| Opcode::Stfdux
|
||||||
|
| Opcode::Stfdx
|
||||||
|
| Opcode::Stfiwx
|
||||||
|
| Opcode::Stfsux
|
||||||
|
| Opcode::Stfsx
|
||||||
|
| Opcode::Sthbrx
|
||||||
|
| Opcode::Sthux
|
||||||
|
| Opcode::Sthx
|
||||||
|
| Opcode::Stswi
|
||||||
|
| Opcode::Stswx
|
||||||
|
| Opcode::Stwbrx
|
||||||
|
| Opcode::Stwcx_
|
||||||
|
| Opcode::Stwux
|
||||||
|
| Opcode::Stwx
|
||||||
|
| Opcode::Stwu
|
||||||
|
| Opcode::Stb
|
||||||
|
| Opcode::Stbu
|
||||||
|
| Opcode::Sth
|
||||||
|
| Opcode::Sthu
|
||||||
|
| Opcode::Stmw
|
||||||
|
| Opcode::Stfs
|
||||||
|
| Opcode::Stfsu
|
||||||
|
| Opcode::Stfd
|
||||||
|
| Opcode::Stfdu
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn guess_data_type_from_load_store_inst_op(inst_op: ppc750cl::Opcode) -> Option<DataType> {
|
||||||
|
use ppc750cl::Opcode;
|
||||||
|
match inst_op {
|
||||||
|
Opcode::Lbz | Opcode::Lbzu | Opcode::Lbzux | Opcode::Lbzx => Some(DataType::Int8),
|
||||||
|
Opcode::Lhz | Opcode::Lhzu | Opcode::Lhzux | Opcode::Lhzx => Some(DataType::Int16),
|
||||||
|
Opcode::Lha | Opcode::Lhau | Opcode::Lhaux | Opcode::Lhax => Some(DataType::Int16),
|
||||||
|
Opcode::Lwz | Opcode::Lwzu | Opcode::Lwzux | Opcode::Lwzx => Some(DataType::Int32),
|
||||||
|
Opcode::Lfs | Opcode::Lfsu | Opcode::Lfsux | Opcode::Lfsx => Some(DataType::Float),
|
||||||
|
Opcode::Lfd | Opcode::Lfdu | Opcode::Lfdux | Opcode::Lfdx => Some(DataType::Double),
|
||||||
|
|
||||||
|
Opcode::Stb | Opcode::Stbu | Opcode::Stbux | Opcode::Stbx => Some(DataType::Int8),
|
||||||
|
Opcode::Sth | Opcode::Sthu | Opcode::Sthux | Opcode::Sthx => Some(DataType::Int16),
|
||||||
|
Opcode::Stw | Opcode::Stwu | Opcode::Stwux | Opcode::Stwx => Some(DataType::Int32),
|
||||||
|
Opcode::Stfs | Opcode::Stfsu | Opcode::Stfsux | Opcode::Stfsx => Some(DataType::Float),
|
||||||
|
Opcode::Stfd | Opcode::Stfdu | Opcode::Stfdux | Opcode::Stfdx => Some(DataType::Double),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default, PartialEq, Eq, Copy, Clone, Debug, PartialOrd, Ord)]
|
||||||
|
enum RegisterContent {
|
||||||
|
#[default]
|
||||||
|
Unknown,
|
||||||
|
Variable, // Multiple potential values
|
||||||
|
FloatConstant(RawFloat),
|
||||||
|
DoubleConstant(RawDouble),
|
||||||
|
IntConstant(i32),
|
||||||
|
InputRegister(u8),
|
||||||
|
Symbol(usize),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl core::fmt::Display for RegisterContent {
|
||||||
|
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||||
|
match self {
|
||||||
|
RegisterContent::Unknown => write!(f, "unknown"),
|
||||||
|
RegisterContent::Variable => write!(f, "variable"),
|
||||||
|
RegisterContent::IntConstant(i) =>
|
||||||
|
// -i is safe because it's at most a 16 bit constant in the i32
|
||||||
|
{
|
||||||
|
if *i >= 0 {
|
||||||
|
write!(f, "0x{:x}", i)
|
||||||
|
} else {
|
||||||
|
write!(f, "-0x{:x}", -i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RegisterContent::FloatConstant(RawFloat(fp)) => write!(f, "{fp:?}f"),
|
||||||
|
RegisterContent::DoubleConstant(RawDouble(fp)) => write!(f, "{fp:?}d"),
|
||||||
|
RegisterContent::InputRegister(p) => write!(f, "input{p}"),
|
||||||
|
RegisterContent::Symbol(_u) => write!(f, "relocation"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, PartialEq, Eq, Ord, PartialOrd)]
|
||||||
|
struct RegisterState {
|
||||||
|
gpr: [RegisterContent; 32],
|
||||||
|
fpr: [RegisterContent; 32],
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RegisterState {
|
||||||
|
fn new() -> Self {
|
||||||
|
RegisterState { gpr: [RegisterContent::Unknown; 32], fpr: [RegisterContent::Unknown; 32] }
|
||||||
|
}
|
||||||
|
|
||||||
|
// During a function call, these registers must be assumed trashed.
|
||||||
|
fn clear_volatile(&mut self) {
|
||||||
|
self[ppc750cl::GPR(0)] = RegisterContent::Unknown;
|
||||||
|
for i in 0..=13 {
|
||||||
|
self[ppc750cl::GPR(i)] = RegisterContent::Unknown;
|
||||||
|
}
|
||||||
|
for i in 0..=13 {
|
||||||
|
self[ppc750cl::FPR(i)] = RegisterContent::Unknown;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mark potential input values.
|
||||||
|
// Subsequent flow analysis will "realize" that they are not actually inputs if
|
||||||
|
// they get overwritten with another value before getting read.
|
||||||
|
fn set_potential_inputs(&mut self) {
|
||||||
|
for g_reg in 3..=13 {
|
||||||
|
self[ppc750cl::GPR(g_reg)] = RegisterContent::InputRegister(g_reg);
|
||||||
|
}
|
||||||
|
for f_reg in 1..=13 {
|
||||||
|
self[ppc750cl::FPR(f_reg)] = RegisterContent::InputRegister(f_reg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the there is no value, we can take the new known value.
|
||||||
|
// If there's a known value different than the new value, the content
|
||||||
|
// must is variable.
|
||||||
|
// Returns whether the current value was updated.
|
||||||
|
fn unify_values(current: &mut RegisterContent, new: &RegisterContent) -> bool {
|
||||||
|
if *current == *new {
|
||||||
|
false
|
||||||
|
} else if *current == RegisterContent::Unknown {
|
||||||
|
*current = *new;
|
||||||
|
true
|
||||||
|
} else if *current == RegisterContent::Variable {
|
||||||
|
// Already variable
|
||||||
|
false
|
||||||
|
} else {
|
||||||
|
*current = RegisterContent::Variable;
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unify currently known register contents in a give situation with new
|
||||||
|
// information about the register contents in that situation.
|
||||||
|
// Currently unknown register contents can be filled, but if there are
|
||||||
|
// conflicting contents, we go back to unknown.
|
||||||
|
fn unify(&mut self, other: &RegisterState) -> bool {
|
||||||
|
let mut updated = false;
|
||||||
|
for i in 0..32 {
|
||||||
|
updated |= Self::unify_values(&mut self.gpr[i], &other.gpr[i]);
|
||||||
|
updated |= Self::unify_values(&mut self.fpr[i], &other.fpr[i]);
|
||||||
|
}
|
||||||
|
updated
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Index<ppc750cl::GPR> for RegisterState {
|
||||||
|
type Output = RegisterContent;
|
||||||
|
|
||||||
|
fn index(&self, gpr: ppc750cl::GPR) -> &Self::Output { &self.gpr[gpr.0 as usize] }
|
||||||
|
}
|
||||||
|
impl IndexMut<ppc750cl::GPR> for RegisterState {
|
||||||
|
fn index_mut(&mut self, gpr: ppc750cl::GPR) -> &mut Self::Output {
|
||||||
|
&mut self.gpr[gpr.0 as usize]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Index<ppc750cl::FPR> for RegisterState {
|
||||||
|
type Output = RegisterContent;
|
||||||
|
|
||||||
|
fn index(&self, fpr: ppc750cl::FPR) -> &Self::Output { &self.fpr[fpr.0 as usize] }
|
||||||
|
}
|
||||||
|
impl IndexMut<ppc750cl::FPR> for RegisterState {
|
||||||
|
fn index_mut(&mut self, fpr: ppc750cl::FPR) -> &mut Self::Output {
|
||||||
|
&mut self.fpr[fpr.0 as usize]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn execute_instruction(
|
||||||
|
registers: &mut RegisterState,
|
||||||
|
op: &ppc750cl::Opcode,
|
||||||
|
args: &ppc750cl::Arguments,
|
||||||
|
) {
|
||||||
|
use ppc750cl::{Argument, GPR, Opcode};
|
||||||
|
match (op, args[0], args[1], args[2]) {
|
||||||
|
(Opcode::Or, Argument::GPR(a), Argument::GPR(b), Argument::GPR(c)) => {
|
||||||
|
// Move is implemented as or with self for ints
|
||||||
|
if b == c {
|
||||||
|
registers[a] = registers[b];
|
||||||
|
} else {
|
||||||
|
registers[a] = RegisterContent::Unknown;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(Opcode::Fmr, Argument::FPR(a), Argument::FPR(b), _) => {
|
||||||
|
registers[a] = registers[b];
|
||||||
|
}
|
||||||
|
(Opcode::Addi, Argument::GPR(a), Argument::GPR(GPR(0)), Argument::Simm(c)) => {
|
||||||
|
// Load immidiate implemented as addi with addend = r0
|
||||||
|
// Let Addi with other addends fall through to the case which
|
||||||
|
// overwrites the destination
|
||||||
|
registers[a] = RegisterContent::IntConstant(c.0 as i32);
|
||||||
|
}
|
||||||
|
(Opcode::Bcctr, _, _, _) => {
|
||||||
|
// Called a function pointer, may have erased volatile registers
|
||||||
|
registers.clear_volatile();
|
||||||
|
}
|
||||||
|
(Opcode::B, _, _, _) => {
|
||||||
|
if get_branch_offset(args) == 0 {
|
||||||
|
// Call to another function
|
||||||
|
registers.clear_volatile();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(
|
||||||
|
Opcode::Stbu | Opcode::Sthu | Opcode::Stwu | Opcode::Stfsu | Opcode::Stfdu,
|
||||||
|
_,
|
||||||
|
_,
|
||||||
|
Argument::GPR(rel),
|
||||||
|
) => {
|
||||||
|
// Storing with update, clear updated register (third arg)
|
||||||
|
registers[rel] = RegisterContent::Unknown;
|
||||||
|
}
|
||||||
|
(
|
||||||
|
Opcode::Stbux | Opcode::Sthux | Opcode::Stwux | Opcode::Stfsux | Opcode::Stfdux,
|
||||||
|
_,
|
||||||
|
Argument::GPR(rel),
|
||||||
|
_,
|
||||||
|
) => {
|
||||||
|
// Storing indexed with update, clear updated register (second arg)
|
||||||
|
registers[rel] = RegisterContent::Unknown;
|
||||||
|
}
|
||||||
|
(Opcode::Lmw, Argument::GPR(target), _, _) => {
|
||||||
|
// `lmw` overwrites all registers from rd to r31.
|
||||||
|
for reg in target.0..31 {
|
||||||
|
registers[GPR(reg)] = RegisterContent::Unknown;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(_, Argument::GPR(a), _, _) => {
|
||||||
|
// Store instructions don't modify the GPR
|
||||||
|
if !is_store_instruction(*op) {
|
||||||
|
// Other operations which write to GPR a
|
||||||
|
registers[a] = RegisterContent::Unknown;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(_, Argument::FPR(a), _, _) => {
|
||||||
|
// Store instructions don't modify the FPR
|
||||||
|
if !is_store_instruction(*op) {
|
||||||
|
// Other operations which write to FPR a
|
||||||
|
registers[a] = RegisterContent::Unknown;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(_, _, _, _) => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_branch_offset(args: &ppc750cl::Arguments) -> i32 {
|
||||||
|
for arg in args.iter() {
|
||||||
|
match arg {
|
||||||
|
ppc750cl::Argument::BranchDest(dest) => return dest.0 / 4,
|
||||||
|
ppc750cl::Argument::None => break,
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
0
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default)]
|
||||||
|
struct PPCFlowAnalysisResult {
|
||||||
|
argument_contents: BTreeMap<(u64, u8), FlowAnalysisValue>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PPCFlowAnalysisResult {
|
||||||
|
fn set_argument_value_at_address(
|
||||||
|
&mut self,
|
||||||
|
address: u64,
|
||||||
|
argument: u8,
|
||||||
|
value: FlowAnalysisValue,
|
||||||
|
) {
|
||||||
|
self.argument_contents.insert((address, argument), value);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn new() -> Self { PPCFlowAnalysisResult { argument_contents: Default::default() } }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FlowAnalysisResult for PPCFlowAnalysisResult {
|
||||||
|
fn get_argument_value_at_address(
|
||||||
|
&self,
|
||||||
|
address: u64,
|
||||||
|
argument: u8,
|
||||||
|
) -> Option<&FlowAnalysisValue> {
|
||||||
|
self.argument_contents.get(&(address, argument))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn clamp_text_length(s: String, max: usize) -> String {
|
||||||
|
if s.len() <= max { s } else { format!("{}…", s.chars().take(max - 3).collect::<String>()) }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_register_content_from_reloc(
|
||||||
|
reloc: &Relocation,
|
||||||
|
obj: &Object,
|
||||||
|
op: ppc750cl::Opcode,
|
||||||
|
) -> RegisterContent {
|
||||||
|
if let Some(bytes) = obj.symbol_data(reloc.target_symbol) {
|
||||||
|
match guess_data_type_from_load_store_inst_op(op) {
|
||||||
|
Some(DataType::Float) => {
|
||||||
|
RegisterContent::FloatConstant(RawFloat(match obj.endianness {
|
||||||
|
object::Endianness::Little => {
|
||||||
|
f32::from_le_bytes(bytes.try_into().unwrap_or([0; 4]))
|
||||||
|
}
|
||||||
|
object::Endianness::Big => {
|
||||||
|
f32::from_be_bytes(bytes.try_into().unwrap_or([0; 4]))
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
Some(DataType::Double) => {
|
||||||
|
RegisterContent::DoubleConstant(RawDouble(match obj.endianness {
|
||||||
|
object::Endianness::Little => {
|
||||||
|
f64::from_le_bytes(bytes.try_into().unwrap_or([0; 8]))
|
||||||
|
}
|
||||||
|
object::Endianness::Big => {
|
||||||
|
f64::from_be_bytes(bytes.try_into().unwrap_or([0; 8]))
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
_ => RegisterContent::Symbol(reloc.target_symbol),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
RegisterContent::Symbol(reloc.target_symbol)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Executing op with args at cur_address, update current_state with symbols that
|
||||||
|
// come from relocations. That is, references to globals, floating point
|
||||||
|
// constants, string constants, etc.
|
||||||
|
fn fill_registers_from_relocation(
|
||||||
|
reloc: &Relocation,
|
||||||
|
current_state: &mut RegisterState,
|
||||||
|
obj: &Object,
|
||||||
|
op: ppc750cl::Opcode,
|
||||||
|
args: &ppc750cl::Arguments,
|
||||||
|
) {
|
||||||
|
// Only update the register state for loads. We may store to a reloc
|
||||||
|
// address but that doesn't update register contents.
|
||||||
|
if !is_store_instruction(op) {
|
||||||
|
match (op, args[0]) {
|
||||||
|
// Everything else is a load of some sort
|
||||||
|
(_, ppc750cl::Argument::GPR(gpr)) => {
|
||||||
|
current_state[gpr] = get_register_content_from_reloc(reloc, obj, op);
|
||||||
|
}
|
||||||
|
(_, ppc750cl::Argument::FPR(fpr)) => {
|
||||||
|
current_state[fpr] = get_register_content_from_reloc(reloc, obj, op);
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Special helper fragments generated by MWCC.
|
||||||
|
// See: https://github.com/encounter/decomp-toolkit/blob/main/src/analysis/pass.rs
|
||||||
|
const SLEDS: [&str; 6] = ["_savefpr_", "_restfpr_", "_savegpr_", "_restgpr_", "_savev", "_restv"];
|
||||||
|
|
||||||
|
fn is_sled_function(name: &str) -> bool { SLEDS.iter().any(|sled| name.starts_with(sled)) }
|
||||||
|
|
||||||
|
pub fn ppc_data_flow_analysis(
|
||||||
|
obj: &Object,
|
||||||
|
func_symbol: &Symbol,
|
||||||
|
code: &[u8],
|
||||||
|
relocations: &[Relocation],
|
||||||
|
) -> Box<dyn FlowAnalysisResult> {
|
||||||
|
use alloc::collections::VecDeque;
|
||||||
|
|
||||||
|
use ppc750cl::InsIter;
|
||||||
|
let instructions = InsIter::new(code, func_symbol.address as u32)
|
||||||
|
.map(|(_addr, ins)| (ins.op, ins.basic().args))
|
||||||
|
.collect_vec();
|
||||||
|
|
||||||
|
let func_address = func_symbol.address;
|
||||||
|
|
||||||
|
// Get initial register values from function parameters
|
||||||
|
let mut initial_register_state = RegisterState::new();
|
||||||
|
initial_register_state.set_potential_inputs();
|
||||||
|
|
||||||
|
let mut execution_queue = VecDeque::<(usize, RegisterState)>::new();
|
||||||
|
execution_queue.push_back((0, initial_register_state));
|
||||||
|
|
||||||
|
// Execute the instructions against abstract data
|
||||||
|
let mut failsafe_counter = 0;
|
||||||
|
let mut taken_branches = BTreeSet::<(usize, RegisterState)>::new();
|
||||||
|
let mut register_state_at = Vec::<RegisterState>::new();
|
||||||
|
let mut completed_first_pass = false;
|
||||||
|
register_state_at.resize_with(instructions.len(), RegisterState::new);
|
||||||
|
while let Some((mut index, mut current_state)) = execution_queue.pop_front() {
|
||||||
|
while let Some((op, args)) = instructions.get(index) {
|
||||||
|
// Record the state at this index
|
||||||
|
// If recording does not result in any changes to the known values
|
||||||
|
// we're done, because the subsequent values are a function of the
|
||||||
|
// current values so we'll get the same result as the last time
|
||||||
|
// we went down this path.
|
||||||
|
// Don't break out if we haven't even completed the first pass
|
||||||
|
// through the function though.
|
||||||
|
if !register_state_at[index].unify(¤t_state) && completed_first_pass {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get symbol used in this instruction
|
||||||
|
let cur_addr = (func_address as u32) + ((index * 4) as u32);
|
||||||
|
let reloc = relocations.iter().find(|r| (r.address as u32 & !3) == cur_addr);
|
||||||
|
|
||||||
|
// Is this a branch to a compiler generated helper? These helpers
|
||||||
|
// do not trash registers like normal function calls, so we don't
|
||||||
|
// want to treat this as normal execution.
|
||||||
|
let symbol = reloc.and_then(|r| obj.symbols.get(r.target_symbol));
|
||||||
|
let is_sled_invocation = symbol.is_some_and(|x| is_sled_function(&x.name));
|
||||||
|
|
||||||
|
// Execute the instruction to update the state
|
||||||
|
// Since sled invocations are only used to save / restore registers
|
||||||
|
// as part of prelude / cleanup in a function call we don't have to
|
||||||
|
// do any execution for them.
|
||||||
|
if !is_sled_invocation {
|
||||||
|
execute_instruction(&mut current_state, op, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fill in register state coming from relocations at this line. This
|
||||||
|
// handles references to global variables, floating point constants,
|
||||||
|
// etc.
|
||||||
|
if let Some(reloc) = reloc {
|
||||||
|
fill_registers_from_relocation(reloc, &mut current_state, obj, *op, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add conditional branches to execution queue
|
||||||
|
// Only take a given (address, register state) combination once. If
|
||||||
|
// the known register state is different we have to take the branch
|
||||||
|
// again to stabilize the known values for backwards branches.
|
||||||
|
if op == &ppc750cl::Opcode::Bc {
|
||||||
|
let branch_state = (index, current_state.clone());
|
||||||
|
if !taken_branches.contains(&branch_state) {
|
||||||
|
let offset = get_branch_offset(args);
|
||||||
|
let target_index = ((index as i32) + offset) as usize;
|
||||||
|
execution_queue.push_back((target_index, current_state.clone()));
|
||||||
|
taken_branches.insert(branch_state);
|
||||||
|
|
||||||
|
// We should never hit this case, but avoid getting stuck in
|
||||||
|
// an infinite loop if we hit some kind of bad behavior.
|
||||||
|
failsafe_counter += 1;
|
||||||
|
if failsafe_counter > 256 {
|
||||||
|
//println!("Analysis of {} failed to stabilize", func_symbol.name);
|
||||||
|
return Box::new(PPCFlowAnalysisResult::new());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update index
|
||||||
|
if op == &ppc750cl::Opcode::B {
|
||||||
|
// Unconditional branch
|
||||||
|
let offset = get_branch_offset(args);
|
||||||
|
if offset > 0 {
|
||||||
|
// Jump table or branch to over else clause.
|
||||||
|
index += offset as usize;
|
||||||
|
} else if offset == 0 {
|
||||||
|
// Function call with relocation. We'll return to
|
||||||
|
// the next instruction.
|
||||||
|
index += 1;
|
||||||
|
} else {
|
||||||
|
// Unconditional branch (E.g.: loop { ... })
|
||||||
|
// Also some compilations of loops put the conditional at
|
||||||
|
// the end and B to it for the check of the first iteration.
|
||||||
|
let branch_state = (index, current_state.clone());
|
||||||
|
if taken_branches.contains(&branch_state) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
taken_branches.insert(branch_state);
|
||||||
|
index = ((index as i32) + offset) as usize;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Normal execution of next instruction
|
||||||
|
index += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mark that we've completed at least one pass over the function, at
|
||||||
|
// this point we can break out if the code we're running doesn't change
|
||||||
|
// any register outcomes.
|
||||||
|
completed_first_pass = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store the relevant data flow values for simplified instructions
|
||||||
|
generate_flow_analysis_result(obj, func_address, code, register_state_at, relocations)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_string_data(obj: &Object, symbol_index: usize, offset: Simm) -> Option<&str> {
|
||||||
|
if let Some(sym) = obj.symbols.get(symbol_index) {
|
||||||
|
if sym.name.starts_with("@stringBase") && offset.0 != 0 {
|
||||||
|
if let Some(data) = obj.symbol_data(symbol_index) {
|
||||||
|
let bytes = &data[offset.0 as usize..];
|
||||||
|
if let Ok(Ok(str)) = CStr::from_bytes_until_nul(bytes).map(|x| x.to_str()) {
|
||||||
|
return Some(str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write the relevant part of the flow analysis out into the FlowAnalysisResult
|
||||||
|
// the rest of the application will use to query results of the flow analysis.
|
||||||
|
// Flow analysis will compute the known contents of every register at every
|
||||||
|
// line, but we only need to record the values of registers that are actually
|
||||||
|
// referenced at each line.
|
||||||
|
fn generate_flow_analysis_result(
|
||||||
|
obj: &Object,
|
||||||
|
base_address: u64,
|
||||||
|
code: &[u8],
|
||||||
|
register_state_at: Vec<RegisterState>,
|
||||||
|
relocations: &[Relocation],
|
||||||
|
) -> Box<PPCFlowAnalysisResult> {
|
||||||
|
use ppc750cl::{Argument, InsIter};
|
||||||
|
let mut analysis_result = PPCFlowAnalysisResult::new();
|
||||||
|
let default_register_state = RegisterState::new();
|
||||||
|
for (addr, ins) in InsIter::new(code, 0) {
|
||||||
|
let ins_address = base_address + (addr as u64);
|
||||||
|
let index = addr / 4;
|
||||||
|
let ppc750cl::ParsedIns { mnemonic: _, args } = ins.simplified();
|
||||||
|
|
||||||
|
// If we're already showing relocations on a line don't also show data flow
|
||||||
|
let reloc = relocations.iter().find(|r| (r.address & !3) == ins_address);
|
||||||
|
|
||||||
|
// Special case to show float and double constants on the line where
|
||||||
|
// they are being loaded.
|
||||||
|
// We need to do this before we break out on showing relocations in the
|
||||||
|
// subsequent if statement.
|
||||||
|
if let (ppc750cl::Opcode::Lfs | ppc750cl::Opcode::Lfd, Some(reloc)) = (ins.op, reloc) {
|
||||||
|
let content = get_register_content_from_reloc(reloc, obj, ins.op);
|
||||||
|
if matches!(
|
||||||
|
content,
|
||||||
|
RegisterContent::FloatConstant(_) | RegisterContent::DoubleConstant(_)
|
||||||
|
) {
|
||||||
|
analysis_result.set_argument_value_at_address(
|
||||||
|
ins_address,
|
||||||
|
1,
|
||||||
|
FlowAnalysisValue::Text(content.to_string()),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Don't need to show any other data flow if we're showing that
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Special case to show string constants on the line where they are
|
||||||
|
// being indexed to. This will typically be "addi t, stringbase, offset"
|
||||||
|
let registers = register_state_at.get(index as usize).unwrap_or(&default_register_state);
|
||||||
|
if let (ppc750cl::Opcode::Addi, Argument::GPR(rel), Argument::Simm(offset)) =
|
||||||
|
(ins.op, args[1], args[2])
|
||||||
|
{
|
||||||
|
if let RegisterContent::Symbol(sym_index) = registers[rel] {
|
||||||
|
if let Some(str) = get_string_data(obj, sym_index, offset) {
|
||||||
|
// Show the string constant in the analysis result
|
||||||
|
let formatted = format!("\"{str}\"");
|
||||||
|
analysis_result.set_argument_value_at_address(
|
||||||
|
ins_address,
|
||||||
|
2,
|
||||||
|
FlowAnalysisValue::Text(clamp_text_length(formatted, 20)),
|
||||||
|
);
|
||||||
|
// Don't continue, we want to show the stringbase value as well
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let is_store = is_store_instruction(ins.op);
|
||||||
|
for (arg_index, arg) in args.into_iter().enumerate() {
|
||||||
|
// Hacky shorthand for determining which arguments are sources,
|
||||||
|
// We only want to show data flow for source registers, not target
|
||||||
|
// registers. Technically there are some non-"st_" operations which
|
||||||
|
// read from their first argument but they're rare.
|
||||||
|
if (arg_index == 0) && !is_store {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let content = match arg {
|
||||||
|
Argument::GPR(gpr) => Some(registers[gpr]),
|
||||||
|
Argument::FPR(fpr) => Some(registers[fpr]),
|
||||||
|
_ => None,
|
||||||
|
};
|
||||||
|
let analysis_value = match content {
|
||||||
|
Some(RegisterContent::Symbol(s)) => {
|
||||||
|
if reloc.is_none() {
|
||||||
|
// Only symbols if there isn't already a relocation, because
|
||||||
|
// code other than the data flow analysis will be showing
|
||||||
|
// the symbol for a relocation on the line it is for. If we
|
||||||
|
// also showed it as data flow analysis value we would be
|
||||||
|
// showing redundant information.
|
||||||
|
obj.symbols.get(s).map(|sym| {
|
||||||
|
FlowAnalysisValue::Text(clamp_text_length(
|
||||||
|
sym.demangled_name.as_ref().unwrap_or(&sym.name).clone(),
|
||||||
|
20,
|
||||||
|
))
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Some(RegisterContent::InputRegister(reg)) => {
|
||||||
|
let reg_name = match arg {
|
||||||
|
Argument::GPR(_) => format!("in_r{reg}"),
|
||||||
|
Argument::FPR(_) => format!("in_f{reg}"),
|
||||||
|
_ => panic!("Register content should only be in a register"),
|
||||||
|
};
|
||||||
|
Some(FlowAnalysisValue::Text(reg_name))
|
||||||
|
}
|
||||||
|
Some(RegisterContent::Unknown) | Some(RegisterContent::Variable) => None,
|
||||||
|
Some(value) => Some(FlowAnalysisValue::Text(format!("{value}"))),
|
||||||
|
None => None,
|
||||||
|
};
|
||||||
|
if let Some(analysis_value) = analysis_value {
|
||||||
|
analysis_result.set_argument_value_at_address(
|
||||||
|
ins_address,
|
||||||
|
arg_index as u8,
|
||||||
|
analysis_value,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Box::new(analysis_result)
|
||||||
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
use alloc::{
|
use alloc::{
|
||||||
|
boxed::Box,
|
||||||
collections::{BTreeMap, BTreeSet},
|
collections::{BTreeMap, BTreeSet},
|
||||||
string::{String, ToString},
|
string::{String, ToString},
|
||||||
vec,
|
vec,
|
||||||
@@ -18,11 +19,13 @@ use crate::{
|
|||||||
display::{ContextItem, HoverItem, HoverItemColor, InstructionPart, SymbolNavigationKind},
|
display::{ContextItem, HoverItem, HoverItemColor, InstructionPart, SymbolNavigationKind},
|
||||||
},
|
},
|
||||||
obj::{
|
obj::{
|
||||||
InstructionRef, Object, Relocation, RelocationFlags, ResolvedInstructionRef,
|
FlowAnalysisResult, InstructionRef, Object, Relocation, RelocationFlags,
|
||||||
ResolvedRelocation, ScannedInstruction, Symbol, SymbolFlag, SymbolFlagSet,
|
ResolvedInstructionRef, ResolvedRelocation, Symbol, SymbolFlag, SymbolFlagSet,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
mod flow_analysis;
|
||||||
|
|
||||||
// Relative relocation, can be Simm, Offset or BranchDest
|
// Relative relocation, can be Simm, Offset or BranchDest
|
||||||
fn is_relative_arg(arg: &ppc750cl::Argument) -> bool {
|
fn is_relative_arg(arg: &ppc750cl::Argument) -> bool {
|
||||||
matches!(
|
matches!(
|
||||||
@@ -82,24 +85,22 @@ impl ArchPpc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Arch for ArchPpc {
|
impl Arch for ArchPpc {
|
||||||
fn scan_instructions(
|
fn scan_instructions_internal(
|
||||||
&self,
|
&self,
|
||||||
address: u64,
|
address: u64,
|
||||||
code: &[u8],
|
code: &[u8],
|
||||||
_section_index: usize,
|
_section_index: usize,
|
||||||
_relocations: &[Relocation],
|
_relocations: &[Relocation],
|
||||||
_diff_config: &DiffObjConfig,
|
_diff_config: &DiffObjConfig,
|
||||||
) -> Result<Vec<ScannedInstruction>> {
|
) -> Result<Vec<InstructionRef>> {
|
||||||
ensure!(code.len() & 3 == 0, "Code length must be a multiple of 4");
|
ensure!(code.len() & 3 == 0, "Code length must be a multiple of 4");
|
||||||
let ins_count = code.len() / 4;
|
let ins_count = code.len() / 4;
|
||||||
let mut insts = Vec::<ScannedInstruction>::with_capacity(ins_count);
|
let mut insts = Vec::<InstructionRef>::with_capacity(ins_count);
|
||||||
for (cur_addr, ins) in ppc750cl::InsIter::new(code, address as u32) {
|
for (cur_addr, ins) in ppc750cl::InsIter::new(code, address as u32) {
|
||||||
insts.push(ScannedInstruction {
|
insts.push(InstructionRef {
|
||||||
ins_ref: InstructionRef {
|
address: cur_addr as u64,
|
||||||
address: cur_addr as u64,
|
size: 4,
|
||||||
size: 4,
|
opcode: u8::from(ins.op) as u16,
|
||||||
opcode: u8::from(ins.op) as u16,
|
|
||||||
},
|
|
||||||
branch_dest: ins.branch_dest(cur_addr).map(u64::from),
|
branch_dest: ins.branch_dest(cur_addr).map(u64::from),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -159,6 +160,7 @@ impl Arch for ArchPpc {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Could be replaced by data_flow_analysis once that feature stabilizes
|
||||||
fn generate_pooled_relocations(
|
fn generate_pooled_relocations(
|
||||||
&self,
|
&self,
|
||||||
address: u64,
|
address: u64,
|
||||||
@@ -169,6 +171,16 @@ impl Arch for ArchPpc {
|
|||||||
generate_fake_pool_relocations_for_function(address, code, relocations, symbols)
|
generate_fake_pool_relocations_for_function(address, code, relocations, symbols)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn data_flow_analysis(
|
||||||
|
&self,
|
||||||
|
obj: &Object,
|
||||||
|
symbol: &Symbol,
|
||||||
|
code: &[u8],
|
||||||
|
relocations: &[Relocation],
|
||||||
|
) -> Option<Box<dyn FlowAnalysisResult>> {
|
||||||
|
Some(flow_analysis::ppc_data_flow_analysis(obj, symbol, code, relocations))
|
||||||
|
}
|
||||||
|
|
||||||
fn implcit_addend(
|
fn implcit_addend(
|
||||||
&self,
|
&self,
|
||||||
_file: &object::File<'_>,
|
_file: &object::File<'_>,
|
||||||
@@ -227,7 +239,7 @@ impl Arch for ArchPpc {
|
|||||||
return Some(DataType::String);
|
return Some(DataType::String);
|
||||||
}
|
}
|
||||||
let opcode = ppc750cl::Opcode::from(resolved.ins_ref.opcode as u8);
|
let opcode = ppc750cl::Opcode::from(resolved.ins_ref.opcode as u8);
|
||||||
if let Some(ty) = guess_data_type_from_load_store_inst_op(opcode) {
|
if let Some(ty) = flow_analysis::guess_data_type_from_load_store_inst_op(opcode) {
|
||||||
// Numeric type.
|
// Numeric type.
|
||||||
return Some(ty);
|
return Some(ty);
|
||||||
}
|
}
|
||||||
@@ -503,25 +515,6 @@ fn make_symbol_ref(symbol: &object::Symbol) -> Result<ExtabSymbolRef> {
|
|||||||
Ok(ExtabSymbolRef { original_index: symbol.index().0 - 1, name, demangled_name })
|
Ok(ExtabSymbolRef { original_index: symbol.index().0 - 1, name, demangled_name })
|
||||||
}
|
}
|
||||||
|
|
||||||
fn guess_data_type_from_load_store_inst_op(inst_op: ppc750cl::Opcode) -> Option<DataType> {
|
|
||||||
use ppc750cl::Opcode;
|
|
||||||
match inst_op {
|
|
||||||
Opcode::Lbz | Opcode::Lbzu | Opcode::Lbzux | Opcode::Lbzx => Some(DataType::Int8),
|
|
||||||
Opcode::Lhz | Opcode::Lhzu | Opcode::Lhzux | Opcode::Lhzx => Some(DataType::Int16),
|
|
||||||
Opcode::Lha | Opcode::Lhau | Opcode::Lhaux | Opcode::Lhax => Some(DataType::Int16),
|
|
||||||
Opcode::Lwz | Opcode::Lwzu | Opcode::Lwzux | Opcode::Lwzx => Some(DataType::Int32),
|
|
||||||
Opcode::Lfs | Opcode::Lfsu | Opcode::Lfsux | Opcode::Lfsx => Some(DataType::Float),
|
|
||||||
Opcode::Lfd | Opcode::Lfdu | Opcode::Lfdux | Opcode::Lfdx => Some(DataType::Double),
|
|
||||||
|
|
||||||
Opcode::Stb | Opcode::Stbu | Opcode::Stbux | Opcode::Stbx => Some(DataType::Int8),
|
|
||||||
Opcode::Sth | Opcode::Sthu | Opcode::Sthux | Opcode::Sthx => Some(DataType::Int16),
|
|
||||||
Opcode::Stw | Opcode::Stwu | Opcode::Stwux | Opcode::Stwx => Some(DataType::Int32),
|
|
||||||
Opcode::Stfs | Opcode::Stfsu | Opcode::Stfsux | Opcode::Stfsx => Some(DataType::Float),
|
|
||||||
Opcode::Stfd | Opcode::Stfdu | Opcode::Stfdux | Opcode::Stfdx => Some(DataType::Double),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct PoolReference {
|
struct PoolReference {
|
||||||
addr_src_gpr: ppc750cl::GPR,
|
addr_src_gpr: ppc750cl::GPR,
|
||||||
@@ -538,7 +531,7 @@ fn get_pool_reference_for_inst(
|
|||||||
) -> Option<PoolReference> {
|
) -> Option<PoolReference> {
|
||||||
use ppc750cl::{Argument, Opcode};
|
use ppc750cl::{Argument, Opcode};
|
||||||
let args = &simplified.args;
|
let args = &simplified.args;
|
||||||
if guess_data_type_from_load_store_inst_op(opcode).is_some() {
|
if flow_analysis::guess_data_type_from_load_store_inst_op(opcode).is_some() {
|
||||||
match (args[1], args[2]) {
|
match (args[1], args[2]) {
|
||||||
(Argument::Offset(offset), Argument::GPR(addr_src_gpr)) => {
|
(Argument::Offset(offset), Argument::GPR(addr_src_gpr)) => {
|
||||||
// e.g. lwz. Immediate offset.
|
// e.g. lwz. Immediate offset.
|
||||||
@@ -670,7 +663,7 @@ fn make_fake_pool_reloc(
|
|||||||
// and returns a Vec of "fake pool relocations" that simulate what a relocation for that instruction
|
// and returns a Vec of "fake pool relocations" that simulate what a relocation for that instruction
|
||||||
// would look like if data hadn't been pooled.
|
// would look like if data hadn't been pooled.
|
||||||
// This method tries to follow the function's proper control flow. It keeps track of a queue of
|
// This method tries to follow the function's proper control flow. It keeps track of a queue of
|
||||||
// states it hasn't traversed yet, where each state holds an instruction address and a HashMap of
|
// states it hasn't traversed yet, where each state holds an instruction address and a map of
|
||||||
// which registers hold which pool relocations at that point.
|
// which registers hold which pool relocations at that point.
|
||||||
// When a conditional or unconditional branch is encountered, the destination of the branch is added
|
// When a conditional or unconditional branch is encountered, the destination of the branch is added
|
||||||
// to the queue. Conditional branches will traverse both the path where the branch is taken and the
|
// to the queue. Conditional branches will traverse both the path where the branch is taken and the
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
|
use alloc::{format, vec::Vec};
|
||||||
|
|
||||||
use crate::{diff::display::InstructionPart, obj::ResolvedInstructionRef};
|
use crate::{diff::display::InstructionPart, obj::ResolvedInstructionRef};
|
||||||
|
|
||||||
static REG_NAMES: [&str; 16] = [
|
static REG_NAMES: [&str; 16] = [
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
use alloc::{string::String, vec::Vec};
|
use alloc::{collections::BTreeMap, format, string::String, vec, vec::Vec};
|
||||||
use std::collections::HashMap;
|
|
||||||
|
|
||||||
use anyhow::{Result, bail};
|
use anyhow::{Result, bail};
|
||||||
use object::elf;
|
use object::elf;
|
||||||
@@ -7,9 +6,7 @@ use object::elf;
|
|||||||
use crate::{
|
use crate::{
|
||||||
arch::{Arch, superh::disasm::sh2_disasm},
|
arch::{Arch, superh::disasm::sh2_disasm},
|
||||||
diff::{DiffObjConfig, display::InstructionPart},
|
diff::{DiffObjConfig, display::InstructionPart},
|
||||||
obj::{
|
obj::{InstructionRef, Relocation, RelocationFlags, ResolvedInstructionRef},
|
||||||
InstructionRef, Relocation, RelocationFlags, ResolvedInstructionRef, ScannedInstruction,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub mod disasm;
|
pub mod disasm;
|
||||||
@@ -27,15 +24,15 @@ struct DataInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Arch for ArchSuperH {
|
impl Arch for ArchSuperH {
|
||||||
fn scan_instructions(
|
fn scan_instructions_internal(
|
||||||
&self,
|
&self,
|
||||||
address: u64,
|
address: u64,
|
||||||
code: &[u8],
|
code: &[u8],
|
||||||
_section_index: usize,
|
_section_index: usize,
|
||||||
_relocations: &[Relocation],
|
_relocations: &[Relocation],
|
||||||
_diff_config: &DiffObjConfig,
|
_diff_config: &DiffObjConfig,
|
||||||
) -> Result<Vec<ScannedInstruction>> {
|
) -> Result<Vec<InstructionRef>> {
|
||||||
let mut ops = Vec::<ScannedInstruction>::with_capacity(code.len() / 2);
|
let mut ops = Vec::<InstructionRef>::with_capacity(code.len() / 2);
|
||||||
let mut offset = address;
|
let mut offset = address;
|
||||||
|
|
||||||
for chunk in code.chunks_exact(2) {
|
for chunk in code.chunks_exact(2) {
|
||||||
@@ -56,9 +53,7 @@ impl Arch for ArchSuperH {
|
|||||||
Some(InstructionPart::Opcode(_, val)) => *val,
|
Some(InstructionPart::Opcode(_, val)) => *val,
|
||||||
_ => 0,
|
_ => 0,
|
||||||
};
|
};
|
||||||
let ins_ref: InstructionRef =
|
ops.push(InstructionRef { address: offset, size: 2, opcode: opcode_enum, branch_dest });
|
||||||
InstructionRef { address: offset, size: 2, opcode: opcode_enum };
|
|
||||||
ops.push(ScannedInstruction { ins_ref, branch_dest });
|
|
||||||
offset += 2;
|
offset += 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -77,10 +72,12 @@ impl Arch for ArchSuperH {
|
|||||||
|
|
||||||
sh2_disasm(0, opcode, true, &mut parts, &resolved, &mut branch_dest);
|
sh2_disasm(0, opcode, true, &mut parts, &resolved, &mut branch_dest);
|
||||||
|
|
||||||
if let Some(symbol_data) = resolved.section.symbol_data(resolved.symbol) {
|
if let Some(symbol_data) =
|
||||||
|
resolved.section.data_range(resolved.symbol.address, resolved.symbol.size as usize)
|
||||||
|
{
|
||||||
// scan for data
|
// scan for data
|
||||||
// map of instruction offsets to data target offsets
|
// map of instruction offsets to data target offsets
|
||||||
let mut data_offsets: HashMap<u64, DataInfo> = HashMap::<u64, DataInfo>::new();
|
let mut data_offsets = BTreeMap::<u64, DataInfo>::new();
|
||||||
|
|
||||||
let mut pos: u64 = 0;
|
let mut pos: u64 = 0;
|
||||||
for chunk in symbol_data.chunks_exact(2) {
|
for chunk in symbol_data.chunks_exact(2) {
|
||||||
@@ -255,7 +252,7 @@ mod test {
|
|||||||
|
|
||||||
arch.display_instruction(
|
arch.display_instruction(
|
||||||
ResolvedInstructionRef {
|
ResolvedInstructionRef {
|
||||||
ins_ref: InstructionRef { address: 0x1000, size: 2, opcode },
|
ins_ref: InstructionRef { address: 0x1000, size: 2, opcode, branch_dest: None },
|
||||||
code: &code,
|
code: &code,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
@@ -333,7 +330,7 @@ mod test {
|
|||||||
|
|
||||||
arch.display_instruction(
|
arch.display_instruction(
|
||||||
ResolvedInstructionRef {
|
ResolvedInstructionRef {
|
||||||
ins_ref: InstructionRef { address: 0x1000, size: 2, opcode },
|
ins_ref: InstructionRef { address: 0x1000, size: 2, opcode, branch_dest: None },
|
||||||
code: &code,
|
code: &code,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
@@ -416,7 +413,7 @@ mod test {
|
|||||||
|
|
||||||
arch.display_instruction(
|
arch.display_instruction(
|
||||||
ResolvedInstructionRef {
|
ResolvedInstructionRef {
|
||||||
ins_ref: InstructionRef { address: 0x1000, size: 2, opcode },
|
ins_ref: InstructionRef { address: 0x1000, size: 2, opcode, branch_dest: None },
|
||||||
code: &code,
|
code: &code,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
@@ -453,7 +450,7 @@ mod test {
|
|||||||
|
|
||||||
arch.display_instruction(
|
arch.display_instruction(
|
||||||
ResolvedInstructionRef {
|
ResolvedInstructionRef {
|
||||||
ins_ref: InstructionRef { address: 0x1000, size: 2, opcode },
|
ins_ref: InstructionRef { address: 0x1000, size: 2, opcode, branch_dest: None },
|
||||||
code: &code,
|
code: &code,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
@@ -502,7 +499,12 @@ mod test {
|
|||||||
|
|
||||||
arch.display_instruction(
|
arch.display_instruction(
|
||||||
ResolvedInstructionRef {
|
ResolvedInstructionRef {
|
||||||
ins_ref: InstructionRef { address: addr as u64, size: 2, opcode },
|
ins_ref: InstructionRef {
|
||||||
|
address: addr as u64,
|
||||||
|
size: 2,
|
||||||
|
opcode,
|
||||||
|
branch_dest: None,
|
||||||
|
},
|
||||||
code: &code,
|
code: &code,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
@@ -538,7 +540,12 @@ mod test {
|
|||||||
|
|
||||||
arch.display_instruction(
|
arch.display_instruction(
|
||||||
ResolvedInstructionRef {
|
ResolvedInstructionRef {
|
||||||
ins_ref: InstructionRef { address: addr as u64, size: 2, opcode },
|
ins_ref: InstructionRef {
|
||||||
|
address: addr as u64,
|
||||||
|
size: 2,
|
||||||
|
opcode,
|
||||||
|
branch_dest: None,
|
||||||
|
},
|
||||||
code: &code,
|
code: &code,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
@@ -577,7 +584,12 @@ mod test {
|
|||||||
|
|
||||||
arch.display_instruction(
|
arch.display_instruction(
|
||||||
ResolvedInstructionRef {
|
ResolvedInstructionRef {
|
||||||
ins_ref: InstructionRef { address: addr as u64, size: 2, opcode },
|
ins_ref: InstructionRef {
|
||||||
|
address: addr as u64,
|
||||||
|
size: 2,
|
||||||
|
opcode,
|
||||||
|
branch_dest: None,
|
||||||
|
},
|
||||||
code: &code,
|
code: &code,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
@@ -616,7 +628,12 @@ mod test {
|
|||||||
|
|
||||||
arch.display_instruction(
|
arch.display_instruction(
|
||||||
ResolvedInstructionRef {
|
ResolvedInstructionRef {
|
||||||
ins_ref: InstructionRef { address: addr as u64, size: 2, opcode },
|
ins_ref: InstructionRef {
|
||||||
|
address: addr as u64,
|
||||||
|
size: 2,
|
||||||
|
opcode,
|
||||||
|
branch_dest: None,
|
||||||
|
},
|
||||||
code: &code,
|
code: &code,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
@@ -648,7 +665,12 @@ mod test {
|
|||||||
|
|
||||||
arch.display_instruction(
|
arch.display_instruction(
|
||||||
ResolvedInstructionRef {
|
ResolvedInstructionRef {
|
||||||
ins_ref: InstructionRef { address: addr as u64, size: 2, opcode },
|
ins_ref: InstructionRef {
|
||||||
|
address: addr as u64,
|
||||||
|
size: 2,
|
||||||
|
opcode,
|
||||||
|
branch_dest: None,
|
||||||
|
},
|
||||||
code: &code,
|
code: &code,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
@@ -677,7 +699,12 @@ mod test {
|
|||||||
|
|
||||||
arch.display_instruction(
|
arch.display_instruction(
|
||||||
ResolvedInstructionRef {
|
ResolvedInstructionRef {
|
||||||
ins_ref: InstructionRef { address: addr as u64, size: 2, opcode },
|
ins_ref: InstructionRef {
|
||||||
|
address: addr as u64,
|
||||||
|
size: 2,
|
||||||
|
opcode,
|
||||||
|
branch_dest: None,
|
||||||
|
},
|
||||||
code: &code,
|
code: &code,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
@@ -709,7 +736,12 @@ mod test {
|
|||||||
|
|
||||||
arch.display_instruction(
|
arch.display_instruction(
|
||||||
ResolvedInstructionRef {
|
ResolvedInstructionRef {
|
||||||
ins_ref: InstructionRef { address: addr as u64, size: 2, opcode },
|
ins_ref: InstructionRef {
|
||||||
|
address: addr as u64,
|
||||||
|
size: 2,
|
||||||
|
opcode,
|
||||||
|
branch_dest: None,
|
||||||
|
},
|
||||||
code: &opcode.to_be_bytes(),
|
code: &opcode.to_be_bytes(),
|
||||||
symbol: &Symbol {
|
symbol: &Symbol {
|
||||||
address: 0x0606F378, // func base address
|
address: 0x0606F378, // func base address
|
||||||
@@ -754,7 +786,12 @@ mod test {
|
|||||||
|
|
||||||
arch.display_instruction(
|
arch.display_instruction(
|
||||||
ResolvedInstructionRef {
|
ResolvedInstructionRef {
|
||||||
ins_ref: InstructionRef { address: addr as u64, size: 2, opcode },
|
ins_ref: InstructionRef {
|
||||||
|
address: addr as u64,
|
||||||
|
size: 2,
|
||||||
|
opcode,
|
||||||
|
branch_dest: None,
|
||||||
|
},
|
||||||
code: &opcode.to_be_bytes(),
|
code: &opcode.to_be_bytes(),
|
||||||
symbol: &Symbol {
|
symbol: &Symbol {
|
||||||
address: 0x0606F378, // func base address
|
address: 0x0606F378, // func base address
|
||||||
|
|||||||
@@ -6,14 +6,12 @@ use iced_x86::{
|
|||||||
Decoder, DecoderOptions, DecoratorKind, FormatterOutput, FormatterTextKind, GasFormatter,
|
Decoder, DecoderOptions, DecoratorKind, FormatterOutput, FormatterTextKind, GasFormatter,
|
||||||
Instruction, IntelFormatter, MasmFormatter, NasmFormatter, NumberKind, OpKind, Register,
|
Instruction, IntelFormatter, MasmFormatter, NasmFormatter, NumberKind, OpKind, Register,
|
||||||
};
|
};
|
||||||
use object::{Endian as _, Object as _, ObjectSection as _, pe};
|
use object::{Endian as _, Object as _, ObjectSection as _, elf, pe};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
arch::Arch,
|
arch::Arch,
|
||||||
diff::{DiffObjConfig, X86Formatter, display::InstructionPart},
|
diff::{DiffObjConfig, X86Formatter, display::InstructionPart},
|
||||||
obj::{
|
obj::{InstructionRef, Relocation, RelocationFlags, ResolvedInstructionRef},
|
||||||
InstructionRef, Relocation, RelocationFlags, ResolvedInstructionRef, ScannedInstruction,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@@ -69,7 +67,11 @@ impl ArchX86 {
|
|||||||
pe::IMAGE_REL_I386_DIR32 | pe::IMAGE_REL_I386_REL32 => Some(4),
|
pe::IMAGE_REL_I386_DIR32 | pe::IMAGE_REL_I386_REL32 => Some(4),
|
||||||
_ => None,
|
_ => None,
|
||||||
},
|
},
|
||||||
_ => None,
|
RelocationFlags::Elf(typ) => match typ {
|
||||||
|
elf::R_386_32 | elf::R_386_PC32 => Some(4),
|
||||||
|
elf::R_386_16 => Some(2),
|
||||||
|
_ => None,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Architecture::X86_64 => match flags {
|
Architecture::X86_64 => match flags {
|
||||||
RelocationFlags::Coff(typ) => match typ {
|
RelocationFlags::Coff(typ) => match typ {
|
||||||
@@ -77,7 +79,11 @@ impl ArchX86 {
|
|||||||
pe::IMAGE_REL_AMD64_ADDR64 => Some(8),
|
pe::IMAGE_REL_AMD64_ADDR64 => Some(8),
|
||||||
_ => None,
|
_ => None,
|
||||||
},
|
},
|
||||||
_ => None,
|
RelocationFlags::Elf(typ) => match typ {
|
||||||
|
elf::R_X86_64_PC32 => Some(4),
|
||||||
|
elf::R_X86_64_64 => Some(8),
|
||||||
|
_ => None,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -86,14 +92,14 @@ impl ArchX86 {
|
|||||||
const DATA_OPCODE: u16 = u16::MAX - 1;
|
const DATA_OPCODE: u16 = u16::MAX - 1;
|
||||||
|
|
||||||
impl Arch for ArchX86 {
|
impl Arch for ArchX86 {
|
||||||
fn scan_instructions(
|
fn scan_instructions_internal(
|
||||||
&self,
|
&self,
|
||||||
address: u64,
|
address: u64,
|
||||||
code: &[u8],
|
code: &[u8],
|
||||||
_section_index: usize,
|
_section_index: usize,
|
||||||
relocations: &[Relocation],
|
relocations: &[Relocation],
|
||||||
_diff_config: &DiffObjConfig,
|
_diff_config: &DiffObjConfig,
|
||||||
) -> Result<Vec<ScannedInstruction>> {
|
) -> Result<Vec<InstructionRef>> {
|
||||||
let mut out = Vec::with_capacity(code.len() / 2);
|
let mut out = Vec::with_capacity(code.len() / 2);
|
||||||
let mut decoder = self.decoder(code, address);
|
let mut decoder = self.decoder(code, address);
|
||||||
let mut instruction = Instruction::default();
|
let mut instruction = Instruction::default();
|
||||||
@@ -112,12 +118,10 @@ impl Arch for ArchX86 {
|
|||||||
})?;
|
})?;
|
||||||
if decoder.set_position(decoder.position() + size).is_ok() {
|
if decoder.set_position(decoder.position() + size).is_ok() {
|
||||||
decoder.set_ip(address + size as u64);
|
decoder.set_ip(address + size as u64);
|
||||||
out.push(ScannedInstruction {
|
out.push(InstructionRef {
|
||||||
ins_ref: InstructionRef {
|
address,
|
||||||
address,
|
size: size as u8,
|
||||||
size: size as u8,
|
opcode: DATA_OPCODE,
|
||||||
opcode: DATA_OPCODE,
|
|
||||||
},
|
|
||||||
branch_dest: None,
|
branch_dest: None,
|
||||||
});
|
});
|
||||||
reloc_iter.next();
|
reloc_iter.next();
|
||||||
@@ -134,12 +138,10 @@ impl Arch for ArchX86 {
|
|||||||
OpKind::NearBranch64 => Some(instruction.near_branch64()),
|
OpKind::NearBranch64 => Some(instruction.near_branch64()),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
out.push(ScannedInstruction {
|
out.push(InstructionRef {
|
||||||
ins_ref: InstructionRef {
|
address,
|
||||||
address,
|
size: instruction.len() as u8,
|
||||||
size: instruction.len() as u8,
|
opcode: instruction.mnemonic() as u16,
|
||||||
opcode: instruction.mnemonic() as u16,
|
|
||||||
},
|
|
||||||
branch_dest,
|
branch_dest,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -233,7 +235,8 @@ impl Arch for ArchX86 {
|
|||||||
) -> Result<i64> {
|
) -> Result<i64> {
|
||||||
match self.arch {
|
match self.arch {
|
||||||
Architecture::X86 => match flags {
|
Architecture::X86 => match flags {
|
||||||
RelocationFlags::Coff(pe::IMAGE_REL_I386_DIR32 | pe::IMAGE_REL_I386_REL32) => {
|
RelocationFlags::Coff(pe::IMAGE_REL_I386_DIR32 | pe::IMAGE_REL_I386_REL32)
|
||||||
|
| RelocationFlags::Elf(elf::R_386_32 | elf::R_386_PC32) => {
|
||||||
let data =
|
let data =
|
||||||
section.data()?[address as usize..address as usize + 4].try_into()?;
|
section.data()?[address as usize..address as usize + 4].try_into()?;
|
||||||
Ok(self.endianness.read_i32_bytes(data) as i64)
|
Ok(self.endianness.read_i32_bytes(data) as i64)
|
||||||
@@ -241,12 +244,14 @@ impl Arch for ArchX86 {
|
|||||||
flags => bail!("Unsupported x86 implicit relocation {flags:?}"),
|
flags => bail!("Unsupported x86 implicit relocation {flags:?}"),
|
||||||
},
|
},
|
||||||
Architecture::X86_64 => match flags {
|
Architecture::X86_64 => match flags {
|
||||||
RelocationFlags::Coff(pe::IMAGE_REL_AMD64_ADDR32NB | pe::IMAGE_REL_AMD64_REL32) => {
|
RelocationFlags::Coff(pe::IMAGE_REL_AMD64_ADDR32NB | pe::IMAGE_REL_AMD64_REL32)
|
||||||
|
| RelocationFlags::Elf(elf::R_X86_64_32 | elf::R_X86_64_PC32) => {
|
||||||
let data =
|
let data =
|
||||||
section.data()?[address as usize..address as usize + 4].try_into()?;
|
section.data()?[address as usize..address as usize + 4].try_into()?;
|
||||||
Ok(self.endianness.read_i32_bytes(data) as i64)
|
Ok(self.endianness.read_i32_bytes(data) as i64)
|
||||||
}
|
}
|
||||||
RelocationFlags::Coff(pe::IMAGE_REL_AMD64_ADDR64) => {
|
RelocationFlags::Coff(pe::IMAGE_REL_AMD64_ADDR64)
|
||||||
|
| RelocationFlags::Elf(elf::R_X86_64_64) => {
|
||||||
let data =
|
let data =
|
||||||
section.data()?[address as usize..address as usize + 8].try_into()?;
|
section.data()?[address as usize..address as usize + 8].try_into()?;
|
||||||
Ok(self.endianness.read_i64_bytes(data))
|
Ok(self.endianness.read_i64_bytes(data))
|
||||||
@@ -457,15 +462,16 @@ mod test {
|
|||||||
0xc7, 0x85, 0x68, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x8b, 0x04, 0x85, 0x00,
|
0xc7, 0x85, 0x68, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x8b, 0x04, 0x85, 0x00,
|
||||||
0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00,
|
||||||
];
|
];
|
||||||
let scanned = arch.scan_instructions(0, &code, 0, &[], &DiffObjConfig::default()).unwrap();
|
let scanned =
|
||||||
|
arch.scan_instructions_internal(0, &code, 0, &[], &DiffObjConfig::default()).unwrap();
|
||||||
assert_eq!(scanned.len(), 2);
|
assert_eq!(scanned.len(), 2);
|
||||||
assert_eq!(scanned[0].ins_ref.address, 0);
|
assert_eq!(scanned[0].address, 0);
|
||||||
assert_eq!(scanned[0].ins_ref.size, 10);
|
assert_eq!(scanned[0].size, 10);
|
||||||
assert_eq!(scanned[0].ins_ref.opcode, iced_x86::Mnemonic::Mov as u16);
|
assert_eq!(scanned[0].opcode, iced_x86::Mnemonic::Mov as u16);
|
||||||
assert_eq!(scanned[0].branch_dest, None);
|
assert_eq!(scanned[0].branch_dest, None);
|
||||||
assert_eq!(scanned[1].ins_ref.address, 10);
|
assert_eq!(scanned[1].address, 10);
|
||||||
assert_eq!(scanned[1].ins_ref.size, 7);
|
assert_eq!(scanned[1].size, 7);
|
||||||
assert_eq!(scanned[1].ins_ref.opcode, iced_x86::Mnemonic::Mov as u16);
|
assert_eq!(scanned[1].opcode, iced_x86::Mnemonic::Mov as u16);
|
||||||
assert_eq!(scanned[1].branch_dest, None);
|
assert_eq!(scanned[1].branch_dest, None);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -477,7 +483,7 @@ mod test {
|
|||||||
let mut parts = Vec::new();
|
let mut parts = Vec::new();
|
||||||
arch.display_instruction(
|
arch.display_instruction(
|
||||||
ResolvedInstructionRef {
|
ResolvedInstructionRef {
|
||||||
ins_ref: InstructionRef { address: 0x1234, size: 10, opcode },
|
ins_ref: InstructionRef { address: 0x1234, size: 10, opcode, branch_dest: None },
|
||||||
code: &code,
|
code: &code,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
@@ -513,7 +519,7 @@ mod test {
|
|||||||
let mut parts = Vec::new();
|
let mut parts = Vec::new();
|
||||||
arch.display_instruction(
|
arch.display_instruction(
|
||||||
ResolvedInstructionRef {
|
ResolvedInstructionRef {
|
||||||
ins_ref: InstructionRef { address: 0x1234, size: 10, opcode },
|
ins_ref: InstructionRef { address: 0x1234, size: 10, opcode, branch_dest: None },
|
||||||
code: &code,
|
code: &code,
|
||||||
relocation: Some(ResolvedRelocation {
|
relocation: Some(ResolvedRelocation {
|
||||||
relocation: &Relocation {
|
relocation: &Relocation {
|
||||||
@@ -558,7 +564,7 @@ mod test {
|
|||||||
let mut parts = Vec::new();
|
let mut parts = Vec::new();
|
||||||
arch.display_instruction(
|
arch.display_instruction(
|
||||||
ResolvedInstructionRef {
|
ResolvedInstructionRef {
|
||||||
ins_ref: InstructionRef { address: 0x1234, size: 7, opcode },
|
ins_ref: InstructionRef { address: 0x1234, size: 7, opcode, branch_dest: None },
|
||||||
code: &code,
|
code: &code,
|
||||||
relocation: Some(ResolvedRelocation {
|
relocation: Some(ResolvedRelocation {
|
||||||
relocation: &Relocation {
|
relocation: &Relocation {
|
||||||
@@ -601,7 +607,7 @@ mod test {
|
|||||||
let mut parts = Vec::new();
|
let mut parts = Vec::new();
|
||||||
arch.display_instruction(
|
arch.display_instruction(
|
||||||
ResolvedInstructionRef {
|
ResolvedInstructionRef {
|
||||||
ins_ref: InstructionRef { address: 0x1234, size: 5, opcode },
|
ins_ref: InstructionRef { address: 0x1234, size: 5, opcode, branch_dest: None },
|
||||||
code: &code,
|
code: &code,
|
||||||
relocation: Some(ResolvedRelocation {
|
relocation: Some(ResolvedRelocation {
|
||||||
relocation: &Relocation {
|
relocation: &Relocation {
|
||||||
@@ -632,7 +638,7 @@ mod test {
|
|||||||
let mut parts = Vec::new();
|
let mut parts = Vec::new();
|
||||||
arch.display_instruction(
|
arch.display_instruction(
|
||||||
ResolvedInstructionRef {
|
ResolvedInstructionRef {
|
||||||
ins_ref: InstructionRef { address: 0x1234, size: 6, opcode },
|
ins_ref: InstructionRef { address: 0x1234, size: 6, opcode, branch_dest: None },
|
||||||
code: &code,
|
code: &code,
|
||||||
relocation: Some(ResolvedRelocation {
|
relocation: Some(ResolvedRelocation {
|
||||||
relocation: &Relocation {
|
relocation: &Relocation {
|
||||||
@@ -671,7 +677,7 @@ mod test {
|
|||||||
let mut parts = Vec::new();
|
let mut parts = Vec::new();
|
||||||
arch.display_instruction(
|
arch.display_instruction(
|
||||||
ResolvedInstructionRef {
|
ResolvedInstructionRef {
|
||||||
ins_ref: InstructionRef { address: 0x1234, size: 7, opcode },
|
ins_ref: InstructionRef { address: 0x1234, size: 7, opcode, branch_dest: None },
|
||||||
code: &code,
|
code: &code,
|
||||||
relocation: Some(ResolvedRelocation {
|
relocation: Some(ResolvedRelocation {
|
||||||
relocation: &Relocation {
|
relocation: &Relocation {
|
||||||
@@ -710,7 +716,7 @@ mod test {
|
|||||||
let mut parts = Vec::new();
|
let mut parts = Vec::new();
|
||||||
arch.display_instruction(
|
arch.display_instruction(
|
||||||
ResolvedInstructionRef {
|
ResolvedInstructionRef {
|
||||||
ins_ref: InstructionRef { address: 0x1234, size: 5, opcode },
|
ins_ref: InstructionRef { address: 0x1234, size: 5, opcode, branch_dest: None },
|
||||||
code: &code,
|
code: &code,
|
||||||
relocation: Some(ResolvedRelocation {
|
relocation: Some(ResolvedRelocation {
|
||||||
relocation: &Relocation {
|
relocation: &Relocation {
|
||||||
|
|||||||
@@ -434,6 +434,7 @@ impl From<LegacyReportItem> for ReportItem {
|
|||||||
demangled_name: value.demangled_name,
|
demangled_name: value.demangled_name,
|
||||||
virtual_address: value.address,
|
virtual_address: value.address,
|
||||||
}),
|
}),
|
||||||
|
address: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,15 +14,15 @@ use super::{
|
|||||||
};
|
};
|
||||||
use crate::obj::{
|
use crate::obj::{
|
||||||
InstructionArg, InstructionArgValue, InstructionRef, Object, ResolvedInstructionRef,
|
InstructionArg, InstructionArgValue, InstructionRef, Object, ResolvedInstructionRef,
|
||||||
ResolvedRelocation, ScannedInstruction, SymbolFlag, SymbolKind,
|
ResolvedRelocation, ResolvedSymbol, SymbolFlag, SymbolKind,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn no_diff_code(
|
pub fn no_diff_code(
|
||||||
obj: &Object,
|
obj: &Object,
|
||||||
symbol_idx: usize,
|
symbol_index: usize,
|
||||||
diff_config: &DiffObjConfig,
|
diff_config: &DiffObjConfig,
|
||||||
) -> Result<SymbolDiff> {
|
) -> Result<SymbolDiff> {
|
||||||
let symbol = &obj.symbols[symbol_idx];
|
let symbol = &obj.symbols[symbol_index];
|
||||||
let section_index = symbol.section.ok_or_else(|| anyhow!("Missing section for symbol"))?;
|
let section_index = symbol.section.ok_or_else(|| anyhow!("Missing section for symbol"))?;
|
||||||
let section = &obj.sections[section_index];
|
let section = &obj.sections[section_index];
|
||||||
let data = section.data_range(symbol.address, symbol.size as usize).ok_or_else(|| {
|
let data = section.data_range(symbol.address, symbol.size as usize).ok_or_else(|| {
|
||||||
@@ -33,18 +33,14 @@ pub fn no_diff_code(
|
|||||||
)
|
)
|
||||||
})?;
|
})?;
|
||||||
let ops = obj.arch.scan_instructions(
|
let ops = obj.arch.scan_instructions(
|
||||||
symbol.address,
|
ResolvedSymbol { obj, symbol_index, symbol, section_index, section, data },
|
||||||
data,
|
|
||||||
section_index,
|
|
||||||
§ion.relocations,
|
|
||||||
diff_config,
|
diff_config,
|
||||||
)?;
|
)?;
|
||||||
let mut instruction_rows = Vec::<InstructionDiffRow>::new();
|
let mut instruction_rows = Vec::<InstructionDiffRow>::new();
|
||||||
for i in &ops {
|
for i in &ops {
|
||||||
instruction_rows
|
instruction_rows.push(InstructionDiffRow { ins_ref: Some(*i), ..Default::default() });
|
||||||
.push(InstructionDiffRow { ins_ref: Some(i.ins_ref), ..Default::default() });
|
|
||||||
}
|
}
|
||||||
resolve_branches(obj, section_index, &ops, &mut instruction_rows);
|
resolve_branches(&ops, &mut instruction_rows);
|
||||||
Ok(SymbolDiff { target_symbol: None, match_percent: None, diff_score: None, instruction_rows })
|
Ok(SymbolDiff { target_symbol: None, match_percent: None, diff_score: None, instruction_rows })
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,22 +88,30 @@ pub fn diff_code(
|
|||||||
let left_section_idx = left_symbol.section.unwrap();
|
let left_section_idx = left_symbol.section.unwrap();
|
||||||
let right_section_idx = right_symbol.section.unwrap();
|
let right_section_idx = right_symbol.section.unwrap();
|
||||||
let left_ops = left_obj.arch.scan_instructions(
|
let left_ops = left_obj.arch.scan_instructions(
|
||||||
left_symbol.address,
|
ResolvedSymbol {
|
||||||
left_data,
|
obj: left_obj,
|
||||||
left_section_idx,
|
symbol_index: left_symbol_idx,
|
||||||
&left_section.relocations,
|
symbol: left_symbol,
|
||||||
|
section_index: left_section_idx,
|
||||||
|
section: left_section,
|
||||||
|
data: left_data,
|
||||||
|
},
|
||||||
diff_config,
|
diff_config,
|
||||||
)?;
|
)?;
|
||||||
let right_ops = right_obj.arch.scan_instructions(
|
let right_ops = right_obj.arch.scan_instructions(
|
||||||
right_symbol.address,
|
ResolvedSymbol {
|
||||||
right_data,
|
obj: right_obj,
|
||||||
right_section_idx,
|
symbol_index: right_symbol_idx,
|
||||||
&right_section.relocations,
|
symbol: right_symbol,
|
||||||
|
section_index: right_section_idx,
|
||||||
|
section: right_section,
|
||||||
|
data: right_data,
|
||||||
|
},
|
||||||
diff_config,
|
diff_config,
|
||||||
)?;
|
)?;
|
||||||
let (mut left_rows, mut right_rows) = diff_instructions(&left_ops, &right_ops)?;
|
let (mut left_rows, mut right_rows) = diff_instructions(&left_ops, &right_ops)?;
|
||||||
resolve_branches(left_obj, left_section_idx, &left_ops, &mut left_rows);
|
resolve_branches(&left_ops, &mut left_rows);
|
||||||
resolve_branches(right_obj, right_section_idx, &right_ops, &mut right_rows);
|
resolve_branches(&right_ops, &mut right_rows);
|
||||||
|
|
||||||
let mut diff_state = InstructionDiffState::default();
|
let mut diff_state = InstructionDiffState::default();
|
||||||
for (left_row, right_row) in left_rows.iter_mut().zip(right_rows.iter_mut()) {
|
for (left_row, right_row) in left_rows.iter_mut().zip(right_rows.iter_mut()) {
|
||||||
@@ -154,21 +158,21 @@ pub fn diff_code(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn diff_instructions(
|
fn diff_instructions(
|
||||||
left_insts: &[ScannedInstruction],
|
left_insts: &[InstructionRef],
|
||||||
right_insts: &[ScannedInstruction],
|
right_insts: &[InstructionRef],
|
||||||
) -> Result<(Vec<InstructionDiffRow>, Vec<InstructionDiffRow>)> {
|
) -> Result<(Vec<InstructionDiffRow>, Vec<InstructionDiffRow>)> {
|
||||||
let left_ops = left_insts.iter().map(|i| i.ins_ref.opcode).collect::<Vec<_>>();
|
let left_ops = left_insts.iter().map(|i| i.opcode).collect::<Vec<_>>();
|
||||||
let right_ops = right_insts.iter().map(|i| i.ins_ref.opcode).collect::<Vec<_>>();
|
let right_ops = right_insts.iter().map(|i| i.opcode).collect::<Vec<_>>();
|
||||||
let ops = similar::capture_diff_slices(similar::Algorithm::Patience, &left_ops, &right_ops);
|
let ops = similar::capture_diff_slices(similar::Algorithm::Patience, &left_ops, &right_ops);
|
||||||
if ops.is_empty() {
|
if ops.is_empty() {
|
||||||
ensure!(left_insts.len() == right_insts.len());
|
ensure!(left_insts.len() == right_insts.len());
|
||||||
let left_diff = left_insts
|
let left_diff = left_insts
|
||||||
.iter()
|
.iter()
|
||||||
.map(|i| InstructionDiffRow { ins_ref: Some(i.ins_ref), ..Default::default() })
|
.map(|i| InstructionDiffRow { ins_ref: Some(*i), ..Default::default() })
|
||||||
.collect();
|
.collect();
|
||||||
let right_diff = right_insts
|
let right_diff = right_insts
|
||||||
.iter()
|
.iter()
|
||||||
.map(|i| InstructionDiffRow { ins_ref: Some(i.ins_ref), ..Default::default() })
|
.map(|i| InstructionDiffRow { ins_ref: Some(*i), ..Default::default() })
|
||||||
.collect();
|
.collect();
|
||||||
return Ok((left_diff, right_diff));
|
return Ok((left_diff, right_diff));
|
||||||
}
|
}
|
||||||
@@ -187,14 +191,17 @@ fn diff_instructions(
|
|||||||
for op in ops {
|
for op in ops {
|
||||||
let (_tag, left_range, right_range) = op.as_tag_tuple();
|
let (_tag, left_range, right_range) = op.as_tag_tuple();
|
||||||
let len = left_range.len().max(right_range.len());
|
let len = left_range.len().max(right_range.len());
|
||||||
left_diff.extend(left_range.clone().map(|i| InstructionDiffRow {
|
left_diff.extend(
|
||||||
ins_ref: Some(left_insts[i].ins_ref),
|
left_range
|
||||||
..Default::default()
|
.clone()
|
||||||
}));
|
.map(|i| InstructionDiffRow { ins_ref: Some(left_insts[i]), ..Default::default() }),
|
||||||
right_diff.extend(right_range.clone().map(|i| InstructionDiffRow {
|
);
|
||||||
ins_ref: Some(right_insts[i].ins_ref),
|
right_diff.extend(
|
||||||
..Default::default()
|
right_range.clone().map(|i| InstructionDiffRow {
|
||||||
}));
|
ins_ref: Some(right_insts[i]),
|
||||||
|
..Default::default()
|
||||||
|
}),
|
||||||
|
);
|
||||||
if left_range.len() < len {
|
if left_range.len() < len {
|
||||||
left_diff.extend((left_range.len()..len).map(|_| InstructionDiffRow::default()));
|
left_diff.extend((left_range.len()..len).map(|_| InstructionDiffRow::default()));
|
||||||
}
|
}
|
||||||
@@ -215,13 +222,7 @@ fn arg_to_string(arg: &InstructionArg, reloc: Option<ResolvedRelocation>) -> Str
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_branches(
|
fn resolve_branches(ops: &[InstructionRef], rows: &mut [InstructionDiffRow]) {
|
||||||
obj: &Object,
|
|
||||||
section_index: usize,
|
|
||||||
ops: &[ScannedInstruction],
|
|
||||||
rows: &mut [InstructionDiffRow],
|
|
||||||
) {
|
|
||||||
let section = &obj.sections[section_index];
|
|
||||||
let mut branch_idx = 0u32;
|
let mut branch_idx = 0u32;
|
||||||
// Map addresses to indices
|
// Map addresses to indices
|
||||||
let mut addr_map = BTreeMap::<u64, u32>::new();
|
let mut addr_map = BTreeMap::<u64, u32>::new();
|
||||||
@@ -235,17 +236,7 @@ fn resolve_branches(
|
|||||||
for ((i, ins_diff), ins) in
|
for ((i, ins_diff), ins) in
|
||||||
rows.iter_mut().enumerate().filter(|(_, row)| row.ins_ref.is_some()).zip(ops)
|
rows.iter_mut().enumerate().filter(|(_, row)| row.ins_ref.is_some()).zip(ops)
|
||||||
{
|
{
|
||||||
let branch_dest = if let Some(resolved) = section.relocation_at(obj, ins.ins_ref) {
|
if let Some(ins_idx) = ins.branch_dest.and_then(|a| addr_map.get(&a).copied()) {
|
||||||
if resolved.symbol.section == Some(section_index) {
|
|
||||||
// If the relocation target is in the same section, use it as the branch destination
|
|
||||||
resolved.symbol.address.checked_add_signed(resolved.relocation.addend)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ins.branch_dest
|
|
||||||
};
|
|
||||||
if let Some(ins_idx) = branch_dest.and_then(|a| addr_map.get(&a).copied()) {
|
|
||||||
match branches.entry(ins_idx) {
|
match branches.entry(ins_idx) {
|
||||||
btree_map::Entry::Vacant(e) => {
|
btree_map::Entry::Vacant(e) => {
|
||||||
ins_diff.branch_to = Some(InstructionBranchTo { ins_idx, branch_idx });
|
ins_diff.branch_to = Some(InstructionBranchTo { ins_idx, branch_idx });
|
||||||
@@ -334,12 +325,11 @@ fn reloc_eq(
|
|||||||
|| display_ins_data_literals(left_obj, left_ins)
|
|| display_ins_data_literals(left_obj, left_ins)
|
||||||
== display_ins_data_literals(right_obj, right_ins))
|
== display_ins_data_literals(right_obj, right_ins))
|
||||||
}
|
}
|
||||||
(Some(_), None) => false,
|
|
||||||
(None, Some(_)) => {
|
(None, Some(_)) => {
|
||||||
// Match if possibly stripped weak symbol
|
// Match if possibly stripped weak symbol
|
||||||
symbol_name_addend_matches && right_reloc.symbol.flags.contains(SymbolFlag::Weak)
|
symbol_name_addend_matches && right_reloc.symbol.flags.contains(SymbolFlag::Weak)
|
||||||
}
|
}
|
||||||
(None, None) => symbol_name_addend_matches,
|
(Some(_), None) | (None, None) => symbol_name_addend_matches,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -53,12 +53,11 @@ fn reloc_eq(
|
|||||||
section_name_eq(left_obj, right_obj, sl, sr)
|
section_name_eq(left_obj, right_obj, sl, sr)
|
||||||
&& (symbol_name_addend_matches || address_eq(left, right))
|
&& (symbol_name_addend_matches || address_eq(left, right))
|
||||||
}
|
}
|
||||||
(Some(_), None) => false,
|
|
||||||
(None, Some(_)) => {
|
(None, Some(_)) => {
|
||||||
// Match if possibly stripped weak symbol
|
// Match if possibly stripped weak symbol
|
||||||
symbol_name_addend_matches && right.symbol.flags.contains(SymbolFlag::Weak)
|
symbol_name_addend_matches && right.symbol.flags.contains(SymbolFlag::Weak)
|
||||||
}
|
}
|
||||||
(None, None) => symbol_name_addend_matches,
|
(Some(_), None) | (None, None) => symbol_name_addend_matches,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -274,7 +273,6 @@ pub fn diff_data_section(
|
|||||||
// We only do this when all relocations on the left side match.
|
// We only do this when all relocations on the left side match.
|
||||||
if left_section_diff.match_percent.unwrap_or(-1.0) < match_percent {
|
if left_section_diff.match_percent.unwrap_or(-1.0) < match_percent {
|
||||||
left_section_diff.match_percent = Some(match_percent);
|
left_section_diff.match_percent = Some(match_percent);
|
||||||
right_section_diff.match_percent = Some(match_percent);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok((left_section_diff, right_section_diff))
|
Ok((left_section_diff, right_section_diff))
|
||||||
@@ -413,7 +411,7 @@ pub fn diff_generic_section(
|
|||||||
};
|
};
|
||||||
Ok((
|
Ok((
|
||||||
SectionDiff { match_percent: Some(match_percent), data_diff: vec![], reloc_diff: vec![] },
|
SectionDiff { match_percent: Some(match_percent), data_diff: vec![], reloc_diff: vec![] },
|
||||||
SectionDiff { match_percent: Some(match_percent), data_diff: vec![], reloc_diff: vec![] },
|
SectionDiff { match_percent: None, data_diff: vec![], reloc_diff: vec![] },
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -454,7 +452,7 @@ pub fn diff_bss_section(
|
|||||||
|
|
||||||
Ok((
|
Ok((
|
||||||
SectionDiff { match_percent: Some(match_percent), data_diff: vec![], reloc_diff: vec![] },
|
SectionDiff { match_percent: Some(match_percent), data_diff: vec![], reloc_diff: vec![] },
|
||||||
SectionDiff { match_percent: Some(match_percent), data_diff: vec![], reloc_diff: vec![] },
|
SectionDiff { match_percent: None, data_diff: vec![], reloc_diff: vec![] },
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,8 +14,9 @@ use regex::Regex;
|
|||||||
use crate::{
|
use crate::{
|
||||||
diff::{DiffObjConfig, InstructionDiffKind, InstructionDiffRow, ObjectDiff, SymbolDiff},
|
diff::{DiffObjConfig, InstructionDiffKind, InstructionDiffRow, ObjectDiff, SymbolDiff},
|
||||||
obj::{
|
obj::{
|
||||||
InstructionArg, InstructionArgValue, Object, ParsedInstruction, ResolvedInstructionRef,
|
FlowAnalysisValue, InstructionArg, InstructionArgValue, Object, ParsedInstruction,
|
||||||
ResolvedRelocation, SectionFlag, SectionKind, Symbol, SymbolFlag, SymbolKind,
|
ResolvedInstructionRef, ResolvedRelocation, SectionFlag, SectionKind, Symbol, SymbolFlag,
|
||||||
|
SymbolKind,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -47,11 +48,12 @@ pub enum DiffText<'a> {
|
|||||||
pub enum DiffTextColor {
|
pub enum DiffTextColor {
|
||||||
#[default]
|
#[default]
|
||||||
Normal, // Grey
|
Normal, // Grey
|
||||||
Dim, // Dark grey
|
Dim, // Dark grey
|
||||||
Bright, // White
|
Bright, // White
|
||||||
Replace, // Blue
|
DataFlow, // Light blue
|
||||||
Delete, // Red
|
Replace, // Blue
|
||||||
Insert, // Green
|
Delete, // Red
|
||||||
|
Insert, // Green
|
||||||
Rotating(u8),
|
Rotating(u8),
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -77,7 +79,7 @@ impl<'a> DiffTextSegment<'a> {
|
|||||||
const EOL_SEGMENT: DiffTextSegment<'static> =
|
const EOL_SEGMENT: DiffTextSegment<'static> =
|
||||||
DiffTextSegment { text: DiffText::Eol, color: DiffTextColor::Normal, pad_to: 0 };
|
DiffTextSegment { text: DiffText::Eol, color: DiffTextColor::Normal, pad_to: 0 };
|
||||||
|
|
||||||
#[derive(Debug, Default, Clone, PartialEq, Eq)]
|
#[derive(Debug, Default, Clone)]
|
||||||
pub enum HighlightKind {
|
pub enum HighlightKind {
|
||||||
#[default]
|
#[default]
|
||||||
None,
|
None,
|
||||||
@@ -186,6 +188,11 @@ pub fn display_row(
|
|||||||
}
|
}
|
||||||
let mut arg_idx = 0;
|
let mut arg_idx = 0;
|
||||||
let mut displayed_relocation = false;
|
let mut displayed_relocation = false;
|
||||||
|
let analysis_result = if diff_config.show_data_flow {
|
||||||
|
obj.flow_analysis_results.get(&resolved.symbol.address)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
obj.arch.display_instruction(resolved, diff_config, &mut |part| match part {
|
obj.arch.display_instruction(resolved, diff_config, &mut |part| match part {
|
||||||
InstructionPart::Basic(text) => {
|
InstructionPart::Basic(text) => {
|
||||||
if text.chars().all(|c| c == ' ') {
|
if text.chars().all(|c| c == ' ') {
|
||||||
@@ -205,16 +212,33 @@ pub fn display_row(
|
|||||||
InstructionPart::Arg(arg) => {
|
InstructionPart::Arg(arg) => {
|
||||||
let diff_index = ins_row.arg_diff.get(arg_idx).copied().unwrap_or_default();
|
let diff_index = ins_row.arg_diff.get(arg_idx).copied().unwrap_or_default();
|
||||||
arg_idx += 1;
|
arg_idx += 1;
|
||||||
match arg {
|
if arg == InstructionArg::Reloc {
|
||||||
InstructionArg::Value(value) => cb(DiffTextSegment {
|
displayed_relocation = true;
|
||||||
text: DiffText::Argument(value),
|
}
|
||||||
color: diff_index
|
let data_flow_value =
|
||||||
|
analysis_result.and_then(|result|
|
||||||
|
result.as_ref().get_argument_value_at_address(
|
||||||
|
ins_ref.address, (arg_idx - 1) as u8));
|
||||||
|
match (arg, data_flow_value, resolved.ins_ref.branch_dest) {
|
||||||
|
// If we have a flow analysis result, always use that over anything else.
|
||||||
|
(InstructionArg::Value(_) | InstructionArg::Reloc, Some(FlowAnalysisValue::Text(text)), _) => {
|
||||||
|
cb(DiffTextSegment {
|
||||||
|
text: DiffText::Argument(InstructionArgValue::Opaque(Cow::Borrowed(text))),
|
||||||
|
color: DiffTextColor::DataFlow,
|
||||||
|
pad_to: 0,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
(InstructionArg::Value(value), None, _) => {
|
||||||
|
let color = diff_index
|
||||||
.get()
|
.get()
|
||||||
.map_or(base_color, |i| DiffTextColor::Rotating(i as u8)),
|
.map_or(base_color, |i| DiffTextColor::Rotating(i as u8));
|
||||||
pad_to: 0,
|
cb(DiffTextSegment {
|
||||||
}),
|
text: DiffText::Argument(value),
|
||||||
InstructionArg::Reloc => {
|
color,
|
||||||
displayed_relocation = true;
|
pad_to: 0,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
(InstructionArg::Reloc, _, None) => {
|
||||||
let resolved = resolved.relocation.unwrap();
|
let resolved = resolved.relocation.unwrap();
|
||||||
let color = diff_index
|
let color = diff_index
|
||||||
.get()
|
.get()
|
||||||
@@ -233,7 +257,9 @@ pub fn display_row(
|
|||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
InstructionArg::BranchDest(dest) => {
|
(InstructionArg::BranchDest(dest), _, _) |
|
||||||
|
// If the relocation was resolved to a branch destination, emit that instead.
|
||||||
|
(InstructionArg::Reloc, _, Some(dest)) => {
|
||||||
if let Some(addr) = dest.checked_sub(resolved.symbol.address) {
|
if let Some(addr) = dest.checked_sub(resolved.symbol.address) {
|
||||||
cb(DiffTextSegment {
|
cb(DiffTextSegment {
|
||||||
text: DiffText::BranchDest(addr),
|
text: DiffText::BranchDest(addr),
|
||||||
@@ -284,6 +310,18 @@ pub fn display_row(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl PartialEq<HighlightKind> for HighlightKind {
|
||||||
|
fn eq(&self, other: &HighlightKind) -> bool {
|
||||||
|
match (self, other) {
|
||||||
|
(HighlightKind::Opcode(a), HighlightKind::Opcode(b)) => a == b,
|
||||||
|
(HighlightKind::Argument(a), HighlightKind::Argument(b)) => a.loose_eq(b),
|
||||||
|
(HighlightKind::Symbol(a), HighlightKind::Symbol(b)) => a == b,
|
||||||
|
(HighlightKind::Address(a), HighlightKind::Address(b)) => a == b,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl PartialEq<DiffText<'_>> for HighlightKind {
|
impl PartialEq<DiffText<'_>> for HighlightKind {
|
||||||
fn eq(&self, other: &DiffText) -> bool {
|
fn eq(&self, other: &DiffText) -> bool {
|
||||||
match (self, other) {
|
match (self, other) {
|
||||||
@@ -684,24 +722,25 @@ pub fn display_sections(
|
|||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
if let Some(section_idx) = section_idx {
|
if let Some(section_idx) = section_idx {
|
||||||
let section = &obj.sections[section_idx];
|
let section = &obj.sections[section_idx];
|
||||||
if section.kind == SectionKind::Unknown || section.flags.contains(SectionFlag::Hidden) {
|
if section.kind == SectionKind::Unknown {
|
||||||
// Skip unknown and hidden sections
|
// Skip unknown and hidden sections
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let section_diff = &diff.sections[section_idx];
|
let section_diff = &diff.sections[section_idx];
|
||||||
if section.kind == SectionKind::Code && reverse_fn_order {
|
let reverse_fn_order = section.kind == SectionKind::Code && reverse_fn_order;
|
||||||
symbols.sort_by(|a, b| {
|
symbols.sort_by(|a, b| {
|
||||||
let a_symbol = &obj.symbols[a.symbol];
|
let a = &obj.symbols[a.symbol];
|
||||||
let b_symbol = &obj.symbols[b.symbol];
|
let b = &obj.symbols[b.symbol];
|
||||||
symbol_sort_reverse(a_symbol, b_symbol)
|
section_symbol_sort(a, b)
|
||||||
});
|
.then_with(|| {
|
||||||
} else {
|
if reverse_fn_order {
|
||||||
symbols.sort_by(|a, b| {
|
b.address.cmp(&a.address)
|
||||||
let a_symbol = &obj.symbols[a.symbol];
|
} else {
|
||||||
let b_symbol = &obj.symbols[b.symbol];
|
a.address.cmp(&b.address)
|
||||||
symbol_sort(a_symbol, b_symbol)
|
}
|
||||||
});
|
})
|
||||||
}
|
.then_with(|| a.size.cmp(&b.size))
|
||||||
|
});
|
||||||
sections.push(SectionDisplay {
|
sections.push(SectionDisplay {
|
||||||
id: section.id.clone(),
|
id: section.id.clone(),
|
||||||
name: if section.flags.contains(SectionFlag::Combined) {
|
name: if section.flags.contains(SectionFlag::Combined) {
|
||||||
@@ -739,14 +778,6 @@ fn section_symbol_sort(a: &Symbol, b: &Symbol) -> Ordering {
|
|||||||
Ordering::Equal
|
Ordering::Equal
|
||||||
}
|
}
|
||||||
|
|
||||||
fn symbol_sort(a: &Symbol, b: &Symbol) -> Ordering {
|
|
||||||
section_symbol_sort(a, b).then(a.address.cmp(&b.address)).then(a.size.cmp(&b.size))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn symbol_sort_reverse(a: &Symbol, b: &Symbol) -> Ordering {
|
|
||||||
section_symbol_sort(a, b).then(b.address.cmp(&a.address)).then(b.size.cmp(&a.size))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn display_ins_data_labels(obj: &Object, resolved: ResolvedInstructionRef) -> Vec<String> {
|
pub fn display_ins_data_labels(obj: &Object, resolved: ResolvedInstructionRef) -> Vec<String> {
|
||||||
let Some(reloc) = resolved.relocation else {
|
let Some(reloc) = resolved.relocation else {
|
||||||
return Vec::new();
|
return Vec::new();
|
||||||
|
|||||||
@@ -341,11 +341,25 @@ pub fn diff_objs(
|
|||||||
if let (Some((right_obj, right_out)), Some((left_obj, left_out))) =
|
if let (Some((right_obj, right_out)), Some((left_obj, left_out))) =
|
||||||
(right.as_mut(), left.as_mut())
|
(right.as_mut(), left.as_mut())
|
||||||
{
|
{
|
||||||
if let Some(right_name) = &mapping_config.selecting_left {
|
if let Some(right_name) = mapping_config.selecting_left.as_deref() {
|
||||||
generate_mapping_symbols(right_obj, right_name, left_obj, left_out, diff_config)?;
|
generate_mapping_symbols(
|
||||||
|
left_obj,
|
||||||
|
left_out,
|
||||||
|
right_obj,
|
||||||
|
right_out,
|
||||||
|
MappingSymbol::Right(right_name),
|
||||||
|
diff_config,
|
||||||
|
)?;
|
||||||
}
|
}
|
||||||
if let Some(left_name) = &mapping_config.selecting_right {
|
if let Some(left_name) = mapping_config.selecting_right.as_deref() {
|
||||||
generate_mapping_symbols(left_obj, left_name, right_obj, right_out, diff_config)?;
|
generate_mapping_symbols(
|
||||||
|
left_obj,
|
||||||
|
left_out,
|
||||||
|
right_obj,
|
||||||
|
right_out,
|
||||||
|
MappingSymbol::Left(left_name),
|
||||||
|
diff_config,
|
||||||
|
)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -356,17 +370,28 @@ pub fn diff_objs(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
enum MappingSymbol<'a> {
|
||||||
|
Left(&'a str),
|
||||||
|
Right(&'a str),
|
||||||
|
}
|
||||||
|
|
||||||
/// When we're selecting a symbol to use as a comparison, we'll create comparisons for all
|
/// When we're selecting a symbol to use as a comparison, we'll create comparisons for all
|
||||||
/// symbols in the other object that match the selected symbol's section and kind. This allows
|
/// symbols in the other object that match the selected symbol's section and kind. This allows
|
||||||
/// us to display match percentages for all symbols in the other object that could be selected.
|
/// us to display match percentages for all symbols in the other object that could be selected.
|
||||||
fn generate_mapping_symbols(
|
fn generate_mapping_symbols(
|
||||||
base_obj: &Object,
|
left_obj: &Object,
|
||||||
base_name: &str,
|
left_out: &mut ObjectDiff,
|
||||||
target_obj: &Object,
|
right_obj: &Object,
|
||||||
target_out: &mut ObjectDiff,
|
right_out: &mut ObjectDiff,
|
||||||
|
mapping_symbol: MappingSymbol,
|
||||||
config: &DiffObjConfig,
|
config: &DiffObjConfig,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let Some(base_symbol_ref) = symbol_ref_by_name(base_obj, base_name) else {
|
let (base_obj, base_name, target_obj) = match mapping_symbol {
|
||||||
|
MappingSymbol::Left(name) => (left_obj, name, right_obj),
|
||||||
|
MappingSymbol::Right(name) => (right_obj, name, left_obj),
|
||||||
|
};
|
||||||
|
let Some(base_symbol_ref) = base_obj.symbol_by_name(base_name) else {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
};
|
};
|
||||||
let base_section_kind = symbol_section_kind(base_obj, &base_obj.symbols[base_symbol_ref]);
|
let base_section_kind = symbol_section_kind(base_obj, &base_obj.symbols[base_symbol_ref]);
|
||||||
@@ -377,32 +402,30 @@ fn generate_mapping_symbols(
|
|||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
match base_section_kind {
|
let (left_symbol_idx, right_symbol_idx) = match mapping_symbol {
|
||||||
|
MappingSymbol::Left(_) => (base_symbol_ref, target_symbol_index),
|
||||||
|
MappingSymbol::Right(_) => (target_symbol_index, base_symbol_ref),
|
||||||
|
};
|
||||||
|
let (left_diff, right_diff) = match base_section_kind {
|
||||||
SectionKind::Code => {
|
SectionKind::Code => {
|
||||||
let (left_diff, _right_diff) =
|
diff_code(left_obj, right_obj, left_symbol_idx, right_symbol_idx, config)
|
||||||
diff_code(target_obj, base_obj, target_symbol_index, base_symbol_ref, config)?;
|
|
||||||
target_out.mapping_symbols.push(MappingSymbolDiff {
|
|
||||||
symbol_index: target_symbol_index,
|
|
||||||
symbol_diff: left_diff,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
SectionKind::Data => {
|
SectionKind::Data => {
|
||||||
let (left_diff, _right_diff) =
|
diff_data_symbol(left_obj, right_obj, left_symbol_idx, right_symbol_idx)
|
||||||
diff_data_symbol(target_obj, base_obj, target_symbol_index, base_symbol_ref)?;
|
|
||||||
target_out.mapping_symbols.push(MappingSymbolDiff {
|
|
||||||
symbol_index: target_symbol_index,
|
|
||||||
symbol_diff: left_diff,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
SectionKind::Bss | SectionKind::Common => {
|
SectionKind::Bss | SectionKind::Common => {
|
||||||
let (left_diff, _right_diff) =
|
diff_bss_symbol(left_obj, right_obj, left_symbol_idx, right_symbol_idx)
|
||||||
diff_bss_symbol(target_obj, base_obj, target_symbol_index, base_symbol_ref)?;
|
|
||||||
target_out.mapping_symbols.push(MappingSymbolDiff {
|
|
||||||
symbol_index: target_symbol_index,
|
|
||||||
symbol_diff: left_diff,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
SectionKind::Unknown => {}
|
SectionKind::Unknown => continue,
|
||||||
|
}?;
|
||||||
|
match mapping_symbol {
|
||||||
|
MappingSymbol::Left(_) => right_out.mapping_symbols.push(MappingSymbolDiff {
|
||||||
|
symbol_index: right_symbol_idx,
|
||||||
|
symbol_diff: right_diff,
|
||||||
|
}),
|
||||||
|
MappingSymbol::Right(_) => left_out
|
||||||
|
.mapping_symbols
|
||||||
|
.push(MappingSymbolDiff { symbol_index: left_symbol_idx, symbol_diff: left_diff }),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -434,10 +457,6 @@ pub struct MappingConfig {
|
|||||||
pub selecting_right: Option<String>,
|
pub selecting_right: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn symbol_ref_by_name(obj: &Object, name: &str) -> Option<usize> {
|
|
||||||
obj.symbols.iter().position(|s| s.name == name)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn apply_symbol_mappings(
|
fn apply_symbol_mappings(
|
||||||
left: &Object,
|
left: &Object,
|
||||||
right: &Object,
|
right: &Object,
|
||||||
@@ -449,25 +468,25 @@ fn apply_symbol_mappings(
|
|||||||
// If we're selecting a symbol to use as a comparison, mark it as used
|
// If we're selecting a symbol to use as a comparison, mark it as used
|
||||||
// This ensures that we don't match it to another symbol at any point
|
// This ensures that we don't match it to another symbol at any point
|
||||||
if let Some(left_name) = &mapping_config.selecting_left {
|
if let Some(left_name) = &mapping_config.selecting_left {
|
||||||
if let Some(left_symbol) = symbol_ref_by_name(left, left_name) {
|
if let Some(left_symbol) = left.symbol_by_name(left_name) {
|
||||||
left_used.insert(left_symbol);
|
left_used.insert(left_symbol);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let Some(right_name) = &mapping_config.selecting_right {
|
if let Some(right_name) = &mapping_config.selecting_right {
|
||||||
if let Some(right_symbol) = symbol_ref_by_name(right, right_name) {
|
if let Some(right_symbol) = right.symbol_by_name(right_name) {
|
||||||
right_used.insert(right_symbol);
|
right_used.insert(right_symbol);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply manual symbol mappings
|
// Apply manual symbol mappings
|
||||||
for (left_name, right_name) in &mapping_config.mappings {
|
for (left_name, right_name) in &mapping_config.mappings {
|
||||||
let Some(left_symbol_index) = symbol_ref_by_name(left, left_name) else {
|
let Some(left_symbol_index) = left.symbol_by_name(left_name) else {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
if left_used.contains(&left_symbol_index) {
|
if left_used.contains(&left_symbol_index) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let Some(right_symbol_index) = symbol_ref_by_name(right, right_name) else {
|
let Some(right_symbol_index) = right.symbol_by_name(right_name) else {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
if right_used.contains(&right_symbol_index) {
|
if right_used.contains(&right_symbol_index) {
|
||||||
@@ -658,7 +677,11 @@ fn find_symbol(
|
|||||||
|
|
||||||
/// Find matching sections between each object.
|
/// Find matching sections between each object.
|
||||||
fn matching_sections(left: Option<&Object>, right: Option<&Object>) -> Result<Vec<SectionMatch>> {
|
fn matching_sections(left: Option<&Object>, right: Option<&Object>) -> Result<Vec<SectionMatch>> {
|
||||||
let mut matches = Vec::new();
|
let mut matches = Vec::with_capacity(
|
||||||
|
left.as_ref()
|
||||||
|
.map_or(0, |o| o.sections.len())
|
||||||
|
.max(right.as_ref().map_or(0, |o| o.sections.len())),
|
||||||
|
);
|
||||||
if let Some(left) = left {
|
if let Some(left) = left {
|
||||||
for (section_idx, section) in left.sections.iter().enumerate() {
|
for (section_idx, section) in left.sections.iter().enumerate() {
|
||||||
if section.kind == SectionKind::Unknown {
|
if section.kind == SectionKind::Unknown {
|
||||||
@@ -666,7 +689,7 @@ fn matching_sections(left: Option<&Object>, right: Option<&Object>) -> Result<Ve
|
|||||||
}
|
}
|
||||||
matches.push(SectionMatch {
|
matches.push(SectionMatch {
|
||||||
left: Some(section_idx),
|
left: Some(section_idx),
|
||||||
right: find_section(right, §ion.name, section.kind),
|
right: find_section(right, §ion.name, section.kind, &matches),
|
||||||
section_kind: section.kind,
|
section_kind: section.kind,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -689,6 +712,13 @@ fn matching_sections(left: Option<&Object>, right: Option<&Object>) -> Result<Ve
|
|||||||
Ok(matches)
|
Ok(matches)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_section(obj: Option<&Object>, name: &str, section_kind: SectionKind) -> Option<usize> {
|
fn find_section(
|
||||||
obj?.sections.iter().position(|s| s.kind == section_kind && s.name == name)
|
obj: Option<&Object>,
|
||||||
|
name: &str,
|
||||||
|
section_kind: SectionKind,
|
||||||
|
matches: &[SectionMatch],
|
||||||
|
) -> Option<usize> {
|
||||||
|
obj?.sections.iter().enumerate().position(|(i, s)| {
|
||||||
|
s.kind == section_kind && s.name == name && !matches.iter().any(|m| m.right == Some(i))
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,7 +57,6 @@ flags! {
|
|||||||
pub enum SectionFlag: u8 {
|
pub enum SectionFlag: u8 {
|
||||||
/// Section combined from multiple input sections
|
/// Section combined from multiple input sections
|
||||||
Combined,
|
Combined,
|
||||||
Hidden,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -99,19 +98,8 @@ impl fmt::Debug for SectionData {
|
|||||||
|
|
||||||
impl Section {
|
impl Section {
|
||||||
pub fn data_range(&self, address: u64, size: usize) -> Option<&[u8]> {
|
pub fn data_range(&self, address: u64, size: usize) -> Option<&[u8]> {
|
||||||
let start = self.address;
|
let offset = address.checked_sub(self.address)?;
|
||||||
let end = start + self.size;
|
self.data.get(offset as usize..offset as usize + size)
|
||||||
if address >= start && address + size as u64 <= end {
|
|
||||||
let offset = (address - start) as usize;
|
|
||||||
Some(&self.data[offset..offset + size])
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn symbol_data(&self, symbol: &Symbol) -> Option<&[u8]> {
|
|
||||||
let offset = symbol.address.checked_sub(self.address)?;
|
|
||||||
self.data.get(offset as usize..offset as usize + symbol.size as usize)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// The alignment to use when "Combine data/text sections" is enabled.
|
// The alignment to use when "Combine data/text sections" is enabled.
|
||||||
@@ -130,7 +118,7 @@ impl Section {
|
|||||||
Err(i) => self
|
Err(i) => self
|
||||||
.relocations
|
.relocations
|
||||||
.get(i)
|
.get(i)
|
||||||
.take_if(|r| r.address < ins_ref.address + ins_ref.size as u64),
|
.filter(|r| r.address < ins_ref.address + ins_ref.size as u64),
|
||||||
}
|
}
|
||||||
.and_then(|relocation| {
|
.and_then(|relocation| {
|
||||||
let symbol = obj.symbols.get(relocation.target_symbol)?;
|
let symbol = obj.symbols.get(relocation.target_symbol)?;
|
||||||
@@ -226,11 +214,6 @@ pub struct InstructionRef {
|
|||||||
pub address: u64,
|
pub address: u64,
|
||||||
pub size: u8,
|
pub size: u8,
|
||||||
pub opcode: u16,
|
pub opcode: u16,
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug)]
|
|
||||||
pub struct ScannedInstruction {
|
|
||||||
pub ins_ref: InstructionRef,
|
|
||||||
pub branch_dest: Option<u64>,
|
pub branch_dest: Option<u64>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -250,6 +233,19 @@ pub enum SymbolKind {
|
|||||||
Section,
|
Section,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum FlowAnalysisValue {
|
||||||
|
Text(String),
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait FlowAnalysisResult: core::fmt::Debug + Send {
|
||||||
|
fn get_argument_value_at_address(
|
||||||
|
&self,
|
||||||
|
address: u64,
|
||||||
|
argument: u8,
|
||||||
|
) -> Option<&FlowAnalysisValue>;
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Eq, PartialEq, Hash, Default)]
|
#[derive(Debug, Clone, Eq, PartialEq, Hash, Default)]
|
||||||
pub struct Symbol {
|
pub struct Symbol {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
@@ -277,6 +273,7 @@ pub struct Object {
|
|||||||
pub path: Option<std::path::PathBuf>,
|
pub path: Option<std::path::PathBuf>,
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
pub timestamp: Option<filetime::FileTime>,
|
pub timestamp: Option<filetime::FileTime>,
|
||||||
|
pub flow_analysis_results: BTreeMap<u64, Box<dyn FlowAnalysisResult>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Object {
|
impl Default for Object {
|
||||||
@@ -291,6 +288,7 @@ impl Default for Object {
|
|||||||
path: None,
|
path: None,
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
timestamp: None,
|
timestamp: None,
|
||||||
|
flow_analysis_results: BTreeMap::<u64, Box<dyn FlowAnalysisResult>>::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -325,6 +323,12 @@ impl Object {
|
|||||||
let offset = symbol.address.checked_sub(section.address)?;
|
let offset = symbol.address.checked_sub(section.address)?;
|
||||||
section.data.get(offset as usize..offset as usize + symbol.size as usize)
|
section.data.get(offset as usize..offset as usize + symbol.size as usize)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn symbol_by_name(&self, name: &str) -> Option<usize> {
|
||||||
|
self.symbols.iter().position(|symbol| symbol.section.is_some() && symbol.name == name)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn has_flow_analysis_result(&self) -> bool { !self.flow_analysis_results.is_empty() }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
|
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
|
||||||
@@ -347,6 +351,16 @@ pub struct ResolvedRelocation<'a> {
|
|||||||
pub symbol: &'a Symbol,
|
pub symbol: &'a Symbol,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Copy, Clone)]
|
||||||
|
pub struct ResolvedSymbol<'obj> {
|
||||||
|
pub obj: &'obj Object,
|
||||||
|
pub symbol_index: usize,
|
||||||
|
pub symbol: &'obj Symbol,
|
||||||
|
pub section_index: usize,
|
||||||
|
pub section: &'obj Section,
|
||||||
|
pub data: &'obj [u8],
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
pub struct ResolvedInstructionRef<'obj> {
|
pub struct ResolvedInstructionRef<'obj> {
|
||||||
pub ins_ref: InstructionRef,
|
pub ins_ref: InstructionRef,
|
||||||
|
|||||||
@@ -121,6 +121,15 @@ fn map_symbols(
|
|||||||
Ok((symbols, symbol_indices))
|
Ok((symbols, symbol_indices))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// When inferring a symbol's size, we ignore symbols that start with specific prefixes. They are
|
||||||
|
/// usually emitted as branch targets and do not represent the start of a function or object.
|
||||||
|
fn is_local_label(symbol: &Symbol) -> bool {
|
||||||
|
const LABEL_PREFIXES: &[&str] = &[".L", "LAB_"];
|
||||||
|
symbol.size == 0
|
||||||
|
&& symbol.flags.contains(SymbolFlag::Local)
|
||||||
|
&& LABEL_PREFIXES.iter().any(|p| symbol.name.starts_with(p))
|
||||||
|
}
|
||||||
|
|
||||||
fn infer_symbol_sizes(symbols: &mut [Symbol], sections: &[Section]) {
|
fn infer_symbol_sizes(symbols: &mut [Symbol], sections: &[Section]) {
|
||||||
// Create a sorted list of symbol indices by section
|
// Create a sorted list of symbol indices by section
|
||||||
let mut symbols_with_section = Vec::<usize>::with_capacity(symbols.len());
|
let mut symbols_with_section = Vec::<usize>::with_capacity(symbols.len());
|
||||||
@@ -167,27 +176,28 @@ fn infer_symbol_sizes(symbols: &mut [Symbol], sections: &[Section]) {
|
|||||||
if last_end.0 == section_idx && last_end.1 > symbol.address {
|
if last_end.0 == section_idx && last_end.1 > symbol.address {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let next_symbol = match symbol.kind {
|
let next_symbol = loop {
|
||||||
// For function/object symbols, find the next function/object symbol (in other words:
|
if iter_idx >= symbols_with_section.len() {
|
||||||
// skip over labels)
|
break None;
|
||||||
SymbolKind::Function | SymbolKind::Object => loop {
|
}
|
||||||
if iter_idx >= symbols_with_section.len() {
|
let next_symbol = &symbols[symbols_with_section[iter_idx]];
|
||||||
break None;
|
if next_symbol.section != Some(section_idx) {
|
||||||
|
break None;
|
||||||
|
}
|
||||||
|
if match symbol.kind {
|
||||||
|
SymbolKind::Function | SymbolKind::Object => {
|
||||||
|
// For function/object symbols, find the next function/object
|
||||||
|
matches!(next_symbol.kind, SymbolKind::Function | SymbolKind::Object)
|
||||||
}
|
}
|
||||||
let next_symbol = &symbols[symbols_with_section[iter_idx]];
|
SymbolKind::Unknown | SymbolKind::Section => {
|
||||||
if next_symbol.section != Some(section_idx) {
|
// For labels (or anything else), stop at any symbol
|
||||||
break None;
|
true
|
||||||
}
|
}
|
||||||
if let SymbolKind::Function | SymbolKind::Object = next_symbol.kind {
|
} && !is_local_label(next_symbol)
|
||||||
break Some(next_symbol);
|
{
|
||||||
}
|
break Some(next_symbol);
|
||||||
iter_idx += 1;
|
}
|
||||||
},
|
iter_idx += 1;
|
||||||
// For labels (or anything else), simply use the next symbol's address
|
|
||||||
SymbolKind::Unknown | SymbolKind::Section => symbols_with_section
|
|
||||||
.get(iter_idx)
|
|
||||||
.map(|&i| &symbols[i])
|
|
||||||
.take_if(|s| s.section == Some(section_idx)),
|
|
||||||
};
|
};
|
||||||
let next_address = next_symbol.map(|s| s.address).unwrap_or_else(|| {
|
let next_address = next_symbol.map(|s| s.address).unwrap_or_else(|| {
|
||||||
let section = §ions[section_idx];
|
let section = §ions[section_idx];
|
||||||
@@ -341,7 +351,7 @@ fn map_section_relocations(
|
|||||||
let idx = if let Some(section_symbol) = obj_file
|
let idx = if let Some(section_symbol) = obj_file
|
||||||
.symbol_by_index(idx)
|
.symbol_by_index(idx)
|
||||||
.ok()
|
.ok()
|
||||||
.take_if(|s| s.kind() == object::SymbolKind::Section)
|
.filter(|s| s.kind() == object::SymbolKind::Section)
|
||||||
{
|
{
|
||||||
let section_index =
|
let section_index =
|
||||||
section_symbol.section_index().context("Section symbol without section")?;
|
section_symbol.section_index().context("Section symbol without section")?;
|
||||||
@@ -422,17 +432,18 @@ fn map_relocations(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn calculate_pooled_relocations(
|
fn perform_data_flow_analysis(obj: &mut Object, config: &DiffObjConfig) -> Result<()> {
|
||||||
arch: &dyn Arch,
|
// If neither of these settings are on, no flow analysis to perform
|
||||||
sections: &mut [Section],
|
if !config.analyze_data_flow && !config.ppc_calculate_pool_relocations {
|
||||||
symbols: &[Symbol],
|
return Ok(());
|
||||||
) -> Result<()> {
|
}
|
||||||
for (section_index, section) in sections.iter_mut().enumerate() {
|
|
||||||
|
let mut generated_relocations = Vec::<(usize, Vec<Relocation>)>::new();
|
||||||
|
for (section_index, section) in obj.sections.iter().enumerate() {
|
||||||
if section.kind != SectionKind::Code {
|
if section.kind != SectionKind::Code {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let mut fake_pool_relocs = Vec::new();
|
for symbol in obj.symbols.iter() {
|
||||||
for symbol in symbols {
|
|
||||||
if symbol.section != Some(section_index) {
|
if symbol.section != Some(section_index) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -447,14 +458,32 @@ fn calculate_pooled_relocations(
|
|||||||
symbol.address + symbol.size
|
symbol.address + symbol.size
|
||||||
)
|
)
|
||||||
})?;
|
})?;
|
||||||
fake_pool_relocs.append(&mut arch.generate_pooled_relocations(
|
|
||||||
symbol.address,
|
// Optional pooled relocation computation
|
||||||
code,
|
// Long view: This could be replaced by the full data flow analysis
|
||||||
§ion.relocations,
|
// once that feature has stabilized.
|
||||||
symbols,
|
if config.ppc_calculate_pool_relocations {
|
||||||
));
|
let relocations = obj.arch.generate_pooled_relocations(
|
||||||
|
symbol.address,
|
||||||
|
code,
|
||||||
|
§ion.relocations,
|
||||||
|
&obj.symbols,
|
||||||
|
);
|
||||||
|
generated_relocations.push((section_index, relocations));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Optional full data flow analysis
|
||||||
|
if config.analyze_data_flow {
|
||||||
|
obj.arch.data_flow_analysis(obj, symbol, code, §ion.relocations).and_then(
|
||||||
|
|flow_result| obj.flow_analysis_results.insert(symbol.address, flow_result),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
section.relocations.append(&mut fake_pool_relocs);
|
}
|
||||||
|
for (section_index, mut relocations) in generated_relocations {
|
||||||
|
obj.sections[section_index].relocations.append(&mut relocations);
|
||||||
|
}
|
||||||
|
for section in obj.sections.iter_mut() {
|
||||||
section.relocations.sort_by_key(|r| r.address);
|
section.relocations.sort_by_key(|r| r.address);
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -764,7 +793,7 @@ fn do_combine_sections(
|
|||||||
line_info.append(&mut section.line_info.iter().map(|(&a, &l)| (a + offset, l)).collect());
|
line_info.append(&mut section.line_info.iter().map(|(&a, &l)| (a + offset, l)).collect());
|
||||||
section.line_info.clear();
|
section.line_info.clear();
|
||||||
if offset > 0 {
|
if offset > 0 {
|
||||||
section.flags |= SectionFlag::Hidden;
|
section.kind = SectionKind::Unknown;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
@@ -855,15 +884,12 @@ pub fn parse(data: &[u8], config: &DiffObjConfig) -> Result<Object> {
|
|||||||
let (mut symbols, symbol_indices) =
|
let (mut symbols, symbol_indices) =
|
||||||
map_symbols(arch.as_ref(), &obj_file, §ions, §ion_indices, split_meta.as_ref())?;
|
map_symbols(arch.as_ref(), &obj_file, §ions, §ion_indices, split_meta.as_ref())?;
|
||||||
map_relocations(arch.as_ref(), &obj_file, &mut sections, §ion_indices, &symbol_indices)?;
|
map_relocations(arch.as_ref(), &obj_file, &mut sections, §ion_indices, &symbol_indices)?;
|
||||||
if config.ppc_calculate_pool_relocations {
|
|
||||||
calculate_pooled_relocations(arch.as_ref(), &mut sections, &symbols)?;
|
|
||||||
}
|
|
||||||
parse_line_info(&obj_file, &mut sections, §ion_indices, data)?;
|
parse_line_info(&obj_file, &mut sections, §ion_indices, data)?;
|
||||||
if config.combine_data_sections || config.combine_text_sections {
|
if config.combine_data_sections || config.combine_text_sections {
|
||||||
combine_sections(&mut sections, &mut symbols, config)?;
|
combine_sections(&mut sections, &mut symbols, config)?;
|
||||||
}
|
}
|
||||||
arch.post_init(§ions, &symbols);
|
arch.post_init(§ions, &symbols);
|
||||||
Ok(Object {
|
let mut obj = Object {
|
||||||
arch,
|
arch,
|
||||||
endianness: obj_file.endianness(),
|
endianness: obj_file.endianness(),
|
||||||
symbols,
|
symbols,
|
||||||
@@ -873,7 +899,14 @@ pub fn parse(data: &[u8], config: &DiffObjConfig) -> Result<Object> {
|
|||||||
path: None,
|
path: None,
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
timestamp: None,
|
timestamp: None,
|
||||||
})
|
flow_analysis_results: Default::default(),
|
||||||
|
};
|
||||||
|
|
||||||
|
// Need to construct the obj first so that we have a convinient package to
|
||||||
|
// pass to flow analysis. Then the flow analysis will mutate obj adding
|
||||||
|
// additional data to it.
|
||||||
|
perform_data_flow_analysis(&mut obj, config)?;
|
||||||
|
Ok(obj)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
|
|||||||
@@ -84,11 +84,11 @@ expression: "(sections, symbols)"
|
|||||||
name: ".data",
|
name: ".data",
|
||||||
address: 0,
|
address: 0,
|
||||||
size: 0,
|
size: 0,
|
||||||
kind: Data,
|
kind: Unknown,
|
||||||
data: SectionData(
|
data: SectionData(
|
||||||
0,
|
0,
|
||||||
),
|
),
|
||||||
flags: FlagSet(Hidden),
|
flags: FlagSet(),
|
||||||
align: None,
|
align: None,
|
||||||
relocations: [],
|
relocations: [],
|
||||||
line_info: {},
|
line_info: {},
|
||||||
@@ -99,11 +99,11 @@ expression: "(sections, symbols)"
|
|||||||
name: ".data",
|
name: ".data",
|
||||||
address: 0,
|
address: 0,
|
||||||
size: 0,
|
size: 0,
|
||||||
kind: Data,
|
kind: Unknown,
|
||||||
data: SectionData(
|
data: SectionData(
|
||||||
0,
|
0,
|
||||||
),
|
),
|
||||||
flags: FlagSet(Hidden),
|
flags: FlagSet(),
|
||||||
align: None,
|
align: None,
|
||||||
relocations: [],
|
relocations: [],
|
||||||
line_info: {},
|
line_info: {},
|
||||||
|
|||||||
@@ -57,6 +57,35 @@ pub fn align_data_to_4<W: std::io::Write + ?Sized>(
|
|||||||
pub fn align_u64_to(len: u64, align: u64) -> u64 { len + ((align - (len % align)) % align) }
|
pub fn align_u64_to(len: u64, align: u64) -> u64 { len + ((align - (len % align)) % align) }
|
||||||
|
|
||||||
pub fn align_data_slice_to(data: &mut Vec<u8>, align: u64) {
|
pub fn align_data_slice_to(data: &mut Vec<u8>, align: u64) {
|
||||||
const ALIGN_BYTE: u8 = 0;
|
data.resize(align_u64_to(data.len() as u64, align) as usize, 0);
|
||||||
data.resize(align_u64_to(data.len() as u64, align) as usize, ALIGN_BYTE);
|
}
|
||||||
|
|
||||||
|
// Float where we specifically care about comparing the raw bits rather than
|
||||||
|
// caring about IEEE semantics.
|
||||||
|
#[derive(Copy, Clone, Debug)]
|
||||||
|
pub struct RawFloat(pub f32);
|
||||||
|
impl PartialEq for RawFloat {
|
||||||
|
fn eq(&self, other: &Self) -> bool { self.0.to_bits() == other.0.to_bits() }
|
||||||
|
}
|
||||||
|
impl Eq for RawFloat {}
|
||||||
|
impl Ord for RawFloat {
|
||||||
|
fn cmp(&self, other: &Self) -> core::cmp::Ordering { self.0.to_bits().cmp(&other.0.to_bits()) }
|
||||||
|
}
|
||||||
|
impl PartialOrd for RawFloat {
|
||||||
|
fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> { Some(self.cmp(other)) }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Double where we specifically care about comparing the raw bits rather than
|
||||||
|
// caring about IEEE semantics.
|
||||||
|
#[derive(Copy, Clone, Debug)]
|
||||||
|
pub struct RawDouble(pub f64);
|
||||||
|
impl PartialEq for RawDouble {
|
||||||
|
fn eq(&self, other: &Self) -> bool { self.0.to_bits() == other.0.to_bits() }
|
||||||
|
}
|
||||||
|
impl Eq for RawDouble {}
|
||||||
|
impl Ord for RawDouble {
|
||||||
|
fn cmp(&self, other: &Self) -> core::cmp::Ordering { self.0.to_bits().cmp(&other.0.to_bits()) }
|
||||||
|
}
|
||||||
|
impl PartialOrd for RawDouble {
|
||||||
|
fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> { Some(self.cmp(other)) }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,3 +68,12 @@ fn read_x86_jumptable() {
|
|||||||
let output = common::display_diff(&obj, &diff, symbol_idx, &diff_config);
|
let output = common::display_diff(&obj, &diff, symbol_idx, &diff_config);
|
||||||
insta::assert_snapshot!(output);
|
insta::assert_snapshot!(output);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Inferred size of functions should ignore symbols with specific prefixes
|
||||||
|
#[test]
|
||||||
|
#[cfg(feature = "x86")]
|
||||||
|
fn read_x86_local_labels() {
|
||||||
|
let diff_config = diff::DiffObjConfig::default();
|
||||||
|
let obj = obj::read::parse(include_object!("data/x86/local_labels.obj"), &diff_config).unwrap();
|
||||||
|
insta::assert_debug_snapshot!(obj);
|
||||||
|
}
|
||||||
|
|||||||
BIN
objdiff-core/tests/data/x86/local_labels.obj
Normal file
BIN
objdiff-core/tests/data/x86/local_labels.obj
Normal file
Binary file not shown.
@@ -1,6 +1,5 @@
|
|||||||
---
|
---
|
||||||
source: objdiff-core/tests/arch_arm.rs
|
source: objdiff-core/tests/arch_arm.rs
|
||||||
assertion_line: 43
|
|
||||||
expression: diff.instruction_rows
|
expression: diff.instruction_rows
|
||||||
---
|
---
|
||||||
[
|
[
|
||||||
@@ -10,6 +9,7 @@ expression: diff.instruction_rows
|
|||||||
address: 76,
|
address: 76,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32799,
|
opcode: 32799,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -23,6 +23,7 @@ expression: diff.instruction_rows
|
|||||||
address: 80,
|
address: 80,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32779,
|
opcode: 32779,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -36,6 +37,7 @@ expression: diff.instruction_rows
|
|||||||
address: 84,
|
address: 84,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 65535,
|
opcode: 65535,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ expression: diff.instruction_rows
|
|||||||
address: 40,
|
address: 40,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32895,
|
opcode: 32895,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -22,6 +23,7 @@ expression: diff.instruction_rows
|
|||||||
address: 44,
|
address: 44,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32818,
|
opcode: 32818,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -35,6 +37,7 @@ expression: diff.instruction_rows
|
|||||||
address: 48,
|
address: 48,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32818,
|
opcode: 32818,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -48,6 +51,7 @@ expression: diff.instruction_rows
|
|||||||
address: 52,
|
address: 52,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32774,
|
opcode: 32774,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -61,6 +65,7 @@ expression: diff.instruction_rows
|
|||||||
address: 56,
|
address: 56,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32799,
|
opcode: 32799,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -74,6 +79,7 @@ expression: diff.instruction_rows
|
|||||||
address: 60,
|
address: 60,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32786,
|
opcode: 32786,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -87,6 +93,7 @@ expression: diff.instruction_rows
|
|||||||
address: 64,
|
address: 64,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32770,
|
opcode: 32770,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -100,6 +107,9 @@ expression: diff.instruction_rows
|
|||||||
address: 68,
|
address: 68,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32773,
|
opcode: 32773,
|
||||||
|
branch_dest: Some(
|
||||||
|
240,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -118,6 +128,9 @@ expression: diff.instruction_rows
|
|||||||
address: 72,
|
address: 72,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32773,
|
opcode: 32773,
|
||||||
|
branch_dest: Some(
|
||||||
|
240,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -136,6 +149,9 @@ expression: diff.instruction_rows
|
|||||||
address: 76,
|
address: 76,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32773,
|
opcode: 32773,
|
||||||
|
branch_dest: Some(
|
||||||
|
240,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -154,6 +170,9 @@ expression: diff.instruction_rows
|
|||||||
address: 80,
|
address: 80,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32773,
|
opcode: 32773,
|
||||||
|
branch_dest: Some(
|
||||||
|
240,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -172,6 +191,9 @@ expression: diff.instruction_rows
|
|||||||
address: 84,
|
address: 84,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32773,
|
opcode: 32773,
|
||||||
|
branch_dest: Some(
|
||||||
|
232,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -190,6 +212,9 @@ expression: diff.instruction_rows
|
|||||||
address: 88,
|
address: 88,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32773,
|
opcode: 32773,
|
||||||
|
branch_dest: Some(
|
||||||
|
164,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -208,6 +233,9 @@ expression: diff.instruction_rows
|
|||||||
address: 92,
|
address: 92,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32773,
|
opcode: 32773,
|
||||||
|
branch_dest: Some(
|
||||||
|
240,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -226,6 +254,9 @@ expression: diff.instruction_rows
|
|||||||
address: 96,
|
address: 96,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32773,
|
opcode: 32773,
|
||||||
|
branch_dest: Some(
|
||||||
|
180,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -244,6 +275,9 @@ expression: diff.instruction_rows
|
|||||||
address: 100,
|
address: 100,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32773,
|
opcode: 32773,
|
||||||
|
branch_dest: Some(
|
||||||
|
116,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -262,6 +296,9 @@ expression: diff.instruction_rows
|
|||||||
address: 104,
|
address: 104,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32773,
|
opcode: 32773,
|
||||||
|
branch_dest: Some(
|
||||||
|
192,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -280,6 +317,9 @@ expression: diff.instruction_rows
|
|||||||
address: 108,
|
address: 108,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32773,
|
opcode: 32773,
|
||||||
|
branch_dest: Some(
|
||||||
|
204,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -298,6 +338,9 @@ expression: diff.instruction_rows
|
|||||||
address: 112,
|
address: 112,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32773,
|
opcode: 32773,
|
||||||
|
branch_dest: Some(
|
||||||
|
204,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -316,6 +359,7 @@ expression: diff.instruction_rows
|
|||||||
address: 116,
|
address: 116,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32799,
|
opcode: 32799,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -336,6 +380,7 @@ expression: diff.instruction_rows
|
|||||||
address: 120,
|
address: 120,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32799,
|
opcode: 32799,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -349,6 +394,7 @@ expression: diff.instruction_rows
|
|||||||
address: 124,
|
address: 124,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32774,
|
opcode: 32774,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -362,6 +408,7 @@ expression: diff.instruction_rows
|
|||||||
address: 128,
|
address: 128,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32800,
|
opcode: 32800,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -375,6 +422,7 @@ expression: diff.instruction_rows
|
|||||||
address: 132,
|
address: 132,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32786,
|
opcode: 32786,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -388,6 +436,9 @@ expression: diff.instruction_rows
|
|||||||
address: 136,
|
address: 136,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32773,
|
opcode: 32773,
|
||||||
|
branch_dest: Some(
|
||||||
|
148,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -406,6 +457,9 @@ expression: diff.instruction_rows
|
|||||||
address: 140,
|
address: 140,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32774,
|
opcode: 32774,
|
||||||
|
branch_dest: Some(
|
||||||
|
464,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -424,6 +478,7 @@ expression: diff.instruction_rows
|
|||||||
address: 144,
|
address: 144,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32774,
|
opcode: 32774,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -437,6 +492,7 @@ expression: diff.instruction_rows
|
|||||||
address: 148,
|
address: 148,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32799,
|
opcode: 32799,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -457,6 +513,7 @@ expression: diff.instruction_rows
|
|||||||
address: 152,
|
address: 152,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32799,
|
opcode: 32799,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -470,6 +527,7 @@ expression: diff.instruction_rows
|
|||||||
address: 156,
|
address: 156,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32777,
|
opcode: 32777,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -483,6 +541,9 @@ expression: diff.instruction_rows
|
|||||||
address: 160,
|
address: 160,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32773,
|
opcode: 32773,
|
||||||
|
branch_dest: Some(
|
||||||
|
240,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -501,6 +562,7 @@ expression: diff.instruction_rows
|
|||||||
address: 164,
|
address: 164,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32818,
|
opcode: 32818,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -521,6 +583,7 @@ expression: diff.instruction_rows
|
|||||||
address: 168,
|
address: 168,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32818,
|
opcode: 32818,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -534,6 +597,7 @@ expression: diff.instruction_rows
|
|||||||
address: 172,
|
address: 172,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32774,
|
opcode: 32774,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -547,6 +611,9 @@ expression: diff.instruction_rows
|
|||||||
address: 176,
|
address: 176,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32773,
|
opcode: 32773,
|
||||||
|
branch_dest: Some(
|
||||||
|
240,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -565,6 +632,7 @@ expression: diff.instruction_rows
|
|||||||
address: 180,
|
address: 180,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32818,
|
opcode: 32818,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -585,6 +653,7 @@ expression: diff.instruction_rows
|
|||||||
address: 184,
|
address: 184,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32774,
|
opcode: 32774,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -598,6 +667,9 @@ expression: diff.instruction_rows
|
|||||||
address: 188,
|
address: 188,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32773,
|
opcode: 32773,
|
||||||
|
branch_dest: Some(
|
||||||
|
240,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -616,6 +688,7 @@ expression: diff.instruction_rows
|
|||||||
address: 192,
|
address: 192,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32818,
|
opcode: 32818,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -636,6 +709,7 @@ expression: diff.instruction_rows
|
|||||||
address: 196,
|
address: 196,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32774,
|
opcode: 32774,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -649,6 +723,9 @@ expression: diff.instruction_rows
|
|||||||
address: 200,
|
address: 200,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32773,
|
opcode: 32773,
|
||||||
|
branch_dest: Some(
|
||||||
|
240,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -667,6 +744,7 @@ expression: diff.instruction_rows
|
|||||||
address: 204,
|
address: 204,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32799,
|
opcode: 32799,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -688,6 +766,7 @@ expression: diff.instruction_rows
|
|||||||
address: 208,
|
address: 208,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32818,
|
opcode: 32818,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -701,6 +780,7 @@ expression: diff.instruction_rows
|
|||||||
address: 212,
|
address: 212,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32799,
|
opcode: 32799,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -714,6 +794,7 @@ expression: diff.instruction_rows
|
|||||||
address: 216,
|
address: 216,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32818,
|
opcode: 32818,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -727,6 +808,7 @@ expression: diff.instruction_rows
|
|||||||
address: 220,
|
address: 220,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32899,
|
opcode: 32899,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -740,6 +822,7 @@ expression: diff.instruction_rows
|
|||||||
address: 224,
|
address: 224,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32774,
|
opcode: 32774,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -753,6 +836,9 @@ expression: diff.instruction_rows
|
|||||||
address: 228,
|
address: 228,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32773,
|
opcode: 32773,
|
||||||
|
branch_dest: Some(
|
||||||
|
240,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -771,6 +857,7 @@ expression: diff.instruction_rows
|
|||||||
address: 232,
|
address: 232,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32818,
|
opcode: 32818,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -791,6 +878,7 @@ expression: diff.instruction_rows
|
|||||||
address: 236,
|
address: 236,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32774,
|
opcode: 32774,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -804,6 +892,7 @@ expression: diff.instruction_rows
|
|||||||
address: 240,
|
address: 240,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32799,
|
opcode: 32799,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -833,6 +922,7 @@ expression: diff.instruction_rows
|
|||||||
address: 244,
|
address: 244,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32829,
|
opcode: 32829,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -846,6 +936,7 @@ expression: diff.instruction_rows
|
|||||||
address: 248,
|
address: 248,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32786,
|
opcode: 32786,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -859,6 +950,9 @@ expression: diff.instruction_rows
|
|||||||
address: 252,
|
address: 252,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32773,
|
opcode: 32773,
|
||||||
|
branch_dest: Some(
|
||||||
|
276,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -877,6 +971,7 @@ expression: diff.instruction_rows
|
|||||||
address: 256,
|
address: 256,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32818,
|
opcode: 32818,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -890,6 +985,7 @@ expression: diff.instruction_rows
|
|||||||
address: 260,
|
address: 260,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32774,
|
opcode: 32774,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -903,6 +999,7 @@ expression: diff.instruction_rows
|
|||||||
address: 264,
|
address: 264,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32799,
|
opcode: 32799,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -916,6 +1013,7 @@ expression: diff.instruction_rows
|
|||||||
address: 268,
|
address: 268,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32799,
|
opcode: 32799,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -929,6 +1027,7 @@ expression: diff.instruction_rows
|
|||||||
address: 272,
|
address: 272,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32778,
|
opcode: 32778,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -942,6 +1041,7 @@ expression: diff.instruction_rows
|
|||||||
address: 276,
|
address: 276,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32799,
|
opcode: 32799,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -962,6 +1062,7 @@ expression: diff.instruction_rows
|
|||||||
address: 280,
|
address: 280,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32786,
|
opcode: 32786,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -975,6 +1076,9 @@ expression: diff.instruction_rows
|
|||||||
address: 284,
|
address: 284,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32773,
|
opcode: 32773,
|
||||||
|
branch_dest: Some(
|
||||||
|
328,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -993,6 +1097,9 @@ expression: diff.instruction_rows
|
|||||||
address: 288,
|
address: 288,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32773,
|
opcode: 32773,
|
||||||
|
branch_dest: Some(
|
||||||
|
336,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -1011,6 +1118,7 @@ expression: diff.instruction_rows
|
|||||||
address: 292,
|
address: 292,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32786,
|
opcode: 32786,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -1024,6 +1132,9 @@ expression: diff.instruction_rows
|
|||||||
address: 296,
|
address: 296,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32773,
|
opcode: 32773,
|
||||||
|
branch_dest: Some(
|
||||||
|
348,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -1042,6 +1153,7 @@ expression: diff.instruction_rows
|
|||||||
address: 300,
|
address: 300,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32829,
|
opcode: 32829,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -1055,6 +1167,7 @@ expression: diff.instruction_rows
|
|||||||
address: 304,
|
address: 304,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32786,
|
opcode: 32786,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -1068,6 +1181,9 @@ expression: diff.instruction_rows
|
|||||||
address: 308,
|
address: 308,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32773,
|
opcode: 32773,
|
||||||
|
branch_dest: Some(
|
||||||
|
348,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -1086,6 +1202,7 @@ expression: diff.instruction_rows
|
|||||||
address: 312,
|
address: 312,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32786,
|
opcode: 32786,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -1099,6 +1216,7 @@ expression: diff.instruction_rows
|
|||||||
address: 316,
|
address: 316,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32786,
|
opcode: 32786,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -1112,6 +1230,9 @@ expression: diff.instruction_rows
|
|||||||
address: 320,
|
address: 320,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32773,
|
opcode: 32773,
|
||||||
|
branch_dest: Some(
|
||||||
|
380,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -1130,6 +1251,9 @@ expression: diff.instruction_rows
|
|||||||
address: 324,
|
address: 324,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32773,
|
opcode: 32773,
|
||||||
|
branch_dest: Some(
|
||||||
|
348,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -1148,6 +1272,7 @@ expression: diff.instruction_rows
|
|||||||
address: 328,
|
address: 328,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32786,
|
opcode: 32786,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -1168,6 +1293,9 @@ expression: diff.instruction_rows
|
|||||||
address: 332,
|
address: 332,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32773,
|
opcode: 32773,
|
||||||
|
branch_dest: Some(
|
||||||
|
348,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -1186,6 +1314,7 @@ expression: diff.instruction_rows
|
|||||||
address: 336,
|
address: 336,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32818,
|
opcode: 32818,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -1206,6 +1335,7 @@ expression: diff.instruction_rows
|
|||||||
address: 340,
|
address: 340,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32774,
|
opcode: 32774,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -1219,6 +1349,9 @@ expression: diff.instruction_rows
|
|||||||
address: 344,
|
address: 344,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32773,
|
opcode: 32773,
|
||||||
|
branch_dest: Some(
|
||||||
|
380,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -1237,6 +1370,7 @@ expression: diff.instruction_rows
|
|||||||
address: 348,
|
address: 348,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32818,
|
opcode: 32818,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -1260,6 +1394,7 @@ expression: diff.instruction_rows
|
|||||||
address: 352,
|
address: 352,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32774,
|
opcode: 32774,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -1273,6 +1408,7 @@ expression: diff.instruction_rows
|
|||||||
address: 356,
|
address: 356,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32786,
|
opcode: 32786,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -1286,6 +1422,7 @@ expression: diff.instruction_rows
|
|||||||
address: 360,
|
address: 360,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32786,
|
opcode: 32786,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -1299,6 +1436,9 @@ expression: diff.instruction_rows
|
|||||||
address: 364,
|
address: 364,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32773,
|
opcode: 32773,
|
||||||
|
branch_dest: Some(
|
||||||
|
380,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -1317,6 +1457,7 @@ expression: diff.instruction_rows
|
|||||||
address: 368,
|
address: 368,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32774,
|
opcode: 32774,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -1330,6 +1471,7 @@ expression: diff.instruction_rows
|
|||||||
address: 372,
|
address: 372,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32818,
|
opcode: 32818,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -1343,6 +1485,7 @@ expression: diff.instruction_rows
|
|||||||
address: 376,
|
address: 376,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32899,
|
opcode: 32899,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -1356,6 +1499,7 @@ expression: diff.instruction_rows
|
|||||||
address: 380,
|
address: 380,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32829,
|
opcode: 32829,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -1378,6 +1522,7 @@ expression: diff.instruction_rows
|
|||||||
address: 384,
|
address: 384,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32770,
|
opcode: 32770,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -1391,6 +1536,7 @@ expression: diff.instruction_rows
|
|||||||
address: 388,
|
address: 388,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32770,
|
opcode: 32770,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -1404,6 +1550,7 @@ expression: diff.instruction_rows
|
|||||||
address: 392,
|
address: 392,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32898,
|
opcode: 32898,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -1417,6 +1564,7 @@ expression: diff.instruction_rows
|
|||||||
address: 396,
|
address: 396,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32786,
|
opcode: 32786,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -1430,6 +1578,9 @@ expression: diff.instruction_rows
|
|||||||
address: 400,
|
address: 400,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32773,
|
opcode: 32773,
|
||||||
|
branch_dest: Some(
|
||||||
|
424,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -1448,6 +1599,7 @@ expression: diff.instruction_rows
|
|||||||
address: 404,
|
address: 404,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32818,
|
opcode: 32818,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -1468,6 +1620,7 @@ expression: diff.instruction_rows
|
|||||||
address: 408,
|
address: 408,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32774,
|
opcode: 32774,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -1481,6 +1634,7 @@ expression: diff.instruction_rows
|
|||||||
address: 412,
|
address: 412,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32770,
|
opcode: 32770,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -1494,6 +1648,7 @@ expression: diff.instruction_rows
|
|||||||
address: 416,
|
address: 416,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32786,
|
opcode: 32786,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -1507,6 +1662,9 @@ expression: diff.instruction_rows
|
|||||||
address: 420,
|
address: 420,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32773,
|
opcode: 32773,
|
||||||
|
branch_dest: Some(
|
||||||
|
404,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -1525,6 +1683,7 @@ expression: diff.instruction_rows
|
|||||||
address: 424,
|
address: 424,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32799,
|
opcode: 32799,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -1545,6 +1704,7 @@ expression: diff.instruction_rows
|
|||||||
address: 428,
|
address: 428,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32799,
|
opcode: 32799,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -1558,6 +1718,7 @@ expression: diff.instruction_rows
|
|||||||
address: 432,
|
address: 432,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32800,
|
opcode: 32800,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -1571,6 +1732,7 @@ expression: diff.instruction_rows
|
|||||||
address: 436,
|
address: 436,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32786,
|
opcode: 32786,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -1584,6 +1746,9 @@ expression: diff.instruction_rows
|
|||||||
address: 440,
|
address: 440,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32773,
|
opcode: 32773,
|
||||||
|
branch_dest: Some(
|
||||||
|
448,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -1602,6 +1767,7 @@ expression: diff.instruction_rows
|
|||||||
address: 444,
|
address: 444,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32774,
|
opcode: 32774,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -1615,6 +1781,7 @@ expression: diff.instruction_rows
|
|||||||
address: 448,
|
address: 448,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32818,
|
opcode: 32818,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -1635,6 +1802,7 @@ expression: diff.instruction_rows
|
|||||||
address: 452,
|
address: 452,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32899,
|
opcode: 32899,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -1648,6 +1816,7 @@ expression: diff.instruction_rows
|
|||||||
address: 456,
|
address: 456,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 32793,
|
opcode: 32793,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -1661,6 +1830,7 @@ expression: diff.instruction_rows
|
|||||||
address: 460,
|
address: 460,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 65535,
|
opcode: 65535,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -1674,6 +1844,7 @@ expression: diff.instruction_rows
|
|||||||
address: 464,
|
address: 464,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 65535,
|
opcode: 65535,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -1694,6 +1865,7 @@ expression: diff.instruction_rows
|
|||||||
address: 468,
|
address: 468,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 65535,
|
opcode: 65535,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
---
|
---
|
||||||
source: objdiff-core/tests/arch_arm.rs
|
source: objdiff-core/tests/arch_arm.rs
|
||||||
assertion_line: 16
|
|
||||||
expression: output
|
expression: output
|
||||||
---
|
---
|
||||||
[(Address(0), Normal, 5), (Spacing(4), Normal, 0), (Opcode("stmdb", 32895), Normal, 10), (Argument(Opaque("sp")), Normal, 0), (Argument(Opaque("!")), Normal, 0), (Basic(", "), Normal, 0), (Basic("{"), Normal, 0), (Argument(Opaque("r4")), Normal, 0), (Basic(", "), Normal, 0), (Argument(Opaque("r5")), Normal, 0), (Basic(", "), Normal, 0), (Argument(Opaque("r6")), Normal, 0), (Basic(", "), Normal, 0), (Argument(Opaque("lr")), Normal, 0), (Basic("}"), Normal, 0), (Eol, Normal, 0)]
|
[(Address(0), Normal, 5), (Spacing(4), Normal, 0), (Opcode("stmdb", 32895), Normal, 10), (Argument(Opaque("sp")), Normal, 0), (Argument(Opaque("!")), Normal, 0), (Basic(", "), Normal, 0), (Basic("{"), Normal, 0), (Argument(Opaque("r4")), Normal, 0), (Basic(", "), Normal, 0), (Argument(Opaque("r5")), Normal, 0), (Basic(", "), Normal, 0), (Argument(Opaque("r6")), Normal, 0), (Basic(", "), Normal, 0), (Argument(Opaque("lr")), Normal, 0), (Basic("}"), Normal, 0), (Eol, Normal, 0)]
|
||||||
@@ -28,7 +27,7 @@ expression: output
|
|||||||
[(Address(88), Normal, 5), (Spacing(4), Normal, 0), (Opcode("ldrb", 32800), Normal, 10), (Argument(Opaque("r0")), Normal, 0), (Basic(", "), Normal, 0), (Basic("["), Normal, 0), (Argument(Opaque("r0")), Normal, 0), (Basic(", "), Normal, 0), (Basic("#"), Normal, 0), (Argument(Signed(224)), Normal, 0), (Basic("]"), Normal, 0), (Eol, Normal, 0)]
|
[(Address(88), Normal, 5), (Spacing(4), Normal, 0), (Opcode("ldrb", 32800), Normal, 10), (Argument(Opaque("r0")), Normal, 0), (Basic(", "), Normal, 0), (Basic("["), Normal, 0), (Argument(Opaque("r0")), Normal, 0), (Basic(", "), Normal, 0), (Basic("#"), Normal, 0), (Argument(Signed(224)), Normal, 0), (Basic("]"), Normal, 0), (Eol, Normal, 0)]
|
||||||
[(Address(92), Normal, 5), (Spacing(4), Normal, 0), (Opcode("cmp", 32786), Normal, 10), (Argument(Opaque("r0")), Normal, 0), (Basic(", "), Normal, 0), (Basic("#"), Normal, 0), (Argument(Unsigned(0)), Normal, 0), (Eol, Normal, 0)]
|
[(Address(92), Normal, 5), (Spacing(4), Normal, 0), (Opcode("cmp", 32786), Normal, 10), (Argument(Opaque("r0")), Normal, 0), (Basic(", "), Normal, 0), (Basic("#"), Normal, 0), (Argument(Unsigned(0)), Normal, 0), (Eol, Normal, 0)]
|
||||||
[(Address(96), Normal, 5), (Spacing(4), Normal, 0), (Opcode("bne", 32773), Normal, 10), (BranchDest(108), Normal, 0), (Basic(" ~>"), Rotating(7), 0), (Eol, Normal, 0)]
|
[(Address(96), Normal, 5), (Spacing(4), Normal, 0), (Opcode("bne", 32773), Normal, 10), (BranchDest(108), Normal, 0), (Basic(" ~>"), Rotating(7), 0), (Eol, Normal, 0)]
|
||||||
[(Address(100), Normal, 5), (Spacing(4), Normal, 0), (Opcode("bl", 32774), Normal, 10), (Symbol(Symbol { name: "_ZN13LinkStateItem15GetEquipBombchuEv", demangled_name: Some("LinkStateItem::GetEquipBombchu()"), address: 472, size: 16, kind: Function, section: Some(0), flags: FlagSet(Global), align: None, virtual_address: None }), Bright, 0), (Addend(-8), Bright, 0), (Basic(" ~>"), Rotating(8), 0), (Eol, Normal, 0)]
|
[(Address(100), Normal, 5), (Spacing(4), Normal, 0), (Opcode("bl", 32774), Normal, 10), (BranchDest(424), Normal, 0), (Basic(" ~>"), Rotating(8), 0), (Eol, Normal, 0)]
|
||||||
[(Address(104), Normal, 5), (Spacing(4), Normal, 0), (Opcode("bl", 32774), Normal, 10), (Symbol(Symbol { name: "_ZN12EquipBombchu19func_ov014_0213ec64Ev", demangled_name: Some("EquipBombchu::func_ov014_0213ec64()"), address: 0, size: 0, kind: Unknown, section: None, flags: FlagSet(Global | Weak), align: None, virtual_address: None }), Bright, 0), (Addend(-8), Bright, 0), (Eol, Normal, 0)]
|
[(Address(104), Normal, 5), (Spacing(4), Normal, 0), (Opcode("bl", 32774), Normal, 10), (Symbol(Symbol { name: "_ZN12EquipBombchu19func_ov014_0213ec64Ev", demangled_name: Some("EquipBombchu::func_ov014_0213ec64()"), address: 0, size: 0, kind: Unknown, section: None, flags: FlagSet(Global | Weak), align: None, virtual_address: None }), Bright, 0), (Addend(-8), Bright, 0), (Eol, Normal, 0)]
|
||||||
[(Address(108), Normal, 5), (Basic(" ~> "), Rotating(7), 0), (Opcode("ldr", 32799), Normal, 10), (Argument(Opaque("r0")), Normal, 0), (Basic(", "), Normal, 0), (Basic("["), Normal, 0), (Argument(Opaque("pc")), Normal, 0), (Basic(", "), Normal, 0), (Basic("#"), Normal, 0), (Argument(Signed(308)), Normal, 0), (Basic("]"), Normal, 0), (Basic(" (->"), Normal, 0), (BranchDest(424), Normal, 0), (Basic(")"), Normal, 0), (Eol, Normal, 0)]
|
[(Address(108), Normal, 5), (Basic(" ~> "), Rotating(7), 0), (Opcode("ldr", 32799), Normal, 10), (Argument(Opaque("r0")), Normal, 0), (Basic(", "), Normal, 0), (Basic("["), Normal, 0), (Argument(Opaque("pc")), Normal, 0), (Basic(", "), Normal, 0), (Basic("#"), Normal, 0), (Argument(Signed(308)), Normal, 0), (Basic("]"), Normal, 0), (Basic(" (->"), Normal, 0), (BranchDest(424), Normal, 0), (Basic(")"), Normal, 0), (Eol, Normal, 0)]
|
||||||
[(Address(112), Normal, 5), (Spacing(4), Normal, 0), (Opcode("ldr", 32799), Normal, 10), (Argument(Opaque("r0")), Normal, 0), (Basic(", "), Normal, 0), (Basic("["), Normal, 0), (Argument(Opaque("r0")), Normal, 0), (Basic(", "), Normal, 0), (Basic("#"), Normal, 0), (Argument(Signed(0)), Normal, 0), (Basic("]"), Normal, 0), (Eol, Normal, 0)]
|
[(Address(112), Normal, 5), (Spacing(4), Normal, 0), (Opcode("ldr", 32799), Normal, 10), (Argument(Opaque("r0")), Normal, 0), (Basic(", "), Normal, 0), (Basic("["), Normal, 0), (Argument(Opaque("r0")), Normal, 0), (Basic(", "), Normal, 0), (Basic("#"), Normal, 0), (Argument(Signed(0)), Normal, 0), (Basic("]"), Normal, 0), (Eol, Normal, 0)]
|
||||||
|
|||||||
@@ -1954,4 +1954,5 @@ Object {
|
|||||||
split_meta: None,
|
split_meta: None,
|
||||||
path: None,
|
path: None,
|
||||||
timestamp: None,
|
timestamp: None,
|
||||||
|
flow_analysis_results: {},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ expression: diff.instruction_rows
|
|||||||
address: 0,
|
address: 0,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 56,
|
opcode: 56,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -22,6 +23,7 @@ expression: diff.instruction_rows
|
|||||||
address: 2,
|
address: 2,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 74,
|
opcode: 74,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -35,6 +37,7 @@ expression: diff.instruction_rows
|
|||||||
address: 4,
|
address: 4,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 47,
|
opcode: 47,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -48,6 +51,7 @@ expression: diff.instruction_rows
|
|||||||
address: 6,
|
address: 6,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 47,
|
opcode: 47,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -61,6 +65,7 @@ expression: diff.instruction_rows
|
|||||||
address: 8,
|
address: 8,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 47,
|
opcode: 47,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -74,6 +79,7 @@ expression: diff.instruction_rows
|
|||||||
address: 10,
|
address: 10,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 47,
|
opcode: 47,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -87,6 +93,7 @@ expression: diff.instruction_rows
|
|||||||
address: 12,
|
address: 12,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 66,
|
opcode: 66,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -100,6 +107,7 @@ expression: diff.instruction_rows
|
|||||||
address: 14,
|
address: 14,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 19,
|
opcode: 19,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -113,6 +121,7 @@ expression: diff.instruction_rows
|
|||||||
address: 18,
|
address: 18,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 25,
|
opcode: 25,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -126,6 +135,9 @@ expression: diff.instruction_rows
|
|||||||
address: 20,
|
address: 20,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 15,
|
opcode: 15,
|
||||||
|
branch_dest: Some(
|
||||||
|
212,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -144,6 +156,7 @@ expression: diff.instruction_rows
|
|||||||
address: 22,
|
address: 22,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 38,
|
opcode: 38,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -157,6 +170,7 @@ expression: diff.instruction_rows
|
|||||||
address: 24,
|
address: 24,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 25,
|
opcode: 25,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -170,6 +184,9 @@ expression: diff.instruction_rows
|
|||||||
address: 26,
|
address: 26,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 15,
|
opcode: 15,
|
||||||
|
branch_dest: Some(
|
||||||
|
48,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -188,6 +205,7 @@ expression: diff.instruction_rows
|
|||||||
address: 28,
|
address: 28,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 34,
|
opcode: 34,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -201,6 +219,7 @@ expression: diff.instruction_rows
|
|||||||
address: 30,
|
address: 30,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 26,
|
opcode: 26,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -214,6 +233,9 @@ expression: diff.instruction_rows
|
|||||||
address: 32,
|
address: 32,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 15,
|
opcode: 15,
|
||||||
|
branch_dest: Some(
|
||||||
|
94,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -232,6 +254,7 @@ expression: diff.instruction_rows
|
|||||||
address: 34,
|
address: 34,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 35,
|
opcode: 35,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -245,6 +268,7 @@ expression: diff.instruction_rows
|
|||||||
address: 36,
|
address: 36,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 47,
|
opcode: 47,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -258,6 +282,7 @@ expression: diff.instruction_rows
|
|||||||
address: 38,
|
address: 38,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 47,
|
opcode: 47,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -271,6 +296,7 @@ expression: diff.instruction_rows
|
|||||||
address: 40,
|
address: 40,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 19,
|
opcode: 19,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -284,6 +310,7 @@ expression: diff.instruction_rows
|
|||||||
address: 44,
|
address: 44,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 7,
|
opcode: 7,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -297,6 +324,7 @@ expression: diff.instruction_rows
|
|||||||
address: 46,
|
address: 46,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 55,
|
opcode: 55,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -310,6 +338,7 @@ expression: diff.instruction_rows
|
|||||||
address: 48,
|
address: 48,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 47,
|
opcode: 47,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -330,6 +359,7 @@ expression: diff.instruction_rows
|
|||||||
address: 50,
|
address: 50,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 47,
|
opcode: 47,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -343,6 +373,7 @@ expression: diff.instruction_rows
|
|||||||
address: 52,
|
address: 52,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 19,
|
opcode: 19,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -356,6 +387,7 @@ expression: diff.instruction_rows
|
|||||||
address: 56,
|
address: 56,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 25,
|
opcode: 25,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -369,6 +401,9 @@ expression: diff.instruction_rows
|
|||||||
address: 58,
|
address: 58,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 15,
|
opcode: 15,
|
||||||
|
branch_dest: Some(
|
||||||
|
212,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -387,6 +422,7 @@ expression: diff.instruction_rows
|
|||||||
address: 60,
|
address: 60,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 34,
|
opcode: 34,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -400,6 +436,7 @@ expression: diff.instruction_rows
|
|||||||
address: 62,
|
address: 62,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 33,
|
opcode: 33,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -413,6 +450,7 @@ expression: diff.instruction_rows
|
|||||||
address: 64,
|
address: 64,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 36,
|
opcode: 36,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -426,6 +464,7 @@ expression: diff.instruction_rows
|
|||||||
address: 66,
|
address: 66,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 42,
|
opcode: 42,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -439,6 +478,7 @@ expression: diff.instruction_rows
|
|||||||
address: 68,
|
address: 68,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 44,
|
opcode: 44,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -452,6 +492,9 @@ expression: diff.instruction_rows
|
|||||||
address: 70,
|
address: 70,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 15,
|
opcode: 15,
|
||||||
|
branch_dest: Some(
|
||||||
|
212,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -470,6 +513,7 @@ expression: diff.instruction_rows
|
|||||||
address: 72,
|
address: 72,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 46,
|
opcode: 46,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -483,6 +527,7 @@ expression: diff.instruction_rows
|
|||||||
address: 74,
|
address: 74,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 17,
|
opcode: 17,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -496,6 +541,7 @@ expression: diff.instruction_rows
|
|||||||
address: 76,
|
address: 76,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 46,
|
opcode: 46,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -509,6 +555,7 @@ expression: diff.instruction_rows
|
|||||||
address: 78,
|
address: 78,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 54,
|
opcode: 54,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -522,6 +569,7 @@ expression: diff.instruction_rows
|
|||||||
address: 80,
|
address: 80,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 67,
|
opcode: 67,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -535,6 +583,7 @@ expression: diff.instruction_rows
|
|||||||
address: 82,
|
address: 82,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 36,
|
opcode: 36,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -548,6 +597,7 @@ expression: diff.instruction_rows
|
|||||||
address: 84,
|
address: 84,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 46,
|
opcode: 46,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -561,6 +611,7 @@ expression: diff.instruction_rows
|
|||||||
address: 86,
|
address: 86,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 7,
|
opcode: 7,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -574,6 +625,7 @@ expression: diff.instruction_rows
|
|||||||
address: 88,
|
address: 88,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 54,
|
opcode: 54,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -587,6 +639,7 @@ expression: diff.instruction_rows
|
|||||||
address: 90,
|
address: 90,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 67,
|
opcode: 67,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -600,6 +653,7 @@ expression: diff.instruction_rows
|
|||||||
address: 92,
|
address: 92,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 55,
|
opcode: 55,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -613,6 +667,7 @@ expression: diff.instruction_rows
|
|||||||
address: 94,
|
address: 94,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 34,
|
opcode: 34,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -633,6 +688,7 @@ expression: diff.instruction_rows
|
|||||||
address: 96,
|
address: 96,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 34,
|
opcode: 34,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -646,6 +702,7 @@ expression: diff.instruction_rows
|
|||||||
address: 98,
|
address: 98,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 4,
|
opcode: 4,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -659,6 +716,7 @@ expression: diff.instruction_rows
|
|||||||
address: 100,
|
address: 100,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 19,
|
opcode: 19,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -672,6 +730,7 @@ expression: diff.instruction_rows
|
|||||||
address: 104,
|
address: 104,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 66,
|
opcode: 66,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -685,6 +744,7 @@ expression: diff.instruction_rows
|
|||||||
address: 106,
|
address: 106,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 47,
|
opcode: 47,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -698,6 +758,7 @@ expression: diff.instruction_rows
|
|||||||
address: 108,
|
address: 108,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 19,
|
opcode: 19,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -711,6 +772,7 @@ expression: diff.instruction_rows
|
|||||||
address: 112,
|
address: 112,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 47,
|
opcode: 47,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -724,6 +786,7 @@ expression: diff.instruction_rows
|
|||||||
address: 114,
|
address: 114,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 6,
|
opcode: 6,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -737,6 +800,7 @@ expression: diff.instruction_rows
|
|||||||
address: 116,
|
address: 116,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 66,
|
opcode: 66,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -750,6 +814,7 @@ expression: diff.instruction_rows
|
|||||||
address: 118,
|
address: 118,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 35,
|
opcode: 35,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -763,6 +828,7 @@ expression: diff.instruction_rows
|
|||||||
address: 120,
|
address: 120,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 47,
|
opcode: 47,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -776,6 +842,7 @@ expression: diff.instruction_rows
|
|||||||
address: 122,
|
address: 122,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 47,
|
opcode: 47,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -789,6 +856,7 @@ expression: diff.instruction_rows
|
|||||||
address: 124,
|
address: 124,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 47,
|
opcode: 47,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -802,6 +870,7 @@ expression: diff.instruction_rows
|
|||||||
address: 126,
|
address: 126,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 19,
|
opcode: 19,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -815,6 +884,7 @@ expression: diff.instruction_rows
|
|||||||
address: 130,
|
address: 130,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 25,
|
opcode: 25,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -828,6 +898,9 @@ expression: diff.instruction_rows
|
|||||||
address: 132,
|
address: 132,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 15,
|
opcode: 15,
|
||||||
|
branch_dest: Some(
|
||||||
|
168,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -846,6 +919,7 @@ expression: diff.instruction_rows
|
|||||||
address: 134,
|
address: 134,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 47,
|
opcode: 47,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -859,6 +933,7 @@ expression: diff.instruction_rows
|
|||||||
address: 136,
|
address: 136,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 19,
|
opcode: 19,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -872,6 +947,7 @@ expression: diff.instruction_rows
|
|||||||
address: 140,
|
address: 140,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 47,
|
opcode: 47,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -885,6 +961,7 @@ expression: diff.instruction_rows
|
|||||||
address: 142,
|
address: 142,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 25,
|
opcode: 25,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -898,6 +975,9 @@ expression: diff.instruction_rows
|
|||||||
address: 144,
|
address: 144,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 15,
|
opcode: 15,
|
||||||
|
branch_dest: Some(
|
||||||
|
168,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -916,6 +996,7 @@ expression: diff.instruction_rows
|
|||||||
address: 146,
|
address: 146,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 34,
|
opcode: 34,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -929,6 +1010,7 @@ expression: diff.instruction_rows
|
|||||||
address: 148,
|
address: 148,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 33,
|
opcode: 33,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -942,6 +1024,7 @@ expression: diff.instruction_rows
|
|||||||
address: 150,
|
address: 150,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 36,
|
opcode: 36,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -955,6 +1038,7 @@ expression: diff.instruction_rows
|
|||||||
address: 152,
|
address: 152,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 42,
|
opcode: 42,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -968,6 +1052,7 @@ expression: diff.instruction_rows
|
|||||||
address: 154,
|
address: 154,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 44,
|
opcode: 44,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -981,6 +1066,9 @@ expression: diff.instruction_rows
|
|||||||
address: 156,
|
address: 156,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 15,
|
opcode: 15,
|
||||||
|
branch_dest: Some(
|
||||||
|
168,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -999,6 +1087,7 @@ expression: diff.instruction_rows
|
|||||||
address: 158,
|
address: 158,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 46,
|
opcode: 46,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -1012,6 +1101,7 @@ expression: diff.instruction_rows
|
|||||||
address: 160,
|
address: 160,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 17,
|
opcode: 17,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -1025,6 +1115,7 @@ expression: diff.instruction_rows
|
|||||||
address: 162,
|
address: 162,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 46,
|
opcode: 46,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -1038,6 +1129,7 @@ expression: diff.instruction_rows
|
|||||||
address: 164,
|
address: 164,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 54,
|
opcode: 54,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -1051,6 +1143,7 @@ expression: diff.instruction_rows
|
|||||||
address: 166,
|
address: 166,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 67,
|
opcode: 67,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -1064,6 +1157,7 @@ expression: diff.instruction_rows
|
|||||||
address: 168,
|
address: 168,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 25,
|
opcode: 25,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -1086,6 +1180,9 @@ expression: diff.instruction_rows
|
|||||||
address: 170,
|
address: 170,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 15,
|
opcode: 15,
|
||||||
|
branch_dest: Some(
|
||||||
|
200,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -1104,6 +1201,7 @@ expression: diff.instruction_rows
|
|||||||
address: 172,
|
address: 172,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 35,
|
opcode: 35,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -1117,6 +1215,7 @@ expression: diff.instruction_rows
|
|||||||
address: 174,
|
address: 174,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 25,
|
opcode: 25,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -1130,6 +1229,9 @@ expression: diff.instruction_rows
|
|||||||
address: 176,
|
address: 176,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 15,
|
opcode: 15,
|
||||||
|
branch_dest: Some(
|
||||||
|
200,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -1148,6 +1250,7 @@ expression: diff.instruction_rows
|
|||||||
address: 178,
|
address: 178,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 34,
|
opcode: 34,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -1161,6 +1264,7 @@ expression: diff.instruction_rows
|
|||||||
address: 180,
|
address: 180,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 37,
|
opcode: 37,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -1174,6 +1278,7 @@ expression: diff.instruction_rows
|
|||||||
address: 182,
|
address: 182,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 42,
|
opcode: 42,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -1187,6 +1292,7 @@ expression: diff.instruction_rows
|
|||||||
address: 184,
|
address: 184,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 44,
|
opcode: 44,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -1200,6 +1306,9 @@ expression: diff.instruction_rows
|
|||||||
address: 186,
|
address: 186,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 15,
|
opcode: 15,
|
||||||
|
branch_dest: Some(
|
||||||
|
200,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -1218,6 +1327,7 @@ expression: diff.instruction_rows
|
|||||||
address: 188,
|
address: 188,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 32,
|
opcode: 32,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -1231,6 +1341,7 @@ expression: diff.instruction_rows
|
|||||||
address: 190,
|
address: 190,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 34,
|
opcode: 34,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -1244,6 +1355,7 @@ expression: diff.instruction_rows
|
|||||||
address: 192,
|
address: 192,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 46,
|
opcode: 46,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -1257,6 +1369,7 @@ expression: diff.instruction_rows
|
|||||||
address: 194,
|
address: 194,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 46,
|
opcode: 46,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -1270,6 +1383,7 @@ expression: diff.instruction_rows
|
|||||||
address: 196,
|
address: 196,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 19,
|
opcode: 19,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -1283,6 +1397,7 @@ expression: diff.instruction_rows
|
|||||||
address: 200,
|
address: 200,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 34,
|
opcode: 34,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -1305,6 +1420,7 @@ expression: diff.instruction_rows
|
|||||||
address: 202,
|
address: 202,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 35,
|
opcode: 35,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -1318,6 +1434,7 @@ expression: diff.instruction_rows
|
|||||||
address: 204,
|
address: 204,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 34,
|
opcode: 34,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -1331,6 +1448,7 @@ expression: diff.instruction_rows
|
|||||||
address: 206,
|
address: 206,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 4,
|
opcode: 4,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -1344,6 +1462,7 @@ expression: diff.instruction_rows
|
|||||||
address: 208,
|
address: 208,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 19,
|
opcode: 19,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -1357,6 +1476,7 @@ expression: diff.instruction_rows
|
|||||||
address: 212,
|
address: 212,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 7,
|
opcode: 7,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -1379,6 +1499,7 @@ expression: diff.instruction_rows
|
|||||||
address: 214,
|
address: 214,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 55,
|
opcode: 55,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -1392,6 +1513,7 @@ expression: diff.instruction_rows
|
|||||||
address: 216,
|
address: 216,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 65535,
|
opcode: 65535,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -1405,6 +1527,7 @@ expression: diff.instruction_rows
|
|||||||
address: 220,
|
address: 220,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 65535,
|
opcode: 65535,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -1418,6 +1541,7 @@ expression: diff.instruction_rows
|
|||||||
address: 224,
|
address: 224,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 65535,
|
opcode: 65535,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -1431,6 +1555,7 @@ expression: diff.instruction_rows
|
|||||||
address: 228,
|
address: 228,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 65535,
|
opcode: 65535,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -1444,6 +1569,7 @@ expression: diff.instruction_rows
|
|||||||
address: 232,
|
address: 232,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 65535,
|
opcode: 65535,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -1457,6 +1583,7 @@ expression: diff.instruction_rows
|
|||||||
address: 236,
|
address: 236,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 65535,
|
opcode: 65535,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -1470,6 +1597,7 @@ expression: diff.instruction_rows
|
|||||||
address: 240,
|
address: 240,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 65535,
|
opcode: 65535,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
|
|||||||
@@ -3826,4 +3826,5 @@ Object {
|
|||||||
split_meta: None,
|
split_meta: None,
|
||||||
path: None,
|
path: None,
|
||||||
timestamp: None,
|
timestamp: None,
|
||||||
|
flow_analysis_results: {},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ expression: diff.instruction_rows
|
|||||||
address: 0,
|
address: 0,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 12,
|
opcode: 12,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -22,6 +23,7 @@ expression: diff.instruction_rows
|
|||||||
address: 4,
|
address: 4,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 44,
|
opcode: 44,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -35,6 +37,7 @@ expression: diff.instruction_rows
|
|||||||
address: 8,
|
address: 8,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 44,
|
opcode: 44,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -48,6 +51,7 @@ expression: diff.instruction_rows
|
|||||||
address: 12,
|
address: 12,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 44,
|
opcode: 44,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -61,6 +65,7 @@ expression: diff.instruction_rows
|
|||||||
address: 16,
|
address: 16,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 44,
|
opcode: 44,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -74,6 +79,7 @@ expression: diff.instruction_rows
|
|||||||
address: 20,
|
address: 20,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 2,
|
opcode: 2,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -87,6 +93,7 @@ expression: diff.instruction_rows
|
|||||||
address: 24,
|
address: 24,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 113,
|
opcode: 113,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -100,6 +107,7 @@ expression: diff.instruction_rows
|
|||||||
address: 28,
|
address: 28,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 26,
|
opcode: 26,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -113,6 +121,7 @@ expression: diff.instruction_rows
|
|||||||
address: 32,
|
address: 32,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 20,
|
opcode: 20,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -126,6 +135,7 @@ expression: diff.instruction_rows
|
|||||||
address: 36,
|
address: 36,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 97,
|
opcode: 97,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -139,6 +149,7 @@ expression: diff.instruction_rows
|
|||||||
address: 40,
|
address: 40,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 2,
|
opcode: 2,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -152,6 +163,7 @@ expression: diff.instruction_rows
|
|||||||
address: 44,
|
address: 44,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 12,
|
opcode: 12,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -165,6 +177,7 @@ expression: diff.instruction_rows
|
|||||||
address: 48,
|
address: 48,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 20,
|
opcode: 20,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -178,6 +191,7 @@ expression: diff.instruction_rows
|
|||||||
address: 52,
|
address: 52,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 26,
|
opcode: 26,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -191,6 +205,7 @@ expression: diff.instruction_rows
|
|||||||
address: 56,
|
address: 56,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 2,
|
opcode: 2,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -204,6 +219,7 @@ expression: diff.instruction_rows
|
|||||||
address: 60,
|
address: 60,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 12,
|
opcode: 12,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -217,6 +233,7 @@ expression: diff.instruction_rows
|
|||||||
address: 64,
|
address: 64,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 26,
|
opcode: 26,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -230,6 +247,7 @@ expression: diff.instruction_rows
|
|||||||
address: 68,
|
address: 68,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 97,
|
opcode: 97,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -243,6 +261,7 @@ expression: diff.instruction_rows
|
|||||||
address: 72,
|
address: 72,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 2,
|
opcode: 2,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -256,6 +275,7 @@ expression: diff.instruction_rows
|
|||||||
address: 76,
|
address: 76,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 97,
|
opcode: 97,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -269,6 +289,7 @@ expression: diff.instruction_rows
|
|||||||
address: 80,
|
address: 80,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 2,
|
opcode: 2,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -289,6 +310,7 @@ expression: diff.instruction_rows
|
|||||||
address: 84,
|
address: 84,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 97,
|
opcode: 97,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -302,6 +324,9 @@ expression: diff.instruction_rows
|
|||||||
address: 88,
|
address: 88,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 56,
|
opcode: 56,
|
||||||
|
branch_dest: Some(
|
||||||
|
80,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -320,6 +345,7 @@ expression: diff.instruction_rows
|
|||||||
address: 92,
|
address: 92,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 113,
|
opcode: 113,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -333,6 +359,7 @@ expression: diff.instruction_rows
|
|||||||
address: 96,
|
address: 96,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 2,
|
opcode: 2,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -346,6 +373,7 @@ expression: diff.instruction_rows
|
|||||||
address: 100,
|
address: 100,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 20,
|
opcode: 20,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -359,6 +387,7 @@ expression: diff.instruction_rows
|
|||||||
address: 104,
|
address: 104,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 2,
|
opcode: 2,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -372,6 +401,7 @@ expression: diff.instruction_rows
|
|||||||
address: 108,
|
address: 108,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 12,
|
opcode: 12,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -385,6 +415,7 @@ expression: diff.instruction_rows
|
|||||||
address: 112,
|
address: 112,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 2,
|
opcode: 2,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -398,6 +429,7 @@ expression: diff.instruction_rows
|
|||||||
address: 116,
|
address: 116,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 16,
|
opcode: 16,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -411,6 +443,7 @@ expression: diff.instruction_rows
|
|||||||
address: 120,
|
address: 120,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 20,
|
opcode: 20,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -424,6 +457,7 @@ expression: diff.instruction_rows
|
|||||||
address: 124,
|
address: 124,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 12,
|
opcode: 12,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -437,6 +471,7 @@ expression: diff.instruction_rows
|
|||||||
address: 128,
|
address: 128,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 2,
|
opcode: 2,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -459,6 +494,7 @@ expression: diff.instruction_rows
|
|||||||
address: 132,
|
address: 132,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 12,
|
opcode: 12,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -472,6 +508,7 @@ expression: diff.instruction_rows
|
|||||||
address: 136,
|
address: 136,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 2,
|
opcode: 2,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -485,6 +522,7 @@ expression: diff.instruction_rows
|
|||||||
address: 140,
|
address: 140,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 113,
|
opcode: 113,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -498,6 +536,9 @@ expression: diff.instruction_rows
|
|||||||
address: 144,
|
address: 144,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 55,
|
opcode: 55,
|
||||||
|
branch_dest: Some(
|
||||||
|
128,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -516,6 +557,7 @@ expression: diff.instruction_rows
|
|||||||
address: 148,
|
address: 148,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 90,
|
opcode: 90,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -529,6 +571,9 @@ expression: diff.instruction_rows
|
|||||||
address: 152,
|
address: 152,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 3,
|
opcode: 3,
|
||||||
|
branch_dest: Some(
|
||||||
|
128,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -547,6 +592,7 @@ expression: diff.instruction_rows
|
|||||||
address: 156,
|
address: 156,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 113,
|
opcode: 113,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -560,6 +606,7 @@ expression: diff.instruction_rows
|
|||||||
address: 160,
|
address: 160,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 2,
|
opcode: 2,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -573,6 +620,7 @@ expression: diff.instruction_rows
|
|||||||
address: 164,
|
address: 164,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 60,
|
opcode: 60,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -586,6 +634,7 @@ expression: diff.instruction_rows
|
|||||||
address: 168,
|
address: 168,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 77,
|
opcode: 77,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -599,6 +648,7 @@ expression: diff.instruction_rows
|
|||||||
address: 172,
|
address: 172,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 113,
|
opcode: 113,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -612,6 +662,9 @@ expression: diff.instruction_rows
|
|||||||
address: 176,
|
address: 176,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 54,
|
opcode: 54,
|
||||||
|
branch_dest: Some(
|
||||||
|
128,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -630,6 +683,7 @@ expression: diff.instruction_rows
|
|||||||
address: 180,
|
address: 180,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 113,
|
opcode: 113,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
|
|||||||
@@ -1490,4 +1490,5 @@ Object {
|
|||||||
split_meta: None,
|
split_meta: None,
|
||||||
path: None,
|
path: None,
|
||||||
timestamp: None,
|
timestamp: None,
|
||||||
|
flow_analysis_results: {},
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -548,4 +548,5 @@ Object {
|
|||||||
split_meta: None,
|
split_meta: None,
|
||||||
path: None,
|
path: None,
|
||||||
timestamp: None,
|
timestamp: None,
|
||||||
|
flow_analysis_results: {},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ expression: diff.instruction_rows
|
|||||||
address: 0,
|
address: 0,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 60,
|
opcode: 60,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -22,6 +23,7 @@ expression: diff.instruction_rows
|
|||||||
address: 4,
|
address: 4,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 38,
|
opcode: 38,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -35,6 +37,9 @@ expression: diff.instruction_rows
|
|||||||
address: 8,
|
address: 8,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 43,
|
opcode: 43,
|
||||||
|
branch_dest: Some(
|
||||||
|
20,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -53,6 +58,7 @@ expression: diff.instruction_rows
|
|||||||
address: 12,
|
address: 12,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 41,
|
opcode: 41,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -66,6 +72,9 @@ expression: diff.instruction_rows
|
|||||||
address: 16,
|
address: 16,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 45,
|
opcode: 45,
|
||||||
|
branch_dest: Some(
|
||||||
|
32,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -84,6 +93,7 @@ expression: diff.instruction_rows
|
|||||||
address: 20,
|
address: 20,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 42,
|
opcode: 42,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -104,6 +114,7 @@ expression: diff.instruction_rows
|
|||||||
address: 24,
|
address: 24,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 41,
|
opcode: 41,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -117,6 +128,7 @@ expression: diff.instruction_rows
|
|||||||
address: 28,
|
address: 28,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 94,
|
opcode: 94,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -130,6 +142,7 @@ expression: diff.instruction_rows
|
|||||||
address: 32,
|
address: 32,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 60,
|
opcode: 60,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -150,6 +163,7 @@ expression: diff.instruction_rows
|
|||||||
address: 36,
|
address: 36,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 166,
|
opcode: 166,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -163,6 +177,7 @@ expression: diff.instruction_rows
|
|||||||
address: 40,
|
address: 40,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 38,
|
opcode: 38,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -176,6 +191,9 @@ expression: diff.instruction_rows
|
|||||||
address: 44,
|
address: 44,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 43,
|
opcode: 43,
|
||||||
|
branch_dest: Some(
|
||||||
|
56,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -194,6 +212,7 @@ expression: diff.instruction_rows
|
|||||||
address: 48,
|
address: 48,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 41,
|
opcode: 41,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -207,6 +226,9 @@ expression: diff.instruction_rows
|
|||||||
address: 52,
|
address: 52,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 45,
|
opcode: 45,
|
||||||
|
branch_dest: Some(
|
||||||
|
68,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -225,6 +247,7 @@ expression: diff.instruction_rows
|
|||||||
address: 56,
|
address: 56,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 42,
|
opcode: 42,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -245,6 +268,7 @@ expression: diff.instruction_rows
|
|||||||
address: 60,
|
address: 60,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 41,
|
opcode: 41,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -258,6 +282,7 @@ expression: diff.instruction_rows
|
|||||||
address: 64,
|
address: 64,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 94,
|
opcode: 94,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -271,6 +296,7 @@ expression: diff.instruction_rows
|
|||||||
address: 68,
|
address: 68,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 60,
|
opcode: 60,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -291,6 +317,7 @@ expression: diff.instruction_rows
|
|||||||
address: 72,
|
address: 72,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 41,
|
opcode: 41,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -304,6 +331,7 @@ expression: diff.instruction_rows
|
|||||||
address: 76,
|
address: 76,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 38,
|
opcode: 38,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -317,6 +345,7 @@ expression: diff.instruction_rows
|
|||||||
address: 80,
|
address: 80,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 166,
|
opcode: 166,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -330,6 +359,9 @@ expression: diff.instruction_rows
|
|||||||
address: 84,
|
address: 84,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 43,
|
opcode: 43,
|
||||||
|
branch_dest: Some(
|
||||||
|
96,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -348,6 +380,7 @@ expression: diff.instruction_rows
|
|||||||
address: 88,
|
address: 88,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 41,
|
opcode: 41,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -361,6 +394,9 @@ expression: diff.instruction_rows
|
|||||||
address: 92,
|
address: 92,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 45,
|
opcode: 45,
|
||||||
|
branch_dest: Some(
|
||||||
|
108,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -379,6 +415,7 @@ expression: diff.instruction_rows
|
|||||||
address: 96,
|
address: 96,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 42,
|
opcode: 42,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -399,6 +436,7 @@ expression: diff.instruction_rows
|
|||||||
address: 100,
|
address: 100,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 41,
|
opcode: 41,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -412,6 +450,7 @@ expression: diff.instruction_rows
|
|||||||
address: 104,
|
address: 104,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 94,
|
opcode: 94,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -425,6 +464,7 @@ expression: diff.instruction_rows
|
|||||||
address: 108,
|
address: 108,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 60,
|
opcode: 60,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -445,6 +485,7 @@ expression: diff.instruction_rows
|
|||||||
address: 112,
|
address: 112,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 41,
|
opcode: 41,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -458,6 +499,7 @@ expression: diff.instruction_rows
|
|||||||
address: 116,
|
address: 116,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 38,
|
opcode: 38,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -471,6 +513,7 @@ expression: diff.instruction_rows
|
|||||||
address: 120,
|
address: 120,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 166,
|
opcode: 166,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -484,6 +527,9 @@ expression: diff.instruction_rows
|
|||||||
address: 124,
|
address: 124,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 43,
|
opcode: 43,
|
||||||
|
branch_dest: Some(
|
||||||
|
136,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -502,6 +548,7 @@ expression: diff.instruction_rows
|
|||||||
address: 128,
|
address: 128,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 41,
|
opcode: 41,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -515,6 +562,9 @@ expression: diff.instruction_rows
|
|||||||
address: 132,
|
address: 132,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 45,
|
opcode: 45,
|
||||||
|
branch_dest: Some(
|
||||||
|
148,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -533,6 +583,7 @@ expression: diff.instruction_rows
|
|||||||
address: 136,
|
address: 136,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 42,
|
opcode: 42,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -553,6 +604,7 @@ expression: diff.instruction_rows
|
|||||||
address: 140,
|
address: 140,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 41,
|
opcode: 41,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -566,6 +618,7 @@ expression: diff.instruction_rows
|
|||||||
address: 144,
|
address: 144,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 94,
|
opcode: 94,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -579,6 +632,7 @@ expression: diff.instruction_rows
|
|||||||
address: 148,
|
address: 148,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 41,
|
opcode: 41,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -599,6 +653,7 @@ expression: diff.instruction_rows
|
|||||||
address: 152,
|
address: 152,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 41,
|
opcode: 41,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -612,6 +667,7 @@ expression: diff.instruction_rows
|
|||||||
address: 156,
|
address: 156,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 166,
|
opcode: 166,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -625,6 +681,7 @@ expression: diff.instruction_rows
|
|||||||
address: 160,
|
address: 160,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 42,
|
opcode: 42,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -638,6 +695,7 @@ expression: diff.instruction_rows
|
|||||||
address: 164,
|
address: 164,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 41,
|
opcode: 41,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -651,6 +709,7 @@ expression: diff.instruction_rows
|
|||||||
address: 168,
|
address: 168,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 166,
|
opcode: 166,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -664,6 +723,7 @@ expression: diff.instruction_rows
|
|||||||
address: 172,
|
address: 172,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 41,
|
opcode: 41,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -677,6 +737,7 @@ expression: diff.instruction_rows
|
|||||||
address: 176,
|
address: 176,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 162,
|
opcode: 162,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -690,6 +751,7 @@ expression: diff.instruction_rows
|
|||||||
address: 180,
|
address: 180,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 94,
|
opcode: 94,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -703,6 +765,7 @@ expression: diff.instruction_rows
|
|||||||
address: 184,
|
address: 184,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 66,
|
opcode: 66,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -716,6 +779,9 @@ expression: diff.instruction_rows
|
|||||||
address: 188,
|
address: 188,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 43,
|
opcode: 43,
|
||||||
|
branch_dest: Some(
|
||||||
|
196,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -734,6 +800,7 @@ expression: diff.instruction_rows
|
|||||||
address: 192,
|
address: 192,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 166,
|
opcode: 166,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -747,6 +814,7 @@ expression: diff.instruction_rows
|
|||||||
address: 196,
|
address: 196,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 163,
|
opcode: 163,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -767,6 +835,7 @@ expression: diff.instruction_rows
|
|||||||
address: 200,
|
address: 200,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 94,
|
opcode: 94,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -780,6 +849,7 @@ expression: diff.instruction_rows
|
|||||||
address: 204,
|
address: 204,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 66,
|
opcode: 66,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -793,6 +863,9 @@ expression: diff.instruction_rows
|
|||||||
address: 208,
|
address: 208,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 43,
|
opcode: 43,
|
||||||
|
branch_dest: Some(
|
||||||
|
216,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -811,6 +884,7 @@ expression: diff.instruction_rows
|
|||||||
address: 212,
|
address: 212,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 166,
|
opcode: 166,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -824,6 +898,7 @@ expression: diff.instruction_rows
|
|||||||
address: 216,
|
address: 216,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 163,
|
opcode: 163,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -844,6 +919,7 @@ expression: diff.instruction_rows
|
|||||||
address: 220,
|
address: 220,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 94,
|
opcode: 94,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -857,6 +933,7 @@ expression: diff.instruction_rows
|
|||||||
address: 224,
|
address: 224,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 66,
|
opcode: 66,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -870,6 +947,9 @@ expression: diff.instruction_rows
|
|||||||
address: 228,
|
address: 228,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 43,
|
opcode: 43,
|
||||||
|
branch_dest: Some(
|
||||||
|
236,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -888,6 +968,7 @@ expression: diff.instruction_rows
|
|||||||
address: 232,
|
address: 232,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 166,
|
opcode: 166,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -901,6 +982,7 @@ expression: diff.instruction_rows
|
|||||||
address: 236,
|
address: 236,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 163,
|
opcode: 163,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -921,6 +1003,7 @@ expression: diff.instruction_rows
|
|||||||
address: 240,
|
address: 240,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 94,
|
opcode: 94,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -934,6 +1017,7 @@ expression: diff.instruction_rows
|
|||||||
address: 244,
|
address: 244,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 66,
|
opcode: 66,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -947,6 +1031,9 @@ expression: diff.instruction_rows
|
|||||||
address: 248,
|
address: 248,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 43,
|
opcode: 43,
|
||||||
|
branch_dest: Some(
|
||||||
|
256,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -965,6 +1052,7 @@ expression: diff.instruction_rows
|
|||||||
address: 252,
|
address: 252,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 166,
|
opcode: 166,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -978,6 +1066,7 @@ expression: diff.instruction_rows
|
|||||||
address: 256,
|
address: 256,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 41,
|
opcode: 41,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -998,6 +1087,7 @@ expression: diff.instruction_rows
|
|||||||
address: 260,
|
address: 260,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 47,
|
opcode: 47,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
|
|||||||
@@ -581,4 +581,5 @@ Object {
|
|||||||
),
|
),
|
||||||
path: None,
|
path: None,
|
||||||
timestamp: None,
|
timestamp: None,
|
||||||
|
flow_analysis_results: {},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ expression: diff.instruction_rows
|
|||||||
address: 0,
|
address: 0,
|
||||||
size: 1,
|
size: 1,
|
||||||
opcode: 640,
|
opcode: 640,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -22,6 +23,7 @@ expression: diff.instruction_rows
|
|||||||
address: 1,
|
address: 1,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 414,
|
opcode: 414,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -35,6 +37,7 @@ expression: diff.instruction_rows
|
|||||||
address: 3,
|
address: 3,
|
||||||
size: 5,
|
size: 5,
|
||||||
opcode: 640,
|
opcode: 640,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -48,6 +51,7 @@ expression: diff.instruction_rows
|
|||||||
address: 8,
|
address: 8,
|
||||||
size: 5,
|
size: 5,
|
||||||
opcode: 59,
|
opcode: 59,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -61,6 +65,7 @@ expression: diff.instruction_rows
|
|||||||
address: 13,
|
address: 13,
|
||||||
size: 3,
|
size: 3,
|
||||||
opcode: 7,
|
opcode: 7,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -74,6 +79,7 @@ expression: diff.instruction_rows
|
|||||||
address: 16,
|
address: 16,
|
||||||
size: 1,
|
size: 1,
|
||||||
opcode: 590,
|
opcode: 590,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -87,6 +93,7 @@ expression: diff.instruction_rows
|
|||||||
address: 17,
|
address: 17,
|
||||||
size: 1,
|
size: 1,
|
||||||
opcode: 662,
|
opcode: 662,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
|
|||||||
@@ -207,4 +207,5 @@ Object {
|
|||||||
split_meta: None,
|
split_meta: None,
|
||||||
path: None,
|
path: None,
|
||||||
timestamp: None,
|
timestamp: None,
|
||||||
|
flow_analysis_results: {},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ expression: diff.instruction_rows
|
|||||||
address: 0,
|
address: 0,
|
||||||
size: 5,
|
size: 5,
|
||||||
opcode: 414,
|
opcode: 414,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -22,6 +23,7 @@ expression: diff.instruction_rows
|
|||||||
address: 5,
|
address: 5,
|
||||||
size: 5,
|
size: 5,
|
||||||
opcode: 414,
|
opcode: 414,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -35,6 +37,7 @@ expression: diff.instruction_rows
|
|||||||
address: 10,
|
address: 10,
|
||||||
size: 1,
|
size: 1,
|
||||||
opcode: 640,
|
opcode: 640,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -48,6 +51,7 @@ expression: diff.instruction_rows
|
|||||||
address: 11,
|
address: 11,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 740,
|
opcode: 740,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -61,6 +65,7 @@ expression: diff.instruction_rows
|
|||||||
address: 15,
|
address: 15,
|
||||||
size: 5,
|
size: 5,
|
||||||
opcode: 414,
|
opcode: 414,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -74,6 +79,7 @@ expression: diff.instruction_rows
|
|||||||
address: 20,
|
address: 20,
|
||||||
size: 5,
|
size: 5,
|
||||||
opcode: 414,
|
opcode: 414,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -87,6 +93,7 @@ expression: diff.instruction_rows
|
|||||||
address: 25,
|
address: 25,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 448,
|
opcode: 448,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -100,6 +107,7 @@ expression: diff.instruction_rows
|
|||||||
address: 29,
|
address: 29,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 460,
|
opcode: 460,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -113,6 +121,7 @@ expression: diff.instruction_rows
|
|||||||
address: 33,
|
address: 33,
|
||||||
size: 5,
|
size: 5,
|
||||||
opcode: 414,
|
opcode: 414,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -126,6 +135,7 @@ expression: diff.instruction_rows
|
|||||||
address: 38,
|
address: 38,
|
||||||
size: 5,
|
size: 5,
|
||||||
opcode: 414,
|
opcode: 414,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -139,6 +149,7 @@ expression: diff.instruction_rows
|
|||||||
address: 43,
|
address: 43,
|
||||||
size: 5,
|
size: 5,
|
||||||
opcode: 448,
|
opcode: 448,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -152,6 +163,7 @@ expression: diff.instruction_rows
|
|||||||
address: 48,
|
address: 48,
|
||||||
size: 5,
|
size: 5,
|
||||||
opcode: 460,
|
opcode: 460,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -165,6 +177,7 @@ expression: diff.instruction_rows
|
|||||||
address: 53,
|
address: 53,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 11,
|
opcode: 11,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -178,6 +191,7 @@ expression: diff.instruction_rows
|
|||||||
address: 57,
|
address: 57,
|
||||||
size: 5,
|
size: 5,
|
||||||
opcode: 414,
|
opcode: 414,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -191,6 +205,7 @@ expression: diff.instruction_rows
|
|||||||
address: 62,
|
address: 62,
|
||||||
size: 5,
|
size: 5,
|
||||||
opcode: 414,
|
opcode: 414,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -204,6 +219,7 @@ expression: diff.instruction_rows
|
|||||||
address: 67,
|
address: 67,
|
||||||
size: 5,
|
size: 5,
|
||||||
opcode: 448,
|
opcode: 448,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -217,6 +233,7 @@ expression: diff.instruction_rows
|
|||||||
address: 72,
|
address: 72,
|
||||||
size: 5,
|
size: 5,
|
||||||
opcode: 460,
|
opcode: 460,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -230,6 +247,7 @@ expression: diff.instruction_rows
|
|||||||
address: 77,
|
address: 77,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 11,
|
opcode: 11,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -243,6 +261,7 @@ expression: diff.instruction_rows
|
|||||||
address: 81,
|
address: 81,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 7,
|
opcode: 7,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -256,6 +275,7 @@ expression: diff.instruction_rows
|
|||||||
address: 85,
|
address: 85,
|
||||||
size: 1,
|
size: 1,
|
||||||
opcode: 590,
|
opcode: 590,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -269,6 +289,7 @@ expression: diff.instruction_rows
|
|||||||
address: 86,
|
address: 86,
|
||||||
size: 1,
|
size: 1,
|
||||||
opcode: 662,
|
opcode: 662,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
|
|||||||
@@ -1574,4 +1574,5 @@ Object {
|
|||||||
split_meta: None,
|
split_meta: None,
|
||||||
path: None,
|
path: None,
|
||||||
timestamp: None,
|
timestamp: None,
|
||||||
|
flow_analysis_results: {},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,11 +42,11 @@ expression: obj.sections
|
|||||||
name: ".rdata",
|
name: ".rdata",
|
||||||
address: 0,
|
address: 0,
|
||||||
size: 0,
|
size: 0,
|
||||||
kind: Data,
|
kind: Unknown,
|
||||||
data: SectionData(
|
data: SectionData(
|
||||||
0,
|
0,
|
||||||
),
|
),
|
||||||
flags: FlagSet(Hidden),
|
flags: FlagSet(),
|
||||||
align: Some(
|
align: Some(
|
||||||
4,
|
4,
|
||||||
),
|
),
|
||||||
@@ -59,11 +59,11 @@ expression: obj.sections
|
|||||||
name: ".rdata",
|
name: ".rdata",
|
||||||
address: 0,
|
address: 0,
|
||||||
size: 0,
|
size: 0,
|
||||||
kind: Data,
|
kind: Unknown,
|
||||||
data: SectionData(
|
data: SectionData(
|
||||||
0,
|
0,
|
||||||
),
|
),
|
||||||
flags: FlagSet(Hidden),
|
flags: FlagSet(),
|
||||||
align: Some(
|
align: Some(
|
||||||
4,
|
4,
|
||||||
),
|
),
|
||||||
@@ -76,11 +76,11 @@ expression: obj.sections
|
|||||||
name: ".text$mn",
|
name: ".text$mn",
|
||||||
address: 0,
|
address: 0,
|
||||||
size: 0,
|
size: 0,
|
||||||
kind: Code,
|
kind: Unknown,
|
||||||
data: SectionData(
|
data: SectionData(
|
||||||
0,
|
0,
|
||||||
),
|
),
|
||||||
flags: FlagSet(Hidden),
|
flags: FlagSet(),
|
||||||
align: Some(
|
align: Some(
|
||||||
16,
|
16,
|
||||||
),
|
),
|
||||||
@@ -425,11 +425,11 @@ expression: obj.sections
|
|||||||
name: ".rdata$r",
|
name: ".rdata$r",
|
||||||
address: 0,
|
address: 0,
|
||||||
size: 0,
|
size: 0,
|
||||||
kind: Data,
|
kind: Unknown,
|
||||||
data: SectionData(
|
data: SectionData(
|
||||||
0,
|
0,
|
||||||
),
|
),
|
||||||
flags: FlagSet(Hidden),
|
flags: FlagSet(),
|
||||||
align: Some(
|
align: Some(
|
||||||
4,
|
4,
|
||||||
),
|
),
|
||||||
@@ -442,11 +442,11 @@ expression: obj.sections
|
|||||||
name: ".rdata$r",
|
name: ".rdata$r",
|
||||||
address: 0,
|
address: 0,
|
||||||
size: 0,
|
size: 0,
|
||||||
kind: Data,
|
kind: Unknown,
|
||||||
data: SectionData(
|
data: SectionData(
|
||||||
0,
|
0,
|
||||||
),
|
),
|
||||||
flags: FlagSet(Hidden),
|
flags: FlagSet(),
|
||||||
align: Some(
|
align: Some(
|
||||||
4,
|
4,
|
||||||
),
|
),
|
||||||
@@ -459,11 +459,11 @@ expression: obj.sections
|
|||||||
name: ".data$rs",
|
name: ".data$rs",
|
||||||
address: 0,
|
address: 0,
|
||||||
size: 0,
|
size: 0,
|
||||||
kind: Data,
|
kind: Unknown,
|
||||||
data: SectionData(
|
data: SectionData(
|
||||||
0,
|
0,
|
||||||
),
|
),
|
||||||
flags: FlagSet(Hidden),
|
flags: FlagSet(),
|
||||||
align: Some(
|
align: Some(
|
||||||
4,
|
4,
|
||||||
),
|
),
|
||||||
@@ -476,11 +476,11 @@ expression: obj.sections
|
|||||||
name: ".rdata$r",
|
name: ".rdata$r",
|
||||||
address: 0,
|
address: 0,
|
||||||
size: 0,
|
size: 0,
|
||||||
kind: Data,
|
kind: Unknown,
|
||||||
data: SectionData(
|
data: SectionData(
|
||||||
0,
|
0,
|
||||||
),
|
),
|
||||||
flags: FlagSet(Hidden),
|
flags: FlagSet(),
|
||||||
align: Some(
|
align: Some(
|
||||||
4,
|
4,
|
||||||
),
|
),
|
||||||
@@ -493,11 +493,11 @@ expression: obj.sections
|
|||||||
name: ".rdata$r",
|
name: ".rdata$r",
|
||||||
address: 0,
|
address: 0,
|
||||||
size: 0,
|
size: 0,
|
||||||
kind: Data,
|
kind: Unknown,
|
||||||
data: SectionData(
|
data: SectionData(
|
||||||
0,
|
0,
|
||||||
),
|
),
|
||||||
flags: FlagSet(Hidden),
|
flags: FlagSet(),
|
||||||
align: Some(
|
align: Some(
|
||||||
4,
|
4,
|
||||||
),
|
),
|
||||||
@@ -510,11 +510,11 @@ expression: obj.sections
|
|||||||
name: ".rdata$r",
|
name: ".rdata$r",
|
||||||
address: 0,
|
address: 0,
|
||||||
size: 0,
|
size: 0,
|
||||||
kind: Data,
|
kind: Unknown,
|
||||||
data: SectionData(
|
data: SectionData(
|
||||||
0,
|
0,
|
||||||
),
|
),
|
||||||
flags: FlagSet(Hidden),
|
flags: FlagSet(),
|
||||||
align: Some(
|
align: Some(
|
||||||
4,
|
4,
|
||||||
),
|
),
|
||||||
@@ -527,11 +527,11 @@ expression: obj.sections
|
|||||||
name: ".rdata$r",
|
name: ".rdata$r",
|
||||||
address: 0,
|
address: 0,
|
||||||
size: 0,
|
size: 0,
|
||||||
kind: Data,
|
kind: Unknown,
|
||||||
data: SectionData(
|
data: SectionData(
|
||||||
0,
|
0,
|
||||||
),
|
),
|
||||||
flags: FlagSet(Hidden),
|
flags: FlagSet(),
|
||||||
align: Some(
|
align: Some(
|
||||||
4,
|
4,
|
||||||
),
|
),
|
||||||
@@ -544,11 +544,11 @@ expression: obj.sections
|
|||||||
name: ".data$rs",
|
name: ".data$rs",
|
||||||
address: 0,
|
address: 0,
|
||||||
size: 0,
|
size: 0,
|
||||||
kind: Data,
|
kind: Unknown,
|
||||||
data: SectionData(
|
data: SectionData(
|
||||||
0,
|
0,
|
||||||
),
|
),
|
||||||
flags: FlagSet(Hidden),
|
flags: FlagSet(),
|
||||||
align: Some(
|
align: Some(
|
||||||
4,
|
4,
|
||||||
),
|
),
|
||||||
@@ -561,11 +561,11 @@ expression: obj.sections
|
|||||||
name: ".rdata$r",
|
name: ".rdata$r",
|
||||||
address: 0,
|
address: 0,
|
||||||
size: 0,
|
size: 0,
|
||||||
kind: Data,
|
kind: Unknown,
|
||||||
data: SectionData(
|
data: SectionData(
|
||||||
0,
|
0,
|
||||||
),
|
),
|
||||||
flags: FlagSet(Hidden),
|
flags: FlagSet(),
|
||||||
align: Some(
|
align: Some(
|
||||||
4,
|
4,
|
||||||
),
|
),
|
||||||
@@ -578,11 +578,11 @@ expression: obj.sections
|
|||||||
name: ".rdata$r",
|
name: ".rdata$r",
|
||||||
address: 0,
|
address: 0,
|
||||||
size: 0,
|
size: 0,
|
||||||
kind: Data,
|
kind: Unknown,
|
||||||
data: SectionData(
|
data: SectionData(
|
||||||
0,
|
0,
|
||||||
),
|
),
|
||||||
flags: FlagSet(Hidden),
|
flags: FlagSet(),
|
||||||
align: Some(
|
align: Some(
|
||||||
4,
|
4,
|
||||||
),
|
),
|
||||||
@@ -595,11 +595,11 @@ expression: obj.sections
|
|||||||
name: ".rdata$r",
|
name: ".rdata$r",
|
||||||
address: 0,
|
address: 0,
|
||||||
size: 0,
|
size: 0,
|
||||||
kind: Data,
|
kind: Unknown,
|
||||||
data: SectionData(
|
data: SectionData(
|
||||||
0,
|
0,
|
||||||
),
|
),
|
||||||
flags: FlagSet(Hidden),
|
flags: FlagSet(),
|
||||||
align: Some(
|
align: Some(
|
||||||
4,
|
4,
|
||||||
),
|
),
|
||||||
@@ -612,11 +612,11 @@ expression: obj.sections
|
|||||||
name: ".rdata$r",
|
name: ".rdata$r",
|
||||||
address: 0,
|
address: 0,
|
||||||
size: 0,
|
size: 0,
|
||||||
kind: Data,
|
kind: Unknown,
|
||||||
data: SectionData(
|
data: SectionData(
|
||||||
0,
|
0,
|
||||||
),
|
),
|
||||||
flags: FlagSet(Hidden),
|
flags: FlagSet(),
|
||||||
align: Some(
|
align: Some(
|
||||||
4,
|
4,
|
||||||
),
|
),
|
||||||
@@ -629,11 +629,11 @@ expression: obj.sections
|
|||||||
name: ".text$mn",
|
name: ".text$mn",
|
||||||
address: 0,
|
address: 0,
|
||||||
size: 0,
|
size: 0,
|
||||||
kind: Code,
|
kind: Unknown,
|
||||||
data: SectionData(
|
data: SectionData(
|
||||||
0,
|
0,
|
||||||
),
|
),
|
||||||
flags: FlagSet(Hidden),
|
flags: FlagSet(),
|
||||||
align: Some(
|
align: Some(
|
||||||
1,
|
1,
|
||||||
),
|
),
|
||||||
@@ -646,11 +646,11 @@ expression: obj.sections
|
|||||||
name: ".rdata$r",
|
name: ".rdata$r",
|
||||||
address: 0,
|
address: 0,
|
||||||
size: 0,
|
size: 0,
|
||||||
kind: Data,
|
kind: Unknown,
|
||||||
data: SectionData(
|
data: SectionData(
|
||||||
0,
|
0,
|
||||||
),
|
),
|
||||||
flags: FlagSet(Hidden),
|
flags: FlagSet(),
|
||||||
align: Some(
|
align: Some(
|
||||||
4,
|
4,
|
||||||
),
|
),
|
||||||
@@ -663,11 +663,11 @@ expression: obj.sections
|
|||||||
name: ".text$mn",
|
name: ".text$mn",
|
||||||
address: 0,
|
address: 0,
|
||||||
size: 0,
|
size: 0,
|
||||||
kind: Code,
|
kind: Unknown,
|
||||||
data: SectionData(
|
data: SectionData(
|
||||||
0,
|
0,
|
||||||
),
|
),
|
||||||
flags: FlagSet(Hidden),
|
flags: FlagSet(),
|
||||||
align: Some(
|
align: Some(
|
||||||
16,
|
16,
|
||||||
),
|
),
|
||||||
@@ -680,11 +680,11 @@ expression: obj.sections
|
|||||||
name: ".text$mn",
|
name: ".text$mn",
|
||||||
address: 0,
|
address: 0,
|
||||||
size: 0,
|
size: 0,
|
||||||
kind: Code,
|
kind: Unknown,
|
||||||
data: SectionData(
|
data: SectionData(
|
||||||
0,
|
0,
|
||||||
),
|
),
|
||||||
flags: FlagSet(Hidden),
|
flags: FlagSet(),
|
||||||
align: Some(
|
align: Some(
|
||||||
16,
|
16,
|
||||||
),
|
),
|
||||||
@@ -697,11 +697,11 @@ expression: obj.sections
|
|||||||
name: ".text$mn",
|
name: ".text$mn",
|
||||||
address: 0,
|
address: 0,
|
||||||
size: 0,
|
size: 0,
|
||||||
kind: Code,
|
kind: Unknown,
|
||||||
data: SectionData(
|
data: SectionData(
|
||||||
0,
|
0,
|
||||||
),
|
),
|
||||||
flags: FlagSet(Hidden),
|
flags: FlagSet(),
|
||||||
align: Some(
|
align: Some(
|
||||||
16,
|
16,
|
||||||
),
|
),
|
||||||
@@ -714,11 +714,11 @@ expression: obj.sections
|
|||||||
name: ".text$mn",
|
name: ".text$mn",
|
||||||
address: 0,
|
address: 0,
|
||||||
size: 0,
|
size: 0,
|
||||||
kind: Code,
|
kind: Unknown,
|
||||||
data: SectionData(
|
data: SectionData(
|
||||||
0,
|
0,
|
||||||
),
|
),
|
||||||
flags: FlagSet(Hidden),
|
flags: FlagSet(),
|
||||||
align: Some(
|
align: Some(
|
||||||
16,
|
16,
|
||||||
),
|
),
|
||||||
@@ -731,11 +731,11 @@ expression: obj.sections
|
|||||||
name: ".text$mn",
|
name: ".text$mn",
|
||||||
address: 0,
|
address: 0,
|
||||||
size: 0,
|
size: 0,
|
||||||
kind: Code,
|
kind: Unknown,
|
||||||
data: SectionData(
|
data: SectionData(
|
||||||
0,
|
0,
|
||||||
),
|
),
|
||||||
flags: FlagSet(Hidden),
|
flags: FlagSet(),
|
||||||
align: Some(
|
align: Some(
|
||||||
16,
|
16,
|
||||||
),
|
),
|
||||||
@@ -902,11 +902,11 @@ expression: obj.sections
|
|||||||
name: ".text$yd",
|
name: ".text$yd",
|
||||||
address: 0,
|
address: 0,
|
||||||
size: 0,
|
size: 0,
|
||||||
kind: Code,
|
kind: Unknown,
|
||||||
data: SectionData(
|
data: SectionData(
|
||||||
0,
|
0,
|
||||||
),
|
),
|
||||||
flags: FlagSet(Hidden),
|
flags: FlagSet(),
|
||||||
align: Some(
|
align: Some(
|
||||||
16,
|
16,
|
||||||
),
|
),
|
||||||
@@ -919,11 +919,11 @@ expression: obj.sections
|
|||||||
name: ".rdata",
|
name: ".rdata",
|
||||||
address: 0,
|
address: 0,
|
||||||
size: 0,
|
size: 0,
|
||||||
kind: Data,
|
kind: Unknown,
|
||||||
data: SectionData(
|
data: SectionData(
|
||||||
0,
|
0,
|
||||||
),
|
),
|
||||||
flags: FlagSet(Hidden),
|
flags: FlagSet(),
|
||||||
align: Some(
|
align: Some(
|
||||||
4,
|
4,
|
||||||
),
|
),
|
||||||
@@ -936,11 +936,11 @@ expression: obj.sections
|
|||||||
name: ".rdata",
|
name: ".rdata",
|
||||||
address: 0,
|
address: 0,
|
||||||
size: 0,
|
size: 0,
|
||||||
kind: Data,
|
kind: Unknown,
|
||||||
data: SectionData(
|
data: SectionData(
|
||||||
0,
|
0,
|
||||||
),
|
),
|
||||||
flags: FlagSet(Hidden),
|
flags: FlagSet(),
|
||||||
align: Some(
|
align: Some(
|
||||||
4,
|
4,
|
||||||
),
|
),
|
||||||
@@ -953,11 +953,11 @@ expression: obj.sections
|
|||||||
name: ".data",
|
name: ".data",
|
||||||
address: 0,
|
address: 0,
|
||||||
size: 0,
|
size: 0,
|
||||||
kind: Data,
|
kind: Unknown,
|
||||||
data: SectionData(
|
data: SectionData(
|
||||||
0,
|
0,
|
||||||
),
|
),
|
||||||
flags: FlagSet(Hidden),
|
flags: FlagSet(),
|
||||||
align: Some(
|
align: Some(
|
||||||
4,
|
4,
|
||||||
),
|
),
|
||||||
@@ -970,11 +970,11 @@ expression: obj.sections
|
|||||||
name: ".rdata$r",
|
name: ".rdata$r",
|
||||||
address: 0,
|
address: 0,
|
||||||
size: 0,
|
size: 0,
|
||||||
kind: Data,
|
kind: Unknown,
|
||||||
data: SectionData(
|
data: SectionData(
|
||||||
0,
|
0,
|
||||||
),
|
),
|
||||||
flags: FlagSet(Hidden),
|
flags: FlagSet(),
|
||||||
align: Some(
|
align: Some(
|
||||||
4,
|
4,
|
||||||
),
|
),
|
||||||
@@ -987,11 +987,11 @@ expression: obj.sections
|
|||||||
name: ".rdata$r",
|
name: ".rdata$r",
|
||||||
address: 0,
|
address: 0,
|
||||||
size: 0,
|
size: 0,
|
||||||
kind: Data,
|
kind: Unknown,
|
||||||
data: SectionData(
|
data: SectionData(
|
||||||
0,
|
0,
|
||||||
),
|
),
|
||||||
flags: FlagSet(Hidden),
|
flags: FlagSet(),
|
||||||
align: Some(
|
align: Some(
|
||||||
4,
|
4,
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ expression: diff.instruction_rows
|
|||||||
address: 0,
|
address: 0,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 414,
|
opcode: 414,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -22,6 +23,7 @@ expression: diff.instruction_rows
|
|||||||
address: 4,
|
address: 4,
|
||||||
size: 1,
|
size: 1,
|
||||||
opcode: 137,
|
opcode: 137,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -35,6 +37,7 @@ expression: diff.instruction_rows
|
|||||||
address: 5,
|
address: 5,
|
||||||
size: 3,
|
size: 3,
|
||||||
opcode: 93,
|
opcode: 93,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -48,6 +51,9 @@ expression: diff.instruction_rows
|
|||||||
address: 8,
|
address: 8,
|
||||||
size: 2,
|
size: 2,
|
||||||
opcode: 297,
|
opcode: 297,
|
||||||
|
branch_dest: Some(
|
||||||
|
58,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -66,6 +72,9 @@ expression: diff.instruction_rows
|
|||||||
address: 10,
|
address: 10,
|
||||||
size: 7,
|
size: 7,
|
||||||
opcode: 308,
|
opcode: 308,
|
||||||
|
branch_dest: Some(
|
||||||
|
60,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -84,6 +93,7 @@ expression: diff.instruction_rows
|
|||||||
address: 17,
|
address: 17,
|
||||||
size: 5,
|
size: 5,
|
||||||
opcode: 414,
|
opcode: 414,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -104,6 +114,7 @@ expression: diff.instruction_rows
|
|||||||
address: 22,
|
address: 22,
|
||||||
size: 1,
|
size: 1,
|
||||||
opcode: 662,
|
opcode: 662,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -117,6 +128,7 @@ expression: diff.instruction_rows
|
|||||||
address: 23,
|
address: 23,
|
||||||
size: 5,
|
size: 5,
|
||||||
opcode: 414,
|
opcode: 414,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -137,6 +149,7 @@ expression: diff.instruction_rows
|
|||||||
address: 28,
|
address: 28,
|
||||||
size: 1,
|
size: 1,
|
||||||
opcode: 662,
|
opcode: 662,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -150,6 +163,7 @@ expression: diff.instruction_rows
|
|||||||
address: 29,
|
address: 29,
|
||||||
size: 5,
|
size: 5,
|
||||||
opcode: 414,
|
opcode: 414,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -170,6 +184,7 @@ expression: diff.instruction_rows
|
|||||||
address: 34,
|
address: 34,
|
||||||
size: 1,
|
size: 1,
|
||||||
opcode: 662,
|
opcode: 662,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -183,6 +198,7 @@ expression: diff.instruction_rows
|
|||||||
address: 35,
|
address: 35,
|
||||||
size: 5,
|
size: 5,
|
||||||
opcode: 414,
|
opcode: 414,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -203,6 +219,7 @@ expression: diff.instruction_rows
|
|||||||
address: 40,
|
address: 40,
|
||||||
size: 1,
|
size: 1,
|
||||||
opcode: 662,
|
opcode: 662,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -216,6 +233,7 @@ expression: diff.instruction_rows
|
|||||||
address: 41,
|
address: 41,
|
||||||
size: 5,
|
size: 5,
|
||||||
opcode: 414,
|
opcode: 414,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -236,6 +254,7 @@ expression: diff.instruction_rows
|
|||||||
address: 46,
|
address: 46,
|
||||||
size: 1,
|
size: 1,
|
||||||
opcode: 662,
|
opcode: 662,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -249,6 +268,7 @@ expression: diff.instruction_rows
|
|||||||
address: 47,
|
address: 47,
|
||||||
size: 5,
|
size: 5,
|
||||||
opcode: 414,
|
opcode: 414,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -269,6 +289,7 @@ expression: diff.instruction_rows
|
|||||||
address: 52,
|
address: 52,
|
||||||
size: 1,
|
size: 1,
|
||||||
opcode: 662,
|
opcode: 662,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -282,6 +303,7 @@ expression: diff.instruction_rows
|
|||||||
address: 53,
|
address: 53,
|
||||||
size: 5,
|
size: 5,
|
||||||
opcode: 414,
|
opcode: 414,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -302,6 +324,7 @@ expression: diff.instruction_rows
|
|||||||
address: 58,
|
address: 58,
|
||||||
size: 1,
|
size: 1,
|
||||||
opcode: 662,
|
opcode: 662,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -322,6 +345,7 @@ expression: diff.instruction_rows
|
|||||||
address: 59,
|
address: 59,
|
||||||
size: 1,
|
size: 1,
|
||||||
opcode: 465,
|
opcode: 465,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -335,6 +359,9 @@ expression: diff.instruction_rows
|
|||||||
address: 60,
|
address: 60,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 65534,
|
opcode: 65534,
|
||||||
|
branch_dest: Some(
|
||||||
|
17,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -360,6 +387,9 @@ expression: diff.instruction_rows
|
|||||||
address: 64,
|
address: 64,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 65534,
|
opcode: 65534,
|
||||||
|
branch_dest: Some(
|
||||||
|
23,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -378,6 +408,9 @@ expression: diff.instruction_rows
|
|||||||
address: 68,
|
address: 68,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 65534,
|
opcode: 65534,
|
||||||
|
branch_dest: Some(
|
||||||
|
29,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -396,6 +429,9 @@ expression: diff.instruction_rows
|
|||||||
address: 72,
|
address: 72,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 65534,
|
opcode: 65534,
|
||||||
|
branch_dest: Some(
|
||||||
|
35,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -414,6 +450,9 @@ expression: diff.instruction_rows
|
|||||||
address: 76,
|
address: 76,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 65534,
|
opcode: 65534,
|
||||||
|
branch_dest: Some(
|
||||||
|
41,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -432,6 +471,9 @@ expression: diff.instruction_rows
|
|||||||
address: 80,
|
address: 80,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 65534,
|
opcode: 65534,
|
||||||
|
branch_dest: Some(
|
||||||
|
47,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -450,6 +492,9 @@ expression: diff.instruction_rows
|
|||||||
address: 84,
|
address: 84,
|
||||||
size: 4,
|
size: 4,
|
||||||
opcode: 65534,
|
opcode: 65534,
|
||||||
|
branch_dest: Some(
|
||||||
|
53,
|
||||||
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -468,6 +513,7 @@ expression: diff.instruction_rows
|
|||||||
address: 88,
|
address: 88,
|
||||||
size: 1,
|
size: 1,
|
||||||
opcode: 465,
|
opcode: 465,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -481,6 +527,7 @@ expression: diff.instruction_rows
|
|||||||
address: 89,
|
address: 89,
|
||||||
size: 1,
|
size: 1,
|
||||||
opcode: 465,
|
opcode: 465,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -494,6 +541,7 @@ expression: diff.instruction_rows
|
|||||||
address: 90,
|
address: 90,
|
||||||
size: 1,
|
size: 1,
|
||||||
opcode: 465,
|
opcode: 465,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -507,6 +555,7 @@ expression: diff.instruction_rows
|
|||||||
address: 91,
|
address: 91,
|
||||||
size: 1,
|
size: 1,
|
||||||
opcode: 465,
|
opcode: 465,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -520,6 +569,7 @@ expression: diff.instruction_rows
|
|||||||
address: 92,
|
address: 92,
|
||||||
size: 1,
|
size: 1,
|
||||||
opcode: 465,
|
opcode: 465,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -533,6 +583,7 @@ expression: diff.instruction_rows
|
|||||||
address: 93,
|
address: 93,
|
||||||
size: 1,
|
size: 1,
|
||||||
opcode: 465,
|
opcode: 465,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -546,6 +597,7 @@ expression: diff.instruction_rows
|
|||||||
address: 94,
|
address: 94,
|
||||||
size: 1,
|
size: 1,
|
||||||
opcode: 465,
|
opcode: 465,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
@@ -559,6 +611,7 @@ expression: diff.instruction_rows
|
|||||||
address: 95,
|
address: 95,
|
||||||
size: 1,
|
size: 1,
|
||||||
opcode: 465,
|
opcode: 465,
|
||||||
|
branch_dest: None,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
kind: None,
|
kind: None,
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ expression: output
|
|||||||
[(Address(4), Normal, 5), (Spacing(4), Normal, 0), (Opcode("dec", 137), Normal, 10), (Argument(Opaque("eax")), Normal, 0), (Eol, Normal, 0)]
|
[(Address(4), Normal, 5), (Spacing(4), Normal, 0), (Opcode("dec", 137), Normal, 10), (Argument(Opaque("eax")), Normal, 0), (Eol, Normal, 0)]
|
||||||
[(Address(5), Normal, 5), (Spacing(4), Normal, 0), (Opcode("cmp", 93), Normal, 10), (Argument(Opaque("eax")), Normal, 0), (Basic(","), Normal, 0), (Spacing(1), Normal, 0), (Argument(Unsigned(6)), Normal, 0), (Eol, Normal, 0)]
|
[(Address(5), Normal, 5), (Spacing(4), Normal, 0), (Opcode("cmp", 93), Normal, 10), (Argument(Opaque("eax")), Normal, 0), (Basic(","), Normal, 0), (Spacing(1), Normal, 0), (Argument(Unsigned(6)), Normal, 0), (Eol, Normal, 0)]
|
||||||
[(Address(8), Normal, 5), (Spacing(4), Normal, 0), (Opcode("ja", 297), Normal, 10), (Argument(Opaque("short")), Normal, 0), (Spacing(1), Normal, 0), (BranchDest(58), Normal, 0), (Basic(" ~>"), Rotating(0), 0), (Eol, Normal, 0)]
|
[(Address(8), Normal, 5), (Spacing(4), Normal, 0), (Opcode("ja", 297), Normal, 10), (Argument(Opaque("short")), Normal, 0), (Spacing(1), Normal, 0), (BranchDest(58), Normal, 0), (Basic(" ~>"), Rotating(0), 0), (Eol, Normal, 0)]
|
||||||
[(Address(10), Normal, 5), (Spacing(4), Normal, 0), (Opcode("jmp", 308), Normal, 10), (Argument(Opaque("dword")), Normal, 0), (Spacing(1), Normal, 0), (Argument(Opaque("ptr")), Normal, 0), (Spacing(1), Normal, 0), (Basic("["), Normal, 0), (Argument(Opaque("eax")), Normal, 0), (Argument(Opaque("*")), Normal, 0), (Argument(Signed(4)), Normal, 0), (Argument(Opaque("+")), Normal, 0), (Symbol(Symbol { name: "$L282", demangled_name: None, address: 60, size: 0, kind: Unknown, section: Some(1), flags: FlagSet(Local), align: None, virtual_address: None }), Bright, 0), (Basic("]"), Normal, 0), (Basic(" ~>"), Rotating(1), 0), (Eol, Normal, 0)]
|
[(Address(10), Normal, 5), (Spacing(4), Normal, 0), (Opcode("jmp", 308), Normal, 10), (Argument(Opaque("dword")), Normal, 0), (Spacing(1), Normal, 0), (Argument(Opaque("ptr")), Normal, 0), (Spacing(1), Normal, 0), (Basic("["), Normal, 0), (Argument(Opaque("eax")), Normal, 0), (Argument(Opaque("*")), Normal, 0), (Argument(Signed(4)), Normal, 0), (Argument(Opaque("+")), Normal, 0), (BranchDest(60), Normal, 0), (Basic("]"), Normal, 0), (Basic(" ~>"), Rotating(1), 0), (Eol, Normal, 0)]
|
||||||
[(Address(17), Normal, 5), (Basic(" ~> "), Rotating(2), 0), (Opcode("mov", 414), Normal, 10), (Argument(Opaque("eax")), Normal, 0), (Basic(","), Normal, 0), (Spacing(1), Normal, 0), (Argument(Unsigned(8)), Normal, 0), (Eol, Normal, 0)]
|
[(Address(17), Normal, 5), (Basic(" ~> "), Rotating(2), 0), (Opcode("mov", 414), Normal, 10), (Argument(Opaque("eax")), Normal, 0), (Basic(","), Normal, 0), (Spacing(1), Normal, 0), (Argument(Unsigned(8)), Normal, 0), (Eol, Normal, 0)]
|
||||||
[(Address(22), Normal, 5), (Spacing(4), Normal, 0), (Opcode("ret", 662), Normal, 10), (Eol, Normal, 0)]
|
[(Address(22), Normal, 5), (Spacing(4), Normal, 0), (Opcode("ret", 662), Normal, 10), (Eol, Normal, 0)]
|
||||||
[(Address(23), Normal, 5), (Basic(" ~> "), Rotating(3), 0), (Opcode("mov", 414), Normal, 10), (Argument(Opaque("eax")), Normal, 0), (Basic(","), Normal, 0), (Spacing(1), Normal, 0), (Argument(Unsigned(7)), Normal, 0), (Eol, Normal, 0)]
|
[(Address(23), Normal, 5), (Basic(" ~> "), Rotating(3), 0), (Opcode("mov", 414), Normal, 10), (Argument(Opaque("eax")), Normal, 0), (Basic(","), Normal, 0), (Spacing(1), Normal, 0), (Argument(Unsigned(7)), Normal, 0), (Eol, Normal, 0)]
|
||||||
@@ -22,13 +22,13 @@ expression: output
|
|||||||
[(Address(53), Normal, 5), (Basic(" ~> "), Rotating(8), 0), (Opcode("mov", 414), Normal, 10), (Argument(Opaque("eax")), Normal, 0), (Basic(","), Normal, 0), (Spacing(1), Normal, 0), (Argument(Unsigned(2)), Normal, 0), (Eol, Normal, 0)]
|
[(Address(53), Normal, 5), (Basic(" ~> "), Rotating(8), 0), (Opcode("mov", 414), Normal, 10), (Argument(Opaque("eax")), Normal, 0), (Basic(","), Normal, 0), (Spacing(1), Normal, 0), (Argument(Unsigned(2)), Normal, 0), (Eol, Normal, 0)]
|
||||||
[(Address(58), Normal, 5), (Basic(" ~> "), Rotating(0), 0), (Opcode("ret", 662), Normal, 10), (Eol, Normal, 0)]
|
[(Address(58), Normal, 5), (Basic(" ~> "), Rotating(0), 0), (Opcode("ret", 662), Normal, 10), (Eol, Normal, 0)]
|
||||||
[(Address(59), Normal, 5), (Spacing(4), Normal, 0), (Opcode("nop", 465), Normal, 10), (Eol, Normal, 0)]
|
[(Address(59), Normal, 5), (Spacing(4), Normal, 0), (Opcode("nop", 465), Normal, 10), (Eol, Normal, 0)]
|
||||||
[(Address(60), Normal, 5), (Basic(" ~> "), Rotating(1), 0), (Opcode(".dword", 65534), Normal, 10), (Symbol(Symbol { name: "$L272", demangled_name: None, address: 17, size: 0, kind: Unknown, section: Some(1), flags: FlagSet(Local), align: None, virtual_address: None }), Bright, 0), (Basic(" ~>"), Rotating(2), 0), (Eol, Normal, 0)]
|
[(Address(60), Normal, 5), (Basic(" ~> "), Rotating(1), 0), (Opcode(".dword", 65534), Normal, 10), (BranchDest(17), Normal, 0), (Basic(" ~>"), Rotating(2), 0), (Eol, Normal, 0)]
|
||||||
[(Address(64), Normal, 5), (Spacing(4), Normal, 0), (Opcode(".dword", 65534), Normal, 10), (Symbol(Symbol { name: "$L273", demangled_name: None, address: 23, size: 0, kind: Unknown, section: Some(1), flags: FlagSet(Local), align: None, virtual_address: None }), Bright, 0), (Basic(" ~>"), Rotating(3), 0), (Eol, Normal, 0)]
|
[(Address(64), Normal, 5), (Spacing(4), Normal, 0), (Opcode(".dword", 65534), Normal, 10), (BranchDest(23), Normal, 0), (Basic(" ~>"), Rotating(3), 0), (Eol, Normal, 0)]
|
||||||
[(Address(68), Normal, 5), (Spacing(4), Normal, 0), (Opcode(".dword", 65534), Normal, 10), (Symbol(Symbol { name: "$L274", demangled_name: None, address: 29, size: 0, kind: Unknown, section: Some(1), flags: FlagSet(Local), align: None, virtual_address: None }), Bright, 0), (Basic(" ~>"), Rotating(4), 0), (Eol, Normal, 0)]
|
[(Address(68), Normal, 5), (Spacing(4), Normal, 0), (Opcode(".dword", 65534), Normal, 10), (BranchDest(29), Normal, 0), (Basic(" ~>"), Rotating(4), 0), (Eol, Normal, 0)]
|
||||||
[(Address(72), Normal, 5), (Spacing(4), Normal, 0), (Opcode(".dword", 65534), Normal, 10), (Symbol(Symbol { name: "$L275", demangled_name: None, address: 35, size: 0, kind: Unknown, section: Some(1), flags: FlagSet(Local), align: None, virtual_address: None }), Bright, 0), (Basic(" ~>"), Rotating(5), 0), (Eol, Normal, 0)]
|
[(Address(72), Normal, 5), (Spacing(4), Normal, 0), (Opcode(".dword", 65534), Normal, 10), (BranchDest(35), Normal, 0), (Basic(" ~>"), Rotating(5), 0), (Eol, Normal, 0)]
|
||||||
[(Address(76), Normal, 5), (Spacing(4), Normal, 0), (Opcode(".dword", 65534), Normal, 10), (Symbol(Symbol { name: "$L276", demangled_name: None, address: 41, size: 0, kind: Unknown, section: Some(1), flags: FlagSet(Local), align: None, virtual_address: None }), Bright, 0), (Basic(" ~>"), Rotating(6), 0), (Eol, Normal, 0)]
|
[(Address(76), Normal, 5), (Spacing(4), Normal, 0), (Opcode(".dword", 65534), Normal, 10), (BranchDest(41), Normal, 0), (Basic(" ~>"), Rotating(6), 0), (Eol, Normal, 0)]
|
||||||
[(Address(80), Normal, 5), (Spacing(4), Normal, 0), (Opcode(".dword", 65534), Normal, 10), (Symbol(Symbol { name: "$L277", demangled_name: None, address: 47, size: 0, kind: Unknown, section: Some(1), flags: FlagSet(Local), align: None, virtual_address: None }), Bright, 0), (Basic(" ~>"), Rotating(7), 0), (Eol, Normal, 0)]
|
[(Address(80), Normal, 5), (Spacing(4), Normal, 0), (Opcode(".dword", 65534), Normal, 10), (BranchDest(47), Normal, 0), (Basic(" ~>"), Rotating(7), 0), (Eol, Normal, 0)]
|
||||||
[(Address(84), Normal, 5), (Spacing(4), Normal, 0), (Opcode(".dword", 65534), Normal, 10), (Symbol(Symbol { name: "$L278", demangled_name: None, address: 53, size: 0, kind: Unknown, section: Some(1), flags: FlagSet(Local), align: None, virtual_address: None }), Bright, 0), (Basic(" ~>"), Rotating(8), 0), (Eol, Normal, 0)]
|
[(Address(84), Normal, 5), (Spacing(4), Normal, 0), (Opcode(".dword", 65534), Normal, 10), (BranchDest(53), Normal, 0), (Basic(" ~>"), Rotating(8), 0), (Eol, Normal, 0)]
|
||||||
[(Address(88), Normal, 5), (Spacing(4), Normal, 0), (Opcode("nop", 465), Normal, 10), (Eol, Normal, 0)]
|
[(Address(88), Normal, 5), (Spacing(4), Normal, 0), (Opcode("nop", 465), Normal, 10), (Eol, Normal, 0)]
|
||||||
[(Address(89), Normal, 5), (Spacing(4), Normal, 0), (Opcode("nop", 465), Normal, 10), (Eol, Normal, 0)]
|
[(Address(89), Normal, 5), (Spacing(4), Normal, 0), (Opcode("nop", 465), Normal, 10), (Eol, Normal, 0)]
|
||||||
[(Address(90), Normal, 5), (Spacing(4), Normal, 0), (Opcode("nop", 465), Normal, 10), (Eol, Normal, 0)]
|
[(Address(90), Normal, 5), (Spacing(4), Normal, 0), (Opcode("nop", 465), Normal, 10), (Eol, Normal, 0)]
|
||||||
|
|||||||
@@ -311,4 +311,5 @@ Object {
|
|||||||
split_meta: None,
|
split_meta: None,
|
||||||
path: None,
|
path: None,
|
||||||
timestamp: None,
|
timestamp: None,
|
||||||
|
flow_analysis_results: {},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,164 @@
|
|||||||
|
---
|
||||||
|
source: objdiff-core/tests/arch_x86.rs
|
||||||
|
expression: obj
|
||||||
|
---
|
||||||
|
Object {
|
||||||
|
arch: ArchX86 {
|
||||||
|
arch: X86,
|
||||||
|
endianness: Little,
|
||||||
|
},
|
||||||
|
endianness: Little,
|
||||||
|
symbols: [
|
||||||
|
Symbol {
|
||||||
|
name: "42b830_convertToUppercaseShiftJIS.obj",
|
||||||
|
demangled_name: None,
|
||||||
|
address: 0,
|
||||||
|
size: 0,
|
||||||
|
kind: Unknown,
|
||||||
|
section: None,
|
||||||
|
flags: FlagSet(Local),
|
||||||
|
align: None,
|
||||||
|
virtual_address: None,
|
||||||
|
},
|
||||||
|
Symbol {
|
||||||
|
name: "[.text]",
|
||||||
|
demangled_name: None,
|
||||||
|
address: 0,
|
||||||
|
size: 0,
|
||||||
|
kind: Section,
|
||||||
|
section: Some(
|
||||||
|
0,
|
||||||
|
),
|
||||||
|
flags: FlagSet(Local),
|
||||||
|
align: None,
|
||||||
|
virtual_address: None,
|
||||||
|
},
|
||||||
|
Symbol {
|
||||||
|
name: "LAB_0042b850",
|
||||||
|
demangled_name: None,
|
||||||
|
address: 32,
|
||||||
|
size: 0,
|
||||||
|
kind: Object,
|
||||||
|
section: Some(
|
||||||
|
0,
|
||||||
|
),
|
||||||
|
flags: FlagSet(Local),
|
||||||
|
align: None,
|
||||||
|
virtual_address: None,
|
||||||
|
},
|
||||||
|
Symbol {
|
||||||
|
name: "LAB_0042b883",
|
||||||
|
demangled_name: None,
|
||||||
|
address: 83,
|
||||||
|
size: 0,
|
||||||
|
kind: Object,
|
||||||
|
section: Some(
|
||||||
|
0,
|
||||||
|
),
|
||||||
|
flags: FlagSet(Local),
|
||||||
|
align: None,
|
||||||
|
virtual_address: None,
|
||||||
|
},
|
||||||
|
Symbol {
|
||||||
|
name: "LAB_0042b87c",
|
||||||
|
demangled_name: None,
|
||||||
|
address: 76,
|
||||||
|
size: 0,
|
||||||
|
kind: Object,
|
||||||
|
section: Some(
|
||||||
|
0,
|
||||||
|
),
|
||||||
|
flags: FlagSet(Local),
|
||||||
|
align: None,
|
||||||
|
virtual_address: None,
|
||||||
|
},
|
||||||
|
Symbol {
|
||||||
|
name: "LAB_0042b884",
|
||||||
|
demangled_name: None,
|
||||||
|
address: 84,
|
||||||
|
size: 0,
|
||||||
|
kind: Object,
|
||||||
|
section: Some(
|
||||||
|
0,
|
||||||
|
),
|
||||||
|
flags: FlagSet(Local),
|
||||||
|
align: None,
|
||||||
|
virtual_address: None,
|
||||||
|
},
|
||||||
|
Symbol {
|
||||||
|
name: "LAB_0042b889",
|
||||||
|
demangled_name: None,
|
||||||
|
address: 89,
|
||||||
|
size: 0,
|
||||||
|
kind: Object,
|
||||||
|
section: Some(
|
||||||
|
0,
|
||||||
|
),
|
||||||
|
flags: FlagSet(Local),
|
||||||
|
align: None,
|
||||||
|
virtual_address: None,
|
||||||
|
},
|
||||||
|
Symbol {
|
||||||
|
name: "LAB_0042b845",
|
||||||
|
demangled_name: None,
|
||||||
|
address: 21,
|
||||||
|
size: 0,
|
||||||
|
kind: Object,
|
||||||
|
section: Some(
|
||||||
|
0,
|
||||||
|
),
|
||||||
|
flags: FlagSet(Local),
|
||||||
|
align: None,
|
||||||
|
virtual_address: None,
|
||||||
|
},
|
||||||
|
Symbol {
|
||||||
|
name: "LAB_0042b869",
|
||||||
|
demangled_name: None,
|
||||||
|
address: 57,
|
||||||
|
size: 0,
|
||||||
|
kind: Object,
|
||||||
|
section: Some(
|
||||||
|
0,
|
||||||
|
),
|
||||||
|
flags: FlagSet(Local),
|
||||||
|
align: None,
|
||||||
|
virtual_address: None,
|
||||||
|
},
|
||||||
|
Symbol {
|
||||||
|
name: "ConvertToUppercaseShiftJIS",
|
||||||
|
demangled_name: None,
|
||||||
|
address: 0,
|
||||||
|
size: 92,
|
||||||
|
kind: Function,
|
||||||
|
section: Some(
|
||||||
|
0,
|
||||||
|
),
|
||||||
|
flags: FlagSet(Global | SizeInferred),
|
||||||
|
align: None,
|
||||||
|
virtual_address: None,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
sections: [
|
||||||
|
Section {
|
||||||
|
id: ".text-0",
|
||||||
|
name: ".text",
|
||||||
|
address: 0,
|
||||||
|
size: 92,
|
||||||
|
kind: Code,
|
||||||
|
data: SectionData(
|
||||||
|
92,
|
||||||
|
),
|
||||||
|
flags: FlagSet(),
|
||||||
|
align: Some(
|
||||||
|
16,
|
||||||
|
),
|
||||||
|
relocations: [],
|
||||||
|
line_info: {},
|
||||||
|
virtual_address: None,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
split_meta: None,
|
||||||
|
path: None,
|
||||||
|
timestamp: None,
|
||||||
|
flow_analysis_results: {},
|
||||||
|
}
|
||||||
@@ -46,7 +46,7 @@ rlwinmdec = "1.1"
|
|||||||
ron = "0.8"
|
ron = "0.8"
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
time = { version = "0.3", features = ["formatting", "local-offset"] }
|
time = { version = "0.3", features = ["formatting", "local-offset"] }
|
||||||
typed-path = "0.10"
|
typed-path = "0.11"
|
||||||
winit = { version = "0.30", features = ["wayland-csd-adwaita"] }
|
winit = { version = "0.30", features = ["wayland-csd-adwaita"] }
|
||||||
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
|
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
|
||||||
|
|
||||||
|
|||||||
@@ -23,6 +23,8 @@ pub struct Appearance {
|
|||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
pub highlight_color: Color32, // WHITE
|
pub highlight_color: Color32, // WHITE
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
|
pub dataflow_color: Color32, //
|
||||||
|
#[serde(skip)]
|
||||||
pub replace_color: Color32, // LIGHT_BLUE
|
pub replace_color: Color32, // LIGHT_BLUE
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
pub insert_color: Color32, // GREEN
|
pub insert_color: Color32, // GREEN
|
||||||
@@ -61,6 +63,7 @@ impl Default for Appearance {
|
|||||||
emphasized_text_color: Color32::LIGHT_GRAY,
|
emphasized_text_color: Color32::LIGHT_GRAY,
|
||||||
deemphasized_text_color: Color32::DARK_GRAY,
|
deemphasized_text_color: Color32::DARK_GRAY,
|
||||||
highlight_color: Color32::WHITE,
|
highlight_color: Color32::WHITE,
|
||||||
|
dataflow_color: Color32::from_rgb(0, 128, 128),
|
||||||
replace_color: Color32::LIGHT_BLUE,
|
replace_color: Color32::LIGHT_BLUE,
|
||||||
insert_color: Color32::GREEN,
|
insert_color: Color32::GREEN,
|
||||||
delete_color: Color32::from_rgb(200, 40, 41),
|
delete_color: Color32::from_rgb(200, 40, 41),
|
||||||
@@ -104,6 +107,7 @@ impl Appearance {
|
|||||||
self.emphasized_text_color = Color32::LIGHT_GRAY;
|
self.emphasized_text_color = Color32::LIGHT_GRAY;
|
||||||
self.deemphasized_text_color = Color32::DARK_GRAY;
|
self.deemphasized_text_color = Color32::DARK_GRAY;
|
||||||
self.highlight_color = Color32::WHITE;
|
self.highlight_color = Color32::WHITE;
|
||||||
|
self.dataflow_color = Color32::from_rgb(0, 128, 128);
|
||||||
self.replace_color = Color32::LIGHT_BLUE;
|
self.replace_color = Color32::LIGHT_BLUE;
|
||||||
self.insert_color = Color32::GREEN;
|
self.insert_color = Color32::GREEN;
|
||||||
self.delete_color = Color32::from_rgb(200, 40, 41);
|
self.delete_color = Color32::from_rgb(200, 40, 41);
|
||||||
@@ -114,6 +118,7 @@ impl Appearance {
|
|||||||
self.emphasized_text_color = Color32::DARK_GRAY;
|
self.emphasized_text_color = Color32::DARK_GRAY;
|
||||||
self.deemphasized_text_color = Color32::LIGHT_GRAY;
|
self.deemphasized_text_color = Color32::LIGHT_GRAY;
|
||||||
self.highlight_color = Color32::BLACK;
|
self.highlight_color = Color32::BLACK;
|
||||||
|
self.dataflow_color = Color32::from_rgb(0, 128, 128);
|
||||||
self.replace_color = Color32::DARK_BLUE;
|
self.replace_color = Color32::DARK_BLUE;
|
||||||
self.insert_color = Color32::DARK_GREEN;
|
self.insert_color = Color32::DARK_GREEN;
|
||||||
self.delete_color = Color32::from_rgb(200, 40, 41);
|
self.delete_color = Color32::from_rgb(200, 40, 41);
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -49,7 +49,9 @@ impl<'a> DiffColumnContext<'a> {
|
|||||||
let selected_symbol = match view {
|
let selected_symbol = match view {
|
||||||
View::SymbolDiff => None,
|
View::SymbolDiff => None,
|
||||||
View::FunctionDiff | View::ExtabDiff => match (obj, selected_symbol) {
|
View::FunctionDiff | View::ExtabDiff => match (obj, selected_symbol) {
|
||||||
(Some(obj), Some(s)) => find_symbol(&obj.0, s).map(SelectedSymbol::Symbol),
|
(Some(obj), Some(s)) => {
|
||||||
|
obj.0.symbol_by_name(&s.symbol_name).map(SelectedSymbol::Symbol)
|
||||||
|
}
|
||||||
_ => None,
|
_ => None,
|
||||||
},
|
},
|
||||||
View::DataDiff => match (obj, selected_symbol) {
|
View::DataDiff => match (obj, selected_symbol) {
|
||||||
@@ -279,6 +281,24 @@ pub fn diff_view_ui(
|
|||||||
})
|
})
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Only need to check the first Object. Technically the first could not have a flow analysis
|
||||||
|
// result while the second does but we don't want to waste space on two separate checkboxes.
|
||||||
|
if state.current_view == View::FunctionDiff
|
||||||
|
&& result
|
||||||
|
.first_obj
|
||||||
|
.as_ref()
|
||||||
|
.is_some_and(|(first, _)| first.has_flow_analysis_result())
|
||||||
|
{
|
||||||
|
let mut value = diff_config.show_data_flow;
|
||||||
|
if ui
|
||||||
|
.checkbox(&mut value, "Show data flow")
|
||||||
|
.on_hover_text("Show data flow analysis results in place of register names")
|
||||||
|
.clicked()
|
||||||
|
{
|
||||||
|
ret = Some(DiffViewAction::SetShowDataFlow(value));
|
||||||
|
}
|
||||||
|
}
|
||||||
} else if column == 1 {
|
} else if column == 1 {
|
||||||
// Right column
|
// Right column
|
||||||
|
|
||||||
@@ -497,6 +517,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 =
|
||||||
@@ -779,10 +800,6 @@ fn missing_obj_ui(ui: &mut Ui, appearance: &Appearance) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_symbol(obj: &Object, selected_symbol: &SymbolRefByName) -> Option<usize> {
|
|
||||||
obj.symbols.iter().position(|symbol| symbol.name == selected_symbol.symbol_name)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn find_section(obj: &Object, section_name: &str) -> Option<usize> {
|
fn find_section(obj: &Object, section_name: &str) -> Option<usize> {
|
||||||
obj.sections.iter().position(|section| section.name == section_name)
|
obj.sections.iter().position(|section| section.name == section_name)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -174,6 +174,7 @@ fn diff_text_ui(
|
|||||||
DiffTextColor::Normal => appearance.text_color,
|
DiffTextColor::Normal => appearance.text_color,
|
||||||
DiffTextColor::Dim => appearance.deemphasized_text_color,
|
DiffTextColor::Dim => appearance.deemphasized_text_color,
|
||||||
DiffTextColor::Bright => appearance.emphasized_text_color,
|
DiffTextColor::Bright => appearance.emphasized_text_color,
|
||||||
|
DiffTextColor::DataFlow => appearance.dataflow_color,
|
||||||
DiffTextColor::Replace => appearance.replace_color,
|
DiffTextColor::Replace => appearance.replace_color,
|
||||||
DiffTextColor::Delete => appearance.delete_color,
|
DiffTextColor::Delete => appearance.delete_color,
|
||||||
DiffTextColor::Insert => appearance.insert_color,
|
DiffTextColor::Insert => appearance.insert_color,
|
||||||
|
|||||||
@@ -79,6 +79,8 @@ pub enum DiffViewAction {
|
|||||||
SetMapping(usize, usize),
|
SetMapping(usize, usize),
|
||||||
/// Set the show_mapped_symbols flag
|
/// Set the show_mapped_symbols flag
|
||||||
SetShowMappedSymbols(bool),
|
SetShowMappedSymbols(bool),
|
||||||
|
/// Set the show_data_flow flag
|
||||||
|
SetShowDataFlow(bool),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Default, Eq, PartialEq)]
|
#[derive(Debug, Clone, Default, Eq, PartialEq)]
|
||||||
@@ -350,6 +352,12 @@ impl DiffViewState {
|
|||||||
DiffViewAction::SetShowMappedSymbols(value) => {
|
DiffViewAction::SetShowMappedSymbols(value) => {
|
||||||
self.symbol_state.show_mapped_symbols = value;
|
self.symbol_state.show_mapped_symbols = value;
|
||||||
}
|
}
|
||||||
|
DiffViewAction::SetShowDataFlow(value) => {
|
||||||
|
let Ok(mut state) = state.write() else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
state.config.diff_obj_config.show_data_flow = value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,13 +28,13 @@ xxhash-rust = { version = "0.8", default-features = false, features = ["xxh3"] }
|
|||||||
[dependencies.objdiff-core]
|
[dependencies.objdiff-core]
|
||||||
path = "../objdiff-core"
|
path = "../objdiff-core"
|
||||||
default-features = false
|
default-features = false
|
||||||
features = ["arm", "arm64", "mips", "ppc", "x86", "dwarf"]
|
features = ["arm", "arm64", "mips", "ppc", "superh", "x86", "dwarf"]
|
||||||
|
|
||||||
[target.'cfg(target_family = "wasm")'.dependencies]
|
[target.'cfg(target_family = "wasm")'.dependencies]
|
||||||
talc = { version = "4.4", default-features = false, features = ["lock_api"] }
|
talc = { version = "4.4", default-features = false, features = ["lock_api"] }
|
||||||
|
|
||||||
[target.'cfg(target_os = "wasi")'.dependencies]
|
[target.'cfg(target_os = "wasi")'.dependencies]
|
||||||
wit-bindgen = { version = "0.41", default-features = false, features = ["macros"] }
|
wit-bindgen = { version = "0.42", default-features = false, features = ["macros"] }
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
wit-deps = "0.5"
|
wit-deps = "0.5"
|
||||||
|
|||||||
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.6",
|
"version": "3.0.0-beta.10",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "objdiff-wasm",
|
"name": "objdiff-wasm",
|
||||||
"version": "3.0.0-beta.6",
|
"version": "3.0.0-beta.10",
|
||||||
"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.6",
|
"version": "3.0.0-beta.10",
|
||||||
"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(),
|
||||||
@@ -404,6 +401,7 @@ impl From<diff::display::DiffTextColor> for DiffTextColor {
|
|||||||
diff::display::DiffTextColor::Replace => DiffTextColor::Replace,
|
diff::display::DiffTextColor::Replace => DiffTextColor::Replace,
|
||||||
diff::display::DiffTextColor::Delete => DiffTextColor::Delete,
|
diff::display::DiffTextColor::Delete => DiffTextColor::Delete,
|
||||||
diff::display::DiffTextColor::Insert => DiffTextColor::Insert,
|
diff::display::DiffTextColor::Insert => DiffTextColor::Insert,
|
||||||
|
diff::display::DiffTextColor::DataFlow => DiffTextColor::DataFlow,
|
||||||
diff::display::DiffTextColor::Rotating(v) => DiffTextColor::Rotating(v),
|
diff::display::DiffTextColor::Rotating(v) => DiffTextColor::Rotating(v),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -497,20 +495,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 +614,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 +644,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>>,
|
||||||
@@ -194,6 +201,7 @@ interface display {
|
|||||||
dim,
|
dim,
|
||||||
bright,
|
bright,
|
||||||
replace,
|
replace,
|
||||||
|
data-flow,
|
||||||
delete,
|
delete,
|
||||||
insert,
|
insert,
|
||||||
rotating(u8),
|
rotating(u8),
|
||||||
@@ -232,36 +240,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