@@ -15,17 +15,36 @@ use crate::{
15
15
16
16
#[ derive( Debug ) ]
17
17
pub struct ArchX86 {
18
- bits : u32 ,
18
+ arch : Architecture ,
19
19
endianness : object:: Endianness ,
20
20
}
21
21
22
+ #[ derive( Debug ) ]
23
+ enum Architecture {
24
+ X86 ,
25
+ X86_64 ,
26
+ }
27
+
22
28
impl ArchX86 {
23
29
pub fn new ( object : & object:: File ) -> Result < Self > {
24
- Ok ( Self { bits : if object. is_64 ( ) { 64 } else { 32 } , endianness : object. endianness ( ) } )
30
+ let arch = match object. architecture ( ) {
31
+ object:: Architecture :: I386 => Architecture :: X86 ,
32
+ object:: Architecture :: X86_64 => Architecture :: X86_64 ,
33
+ _ => bail ! ( "Unsupported architecture for ArchX86: {:?}" , object. architecture( ) ) ,
34
+ } ;
35
+ Ok ( Self { arch, endianness : object. endianness ( ) } )
25
36
}
26
37
27
38
fn decoder < ' a > ( & self , code : & ' a [ u8 ] , address : u64 ) -> Decoder < ' a > {
28
- Decoder :: with_ip ( self . bits , code, address, DecoderOptions :: NONE )
39
+ Decoder :: with_ip (
40
+ match self . arch {
41
+ Architecture :: X86 => 32 ,
42
+ Architecture :: X86_64 => 64 ,
43
+ } ,
44
+ code,
45
+ address,
46
+ DecoderOptions :: NONE ,
47
+ )
29
48
}
30
49
31
50
fn formatter ( & self , diff_config : & DiffObjConfig ) -> Box < dyn iced_x86:: Formatter > {
@@ -38,6 +57,27 @@ impl ArchX86 {
38
57
formatter. options_mut ( ) . set_space_after_operand_separator ( diff_config. space_between_args ) ;
39
58
formatter
40
59
}
60
+
61
+ fn reloc_size ( & self , flags : RelocationFlags ) -> Option < usize > {
62
+ match self . arch {
63
+ Architecture :: X86 => match flags {
64
+ RelocationFlags :: Coff ( typ) => match typ {
65
+ pe:: IMAGE_REL_I386_DIR16 | pe:: IMAGE_REL_I386_REL16 => Some ( 2 ) ,
66
+ pe:: IMAGE_REL_I386_DIR32 | pe:: IMAGE_REL_I386_REL32 => Some ( 4 ) ,
67
+ _ => None ,
68
+ } ,
69
+ _ => None ,
70
+ } ,
71
+ Architecture :: X86_64 => match flags {
72
+ RelocationFlags :: Coff ( typ) => match typ {
73
+ pe:: IMAGE_REL_AMD64_ADDR32NB | pe:: IMAGE_REL_AMD64_REL32 => Some ( 4 ) ,
74
+ pe:: IMAGE_REL_AMD64_ADDR64 => Some ( 8 ) ,
75
+ _ => None ,
76
+ } ,
77
+ _ => None ,
78
+ } ,
79
+ }
80
+ }
41
81
}
42
82
43
83
impl Arch for ArchX86 {
@@ -88,10 +128,9 @@ impl Arch for ArchX86 {
88
128
// memory operand.
89
129
let mut reloc_replace = None ;
90
130
if let Some ( reloc) = resolved. relocation {
91
- const PLACEHOLDER : u64 = 0x7BDE3E7D ; // chosen by fair dice roll.
92
- // guaranteed to be random.
131
+ const PLACEHOLDER : u64 = 0x7BDE3E7D ; // chosen by fair dice roll. guaranteed to be random.
93
132
let reloc_offset = reloc. relocation . address - resolved. ins_ref . address ;
94
- let reloc_size = reloc_size ( reloc. relocation . flags ) . unwrap_or ( usize:: MAX ) ;
133
+ let reloc_size = self . reloc_size ( reloc. relocation . flags ) . unwrap_or ( usize:: MAX ) ;
95
134
let offsets = decoder. get_constant_offsets ( & instruction) ;
96
135
if reloc_offset == offsets. displacement_offset ( ) as u64
97
136
&& reloc_size == offsets. displacement_size ( )
@@ -148,12 +187,28 @@ impl Arch for ArchX86 {
148
187
_relocation : & object:: Relocation ,
149
188
flags : RelocationFlags ,
150
189
) -> Result < i64 > {
151
- match flags {
152
- RelocationFlags :: Coff ( pe:: IMAGE_REL_I386_DIR32 | pe:: IMAGE_REL_I386_REL32 ) => {
153
- let data = section. data ( ) ?[ address as usize ..address as usize + 4 ] . try_into ( ) ?;
154
- Ok ( self . endianness . read_i32_bytes ( data) as i64 )
155
- }
156
- flags => bail ! ( "Unsupported x86 implicit relocation {flags:?}" ) ,
190
+ match self . arch {
191
+ Architecture :: X86 => match flags {
192
+ RelocationFlags :: Coff ( pe:: IMAGE_REL_I386_DIR32 | pe:: IMAGE_REL_I386_REL32 ) => {
193
+ let data =
194
+ section. data ( ) ?[ address as usize ..address as usize + 4 ] . try_into ( ) ?;
195
+ Ok ( self . endianness . read_i32_bytes ( data) as i64 )
196
+ }
197
+ flags => bail ! ( "Unsupported x86 implicit relocation {flags:?}" ) ,
198
+ } ,
199
+ Architecture :: X86_64 => match flags {
200
+ RelocationFlags :: Coff ( pe:: IMAGE_REL_AMD64_ADDR32NB | pe:: IMAGE_REL_AMD64_REL32 ) => {
201
+ let data =
202
+ section. data ( ) ?[ address as usize ..address as usize + 4 ] . try_into ( ) ?;
203
+ Ok ( self . endianness . read_i32_bytes ( data) as i64 )
204
+ }
205
+ RelocationFlags :: Coff ( pe:: IMAGE_REL_AMD64_ADDR64 ) => {
206
+ let data =
207
+ section. data ( ) ?[ address as usize ..address as usize + 8 ] . try_into ( ) ?;
208
+ Ok ( self . endianness . read_i64_bytes ( data) )
209
+ }
210
+ flags => bail ! ( "Unsupported x86-64 implicit relocation {flags:?}" ) ,
211
+ } ,
157
212
}
158
213
}
159
214
@@ -168,27 +223,29 @@ impl Arch for ArchX86 {
168
223
}
169
224
170
225
fn reloc_name ( & self , flags : RelocationFlags ) -> Option < & ' static str > {
171
- match flags {
172
- RelocationFlags :: Coff ( typ) => match typ {
173
- pe:: IMAGE_REL_I386_DIR32 => Some ( "IMAGE_REL_I386_DIR32" ) ,
174
- pe:: IMAGE_REL_I386_REL32 => Some ( "IMAGE_REL_I386_REL32" ) ,
226
+ match self . arch {
227
+ Architecture :: X86 => match flags {
228
+ RelocationFlags :: Coff ( typ) => match typ {
229
+ pe:: IMAGE_REL_I386_DIR32 => Some ( "IMAGE_REL_I386_DIR32" ) ,
230
+ pe:: IMAGE_REL_I386_REL32 => Some ( "IMAGE_REL_I386_REL32" ) ,
231
+ _ => None ,
232
+ } ,
233
+ _ => None ,
234
+ } ,
235
+ Architecture :: X86_64 => match flags {
236
+ RelocationFlags :: Coff ( typ) => match typ {
237
+ pe:: IMAGE_REL_AMD64_ADDR64 => Some ( "IMAGE_REL_AMD64_ADDR64" ) ,
238
+ pe:: IMAGE_REL_AMD64_ADDR32NB => Some ( "IMAGE_REL_AMD64_ADDR32NB" ) ,
239
+ pe:: IMAGE_REL_AMD64_REL32 => Some ( "IMAGE_REL_AMD64_REL32" ) ,
240
+ _ => None ,
241
+ } ,
175
242
_ => None ,
176
243
} ,
177
- _ => None ,
178
244
}
179
245
}
180
246
181
- fn data_reloc_size ( & self , flags : RelocationFlags ) -> usize { reloc_size ( flags) . unwrap_or ( 1 ) }
182
- }
183
-
184
- fn reloc_size ( flags : RelocationFlags ) -> Option < usize > {
185
- match flags {
186
- RelocationFlags :: Coff ( typ) => match typ {
187
- pe:: IMAGE_REL_I386_DIR16 | pe:: IMAGE_REL_I386_REL16 => Some ( 2 ) ,
188
- pe:: IMAGE_REL_I386_DIR32 | pe:: IMAGE_REL_I386_REL32 => Some ( 4 ) ,
189
- _ => None ,
190
- } ,
191
- _ => None ,
247
+ fn data_reloc_size ( & self , flags : RelocationFlags ) -> usize {
248
+ self . reloc_size ( flags) . unwrap_or ( 1 )
192
249
}
193
250
}
194
251
@@ -343,7 +400,7 @@ mod test {
343
400
344
401
#[ test]
345
402
fn test_scan_instructions ( ) {
346
- let arch = ArchX86 { bits : 32 , endianness : object:: Endianness :: Little } ;
403
+ let arch = ArchX86 { arch : Architecture :: X86 , endianness : object:: Endianness :: Little } ;
347
404
let code = [
348
405
0xc7 , 0x85 , 0x68 , 0xff , 0xff , 0xff , 0x00 , 0x00 , 0x00 , 0x00 , 0x8b , 0x04 , 0x85 , 0x00 ,
349
406
0x00 , 0x00 , 0x00 ,
@@ -362,7 +419,7 @@ mod test {
362
419
363
420
#[ test]
364
421
fn test_process_instruction ( ) {
365
- let arch = ArchX86 { bits : 32 , endianness : object:: Endianness :: Little } ;
422
+ let arch = ArchX86 { arch : Architecture :: X86 , endianness : object:: Endianness :: Little } ;
366
423
let code = [ 0xc7 , 0x85 , 0x68 , 0xff , 0xff , 0xff , 0x00 , 0x00 , 0x00 , 0x00 ] ;
367
424
let opcode = iced_x86:: Mnemonic :: Mov as u16 ;
368
425
let mut parts = Vec :: new ( ) ;
@@ -398,7 +455,7 @@ mod test {
398
455
399
456
#[ test]
400
457
fn test_process_instruction_with_reloc_1 ( ) {
401
- let arch = ArchX86 { bits : 32 , endianness : object:: Endianness :: Little } ;
458
+ let arch = ArchX86 { arch : Architecture :: X86 , endianness : object:: Endianness :: Little } ;
402
459
let code = [ 0xc7 , 0x85 , 0x68 , 0xff , 0xff , 0xff , 0x00 , 0x00 , 0x00 , 0x00 ] ;
403
460
let opcode = iced_x86:: Mnemonic :: Mov as u16 ;
404
461
let mut parts = Vec :: new ( ) ;
@@ -443,7 +500,7 @@ mod test {
443
500
444
501
#[ test]
445
502
fn test_process_instruction_with_reloc_2 ( ) {
446
- let arch = ArchX86 { bits : 32 , endianness : object:: Endianness :: Little } ;
503
+ let arch = ArchX86 { arch : Architecture :: X86 , endianness : object:: Endianness :: Little } ;
447
504
let code = [ 0x8b , 0x04 , 0x85 , 0x00 , 0x00 , 0x00 , 0x00 ] ;
448
505
let opcode = iced_x86:: Mnemonic :: Mov as u16 ;
449
506
let mut parts = Vec :: new ( ) ;
@@ -486,7 +543,7 @@ mod test {
486
543
487
544
#[ test]
488
545
fn test_process_instruction_with_reloc_3 ( ) {
489
- let arch = ArchX86 { bits : 32 , endianness : object:: Endianness :: Little } ;
546
+ let arch = ArchX86 { arch : Architecture :: X86 , endianness : object:: Endianness :: Little } ;
490
547
let code = [ 0xe8 , 0x00 , 0x00 , 0x00 , 0x00 ] ;
491
548
let opcode = iced_x86:: Mnemonic :: Call as u16 ;
492
549
let mut parts = Vec :: new ( ) ;
0 commit comments