OLD | NEW |
| (Empty) |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 // | |
5 // Several simple types used by the disassembler and some of the patching | |
6 // mechanisms. | |
7 | |
8 #ifndef SANDBOX_SRC_SIDESTEP_MINI_DISASSEMBLER_TYPES_H__ | |
9 #define SANDBOX_SRC_SIDESTEP_MINI_DISASSEMBLER_TYPES_H__ | |
10 | |
11 namespace sidestep { | |
12 | |
13 // Categories of instructions that we care about | |
14 enum InstructionType { | |
15 // This opcode is not used | |
16 IT_UNUSED, | |
17 // This disassembler does not recognize this opcode (error) | |
18 IT_UNKNOWN, | |
19 // This is not an instruction but a reference to another table | |
20 IT_REFERENCE, | |
21 // This byte is a prefix byte that we can ignore | |
22 IT_PREFIX, | |
23 // This is a prefix byte that switches to the nondefault address size | |
24 IT_PREFIX_ADDRESS, | |
25 // This is a prefix byte that switches to the nondefault operand size | |
26 IT_PREFIX_OPERAND, | |
27 // A jump or call instruction | |
28 IT_JUMP, | |
29 // A return instruction | |
30 IT_RETURN, | |
31 // Any other type of instruction (in this case we don't care what it is) | |
32 IT_GENERIC, | |
33 }; | |
34 | |
35 // Lists IA-32 operand sizes in multiples of 8 bits | |
36 enum OperandSize { | |
37 OS_ZERO = 0, | |
38 OS_BYTE = 1, | |
39 OS_WORD = 2, | |
40 OS_DOUBLE_WORD = 4, | |
41 OS_QUAD_WORD = 8, | |
42 OS_DOUBLE_QUAD_WORD = 16, | |
43 OS_32_BIT_POINTER = 32/8, | |
44 OS_48_BIT_POINTER = 48/8, | |
45 OS_SINGLE_PRECISION_FLOATING = 32/8, | |
46 OS_DOUBLE_PRECISION_FLOATING = 64/8, | |
47 OS_DOUBLE_EXTENDED_PRECISION_FLOATING = 80/8, | |
48 OS_128_BIT_PACKED_SINGLE_PRECISION_FLOATING = 128/8, | |
49 OS_PSEUDO_DESCRIPTOR = 6 | |
50 }; | |
51 | |
52 // Operand addressing methods from the IA-32 manual. The enAmMask value | |
53 // is a mask for the rest. The other enumeration values are named for the | |
54 // names given to the addressing methods in the manual, e.g. enAm_D is for | |
55 // the D addressing method. | |
56 // | |
57 // The reason we use a full 4 bytes and a mask, is that we need to combine | |
58 // these flags with the enOperandType to store the details | |
59 // on the operand in a single integer. | |
60 enum AddressingMethod { | |
61 AM_NOT_USED = 0, // This operand is not used for this instruction | |
62 AM_MASK = 0x00FF0000, // Mask for the rest of the values in this enumeration | |
63 AM_A = 0x00010000, // A addressing type | |
64 AM_C = 0x00020000, // C addressing type | |
65 AM_D = 0x00030000, // D addressing type | |
66 AM_E = 0x00040000, // E addressing type | |
67 AM_F = 0x00050000, // F addressing type | |
68 AM_G = 0x00060000, // G addressing type | |
69 AM_I = 0x00070000, // I addressing type | |
70 AM_J = 0x00080000, // J addressing type | |
71 AM_M = 0x00090000, // M addressing type | |
72 AM_O = 0x000A0000, // O addressing type | |
73 AM_P = 0x000B0000, // P addressing type | |
74 AM_Q = 0x000C0000, // Q addressing type | |
75 AM_R = 0x000D0000, // R addressing type | |
76 AM_S = 0x000E0000, // S addressing type | |
77 AM_T = 0x000F0000, // T addressing type | |
78 AM_V = 0x00100000, // V addressing type | |
79 AM_W = 0x00110000, // W addressing type | |
80 AM_X = 0x00120000, // X addressing type | |
81 AM_Y = 0x00130000, // Y addressing type | |
82 AM_REGISTER = 0x00140000, // Specific register is always used as this op | |
83 AM_IMPLICIT = 0x00150000, // An implicit, fixed value is used | |
84 }; | |
85 | |
86 // Operand types from the IA-32 manual. The enOtMask value is | |
87 // a mask for the rest. The rest of the values are named for the | |
88 // names given to these operand types in the manual, e.g. enOt_ps | |
89 // is for the ps operand type in the manual. | |
90 // | |
91 // The reason we use a full 4 bytes and a mask, is that we need | |
92 // to combine these flags with the enAddressingMethod to store the details | |
93 // on the operand in a single integer. | |
94 enum OperandType { | |
95 OT_MASK = 0xFF000000, | |
96 OT_A = 0x01000000, | |
97 OT_B = 0x02000000, | |
98 OT_C = 0x03000000, | |
99 OT_D = 0x04000000, | |
100 OT_DQ = 0x05000000, | |
101 OT_P = 0x06000000, | |
102 OT_PI = 0x07000000, | |
103 OT_PS = 0x08000000, // actually unsupported for (we don't know its size) | |
104 OT_Q = 0x09000000, | |
105 OT_S = 0x0A000000, | |
106 OT_SS = 0x0B000000, | |
107 OT_SI = 0x0C000000, | |
108 OT_V = 0x0D000000, | |
109 OT_W = 0x0E000000, | |
110 OT_SD = 0x0F000000, // scalar double-precision floating-point value | |
111 OT_PD = 0x10000000, // double-precision floating point | |
112 // dummy "operand type" for address mode M - which doesn't specify | |
113 // operand type | |
114 OT_ADDRESS_MODE_M = 0x80000000 | |
115 }; | |
116 | |
117 // Everything that's in an Opcode (see below) except the three | |
118 // alternative opcode structs for different prefixes. | |
119 struct SpecificOpcode { | |
120 // Index to continuation table, or 0 if this is the last | |
121 // byte in the opcode. | |
122 int table_index_; | |
123 | |
124 // The opcode type | |
125 InstructionType type_; | |
126 | |
127 // Description of the type of the dest, src and aux operands, | |
128 // put together from an enOperandType flag and an enAddressingMethod | |
129 // flag. | |
130 int flag_dest_; | |
131 int flag_source_; | |
132 int flag_aux_; | |
133 | |
134 // We indicate the mnemonic for debugging purposes | |
135 const char* mnemonic_; | |
136 }; | |
137 | |
138 // The information we keep in our tables about each of the different | |
139 // valid instructions recognized by the IA-32 architecture. | |
140 struct Opcode { | |
141 // Index to continuation table, or 0 if this is the last | |
142 // byte in the opcode. | |
143 int table_index_; | |
144 | |
145 // The opcode type | |
146 InstructionType type_; | |
147 | |
148 // Description of the type of the dest, src and aux operands, | |
149 // put together from an enOperandType flag and an enAddressingMethod | |
150 // flag. | |
151 int flag_dest_; | |
152 int flag_source_; | |
153 int flag_aux_; | |
154 | |
155 // We indicate the mnemonic for debugging purposes | |
156 const char* mnemonic_; | |
157 | |
158 // Alternative opcode info if certain prefixes are specified. | |
159 // In most cases, all of these are zeroed-out. Only used if | |
160 // bPrefixDependent is true. | |
161 bool is_prefix_dependent_; | |
162 SpecificOpcode opcode_if_f2_prefix_; | |
163 SpecificOpcode opcode_if_f3_prefix_; | |
164 SpecificOpcode opcode_if_66_prefix_; | |
165 }; | |
166 | |
167 // Information about each table entry. | |
168 struct OpcodeTable { | |
169 // Table of instruction entries | |
170 const Opcode* table_; | |
171 // How many bytes left to shift ModR/M byte <b>before</b> applying mask | |
172 unsigned char shift_; | |
173 // Mask to apply to byte being looked at before comparing to table | |
174 unsigned char mask_; | |
175 // Minimum/maximum indexes in table. | |
176 unsigned char min_lim_; | |
177 unsigned char max_lim_; | |
178 }; | |
179 | |
180 // Information about each entry in table used to decode ModR/M byte. | |
181 struct ModrmEntry { | |
182 // Is the operand encoded as bytes in the instruction (rather than | |
183 // if it's e.g. a register in which case it's just encoded in the | |
184 // ModR/M byte) | |
185 bool is_encoded_in_instruction_; | |
186 | |
187 // Is there a SIB byte? In this case we always need to decode it. | |
188 bool use_sib_byte_; | |
189 | |
190 // What is the size of the operand (only important if it's encoded | |
191 // in the instruction)? | |
192 OperandSize operand_size_; | |
193 }; | |
194 | |
195 }; // namespace sidestep | |
196 | |
197 #endif // SANDBOX_SRC_SIDESTEP_MINI_DISASSEMBLER_TYPES_H__ | |
OLD | NEW |