Skip to content

Commit 9e57a66

Browse files
committed
Auto-detect MIPS ABI/category & add config
Under Diff Options -> Arch Settings, one can override the ABI/instruction category
1 parent e254af5 commit 9e57a66

File tree

9 files changed

+188
-34
lines changed

9 files changed

+188
-34
lines changed

Cargo.lock

Lines changed: 5 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

objdiff-cli/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "objdiff-cli"
3-
version = "2.0.0-alpha.1"
3+
version = "2.0.0-alpha.2"
44
edition = "2021"
55
rust-version = "1.70"
66
authors = ["Luke Street <[email protected]>"]

objdiff-cli/src/cmd/diff.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -821,8 +821,10 @@ impl FunctionDiffUi {
821821
.transpose()?;
822822
let config = diff::DiffObjConfig {
823823
relax_reloc_diffs: self.relax_reloc_diffs,
824-
space_between_args: true, // TODO
825-
x86_formatter: Default::default(), // TODO
824+
space_between_args: true, // TODO
825+
x86_formatter: Default::default(), // TODO
826+
mips_abi: Default::default(), // TODO
827+
mips_instr_category: Default::default(), // TODO
826828
};
827829
let result = diff::diff_objs(&config, target.as_ref(), base.as_ref(), prev.as_ref())?;
828830

objdiff-core/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "objdiff-core"
3-
version = "2.0.0-alpha.1"
3+
version = "2.0.0-alpha.2"
44
edition = "2021"
55
rust-version = "1.70"
66
authors = ["Luke Street <[email protected]>"]
@@ -31,6 +31,7 @@ num-traits = "0.2.18"
3131
object = { version = "0.35.0", features = ["read_core", "std", "elf", "pe"], default-features = false }
3232
serde = { version = "1", features = ["derive"] }
3333
similar = { version = "2.5.0", default-features = false }
34+
strum = { version = "0.26.2", features = ["derive"] }
3435

3536
# config
3637
globset = { version = "0.4.14", features = ["serde1"], optional = true }

objdiff-core/src/arch/mips.rs

Lines changed: 51 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,56 @@
1-
use std::borrow::Cow;
1+
use std::{borrow::Cow, sync::Mutex};
22

33
use anyhow::{anyhow, bail, Result};
4-
use object::{elf, Endian, Endianness, File, Object, Relocation, RelocationFlags};
4+
use object::{elf, Endian, Endianness, File, FileFlags, Object, Relocation, RelocationFlags};
55
use rabbitizer::{config, Abi, InstrCategory, Instruction, OperandType};
66

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

13-
fn configure_rabbitizer() {
13+
static RABBITIZER_MUTEX: Mutex<()> = Mutex::new(());
14+
15+
fn configure_rabbitizer(abi: Abi) {
1416
unsafe {
15-
config::RabbitizerConfig_Cfg.reg_names.fpr_abi_names = Abi::O32;
17+
config::RabbitizerConfig_Cfg.reg_names.fpr_abi_names = abi;
1618
}
1719
}
1820

1921
pub struct ObjArchMips {
2022
pub endianness: Endianness,
23+
pub abi: Abi,
24+
pub instr_category: InstrCategory,
2125
}
2226

27+
const EF_MIPS_ABI: u32 = 0x0000F000;
28+
const EF_MIPS_MACH: u32 = 0x00FF0000;
29+
30+
const E_MIPS_MACH_ALLEGREX: u32 = 0x00840000;
31+
const E_MIPS_MACH_5900: u32 = 0x00920000;
32+
2333
impl ObjArchMips {
2434
pub fn new(object: &File) -> Result<Self> {
25-
configure_rabbitizer();
26-
Ok(Self { endianness: object.endianness() })
35+
let mut abi = Abi::NUMERIC;
36+
let mut instr_category = InstrCategory::CPU;
37+
match object.flags() {
38+
FileFlags::None => {}
39+
FileFlags::Elf { e_flags, .. } => {
40+
abi = match e_flags & EF_MIPS_ABI {
41+
elf::EF_MIPS_ABI_O32 => Abi::O32,
42+
elf::EF_MIPS_ABI_EABI32 | elf::EF_MIPS_ABI_EABI64 => Abi::N32,
43+
_ => Abi::NUMERIC,
44+
};
45+
instr_category = match e_flags & EF_MIPS_MACH {
46+
E_MIPS_MACH_ALLEGREX => InstrCategory::R4000ALLEGREX,
47+
E_MIPS_MACH_5900 => InstrCategory::R5900,
48+
_ => InstrCategory::CPU,
49+
};
50+
}
51+
_ => bail!("Unsupported MIPS file flags"),
52+
}
53+
Ok(Self { endianness: object.endianness(), abi, instr_category })
2754
}
2855
}
2956

@@ -39,6 +66,22 @@ impl ObjArch for ObjArchMips {
3966
let code = &section.data
4067
[symbol.section_address as usize..(symbol.section_address + symbol.size) as usize];
4168

69+
let _guard = RABBITIZER_MUTEX.lock().map_err(|e| anyhow!("Failed to lock mutex: {e}"))?;
70+
configure_rabbitizer(match config.mips_abi {
71+
MipsAbi::Auto => self.abi,
72+
MipsAbi::O32 => Abi::O32,
73+
MipsAbi::N32 => Abi::N32,
74+
MipsAbi::N64 => Abi::N64,
75+
});
76+
let instr_category = match config.mips_instr_category {
77+
MipsInstrCategory::Auto => self.instr_category,
78+
MipsInstrCategory::Cpu => InstrCategory::CPU,
79+
MipsInstrCategory::Rsp => InstrCategory::RSP,
80+
MipsInstrCategory::R3000Gte => InstrCategory::R3000GTE,
81+
MipsInstrCategory::R4000Allegrex => InstrCategory::R4000ALLEGREX,
82+
MipsInstrCategory::R5900 => InstrCategory::R5900,
83+
};
84+
4285
let start_address = symbol.address;
4386
let end_address = symbol.address + symbol.size;
4487
let ins_count = code.len() / 4;
@@ -48,7 +91,7 @@ impl ObjArch for ObjArchMips {
4891
for chunk in code.chunks_exact(4) {
4992
let reloc = section.relocations.iter().find(|r| (r.address as u32 & !3) == cur_addr);
5093
let code = self.endianness.read_u32_bytes(chunk.try_into()?);
51-
let instruction = Instruction::new(code, cur_addr, InstrCategory::CPU);
94+
let instruction = Instruction::new(code, cur_addr, instr_category);
5295

5396
let formatted = instruction.disassemble(None, 0);
5497
let op = instruction.unique_id as u16;

objdiff-core/src/diff/mod.rs

Lines changed: 72 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,82 @@ mod code;
1717
mod data;
1818
pub mod display;
1919

20-
#[derive(Debug, Copy, Clone, Default, Eq, PartialEq, serde::Deserialize, serde::Serialize)]
20+
#[derive(
21+
Debug,
22+
Copy,
23+
Clone,
24+
Default,
25+
Eq,
26+
PartialEq,
27+
serde::Deserialize,
28+
serde::Serialize,
29+
strum::VariantArray,
30+
strum::EnumMessage,
31+
)]
2132
pub enum X86Formatter {
2233
#[default]
34+
#[strum(message = "Intel (default)")]
2335
Intel,
36+
#[strum(message = "AT&T")]
2437
Gas,
38+
#[strum(message = "NASM")]
2539
Nasm,
40+
#[strum(message = "MASM")]
2641
Masm,
2742
}
2843

44+
#[derive(
45+
Debug,
46+
Copy,
47+
Clone,
48+
Default,
49+
Eq,
50+
PartialEq,
51+
serde::Deserialize,
52+
serde::Serialize,
53+
strum::VariantArray,
54+
strum::EnumMessage,
55+
)]
56+
pub enum MipsAbi {
57+
#[default]
58+
#[strum(message = "Auto (default)")]
59+
Auto,
60+
#[strum(message = "O32")]
61+
O32,
62+
#[strum(message = "N32")]
63+
N32,
64+
#[strum(message = "N64")]
65+
N64,
66+
}
67+
68+
#[derive(
69+
Debug,
70+
Copy,
71+
Clone,
72+
Default,
73+
Eq,
74+
PartialEq,
75+
serde::Deserialize,
76+
serde::Serialize,
77+
strum::VariantArray,
78+
strum::EnumMessage,
79+
)]
80+
pub enum MipsInstrCategory {
81+
#[default]
82+
#[strum(message = "Auto (default)")]
83+
Auto,
84+
#[strum(message = "CPU")]
85+
Cpu,
86+
#[strum(message = "RSP (N64)")]
87+
Rsp,
88+
#[strum(message = "R3000 GTE (PS1)")]
89+
R3000Gte,
90+
#[strum(message = "R4000 ALLEGREX (PSP)")]
91+
R4000Allegrex,
92+
#[strum(message = "R5900 EE (PS2)")]
93+
R5900,
94+
}
95+
2996
#[inline]
3097
const fn default_true() -> bool { true }
3198

