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.
7 /* Captures instructions that are considered illegal in native client.
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.
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.
23 #ifndef NACL_TRUSTED_BUT_NOT_TCB
24 #error("This file is not meant for use in the TCB")
27 #include "native_client/src/trusted/validator/x86/decoder/generator/nacl_illegal.h"
29 #include "native_client/src/include/nacl_macros.h"
30 #include "native_client/src/trusted/validator/x86/decoder/generator/ncdecode_forms.h"
31 #include "native_client/src/trusted/validator/x86/decoder/generator/ncdecode_tablegen.h"
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.
38 /* ISE reviewers suggested making loopne, loope, loop, jcxz illegal */
73 InstPrefetch_reserved,
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.
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.
92 InstXlat, /* ISE reviewers suggested this omision */
93 /* https://code.google.com/p/nativeclient/issues/detail?id=3944 */
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.
101 { InstPush, { 0x06 , END_OPCODE_SEQ } },
102 { InstPush, { 0x0e , END_OPCODE_SEQ } },
104 /* The following are illegal since they are define by AMD(tm), but not
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 } },
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 } },
128 /* The following operations are provided as a synonym
129 * for the corresponding 0x80 code. NaCl requires the
130 * use of the 0x80 version.
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 } },
141 /* TODO(Karl): Don't know why these are disallowed. */
142 { InstMov , { 0x8c , END_OPCODE_SEQ } },
143 { InstMov , { 0x8e , END_OPCODE_SEQ } },
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
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
154 { InstJmp , { 0xea , END_OPCODE_SEQ } },
155 { InstCall, { 0xff , SL(3), END_OPCODE_SEQ } },
156 { InstJmp , { 0xff , SL(5), END_OPCODE_SEQ } },
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.
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 } },
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.
172 { InstExtrq , { PR(0x66) , 0x0f, 0x78 , SL(0), END_OPCODE_SEQ } },
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.
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 } },
189 void NaClAddNaClIllegalIfApplicable(void) {
190 Bool is_illegal = FALSE; /* until proven otherwise. */
191 NaClModeledInst* inst = NaClGetDefInst();
193 /* TODO(karl) Once all instructions have been modified to be explicitly
194 * marked as illegal, remove the corresponding switch from nc_illegal.c.
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.
200 /* Be sure to handle instruction groups we don't allow. */
201 switch (inst->insttype) {
204 /* EMMX needs to be supported someday but isn't ready yet. */
211 case NACLi_UNDEFINED:
216 case NACLi_FXSAVE: /* don't allow until we can handle. */
220 if (NaClInInstructionSet(
221 kNaClIllegalOp, NACL_ARRAY_SIZE(kNaClIllegalOp),
222 kNaClIllegalOpSeq, NACL_ARRAY_SIZE(kNaClIllegalOpSeq)) ||
223 ((X86_32 == NACL_FLAGS_run_mode) &&
224 NaClInInstructionSet(
226 kNaClIllegal32OpSeq, NACL_ARRAY_SIZE(kNaClIllegal32OpSeq)))) {
232 NaClAddIFlags(NACL_IFLAG(NaClIllegal));