| OLD | NEW |
| (Empty) |
| 1 /* | |
| 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 | |
| 4 * found in the LICENSE file. | |
| 5 */ | |
| 6 | |
| 7 #ifndef NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_RAGEL_DECODER_H_ | |
| 8 #define NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_RAGEL_DECODER_H_ | |
| 9 | |
| 10 #include "native_client/src/shared/utils/types.h" | |
| 11 #include "native_client/src/trusted/validator/x86/nacl_cpuid.h" | |
| 12 | |
| 13 EXTERN_C_BEGIN | |
| 14 | |
| 15 enum OperandType { | |
| 16 /* | |
| 17 * These are for general-purpose registers, memory access and immediates. | |
| 18 * They are not used for XMM, MMX etc. | |
| 19 */ | |
| 20 OPERAND_TYPE_8_BIT, | |
| 21 OPERAND_TYPE_16_BIT, | |
| 22 OPERAND_TYPE_32_BIT, | |
| 23 OPERAND_TYPE_64_BIT, | |
| 24 | |
| 25 /* Non-GP registers. */ | |
| 26 OPERAND_TYPE_ST, /* Any X87 register. */ | |
| 27 OPERAND_TYPE_MMX, /* MMX registers: %mmX. */ | |
| 28 OPERAND_TYPE_XMM, /* XMM register: %xmmX. */ | |
| 29 OPERAND_TYPE_YMM, /* YMM registers: %ymmX. */ | |
| 30 OPERAND_TYPE_SEGMENT_REGISTER, /* Operand is segment register: %es … %gs. */ | |
| 31 OPERAND_TYPE_CONTROL_REGISTER, /* Operand is control register: %crX. */ | |
| 32 OPERAND_TYPE_DEBUG_REGISTER, /* Operand is debug register: %drX. */ | |
| 33 OPERAND_TYPE_TEST_REGISTER, /* Operand is test register: %trX. */ | |
| 34 | |
| 35 /* | |
| 36 * All other operand types are not used as register arguments. These are | |
| 37 * immediates or memory. | |
| 38 */ | |
| 39 OPERAND_TYPES_REGISTER_MAX = OPERAND_TYPE_TEST_REGISTER + 1, | |
| 40 | |
| 41 /* See VPERMIL2Px instruction for description of 2-bit operand type. */ | |
| 42 OPERAND_TYPE_2_BIT = OPERAND_TYPES_REGISTER_MAX, | |
| 43 /* | |
| 44 * SIMD memory access operands. Note: 3D Now! and MMX instructions use | |
| 45 * OPERAND_TYPE_64_BIT operands which are used for GP registers, too. | |
| 46 * This overloading is not good and it may be good idea to separate them | |
| 47 * but sadly AMD/Intel manuals conflate them and it was deemed that it's | |
| 48 * too much work to separate them. | |
| 49 */ | |
| 50 OPERAND_TYPE_128_BIT, | |
| 51 OPERAND_TYPE_256_BIT, | |
| 52 | |
| 53 /* OPERAND_X87_SIZE_*_BIT are signed integers in memory.*/ | |
| 54 OPERAND_TYPE_X87_16_BIT, | |
| 55 OPERAND_TYPE_X87_32_BIT, | |
| 56 OPERAND_TYPE_X87_64_BIT, | |
| 57 | |
| 58 /* OPERAND_FLOAT_SIZE_*_BIT are used for in-memory operands. */ | |
| 59 OPERAND_TYPE_FLOAT_32_BIT, | |
| 60 OPERAND_TYPE_FLOAT_64_BIT, | |
| 61 OPERAND_TYPE_FLOAT_80_BIT, | |
| 62 | |
| 63 /* Miscellaneous structures in memory. */ | |
| 64 OPERAND_TYPE_X87_BCD, /* 10-byte packed BCD value. */ | |
| 65 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. */ | |
| 67 OPERAND_TYPE_X87_MMX_XMM_STATE, /* A 512-byte extended x87/MMX/XMM state. */ | |
| 68 OPERAND_TYPE_SELECTOR, /* Operand is 6/10 bytes selector. */ | |
| 69 OPERAND_TYPE_FAR_PTR /* Operand is 6/10 bytes far pointer. */ | |
| 70 }; | |
| 71 | |
| 72 enum OperandName { | |
| 73 /* First 16 registers are compatible with encoding of registers in x86 ABI. */ | |
| 74 REG_RAX, | |
| 75 REG_RCX, | |
| 76 REG_RDX, | |
| 77 REG_RBX, | |
| 78 REG_RSP, | |
| 79 REG_RBP, | |
| 80 REG_RSI, | |
| 81 REG_RDI, | |
| 82 REG_R8, | |
| 83 REG_R9, | |
| 84 REG_R10, | |
| 85 REG_R11, | |
| 86 REG_R12, | |
| 87 REG_R13, | |
| 88 REG_R14, | |
| 89 REG_R15, | |
| 90 /* These are different kinds of operands used in special cases. */ | |
| 91 REG_RM, /* Address in memory via rm field. */ | |
| 92 REG_RIP, /* RIP - used as base in x86-64 mode. */ | |
| 93 REG_RIZ, /* EIZ/RIZ - used as "always zero index" register. */ | |
| 94 REG_IMM, /* Fixed value in imm field. */ | |
| 95 REG_IMM2, /* Fixed value in second imm field. */ | |
| 96 REG_DS_RBX, /* Fox xlat: %ds(%rbx). */ | |
| 97 REG_ES_RDI, /* For string instructions: %es:(%rsi). */ | |
| 98 REG_DS_RSI, /* For string instructions: %ds:(%rdi). */ | |
| 99 REG_PORT_DX, /* 16-bit DX: for in/out instructions. */ | |
| 100 NO_REG, /* For modrm: both index and base can be absent. */ | |
| 101 REG_ST, /* For x87 instructions: implicit %st. */ | |
| 102 JMP_TO, /* Operand is jump target address: usually %rip+offset. */ | |
| 103 }; | |
| 104 | |
| 105 /* | |
| 106 * 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 | |
| 108 * 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 | |
| 110 * offset. | |
| 111 */ | |
| 112 enum DisplacementMode { | |
| 113 DISPNONE, | |
| 114 DISP8, | |
| 115 DISP16, | |
| 116 DISP32, | |
| 117 DISP64 | |
| 118 }; | |
| 119 | |
| 120 struct Instruction { | |
| 121 const char *name; | |
| 122 unsigned char operands_count; | |
| 123 struct { | |
| 124 unsigned char rex; /* Mostly to distingush cases like %ah vs %spl. */ | |
| 125 Bool rex_b_spurious; | |
| 126 Bool rex_x_spurious; | |
| 127 Bool rex_r_spurious; | |
| 128 Bool rex_w_spurious; | |
| 129 Bool data16; /* "Normal", non-rex prefixes. */ | |
| 130 Bool data16_spurious; | |
| 131 Bool lock; | |
| 132 Bool repnz; | |
| 133 Bool repz; | |
| 134 Bool branch_not_taken; | |
| 135 Bool branch_taken; | |
| 136 } prefix; | |
| 137 struct { | |
| 138 enum OperandName name; | |
| 139 enum OperandType type; | |
| 140 } operands[5]; | |
| 141 struct { | |
| 142 enum OperandName base; | |
| 143 enum OperandName index; | |
| 144 int scale; | |
| 145 int64_t offset; | |
| 146 enum DisplacementMode disp_type; | |
| 147 } rm; | |
| 148 uint64_t imm[2]; | |
| 149 const char* att_instruction_suffix; | |
| 150 }; | |
| 151 | |
| 152 typedef void (*ProcessInstructionFunc) (const uint8_t *begin, | |
| 153 const uint8_t *end, | |
| 154 struct Instruction *instruction, | |
| 155 void *userdata); | |
| 156 | |
| 157 typedef void (*ProcessDecodingErrorFunc) (const uint8_t *ptr, | |
| 158 void *userdata); | |
| 159 | |
| 160 /* | |
| 161 * kFullCPUIDFeatures is pre-defined constant of NaClCPUFeaturesX86 type with | |
| 162 * all possible CPUID features enabled. | |
| 163 */ | |
| 164 extern const NaClCPUFeaturesX86 kFullCPUIDFeatures; | |
| 165 | |
| 166 int DecodeChunkAMD64(const uint8_t *data, size_t size, | |
| 167 ProcessInstructionFunc process_instruction, | |
| 168 ProcessDecodingErrorFunc process_error, void *userdata); | |
| 169 | |
| 170 int DecodeChunkIA32(const uint8_t *data, size_t size, | |
| 171 ProcessInstructionFunc process_instruction, | |
| 172 ProcessDecodingErrorFunc process_error, void *userdata); | |
| 173 | |
| 174 EXTERN_C_END | |
| 175 | |
| 176 #endif /* NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_RAGEL_DECODER_H_ */ | |
| OLD | NEW |