Debugging: Add code to print backtrace for guest on SIGSEGV
[nativeclient.git] / ncv / ncdecode.h
blob10c18e0e2e4563be2fa431285a87344615671fda
1 /*
2 * Copyright 2008, Google Inc.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above
12 * copyright notice, this list of conditions and the following disclaimer
13 * in the documentation and/or other materials provided with the
14 * distribution.
15 * * Neither the name of Google Inc. nor the names of its
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 * ncdecode.h - table driven decoder for Native Client.
35 * This header file contains type declarations and constants
36 * used by the decoder input table
38 #ifndef __NCDECODE_H__
39 #define __NCDECODE_H__
40 #include "native_client/include/portability.h"
42 struct NCDecoderState;
43 struct NCValidatorState;
44 /* Function type for a decoder action */
45 typedef void (*NCDecoderAction)(const struct NCDecoderState *mstate);
46 typedef void (*NCDecoderStats)(struct NCValidatorState *vstate);
48 /* Using a bit mask here. Hopefully nobody will be offended.
49 * Prefix usage: 0x2e and 0x3e are used as branch prediction hints
50 * 0x64 and 0x65 needed for TLS
51 * 0x26 and 0x36 shouldn't be needed
52 * These are #defines, not const ints, because they are used
53 * for array initialization
55 #define kPrefixSEGCS 0x0001 /* 0x2e */
56 #define kPrefixSEGSS 0x0002 /* 0x36 */
57 #define kPrefixSEGFS 0x0004 /* 0x64 */
58 #define kPrefixSEGGS 0x0008 /* 0x65 */
59 #define kPrefixDATA16 0x0010 /* 0x66 - OKAY */
60 #define kPrefixADDR16 0x0020 /* 0x67 - disallowed */
61 #define kPrefixREPNE 0x0040 /* 0xf2 - OKAY */
62 #define kPrefixREP 0x0080 /* 0xf3 - OKAY */
63 #define kPrefixLOCK 0x0100 /* 0xf0 - OKAY */
64 #define kPrefixSEGES 0x0200 /* 0x26 - disallowed */
65 #define kPrefixSEGDS 0x0400 /* 0x3e - disallowed */
67 /* a new enumerated type for instructions */
68 typedef enum {
69 NACLi_UNDEFINED=0, /* uninitialized space; should never happen */
70 NACLi_ILLEGAL, /* not allowed in NaCl */
71 NACLi_INVALID, /* not valid on any known x86 */
72 NACLi_SYSTEM, /* ring-0 instruction, not allowed in NaCl */
73 NACLi_386, /* an allowed instruction on all i386 implementations */
74 NACLi_386L, /* subset of i386 that allows LOCK prefix */
75 NACLi_386R, /* subset of i386 that allow REP prefix */
76 NACLi_386RE, /* subset of i386 that allow REPE/REPZ prefixes */
77 NACLi_JMP8,
78 NACLi_JMPZ,
79 NACLi_INDIRECT,
80 NACLi_OPINMRM,
81 NACLi_RETURN,
82 NACLi_CFLUSH,
83 NACLi_CMPXCHG8B,
84 NACLi_CMPXCHG16B, /* 64-bit mode only, illegal for NaCl */
85 NACLi_CMOV,
86 NACLi_RDMSR,
87 NACLi_RDTSC,
88 NACLi_RDTSCP, /* AMD only */
89 NACLi_SYSCALL, /* AMD only; equivalent to SYSENTER */
90 NACLi_SYSENTER,
91 NACLi_X87,
92 NACLi_MMX,
93 NACLi_MMXSSE2, /* MMX with no prefix, SSE2 with 0x66 prefix */
94 NACLi_3DNOW, /* AMD only */
95 NACLi_EMMX, /* Cyrix only; not supported yet */
96 NACLi_E3DNOW, /* AMD only */
97 NACLi_SSE,
98 NACLi_SSE2, /* no prefix => MMX; prefix 66 => SSE; */
99 /* f2, f3 not allowed unless used for opcode selection */
100 NACLi_SSE2x, /* SSE2; prefix 66 required!!! */
101 NACLi_SSE3,
102 NACLi_SSE4A, /* AMD only */
103 NACLi_SSE41,
104 NACLi_SSE42,
105 NACLi_MOVBE,
106 NACLi_POPCNT,
107 NACLi_LZCNT,
108 NACLi_LONGMODE,/* AMD only? */
109 NACLi_SVM, /* AMD only */
110 NACLi_SSSE3,
111 NACLi_3BYTE,
112 NACLi_FCMOV
113 /* NOTE: This enum must be kept consistent with kNaClInstTypeRange */
114 /* (defined below) and with the string constants in ncdecode_table.c */
115 } NaClInstType;
116 #define kNaClInstTypeRange 43
117 #ifdef NEEDSNACLINSTTYPESTRING
118 static const char *kNaClInstTypeString[kNaClInstTypeRange] = {
119 "NACLi_UNDEFINED",
120 "NACLi_ILLEGAL",
121 "NACLi_INVALID",
122 "NACLi_SYSTEM",
123 "NACLi_386",
124 "NACLi_386L",
125 "NACLi_386R",
126 "NACLi_386RE",
127 "NACLi_JMP8",
128 "NACLi_JMPZ",
129 "NACLi_INDIRECT",
130 "NACLi_OPINMRM",
131 "NACLi_RETURN",
132 "NACLi_CFLUSH",
133 "NACLi_CMPXCHG8B",
134 "NACLi_CMPXCHG16B",
135 "NACLi_CMOV",
136 "NACLi_RDMSR",
137 "NACLi_RDTSC",
138 "NACLi_RDTSCP",
139 "NACLi_SYSCALL",
140 "NACLi_SYSENTER",
141 "NACLi_X87",
142 "NACLi_MMX",
143 "NACLi_MMXSSE2",
144 "NACLi_3DNOW",
145 "NACLi_EMMX",
146 "NACLi_E3DNOW",
147 "NACLi_SSE",
148 "NACLi_SSE2",
149 "NACLi_SSE2x",
150 "NACLi_SSE3",
151 "NACLi_SSE4A",
152 "NACLi_SSE41",
153 "NACLi_SSE42",
154 "NACLi_MOVBE",
155 "NACLi_POPCNT",
156 "NACLi_LZCNT",
157 "NACLi_LONGMODE",
158 "NACLi_SVM",
159 "NACLi_SSSE3",
160 "NACLi_3BYTE",
161 "NACLi_FCMOV",
163 #define NaClInstTypeString(itype) (kNaClInstTypeString[itype])
164 #endif /* ifdef NEEDSNACLINSTTYPESTRING */
166 typedef enum {
167 NOGROUP=0,
168 GROUP1,
169 GROUP2,
170 GROUP3,
171 GROUP4,
172 /* these comments facilitate counting */
173 GROUP5,
174 GROUP6,
175 GROUP7,
176 GROUP8,
177 GROUP9,
178 /* these comments facilitate counting */
179 GROUP10,
180 GROUP11,
181 GROUP12,
182 GROUP13,
183 GROUP14,
184 /* these comments facilitate counting */
185 GROUP15,
186 GROUP16,
187 GROUP17,
188 GROUP1A,
189 GROUPP
190 } NaClMRMGroups;
191 /* kModRMOpcodeGroups doesn't work as a const int since it is used */
192 /* as an array dimension */
193 #define kNaClMRMGroupsRange 20
194 #define kModRMOpcodeGroupSize 8
196 /* information derived from the opcode, wherever it happens to be */
197 typedef enum {
198 IMM_UNKNOWN=0,
199 IMM_NONE=1,
200 IMM_FIXED1=2,
201 IMM_FIXED2=3,
202 IMM_FIXED3=4,
203 IMM_FIXED4=5,
204 IMM_DATAV=6,
205 IMM_ADDRV=7,
206 IMM_GROUP3_F6=8,
207 IMM_GROUP3_F7=9,
208 IMM_FARPTR=10
209 /* Don't add to this enum without update kNCDecodeImmediateTypeRange */
210 /* and updating the tables below which are sized using this constant */
211 } NCDecodeImmediateType;
212 #define kNCDecodeImmediateTypeRange 11
214 /* 255 will force an error */
215 static const uint8_t kImmTypeToSize66[kNCDecodeImmediateTypeRange] =
216 { 0, 0, 1, 2, 3, 4, 2, 4, 0, 0, 6 };
217 static const uint8_t kImmTypeToSize67[kNCDecodeImmediateTypeRange] =
218 { 0, 0, 1, 2, 3, 4, 4, 2, 0, 0, 4 };
219 static const uint8_t kImmTypeToSize[kNCDecodeImmediateTypeRange] =
220 { 0, 0, 1, 2, 3, 4, 4, 4, 0, 0, 6 };
222 #define NCDTABLESIZE 256
223 struct OpInfo {
224 NaClInstType insttype;
225 uint8_t hasmrmbyte; /* 1 if this inst has an mrm byte, else 0 */
226 uint8_t immtype; /* IMM_NONE, IMM_FIXED1, etc. */
227 uint8_t opinmrm; /* set to 1..8 if you must find opcode in MRM byte */
230 struct InstInfo {
231 uint32_t vaddr;
232 uint8_t *maddr;
233 uint8_t prefixbytes; /* 0..4 */
234 uint8_t hasopbyte2;
235 uint8_t hasopbyte3;
236 uint8_t hassibbyte;
237 uint8_t mrm;
238 uint8_t immtype;
239 uint8_t dispbytes;
240 uint8_t length;
241 uint32_t prefixmask;
244 struct NCDecoderState {
245 uint8_t *mpc;
246 uint8_t *nextbyte;
247 uint8_t dbindex; /* index into decodebuffer */
248 uint32_t vpc;
249 const struct OpInfo *opinfo;
250 struct InstInfo inst;
251 struct NCValidatorState *vstate;
252 /* The decodebuffer is an array of size kDecodeBufferSize */
253 /* of NCDecoderState records, used to allow the validator */
254 /* to inspect a small number of previous instructions. */
255 /* It is allocated on the stack to make it thread-local, */
256 /* and included here for use by PreviousInst(). */
257 struct NCDecoderState *decodebuffer;
260 /* We track machine state in a three-entry circular buffer,
261 * allowing us to see the two previous instructions and to
262 * check the safe call sequence. I rounded up to a power of
263 * four so we can use a mask, even though we only need to
264 * remember three instructions.
265 * This is #defined rather than const int because it is used
266 * as an array dimension
268 #define kDecodeBufferSize 4
269 static const int kTwoByteOpcodeByte1 = 0x0f;
270 static const int k3DNowOpcodeByte2 = 0x0f;
271 static const int kMaxPrefixBytes = 4;
273 /* Some essential non-macros... */
274 static INLINE uint8_t modrm_mod(uint8_t modrm) { return ((modrm >> 6) & 0x03);}
275 static INLINE uint8_t modrm_rm(uint8_t modrm) { return (modrm & 0x07); }
276 static INLINE uint8_t modrm_reg(uint8_t modrm) { return ((modrm >> 3) & 0x07); }
277 static INLINE uint8_t modrm_opcode(uint8_t modrm) { return modrm_reg(modrm); }
278 static INLINE uint8_t sib_ss(uint8_t sib) { return ((sib >> 6) & 0x03); }
279 static INLINE uint8_t sib_index(uint8_t sib) { return ((sib >> 3) & 0x07); }
280 static INLINE uint8_t sib_base(uint8_t sib) { return (sib & 0x07); }
282 extern void NCDecodeRegisterCallbacks(NCDecoderAction decoderaction,
283 NCDecoderStats newsegment,
284 NCDecoderStats segmentationerror,
285 NCDecoderStats internalerror);
287 extern void NCDecodeSegment(uint8_t *mbase, uint32_t vbase, size_t sz,
288 struct NCValidatorState *vstate);
290 extern struct NCDecoderState *PreviousInst(const struct NCDecoderState *mstate,
291 int nindex);
293 #endif /* __NCDECODE_H__ */