Skip to content

Commit 3f82c1a

Browse files
committed
objdiff-core API adjustments
- Allows using process_code without constructing an ObjInfo - Allows creating an arch without having to provide an object Used in decomp-toolkit
1 parent 0ea6242 commit 3f82c1a

File tree

6 files changed

+71
-67
lines changed

6 files changed

+71
-67
lines changed

objdiff-core/src/arch/mips.rs

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::{borrow::Cow, sync::Mutex};
1+
use std::{borrow::Cow, collections::BTreeMap, sync::Mutex};
22

33
use anyhow::{anyhow, bail, Result};
44
use object::{elf, Endian, Endianness, File, FileFlags, Object, Relocation, RelocationFlags};
@@ -7,7 +7,7 @@ use rabbitizer::{config, Abi, InstrCategory, Instruction, OperandType};
77
use crate::{
88
arch::{ObjArch, ProcessCodeResult},
99
diff::{DiffObjConfig, MipsAbi, MipsInstrCategory},
10-
obj::{ObjInfo, ObjIns, ObjInsArg, ObjInsArgValue, ObjReloc, ObjSection, SymbolRef},
10+
obj::{ObjIns, ObjInsArg, ObjInsArgValue, ObjReloc, ObjSection},
1111
};
1212

1313
static RABBITIZER_MUTEX: Mutex<()> = Mutex::new(());
@@ -57,15 +57,12 @@ impl ObjArchMips {
5757
impl ObjArch for ObjArchMips {
5858
fn process_code(
5959
&self,
60-
obj: &ObjInfo,
61-
symbol_ref: SymbolRef,
60+
address: u64,
61+
code: &[u8],
62+
relocations: &[ObjReloc],
63+
line_info: &BTreeMap<u64, u64>,
6264
config: &DiffObjConfig,
6365
) -> Result<ProcessCodeResult> {
64-
let (section, symbol) = obj.section_symbol(symbol_ref);
65-
let section = section.ok_or_else(|| anyhow!("Code symbol section not found"))?;
66-
let code = &section.data
67-
[symbol.section_address as usize..(symbol.section_address + symbol.size) as usize];
68-
6966
let _guard = RABBITIZER_MUTEX.lock().map_err(|e| anyhow!("Failed to lock mutex: {e}"))?;
7067
configure_rabbitizer(match config.mips_abi {
7168
MipsAbi::Auto => self.abi,
@@ -82,14 +79,14 @@ impl ObjArch for ObjArchMips {
8279
MipsInstrCategory::R5900 => InstrCategory::R5900,
8380
};
8481

85-
let start_address = symbol.address;
86-
let end_address = symbol.address + symbol.size;
82+
let start_address = address;
83+
let end_address = address + code.len() as u64;
8784
let ins_count = code.len() / 4;
8885
let mut ops = Vec::<u16>::with_capacity(ins_count);
8986
let mut insts = Vec::<ObjIns>::with_capacity(ins_count);
9087
let mut cur_addr = start_address as u32;
9188
for chunk in code.chunks_exact(4) {
92-
let reloc = section.relocations.iter().find(|r| (r.address as u32 & !3) == cur_addr);
89+
let reloc = relocations.iter().find(|r| (r.address as u32 & !3) == cur_addr);
9390
let code = self.endianness.read_u32_bytes(chunk.try_into()?);
9491
let instruction = Instruction::new(code, cur_addr, instr_category);
9592

@@ -155,7 +152,7 @@ impl ObjArch for ObjArchMips {
155152
}
156153
}
157154
}
158-
let line = section.line_info.range(..=cur_addr as u64).last().map(|(_, &b)| b);
155+
let line = line_info.range(..=cur_addr as u64).last().map(|(_, &b)| b);
159156
insts.push(ObjIns {
160157
address: cur_addr as u64,
161158
size: 4,

objdiff-core/src/arch/mod.rs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,27 @@
1-
use std::borrow::Cow;
1+
use std::{borrow::Cow, collections::BTreeMap};
22

33
use anyhow::{bail, Result};
44
use object::{Architecture, Object, Relocation, RelocationFlags};
55

66
use crate::{
77
diff::DiffObjConfig,
8-
obj::{ObjInfo, ObjIns, ObjSection, SymbolRef},
8+
obj::{ObjIns, ObjReloc, ObjSection},
99
};
1010

1111
#[cfg(feature = "mips")]
12-
mod mips;
12+
pub mod mips;
1313
#[cfg(feature = "ppc")]
14-
mod ppc;
14+
pub mod ppc;
1515
#[cfg(feature = "x86")]
16-
mod x86;
16+
pub mod x86;
1717

1818
pub trait ObjArch: Send + Sync {
1919
fn process_code(
2020
&self,
21-
obj: &ObjInfo,
22-
symbol_ref: SymbolRef,
21+
address: u64,
22+
code: &[u8],
23+
relocations: &[ObjReloc],
24+
line_info: &BTreeMap<u64, u64>,
2325
config: &DiffObjConfig,
2426
) -> Result<ProcessCodeResult>;
2527

objdiff-core/src/arch/ppc.rs

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
use std::borrow::Cow;
1+
use std::{borrow::Cow, collections::BTreeMap};
22

3-
use anyhow::{anyhow, bail, Result};
3+
use anyhow::{bail, Result};
44
use object::{elf, File, Relocation, RelocationFlags};
55
use ppc750cl::{Argument, InsIter, GPR};
66

77
use crate::{
88
arch::{ObjArch, ProcessCodeResult},
99
diff::DiffObjConfig,
10-
obj::{ObjInfo, ObjIns, ObjInsArg, ObjInsArgValue, ObjReloc, ObjSection, SymbolRef},
10+
obj::{ObjIns, ObjInsArg, ObjInsArgValue, ObjReloc, ObjSection},
1111
};
1212

1313
// Relative relocation, can be Simm, Offset or BranchDest
@@ -31,20 +31,17 @@ impl ObjArchPpc {
3131
impl ObjArch for ObjArchPpc {
3232
fn process_code(
3333
&self,
34-
obj: &ObjInfo,
35-
symbol_ref: SymbolRef,
34+
address: u64,
35+
code: &[u8],
36+
relocations: &[ObjReloc],
37+
line_info: &BTreeMap<u64, u64>,
3638
config: &DiffObjConfig,
3739
) -> Result<ProcessCodeResult> {
38-
let (section, symbol) = obj.section_symbol(symbol_ref);
39-
let section = section.ok_or_else(|| anyhow!("Code symbol section not found"))?;
40-
let code = &section.data
41-
[symbol.section_address as usize..(symbol.section_address + symbol.size) as usize];
42-
4340
let ins_count = code.len() / 4;
4441
let mut ops = Vec::<u16>::with_capacity(ins_count);
4542
let mut insts = Vec::<ObjIns>::with_capacity(ins_count);
46-
for (cur_addr, mut ins) in InsIter::new(code, symbol.address as u32) {
47-
let reloc = section.relocations.iter().find(|r| (r.address as u32 & !3) == cur_addr);
43+
for (cur_addr, mut ins) in InsIter::new(code, address as u32) {
44+
let reloc = relocations.iter().find(|r| (r.address as u32 & !3) == cur_addr);
4845
if let Some(reloc) = reloc {
4946
// Zero out relocations
5047
ins.code = match reloc.flags {
@@ -133,7 +130,7 @@ impl ObjArch for ObjArchPpc {
133130
}
134131

135132
ops.push(ins.op as u16);
136-
let line = section.line_info.range(..=cur_addr as u64).last().map(|(_, &b)| b);
133+
let line = line_info.range(..=cur_addr as u64).last().map(|(_, &b)| b);
137134
insts.push(ObjIns {
138135
address: cur_addr as u64,
139136
size: 4,

objdiff-core/src/arch/x86.rs

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::borrow::Cow;
1+
use std::{borrow::Cow, collections::BTreeMap};
22

33
use anyhow::{anyhow, bail, ensure, Result};
44
use iced_x86::{
@@ -11,7 +11,7 @@ use object::{pe, Endian, Endianness, File, Object, Relocation, RelocationFlags};
1111
use crate::{
1212
arch::{ObjArch, ProcessCodeResult},
1313
diff::{DiffObjConfig, X86Formatter},
14-
obj::{ObjInfo, ObjIns, ObjInsArg, ObjInsArgValue, ObjSection, SymbolRef},
14+
obj::{ObjIns, ObjInsArg, ObjInsArgValue, ObjReloc, ObjSection},
1515
};
1616

1717
pub struct ObjArchX86 {
@@ -28,17 +28,14 @@ impl ObjArchX86 {
2828
impl ObjArch for ObjArchX86 {
2929
fn process_code(
3030
&self,
31-
obj: &ObjInfo,
32-
symbol_ref: SymbolRef,
31+
address: u64,
32+
code: &[u8],
33+
relocations: &[ObjReloc],
34+
line_info: &BTreeMap<u64, u64>,
3335
config: &DiffObjConfig,
3436
) -> Result<ProcessCodeResult> {
35-
let (section, symbol) = obj.section_symbol(symbol_ref);
36-
let section = section.ok_or_else(|| anyhow!("Code symbol section not found"))?;
37-
let code = &section.data
38-
[symbol.section_address as usize..(symbol.section_address + symbol.size) as usize];
39-
4037
let mut result = ProcessCodeResult { ops: Vec::new(), insts: Vec::new() };
41-
let mut decoder = Decoder::with_ip(self.bits, code, symbol.address, DecoderOptions::NONE);
38+
let mut decoder = Decoder::with_ip(self.bits, code, address, DecoderOptions::NONE);
4239
let mut formatter: Box<dyn Formatter> = match config.x86_formatter {
4340
X86Formatter::Intel => Box::new(IntelFormatter::new()),
4441
X86Formatter::Gas => Box::new(GasFormatter::new()),
@@ -70,11 +67,10 @@ impl ObjArch for ObjArchX86 {
7067

7168
let address = instruction.ip();
7269
let op = instruction.mnemonic() as u16;
73-
let reloc = section
74-
.relocations
70+
let reloc = relocations
7571
.iter()
7672
.find(|r| r.address >= address && r.address < address + instruction.len() as u64);
77-
let line = section.line_info.range(..=address).last().map(|(_, &b)| b);
73+
let line = line_info.range(..=address).last().map(|(_, &b)| b);
7874
output.ins = ObjIns {
7975
address,
8076
size: instruction.len() as u8,

objdiff-core/src/diff/code.rs

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use std::{
44
time::{Duration, Instant},
55
};
66

7-
use anyhow::Result;
7+
use anyhow::{anyhow, Result};
88
use similar::{capture_diff_slices_deadline, Algorithm};
99

1010
use crate::{
@@ -16,34 +16,41 @@ use crate::{
1616
obj::{ObjInfo, ObjInsArg, ObjReloc, ObjSymbol, ObjSymbolFlags, SymbolRef},
1717
};
1818

19-
pub fn no_diff_code(
19+
pub fn process_code_symbol(
2020
obj: &ObjInfo,
2121
symbol_ref: SymbolRef,
2222
config: &DiffObjConfig,
23-
) -> Result<ObjSymbolDiff> {
24-
let out = obj.arch.process_code(obj, symbol_ref, config)?;
23+
) -> Result<ProcessCodeResult> {
24+
let (section, symbol) = obj.section_symbol(symbol_ref);
25+
let section = section.ok_or_else(|| anyhow!("Code symbol section not found"))?;
26+
let code = &section.data
27+
[symbol.section_address as usize..(symbol.section_address + symbol.size) as usize];
28+
obj.arch.process_code(symbol.address, code, &section.relocations, &section.line_info, config)
29+
}
2530

31+
pub fn no_diff_code(out: &ProcessCodeResult, symbol_ref: SymbolRef) -> Result<ObjSymbolDiff> {
2632
let mut diff = Vec::<ObjInsDiff>::new();
27-
for i in out.insts {
28-
diff.push(ObjInsDiff { ins: Some(i), kind: ObjInsDiffKind::None, ..Default::default() });
33+
for i in &out.insts {
34+
diff.push(ObjInsDiff {
35+
ins: Some(i.clone()),
36+
kind: ObjInsDiffKind::None,
37+
..Default::default()
38+
});
2939
}
3040
resolve_branches(&mut diff);
3141
Ok(ObjSymbolDiff { symbol_ref, diff_symbol: None, instructions: diff, match_percent: None })
3242
}
3343

3444
pub fn diff_code(
35-
left_obj: &ObjInfo,
36-
right_obj: &ObjInfo,
45+
left_out: &ProcessCodeResult,
46+
right_out: &ProcessCodeResult,
3747
left_symbol_ref: SymbolRef,
3848
right_symbol_ref: SymbolRef,
3949
config: &DiffObjConfig,
4050
) -> Result<(ObjSymbolDiff, ObjSymbolDiff)> {
41-
let left_out = left_obj.arch.process_code(left_obj, left_symbol_ref, config)?;
42-
let right_out = right_obj.arch.process_code(right_obj, right_symbol_ref, config)?;
43-
4451
let mut left_diff = Vec::<ObjInsDiff>::new();
4552
let mut right_diff = Vec::<ObjInsDiff>::new();
46-
diff_instructions(&mut left_diff, &mut right_diff, &left_out, &right_out)?;
53+
diff_instructions(&mut left_diff, &mut right_diff, left_out, right_out)?;
4754

4855
resolve_branches(&mut left_diff);
4956
resolve_branches(&mut right_diff);

objdiff-core/src/diff/mod.rs

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use anyhow::Result;
44

55
use crate::{
66
diff::{
7-
code::{diff_code, no_diff_code},
7+
code::{diff_code, no_diff_code, process_code_symbol},
88
data::{
99
diff_bss_section, diff_bss_symbol, diff_data_section, diff_data_symbol,
1010
diff_text_section, no_diff_symbol,
@@ -13,8 +13,8 @@ use crate::{
1313
obj::{ObjInfo, ObjIns, ObjSection, ObjSectionKind, ObjSymbol, SymbolRef},
1414
};
1515

16-
mod code;
17-
mod data;
16+
pub mod code;
17+
pub mod data;
1818
pub mod display;
1919

2020
#[derive(
@@ -321,9 +321,11 @@ pub fn diff_objs(
321321
let (right_obj, right_out) = right.as_mut().unwrap();
322322
match section_kind {
323323
ObjSectionKind::Code => {
324+
let left_code = process_code_symbol(left_obj, left_symbol_ref, config)?;
325+
let right_code = process_code_symbol(right_obj, right_symbol_ref, config)?;
324326
let (left_diff, right_diff) = diff_code(
325-
left_obj,
326-
right_obj,
327+
&left_code,
328+
&right_code,
327329
left_symbol_ref,
328330
right_symbol_ref,
329331
config,
@@ -333,9 +335,10 @@ pub fn diff_objs(
333335

334336
if let Some(prev_symbol_ref) = prev_symbol_ref {
335337
let (prev_obj, prev_out) = prev.as_mut().unwrap();
338+
let prev_code = process_code_symbol(prev_obj, prev_symbol_ref, config)?;
336339
let (_, prev_diff) = diff_code(
337-
right_obj,
338-
prev_obj,
340+
&right_code,
341+
&prev_code,
339342
right_symbol_ref,
340343
prev_symbol_ref,
341344
config,
@@ -369,8 +372,9 @@ pub fn diff_objs(
369372
let (left_obj, left_out) = left.as_mut().unwrap();
370373
match section_kind {
371374
ObjSectionKind::Code => {
375+
let code = process_code_symbol(left_obj, left_symbol_ref, config)?;
372376
*left_out.symbol_diff_mut(left_symbol_ref) =
373-
no_diff_code(left_obj, left_symbol_ref, config)?;
377+
no_diff_code(&code, left_symbol_ref)?;
374378
}
375379
ObjSectionKind::Data | ObjSectionKind::Bss => {
376380
*left_out.symbol_diff_mut(left_symbol_ref) =
@@ -382,8 +386,9 @@ pub fn diff_objs(
382386
let (right_obj, right_out) = right.as_mut().unwrap();
383387
match section_kind {
384388
ObjSectionKind::Code => {
389+
let code = process_code_symbol(right_obj, right_symbol_ref, config)?;
385390
*right_out.symbol_diff_mut(right_symbol_ref) =
386-
no_diff_code(right_obj, right_symbol_ref, config)?;
391+
no_diff_code(&code, right_symbol_ref)?;
387392
}
388393
ObjSectionKind::Data | ObjSectionKind::Bss => {
389394
*right_out.symbol_diff_mut(right_symbol_ref) =

0 commit comments

Comments
 (0)