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 /* |
| 8 * Data structures for decoding instructions. Includes definitions which are |
| 9 * by both decoders (full-blown standalone one and reduced one in validator). |
| 10 */ |
| 11 |
7 #ifndef NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_RAGEL_DECODER_H_ | 12 #ifndef NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_RAGEL_DECODER_H_ |
8 #define NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_RAGEL_DECODER_H_ | 13 #define NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_RAGEL_DECODER_H_ |
9 | 14 |
10 #include "native_client/src/shared/utils/types.h" | 15 #include "native_client/src/shared/utils/types.h" |
11 #include "native_client/src/trusted/validator/x86/nacl_cpuid.h" | 16 #include "native_client/src/trusted/validator/x86/nacl_cpuid.h" |
12 | 17 |
13 EXTERN_C_BEGIN | 18 EXTERN_C_BEGIN |
14 | 19 |
| 20 /* |
| 21 * Instruction operand TYPE: GP register size (8-bit, 32-bit, MMX, XXM, etc), or |
| 22 * in-memory structure (far pointer, 256-bit SIMD operands, etc). |
| 23 */ |
15 enum OperandType { | 24 enum OperandType { |
16 /* | 25 /* |
17 * These are for general-purpose registers, memory access and immediates. | 26 * These are for general-purpose registers, memory access and immediates. |
18 * They are not used for XMM, MMX etc. | 27 * They are not used for XMM, MMX etc. |
19 */ | 28 */ |
20 OPERAND_TYPE_8_BIT, | 29 OPERAND_TYPE_8_BIT, |
21 OPERAND_TYPE_16_BIT, | 30 OPERAND_TYPE_16_BIT, |
22 OPERAND_TYPE_32_BIT, | 31 OPERAND_TYPE_32_BIT, |
23 OPERAND_TYPE_64_BIT, | 32 OPERAND_TYPE_64_BIT, |
24 | 33 |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
62 | 71 |
63 /* Miscellaneous structures in memory. */ | 72 /* Miscellaneous structures in memory. */ |
64 OPERAND_TYPE_X87_BCD, /* 10-byte packed BCD value. */ | 73 OPERAND_TYPE_X87_BCD, /* 10-byte packed BCD value. */ |
65 OPERAND_TYPE_X87_ENV, /* A 14-byte or 28-byte x87 environment. */ | 74 OPERAND_TYPE_X87_ENV, /* A 14-byte or 28-byte x87 environment. */ |
66 OPERAND_TYPE_X87_STATE, /* A 94-byte or 108-byte x87 state. */ | 75 OPERAND_TYPE_X87_STATE, /* A 94-byte or 108-byte x87 state. */ |
67 OPERAND_TYPE_X87_MMX_XMM_STATE, /* A 512-byte extended x87/MMX/XMM state. */ | 76 OPERAND_TYPE_X87_MMX_XMM_STATE, /* A 512-byte extended x87/MMX/XMM state. */ |
68 OPERAND_TYPE_SELECTOR, /* Operand is 6/10 bytes selector. */ | 77 OPERAND_TYPE_SELECTOR, /* Operand is 6/10 bytes selector. */ |
69 OPERAND_TYPE_FAR_PTR /* Operand is 6/10 bytes far pointer. */ | 78 OPERAND_TYPE_FAR_PTR /* Operand is 6/10 bytes far pointer. */ |
70 }; | 79 }; |
71 | 80 |
| 81 /* |
| 82 * Instruction operand NAME: register number (REG_RAX means any of the following |
| 83 * registers: %al/%ax/%eax/%rax/%st(0)/%mm0/%xmm0/%ymm0/%es/%cr0/%db0/%tr0), or |
| 84 * non-register operand (REG_RM means address in memory specified via “ModR/M |
| 85 * byte” (plus may be “SIB byte” or displacement), REG_DS_RBX is special operand |
| 86 * of “xlat” instruction, REG_ST is to of x87 stack and so on - see below for |
| 87 * for the full list). |
| 88 */ |
72 enum OperandName { | 89 enum OperandName { |
73 /* First 16 registers are compatible with encoding of registers in x86 ABI. */ | 90 /* First 16 registers are compatible with encoding of registers in x86 ABI. */ |
74 REG_RAX, | 91 REG_RAX, |
75 REG_RCX, | 92 REG_RCX, |
76 REG_RDX, | 93 REG_RDX, |
77 REG_RBX, | 94 REG_RBX, |
78 REG_RSP, | 95 REG_RSP, |
79 REG_RBP, | 96 REG_RBP, |
80 REG_RSI, | 97 REG_RSI, |
81 REG_RDI, | 98 REG_RDI, |
82 REG_R8, | 99 REG_R8, |
83 REG_R9, | 100 REG_R9, |
84 REG_R10, | 101 REG_R10, |
85 REG_R11, | 102 REG_R11, |
86 REG_R12, | 103 REG_R12, |
87 REG_R13, | 104 REG_R13, |
88 REG_R14, | 105 REG_R14, |
89 REG_R15, | 106 REG_R15, |
90 /* These are different kinds of operands used in special cases. */ | 107 /* These are different kinds of operands used in special cases. */ |
91 REG_RM, /* Address in memory via rm field. */ | 108 REG_RM, /* Address in memory via ModR/M (+SIB). */ |
92 REG_RIP, /* RIP - used as base in x86-64 mode. */ | 109 REG_RIP, /* RIP - used as base in x86-64 mode. */ |
93 REG_RIZ, /* EIZ/RIZ - used as "always zero index" register. */ | 110 REG_RIZ, /* EIZ/RIZ - used as "always zero index" register. */ |
94 REG_IMM, /* Fixed value in imm field. */ | 111 REG_IMM, /* Fixed value in imm field. */ |
95 REG_IMM2, /* Fixed value in second imm field. */ | 112 REG_IMM2, /* Fixed value in second imm field. */ |
96 REG_DS_RBX, /* Fox xlat: %ds(%rbx). */ | 113 REG_DS_RBX, /* Fox xlat: %ds:(%rbx). */ |
97 REG_ES_RDI, /* For string instructions: %es:(%rsi). */ | 114 REG_ES_RDI, /* For string instructions: %es:(%rsi). */ |
98 REG_DS_RSI, /* For string instructions: %ds:(%rdi). */ | 115 REG_DS_RSI, /* For string instructions: %ds:(%rdi). */ |
99 REG_PORT_DX, /* 16-bit DX: for in/out instructions. */ | 116 REG_PORT_DX, /* 16-bit DX: for in/out instructions. */ |
100 NO_REG, /* For modrm: both index and base can be absent. */ | 117 NO_REG, /* For modrm: both index and base can be absent. */ |
101 REG_ST, /* For x87 instructions: implicit %st. */ | 118 REG_ST, /* For x87 instructions: implicit %st. */ |
102 JMP_TO, /* Operand is jump target address: usually %rip+offset. */ | 119 JMP_TO, /* Operand is jump target address: usually %rip+offset. */ |
103 }; | 120 }; |
104 | 121 |
105 /* | 122 /* |
106 * Displacement can be of four different sizes in x86 instruction set: nothing, | 123 * Displacement can be of four different sizes in x86 instruction set: nothing, |
107 * 8-bit, 16-bit, 32-bit, and 64-bit. These are traditionally treated slightly | 124 * 8-bit, 16-bit, 32-bit, and 64-bit. These are traditionally treated slightly |
108 * differently by decoders: 8-bit are usually printed as signed offset, while | 125 * differently by decoders: 8-bit are usually printed as signed offset, while |
109 * 32-bit (in ia32 mode) and 64-bit (in amd64 mode) are printed as unsigned | 126 * 32-bit (in ia32 mode) and 64-bit (in amd64 mode) are printed as unsigned |
110 * offset. | 127 * offset. |
111 */ | 128 */ |
112 enum DisplacementMode { | 129 enum DisplacementMode { |
113 DISPNONE, | 130 DISPNONE, |
114 DISP8, | 131 DISP8, |
115 DISP16, | 132 DISP16, |
116 DISP32, | 133 DISP32, |
117 DISP64 | 134 DISP64 |
118 }; | 135 }; |
119 | 136 |
| 137 /* |
| 138 * Insformation about decoded instruction: name, operands, prefixes, etc. |
| 139 */ |
120 struct Instruction { | 140 struct Instruction { |
121 const char *name; | 141 const char *name; |
122 unsigned char operands_count; | 142 unsigned char operands_count; |
123 struct { | 143 struct { |
124 unsigned char rex; /* Mostly to distingush cases like %ah vs %spl. */ | 144 unsigned char rex; /* Mostly to distingush cases like %ah vs %spl. */ |
125 Bool rex_b_spurious; | 145 Bool rex_b_spurious; |
126 Bool rex_x_spurious; | 146 Bool rex_x_spurious; |
127 Bool rex_r_spurious; | 147 Bool rex_r_spurious; |
128 Bool rex_w_spurious; | 148 Bool rex_w_spurious; |
129 Bool data16; /* "Normal", non-rex prefixes. */ | 149 Bool data16; /* "Normal", non-rex prefixes. */ |
(...skipping 12 matching lines...) Expand all Loading... |
142 enum OperandName base; | 162 enum OperandName base; |
143 enum OperandName index; | 163 enum OperandName index; |
144 int scale; | 164 int scale; |
145 int64_t offset; | 165 int64_t offset; |
146 enum DisplacementMode disp_type; | 166 enum DisplacementMode disp_type; |
147 } rm; | 167 } rm; |
148 uint64_t imm[2]; | 168 uint64_t imm[2]; |
149 const char* att_instruction_suffix; | 169 const char* att_instruction_suffix; |
150 }; | 170 }; |
151 | 171 |
| 172 /* |
| 173 * Instruction processing callback: called once for each instruction in a stream |
| 174 * |
| 175 * Note: there are peculiar case related to “fwait” threatment. For historical |
| 176 * reasons it's both a standalone instruction (which can be used in separation) |
| 177 * and “prefix” for instructions “fclex”, “finit”, “fsave”, “fsaves”, “fstcw”, |
| 178 * “fstenv”, “fstenvs”, and “fstsw”. Decoder processes sequence of, e.g. |
| 179 * “fwait” and “fninit” in the followin way: |
| 180 * • First “fwait” is processed by ProcessInstructionFunc. |
| 181 * • Then “fninit” is processed by ProcessInstructionFunc. |
| 182 * Decoder detects the case of »“fwait” followed by “fninit”« situation and |
| 183 * reports correct name of the operation but it DOES NOT include “fwait” in |
| 184 * the piece marked by “begin” and “end” pointers. |
| 185 */ |
152 typedef void (*ProcessInstructionFunc) (const uint8_t *begin, | 186 typedef void (*ProcessInstructionFunc) (const uint8_t *begin, |
153 const uint8_t *end, | 187 const uint8_t *end, |
154 struct Instruction *instruction, | 188 struct Instruction *instruction, |
155 void *userdata); | 189 void *callback_data); |
156 | 190 |
| 191 /* |
| 192 * Decoding error: called when decoder's DFA does not recognize the instruction. |
| 193 */ |
157 typedef void (*ProcessDecodingErrorFunc) (const uint8_t *ptr, | 194 typedef void (*ProcessDecodingErrorFunc) (const uint8_t *ptr, |
158 void *userdata); | 195 void *callback_data); |
159 | 196 |
160 /* | 197 /* |
161 * kFullCPUIDFeatures is pre-defined constant of NaClCPUFeaturesX86 type with | 198 * kFullCPUIDFeatures is pre-defined constant of NaClCPUFeaturesX86 type with |
162 * all possible CPUID features enabled. | 199 * all possible CPUID features enabled. |
163 */ | 200 */ |
164 extern const NaClCPUFeaturesX86 kFullCPUIDFeatures; | 201 extern const NaClCPUFeaturesX86 kFullCPUIDFeatures; |
165 | 202 |
166 int DecodeChunkAMD64(const uint8_t *data, size_t size, | 203 int DecodeChunkAMD64(const uint8_t *data, size_t size, |
167 ProcessInstructionFunc process_instruction, | 204 ProcessInstructionFunc process_instruction, |
168 ProcessDecodingErrorFunc process_error, void *userdata); | 205 ProcessDecodingErrorFunc process_error, |
| 206 void *callback_data); |
169 | 207 |
170 int DecodeChunkIA32(const uint8_t *data, size_t size, | 208 int DecodeChunkIA32(const uint8_t *data, size_t size, |
171 ProcessInstructionFunc process_instruction, | 209 ProcessInstructionFunc process_instruction, |
172 ProcessDecodingErrorFunc process_error, void *userdata); | 210 ProcessDecodingErrorFunc process_error, |
| 211 void *callback_data); |
173 | 212 |
174 EXTERN_C_END | 213 EXTERN_C_END |
175 | 214 |
176 #endif /* NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_RAGEL_DECODER_H_ */ | 215 #endif /* NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_RAGEL_DECODER_H_ */ |
OLD | NEW |