| 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 /* | |
| 8 * ncdecode.h - table driven decoder for Native Client. | |
| 9 * | |
| 10 * This header file contains type declarations and constants | |
| 11 * used by the decoder input table | |
| 12 */ | |
| 13 #ifndef NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_X86_NCVAL_SEG_SFI_NCDECODE_H_ | |
| 14 #define NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_X86_NCVAL_SEG_SFI_NCDECODE_H_ | |
| 15 | |
| 16 #include "native_client/src/shared/utils/types.h" | |
| 17 #include "native_client/src/trusted/validator/ncvalidate.h" | |
| 18 #include "native_client/src/trusted/validator/x86/error_reporter.h" | |
| 19 #include "native_client/src/trusted/validator/x86/ncinstbuffer.h" | |
| 20 #include "native_client/src/trusted/validator/x86/x86_insts.h" | |
| 21 | |
| 22 EXTERN_C_BEGIN | |
| 23 | |
| 24 struct NCDecoderInst; | |
| 25 struct NCDecoderState; | |
| 26 | |
| 27 /* Function type for a decoder action. Returns TRUE if action | |
| 28 * was applied successfully. | |
| 29 */ | |
| 30 typedef Bool (*NCDecoderStateAction)(const struct NCDecoderInst* dinst); | |
| 31 | |
| 32 /* Function type for other decoder state methods. */ | |
| 33 typedef void (*NCDecoderStateMethod)(struct NCDecoderState* vstate); | |
| 34 | |
| 35 typedef enum { | |
| 36 NOGROUP = 0, | |
| 37 GROUP1, | |
| 38 GROUP2, | |
| 39 GROUP3, | |
| 40 GROUP4, | |
| 41 /* these comments facilitate counting */ | |
| 42 GROUP5, | |
| 43 GROUP6, | |
| 44 GROUP7, | |
| 45 GROUP8, | |
| 46 GROUP9, | |
| 47 /* these comments facilitate counting */ | |
| 48 GROUP10, | |
| 49 GROUP11, | |
| 50 GROUP12, | |
| 51 GROUP13, | |
| 52 GROUP14, | |
| 53 /* these comments facilitate counting */ | |
| 54 GROUP15, | |
| 55 GROUP16, | |
| 56 GROUP17, | |
| 57 GROUP1A, | |
| 58 GROUPP | |
| 59 } NaClMRMGroups; | |
| 60 /* kModRMOpcodeGroups doesn't work as a const int since it is used */ | |
| 61 /* as an array dimension */ | |
| 62 #define kNaClMRMGroupsRange 20 | |
| 63 | |
| 64 /* Define the maximum value that can be encoded in the modrm mod field. */ | |
| 65 #define kModRMOpcodeGroupSize 8 | |
| 66 | |
| 67 /* Define the maximum register value that can be encoded into the opcode | |
| 68 * byte. | |
| 69 */ | |
| 70 #define kMaxRegisterIndexInOpcode 7 | |
| 71 | |
| 72 /* information derived from the opcode, wherever it happens to be */ | |
| 73 typedef enum { | |
| 74 IMM_UNKNOWN = 0, | |
| 75 IMM_NONE = 1, | |
| 76 IMM_FIXED1 = 2, | |
| 77 IMM_FIXED2 = 3, | |
| 78 IMM_FIXED3 = 4, | |
| 79 IMM_FIXED4 = 5, | |
| 80 IMM_DATAV = 6, | |
| 81 IMM_ADDRV = 7, | |
| 82 IMM_GROUP3_F6 = 8, | |
| 83 IMM_GROUP3_F7 = 9, | |
| 84 IMM_FARPTR = 10, | |
| 85 IMM_MOV_DATAV, /* Special case for 64-bits MOVs (b8 through bf). */ | |
| 86 /* Don't add to this enum without update kNCDecodeImmediateTypeRange */ | |
| 87 /* and updating the tables below which are sized using this constant */ | |
| 88 } NCDecodeImmediateType; | |
| 89 #define kNCDecodeImmediateTypeRange 12 | |
| 90 | |
| 91 /* 255 will force an error */ | |
| 92 static const uint8_t kImmTypeToSize66[kNCDecodeImmediateTypeRange] = | |
| 93 { 0, 0, 1, 2, 3, 4, 2, (NACL_TARGET_SUBARCH == 64 ? 8 : 4), 0, 0, 6, 2}; | |
| 94 static const uint8_t kImmTypeToSize67[kNCDecodeImmediateTypeRange] = | |
| 95 { 0, 0, 1, 2, 3, 4, 4, 2, 0, 0, 4, 4}; | |
| 96 static const uint8_t kImmTypeToSize[kNCDecodeImmediateTypeRange] = | |
| 97 { 0, 0, 1, 2, 3, 4, 4, (NACL_TARGET_SUBARCH == 64 ? 8 : 4), 0, 0, 6, 4 }; | |
| 98 | |
| 99 /* Defines how to decode operands for byte codes. */ | |
| 100 typedef enum { | |
| 101 /* Assume the default size of the operands is 64-bits (if | |
| 102 * not specified in prefix bits). | |
| 103 */ | |
| 104 DECODE_OPS_DEFAULT_64, | |
| 105 /* Assume the default size of the operands is 32-bits (if | |
| 106 * not specified in prefix bits). | |
| 107 */ | |
| 108 DECODE_OPS_DEFAULT_32, | |
| 109 /* Force the size of the operands to 64 bits (prefix bits are | |
| 110 * ignored). | |
| 111 */ | |
| 112 DECODE_OPS_FORCE_64 | |
| 113 } DecodeOpsKind; | |
| 114 | |
| 115 /* Models information on an x86-32 bit instruction. */ | |
| 116 struct OpInfo { | |
| 117 NaClInstType insttype; | |
| 118 uint8_t hasmrmbyte; /* 1 if this inst has an mrm byte, else 0 */ | |
| 119 uint8_t immtype; /* IMM_NONE, IMM_FIXED1, etc. */ | |
| 120 uint8_t opinmrm; /* set to 1..8 if you must find opcode in MRM byte */ | |
| 121 }; | |
| 122 | |
| 123 /* Models a node in a trie of NOP instructions. */ | |
| 124 typedef struct NCNopTrieNode { | |
| 125 /* The matching byte for the trie node. */ | |
| 126 uint8_t matching_byte; | |
| 127 /* The matching modeled nop, if byte matched. */ | |
| 128 struct OpInfo *matching_opinfo; | |
| 129 /* Node to match remaining bytes. */ | |
| 130 struct NCNopTrieNode* success; | |
| 131 /* Node to match remaining bytes. */ | |
| 132 struct NCNopTrieNode* fail; | |
| 133 } NCNopTrieNode; | |
| 134 | |
| 135 /* Predefined value to communicate that the lock prefix was not | |
| 136 * found in an instruction. | |
| 137 */ | |
| 138 static const uint8_t kNoLockPrefixIndex = 0xFF; | |
| 139 | |
| 140 /* Models a parsed x86-32 bit instruction. */ | |
| 141 struct InstInfo { | |
| 142 /* The bytes used to parse the x86-32 instruction (may have added | |
| 143 * zero filler if the instruction straddles the memory segment). | |
| 144 */ | |
| 145 NCInstBytes bytes; | |
| 146 /* The number of prefix bytes in the instruction. */ | |
| 147 uint8_t prefixbytes; /* 0..4 */ | |
| 148 /* Number of opcode bytes in the instruction. */ | |
| 149 uint8_t num_opbytes; | |
| 150 /* non-zero if the instruction contains an SIB byte. */ | |
| 151 uint8_t hassibbyte; | |
| 152 /* The ModRm byte. */ | |
| 153 uint8_t mrm; | |
| 154 /* A NCDecodeImmediateType describing the type of immediate value(s) | |
| 155 * the instruction has. | |
| 156 */ | |
| 157 uint8_t immtype; | |
| 158 /* The number of bytes that define the immediate value(s). */ | |
| 159 uint8_t immbytes; | |
| 160 /* The number of displacement bytes defined by the instruction. */ | |
| 161 uint8_t dispbytes; | |
| 162 /* The set of prefix masks defined by the prefix bytes. */ | |
| 163 uint32_t prefixmask; | |
| 164 /* The prefix form used to select multibyte instructions, or 0 if | |
| 165 * not used. That is, if 66, f2, or f3 is used to select the instruction, | |
| 166 * then this value is non-zero. For example SSE3 instructions. | |
| 167 */ | |
| 168 uint32_t opcode_prefixmask; | |
| 169 /* True if it has a rex prefix. */ | |
| 170 uint8_t rexprefix; | |
| 171 /* Index of lock prefix (F0), or kNoLockPrefixIndex if the lock prefix | |
| 172 * isn't specified. | |
| 173 */ | |
| 174 uint8_t lock_prefix_index; | |
| 175 }; | |
| 176 | |
| 177 /* Models data collected about the parsed instruction. */ | |
| 178 typedef struct NCDecoderInst { | |
| 179 /* The address of the instruction, relative to the begining of the code | |
| 180 * segment. | |
| 181 */ | |
| 182 NaClPcAddress inst_addr; | |
| 183 /* The instruction rule used to decode the instruction. */ | |
| 184 const struct OpInfo* opinfo; | |
| 185 /* The low level details of the instructionm, extracted during parsing. */ | |
| 186 struct InstInfo inst; | |
| 187 /* Pointer to bytes of the parsed instruction (int inst) for easier access. */ | |
| 188 const NCInstBytesPtr inst_bytes; | |
| 189 /* The decoder state the instruction appears in. */ | |
| 190 struct NCDecoderState* dstate; | |
| 191 /* Corresopnding index of this instruction wrt to inst_buffer in | |
| 192 * in the corresponding decoder state NCDecoderState. | |
| 193 */ | |
| 194 size_t inst_index; | |
| 195 /* The number of instructions parsed so far (including this instrruction). | |
| 196 * Used to detect when one tries to get a previous instruction that doesn't | |
| 197 * exist. | |
| 198 */ | |
| 199 size_t inst_count; | |
| 200 /* True if the instruction is unchanged while dynamically replacing code. | |
| 201 * False if the instruction has changed or if code replacement is not being | |
| 202 * performed (i.e. normal validation.) | |
| 203 */ | |
| 204 Bool unchanged; | |
| 205 } NCDecoderInst; | |
| 206 | |
| 207 /* Given a (decoded) instruction, return the instruction that appeared | |
| 208 * n elements before it, or NULL if no such instruction exists. | |
| 209 * | |
| 210 * Parameters: | |
| 211 * dinst - The instruction to look up relative to. | |
| 212 * n - number of elements back to look. | |
| 213 */ | |
| 214 extern NCDecoderInst *PreviousInst(const NCDecoderInst* dinst, int n); | |
| 215 | |
| 216 /* Models decoding instructions in a memory region. | |
| 217 * | |
| 218 * Note: This struct is modeling a notion of a (virtual) base class to parse | |
| 219 * a window of k instructions. In this model, we consider NCDecoderState a | |
| 220 * class that can be (singly) inherited by derived classes. This code | |
| 221 * assumes that the "this" pointer can be cast to a derived class | |
| 222 * using a C cast. This implies that derived classes should have the | |
| 223 * field NCDecoderState as its first field. | |
| 224 * | |
| 225 * Typical use is: | |
| 226 * | |
| 227 * NCDecoderState dstate; | |
| 228 * NCDecoder inst_buffer[BUF_SIZE]; // window of BUF_SIZE instructions. | |
| 229 * NCDecoderStateConstruct(&dstate, mbase, vbase, size, | |
| 230 * inst_buffer, BUF_SIZE); | |
| 231 * NCDecoderStateDecode(&dstate); | |
| 232 * NCDecoderStateDestruct(&dstate); | |
| 233 * | |
| 234 * Note: The old API for this class is further down in this file, | |
| 235 * and should be considered deprecated. | |
| 236 */ | |
| 237 typedef struct NCDecoderState { | |
| 238 /* PROTECTED: */ | |
| 239 | |
| 240 /* The instruction buffer is an array of instructions, used | |
| 241 * by the decoder to define a window of decoded instructions. | |
| 242 * This window automatically moves as instructions are decoded | |
| 243 * so that one can always see the current decoded instruction, | |
| 244 * and some (fixed) number of previously decoded instructions. | |
| 245 */ | |
| 246 NCDecoderInst* inst_buffer; | |
| 247 | |
| 248 /* The number of elements in inst_buffer. Must be greater than zero. */ | |
| 249 size_t inst_buffer_size; | |
| 250 | |
| 251 /* Remaining memory to decode. It is allocated on | |
| 252 * the stack to make it thread-local, and included here | |
| 253 * so that all decoder states have access to it. | |
| 254 */ | |
| 255 NCRemainingMemory memory; | |
| 256 | |
| 257 /* The begining of the memory segment to decode. */ | |
| 258 uint8_t* mbase; | |
| 259 | |
| 260 /* The (virtual) base address of the memory segment. */ | |
| 261 NaClPcAddress vbase; | |
| 262 | |
| 263 /* The number of bytes in the memory segment. */ | |
| 264 NaClMemorySize size; | |
| 265 | |
| 266 /* The index of the current instruction within inst_buffer. */ | |
| 267 size_t cur_inst_index; | |
| 268 | |
| 269 /* Holds the error reporting object to use. */ | |
| 270 NaClErrorReporter* error_reporter; | |
| 271 | |
| 272 /* Member function to apply actions to a decoded instruction. */ | |
| 273 NCDecoderStateAction action_fn; | |
| 274 | |
| 275 /* Member function to process new segment. */ | |
| 276 NCDecoderStateMethod new_segment_fn; | |
| 277 | |
| 278 /* Member function called to report an error with the validity of the | |
| 279 * memory segment. | |
| 280 */ | |
| 281 NCDecoderStateMethod segmentation_error_fn; | |
| 282 | |
| 283 /* Member function called to report other errors while processing the | |
| 284 * memory segment. | |
| 285 */ | |
| 286 NCDecoderStateMethod internal_error_fn; | |
| 287 } NCDecoderState; | |
| 288 | |
| 289 /* | |
| 290 * Construct a decoder state. | |
| 291 * | |
| 292 * Parameters are: | |
| 293 * this - The instance to be constructed. | |
| 294 * mbase - The begining of the memory segment to decode. | |
| 295 * vbase - The (virtual) base address of the memory segment. | |
| 296 * sz - The number of bytes in the memory segment. | |
| 297 * | |
| 298 * Note: Constructors of subclasses of NCDecoderState should | |
| 299 * call this constructor first, to initialize the decoder state. | |
| 300 */ | |
| 301 extern void NCDecoderStateConstruct(NCDecoderState* tthis, | |
| 302 uint8_t* mbase, NaClPcAddress vbase, | |
| 303 NaClMemorySize sz, | |
| 304 NCDecoderInst* inst_buffer, | |
| 305 size_t inst_buffer_size); | |
| 306 | |
| 307 /* Define an error reporter to use to report error messages. | |
| 308 * Note: By default, a decoder state uses the null error reporter, | |
| 309 * which doesn't report error messages. | |
| 310 * | |
| 311 * WARNING: Be sure the error reporter is expecting a NCDecoderInst* for | |
| 312 * the print_inst method. | |
| 313 */ | |
| 314 void NCDecoderStateSetErrorReporter(NCDecoderState* tthis, | |
| 315 NaClErrorReporter* reporter); | |
| 316 | |
| 317 | |
| 318 /* A default, null error reporter for a NCDecoderInst* instruction. */ | |
| 319 extern NaClErrorReporter kNCNullErrorReporter; | |
| 320 | |
| 321 /* | |
| 322 * Decodes the memory segment associated with the decoder state. | |
| 323 * Returns TRUE if able to apply action to all decoded instructions. | |
| 324 * | |
| 325 * Parameters are: | |
| 326 * this - The decoder state. | |
| 327 */ | |
| 328 extern Bool NCDecoderStateDecode(NCDecoderState* tthis); | |
| 329 | |
| 330 /* | |
| 331 * Destruct a decoder state. | |
| 332 * | |
| 333 * Parameters are: | |
| 334 * this - The decoder state. | |
| 335 * | |
| 336 * Note: Destructors of subclasses of NCDecoderState should | |
| 337 * call this destructor last, after the subinstance has been destructed. | |
| 338 */ | |
| 339 extern void NCDecoderStateDestruct(NCDecoderState* tthis); | |
| 340 | |
| 341 /* "Printable" means the value returned by this function can be used for | |
| 342 * printing user-readable output, but it should not be used to influence if the | |
| 343 * validation algorithm passes or fails. The validation algorithm should not | |
| 344 * depend on vbase - in other words, it should not depend on where the code is | |
| 345 * being mapped in memory. | |
| 346 */ | |
| 347 static INLINE NaClPcAddress NCPrintableInstructionAddress( | |
| 348 const NCDecoderInst *dinst) { | |
| 349 return dinst->dstate->vbase + dinst->inst_addr; | |
| 350 } | |
| 351 | |
| 352 struct NCDecoderStatePair; | |
| 353 | |
| 354 /* Models a method that does a compare/update on a pair of instructions from | |
| 355 * the pairwise instruction decoder. Returns true if the action succeeded. | |
| 356 */ | |
| 357 typedef Bool (*NCDecoderStatePairAction)(struct NCDecoderStatePair* tthis, | |
| 358 struct NCDecoderInst* dinst_old, | |
| 359 struct NCDecoderInst* dinst_new); | |
| 360 | |
| 361 /* Models decoding a pair of instruction segments, compariing/updating | |
| 362 * them as appropriate. Assumes that two instruction segments are the same, | |
| 363 * except for some (constant-sized) changes. At the instruction level, | |
| 364 * the instruction lengths are assumed to be the same. Typically, this is | |
| 365 * because the one instruction segment was an updated version of a | |
| 366 * previous instruction segment. | |
| 367 * | |
| 368 * Typical use is: | |
| 369 * | |
| 370 * NCDecoderState dstate_old; | |
| 371 * NCDecoderState dstate_new; | |
| 372 * NCDecoderStatePair dstate_pair; | |
| 373 * ... Code that constructs dstate_old and dstate_new. | |
| 374 * NCDecoderStatePair Construct(&dstate_pair, &dstate_old, &dstate_new); | |
| 375 * NCDecoderStatePairDecode(&dstate_pair); | |
| 376 * NCDecoderStatePairDestruct(&dstate_pair); | |
| 377 */ | |
| 378 typedef struct NCDecoderStatePair { | |
| 379 /* PROTECTED: */ | |
| 380 | |
| 381 /* The old decoder state. */ | |
| 382 NCDecoderState* old_dstate; | |
| 383 | |
| 384 /* The new decoder state. */ | |
| 385 NCDecoderState* new_dstate; | |
| 386 | |
| 387 /* The (virtual method) action to apply to each instruction. */ | |
| 388 NCDecoderStatePairAction action_fn; | |
| 389 | |
| 390 /* Utility function that copies a single instruction in memory, can be used in | |
| 391 * actions. | |
| 392 */ | |
| 393 NaClCopyInstructionFunc copy_func; | |
| 394 } NCDecoderStatePair; | |
| 395 | |
| 396 /* | |
| 397 * Construct a decoder state pair. | |
| 398 * | |
| 399 * Parameters are: | |
| 400 * tthis - The decoder state pair to construct. | |
| 401 * old_dstate - A constructed old decoder state to use. | |
| 402 * new_dstate - A constructed new decoder state to use. | |
| 403 * | |
| 404 * Note: Constructors of subclasses of NCDecoderStatePair should | |
| 405 * call this constructor first, to initialize the decoder pair fields. | |
| 406 */ | |
| 407 extern void NCDecoderStatePairConstruct( | |
| 408 NCDecoderStatePair* tthis, | |
| 409 NCDecoderState* old_dstate, | |
| 410 NCDecoderState* new_dstate, | |
| 411 NaClCopyInstructionFunc copy_func); | |
| 412 | |
| 413 /* | |
| 414 * Decode the memory segments in each instruction state, applying | |
| 415 * the appropriate action on each instruction till either: | |
| 416 * (1) The instruction lengths differ. | |
| 417 * (2) The action returns false. | |
| 418 * Returns true if no instruction lengths differ, and the action | |
| 419 * returns true for all found instructions. | |
| 420 */ | |
| 421 extern Bool NCDecoderStatePairDecode(NCDecoderStatePair* tthis); | |
| 422 | |
| 423 /* | |
| 424 * Destruct a decoder state pair. | |
| 425 * | |
| 426 * Note: Destructors of subclasses of NCDecoderStatePair should | |
| 427 * call this distructor last, after the subinstance has been destructed. | |
| 428 */ | |
| 429 extern void NCDecoderStatePairDestruct(NCDecoderStatePair* tthis); | |
| 430 | |
| 431 EXTERN_C_END | |
| 432 | |
| 433 #endif /* NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_X86_NCVAL_SEG_SFI_NCDECODE_H_ */ | |
| OLD | NEW |