@@ -124,7 +124,40 @@ impl Arch for ArchX86 {
124124 opcode : DATA_OPCODE ,
125125 branch_dest : None ,
126126 } ) ;
127+
127128 reloc_iter. next ( ) ;
129+
130+ // support .byte arrays after jump tables (they're typically known as indirect tables)
131+
132+ let indirect_array_address = address. wrapping_add ( size as u64 ) ;
133+ let indirect_array_pos = decoder. position ( ) ;
134+
135+ let max_size = code. len ( ) . saturating_sub ( indirect_array_pos) ;
136+
137+ let indirect_array_size = reloc_iter
138+ . peek ( )
139+ . map ( |next_reloc| {
140+ next_reloc
141+ . address
142+ . saturating_sub ( indirect_array_address) as usize
143+ } )
144+ . unwrap_or ( max_size)
145+ . min ( max_size) ;
146+
147+ if indirect_array_size > 0 {
148+ for i in 0 ..indirect_array_size {
149+ out. push ( InstructionRef {
150+ address : indirect_array_address + i as u64 ,
151+ size : 1 ,
152+ opcode : DATA_OPCODE ,
153+ branch_dest : None ,
154+ } ) ;
155+ }
156+ // move decoder to after the array (there can be multiple jump+indirect tables in one function)
157+ let _ = decoder. set_position ( indirect_array_pos + indirect_array_size) ;
158+ decoder. set_ip ( indirect_array_address + indirect_array_size as u64 ) ;
159+ }
160+
128161 continue ' outer;
129162 }
130163 }
@@ -156,6 +189,7 @@ impl Arch for ArchX86 {
156189 ) -> Result < ( ) > {
157190 if resolved. ins_ref . opcode == DATA_OPCODE {
158191 let ( mnemonic, imm) = match resolved. ins_ref . size {
192+ 1 => ( ".byte" , resolved. code [ 0 ] as u64 ) ,
159193 2 => ( ".word" , self . endianness . read_u16_bytes ( resolved. code . try_into ( ) ?) as u64 ) ,
160194 4 => ( ".dword" , self . endianness . read_u32_bytes ( resolved. code . try_into ( ) ?) as u64 ) ,
161195 _ => bail ! ( "Unsupported x86 inline data size {}" , resolved. ins_ref. size) ,
@@ -791,4 +825,28 @@ mod test {
791825 . unwrap ( ) ;
792826 assert_eq ! ( parts, & [ InstructionPart :: opcode( "call" , opcode) , InstructionPart :: reloc( ) ] ) ;
793827 }
828+
829+ #[ test]
830+ fn test_display_1_byte_inline_data ( ) {
831+ let arch = ArchX86 { arch : Architecture :: X86 , endianness : object:: Endianness :: Little } ;
832+ let code = [ 0xAB ] ;
833+ let mut parts = Vec :: new ( ) ;
834+ arch. display_instruction (
835+ ResolvedInstructionRef {
836+ ins_ref : InstructionRef { address : 0x1234 , size : 1 , opcode : DATA_OPCODE , branch_dest : None } ,
837+ code : & code,
838+ ..Default :: default ( )
839+ } ,
840+ & DiffObjConfig :: default ( ) ,
841+ & mut |part| {
842+ parts. push ( part. into_static ( ) ) ;
843+ Ok ( ( ) )
844+ } ,
845+ )
846+ . unwrap ( ) ;
847+ assert_eq ! ( parts, & [
848+ InstructionPart :: opcode( ".byte" , DATA_OPCODE ) ,
849+ InstructionPart :: unsigned( 0xABu64 ) ,
850+ ] ) ;
851+ }
794852}
0 commit comments