@@ -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. address . saturating_sub ( indirect_array_address)
141+ as usize
142+ } )
143+ . unwrap_or ( max_size)
144+ . min ( max_size) ;
145+
146+ if indirect_array_size > 0 {
147+ for i in 0 ..indirect_array_size {
148+ out. push ( InstructionRef {
149+ address : indirect_array_address + i as u64 ,
150+ size : 1 ,
151+ opcode : DATA_OPCODE ,
152+ branch_dest : None ,
153+ } ) ;
154+ }
155+ // move decoder to after the array (there can be multiple jump+indirect tables in one function)
156+ let _ =
157+ 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,33 @@ 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 {
837+ address : 0x1234 ,
838+ size : 1 ,
839+ opcode : DATA_OPCODE ,
840+ branch_dest : None ,
841+ } ,
842+ code : & code,
843+ ..Default :: default ( )
844+ } ,
845+ & DiffObjConfig :: default ( ) ,
846+ & mut |part| {
847+ parts. push ( part. into_static ( ) ) ;
848+ Ok ( ( ) )
849+ } ,
850+ )
851+ . unwrap ( ) ;
852+ assert_eq ! ( parts, & [
853+ InstructionPart :: opcode( ".byte" , DATA_OPCODE ) ,
854+ InstructionPart :: unsigned( 0xABu64 ) ,
855+ ] ) ;
856+ }
794857}
0 commit comments