OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2012 The Native Client Authors. All rights reserved. | 2 * Copyright (c) 2012 The Native Client Authors. All rights reserved. |
3 * Use of this source code is governed by a BSD-style license that can be | 3 * Use of this source code is governed by a BSD-style license that can be |
4 * found in the LICENSE file. | 4 * found in the LICENSE file. |
5 */ | 5 */ |
6 | 6 |
7 /* | 7 /* |
8 * Data structures for decoding instructions. Includes definitions which are | 8 * Data structures for decoding instructions. Includes definitions which are |
9 * by both decoders (full-blown standalone one and reduced one in validator). | 9 * used by all decoders (full-blown standalone one and reduced one in validator, |
| 10 * both ia32 version and x86-64 version). |
10 */ | 11 */ |
11 | 12 |
12 #ifndef NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_RAGEL_DECODER_H_ | 13 #ifndef NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_RAGEL_DECODER_H_ |
13 #define NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_RAGEL_DECODER_H_ | 14 #define NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_RAGEL_DECODER_H_ |
14 | 15 |
15 #include "native_client/src/shared/utils/types.h" | 16 #include "native_client/src/shared/utils/types.h" |
16 #include "native_client/src/trusted/cpu_features/arch/x86/cpu_x86.h" | 17 #include "native_client/src/trusted/cpu_features/arch/x86/cpu_x86.h" |
17 | 18 |
18 EXTERN_C_BEGIN | 19 EXTERN_C_BEGIN |
19 | 20 |
| 21 /* |
| 22 * Instruction operand TYPE: GP register size (8-bit, 32-bit, MMX, XXM, etc), or |
| 23 * in-memory structure (far pointer, 256-bit SIMD operands, etc). |
| 24 */ |
20 enum OperandType { | 25 enum OperandType { |
21 /* | 26 /* |
22 * These are for general-purpose registers, memory access and immediates. | 27 * These are for general-purpose registers, memory access and immediates. |
23 * They are not used for XMM, MMX etc. | 28 * They are not used for XMM, MMX etc. |
24 */ | 29 */ |
25 OPERAND_TYPE_8_BIT, | 30 OPERAND_TYPE_8_BIT, |
26 OPERAND_TYPE_16_BIT, | 31 OPERAND_TYPE_16_BIT, |
27 OPERAND_TYPE_32_BIT, | 32 OPERAND_TYPE_32_BIT, |
28 OPERAND_TYPE_64_BIT, | 33 OPERAND_TYPE_64_BIT, |
29 | 34 |
30 /* Non-GP registers. */ | 35 /* Non-GP registers. */ |
31 OPERAND_TYPE_ST, /* Any X87 register. */ | 36 OPERAND_TYPE_ST, /* Any X87 register. */ |
32 OPERAND_TYPE_MMX, /* MMX registers: %mmX. */ | 37 OPERAND_TYPE_MMX, /* MMX registers: %mmX. */ |
33 OPERAND_TYPE_XMM, /* XMM register: %xmmX. */ | 38 OPERAND_TYPE_XMM, /* XMM register: %xmmX. */ |
34 OPERAND_TYPE_YMM, /* YMM registers: %ymmX. */ | 39 OPERAND_TYPE_YMM, /* YMM registers: %ymmX. */ |
35 OPERAND_TYPE_SEGMENT_REGISTER, /* Operand is segment register: %es … %gs. */ | 40 OPERAND_TYPE_SEGMENT_REGISTER, /* Operand is segment register: %es ... %gs. */ |
36 OPERAND_TYPE_CONTROL_REGISTER, /* Operand is control register: %crX. */ | 41 OPERAND_TYPE_CONTROL_REGISTER, /* Operand is control register: %crX. */ |
37 OPERAND_TYPE_DEBUG_REGISTER, /* Operand is debug register: %drX. */ | 42 OPERAND_TYPE_DEBUG_REGISTER, /* Operand is debug register: %drX. */ |
38 OPERAND_TYPE_TEST_REGISTER, /* Operand is test register: %trX. */ | 43 OPERAND_TYPE_TEST_REGISTER, /* Operand is test register: %trX. */ |
39 | 44 |
40 /* | 45 /* |
41 * All other operand types are not used as register arguments. These are | 46 * All other operand types are not used as register arguments. These are |
42 * immediates or memory. | 47 * immediates or memory. |
43 */ | 48 */ |
44 OPERAND_TYPES_REGISTER_MAX = OPERAND_TYPE_TEST_REGISTER + 1, | 49 OPERAND_TYPES_REGISTER_MAX = OPERAND_TYPE_TEST_REGISTER + 1, |
45 | 50 |
(...skipping 21 matching lines...) Expand all Loading... |
67 | 72 |
68 /* Miscellaneous structures in memory. */ | 73 /* Miscellaneous structures in memory. */ |
69 OPERAND_TYPE_X87_BCD, /* 10-byte packed BCD value. */ | 74 OPERAND_TYPE_X87_BCD, /* 10-byte packed BCD value. */ |
70 OPERAND_TYPE_X87_ENV, /* A 14-byte or 28-byte x87 environment. */ | 75 OPERAND_TYPE_X87_ENV, /* A 14-byte or 28-byte x87 environment. */ |
71 OPERAND_TYPE_X87_STATE, /* A 94-byte or 108-byte x87 state. */ | 76 OPERAND_TYPE_X87_STATE, /* A 94-byte or 108-byte x87 state. */ |
72 OPERAND_TYPE_X87_MMX_XMM_STATE, /* A 512-byte extended x87/MMX/XMM state. */ | 77 OPERAND_TYPE_X87_MMX_XMM_STATE, /* A 512-byte extended x87/MMX/XMM state. */ |
73 OPERAND_TYPE_SELECTOR, /* Operand is 6/10 bytes selector. */ | 78 OPERAND_TYPE_SELECTOR, /* Operand is 6/10 bytes selector. */ |
74 OPERAND_TYPE_FAR_PTR /* Operand is 6/10 bytes far pointer. */ | 79 OPERAND_TYPE_FAR_PTR /* Operand is 6/10 bytes far pointer. */ |
75 }; | 80 }; |
76 | 81 |
| 82 /* |
| 83 * Instruction operand NAME: register number (REG_RAX means any of the following |
| 84 * registers: %al/%ax/%eax/%rax/%st(0)/%mm0/%xmm0/%ymm0/%es/%cr0/%db0/%tr0), or |
| 85 * non-register operand (REG_RM means address in memory specified via "ModR/M |
| 86 * byte" (plus may be "SIB byte" or displacement), REG_DS_RBX is special operand |
| 87 * of "xlat" instruction, REG_ST is to of x87 stack and so on - see below for |
| 88 * for the full list). |
| 89 */ |
77 enum OperandName { | 90 enum OperandName { |
78 /* First 16 registers are compatible with encoding of registers in x86 ABI. */ | 91 /* First 16 registers are compatible with encoding of registers in x86 ABI. */ |
79 REG_RAX, | 92 REG_RAX, |
80 REG_RCX, | 93 REG_RCX, |
81 REG_RDX, | 94 REG_RDX, |
82 REG_RBX, | 95 REG_RBX, |
83 REG_RSP, | 96 REG_RSP, |
84 REG_RBP, | 97 REG_RBP, |
85 REG_RSI, | 98 REG_RSI, |
86 REG_RDI, | 99 REG_RDI, |
87 REG_R8, | 100 REG_R8, |
88 REG_R9, | 101 REG_R9, |
89 REG_R10, | 102 REG_R10, |
90 REG_R11, | 103 REG_R11, |
91 REG_R12, | 104 REG_R12, |
92 REG_R13, | 105 REG_R13, |
93 REG_R14, | 106 REG_R14, |
94 REG_R15, | 107 REG_R15, |
95 /* These are different kinds of operands used in special cases. */ | 108 /* These are different kinds of operands used in special cases. */ |
96 REG_RM, /* Address in memory via rm field. */ | 109 REG_RM, /* Address in memory via ModR/M (+SIB). */ |
97 REG_RIP, /* RIP - used as base in x86-64 mode. */ | 110 REG_RIP, /* RIP - used as base in x86-64 mode. */ |
98 REG_RIZ, /* EIZ/RIZ - used as "always zero index" register. */ | 111 REG_RIZ, /* EIZ/RIZ - used as "always zero index" register. */ |
99 REG_IMM, /* Fixed value in imm field. */ | 112 REG_IMM, /* Fixed value in imm field. */ |
100 REG_IMM2, /* Fixed value in second imm field. */ | 113 REG_IMM2, /* Fixed value in second imm field. */ |
101 REG_DS_RBX, /* Fox xlat: %ds(%rbx). */ | 114 REG_DS_RBX, /* For xlat: %ds:(%rbx). */ |
102 REG_ES_RDI, /* For string instructions: %es:(%rsi). */ | 115 REG_ES_RDI, /* For string instructions: %es:(%rsi). */ |
103 REG_DS_RSI, /* For string instructions: %ds:(%rdi). */ | 116 REG_DS_RSI, /* For string instructions: %ds:(%rdi). */ |
104 REG_PORT_DX, /* 16-bit DX: for in/out instructions. */ | 117 REG_PORT_DX, /* 16-bit DX: for in/out instructions. */ |
105 NO_REG, /* For modrm: both index and base can be absent. */ | 118 NO_REG, /* For modrm: both index and base can be absent. */ |
106 REG_ST, /* For x87 instructions: implicit %st. */ | 119 REG_ST, /* For x87 instructions: implicit %st. */ |
107 JMP_TO /* Operand is jump target address: usually %rip+offset. */ | 120 JMP_TO /* Operand is jump target address: usually %rip+offset. */ |
108 }; | 121 }; |
109 | 122 |
110 /* | 123 /* |
111 * Displacement can be of four different sizes in x86 instruction set: nothing, | 124 * Displacement can be of four different sizes in x86 instruction set: nothing, |
112 * 8-bit, 16-bit, 32-bit, and 64-bit. These are traditionally treated slightly | 125 * 8-bit, 16-bit, 32-bit, and 64-bit. These are traditionally treated slightly |
113 * differently by decoders: 8-bit are usually printed as signed offset, while | 126 * differently by decoders: 8-bit are usually printed as signed offset, while |
114 * 32-bit (in ia32 mode) and 64-bit (in amd64 mode) are printed as unsigned | 127 * 32-bit (in ia32 mode) and 64-bit (in amd64 mode) are printed as unsigned |
115 * offset. | 128 * offset. |
116 */ | 129 */ |
117 enum DisplacementMode { | 130 enum DisplacementMode { |
118 DISPNONE, | 131 DISPNONE, |
119 DISP8, | 132 DISP8, |
120 DISP16, | 133 DISP16, |
121 DISP32, | 134 DISP32, |
122 DISP64 | 135 DISP64 |
123 }; | 136 }; |
124 | 137 |
| 138 /* |
| 139 * Information about decoded instruction: name, operands, prefixes, etc. |
| 140 */ |
125 struct Instruction { | 141 struct Instruction { |
126 const char *name; | 142 const char *name; |
127 unsigned char operands_count; | 143 unsigned char operands_count; |
128 struct { | 144 struct { |
129 unsigned char rex; /* Mostly to distingush cases like %ah vs %spl. */ | 145 unsigned char rex; /* Mostly to distingush cases like %ah vs %spl. */ |
130 Bool rex_b_spurious; | 146 Bool rex_b_spurious; |
131 Bool rex_x_spurious; | 147 Bool rex_x_spurious; |
132 Bool rex_r_spurious; | 148 Bool rex_r_spurious; |
133 Bool rex_w_spurious; | 149 Bool rex_w_spurious; |
134 Bool data16; /* "Normal", non-rex prefixes. */ | 150 Bool data16; /* "Normal", non-rex prefixes. */ |
(...skipping 12 matching lines...) Expand all Loading... |
147 enum OperandName index; | 163 enum OperandName index; |
148 int scale; | 164 int scale; |
149 int64_t offset; | 165 int64_t offset; |
150 enum DisplacementMode disp_type; | 166 enum DisplacementMode disp_type; |
151 } rm; | 167 } rm; |
152 uint64_t imm[2]; | 168 uint64_t imm[2]; |
153 const char* att_instruction_suffix; | 169 const char* att_instruction_suffix; |
154 }; | 170 }; |
155 | 171 |
156 /* | 172 /* |
| 173 * Instruction processing callback: called once for each instruction in a stream |
| 174 * |
157 * "begin" points to first byte of the instruction | 175 * "begin" points to first byte of the instruction |
158 * "end" points to the last byte of the instruction | 176 * "end" points to the first byte of the next instruction |
159 * for single-byte instruction “begin” == “end” | 177 * for single-byte instruction "begin + 1" == "end" |
160 * "instruction" is detailed information about instruction | 178 * "instruction" contains detailed information about instruction |
161 */ | 179 */ |
162 typedef void (*ProcessInstructionFunc) (const uint8_t *begin, | 180 typedef void (*ProcessInstructionFunc) (const uint8_t *begin, |
163 const uint8_t *end, | 181 const uint8_t *end, |
164 struct Instruction *instruction, | 182 struct Instruction *instruction, |
165 void *userdata); | 183 void *callback_data); |
166 | 184 |
167 /* | 185 /* |
| 186 * Decoding error: called when decoder's DFA does not recognize the instruction. |
| 187 * |
168 * "ptr" points to the first byte rejected by DFA and can be used in more | 188 * "ptr" points to the first byte rejected by DFA and can be used in more |
169 * advanced decoders to try to do some kind of recovery. | 189 * advanced decoders to try to do some kind of recovery. |
170 */ | 190 */ |
171 typedef void (*ProcessDecodingErrorFunc) (const uint8_t *ptr, | 191 typedef void (*ProcessDecodingErrorFunc) (const uint8_t *ptr, |
172 void *userdata); | 192 void *callback_data); |
173 | 193 |
174 /* | 194 /* |
175 * kFullCPUIDFeatures is pre-defined constant of NaClCPUFeaturesX86 type with | 195 * kFullCPUIDFeatures is pre-defined constant of NaClCPUFeaturesX86 type with |
176 * all possible CPUID features enabled. | 196 * all possible CPUID features enabled. |
177 */ | 197 */ |
178 extern const NaClCPUFeaturesX86 kFullCPUIDFeatures; | 198 extern const NaClCPUFeaturesX86 kFullCPUIDFeatures; |
179 | 199 |
| 200 /* |
| 201 * Returns True when piece of code is valid piece of code. |
| 202 * Returns False If ragel machine does not accept piece of code. |
| 203 * process_instruction callback is called for each instruction accepted by |
| 204 * ragel machine |
| 205 */ |
180 int DecodeChunkAMD64(const uint8_t *data, size_t size, | 206 int DecodeChunkAMD64(const uint8_t *data, size_t size, |
181 ProcessInstructionFunc process_instruction, | 207 ProcessInstructionFunc process_instruction, |
182 ProcessDecodingErrorFunc process_error, void *userdata); | 208 ProcessDecodingErrorFunc process_error, |
| 209 void *callback_data); |
183 | 210 |
184 int DecodeChunkIA32(const uint8_t *data, size_t size, | 211 int DecodeChunkIA32(const uint8_t *data, size_t size, |
185 ProcessInstructionFunc process_instruction, | 212 ProcessInstructionFunc process_instruction, |
186 ProcessDecodingErrorFunc process_error, void *userdata); | 213 ProcessDecodingErrorFunc process_error, |
| 214 void *callback_data); |
187 | 215 |
188 EXTERN_C_END | 216 EXTERN_C_END |
189 | 217 |
190 #endif /* NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_RAGEL_DECODER_H_ */ | 218 #endif /* NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_RAGEL_DECODER_H_ */ |
OLD | NEW |