OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright (c) 2012 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 * ncdecode.h - table driven decoder for Native Client. | |
9 * | |
10 * This header file contains type declarations and constants | |
11 * used by the decoder input table | |
12 */ | |
13 #ifndef NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_X86_NCVAL_SEG_SFI_NCDECODE_H_ | |
14 #define NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_X86_NCVAL_SEG_SFI_NCDECODE_H_ | |
15 | |
16 #include "native_client/src/shared/utils/types.h" | |
17 #include "native_client/src/trusted/validator/ncvalidate.h" | |
18 #include "native_client/src/trusted/validator/x86/error_reporter.h" | |
19 #include "native_client/src/trusted/validator/x86/ncinstbuffer.h" | |
20 #include "native_client/src/trusted/validator/x86/x86_insts.h" | |
21 | |
22 EXTERN_C_BEGIN | |
23 | |
24 struct NCDecoderInst; | |
25 struct NCDecoderState; | |
26 | |
27 /* Function type for a decoder action. Returns TRUE if action | |
28 * was applied successfully. | |
29 */ | |
30 typedef Bool (*NCDecoderStateAction)(const struct NCDecoderInst* dinst); | |
31 | |
32 /* Function type for other decoder state methods. */ | |
33 typedef void (*NCDecoderStateMethod)(struct NCDecoderState* vstate); | |
34 | |
35 typedef enum { | |
36 NOGROUP = 0, | |
37 GROUP1, | |
38 GROUP2, | |
39 GROUP3, | |
40 GROUP4, | |
41 /* these comments facilitate counting */ | |
42 GROUP5, | |
43 GROUP6, | |
44 GROUP7, | |
45 GROUP8, | |
46 GROUP9, | |
47 /* these comments facilitate counting */ | |
48 GROUP10, | |
49 GROUP11, | |
50 GROUP12, | |
51 GROUP13, | |
52 GROUP14, | |
53 /* these comments facilitate counting */ | |
54 GROUP15, | |
55 GROUP16, | |
56 GROUP17, | |
57 GROUP1A, | |
58 GROUPP | |
59 } NaClMRMGroups; | |
60 /* kModRMOpcodeGroups doesn't work as a const int since it is used */ | |
61 /* as an array dimension */ | |
62 #define kNaClMRMGroupsRange 20 | |
63 | |
64 /* Define the maximum value that can be encoded in the modrm mod field. */ | |
65 #define kModRMOpcodeGroupSize 8 | |
66 | |
67 /* Define the maximum register value that can be encoded into the opcode | |
68 * byte. | |
69 */ | |
70 #define kMaxRegisterIndexInOpcode 7 | |
71 | |
72 /* information derived from the opcode, wherever it happens to be */ | |
73 typedef enum { | |
74 IMM_UNKNOWN = 0, | |
75 IMM_NONE = 1, | |
76 IMM_FIXED1 = 2, | |
77 IMM_FIXED2 = 3, | |
78 IMM_FIXED3 = 4, | |
79 IMM_FIXED4 = 5, | |
80 IMM_DATAV = 6, | |
81 IMM_ADDRV = 7, | |
82 IMM_GROUP3_F6 = 8, | |
83 IMM_GROUP3_F7 = 9, | |
84 IMM_FARPTR = 10, | |
85 IMM_MOV_DATAV, /* Special case for 64-bits MOVs (b8 through bf). */ | |
86 /* Don't add to this enum without update kNCDecodeImmediateTypeRange */ | |
87 /* and updating the tables below which are sized using this constant */ | |
88 } NCDecodeImmediateType; | |
89 #define kNCDecodeImmediateTypeRange 12 | |
90 | |
91 /* 255 will force an error */ | |
92 static const uint8_t kImmTypeToSize66[kNCDecodeImmediateTypeRange] = | |
93 { 0, 0, 1, 2, 3, 4, 2, (NACL_TARGET_SUBARCH == 64 ? 8 : 4), 0, 0, 6, 2}; | |
94 static const uint8_t kImmTypeToSize67[kNCDecodeImmediateTypeRange] = | |
95 { 0, 0, 1, 2, 3, 4, 4, 2, 0, 0, 4, 4}; | |
96 static const uint8_t kImmTypeToSize[kNCDecodeImmediateTypeRange] = | |
97 { 0, 0, 1, 2, 3, 4, 4, (NACL_TARGET_SUBARCH == 64 ? 8 : 4), 0, 0, 6, 4 }; | |
98 | |
99 /* Defines how to decode operands for byte codes. */ | |
100 typedef enum { | |
101 /* Assume the default size of the operands is 64-bits (if | |
102 * not specified in prefix bits). | |
103 */ | |
104 DECODE_OPS_DEFAULT_64, | |
105 /* Assume the default size of the operands is 32-bits (if | |
106 * not specified in prefix bits). | |
107 */ | |
108 DECODE_OPS_DEFAULT_32, | |
109 /* Force the size of the operands to 64 bits (prefix bits are | |
110 * ignored). | |
111 */ | |
112 DECODE_OPS_FORCE_64 | |
113 } DecodeOpsKind; | |
114 | |
115 /* Models information on an x86-32 bit instruction. */ | |
116 struct OpInfo { | |
117 NaClInstType insttype; | |
118 uint8_t hasmrmbyte; /* 1 if this inst has an mrm byte, else 0 */ | |
119 uint8_t immtype; /* IMM_NONE, IMM_FIXED1, etc. */ | |
120 uint8_t opinmrm; /* set to 1..8 if you must find opcode in MRM byte */ | |
121 }; | |
122 | |
123 /* Models a node in a trie of NOP instructions. */ | |
124 typedef struct NCNopTrieNode { | |
125 /* The matching byte for the trie node. */ | |
126 uint8_t matching_byte; | |
127 /* The matching modeled nop, if byte matched. */ | |
128 struct OpInfo *matching_opinfo; | |
129 /* Node to match remaining bytes. */ | |
130 struct NCNopTrieNode* success; | |
131 /* Node to match remaining bytes. */ | |
132 struct NCNopTrieNode* fail; | |
133 } NCNopTrieNode; | |
134 | |
135 /* Predefined value to communicate that the lock prefix was not | |
136 * found in an instruction. | |
137 */ | |
138 static const uint8_t kNoLockPrefixIndex = 0xFF; | |
139 | |
140 /* Models a parsed x86-32 bit instruction. */ | |
141 struct InstInfo { | |
142 /* The bytes used to parse the x86-32 instruction (may have added | |
143 * zero filler if the instruction straddles the memory segment). | |
144 */ | |
145 NCInstBytes bytes; | |
146 /* The number of prefix bytes in the instruction. */ | |
147 uint8_t prefixbytes; /* 0..4 */ | |
148 /* Number of opcode bytes in the instruction. */ | |
149 uint8_t num_opbytes; | |
150 /* non-zero if the instruction contains an SIB byte. */ | |
151 uint8_t hassibbyte; | |
152 /* The ModRm byte. */ | |
153 uint8_t mrm; | |
154 /* A NCDecodeImmediateType describing the type of immediate value(s) | |
155 * the instruction has. | |
156 */ | |
157 uint8_t immtype; | |
158 /* The number of bytes that define the immediate value(s). */ | |
159 uint8_t immbytes; | |
160 /* The number of displacement bytes defined by the instruction. */ | |
161 uint8_t dispbytes; | |
162 /* The set of prefix masks defined by the prefix bytes. */ | |
163 uint32_t prefixmask; | |
164 /* The prefix form used to select multibyte instructions, or 0 if | |
165 * not used. That is, if 66, f2, or f3 is used to select the instruction, | |
166 * then this value is non-zero. For example SSE3 instructions. | |
167 */ | |
168 uint32_t opcode_prefixmask; | |
169 /* True if it has a rex prefix. */ | |
170 uint8_t rexprefix; | |
171 /* Index of lock prefix (F0), or kNoLockPrefixIndex if the lock prefix | |
172 * isn't specified. | |
173 */ | |
174 uint8_t lock_prefix_index; | |
175 }; | |
176 | |
177 /* Models data collected about the parsed instruction. */ | |
178 typedef struct NCDecoderInst { | |
179 /* The address of the instruction, relative to the begining of the code | |
180 * segment. | |
181 */ | |
182 NaClPcAddress inst_addr; | |
183 /* The instruction rule used to decode the instruction. */ | |
184 const struct OpInfo* opinfo; | |
185 /* The low level details of the instructionm, extracted during parsing. */ | |
186 struct InstInfo inst; | |
187 /* Pointer to bytes of the parsed instruction (int inst) for easier access. */ | |
188 const NCInstBytesPtr inst_bytes; | |
189 /* The decoder state the instruction appears in. */ | |
190 struct NCDecoderState* dstate; | |
191 /* Corresopnding index of this instruction wrt to inst_buffer in | |
192 * in the corresponding decoder state NCDecoderState. | |
193 */ | |
194 size_t inst_index; | |
195 /* The number of instructions parsed so far (including this instrruction). | |
196 * Used to detect when one tries to get a previous instruction that doesn't | |
197 * exist. | |
198 */ | |
199 size_t inst_count; | |
200 /* True if the instruction is unchanged while dynamically replacing code. | |
201 * False if the instruction has changed or if code replacement is not being | |
202 * performed (i.e. normal validation.) | |
203 */ | |
204 Bool unchanged; | |
205 } NCDecoderInst; | |
206 | |
207 /* Given a (decoded) instruction, return the instruction that appeared | |
208 * n elements before it, or NULL if no such instruction exists. | |
209 * | |
210 * Parameters: | |
211 * dinst - The instruction to look up relative to. | |
212 * n - number of elements back to look. | |
213 */ | |
214 extern NCDecoderInst *PreviousInst(const NCDecoderInst* dinst, int n); | |
215 | |
216 /* Models decoding instructions in a memory region. | |
217 * | |
218 * Note: This struct is modeling a notion of a (virtual) base class to parse | |
219 * a window of k instructions. In this model, we consider NCDecoderState a | |
220 * class that can be (singly) inherited by derived classes. This code | |
221 * assumes that the "this" pointer can be cast to a derived class | |
222 * using a C cast. This implies that derived classes should have the | |
223 * field NCDecoderState as its first field. | |
224 * | |
225 * Typical use is: | |
226 * | |
227 * NCDecoderState dstate; | |
228 * NCDecoder inst_buffer[BUF_SIZE]; // window of BUF_SIZE instructions. | |
229 * NCDecoderStateConstruct(&dstate, mbase, vbase, size, | |
230 * inst_buffer, BUF_SIZE); | |
231 * NCDecoderStateDecode(&dstate); | |
232 * NCDecoderStateDestruct(&dstate); | |
233 * | |
234 * Note: The old API for this class is further down in this file, | |
235 * and should be considered deprecated. | |
236 */ | |
237 typedef struct NCDecoderState { | |
238 /* PROTECTED: */ | |
239 | |
240 /* The instruction buffer is an array of instructions, used | |
241 * by the decoder to define a window of decoded instructions. | |
242 * This window automatically moves as instructions are decoded | |
243 * so that one can always see the current decoded instruction, | |
244 * and some (fixed) number of previously decoded instructions. | |
245 */ | |
246 NCDecoderInst* inst_buffer; | |
247 | |
248 /* The number of elements in inst_buffer. Must be greater than zero. */ | |
249 size_t inst_buffer_size; | |
250 | |
251 /* Remaining memory to decode. It is allocated on | |
252 * the stack to make it thread-local, and included here | |
253 * so that all decoder states have access to it. | |
254 */ | |
255 NCRemainingMemory memory; | |
256 | |
257 /* The begining of the memory segment to decode. */ | |
258 uint8_t* mbase; | |
259 | |
260 /* The (virtual) base address of the memory segment. */ | |
261 NaClPcAddress vbase; | |
262 | |
263 /* The number of bytes in the memory segment. */ | |
264 NaClMemorySize size; | |
265 | |
266 /* The index of the current instruction within inst_buffer. */ | |
267 size_t cur_inst_index; | |
268 | |
269 /* Holds the error reporting object to use. */ | |
270 NaClErrorReporter* error_reporter; | |
271 | |
272 /* Member function to apply actions to a decoded instruction. */ | |
273 NCDecoderStateAction action_fn; | |
274 | |
275 /* Member function to process new segment. */ | |
276 NCDecoderStateMethod new_segment_fn; | |
277 | |
278 /* Member function called to report an error with the validity of the | |
279 * memory segment. | |
280 */ | |
281 NCDecoderStateMethod segmentation_error_fn; | |
282 | |
283 /* Member function called to report other errors while processing the | |
284 * memory segment. | |
285 */ | |
286 NCDecoderStateMethod internal_error_fn; | |
287 } NCDecoderState; | |
288 | |
289 /* | |
290 * Construct a decoder state. | |
291 * | |
292 * Parameters are: | |
293 * this - The instance to be constructed. | |
294 * mbase - The begining of the memory segment to decode. | |
295 * vbase - The (virtual) base address of the memory segment. | |
296 * sz - The number of bytes in the memory segment. | |
297 * | |
298 * Note: Constructors of subclasses of NCDecoderState should | |
299 * call this constructor first, to initialize the decoder state. | |
300 */ | |
301 extern void NCDecoderStateConstruct(NCDecoderState* tthis, | |
302 uint8_t* mbase, NaClPcAddress vbase, | |
303 NaClMemorySize sz, | |
304 NCDecoderInst* inst_buffer, | |
305 size_t inst_buffer_size); | |
306 | |
307 /* Define an error reporter to use to report error messages. | |
308 * Note: By default, a decoder state uses the null error reporter, | |
309 * which doesn't report error messages. | |
310 * | |
311 * WARNING: Be sure the error reporter is expecting a NCDecoderInst* for | |
312 * the print_inst method. | |
313 */ | |
314 void NCDecoderStateSetErrorReporter(NCDecoderState* tthis, | |
315 NaClErrorReporter* reporter); | |
316 | |
317 | |
318 /* A default, null error reporter for a NCDecoderInst* instruction. */ | |
319 extern NaClErrorReporter kNCNullErrorReporter; | |
320 | |
321 /* | |
322 * Decodes the memory segment associated with the decoder state. | |
323 * Returns TRUE if able to apply action to all decoded instructions. | |
324 * | |
325 * Parameters are: | |
326 * this - The decoder state. | |
327 */ | |
328 extern Bool NCDecoderStateDecode(NCDecoderState* tthis); | |
329 | |
330 /* | |
331 * Destruct a decoder state. | |
332 * | |
333 * Parameters are: | |
334 * this - The decoder state. | |
335 * | |
336 * Note: Destructors of subclasses of NCDecoderState should | |
337 * call this destructor last, after the subinstance has been destructed. | |
338 */ | |
339 extern void NCDecoderStateDestruct(NCDecoderState* tthis); | |
340 | |
341 /* "Printable" means the value returned by this function can be used for | |
342 * printing user-readable output, but it should not be used to influence if the | |
343 * validation algorithm passes or fails. The validation algorithm should not | |
344 * depend on vbase - in other words, it should not depend on where the code is | |
345 * being mapped in memory. | |
346 */ | |
347 static INLINE NaClPcAddress NCPrintableInstructionAddress( | |
348 const NCDecoderInst *dinst) { | |
349 return dinst->dstate->vbase + dinst->inst_addr; | |
350 } | |
351 | |
352 struct NCDecoderStatePair; | |
353 | |
354 /* Models a method that does a compare/update on a pair of instructions from | |
355 * the pairwise instruction decoder. Returns true if the action succeeded. | |
356 */ | |
357 typedef Bool (*NCDecoderStatePairAction)(struct NCDecoderStatePair* tthis, | |
358 struct NCDecoderInst* dinst_old, | |
359 struct NCDecoderInst* dinst_new); | |
360 | |
361 /* Models decoding a pair of instruction segments, compariing/updating | |
362 * them as appropriate. Assumes that two instruction segments are the same, | |
363 * except for some (constant-sized) changes. At the instruction level, | |
364 * the instruction lengths are assumed to be the same. Typically, this is | |
365 * because the one instruction segment was an updated version of a | |
366 * previous instruction segment. | |
367 * | |
368 * Typical use is: | |
369 * | |
370 * NCDecoderState dstate_old; | |
371 * NCDecoderState dstate_new; | |
372 * NCDecoderStatePair dstate_pair; | |
373 * ... Code that constructs dstate_old and dstate_new. | |
374 * NCDecoderStatePair Construct(&dstate_pair, &dstate_old, &dstate_new); | |
375 * NCDecoderStatePairDecode(&dstate_pair); | |
376 * NCDecoderStatePairDestruct(&dstate_pair); | |
377 */ | |
378 typedef struct NCDecoderStatePair { | |
379 /* PROTECTED: */ | |
380 | |
381 /* The old decoder state. */ | |
382 NCDecoderState* old_dstate; | |
383 | |
384 /* The new decoder state. */ | |
385 NCDecoderState* new_dstate; | |
386 | |
387 /* The (virtual method) action to apply to each instruction. */ | |
388 NCDecoderStatePairAction action_fn; | |
389 | |
390 /* Utility function that copies a single instruction in memory, can be used in | |
391 * actions. | |
392 */ | |
393 NaClCopyInstructionFunc copy_func; | |
394 } NCDecoderStatePair; | |
395 | |
396 /* | |
397 * Construct a decoder state pair. | |
398 * | |
399 * Parameters are: | |
400 * tthis - The decoder state pair to construct. | |
401 * old_dstate - A constructed old decoder state to use. | |
402 * new_dstate - A constructed new decoder state to use. | |
403 * | |
404 * Note: Constructors of subclasses of NCDecoderStatePair should | |
405 * call this constructor first, to initialize the decoder pair fields. | |
406 */ | |
407 extern void NCDecoderStatePairConstruct( | |
408 NCDecoderStatePair* tthis, | |
409 NCDecoderState* old_dstate, | |
410 NCDecoderState* new_dstate, | |
411 NaClCopyInstructionFunc copy_func); | |
412 | |
413 /* | |
414 * Decode the memory segments in each instruction state, applying | |
415 * the appropriate action on each instruction till either: | |
416 * (1) The instruction lengths differ. | |
417 * (2) The action returns false. | |
418 * Returns true if no instruction lengths differ, and the action | |
419 * returns true for all found instructions. | |
420 */ | |
421 extern Bool NCDecoderStatePairDecode(NCDecoderStatePair* tthis); | |
422 | |
423 /* | |
424 * Destruct a decoder state pair. | |
425 * | |
426 * Note: Destructors of subclasses of NCDecoderStatePair should | |
427 * call this distructor last, after the subinstance has been destructed. | |
428 */ | |
429 extern void NCDecoderStatePairDestruct(NCDecoderStatePair* tthis); | |
430 | |
431 EXTERN_C_END | |
432 | |
433 #endif /* NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_X86_NCVAL_SEG_SFI_NCDECODE_H_ */ | |
OLD | NEW |