| 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. |
| 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 |