| OLD | NEW |
| (Empty) |
| 1 /* | |
| 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 | |
| 4 * found in the LICENSE file. | |
| 5 */ | |
| 6 | |
| 7 /* | |
| 8 * Captures instructions that zero extend 32 bit values. | |
| 9 * | |
| 10 * Extracted from table B-1 in AMD document 25494 - AMD64 Architecture | |
| 11 * Programmer's Manual, Volume 3: General-Purpose and System Instructions. | |
| 12 * | |
| 13 * Note: This is used by the x86-64 validator to decide what operations can | |
| 14 * be used to mask control/memory accesses. Therefore, not all instructions | |
| 15 * listed in table B-1 (above) are defined to zero-extend. In particular, | |
| 16 * this is a NaCl-specific flag that is used to whitelist instructions | |
| 17 * that can be used to zero-extend (mask) 32-bit addresses. As such, although | |
| 18 * some instruction can zero-extend, we don't necessarily allow them here. | |
| 19 */ | |
| 20 | |
| 21 #ifndef NACL_TRUSTED_BUT_NOT_TCB | |
| 22 #error("This file is not meant for use in the TCB") | |
| 23 #endif | |
| 24 | |
| 25 #include "native_client/src/trusted/validator/x86/decoder/generator/zero_extends
.h" | |
| 26 | |
| 27 #include "native_client/src/include/nacl_macros.h" | |
| 28 #include "native_client/src/trusted/validator/x86/decoder/generator/ncdecode_for
ms.h" | |
| 29 #include "native_client/src/trusted/validator/x86/decoder/generator/ncdecode_tab
legen.h" | |
| 30 | |
| 31 /* List of instruction mnemonics that zero extend 32 bit results. */ | |
| 32 static const NaClMnemonic kZeroExtend32Op[] = { | |
| 33 /* Note: The following instructions are listed in table B-1 (above), but are | |
| 34 * not included for the following reasons: | |
| 35 * | |
| 36 * Bsf and Bsr instructions are not included because they conditionally | |
| 37 * write the destination. See | |
| 38 * http://code.google.com/p/nativeclient/issues/detail?id=2010 | |
| 39 * | |
| 40 * Cmovcc instructions (0f40 through 0f4f) are not included out of caution. | |
| 41 * Table B-1 (above) states that these instrucitons always zero extends 32 bit | |
| 42 * register results to 64 bits, and that this occurs even if the condition | |
| 43 * is false. However, we decided to be safe and omit these instructions | |
| 44 * anyway. | |
| 45 * | |
| 46 * Cmpxchg is not included because it conditionally writes to | |
| 47 * different destinations. | |
| 48 * | |
| 49 * Bswap is not included because we don't really think that | |
| 50 * swapping the bottom bytes is a good thing to do to mask a memory | |
| 51 * reference. | |
| 52 * | |
| 53 * Bt, Btc, Btr, Bts, Rcl, Rcr, Rol, Rol, Sar, Shl, Shld, Shr, and | |
| 54 * Shrd instructions are not included out of caution. We assume that | |
| 55 * these instructions are used for bit manipulation rather than | |
| 56 * computing viable addresses. | |
| 57 * | |
| 58 * Adc and Sbb are not included since borrows/carries should not be | |
| 59 * need when calculating an address. | |
| 60 * | |
| 61 * Cpuid, In, and Lar instructions are not included just because they | |
| 62 * shouldn't be. | |
| 63 * | |
| 64 * Div, Idiv, and Mul instructions are not included because we never | |
| 65 * allowed them. | |
| 66 * | |
| 67 * Lfs, Lgs, Lss, and Lsl instructions are not included because segment | |
| 68 * addresses shouldn't be used. | |
| 69 * | |
| 70 * Lzcnt is not included because it is unlikely to be useful for | |
| 71 * computing an address based on the number of leading zeros of a value. | |
| 72 * | |
| 73 * Pextrb is not included because you shouldn't use MMX registers | |
| 74 * to hold addresses. | |
| 75 * | |
| 76 * Popcnt is not included because it is unlikely to be useful for computing | |
| 77 * an address based on the number of ones in a value. | |
| 78 * | |
| 79 * Rdmsr is not included, because you shouldn't be reading model specific | |
| 80 * registers. | |
| 81 * | |
| 82 * Rdpmc is not included because you shouldn't be basing addresses on | |
| 83 * the performance-monitor counter. | |
| 84 * | |
| 85 * Rdtsc and Rdtscp are not included because you shouldn't be basing | |
| 86 * addresses on the time-stamp counter or the processor id. | |
| 87 * | |
| 88 * Smsw is not included since you shouldn't be basing addresses on the | |
| 89 * machine status word. | |
| 90 */ | |
| 91 InstAdd, /* 01, 03, 05, 81/0, 83/0 */ | |
| 92 InstAnd, /* 21, 23, 25, 81/4, 83/4 */ | |
| 93 InstImul, /* f7/5 , 0f af , 69 , 6b */ | |
| 94 InstLea, /* 8D */ | |
| 95 InstMov, /* 89, 8b, c7, b8 through bf, a1 (moffset), | |
| 96 a3 (moffset) | |
| 97 */ | |
| 98 InstMovd, /* 0f 6e, 0f 7e */ | |
| 99 InstMovsx, /* 0f be, 0f bf */ | |
| 100 InstMovsxd, /* 63 */ | |
| 101 InstMovzx, /* 0f b6, 0f b7 */ | |
| 102 InstNeg, /* f7/3 */ | |
| 103 InstNot, /* f7/2 */ | |
| 104 InstOr, /* 09, 0b, 0d, 81/1, 83/1 */ | |
| 105 InstSub, /* 29, 2b, 2d, 81/5, 83/5 */ | |
| 106 InstXadd, /* 0f c1 */ | |
| 107 InstXchg, /* 87, 90 through 97 */ | |
| 108 InstXor, /* 31, 33, 35, 81/6, 83/6 */ | |
| 109 }; | |
| 110 | |
| 111 /* List of instruction nmemonics, for specific opcode sequences, that zero | |
| 112 * extend 32 bit results. | |
| 113 */ | |
| 114 static const NaClNameOpcodeSeq kZeroExtend32Opseq[] = { | |
| 115 { InstDec , { 0xFF , SL(1) , END_OPCODE_SEQ } }, | |
| 116 { InstInc , { 0xFF , SL(0) , END_OPCODE_SEQ } }, | |
| 117 }; | |
| 118 | |
| 119 /* Add OperandZeroExtends_v to instruction, if it can hold | |
| 120 * a 32 bit operand. | |
| 121 */ | |
| 122 static void AddZeroExtendToOpDestArgs(NaClModeledInst* inst) { | |
| 123 if (inst->flags & NACL_IFLAG(OperandSize_v)) { | |
| 124 int i; | |
| 125 for (i = 0; i < inst->num_operands; ++i) { | |
| 126 /* Note: we currently don't allow zero extends for | |
| 127 * implicit arguments. This is done just to be extra | |
| 128 * cautious on what we allow to be masks in the | |
| 129 * NaCl x64-64 validator. | |
| 130 */ | |
| 131 if ((inst->operands[i].flags & NACL_OPFLAG(OpSet)) && | |
| 132 (NACL_EMPTY_OPFLAGS == | |
| 133 (inst->operands[i].flags & NACL_OPFLAG(OpImplicit)))) { | |
| 134 NaClAddOpFlags(i, NACL_OPFLAG(OperandZeroExtends_v)); | |
| 135 } | |
| 136 } | |
| 137 } | |
| 138 } | |
| 139 | |
| 140 /* Add OperandZeroExtends_v instruction flag if applicable. */ | |
| 141 void NaClAddZeroExtend32FlagIfApplicable(void) { | |
| 142 if ((X86_64 == NACL_FLAGS_run_mode) && | |
| 143 NaClInInstructionSet(kZeroExtend32Op, | |
| 144 NACL_ARRAY_SIZE(kZeroExtend32Op), | |
| 145 kZeroExtend32Opseq, | |
| 146 NACL_ARRAY_SIZE(kZeroExtend32Opseq))) { | |
| 147 AddZeroExtendToOpDestArgs(NaClGetDefInst()); | |
| 148 } | |
| 149 } | |
| OLD | NEW |