@@ -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
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
+
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,28 @@ 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 { 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
+ }
794
852
}
0 commit comments