| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2011 The Native Client Authors. All rights reserved. | 2 * Copyright (c) 2011 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 * Defines an instruction (decoder), based on the current location of | 8 * Defines an instruction (decoder), based on the current location of |
| 9 * the instruction iterator. The instruction decoder takes a list | 9 * the instruction iterator. The instruction decoder takes a list |
| 10 * of candidate opcode (instruction) patterns, and searches for the | 10 * of candidate opcode (instruction) patterns, and searches for the |
| 11 * first candidate that matches the requirements of the opcode pattern. | 11 * first candidate that matches the requirements of the opcode pattern. |
| 12 */ | 12 */ |
| 13 | 13 |
| 14 #include <stdio.h> | |
| 15 #include <assert.h> | |
| 16 | 14 |
| 17 #include "native_client/src/trusted/validator_x86/nc_inst_state.h" | 15 #include "native_client/src/trusted/validator_x86/nc_inst_state.h" |
| 18 | 16 |
| 19 #include "native_client/src/shared/platform/nacl_log.h" | |
| 20 #include "native_client/src/trusted/validator_x86/nc_inst_iter.h" | |
| 21 #include "native_client/src/trusted/validator_x86/nc_inst_state_internal.h" | |
| 22 #include "native_client/src/trusted/validator_x86/nc_inst_trans.h" | |
| 23 #include "native_client/src/trusted/validator_x86/nc_segment.h" | |
| 24 #include "native_client/src/trusted/validator_x86/ncop_exps.h" | |
| 25 #include "native_client/src/trusted/validator_x86/ncopcode_desc.h" | |
| 26 #ifdef _WIN64 | |
| 27 #include "gen/native_client/src/trusted/validator_x86/nc_opcode_table64.h" | |
| 28 #else | |
| 29 #include "gen/native_client/src/trusted/validator_x86/nc_opcode_table.h" | |
| 30 #endif | |
| 31 | |
| 32 /* To turn on debugging of instruction decoding, change value of | 17 /* To turn on debugging of instruction decoding, change value of |
| 33 * DEBUGGING to 1. | 18 * DEBUGGING to 1. |
| 34 */ | 19 */ |
| 35 #define DEBUGGING 0 | 20 #define DEBUGGING 0 |
| 36 | 21 |
| 37 #include "native_client/src/shared/utils/debugging.h" | 22 #include "native_client/src/trusted/validator_x86/nc_inst_state_statics.c" |
| 38 | |
| 39 /* Given the current location of the instruction iterator, initialize | |
| 40 * the given state (to match). | |
| 41 */ | |
| 42 static void NaClInstStateInit(NaClInstIter* iter, NaClInstState* state) { | |
| 43 NaClMemorySize limit; | |
| 44 NCInstBytesInit(&state->bytes); | |
| 45 state->vpc = iter->segment->vbase + iter->index; | |
| 46 limit = iter->segment->size - iter->index; | |
| 47 if (limit > NACL_MAX_BYTES_PER_X86_INSTRUCTION) { | |
| 48 limit = NACL_MAX_BYTES_PER_X86_INSTRUCTION; | |
| 49 } | |
| 50 state->length_limit = (uint8_t) limit; | |
| 51 DEBUG(NaClLog(LOG_INFO, | |
| 52 "length limit = %"NACL_PRIu8"\n", state->length_limit)); | |
| 53 state->num_prefix_bytes = 0; | |
| 54 state->rexprefix = 0; | |
| 55 state->num_rex_prefixes = 0; | |
| 56 state->modrm = 0; | |
| 57 state->has_prefix_duplicates = FALSE; | |
| 58 state->has_ambig_segment_prefixes = FALSE; | |
| 59 state->has_sib = FALSE; | |
| 60 state->sib = 0; | |
| 61 state->num_disp_bytes = 0; | |
| 62 state->first_disp_byte = 0; | |
| 63 state->num_imm_bytes = 0; | |
| 64 state->first_imm_byte = 0; | |
| 65 state->num_imm2_bytes = 0; | |
| 66 state->prefix_mask = 0; | |
| 67 state->inst = NULL; | |
| 68 state->nodes.is_defined = FALSE; | |
| 69 state->nodes.number_expr_nodes = 0; | |
| 70 } | |
| 71 | |
| 72 /* Computes the number of bytes defined for operands of the matched | |
| 73 * instruction of the given state. | |
| 74 */ | |
| 75 static int NaClExtractOpSize(NaClInstState* state) { | |
| 76 if (state->inst->flags & NACL_IFLAG(OperandSize_b)) { | |
| 77 return 1; | |
| 78 } | |
| 79 if (NACL_TARGET_SUBARCH == 64) { | |
| 80 if ((state->rexprefix && state->rexprefix & 0x8) || | |
| 81 (state->inst->flags & NACL_IFLAG(OperandSizeForce64))) { | |
| 82 return 8; | |
| 83 } | |
| 84 } | |
| 85 if ((state->prefix_mask & kPrefixDATA16) && | |
| 86 (NACL_EMPTY_IFLAGS == | |
| 87 (state->inst->flags & NACL_IFLAG(SizeIgnoresData16)))) { | |
| 88 return 2; | |
| 89 } | |
| 90 if ((NACL_TARGET_SUBARCH == 64) && | |
| 91 (state->inst->flags & NACL_IFLAG(OperandSizeDefaultIs64))) { | |
| 92 return 8; | |
| 93 } | |
| 94 return 4; | |
| 95 } | |
| 96 | |
| 97 /* Computes the number of bits defined for addresses of the matched | |
| 98 * instruction of the given state. | |
| 99 */ | |
| 100 static int NaClExtractAddressSize(NaClInstState* state) { | |
| 101 if (NACL_TARGET_SUBARCH == 64) { | |
| 102 return (state->prefix_mask & kPrefixADDR16) ? 32 : 64; | |
| 103 } else { | |
| 104 return (state->prefix_mask & kPrefixADDR16) ? 16 : 32; | |
| 105 } | |
| 106 } | |
| 107 | |
| 108 /* Manual implies only 4 bytes is allowed, but I have found up to 6. | |
| 109 * Why don't we allow any number, so long as (1) There is room for | |
| 110 * at least one opcode byte, and (2) we don't exceed the max bytes. | |
| 111 */ | |
| 112 static const int kNaClMaximumPrefixBytes = | |
| 113 NACL_MAX_BYTES_PER_X86_INSTRUCTION - 1; | |
| 114 | |
| 115 /* Captures ambiguous segment prefix forms. Used to make | |
| 116 * detection of multiple prefix segment bytes. | |
| 117 */ | |
| 118 static const uint32_t segment_prefix_forms = | |
| 119 kPrefixSEGCS | kPrefixSEGSS | kPrefixSEGFS | | |
| 120 kPrefixSEGGS | kPrefixSEGES | kPrefixSEGDS; | |
| 121 | |
| 122 /* Match any prefix bytes that can be associated with the instruction | |
| 123 * currently being matched. | |
| 124 */ | |
| 125 static Bool NaClConsumePrefixBytes(NaClInstState* state) { | |
| 126 uint8_t next_byte; | |
| 127 int i; | |
| 128 uint32_t prefix_form; | |
| 129 int rex_index = -1; | |
| 130 for (i = 0; i < kNaClMaximumPrefixBytes; ++i) { | |
| 131 /* Quit early if no more bytes in segment. */ | |
| 132 if (state->bytes.length >= state->length_limit) break; | |
| 133 | |
| 134 /* Look up the corresponding prefix bit associated | |
| 135 * with the next byte in the segment, and record it. | |
| 136 */ | |
| 137 next_byte = NCRemainingMemoryLookahead(state->bytes.memory,0); | |
| 138 prefix_form = kNaClPrefixTable[next_byte]; | |
| 139 if (prefix_form == 0) break; | |
| 140 next_byte = NCInstBytesRead(&state->bytes); | |
| 141 DEBUG(NaClLog(LOG_INFO, | |
| 142 "Consume prefix[%d]: %02"NACL_PRIx8" => %"NACL_PRIx32"\n", | |
| 143 i, next_byte, prefix_form)); | |
| 144 /* Before updating prefix mask, determine if the prefix byte is | |
| 145 * a duplicate. | |
| 146 */ | |
| 147 if ((state->prefix_mask & prefix_form)) { | |
| 148 state->has_prefix_duplicates = TRUE; | |
| 149 DEBUG(NaClLog(LOG_INFO, | |
| 150 "duplicate prefix %02"NACL_PRIx8" detected.\n", next_byte)); | |
| 151 } else if ((prefix_form & segment_prefix_forms) && | |
| 152 (state->prefix_mask & segment_prefix_forms)) { | |
| 153 state->has_ambig_segment_prefixes = TRUE; | |
| 154 DEBUG(NaClLog(LOG_INFO, | |
| 155 "ambiguos segment prefix %02"NACL_PRIx8" detected.\n", | |
| 156 next_byte)); | |
| 157 } | |
| 158 state->prefix_mask |= prefix_form; | |
| 159 ++state->num_prefix_bytes; | |
| 160 DEBUG(NaClLog(LOG_INFO, | |
| 161 " prefix mask: %08"NACL_PRIx32"\n", state->prefix_mask)); | |
| 162 | |
| 163 /* If the prefix byte is a REX prefix, record its value, since | |
| 164 * bits 5-8 of this prefix bit may be needed later. | |
| 165 */ | |
| 166 if (NACL_TARGET_SUBARCH == 64) { | |
| 167 if (prefix_form == kPrefixREX) { | |
| 168 state->rexprefix = next_byte; | |
| 169 DEBUG(NaClLog(LOG_INFO, | |
| 170 " rexprefix = %02"NACL_PRIx8"\n", state->rexprefix)); | |
| 171 ++state->num_rex_prefixes; | |
| 172 rex_index = i; | |
| 173 } | |
| 174 } | |
| 175 } | |
| 176 if (NACL_TARGET_SUBARCH == 64) { | |
| 177 /* REX prefix must be last, unless FO exists. If FO | |
| 178 * exists, it must be after REX (Intel Manual). | |
| 179 * | |
| 180 * NOTE: (karl) It appears that this constraint is violated | |
| 181 * with compiled code of /bin/ld_static. According to AMD, | |
| 182 * the rex prefix must be last. Changing code to allow REX | |
| 183 * prefix to occur anywhere. | |
| 184 */ | |
| 185 if (rex_index >= 0) { | |
| 186 return (rex_index + 1) == state->num_prefix_bytes; | |
| 187 } | |
| 188 } | |
| 189 return TRUE; | |
| 190 } | |
| 191 | |
| 192 /* Structure holding the results of consuming the opcode bytes of the | |
| 193 * instruction. | |
| 194 */ | |
| 195 typedef struct { | |
| 196 /* The (last) byte of the matched opcode. */ | |
| 197 uint8_t opcode_byte; | |
| 198 /* The most specific prefix that the opcode bytes can match | |
| 199 * (or OpcodePrefixEnumSize if no such patterns exist). | |
| 200 */ | |
| 201 NaClInstPrefix matched_prefix; | |
| 202 /* The number of bytes to subtract from the instruction length, | |
| 203 * the next time GetNextNaClInstCandidates is called. | |
| 204 */ | |
| 205 uint8_t next_length_adjustment; | |
| 206 } NaClInstPrefixDescriptor; | |
| 207 | |
| 208 /* Assuming we have matched the byte sequence OF 38, consume the corresponding | |
| 209 * following (instruction) opcode byte, returning the most specific prefix the | |
| 210 * patterns can match (or NaClInstPrefixEnumSize if no such patterns exist); | |
| 211 */ | |
| 212 static void NaClConsume0F38XXNaClInstBytes(NaClInstState* state, | |
| 213 NaClInstPrefixDescriptor* desc) { | |
| 214 /* Fail if there are no more bytes. Otherwise, read the next | |
| 215 * byte. | |
| 216 */ | |
| 217 if (state->bytes.length >= state->length_limit) { | |
| 218 desc->matched_prefix = NaClInstPrefixEnumSize; | |
| 219 return; | |
| 220 } | |
| 221 | |
| 222 desc->opcode_byte = NCInstBytesRead(&state->bytes); | |
| 223 if (state->prefix_mask & kPrefixREPNE) { | |
| 224 desc->matched_prefix = PrefixF20F38; | |
| 225 } | |
| 226 else if (state->prefix_mask & kPrefixDATA16) { | |
| 227 desc->matched_prefix = Prefix660F38; | |
| 228 } else if ((state->prefix_mask & ~kPrefixREX) == 0) { | |
| 229 desc->matched_prefix = Prefix0F38; | |
| 230 } else { | |
| 231 /* Other prefixes like F3 cause an undefined instruction error. */ | |
| 232 desc->matched_prefix = NaClInstPrefixEnumSize; | |
| 233 } | |
| 234 } | |
| 235 | |
| 236 /* Assuming we have matched the byte sequence OF 3A, consume the corresponding | |
| 237 * following (instruction) opcode byte, returning the most specific prefix the | |
| 238 * patterns can match (or NaClInstPrefixEnumSize if no such patterns exist). | |
| 239 */ | |
| 240 static void NaClConsume0F3AXXNaClInstBytes(NaClInstState* state, | |
| 241 NaClInstPrefixDescriptor* desc) { | |
| 242 /* Fail if there are no more bytes. Otherwise, read the next | |
| 243 * byte and choose appropriate prefix. | |
| 244 */ | |
| 245 if (state->bytes.length >= state->length_limit) { | |
| 246 desc->matched_prefix = NaClInstPrefixEnumSize; | |
| 247 return; | |
| 248 } | |
| 249 | |
| 250 desc->opcode_byte = NCInstBytesRead(&state->bytes); | |
| 251 if (state->prefix_mask & kPrefixDATA16) { | |
| 252 desc->matched_prefix = Prefix660F3A; | |
| 253 } else if ((state->prefix_mask & ~kPrefixREX) == 0) { | |
| 254 desc->matched_prefix = Prefix0F3A; | |
| 255 } else { | |
| 256 /* Other prefixes like F3 cause an undefined instruction error. */ | |
| 257 desc->matched_prefix = NaClInstPrefixEnumSize; | |
| 258 } | |
| 259 } | |
| 260 | |
| 261 /* Assuming we have matched byte OF, consume the corresponding | |
| 262 * following (instruction) opcode byte, returning the most specific | |
| 263 * prefix the patterns can match (or NaClInstPrefixEnumSize if no such | |
| 264 * patterns exist). | |
| 265 */ | |
| 266 static void NaClConsume0FXXNaClInstBytes(NaClInstState* state, | |
| 267 NaClInstPrefixDescriptor* desc) { | |
| 268 if (state->prefix_mask & kPrefixREPNE) { | |
| 269 desc->matched_prefix = PrefixF20F; | |
| 270 } else if (state->prefix_mask & kPrefixREP) { | |
| 271 desc->matched_prefix = PrefixF30F; | |
| 272 } else if (state->prefix_mask & kPrefixDATA16) { | |
| 273 desc->matched_prefix = Prefix660F; | |
| 274 } else { | |
| 275 desc->matched_prefix = Prefix0F; | |
| 276 } | |
| 277 } | |
| 278 | |
| 279 /* Consume one of the x87 instructions that begin with D8-Df, and | |
| 280 * match the most specific prefix pattern the opcode bytes can match. | |
| 281 */ | |
| 282 static void NaClConsumeX87NaClInstBytes(NaClInstState* state, | |
| 283 NaClInstPrefixDescriptor* desc) { | |
| 284 if (state->bytes.length < state->length_limit) { | |
| 285 /* Can be two byte opcode. */ | |
| 286 desc->matched_prefix = PrefixD8 + | |
| 287 (((unsigned) desc->opcode_byte) - 0xD8); | |
| 288 desc->opcode_byte = NCInstBytesRead(&state->bytes); | |
| 289 return; | |
| 290 } | |
| 291 | |
| 292 /* If reached, can only be single byte opcode, match as such. */ | |
| 293 desc->matched_prefix = NoPrefix; | |
| 294 } | |
| 295 | |
| 296 /* Consume the opcode bytes, and return the most specific prefix pattern | |
| 297 * the opcode bytes can match (or NaClInstPrefixEnumSize if no such pattern | |
| 298 * exists). | |
| 299 */ | |
| 300 static void NaClConsumeInstBytes(NaClInstState* state, | |
| 301 NaClInstPrefixDescriptor* desc) { | |
| 302 | |
| 303 /* Initialize descriptor to the fail state. */ | |
| 304 desc->opcode_byte = 0x0; | |
| 305 desc->matched_prefix = NaClInstPrefixEnumSize; | |
| 306 desc->next_length_adjustment = 0; | |
| 307 | |
| 308 /* Be sure that we don't exceed the segment length. */ | |
| 309 if (state->bytes.length >= state->length_limit) return; | |
| 310 | |
| 311 desc->opcode_byte = NCInstBytesRead(&state->bytes); | |
| 312 switch (desc->opcode_byte) { | |
| 313 case 0x0F: | |
| 314 if (state->bytes.length >= state->length_limit) return; | |
| 315 desc->opcode_byte = NCInstBytesRead(&state->bytes); | |
| 316 switch (desc->opcode_byte) { | |
| 317 case 0x38: | |
| 318 NaClConsume0F38XXNaClInstBytes(state, desc); | |
| 319 break; | |
| 320 case 0x3a: | |
| 321 NaClConsume0F3AXXNaClInstBytes(state, desc); | |
| 322 break; | |
| 323 default: | |
| 324 NaClConsume0FXXNaClInstBytes(state, desc); | |
| 325 break; | |
| 326 } | |
| 327 break; | |
| 328 case 0xD8: | |
| 329 case 0xD9: | |
| 330 case 0xDA: | |
| 331 case 0xDB: | |
| 332 case 0xDC: | |
| 333 case 0xDD: | |
| 334 case 0xDE: | |
| 335 case 0xDF: | |
| 336 NaClConsumeX87NaClInstBytes(state, desc); | |
| 337 break; | |
| 338 default: | |
| 339 desc->matched_prefix = NoPrefix; | |
| 340 break; | |
| 341 } | |
| 342 DEBUG(NaClLog(LOG_INFO, | |
| 343 "matched prefix = %s\n", | |
| 344 NaClInstPrefixName(desc->matched_prefix))); | |
| 345 } | |
| 346 | |
| 347 /* Compute the operand and address sizes for the instruction. Then, verify | |
| 348 * that the opcode (instruction) pattern allows for such sizes. Aborts | |
| 349 * the pattern match if any problems. | |
| 350 */ | |
| 351 static Bool NaClConsumeAndCheckOperandSize(NaClInstState* state) { | |
| 352 state->operand_size = NaClExtractOpSize(state); | |
| 353 DEBUG(NaClLog(LOG_INFO, | |
| 354 "operand size = %"NACL_PRIu8"\n", state->operand_size)); | |
| 355 if (state->inst->flags & | |
| 356 (NACL_IFLAG(OperandSize_w) | NACL_IFLAG(OperandSize_v) | | |
| 357 NACL_IFLAG(OperandSize_o))) { | |
| 358 NaClIFlags good = 1; | |
| 359 switch (state->operand_size) { | |
| 360 case 2: | |
| 361 good = (state->inst->flags & NACL_IFLAG(OperandSize_w)); | |
| 362 break; | |
| 363 case 4: | |
| 364 good = (state->inst->flags & NACL_IFLAG(OperandSize_v)); | |
| 365 break; | |
| 366 case 8: | |
| 367 good = (state->inst->flags & NACL_IFLAG(OperandSize_o)); | |
| 368 break; | |
| 369 default: | |
| 370 good = 0; | |
| 371 break; | |
| 372 } | |
| 373 if (!good) { | |
| 374 /* The flags associated with the opcode (instruction) don't | |
| 375 * allow the computed sizes, abort the match of the instruction. | |
| 376 */ | |
| 377 DEBUG(NaClLog(LOG_INFO, | |
| 378 "Operand size %"NACL_PRIu8 | |
| 379 " doesn't match flag requirement!\n", | |
| 380 state->operand_size)); | |
| 381 return FALSE; | |
| 382 } | |
| 383 } | |
| 384 return TRUE; | |
| 385 } | |
| 386 | |
| 387 static Bool NaClConsumeAndCheckAddressSize(NaClInstState* state) { | |
| 388 state->address_size = NaClExtractAddressSize(state); | |
| 389 DEBUG(NaClLog(LOG_INFO, | |
| 390 "Address size = %"NACL_PRIu8"\n", state->address_size)); | |
| 391 if (state->inst->flags & | |
| 392 (NACL_IFLAG(AddressSize_w) | NACL_IFLAG(AddressSize_v) | | |
| 393 NACL_IFLAG(AddressSize_o))) { | |
| 394 NaClIFlags good = 1; | |
| 395 switch (state->address_size) { | |
| 396 case 16: | |
| 397 good = (state->inst->flags & NACL_IFLAG(AddressSize_w)); | |
| 398 break; | |
| 399 case 32: | |
| 400 good = (state->inst->flags & NACL_IFLAG(AddressSize_v)); | |
| 401 break; | |
| 402 case 64: | |
| 403 good = (state->inst->flags & NACL_IFLAG(AddressSize_o)); | |
| 404 break; | |
| 405 default: | |
| 406 good = 0; | |
| 407 break; | |
| 408 } | |
| 409 if (!good) { | |
| 410 /* The flags associated with the opcode (instruction) don't | |
| 411 * allow the computed sizes, abort the match of the instruction. | |
| 412 */ | |
| 413 DEBUG(NaClLog(LOG_INFO, | |
| 414 "Address size %"NACL_PRIu8 | |
| 415 " doesn't match flag requirement!\n", | |
| 416 state->address_size)); | |
| 417 return FALSE; | |
| 418 } | |
| 419 } | |
| 420 return TRUE; | |
| 421 } | |
| 422 | |
| 423 /* Returns true if the instruction requires a ModRm bytes. */ | |
| 424 static Bool NaClInstRequiresModRm(NaClInstState* state) { | |
| 425 return | |
| 426 (NACL_EMPTY_IFLAGS != | |
| 427 (state->inst->flags & NACL_IFLAG(OpcodeUsesModRm))); | |
| 428 } | |
| 429 | |
| 430 /* Consume the Mod/Rm byte of the instruction, if applicable. | |
| 431 * Aborts the pattern match if any problems. | |
| 432 */ | |
| 433 static Bool NaClConsumeModRm(NaClInstState* state) { | |
| 434 /* First check if the opcode (instruction) pattern specifies that | |
| 435 * a Mod/Rm byte is needed, and that reading it will not walk | |
| 436 * past the end of the code segment. | |
| 437 */ | |
| 438 if (NaClInstRequiresModRm(state)) { | |
| 439 uint8_t byte; | |
| 440 /* Has modrm byte. */ | |
| 441 if (state->bytes.length >= state->length_limit) { | |
| 442 DEBUG(NaClLog(LOG_INFO, "Can't read mod/rm, no more bytes!\n")); | |
| 443 return FALSE; | |
| 444 } | |
| 445 byte = NCInstBytesPeek(&state->bytes, 0); | |
| 446 | |
| 447 /* Note: Some instructions only allow values where the ModRm mod field | |
| 448 * is 0x3. Others only allow values where the ModRm mod field isn't 0x3. | |
| 449 */ | |
| 450 if (modrm_mod(byte) == 0x3) { | |
| 451 if (state->inst->flags & NACL_IFLAG(ModRmModIsnt0x3)) { | |
| 452 DEBUG(NaClLog(LOG_INFO, "Can't match, modrm mod field is 0x3\n")); | |
| 453 return FALSE; | |
| 454 } | |
| 455 } else { | |
| 456 if (state->inst->flags & NACL_IFLAG(ModRmModIs0x3)) { | |
| 457 DEBUG(NaClLog(LOG_INFO, "Can't match, modrm mod field not 0x3\n")); | |
| 458 return FALSE; | |
| 459 } | |
| 460 } | |
| 461 if ((state->inst->flags & NACL_IFLAG(ModRmRegSOperand)) && | |
| 462 (modrm_reg(byte) > 5)) { | |
| 463 DEBUG(NaClLog(LOG_INFO, | |
| 464 "Can't match, modrm reg field doesn't index segment\n")); | |
| 465 return FALSE; | |
| 466 } | |
| 467 state->modrm = NCInstBytesRead(&state->bytes); | |
| 468 state->num_disp_bytes = 0; | |
| 469 state->first_disp_byte = 0; | |
| 470 state->sib = 0; | |
| 471 state->has_sib = FALSE; | |
| 472 DEBUG(NaClLog(LOG_INFO, "consume modrm = %02"NACL_PRIx8"\n", state->modrm)); | |
| 473 | |
| 474 /* Consume the remaining opcode value in the mod/rm byte | |
| 475 * if applicable. | |
| 476 */ | |
| 477 if (state->inst->flags & NACL_IFLAG(OpcodeInModRm)) { | |
| 478 const NaClInst* inst = state->inst; | |
| 479 if (modrm_opcode(state->modrm) != inst->opcode[inst->num_opcode_bytes]) { | |
| 480 DEBUG( | |
| 481 NaClLog(LOG_INFO, | |
| 482 "Discarding, opcode in mrm byte (%02"NACL_PRIx8") " | |
| 483 "does not match\n", | |
| 484 modrm_opcode(state->modrm))); | |
| 485 return FALSE; | |
| 486 } | |
| 487 if (state->inst->flags & NACL_IFLAG(OpcodeInModRmRm)) { | |
| 488 if (modrm_rm(state->modrm) != | |
| 489 state->inst->opcode[state->inst->num_opcode_bytes+1]) { | |
| 490 DEBUG(NaClLog(LOG_INFO, | |
| 491 "Discarding, opcode in mrm rm field (%02"NACL_PRIx8") " | |
| 492 "does not match\n", | |
| 493 modrm_rm(state->modrm))); | |
| 494 return FALSE; | |
| 495 } | |
| 496 } | |
| 497 } | |
| 498 } | |
| 499 return TRUE; | |
| 500 } | |
| 501 | |
| 502 /* Returns true if the instruction requires a SIB bytes. */ | |
| 503 static Bool NaClInstRequiresSib(NaClInstState* state) { | |
| 504 /* Note: in 64-bit mode, 64-bit addressing is treated the same as 32-bit | |
| 505 * addressing. Hence, required for all but 16-bit addressing, when | |
| 506 * the right modrm bytes are specified. | |
| 507 */ | |
| 508 return NaClInstRequiresModRm(state) && (16 != state->address_size) && | |
| 509 (modrm_rm(state->modrm) == 0x04 && modrm_mod(state->modrm) != 0x3); | |
| 510 } | |
| 511 | |
| 512 /* Consume the SIB byte of the instruction, if applicable. Aborts the pattern | |
| 513 * match if any problems are found. | |
| 514 */ | |
| 515 static Bool NaClConsumeSib(NaClInstState* state) { | |
| 516 /* First check that the opcode (instruction) pattern specifies that | |
| 517 * a SIB byte is needed, and that reading it will not walk past | |
| 518 * the end of the code segment. | |
| 519 */ | |
| 520 state->sib = 0; | |
| 521 state->has_sib = NaClInstRequiresSib(state); | |
| 522 DEBUG(NaClLog(LOG_INFO, "has sib = %d\n", (int) state->has_sib)); | |
| 523 if (state->has_sib) { | |
| 524 if (state->bytes.length >= state->length_limit) { | |
| 525 DEBUG(NaClLog(LOG_INFO, "Can't consume sib, no more bytes!\n")); | |
| 526 return FALSE; | |
| 527 } | |
| 528 /* Read the SIB byte and record. */ | |
| 529 state->sib = NCInstBytesRead(&state->bytes); | |
| 530 DEBUG(NaClLog(LOG_INFO, "sib = %02"NACL_PRIx8"\n", state->sib)); | |
| 531 if (sib_base(state->sib) == 0x05 && modrm_mod(state->modrm) > 2) { | |
| 532 DEBUG(NaClLog(LOG_INFO, | |
| 533 "Sib byte implies modrm.mod field <= 2, match fails\n")); | |
| 534 return FALSE; | |
| 535 } | |
| 536 } | |
| 537 return TRUE; | |
| 538 } | |
| 539 | |
| 540 static int NaClGetNumDispBytes(NaClInstState* state) { | |
| 541 if (NaClInstRequiresModRm(state)) { | |
| 542 if (16 == state->address_size) { | |
| 543 /* Corresponding to table 2-1 of the Intel manual. */ | |
| 544 switch (modrm_mod(state->modrm)) { | |
| 545 case 0x0: | |
| 546 if (modrm_rm(state->modrm) == 0x06) { | |
| 547 return 4; /* disp16 */ | |
| 548 } | |
| 549 break; | |
| 550 case 0x1: | |
| 551 return 1; /* disp8 */ | |
| 552 case 0x2: | |
| 553 return 2; /* disp16 */ | |
| 554 default: | |
| 555 break; | |
| 556 } | |
| 557 } else { | |
| 558 /* Note: in 64-bit mode, 64-bit addressing is treated the same as 32-bit | |
| 559 * addressing. Hence, this section covers the 32-bit addressing. | |
| 560 */ | |
| 561 switch(modrm_mod(state->modrm)) { | |
| 562 case 0x0: | |
| 563 if (modrm_rm(state->modrm) == 0x05) { | |
| 564 return 4; /* disp32 */ | |
| 565 } else if (state->has_sib && sib_base(state->sib) == 0x5) { | |
| 566 return 4; | |
| 567 } | |
| 568 break; | |
| 569 case 0x1: | |
| 570 return 1; /* disp8 */ | |
| 571 case 0x2: | |
| 572 return 4; /* disp32 */ | |
| 573 default: | |
| 574 break; | |
| 575 } | |
| 576 } | |
| 577 } | |
| 578 return 0; | |
| 579 } | |
| 580 | |
| 581 /* Consume the needed displacement bytes, if applicable. Abort the | |
| 582 * pattern match if any problems are found. | |
| 583 */ | |
| 584 static Bool NaClConsumeDispBytes(NaClInstState* state) { | |
| 585 /* First check if the opcode (instruction) pattern specifies that | |
| 586 * displacement bytes should be read, and that reading it will not | |
| 587 * walk past the end of the code segment. | |
| 588 */ | |
| 589 state->num_disp_bytes = NaClGetNumDispBytes(state); | |
| 590 DEBUG(NaClLog(LOG_INFO, | |
| 591 "num disp bytes = %"NACL_PRIu8"\n", state->num_disp_bytes)); | |
| 592 state->first_disp_byte = state->bytes.length; | |
| 593 if (state->num_disp_bytes > 0) { | |
| 594 int new_length = state->bytes.length + state->num_disp_bytes; | |
| 595 if (new_length > state->length_limit) { | |
| 596 DEBUG(NaClLog(LOG_INFO, "Can't consume disp, no more bytes!\n")); | |
| 597 return FALSE; | |
| 598 } | |
| 599 /* Read the displacement bytes. */ | |
| 600 state->first_disp_byte = state->bytes.length; | |
| 601 NCInstBytesReadBytes(state->num_disp_bytes, &state->bytes); | |
| 602 } | |
| 603 return TRUE; | |
| 604 } | |
| 605 | |
| 606 /* Returns the number of immediate bytes to parse. */ | |
| 607 static int NaClGetNumImmedBytes(NaClInstState* state) { | |
| 608 if (state->inst->flags & NACL_IFLAG(OpcodeHasImmed)) { | |
| 609 return state->operand_size; | |
| 610 } | |
| 611 if (state->inst->flags & NACL_IFLAG(OpcodeHasImmed_v)) { | |
| 612 return 4; | |
| 613 } else if (state->inst->flags & NACL_IFLAG(OpcodeHasImmed_b)) { | |
| 614 return 1; | |
| 615 } else if (state->inst->flags & NACL_IFLAG(OpcodeHasImmed_w)) { | |
| 616 return 2; | |
| 617 } else if (state->inst->flags & NACL_IFLAG(OpcodeHasImmed_o)) { | |
| 618 return 8; | |
| 619 } else if (state->inst->flags & NACL_IFLAG(OpcodeHasImmed_Addr)) { | |
| 620 return NaClExtractAddressSize(state) / 8; | |
| 621 } else if (state->inst->flags & NACL_IFLAG(OpcodeHasImmed_z)) { | |
| 622 if (state->operand_size == 2) { | |
| 623 return 2; | |
| 624 } else { | |
| 625 return 4; | |
| 626 } | |
| 627 } else { | |
| 628 return 0; | |
| 629 } | |
| 630 } | |
| 631 | |
| 632 /* Returns the number of immedidate bytes to parse if a second immediate | |
| 633 * number appears in the instruction (zero if no second immediate value). | |
| 634 */ | |
| 635 static int NaClGetNumImmed2Bytes(NaClInstState* state) { | |
| 636 if (state->inst->flags & NACL_IFLAG(OpcodeHasImmed2_b)) { | |
| 637 return 1; | |
| 638 } else if (state->inst->flags & NACL_IFLAG(OpcodeHasImmed2_w)) { | |
| 639 return 2; | |
| 640 } else if (state->inst->flags & NACL_IFLAG(OpcodeHasImmed2_v)) { | |
| 641 return 4; | |
| 642 } else { | |
| 643 return 0; | |
| 644 } | |
| 645 } | |
| 646 | |
| 647 /* Consume the needed immediate bytes, if applicable. Abort the | |
| 648 * pattern match if any problems are found. | |
| 649 */ | |
| 650 static Bool NaClConsumeImmediateBytes(NaClInstState* state) { | |
| 651 /* find out how many immediate bytes are expected. */ | |
| 652 state->num_imm_bytes = NaClGetNumImmedBytes(state); | |
| 653 DEBUG(NaClLog(LOG_INFO, | |
| 654 "num immediate bytes = %"NACL_PRIu8"\n", state->num_imm_bytes)); | |
| 655 state->first_imm_byte = 0; | |
| 656 if (state->num_imm_bytes > 0) { | |
| 657 int new_length; | |
| 658 /* Before reading immediate bytes, be sure that we won't walk | |
| 659 * past the end of the code segment. | |
| 660 */ | |
| 661 new_length = state->bytes.length + state->num_imm_bytes; | |
| 662 if (new_length > state->length_limit) { | |
| 663 DEBUG(NaClLog(LOG_INFO, "Can't consume immediate, no more bytes!\n")); | |
| 664 return FALSE; | |
| 665 } | |
| 666 /* Read the immediate bytes. */ | |
| 667 state->first_imm_byte = state->bytes.length; | |
| 668 NCInstBytesReadBytes(state->num_imm_bytes, &state->bytes); | |
| 669 } | |
| 670 /* Before returning, see if second immediate value specified. */ | |
| 671 state->num_imm2_bytes = NaClGetNumImmed2Bytes(state); | |
| 672 DEBUG(NaClLog(LOG_INFO, "num immediate 2 bytes = %"NACL_PRIu8"\n", | |
| 673 state->num_imm2_bytes)); | |
| 674 if (state->num_imm2_bytes > 0) { | |
| 675 int new_length; | |
| 676 /* Before reading immediate bytes, be sure that we don't walk | |
| 677 * past the end of the code segment. | |
| 678 */ | |
| 679 new_length = state->bytes.length + state->num_imm2_bytes; | |
| 680 if (new_length > state->length_limit) { | |
| 681 DEBUG(NaClLog(LOG_INFO, "Can't consume 2nd immediate, no more bytes!\n")); | |
| 682 return FALSE; | |
| 683 } | |
| 684 /* Read the immediate bytes. */ | |
| 685 NCInstBytesReadBytes(state->num_imm2_bytes, &state->bytes); | |
| 686 } | |
| 687 return TRUE; | |
| 688 } | |
| 689 | |
| 690 /* Validate that any opcode (instruction) pattern prefix assumptions are | |
| 691 * met by prefix bits. If not, abort the pattern match. | |
| 692 */ | |
| 693 static Bool NaClValidatePrefixFlags(NaClInstState* state) { | |
| 694 /* Check lock prefix assumptions. */ | |
| 695 if (state->prefix_mask & kPrefixLOCK) { | |
| 696 if (state->inst->flags & NACL_IFLAG(OpcodeLockable)) { | |
| 697 /* Only allow if all destination operands are memory stores. */ | |
| 698 uint32_t i; | |
| 699 Bool has_lockable_dest = FALSE; | |
| 700 NaClExpVector* vector = NaClInstStateExpVector(state); | |
| 701 DEBUG(NaClLog(LOG_INFO, "checking if lock valid on:\n"); | |
| 702 NaClExpVectorPrint(NaClLogGetGio(), vector)); | |
| 703 for (i = 0; i < vector->number_expr_nodes; ++i) { | |
| 704 NaClExp* node = &vector->node[i]; | |
| 705 DEBUG(NaClLog(LOG_INFO, " checking node %d\n", i)); | |
| 706 if ((NACL_EMPTY_EFLAGS != (node->flags & NACL_EFLAG(ExprDest))) && | |
| 707 (node->kind == ExprMemOffset)) { | |
| 708 has_lockable_dest = TRUE; | |
| 709 break; | |
| 710 } | |
| 711 } | |
| 712 if (!has_lockable_dest) { | |
| 713 DEBUG(NaClLog(LOG_INFO, "Instruction doesn't allow lock prefix " | |
| 714 "on non-memory destination")); | |
| 715 return FALSE; | |
| 716 } | |
| 717 } else { | |
| 718 DEBUG(NaClLog(LOG_INFO, "Instruction doesn't allow lock prefix\n")); | |
| 719 return FALSE; | |
| 720 } | |
| 721 } | |
| 722 /* Check REX prefix assumptions. */ | |
| 723 if (NACL_TARGET_SUBARCH == 64 && | |
| 724 (state->prefix_mask & kPrefixREX)) { | |
| 725 if (state->inst->flags & | |
| 726 (NACL_IFLAG(OpcodeUsesRexW) | NACL_IFLAG(OpcodeHasRexR) | | |
| 727 NACL_IFLAG(OpcodeRex))) { | |
| 728 if (((state->inst->flags & NACL_IFLAG(OpcodeUsesRexW)) && | |
| 729 0 == (state->rexprefix & 0x8)) || | |
| 730 ((state->inst->flags & NACL_IFLAG(OpcodeHasRexR)) && | |
| 731 0 == (state->rexprefix & 0x4))) { | |
| 732 DEBUG(NaClLog(LOG_INFO, "can't match REX prefix requirement\n")); | |
| 733 return FALSE; | |
| 734 } | |
| 735 } | |
| 736 } | |
| 737 return TRUE; | |
| 738 } | |
| 739 | |
| 740 static void NaClClearInstState(NaClInstState* state, uint8_t opcode_length) { | |
| 741 if (state->bytes.length != opcode_length) { | |
| 742 NCInstBytesReset(&state->bytes); | |
| 743 NCInstBytesReadBytes(opcode_length, &state->bytes); | |
| 744 } | |
| 745 state->modrm = 0; | |
| 746 state->has_sib = FALSE; | |
| 747 state->sib = 0; | |
| 748 state->num_disp_bytes = 0; | |
| 749 state->first_disp_byte = 0; | |
| 750 state->num_imm_bytes = 0; | |
| 751 state->first_imm_byte = 0; | |
| 752 state->num_imm2_bytes = 0; | |
| 753 state->operand_size = 32; | |
| 754 state->address_size = 32; | |
| 755 state->nodes.is_defined = FALSE; | |
| 756 state->nodes.number_expr_nodes = 0; | |
| 757 } | |
| 758 | |
| 759 /* | |
| 760 * Given the opcode prefix descriptor, return the list of candidate opcodes to | |
| 761 * try and match against the byte stream in the given state. Before returning, | |
| 762 * this function automatically advances the opcode prefix descriptor to describe | |
| 763 * the next list to use if the returned list doesn't provide any matches. | |
| 764 * | |
| 765 * Parameters: | |
| 766 * state - The state of the instruction being decoded. | |
| 767 * desc - The description of how the opcode bytes have been matched. | |
| 768 * The value passed in is the currrent match, the value at exit is | |
| 769 * the value to be used the next time this function is called (to | |
| 770 * get the next set of possible instructions). | |
| 771 * opcode_length - The length (in bytes) of the opcode for the returned | |
| 772 * candidate opcodes. | |
| 773 */ | |
| 774 static const NaClInst* NaClGetNextInstCandidates( | |
| 775 NaClInstState* state, NaClInstPrefixDescriptor* desc, | |
| 776 uint8_t* opcode_length) { | |
| 777 const NaClInst* cand_insts; | |
| 778 if (desc->next_length_adjustment) { | |
| 779 (*opcode_length) += desc->next_length_adjustment; | |
| 780 desc->opcode_byte = state->bytes.byte[*opcode_length - 1]; | |
| 781 } | |
| 782 cand_insts = g_OpcodeTable[desc->matched_prefix][desc->opcode_byte]; | |
| 783 DEBUG(NaClLog(LOG_INFO, "Lookup candidates using [%s][%x]\n", | |
| 784 NaClInstPrefixName(desc->matched_prefix), desc->opcode_byte)); | |
| 785 switch (desc->matched_prefix) { | |
| 786 case Prefix660F: | |
| 787 desc->matched_prefix = Prefix0F; | |
| 788 break; | |
| 789 case Prefix660F38: | |
| 790 desc->matched_prefix = Prefix0F38; | |
| 791 break; | |
| 792 case Prefix660F3A: | |
| 793 desc->matched_prefix = Prefix0F3A; | |
| 794 break; | |
| 795 case PrefixD8: | |
| 796 case PrefixD9: | |
| 797 case PrefixDA: | |
| 798 case PrefixDB: | |
| 799 case PrefixDC: | |
| 800 case PrefixDD: | |
| 801 case PrefixDE: | |
| 802 case PrefixDF: | |
| 803 desc->matched_prefix = NoPrefix; | |
| 804 desc->next_length_adjustment = -1; | |
| 805 break; | |
| 806 default: | |
| 807 /* No more simplier prefices, give up search after current lookup. */ | |
| 808 desc->matched_prefix = NaClInstPrefixEnumSize; | |
| 809 break; | |
| 810 } | |
| 811 return cand_insts; | |
| 812 } | |
| 813 | |
| 814 static Bool NaClConsumeOpcodeSequence(NaClInstState* state) { | |
| 815 uint8_t next_byte; | |
| 816 const NaClInstNode* next; | |
| 817 uint8_t next_length = 0; | |
| 818 const NaClInst* matching_inst = NULL; | |
| 819 uint8_t matching_length = 0; | |
| 820 | |
| 821 /* Cut quick if first byte not applicable. */ | |
| 822 if (state->bytes.length + next_length >= state->length_limit) return FALSE; | |
| 823 next_byte = NCInstBytesPeek(&state->bytes, next_length); | |
| 824 next = g_OpcodeSeq + 0; | |
| 825 | |
| 826 /* Find maximal match in trie. */ | |
| 827 while (NULL != next) { | |
| 828 if (next_byte == next->matching_byte) { | |
| 829 DEBUG(NaClLog(LOG_INFO, | |
| 830 "NaClConsume opcode char: %"NACL_PRIx8"\n", next_byte)); | |
| 831 next_length++; | |
| 832 if (NULL != next->matching_inst) { | |
| 833 matching_inst = next->matching_inst; | |
| 834 matching_length = next_length; | |
| 835 } | |
| 836 if (next_length < state->length_limit) { | |
| 837 next_byte = NCInstBytesPeek(&state->bytes, next_length); | |
| 838 next = next->success; | |
| 839 } else { | |
| 840 break; | |
| 841 } | |
| 842 } else if (next->matching_byte < next_byte) { | |
| 843 next = next->fail; | |
| 844 } else { | |
| 845 break; | |
| 846 } | |
| 847 } | |
| 848 if (NULL == matching_inst) { | |
| 849 return FALSE; | |
| 850 } else { | |
| 851 /* TODO(karl) Make this more general. Currently assumes that no | |
| 852 * additional processing (other than opcode selection) is needed. | |
| 853 * This is currently safe only because all instructions modeled | |
| 854 * using opcode sequences have no (useful) operands, and hence | |
| 855 * no additional information is needed. | |
| 856 */ | |
| 857 state->inst = matching_inst; | |
| 858 NCInstBytesReadBytes(matching_length, &state->bytes); | |
| 859 DEBUG(NaClLog(LOG_INFO, "matched inst sequence [%d]!\n", matching_length)); | |
| 860 return TRUE; | |
| 861 } | |
| 862 } | |
| 863 | 23 |
| 864 /* Given the current location of the (relative) pc of the given instruction | 24 /* Given the current location of the (relative) pc of the given instruction |
| 865 * iterator, update the given state to hold the (found) matched opcode | 25 * iterator, update the given state to hold the (found) matched opcode |
| 866 * (instruction) pattern. If no matching pattern exists, set the state | 26 * (instruction) pattern. If no matching pattern exists, set the state |
| 867 * to a matched undefined opcode (instruction) pattern. In all cases, | 27 * to a matched undefined opcode (instruction) pattern. In all cases, |
| 868 * update the state to hold all information on the matched bytes of the | 28 * update the state to hold all information on the matched bytes of the |
| 869 * instruction. Note: The iterator expects that the opcode field is | 29 * instruction. Note: The iterator expects that the opcode field is |
| 870 * changed from NULL to non-NULL by this fuction. | 30 * changed from NULL to non-NULL by this fuction. |
| 871 */ | 31 */ |
| 872 void NaClDecodeInst(NaClInstIter* iter, NaClInstState* state) { | 32 void NaClDecodeInst(NaClInstIter* iter, NaClInstState* state) { |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1002 void NaClChangeOpcodesToXedsModel() { | 162 void NaClChangeOpcodesToXedsModel() { |
| 1003 /* Changes opcodes to match xed. That is change: | 163 /* Changes opcodes to match xed. That is change: |
| 1004 * 0f0f..1c: Pf2iw $Pq, $Qq => 0f0f..2c: Pf2iw $Pq, $Qq | 164 * 0f0f..1c: Pf2iw $Pq, $Qq => 0f0f..2c: Pf2iw $Pq, $Qq |
| 1005 * 0f0f..1d: Pf2id $Pq, $Qq => 0f0f..2d: Pf2id $Pq, $Qq | 165 * 0f0f..1d: Pf2id $Pq, $Qq => 0f0f..2d: Pf2id $Pq, $Qq |
| 1006 */ | 166 */ |
| 1007 g_OpcodeTable[Prefix0F0F][0x2c] = g_OpcodeTable[Prefix0F0F][0x1c]; | 167 g_OpcodeTable[Prefix0F0F][0x2c] = g_OpcodeTable[Prefix0F0F][0x1c]; |
| 1008 g_OpcodeTable[Prefix0F0F][0x1c] = NULL; | 168 g_OpcodeTable[Prefix0F0F][0x1c] = NULL; |
| 1009 g_OpcodeTable[Prefix0F0F][0x2d] = g_OpcodeTable[Prefix0F0F][0x1d]; | 169 g_OpcodeTable[Prefix0F0F][0x2d] = g_OpcodeTable[Prefix0F0F][0x1d]; |
| 1010 g_OpcodeTable[Prefix0F0F][0x1d] = NULL; | 170 g_OpcodeTable[Prefix0F0F][0x1d] = NULL; |
| 1011 } | 171 } |
| OLD | NEW |