@@ -35,7 +102,11 @@ pub struct DiffObjConfig {
35102
pub relax_reloc_diffs: bool,
36103
#[serde(default = "default_true")]
37104
pub space_between_args: bool,
105+
// x86
38106
pub x86_formatter: X86Formatter,
107+
// MIPS
108+
pub mips_abi: MipsAbi,
109+
pub mips_instr_category: MipsInstrCategory,
39110
}
40111

41112
impl DiffObjConfig {

objdiff-gui/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "objdiff-gui"
3-
version = "2.0.0-alpha.1"
3+
version = "2.0.0-alpha.2"
44
edition = "2021"
55
rust-version = "1.70"
66
authors = ["Luke Street <[email protected]>"]
@@ -46,6 +46,7 @@ ron = "0.8.1"
4646
serde = { version = "1", features = ["derive"] }
4747
serde_json = "1.0.116"
4848
shell-escape = "0.1.5"
49+
strum = { version = "0.26.2", features = ["derive"] }
4950
tempfile = "3.10.1"
5051
time = { version = "0.3.36", features = ["formatting", "local-offset"] }
5152

objdiff-gui/src/app.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ use crate::{
3030
views::{
3131
appearance::{appearance_window, Appearance},
3232
config::{
33-
config_ui, diff_config_window, project_window, ConfigViewState, CONFIG_DISABLED_TEXT,
33+
arch_config_window, config_ui, project_window, ConfigViewState, CONFIG_DISABLED_TEXT,
3434
},
3535
data_diff::data_diff_ui,
3636
debug::debug_window,
@@ -52,7 +52,7 @@ pub struct ViewState {
5252
pub show_appearance_config: bool,
5353
pub show_demangle: bool,
5454
pub show_project_config: bool,
55-
pub show_diff_config: bool,
55+
pub show_arch_config: bool,
5656
pub show_debug: bool,
5757
}
5858

@@ -414,7 +414,7 @@ impl eframe::App for App {
414414
show_appearance_config,
415415
show_demangle,
416416
show_project_config,
417-
show_diff_config,
417+
show_arch_config,
418418
show_debug,
419419
} = view_state;
420420

@@ -468,8 +468,8 @@ impl eframe::App for App {
468468
}
469469
});
470470
ui.menu_button("Diff Options", |ui| {
471-
if ui.button("More…").clicked() {
472-
*show_diff_config = !*show_diff_config;
471+
if ui.button("Arch Settings…").clicked() {
472+
*show_arch_config = !*show_arch_config;
473473
ui.close_menu();
474474
}
475475
let mut config = config.write().unwrap();
@@ -541,7 +541,7 @@ impl eframe::App for App {
541541
project_window(ctx, config, show_project_config, config_state, appearance);
542542
appearance_window(ctx, show_appearance_config, appearance);
543543
demangle_window(ctx, show_demangle, demangle_state, appearance);
544-
diff_config_window(ctx, config, show_diff_config, appearance);
544+
arch_config_window(ctx, config, show_arch_config, appearance);
545545
debug_window(ctx, show_debug, frame_history, appearance);
546546

547547
self.post_update(ctx);

0 commit comments

Comments
 (0)