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 FORMAT: register size (8-bit, 32-bit, MMX, XXM, etc), or | |
23 * in-memory structure (far pointer, 256-bit SIMD operands, etc). | |
24 */ | |
20 enum OperandFormat { | 25 enum OperandFormat { |
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_FORMAT_8_BIT, | 30 OPERAND_FORMAT_8_BIT, |
26 OPERAND_FORMAT_16_BIT, | 31 OPERAND_FORMAT_16_BIT, |
27 OPERAND_FORMAT_32_BIT, | 32 OPERAND_FORMAT_32_BIT, |
28 OPERAND_FORMAT_64_BIT, | 33 OPERAND_FORMAT_64_BIT, |
29 | 34 |
30 /* Non-GP registers. */ | 35 /* Non-GP registers. */ |
31 OPERAND_FORMAT_ST, /* Any X87 register. */ | 36 OPERAND_FORMAT_ST, /* Any X87 register. */ |
32 OPERAND_FORMAT_MMX, /* MMX registers: %mmX. */ | 37 OPERAND_FORMAT_MMX, /* MMX registers: %mmX. */ |
33 OPERAND_FORMAT_XMM, /* XMM register: %xmmX. */ | 38 OPERAND_FORMAT_XMM, /* XMM register: %xmmX. */ |
34 OPERAND_FORMAT_YMM, /* YMM registers: %ymmX. */ | 39 OPERAND_FORMAT_YMM, /* YMM registers: %ymmX. */ |
35 OPERAND_FORMAT_SEGMENT_REGISTER, /* Operand is segment register: %es … %gs. */ | 40 OPERAND_FORMAT_SEGMENT_REGISTER, /* Operand is segment register: %es...%gs. */ |
36 OPERAND_FORMAT_CONTROL_REGISTER, /* Operand is control register: %crX. */ | 41 OPERAND_FORMAT_CONTROL_REGISTER, /* Operand is control register: %crX. */ |
37 OPERAND_FORMAT_DEBUG_REGISTER, /* Operand is debug register: %drX. */ | 42 OPERAND_FORMAT_DEBUG_REGISTER, /* Operand is debug register: %drX. */ |
38 OPERAND_FORMAT_TEST_REGISTER, /* Operand is test register: %trX. */ | 43 OPERAND_FORMAT_TEST_REGISTER, /* Operand is test register: %trX. */ |
39 | 44 |
40 /* | 45 /* |
41 * All other operand format are not used as register arguments. These are | 46 * All other operand format are not used as register arguments. These are |
42 * immediates or memory. | 47 * immediates or memory. |
43 */ | 48 */ |
44 OPERAND_FORMATS_REGISTER_MAX = OPERAND_FORMAT_TEST_REGISTER + 1, | 49 OPERAND_FORMATS_REGISTER_MAX = OPERAND_FORMAT_TEST_REGISTER + 1, |
45 | 50 |
46 /* See VPERMIL2Px instruction for description of 2-bit operand type. */ | 51 /* See VPERMIL2Px instruction for description of 2-bit operand type. */ |
47 OPERAND_FORMAT_2_BIT = OPERAND_FORMATS_REGISTER_MAX, | 52 OPERAND_FORMAT_2_BIT = OPERAND_FORMATS_REGISTER_MAX, |
48 OPERAND_FORMAT_MEMORY | 53 OPERAND_FORMAT_MEMORY |
49 }; | 54 }; |
50 | 55 |
56 /* | |
57 * Instruction operand NAME: register number (REG_RAX means any of the following | |
58 * registers: %al/%ax/%eax/%rax/%st(0)/%mm0/%xmm0/%ymm0/%es/%cr0/%db0/%tr0), or | |
59 * non-register operand (REG_RM means address in memory specified via "ModR/M | |
60 * byte" (plus may be "SIB byte" or displacement), REG_DS_RBX is special operand | |
61 * of "xlat" instruction, REG_ST is to of x87 stack and so on - see below for | |
62 * for the full list). | |
63 */ | |
51 enum OperandName { | 64 enum OperandName { |
52 /* First 16 registers are compatible with encoding of registers in x86 ABI. */ | 65 /* First 16 registers are compatible with encoding of registers in x86 ABI. */ |
53 REG_RAX, | 66 REG_RAX, |
54 REG_RCX, | 67 REG_RCX, |
55 REG_RDX, | 68 REG_RDX, |
56 REG_RBX, | 69 REG_RBX, |
57 REG_RSP, | 70 REG_RSP, |
58 REG_RBP, | 71 REG_RBP, |
59 REG_RSI, | 72 REG_RSI, |
60 REG_RDI, | 73 REG_RDI, |
61 REG_R8, | 74 REG_R8, |
62 REG_R9, | 75 REG_R9, |
63 REG_R10, | 76 REG_R10, |
64 REG_R11, | 77 REG_R11, |
65 REG_R12, | 78 REG_R12, |
66 REG_R13, | 79 REG_R13, |
67 REG_R14, | 80 REG_R14, |
68 REG_R15, | 81 REG_R15, |
69 /* These are different kinds of operands used in special cases. */ | 82 /* These are different kinds of operands used in special cases. */ |
70 REG_RM, /* Address in memory via rm field. */ | 83 REG_RM, /* Address in memory via ModR/M (+SIB). */ |
71 REG_RIP, /* RIP - used as base in x86-64 mode. */ | 84 REG_RIP, /* RIP - used as base in x86-64 mode. */ |
72 REG_RIZ, /* EIZ/RIZ - used as "always zero index" register. */ | 85 REG_RIZ, /* EIZ/RIZ - used as "always zero index" register. */ |
73 REG_IMM, /* Fixed value in imm field. */ | 86 REG_IMM, /* Fixed value in imm field. */ |
74 REG_IMM2, /* Fixed value in second imm field. */ | 87 REG_IMM2, /* Fixed value in second imm field. */ |
75 REG_DS_RBX, /* Fox xlat: %ds(%rbx). */ | 88 REG_DS_RBX, /* For xlat: %ds:(%rbx). */ |
76 REG_ES_RDI, /* For string instructions: %es:(%rsi). */ | 89 REG_ES_RDI, /* For string instructions: %es:(%rsi). */ |
77 REG_DS_RSI, /* For string instructions: %ds:(%rdi). */ | 90 REG_DS_RSI, /* For string instructions: %ds:(%rdi). */ |
78 REG_PORT_DX, /* 16-bit DX: for in/out instructions. */ | 91 REG_PORT_DX, /* 16-bit DX: for in/out instructions. */ |
79 NO_REG, /* For modrm: both index and base can be absent. */ | 92 NO_REG, /* For modrm: both index and base can be absent. */ |
80 REG_ST, /* For x87 instructions: implicit %st. */ | 93 REG_ST, /* For x87 instructions: implicit %st. */ |
81 JMP_TO /* Operand is jump target address: usually %rip+offset. */ | 94 JMP_TO /* Operand is jump target address: usually %rip+offset. */ |
82 }; | 95 }; |
83 | 96 |
84 /* | 97 /* |
85 * Displacement can be of four different sizes in x86 instruction set: nothing, | 98 * Displacement can be of four different sizes in x86 instruction set: nothing, |
86 * 8-bit, 16-bit, 32-bit, and 64-bit. These are traditionally treated slightly | 99 * 8-bit, 16-bit, 32-bit, and 64-bit. These are traditionally treated slightly |
87 * differently by decoders: 8-bit are usually printed as signed offset, while | 100 * differently by decoders: 8-bit are usually printed as signed offset, while |
88 * 32-bit (in ia32 mode) and 64-bit (in amd64 mode) are printed as unsigned | 101 * 32-bit (in ia32 mode) and 64-bit (in amd64 mode) are printed as unsigned |
89 * offset. | 102 * offset. |
90 */ | 103 */ |
91 enum DisplacementMode { | 104 enum DisplacementMode { |
92 DISPNONE, | 105 DISPNONE, |
93 DISP8, | 106 DISP8, |
94 DISP16, | 107 DISP16, |
95 DISP32, | 108 DISP32, |
96 DISP64 | 109 DISP64 |
97 }; | 110 }; |
98 | 111 |
112 /* | |
113 * Information about decoded instruction: name, operands, prefixes, etc. | |
114 */ | |
99 struct Instruction { | 115 struct Instruction { |
100 const char *name; | 116 const char *name; |
101 unsigned char operands_count; | 117 unsigned char operands_count; |
102 struct { | 118 struct { |
103 unsigned char rex; /* Mostly to distingush cases like %ah vs %spl. */ | 119 unsigned char rex; /* Mostly to distingush cases like %ah vs %spl. */ |
104 Bool rex_b_spurious; | 120 Bool rex_b_spurious; |
105 Bool rex_x_spurious; | 121 Bool rex_x_spurious; |
106 Bool rex_r_spurious; | 122 Bool rex_r_spurious; |
107 Bool rex_w_spurious; | 123 Bool rex_w_spurious; |
108 Bool data16; /* "Normal", non-rex prefixes. */ | 124 Bool data16; /* "Normal", non-rex prefixes. */ |
(...skipping 12 matching lines...) Expand all Loading... | |
121 enum OperandName index; | 137 enum OperandName index; |
122 int scale; | 138 int scale; |
123 int64_t offset; | 139 int64_t offset; |
124 enum DisplacementMode disp_type; | 140 enum DisplacementMode disp_type; |
125 } rm; | 141 } rm; |
126 uint64_t imm[2]; | 142 uint64_t imm[2]; |
127 const char* att_instruction_suffix; | 143 const char* att_instruction_suffix; |
128 }; | 144 }; |
129 | 145 |
130 /* | 146 /* |
147 * Instruction processing callback: called once for each instruction in a stream | |
148 * | |
131 * "begin" points to first byte of the instruction | 149 * "begin" points to first byte of the instruction |
132 * "end" points to the last byte of the instruction | 150 * "end" points to the first byte of the next instruction |
133 * for single-byte instruction “begin” == “end” | 151 * for single-byte instruction "begin + 1" == "end" |
134 * "instruction" is detailed information about instruction | 152 * "instruction" contains detailed information about instruction |
135 */ | 153 */ |
136 typedef void (*ProcessInstructionFunc) (const uint8_t *begin, | 154 typedef void (*ProcessInstructionFunc) (const uint8_t *begin, |
137 const uint8_t *end, | 155 const uint8_t *end, |
138 struct Instruction *instruction, | 156 struct Instruction *instruction, |
139 void *userdata); | 157 void *callback_data); |
140 | 158 |
141 /* | 159 /* |
160 * Decoding error: called when decoder's DFA does not recognize the instruction. | |
161 * | |
142 * "ptr" points to the first byte rejected by DFA and can be used in more | 162 * "ptr" points to the first byte rejected by DFA and can be used in more |
143 * advanced decoders to try to do some kind of recovery. | 163 * advanced decoders to try to do some kind of recovery. |
144 */ | 164 */ |
145 typedef void (*ProcessDecodingErrorFunc) (const uint8_t *ptr, | 165 typedef void (*ProcessDecodingErrorFunc) (const uint8_t *ptr, |
146 void *userdata); | 166 void *callback_data); |
147 | 167 |
148 /* | 168 /* |
149 * kFullCPUIDFeatures is pre-defined constant of NaClCPUFeaturesX86 type with | 169 * kFullCPUIDFeatures is pre-defined constant of NaClCPUFeaturesX86 type with |
150 * all possible CPUID features enabled. | 170 * all possible CPUID features enabled. |
151 */ | 171 */ |
152 extern const NaClCPUFeaturesX86 kFullCPUIDFeatures; | 172 extern const NaClCPUFeaturesX86 kFullCPUIDFeatures; |
153 | 173 |
174 /* | |
175 * Returns True when piece of code is valid piece of code. | |
176 * Returns False If ragel machine does not accept piece of code. | |
halyavin
2013/03/25 09:43:41
Returns true
Returns false, if
khim
2013/03/25 11:33:48
Oops. That's C, not python. TRUE/FALSE, then.
| |
177 * process_instruction callback is called for each instruction accepted by | |
178 * ragel machine | |
179 */ | |
154 int DecodeChunkAMD64(const uint8_t *data, size_t size, | 180 int DecodeChunkAMD64(const uint8_t *data, size_t size, |
155 ProcessInstructionFunc process_instruction, | 181 ProcessInstructionFunc process_instruction, |
156 ProcessDecodingErrorFunc process_error, void *userdata); | 182 ProcessDecodingErrorFunc process_error, |
183 void *callback_data); | |
157 | 184 |
158 int DecodeChunkIA32(const uint8_t *data, size_t size, | 185 int DecodeChunkIA32(const uint8_t *data, size_t size, |
159 ProcessInstructionFunc process_instruction, | 186 ProcessInstructionFunc process_instruction, |
160 ProcessDecodingErrorFunc process_error, void *userdata); | 187 ProcessDecodingErrorFunc process_error, |
188 void *callback_data); | |
161 | 189 |
162 EXTERN_C_END | 190 EXTERN_C_END |
163 | 191 |
164 #endif /* NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_RAGEL_DECODER_H_ */ | 192 #endif /* NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_RAGEL_DECODER_H_ */ |
OLD | NEW |