Upstream version 11.39.266.0
[platform/framework/web/crosswalk.git] / src / native_client / src / trusted / validator / x86 / decoder / generator / nacl_illegal.c
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_forms.h"
31 #include "native_client/src/trusted/validator/x86/decoder/generator/ncdecode_tablegen.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 }