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