1- use std:: borrow:: Cow ;
1+ use std:: { borrow:: Cow , sync :: Mutex } ;
22
33use 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 } ;
55use rabbitizer:: { config, Abi , InstrCategory , Instruction , OperandType } ;
66
77use 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
1921pub 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+
2333impl 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 ;
0 commit comments