| 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 * Translates the recognized opcode (instruction) in the instruction state | 8 * Translates the recognized opcode (instruction) in the instruction state |
| 9 * into an opcode expression. | 9 * into an opcode expression. |
| 10 */ | 10 */ |
| 11 | 11 |
| 12 #include "native_client/src/trusted/validator/x86/decoder/nc_inst_trans.h" | 12 #include "native_client/src/trusted/validator/x86/decoder/nc_inst_trans.h" |
| 13 | 13 |
| 14 #include <stdio.h> | 14 #include <stdio.h> |
| 15 #include <assert.h> | 15 #include <assert.h> |
| 16 | 16 |
| 17 #include "native_client/src/shared/platform/nacl_log.h" | 17 #include "native_client/src/shared/platform/nacl_log.h" |
| 18 #include "native_client/src/trusted/validator/x86/decoder/nc_inst_state.h" | 18 #include "native_client/src/trusted/validator/x86/decoder/nc_inst_state.h" |
| 19 #include "native_client/src/trusted/validator/x86/decoder/nc_inst_state_internal
.h" | 19 #include "native_client/src/trusted/validator/x86/decoder/nc_inst_state_internal
.h" |
| 20 #include "native_client/src/trusted/validator/x86/decoder/ncop_exps.h" | 20 #include "native_client/src/trusted/validator/x86/decoder/ncop_exps.h" |
| 21 #include "native_client/src/trusted/validator/x86/nacl_regs.h" | 21 #include "native_client/src/trusted/validator/x86/nacl_regs.h" |
| 22 | 22 |
| 23 #include "native_client/src/trusted/validator/x86/decoder/ncopcode_desc_inl.c" |
| 24 #include "native_client/src/trusted/validator/x86/x86_insts_inl.c" |
| 25 |
| 23 #if NACL_TARGET_SUBARCH == 64 | 26 #if NACL_TARGET_SUBARCH == 64 |
| 24 # include "native_client/src/trusted/validator/x86/decoder/gen/nc_subregs_64.h" | 27 # include "native_client/src/trusted/validator/x86/decoder/gen/nc_subregs_64.h" |
| 25 #else | 28 #else |
| 26 # include "native_client/src/trusted/validator/x86/decoder/gen/nc_subregs_32.h" | 29 # include "native_client/src/trusted/validator/x86/decoder/gen/nc_subregs_32.h" |
| 27 #endif | 30 #endif |
| 28 | 31 |
| 29 /* To turn on debugging of instruction decoding, change value of | 32 /* To turn on debugging of instruction decoding, change value of |
| 30 * DEBUGGING to 1. | 33 * DEBUGGING to 1. |
| 31 */ | 34 */ |
| 32 #define DEBUGGING 0 | 35 #define DEBUGGING 0 |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 78 return RegGS; | 81 return RegGS; |
| 79 default: | 82 default: |
| 80 break; | 83 break; |
| 81 } | 84 } |
| 82 } | 85 } |
| 83 } | 86 } |
| 84 return reg_default; | 87 return reg_default; |
| 85 } | 88 } |
| 86 | 89 |
| 87 /* Return the segment register to use if DS is the default. */ | 90 /* Return the segment register to use if DS is the default. */ |
| 88 static NaClOpKind NaClGetDsSegmentReg(NaClInstState* state) { | 91 static INLINE NaClOpKind NaClGetDsSegmentReg(NaClInstState* state) { |
| 89 return NaClGetSegmentPrefixReg(state, RegDS); | 92 return NaClGetSegmentPrefixReg(state, RegDS); |
| 90 } | 93 } |
| 91 | 94 |
| 92 /* Return the segment register to use if ES is the default. */ | 95 /* Return the segment register to use if ES is the default. */ |
| 93 static NaClOpKind NaClGetEsSegmentReg(NaClInstState* state) { | 96 static INLINE NaClOpKind NaClGetEsSegmentReg(NaClInstState* state) { |
| 94 return NaClGetSegmentPrefixReg(state, RegES); | 97 return NaClGetSegmentPrefixReg(state, RegES); |
| 95 } | 98 } |
| 96 | 99 |
| 97 /* Append the given expression node onto the given vector of expression | 100 /* Append the given expression node onto the given vector of expression |
| 98 * nodes. Returns the appended expression node. | 101 * nodes. Returns the appended expression node. |
| 99 */ | 102 */ |
| 100 static NaClExp* NaClAppendExp(NaClExpKind kind, | 103 static INLINE NaClExp* NaClAppendExp(NaClExpKind kind, |
| 101 int32_t value, | 104 int32_t value, |
| 102 NaClExpFlags flags, | 105 NaClExpFlags flags, |
| 103 NaClExpVector* vector) { | 106 NaClExpVector* vector) { |
| 104 NaClExp* node; | 107 NaClExp* node; |
| 105 assert(vector->number_expr_nodes < NACL_MAX_EXPS); | 108 assert(vector->number_expr_nodes < NACL_MAX_EXPS); |
| 106 node = &vector->node[vector->number_expr_nodes++]; | 109 node = &vector->node[vector->number_expr_nodes++]; |
| 107 node->kind = kind; | 110 node->kind = kind; |
| 108 node->value = value; | 111 node->value = value; |
| 109 node->flags = flags; | 112 node->flags = flags; |
| 110 return node; | 113 return node; |
| 111 } | 114 } |
| 112 | 115 |
| 113 /* Report the given message and quit because we don't know | 116 /* Report the given message and quit because we don't know |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 156 } | 159 } |
| 157 NaClFatal("Unable to determine segment regsiter from instruction name", | 160 NaClFatal("Unable to determine segment regsiter from instruction name", |
| 158 state); | 161 state); |
| 159 /* NOT REACHED */ | 162 /* NOT REACHED */ |
| 160 return RegUnknown; | 163 return RegUnknown; |
| 161 } | 164 } |
| 162 | 165 |
| 163 /* Append the given constant onto the given vector of expression | 166 /* Append the given constant onto the given vector of expression |
| 164 * nodes. Returns the appended expression node. | 167 * nodes. Returns the appended expression node. |
| 165 */ | 168 */ |
| 166 static NaClExp* NaClAppendConst(uint64_t value, NaClExpFlags flags, | 169 static INLINE NaClExp* NaClAppendConst(uint64_t value, NaClExpFlags flags, |
| 167 NaClExpVector* vector) { | 170 NaClExpVector* vector) { |
| 168 uint32_t val1; | 171 uint32_t val1; |
| 169 uint32_t val2; | 172 uint32_t val2; |
| 170 DEBUG( | 173 DEBUG( |
| 171 NaClLog(LOG_INFO, "Append constant %"NACL_PRIx64" : ", value); | 174 NaClLog(LOG_INFO, "Append constant %"NACL_PRIx64" : ", value); |
| 172 NaClPrintExpFlags(NaClLogGetGio(), flags); | 175 NaClPrintExpFlags(NaClLogGetGio(), flags); |
| 173 gprintf(NaClLogGetGio(), "\n")); | 176 gprintf(NaClLogGetGio(), "\n")); |
| 174 NaClSplitExpConstant(value, &val1, &val2); | 177 NaClSplitExpConstant(value, &val1, &val2); |
| 175 if (val2 == 0) { | 178 if (val2 == 0) { |
| 176 return NaClAppendExp(ExprConstant, val1, flags, vector); | 179 return NaClAppendExp(ExprConstant, val1, flags, vector); |
| 177 } else { | 180 } else { |
| (...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 460 case RegR15: | 463 case RegR15: |
| 461 return NACL_EFLAG(ExprSize64); | 464 return NACL_EFLAG(ExprSize64); |
| 462 default: | 465 default: |
| 463 return 0; | 466 return 0; |
| 464 } | 467 } |
| 465 } | 468 } |
| 466 | 469 |
| 467 /* Appends the given kind of register onto the vector of expression nodes. | 470 /* Appends the given kind of register onto the vector of expression nodes. |
| 468 * Returns the appended register. | 471 * Returns the appended register. |
| 469 */ | 472 */ |
| 470 static NaClExp* NaClAppendReg(NaClOpKind r, NaClExpVector* vector) { | 473 static INLINE NaClExp* NaClAppendReg(NaClOpKind r, NaClExpVector* vector) { |
| 471 NaClExp* node; | 474 NaClExp* node; |
| 472 DEBUG(NaClLog(LOG_INFO, "append register %s\n", NaClOpKindName(r))); | 475 DEBUG(NaClLog(LOG_INFO, "append register %s\n", NaClOpKindName(r))); |
| 473 node = NaClAppendExp(ExprRegister, r, NaClGetRegSize(r), vector); | 476 node = NaClAppendExp(ExprRegister, r, NaClGetRegSize(r), vector); |
| 474 DEBUG(NaClExpVectorPrint(NaClLogGetGio(), vector)); | 477 DEBUG(NaClExpVectorPrint(NaClLogGetGio(), vector)); |
| 475 return node; | 478 return node; |
| 476 } | 479 } |
| 477 | 480 |
| 478 /* Given the given register kind, and the corresponding index, append | 481 /* Given the given register kind, and the corresponding index, append |
| 479 * the appropriate register onto the vector of expression nodes. | 482 * the appropriate register onto the vector of expression nodes. |
| 480 * Returns the appended register | 483 * Returns the appended register |
| 481 */ | 484 */ |
| 482 static NaClExp* NaClAppendRegKind(NaClInstState* state, | 485 static INLINE NaClExp* NaClAppendRegKind(NaClInstState* state, |
| 483 NaClRegKind kind, int reg_index) { | 486 NaClRegKind kind, int reg_index) { |
| 484 DEBUG(NaClLog(LOG_INFO, "NaClAppendRegKind(%d, %d) = %s\n", | 487 DEBUG(NaClLog(LOG_INFO, "NaClAppendRegKind(%d, %d) = %s\n", |
| 485 (int) kind, reg_index, NaClRegKindName(kind))); | 488 (int) kind, reg_index, NaClRegKindName(kind))); |
| 486 return NaClAppendReg(NaClLookupReg(state, kind, reg_index), &state->nodes); | 489 return NaClAppendReg(NaClLookupReg(state, kind, reg_index), &state->nodes); |
| 487 } | 490 } |
| 488 | 491 |
| 489 /* Given an operand of the corresponding opcode instruction of the | 492 /* Given an operand of the corresponding opcode instruction of the |
| 490 * given state, return what kind of register should be used, based | 493 * given state, return what kind of register should be used, based |
| 491 * on the operand size. | 494 * on the operand size. |
| 492 */ | 495 */ |
| 493 static NaClRegKind NaClExtractOpRegKind(NaClInstState* state, | 496 static NaClRegKind NaClExtractOpRegKind(NaClInstState* state, |
| (...skipping 25 matching lines...) Expand all Loading... |
| 519 return RegSize64; | 522 return RegSize64; |
| 520 } else { | 523 } else { |
| 521 return RegSize32; | 524 return RegSize32; |
| 522 } | 525 } |
| 523 } | 526 } |
| 524 } | 527 } |
| 525 | 528 |
| 526 /* Given an address of the corresponding opcode instruction of the | 529 /* Given an address of the corresponding opcode instruction of the |
| 527 * given state, return what kind of register should be used. | 530 * given state, return what kind of register should be used. |
| 528 */ | 531 */ |
| 529 static NaClRegKind NaClExtractAddressRegKind(NaClInstState* state) { | 532 static INLINE NaClRegKind NaClExtractAddressRegKind(NaClInstState* state) { |
| 530 if (state->address_size == 16) { | 533 if (state->address_size == 16) { |
| 531 return RegSize16; | 534 return RegSize16; |
| 532 } else if (state->address_size == 64) { | 535 } else if (state->address_size == 64) { |
| 533 return RegSize64; | 536 return RegSize64; |
| 534 } else { | 537 } else { |
| 535 return RegSize32; | 538 return RegSize32; |
| 536 } | 539 } |
| 537 } | 540 } |
| 538 | 541 |
| 539 /* Given we want to translate an operand (of the form G_Operand), | 542 /* Given we want to translate an operand (of the form G_Operand), |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 602 RegES, | 605 RegES, |
| 603 RegCS, | 606 RegCS, |
| 604 RegSS, | 607 RegSS, |
| 605 RegDS, | 608 RegDS, |
| 606 RegFS, | 609 RegFS, |
| 607 RegGS, | 610 RegGS, |
| 608 /* These should not happen. */ | 611 /* These should not happen. */ |
| 609 RegUnknown, | 612 RegUnknown, |
| 610 RegUnknown | 613 RegUnknown |
| 611 }; | 614 }; |
| 612 return NaClAppendReg(seg[modrm_reg(state->modrm)], &state->nodes); | 615 return NaClAppendReg(seg[modrm_regInline(state->modrm)], &state->nodes); |
| 613 } | 616 } |
| 614 | 617 |
| 615 /* For the given instruction state, and the corresponding 3-bit specification | 618 /* For the given instruction state, and the corresponding 3-bit specification |
| 616 * of a register, update it to a 4-bit specification, based on the REX.R bit. | 619 * of a register, update it to a 4-bit specification, based on the REX.R bit. |
| 617 */ | 620 */ |
| 618 static int NaClGetRexRReg(NaClInstState* state, int reg) { | 621 static INLINE int NaClGetRexRReg(NaClInstState* state, int reg) { |
| 619 DEBUG(NaClLog(LOG_INFO, "Get GenRexRRegister %d\n", reg)); | 622 DEBUG(NaClLog(LOG_INFO, "Get GenRexRRegister %d\n", reg)); |
| 620 if (NACL_TARGET_SUBARCH == 64 && (state->rexprefix & 0x4)) { | 623 if (NACL_TARGET_SUBARCH == 64 && (state->rexprefix & 0x4)) { |
| 621 reg += 8; | 624 reg += 8; |
| 622 } | 625 } |
| 623 return reg; | 626 return reg; |
| 624 } | 627 } |
| 625 | 628 |
| 626 /* For the given instruction state, and the corresponding 3-bit specification | 629 /* For the given instruction state, and the corresponding 3-bit specification |
| 627 * of a register, update it to a 4-bit specification, based on the REX.X bit. | 630 * of a register, update it to a 4-bit specification, based on the REX.X bit. |
| 628 */ | 631 */ |
| 629 static int NaClGetRexXReg(NaClInstState* state, int reg) { | 632 static INLINE int NaClGetRexXReg(NaClInstState* state, int reg) { |
| 630 DEBUG(NaClLog(LOG_INFO, "Get GenRexXRegister\n")); | 633 DEBUG(NaClLog(LOG_INFO, "Get GenRexXRegister\n")); |
| 631 if (NACL_TARGET_SUBARCH == 64 && (state->rexprefix & 0x2)) { | 634 if (NACL_TARGET_SUBARCH == 64 && (state->rexprefix & 0x2)) { |
| 632 reg += 8; | 635 reg += 8; |
| 633 } | 636 } |
| 634 return reg; | 637 return reg; |
| 635 } | 638 } |
| 636 | 639 |
| 637 /* For the given instruction state, and the corresponding 3-bit specification | 640 /* For the given instruction state, and the corresponding 3-bit specification |
| 638 * of a register, update it to a 4-bit specification, based on the REX.B bit. | 641 * of a register, update it to a 4-bit specification, based on the REX.B bit. |
| 639 */ | 642 */ |
| 640 static int NaClGetRexBReg(NaClInstState* state, int reg) { | 643 static INLINE int NaClGetRexBReg(NaClInstState* state, int reg) { |
| 641 DEBUG(NaClLog(LOG_INFO, "Get GenRexBRegister\n")); | 644 DEBUG(NaClLog(LOG_INFO, "Get GenRexBRegister\n")); |
| 642 if (NACL_TARGET_SUBARCH == 64 && (state->rexprefix & 0x1)) { | 645 if (NACL_TARGET_SUBARCH == 64 && (state->rexprefix & 0x1)) { |
| 643 DEBUG(NaClLog(LOG_INFO, "rexprefix == %02x\n", state->rexprefix)); | 646 DEBUG(NaClLog(LOG_INFO, "rexprefix == %02x\n", state->rexprefix)); |
| 644 reg += 8; | 647 reg += 8; |
| 645 } | 648 } |
| 646 return reg; | 649 return reg; |
| 647 } | 650 } |
| 648 | 651 |
| 649 /* Return the general purpose register associated with the modrm.reg | 652 /* Return the general purpose register associated with the modrm.reg |
| 650 * field. | 653 * field. |
| 651 */ | 654 */ |
| 652 static int NaClGetGenRegRegister(NaClInstState* state) { | 655 static INLINE int NaClGetGenRegRegister(NaClInstState* state) { |
| 653 DEBUG(NaClLog(LOG_INFO, "Get GenRegRegister\n")); | 656 DEBUG(NaClLog(LOG_INFO, "Get GenRegRegister\n")); |
| 654 return NaClGetRexRReg(state, modrm_reg(state->modrm)); | 657 return NaClGetRexRReg(state, modrm_regInline(state->modrm)); |
| 655 } | 658 } |
| 656 | 659 |
| 657 /* Return the general purpose register associated with the modrm.rm | 660 /* Return the general purpose register associated with the modrm.rm |
| 658 * field. | 661 * field. |
| 659 */ | 662 */ |
| 660 static int NaClGetGenRmRegister(NaClInstState* state) { | 663 static INLINE int NaClGetGenRmRegister(NaClInstState* state) { |
| 661 DEBUG(NaClLog(LOG_INFO, "Get GenRmRegister\n")); | 664 DEBUG(NaClLog(LOG_INFO, "Get GenRmRegister\n")); |
| 662 return NaClGetRexBReg(state, modrm_rm(state->modrm)); | 665 return NaClGetRexBReg(state, modrm_rmInline(state->modrm)); |
| 663 } | 666 } |
| 664 | 667 |
| 665 /* Get the register index from the difference of the opcode, and | 668 /* Get the register index from the difference of the opcode, and |
| 666 * its opcode base. | 669 * its opcode base. |
| 667 */ | 670 */ |
| 668 static NaClExp* NaClAppendOpcodeBaseReg( | 671 static NaClExp* NaClAppendOpcodeBaseReg( |
| 669 NaClInstState* state, const NaClOp* operand) { | 672 NaClInstState* state, const NaClOp* operand) { |
| 670 int reg_index; | 673 int reg_index; |
| 671 reg_index = NaClGetOpcodePlusR(state->inst->opcode_ext); | 674 reg_index = NaClGetOpcodePlusR(state->inst->opcode_ext); |
| 672 assert(reg_index >= 0 && reg_index < 8); | 675 assert(reg_index >= 0 && reg_index < 8); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 685 DEBUG(NaClLog(LOG_INFO, "Translate opcode base register %d\n", reg_index)); | 688 DEBUG(NaClLog(LOG_INFO, "Translate opcode base register %d\n", reg_index)); |
| 686 return NaClAppendReg(RegST0 + reg_index, &state->nodes); | 689 return NaClAppendReg(RegST0 + reg_index, &state->nodes); |
| 687 } | 690 } |
| 688 | 691 |
| 689 /* Model the extraction of a displacement value and the associated flags. */ | 692 /* Model the extraction of a displacement value and the associated flags. */ |
| 690 typedef struct NaClDisplacement { | 693 typedef struct NaClDisplacement { |
| 691 uint64_t value; | 694 uint64_t value; |
| 692 NaClExpFlags flags; | 695 NaClExpFlags flags; |
| 693 } NaClDisplacement; | 696 } NaClDisplacement; |
| 694 | 697 |
| 695 static void NaClInitializeDisplacement(uint64_t value, NaClExpFlags flags, | 698 static INLINE void NaClInitializeDisplacement( |
| 696 NaClDisplacement* displacement) { | 699 uint64_t value, NaClExpFlags flags, |
| 700 NaClDisplacement* displacement) { |
| 697 displacement->value = value; | 701 displacement->value = value; |
| 698 displacement->flags = flags; | 702 displacement->flags = flags; |
| 699 } | 703 } |
| 700 | 704 |
| 701 /* Extract the binary value from the specified bytes of the instruction. */ | 705 /* Extract the binary value from the specified bytes of the instruction. */ |
| 702 uint64_t NaClExtractUnsignedBinaryValue(NaClInstState* state, | 706 uint64_t NaClExtractUnsignedBinaryValue(NaClInstState* state, |
| 703 int start_byte, int num_bytes) { | 707 int start_byte, int num_bytes) { |
| 704 int i; | 708 int i; |
| 705 uint64_t value = 0; | 709 uint64_t value = 0; |
| 706 for (i = 0; i < num_bytes; ++i) { | 710 for (i = 0; i < num_bytes; ++i) { |
| (...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 984 DEBUG(NaClLog(LOG_INFO, "finished appending memory offset:\n")); | 988 DEBUG(NaClLog(LOG_INFO, "finished appending memory offset:\n")); |
| 985 DEBUG(NaClExpVectorPrint(NaClLogGetGio(), &state->nodes)); | 989 DEBUG(NaClExpVectorPrint(NaClLogGetGio(), &state->nodes)); |
| 986 return root; | 990 return root; |
| 987 } | 991 } |
| 988 | 992 |
| 989 /* Extract the base register from the SIB byte. */ | 993 /* Extract the base register from the SIB byte. */ |
| 990 static NaClOpKind NaClGetSibBase(NaClInstState* state) { | 994 static NaClOpKind NaClGetSibBase(NaClInstState* state) { |
| 991 int base = sib_base(state->sib); | 995 int base = sib_base(state->sib); |
| 992 NaClOpKind base_reg = RegUnknown; | 996 NaClOpKind base_reg = RegUnknown; |
| 993 if (0x5 == base) { | 997 if (0x5 == base) { |
| 994 switch (modrm_mod(state->modrm)) { | 998 switch (modrm_modInline(state->modrm)) { |
| 995 case 0: | 999 case 0: |
| 996 break; | 1000 break; |
| 997 case 1: | 1001 case 1: |
| 998 case 2: | 1002 case 2: |
| 999 if (NACL_TARGET_SUBARCH == 64) { | 1003 if (NACL_TARGET_SUBARCH == 64) { |
| 1000 if (state->rexprefix & 0x1) { | 1004 if (state->rexprefix & 0x1) { |
| 1001 base_reg = RegR13; | 1005 base_reg = RegR13; |
| 1002 } else { | 1006 } else { |
| 1003 base_reg = RegRBP; | 1007 base_reg = RegRBP; |
| 1004 } | 1008 } |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1110 | 1114 |
| 1111 /* Get the Effective address in the mod/rm byte, if the modrm.mod field | 1115 /* Get the Effective address in the mod/rm byte, if the modrm.mod field |
| 1112 * is 00, and append it to the vector of expression nodes. Operand is | 1116 * is 00, and append it to the vector of expression nodes. Operand is |
| 1113 * the corresponding operand of the opcode associated with the instruction | 1117 * the corresponding operand of the opcode associated with the instruction |
| 1114 * of the given state that corresponds to the effective address. Returns | 1118 * of the given state that corresponds to the effective address. Returns |
| 1115 * the root of the appended effective address. | 1119 * the root of the appended effective address. |
| 1116 */ | 1120 */ |
| 1117 static NaClExp* NaClAppendMod00EffectiveAddress( | 1121 static NaClExp* NaClAppendMod00EffectiveAddress( |
| 1118 NaClInstState* state, const NaClOp* operand) { | 1122 NaClInstState* state, const NaClOp* operand) { |
| 1119 DEBUG(NaClLog(LOG_INFO, "Translate modrm(%02x).mod == 00\n", state->modrm)); | 1123 DEBUG(NaClLog(LOG_INFO, "Translate modrm(%02x).mod == 00\n", state->modrm)); |
| 1120 switch (modrm_rm(state->modrm)) { | 1124 switch (modrm_rmInline(state->modrm)) { |
| 1121 case 4: | 1125 case 4: |
| 1122 return NaClAppendSib(state); | 1126 return NaClAppendSib(state); |
| 1123 case 5: | 1127 case 5: |
| 1124 if (NACL_TARGET_SUBARCH == 64) { | 1128 if (NACL_TARGET_SUBARCH == 64) { |
| 1125 NaClDisplacement displacement; | 1129 NaClDisplacement displacement; |
| 1126 NaClExtractDisplacement(state, &displacement, | 1130 NaClExtractDisplacement(state, &displacement, |
| 1127 NACL_EFLAG(ExprSignedHex)); | 1131 NACL_EFLAG(ExprSignedHex)); |
| 1128 return NaClAppendMemoryOffset(state, | 1132 return NaClAppendMemoryOffset(state, |
| 1129 RegRIP, | 1133 RegRIP, |
| 1130 RegUnknown, | 1134 RegUnknown, |
| (...skipping 21 matching lines...) Expand all Loading... |
| 1152 | 1156 |
| 1153 /* Get the Effective address in the mod/rm byte, if the modrm.mod field | 1157 /* Get the Effective address in the mod/rm byte, if the modrm.mod field |
| 1154 * is 01, and append it to the vector of expression nodes. Operand is | 1158 * is 01, and append it to the vector of expression nodes. Operand is |
| 1155 * the corresponding operand of the opcode associated with the instruction | 1159 * the corresponding operand of the opcode associated with the instruction |
| 1156 * of the given state that corresponds to the effective address. Returns | 1160 * of the given state that corresponds to the effective address. Returns |
| 1157 * the root of the appended effective address. | 1161 * the root of the appended effective address. |
| 1158 */ | 1162 */ |
| 1159 static NaClExp* NaClAppendMod01EffectiveAddress( | 1163 static NaClExp* NaClAppendMod01EffectiveAddress( |
| 1160 NaClInstState* state, const NaClOp* operand) { | 1164 NaClInstState* state, const NaClOp* operand) { |
| 1161 DEBUG(NaClLog(LOG_INFO, "Translate modrm(%02x).mod == 01\n", state->modrm)); | 1165 DEBUG(NaClLog(LOG_INFO, "Translate modrm(%02x).mod == 01\n", state->modrm)); |
| 1162 if (4 == modrm_rm(state->modrm)) { | 1166 if (4 == modrm_rmInline(state->modrm)) { |
| 1163 return NaClAppendSib(state); | 1167 return NaClAppendSib(state); |
| 1164 } else { | 1168 } else { |
| 1165 NaClDisplacement displacement; | 1169 NaClDisplacement displacement; |
| 1166 NaClExtractDisplacement(state, &displacement, NACL_EFLAG(ExprSignedHex)); | 1170 NaClExtractDisplacement(state, &displacement, NACL_EFLAG(ExprSignedHex)); |
| 1167 return NaClAppendMemoryOffset(state, | 1171 return NaClAppendMemoryOffset(state, |
| 1168 NaClLookupReg( | 1172 NaClLookupReg( |
| 1169 state, | 1173 state, |
| 1170 NaClExtractAddressRegKind(state), | 1174 NaClExtractAddressRegKind(state), |
| 1171 NaClGetGenRmRegister(state)), | 1175 NaClGetGenRmRegister(state)), |
| 1172 RegUnknown, | 1176 RegUnknown, |
| 1173 1, | 1177 1, |
| 1174 &displacement); | 1178 &displacement); |
| 1175 } | 1179 } |
| 1176 } | 1180 } |
| 1177 | 1181 |
| 1178 /* Get the Effective address in the mod/rm byte, if the modrm.mod field | 1182 /* Get the Effective address in the mod/rm byte, if the modrm.mod field |
| 1179 * is 10, and append it to the vector of expression nodes. Operand is | 1183 * is 10, and append it to the vector of expression nodes. Operand is |
| 1180 * the corresponding operand of the opcode associated with the instruction | 1184 * the corresponding operand of the opcode associated with the instruction |
| 1181 * of the given state that corresponds to the effective address. Returns | 1185 * of the given state that corresponds to the effective address. Returns |
| 1182 * the root of the appended effective address. | 1186 * the root of the appended effective address. |
| 1183 */ | 1187 */ |
| 1184 static NaClExp* NaClAppendMod10EffectiveAddress( | 1188 static NaClExp* NaClAppendMod10EffectiveAddress( |
| 1185 NaClInstState* state, const NaClOp* operand) { | 1189 NaClInstState* state, const NaClOp* operand) { |
| 1186 DEBUG(NaClLog(LOG_INFO, "Translate modrm(%02x).mod == 10\n", state->modrm)); | 1190 DEBUG(NaClLog(LOG_INFO, "Translate modrm(%02x).mod == 10\n", state->modrm)); |
| 1187 if (4 == modrm_rm(state->modrm)) { | 1191 if (4 == modrm_rmInline(state->modrm)) { |
| 1188 return NaClAppendSib(state); | 1192 return NaClAppendSib(state); |
| 1189 } else { | 1193 } else { |
| 1190 NaClDisplacement displacement; | 1194 NaClDisplacement displacement; |
| 1191 NaClOpKind base = | 1195 NaClOpKind base = |
| 1192 NaClLookupReg(state, | 1196 NaClLookupReg(state, |
| 1193 NaClExtractAddressRegKind(state), | 1197 NaClExtractAddressRegKind(state), |
| 1194 NaClGetGenRmRegister(state)); | 1198 NaClGetGenRmRegister(state)); |
| 1195 NaClExtractDisplacement(state, &displacement, NACL_EFLAG(ExprSignedHex)); | 1199 NaClExtractDisplacement(state, &displacement, NACL_EFLAG(ExprSignedHex)); |
| 1196 return NaClAppendMemoryOffset(state, base, RegUnknown, 1, &displacement); | 1200 return NaClAppendMemoryOffset(state, base, RegUnknown, 1, &displacement); |
| 1197 } | 1201 } |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1244 default: | 1248 default: |
| 1245 return NaClFatal("can't translate register group: address size not valid", | 1249 return NaClFatal("can't translate register group: address size not valid", |
| 1246 state); | 1250 state); |
| 1247 } | 1251 } |
| 1248 } | 1252 } |
| 1249 | 1253 |
| 1250 /* Compute the effect address using the Mod/Rm and SIB bytes. */ | 1254 /* Compute the effect address using the Mod/Rm and SIB bytes. */ |
| 1251 static NaClExp* NaClAppendEffectiveAddress( | 1255 static NaClExp* NaClAppendEffectiveAddress( |
| 1252 NaClInstState* state, const NaClOp* operand, | 1256 NaClInstState* state, const NaClOp* operand, |
| 1253 NaClModRmRegKind modrm_reg_kind) { | 1257 NaClModRmRegKind modrm_reg_kind) { |
| 1254 switch(modrm_mod(state->modrm)) { | 1258 switch(modrm_modInline(state->modrm)) { |
| 1255 case 0: | 1259 case 0: |
| 1256 return NaClAppendMod00EffectiveAddress(state, operand); | 1260 return NaClAppendMod00EffectiveAddress(state, operand); |
| 1257 case 1: | 1261 case 1: |
| 1258 return NaClAppendMod01EffectiveAddress(state, operand); | 1262 return NaClAppendMod01EffectiveAddress(state, operand); |
| 1259 case 2: | 1263 case 2: |
| 1260 return NaClAppendMod10EffectiveAddress(state, operand); | 1264 return NaClAppendMod10EffectiveAddress(state, operand); |
| 1261 case 3: | 1265 case 3: |
| 1262 return NaClAppendMod11EffectiveAddress(state, operand, modrm_reg_kind); | 1266 return NaClAppendMod11EffectiveAddress(state, operand, modrm_reg_kind); |
| 1263 default: | 1267 default: |
| 1264 break; | 1268 break; |
| (...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1556 if (operand->flags & NACL_OPFLAG(OpUse)) { | 1560 if (operand->flags & NACL_OPFLAG(OpUse)) { |
| 1557 node->flags |= NACL_EFLAG(ExprUsed); | 1561 node->flags |= NACL_EFLAG(ExprUsed); |
| 1558 } | 1562 } |
| 1559 if (operand->flags & NACL_OPFLAG(OpAddress)) { | 1563 if (operand->flags & NACL_OPFLAG(OpAddress)) { |
| 1560 node->flags |= NACL_EFLAG(ExprAddress); | 1564 node->flags |= NACL_EFLAG(ExprAddress); |
| 1561 } | 1565 } |
| 1562 return node; | 1566 return node; |
| 1563 } | 1567 } |
| 1564 | 1568 |
| 1565 void NaClBuildExpVector(struct NaClInstState* state) { | 1569 void NaClBuildExpVector(struct NaClInstState* state) { |
| 1566 int i; | 1570 uint8_t i; |
| 1571 uint8_t num_ops; |
| 1567 DEBUG(NaClLog(LOG_INFO, | 1572 DEBUG(NaClLog(LOG_INFO, |
| 1568 "building expression vector for pc = %"NACL_PRIxNaClPcAddress | 1573 "building expression vector for pc = %"NACL_PRIxNaClPcAddress |
| 1569 ":\n", | 1574 ":\n", |
| 1570 NaClInstStateVpc(state))); | 1575 NaClInstStateVpc(state))); |
| 1571 for (i = 0; i < state->inst->num_operands; i++) { | 1576 num_ops = NaClGetInstNumberOperandsInline(state->inst); |
| 1577 for (i = 0; i < num_ops; i++) { |
| 1572 NaClExp* n; | 1578 NaClExp* n; |
| 1573 const NaClOp* op = NaClGetInstOperand(state->decoder_tables, | 1579 const NaClOp* op = NaClGetInstOperandInline(state->decoder_tables, |
| 1574 state->inst, i); | 1580 state->inst, i); |
| 1575 DEBUG(NaClLog(LOG_INFO, "translating operand %d:\n", i)); | 1581 DEBUG(NaClLog(LOG_INFO, "translating operand %d:\n", i)); |
| 1576 n = NaClAppendExp(OperandReference, i, 0, &state->nodes); | 1582 n = NaClAppendExp(OperandReference, i, 0, &state->nodes); |
| 1577 if (op->flags & NACL_OPFLAG(OpImplicit)) { | 1583 if (op->flags & NACL_OPFLAG(OpImplicit)) { |
| 1578 n->flags |= NACL_EFLAG(ExprImplicit); | 1584 n->flags |= NACL_EFLAG(ExprImplicit); |
| 1579 } | 1585 } |
| 1580 NaClAddOpSetUse(NaClAppendOperand(state, op), op); | 1586 NaClAddOpSetUse(NaClAppendOperand(state, op), op); |
| 1581 DEBUG(NaClExpVectorPrint(NaClLogGetGio(), &state->nodes)); | 1587 DEBUG(NaClExpVectorPrint(NaClLogGetGio(), &state->nodes)); |
| 1582 } | 1588 } |
| 1583 } | 1589 } |
| OLD | NEW |