@@ -15,17 +15,36 @@ use crate::{
1515
1616#[ derive( Debug ) ]
1717pub struct ArchX86 {
18- bits : u32 ,
18+ arch : Architecture ,
1919 endianness : object:: Endianness ,
2020}
2121
22+ #[ derive( Debug ) ]
23+ enum Architecture {
24+ X86 ,
25+ X86_64 ,
26+ }
27+
2228impl ArchX86 {
2329 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 ( ) } )
2536 }
2637
2738 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+ )
2948 }
3049
3150 fn formatter ( & self , diff_config : & DiffObjConfig ) -> Box < dyn iced_x86:: Formatter > {
@@ -38,6 +57,27 @@ impl ArchX86 {
3857 formatter. options_mut ( ) . set_space_after_operand_separator ( diff_config. space_between_args ) ;
3958 formatter
4059 }
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+ }
4181}
4282
4383impl Arch for ArchX86 {
@@ -88,10 +128,9 @@ impl Arch for ArchX86 {
88128 // memory operand.
89129 let mut reloc_replace = None ;
90130 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.
93132 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 ) ;
95134 let offsets = decoder. get_constant_offsets ( & instruction) ;
96135 if reloc_offset == offsets. displacement_offset ( ) as u64
97136 && reloc_size == offsets. displacement_size ( )
@@ -148,12 +187,28 @@ impl Arch for ArchX86 {
148187 _relocation : & object:: Relocation ,
149188 flags : RelocationFlags ,
150189 ) -> 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+ } ,
157212 }
158213 }
159214
@@ -168,27 +223,29 @@ impl Arch for ArchX86 {
168223 }
169224
170225 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+ } ,
175242 _ => None ,
176243 } ,
177- _ => None ,
178244 }
179245 }
180246
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 )
192249 }
193250}
194251
@@ -343,7 +400,7 @@ mod test {
343400
344401 #[ test]
345402 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 } ;
347404 let code = [
348405 0xc7 , 0x85 , 0x68 , 0xff , 0xff , 0xff , 0x00 , 0x00 , 0x00 , 0x00 , 0x8b , 0x04 , 0x85 , 0x00 ,
349406 0x00 , 0x00 , 0x00 ,
@@ -362,7 +419,7 @@ mod test {
362419
363420 #[ test]
364421 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 } ;
366423 let code = [ 0xc7 , 0x85 , 0x68 , 0xff , 0xff , 0xff , 0x00 , 0x00 , 0x00 , 0x00 ] ;
367424 let opcode = iced_x86:: Mnemonic :: Mov as u16 ;
368425 let mut parts = Vec :: new ( ) ;
@@ -398,7 +455,7 @@ mod test {
398455
399456 #[ test]
400457 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 } ;
402459 let code = [ 0xc7 , 0x85 , 0x68 , 0xff , 0xff , 0xff , 0x00 , 0x00 , 0x00 , 0x00 ] ;
403460 let opcode = iced_x86:: Mnemonic :: Mov as u16 ;
404461 let mut parts = Vec :: new ( ) ;
@@ -443,7 +500,7 @@ mod test {
443500
444501 #[ test]
445502 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 } ;
447504 let code = [ 0x8b , 0x04 , 0x85 , 0x00 , 0x00 , 0x00 , 0x00 ] ;
448505 let opcode = iced_x86:: Mnemonic :: Mov as u16 ;
449506 let mut parts = Vec :: new ( ) ;
@@ -486,7 +543,7 @@ mod test {
486543
487544 #[ test]
488545 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 } ;
490547 let code = [ 0xe8 , 0x00 , 0x00 , 0x00 , 0x00 ] ;
491548 let opcode = iced_x86:: Mnemonic :: Call as u16 ;
492549 let mut parts = Vec :: new ( ) ;
0 commit comments