| 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 /* Captures instructions that are considered illegal in native client. | |
| 8 * | |
| 9 * Note: This is used by the x86-64 validator to decide what instructions | |
| 10 * should be flagged as illegal. It is expected to also be used for | |
| 11 * the x86-32 validator sometime in the future. | |
| 12 * | |
| 13 * Note: This code doesn't include rules to check for the case of | |
| 14 * instructions that are near (relative) jumps with operand word size, | |
| 15 * when decoding 64-bit instructions. These instructions are marked | |
| 16 * illegal separately by DEF_OPERAND(Jzw) in ncdecode_forms.c | |
| 17 * See Call/Jcc instructions in Intel document | |
| 18 * 253666-030US - March 2009, "Intel 654 and IA-32 Architectures | |
| 19 * Software Developer's Manual, Volume2A", which specifies that | |
| 20 * such instructions are not supported on all platforms. | |
| 21 */ | |
| 22 | |
| 23 #ifndef NACL_TRUSTED_BUT_NOT_TCB | |
| 24 #error("This file is not meant for use in the TCB") | |
| 25 #endif | |
| 26 | |
| 27 #include "native_client/src/trusted/validator/x86/decoder/generator/nacl_illegal
.h" | |
| 28 | |
| 29 #include "native_client/src/include/nacl_macros.h" | |
| 30 #include "native_client/src/trusted/validator/x86/decoder/generator/ncdecode_for
ms.h" | |
| 31 #include "native_client/src/trusted/validator/x86/decoder/generator/ncdecode_tab
legen.h" | |
| 32 | |
| 33 /* List of instruction mnemonics that are illegal. */ | |
| 34 static const NaClMnemonic kNaClIllegalOp[] = { | |
| 35 /* TODO(karl) This list is incomplete. As we fix instructions to use the new | |
| 36 * generator model, this list will be extended. | |
| 37 */ | |
| 38 /* ISE reviewers suggested making loopne, loope, loop, jcxz illegal */ | |
| 39 InstAaa, | |
| 40 InstAad, | |
| 41 InstAam, | |
| 42 InstAas, | |
| 43 InstBound, | |
| 44 InstDaa, | |
| 45 InstDas, | |
| 46 InstEnter, | |
| 47 InstIn, | |
| 48 InstInsb, | |
| 49 InstInsd, | |
| 50 InstInsw, | |
| 51 InstInt, | |
| 52 InstInto, | |
| 53 InstInt1, | |
| 54 InstInt3, | |
| 55 InstLes, | |
| 56 InstLds, | |
| 57 InstLfs, | |
| 58 InstLgs, | |
| 59 InstLss, | |
| 60 InstIret, | |
| 61 InstIretd, | |
| 62 InstIretq, | |
| 63 InstLeave, | |
| 64 InstOut, | |
| 65 InstOutsb, | |
| 66 InstOutsd, | |
| 67 InstOutsw, | |
| 68 InstPopa, | |
| 69 InstPopad, | |
| 70 InstPopf, | |
| 71 InstPopfd, | |
| 72 InstPopfq, | |
| 73 InstPrefetch_reserved, | |
| 74 InstPusha, | |
| 75 InstPushad, | |
| 76 InstPushf, | |
| 77 InstPushfd, | |
| 78 InstPushfq, | |
| 79 InstRet, | |
| 80 /* TODO(Karl): Intel manual (see comments above) has a blank entry | |
| 81 * for opcode 0xd6, which states that blank entries in the tables | |
| 82 * correspond to reserved (undefined) values Should we treat this | |
| 83 * accordingly? Making illegal till we know more. | |
| 84 */ | |
| 85 InstSalc, | |
| 86 InstSysret, | |
| 87 /* Note: Ud2 is special. We except the instruction sequence "0f0b" (with no | |
| 88 * no prefix bytes) as a special case on a nop instruction. The entry below | |
| 89 * amkes all other forms, i.e. with a prefix bytes, illegal. | |
| 90 */ | |
| 91 InstUd2, | |
| 92 InstXlat, /* ISE reviewers suggested this omision */ | |
| 93 /* https://code.google.com/p/nativeclient/issues/detail?id=3944 */ | |
| 94 InstClflush | |
| 95 }; | |
| 96 | |
| 97 static const NaClNameOpcodeSeq kNaClIllegalOpSeq[] = { | |
| 98 /* The AMD manual shows 0x82 as a synonym for 0x80 in 32-bit mode only. | |
| 99 * They are illegal in 64-bit mode. We omit them for both cases. | |
| 100 */ | |
| 101 { InstPush, { 0x06 , END_OPCODE_SEQ } }, | |
| 102 { InstPush, { 0x0e , END_OPCODE_SEQ } }, | |
| 103 | |
| 104 /* The following are illegal since they are define by AMD(tm), but not | |
| 105 * Intel(TM). | |
| 106 */ | |
| 107 { InstNop, { 0x0f , 0x19 , END_OPCODE_SEQ } }, | |
| 108 { InstNop, { 0x0f , 0x1a , END_OPCODE_SEQ } }, | |
| 109 { InstNop, { 0x0f , 0x1b , END_OPCODE_SEQ } }, | |
| 110 { InstNop, { 0x0f , 0x1c , END_OPCODE_SEQ } }, | |
| 111 { InstNop, { 0x0f , 0x1d , END_OPCODE_SEQ } }, | |
| 112 { InstNop, { 0x0f , 0x1e , END_OPCODE_SEQ } }, | |
| 113 { InstNop, { 0x0f , 0x1f , END_OPCODE_SEQ } }, | |
| 114 | |
| 115 /* Disallow pushing/popping to segment registers. */ | |
| 116 { InstPush, { 0x06 , END_OPCODE_SEQ } }, | |
| 117 { InstPush, { 0x16 , END_OPCODE_SEQ } }, | |
| 118 { InstPush, { 0x0e , END_OPCODE_SEQ } }, | |
| 119 { InstPush, { 0x1e , END_OPCODE_SEQ } }, | |
| 120 { InstPush, { 0x0f , 0xa0 , END_OPCODE_SEQ } }, | |
| 121 { InstPush, { 0x0f , 0xa8 , END_OPCODE_SEQ } }, | |
| 122 { InstPop , { 0x07 , END_OPCODE_SEQ } }, | |
| 123 { InstPop , { 0x17 , END_OPCODE_SEQ } }, | |
| 124 { InstPop , { 0x1f , END_OPCODE_SEQ } }, | |
| 125 { InstPop , { 0x0f , 0xa1 , END_OPCODE_SEQ } }, | |
| 126 { InstPop , { 0x0f , 0xa9 , END_OPCODE_SEQ } }, | |
| 127 | |
| 128 /* The following operations are provided as a synonym | |
| 129 * for the corresponding 0x80 code. NaCl requires the | |
| 130 * use of the 0x80 version. | |
| 131 */ | |
| 132 { InstAdd , { 0x82 , SL(0) , END_OPCODE_SEQ } }, | |
| 133 { InstOr , { 0x82 , SL(1) , END_OPCODE_SEQ } }, | |
| 134 { InstAdc , { 0x82 , SL(2) , END_OPCODE_SEQ } }, | |
| 135 { InstSbb , { 0x82 , SL(3) , END_OPCODE_SEQ } }, | |
| 136 { InstAnd , { 0x82 , SL(4) , END_OPCODE_SEQ } }, | |
| 137 { InstSub , { 0x82 , SL(5) , END_OPCODE_SEQ } }, | |
| 138 { InstXor , { 0x82 , SL(6) , END_OPCODE_SEQ } }, | |
| 139 { InstCmp , { 0x82 , SL(7) , END_OPCODE_SEQ } }, | |
| 140 | |
| 141 /* TODO(Karl): Don't know why these are disallowed. */ | |
| 142 { InstMov , { 0x8c , END_OPCODE_SEQ } }, | |
| 143 { InstMov , { 0x8e , END_OPCODE_SEQ } }, | |
| 144 | |
| 145 /* Don't allow far calls/jumps. */ | |
| 146 { InstCall , { 0x9a , END_OPCODE_SEQ } }, | |
| 147 /* Note: special case 64-bit with 66 prefix, which is not suppported on some | |
| 148 * Intel Chips. See explicit rules in ncdecode_onebyte.c for specific | |
| 149 * override. | |
| 150 * See Call instruction in Intel document 253666-030US - March 2009, | |
| 151 * "Intel 654 and IA-32 Architectures Software Developer's Manual, Volume2A". | |
| 152 * { InstCall , { 0xe8 , END_OCCODE_SEQ } } with prefix 66 | |
| 153 */ | |
| 154 { InstJmp , { 0xea , END_OPCODE_SEQ } }, | |
| 155 { InstCall, { 0xff , SL(3), END_OPCODE_SEQ } }, | |
| 156 { InstJmp , { 0xff , SL(5), END_OPCODE_SEQ } }, | |
| 157 | |
| 158 /* ISE reviewers suggested omitting bt. Issues have with how many bytes are | |
| 159 * accessable when using memory for bit base. Note: Current solution is | |
| 160 * to allow the form that uses a byte, but not general memory/registers. | |
| 161 * This allows bit access to all standard size integers, but doesn't allow | |
| 162 * accesses that are very far away. | |
| 163 */ | |
| 164 { InstBt , { 0x0f , 0xa3 , END_OPCODE_SEQ } }, | |
| 165 { InstBtc , { 0x0f , 0xbb , END_OPCODE_SEQ } }, | |
| 166 { InstBtr , { 0x0f , 0xb3 , END_OPCODE_SEQ } }, | |
| 167 { InstBts , { 0x0f , 0xab , END_OPCODE_SEQ } }, | |
| 168 | |
| 169 /* Added the group17 form of this instruction, since xed does not implement, | |
| 170 * just to be safe. Note: The form in 660F79 is still allowed. | |
| 171 */ | |
| 172 { InstExtrq , { PR(0x66) , 0x0f, 0x78 , SL(0), END_OPCODE_SEQ } }, | |
| 173 }; | |
| 174 | |
| 175 /* Holds illegal opcode sequences for 32-bit model only. */ | |
| 176 static const NaClNameOpcodeSeq kNaClIllegal32OpSeq[] = { | |
| 177 /* ISE reviewers suggested omitting bt, btc, btr and bts, but bt must | |
| 178 * be kept in 64-bit mode, because the compiler needs it to access | |
| 179 * the top 32-bits of a 64-bit value. | |
| 180 * Note: For 32-bit mode, we followed the existing implementation | |
| 181 * that doesn't even allow the one byte form. | |
| 182 */ | |
| 183 { InstBt , { 0x0f , 0xba , SL(4) , END_OPCODE_SEQ } }, | |
| 184 { InstBts , { 0x0f , 0xba , SL(5) , END_OPCODE_SEQ } }, | |
| 185 { InstBtr , { 0x0f , 0xba , SL(6) , END_OPCODE_SEQ } }, | |
| 186 { InstBtc , { 0x0f , 0xba , SL(7) , END_OPCODE_SEQ } }, | |
| 187 }; | |
| 188 | |
| 189 void NaClAddNaClIllegalIfApplicable(void) { | |
| 190 Bool is_illegal = FALSE; /* until proven otherwise. */ | |
| 191 NaClModeledInst* inst = NaClGetDefInst(); | |
| 192 | |
| 193 /* TODO(karl) Once all instructions have been modified to be explicitly | |
| 194 * marked as illegal, remove the corresponding switch from nc_illegal.c. | |
| 195 * | |
| 196 * Note: As instructions are modified to use the new generator model, | |
| 197 * The file testdata/64/modeled_insts.txt will reflect it by showing | |
| 198 * the NaClIllegal flag. | |
| 199 */ | |
| 200 /* Be sure to handle instruction groups we don't allow. */ | |
| 201 switch (inst->insttype) { | |
| 202 case NACLi_RETURN: | |
| 203 case NACLi_EMMX: | |
| 204 /* EMMX needs to be supported someday but isn't ready yet. */ | |
| 205 case NACLi_ILLEGAL: | |
| 206 case NACLi_SYSTEM: | |
| 207 case NACLi_RDMSR: | |
| 208 case NACLi_RDTSCP: | |
| 209 case NACLi_SVM: | |
| 210 case NACLi_3BYTE: | |
| 211 case NACLi_UNDEFINED: | |
| 212 case NACLi_INVALID: | |
| 213 case NACLi_SYSCALL: | |
| 214 case NACLi_SYSENTER: | |
| 215 case NACLi_VMX: | |
| 216 case NACLi_FXSAVE: /* don't allow until we can handle. */ | |
| 217 is_illegal = TRUE; | |
| 218 break; | |
| 219 default: | |
| 220 if (NaClInInstructionSet( | |
| 221 kNaClIllegalOp, NACL_ARRAY_SIZE(kNaClIllegalOp), | |
| 222 kNaClIllegalOpSeq, NACL_ARRAY_SIZE(kNaClIllegalOpSeq)) || | |
| 223 ((X86_32 == NACL_FLAGS_run_mode) && | |
| 224 NaClInInstructionSet( | |
| 225 NULL, 0, | |
| 226 kNaClIllegal32OpSeq, NACL_ARRAY_SIZE(kNaClIllegal32OpSeq)))) { | |
| 227 is_illegal = TRUE; | |
| 228 } | |
| 229 break; | |
| 230 } | |
| 231 if (is_illegal) { | |
| 232 NaClAddIFlags(NACL_IFLAG(NaClIllegal)); | |
| 233 } | |
| 234 } | |
| OLD | NEW |