@@ -124,7 +124,40 @@ impl Arch for ArchX86 {
124
124
opcode : DATA_OPCODE ,
125
125
branch_dest : None ,
126
126
} ) ;
127
+
127
128
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
+
128
161
continue ' outer;
129
162
}
130
163
}
@@ -156,6 +189,7 @@ impl Arch for ArchX86 {
156
189
) -> Result < ( ) > {
157
190
if resolved. ins_ref . opcode == DATA_OPCODE {
158
191
let ( mnemonic, imm) = match resolved. ins_ref . size {
192
+ 1 => ( ".byte" , resolved. code [ 0 ] as u64 ) ,
159
193
2 => ( ".word" , self . endianness . read_u16_bytes ( resolved. code . try_into ( ) ?) as u64 ) ,
160
194
4 => ( ".dword" , self . endianness . read_u32_bytes ( resolved. code . try_into ( ) ?) as u64 ) ,
161
195
_ => bail ! ( "Unsupported x86 inline data size {}" , resolved. ins_ref. size) ,
@@ -791,4 +825,33 @@ mod test {
791
825
. unwrap ( ) ;
792
826
assert_eq ! ( parts, & [ InstructionPart :: opcode( "call" , opcode) , InstructionPart :: reloc( ) ] ) ;
793
827
}
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
+ }
794
857
}
0 commit comments