OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2011 The Native Client Authors. All rights reserved. | 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 | 3 * Use of this source code is governed by a BSD-style license that can be |
4 * found in the LICENSE file. | 4 * found in the LICENSE file. |
5 */ | 5 */ |
6 | 6 |
7 /* | 7 /* |
8 * Defines an instruction (decoder), based on the current location of | 8 * Defines an instruction (decoder), based on the current location of |
9 * the instruction iterator. The instruction decoder takes a list | 9 * the instruction iterator. The instruction decoder takes a list |
10 * of candidate opcode (instruction) patterns, and searches for the | 10 * of candidate opcode (instruction) patterns, and searches for the |
11 * first candidate that matches the requirements of the opcode pattern. | 11 * first candidate that matches the requirements of the opcode pattern. |
12 */ | 12 */ |
13 | 13 |
14 #include <stdio.h> | |
15 #include <assert.h> | |
16 | 14 |
17 #include "native_client/src/trusted/validator_x86/nc_inst_state.h" | 15 #include "native_client/src/trusted/validator_x86/nc_inst_state.h" |
18 | 16 |
19 #include "native_client/src/shared/platform/nacl_log.h" | |
20 #include "native_client/src/trusted/validator_x86/nc_inst_iter.h" | |
21 #include "native_client/src/trusted/validator_x86/nc_inst_state_internal.h" | |
22 #include "native_client/src/trusted/validator_x86/nc_inst_trans.h" | |
23 #include "native_client/src/trusted/validator_x86/nc_segment.h" | |
24 #include "native_client/src/trusted/validator_x86/ncop_exps.h" | |
25 #include "native_client/src/trusted/validator_x86/ncopcode_desc.h" | |
26 #ifdef _WIN64 | |
27 #include "gen/native_client/src/trusted/validator_x86/nc_opcode_table64.h" | |
28 #else | |
29 #include "gen/native_client/src/trusted/validator_x86/nc_opcode_table.h" | |
30 #endif | |
31 | |
32 /* To turn on debugging of instruction decoding, change value of | 17 /* To turn on debugging of instruction decoding, change value of |
33 * DEBUGGING to 1. | 18 * DEBUGGING to 1. |
34 */ | 19 */ |
35 #define DEBUGGING 0 | 20 #define DEBUGGING 0 |
36 | 21 |
37 #include "native_client/src/shared/utils/debugging.h" | 22 #include "native_client/src/trusted/validator_x86/nc_inst_state_statics.c" |
38 | |
39 /* Given the current location of the instruction iterator, initialize | |
40 * the given state (to match). | |
41 */ | |
42 static void NaClInstStateInit(NaClInstIter* iter, NaClInstState* state) { | |
43 NaClMemorySize limit; | |
44 NCInstBytesInit(&state->bytes); | |
45 state->vpc = iter->segment->vbase + iter->index; | |
46 limit = iter->segment->size - iter->index; | |
47 if (limit > NACL_MAX_BYTES_PER_X86_INSTRUCTION) { | |
48 limit = NACL_MAX_BYTES_PER_X86_INSTRUCTION; | |
49 } | |
50 state->length_limit = (uint8_t) limit; | |
51 DEBUG(NaClLog(LOG_INFO, | |
52 "length limit = %"NACL_PRIu8"\n", state->length_limit)); | |
53 state->num_prefix_bytes = 0; | |
54 state->rexprefix = 0; | |
55 state->num_rex_prefixes = 0; | |
56 state->modrm = 0; | |
57 state->has_prefix_duplicates = FALSE; | |
58 state->has_ambig_segment_prefixes = FALSE; | |
59 state->has_sib = FALSE; | |
60 state->sib = 0; | |
61 state->num_disp_bytes = 0; | |
62 state->first_disp_byte = 0; | |
63 state->num_imm_bytes = 0; | |
64 state->first_imm_byte = 0; | |
65 state->num_imm2_bytes = 0; | |
66 state->prefix_mask = 0; | |
67 state->inst = NULL; | |
68 state->nodes.is_defined = FALSE; | |
69 state->nodes.number_expr_nodes = 0; | |
70 } | |
71 | |
72 /* Computes the number of bytes defined for operands of the matched | |
73 * instruction of the given state. | |
74 */ | |
75 static int NaClExtractOpSize(NaClInstState* state) { | |
76 if (state->inst->flags & NACL_IFLAG(OperandSize_b)) { | |
77 return 1; | |
78 } | |
79 if (NACL_TARGET_SUBARCH == 64) { | |
80 if ((state->rexprefix && state->rexprefix & 0x8) || | |
81 (state->inst->flags & NACL_IFLAG(OperandSizeForce64))) { | |
82 return 8; | |
83 } | |
84 } | |
85 if ((state->prefix_mask & kPrefixDATA16) && | |
86 (NACL_EMPTY_IFLAGS == | |
87 (state->inst->flags & NACL_IFLAG(SizeIgnoresData16)))) { | |
88 return 2; | |
89 } | |
90 if ((NACL_TARGET_SUBARCH == 64) && | |
91 (state->inst->flags & NACL_IFLAG(OperandSizeDefaultIs64))) { | |
92 return 8; | |
93 } | |
94 return 4; | |
95 } | |
96 | |
97 /* Computes the number of bits defined for addresses of the matched | |
98 * instruction of the given state. | |
99 */ | |
100 static int NaClExtractAddressSize(NaClInstState* state) { | |
101 if (NACL_TARGET_SUBARCH == 64) { | |
102 return (state->prefix_mask & kPrefixADDR16) ? 32 : 64; | |
103 } else { | |
104 return (state->prefix_mask & kPrefixADDR16) ? 16 : 32; | |
105 } | |
106 } | |
107 | |
108 /* Manual implies only 4 bytes is allowed, but I have found up to 6. | |
109 * Why don't we allow any number, so long as (1) There is room for | |
110 * at least one opcode byte, and (2) we don't exceed the max bytes. | |
111 */ | |
112 static const int kNaClMaximumPrefixBytes = | |
113 NACL_MAX_BYTES_PER_X86_INSTRUCTION - 1; | |
114 | |
115 /* Captures ambiguous segment prefix forms. Used to make | |
116 * detection of multiple prefix segment bytes. | |
117 */ | |
118 static const uint32_t segment_prefix_forms = | |
119 kPrefixSEGCS | kPrefixSEGSS | kPrefixSEGFS | | |
120 kPrefixSEGGS | kPrefixSEGES | kPrefixSEGDS; | |
121 | |
122 /* Match any prefix bytes that can be associated with the instruction | |
123 * currently being matched. | |
124 */ | |
125 static Bool NaClConsumePrefixBytes(NaClInstState* state) { | |
126 uint8_t next_byte; | |
127 int i; | |
128 uint32_t prefix_form; | |
129 int rex_index = -1; | |
130 for (i = 0; i < kNaClMaximumPrefixBytes; ++i) { | |
131 /* Quit early if no more bytes in segment. */ | |
132 if (state->bytes.length >= state->length_limit) break; | |
133 | |
134 /* Look up the corresponding prefix bit associated | |
135 * with the next byte in the segment, and record it. | |
136 */ | |
137 next_byte = NCRemainingMemoryLookahead(state->bytes.memory,0); | |
138 prefix_form = kNaClPrefixTable[next_byte]; | |
139 if (prefix_form == 0) break; | |
140 next_byte = NCInstBytesRead(&state->bytes); | |
141 DEBUG(NaClLog(LOG_INFO, | |
142 "Consume prefix[%d]: %02"NACL_PRIx8" => %"NACL_PRIx32"\n", | |
143 i, next_byte, prefix_form)); | |
144 /* Before updating prefix mask, determine if the prefix byte is | |
145 * a duplicate. | |
146 */ | |
147 if ((state->prefix_mask & prefix_form)) { | |
148 state->has_prefix_duplicates = TRUE; | |
149 DEBUG(NaClLog(LOG_INFO, | |
150 "duplicate prefix %02"NACL_PRIx8" detected.\n", next_byte)); | |
151 } else if ((prefix_form & segment_prefix_forms) && | |
152 (state->prefix_mask & segment_prefix_forms)) { | |
153 state->has_ambig_segment_prefixes = TRUE; | |
154 DEBUG(NaClLog(LOG_INFO, | |
155 "ambiguos segment prefix %02"NACL_PRIx8" detected.\n", | |
156 next_byte)); | |
157 } | |
158 state->prefix_mask |= prefix_form; | |
159 ++state->num_prefix_bytes; | |
160 DEBUG(NaClLog(LOG_INFO, | |
161 " prefix mask: %08"NACL_PRIx32"\n", state->prefix_mask)); | |
162 | |
163 /* If the prefix byte is a REX prefix, record its value, since | |
164 * bits 5-8 of this prefix bit may be needed later. | |
165 */ | |
166 if (NACL_TARGET_SUBARCH == 64) { | |
167 if (prefix_form == kPrefixREX) { | |
168 state->rexprefix = next_byte; | |
169 DEBUG(NaClLog(LOG_INFO, | |
170 " rexprefix = %02"NACL_PRIx8"\n", state->rexprefix)); | |
171 ++state->num_rex_prefixes; | |
172 rex_index = i; | |
173 } | |
174 } | |
175 } | |
176 if (NACL_TARGET_SUBARCH == 64) { | |
177 /* REX prefix must be last, unless FO exists. If FO | |
178 * exists, it must be after REX (Intel Manual). | |
179 * | |
180 * NOTE: (karl) It appears that this constraint is violated | |
181 * with compiled code of /bin/ld_static. According to AMD, | |
182 * the rex prefix must be last. Changing code to allow REX | |
183 * prefix to occur anywhere. | |
184 */ | |
185 if (rex_index >= 0) { | |
186 return (rex_index + 1) == state->num_prefix_bytes; | |
187 } | |
188 } | |
189 return TRUE; | |
190 } | |
191 | |
192 /* Structure holding the results of consuming the opcode bytes of the | |
193 * instruction. | |
194 */ | |
195 typedef struct { | |
196 /* The (last) byte of the matched opcode. */ | |
197 uint8_t opcode_byte; | |
198 /* The most specific prefix that the opcode bytes can match | |
199 * (or OpcodePrefixEnumSize if no such patterns exist). | |
200 */ | |
201 NaClInstPrefix matched_prefix; | |
202 /* The number of bytes to subtract from the instruction length, | |
203 * the next time GetNextNaClInstCandidates is called. | |
204 */ | |
205 uint8_t next_length_adjustment; | |
206 } NaClInstPrefixDescriptor; | |
207 | |
208 /* Assuming we have matched the byte sequence OF 38, consume the corresponding | |
209 * following (instruction) opcode byte, returning the most specific prefix the | |
210 * patterns can match (or NaClInstPrefixEnumSize if no such patterns exist); | |
211 */ | |
212 static void NaClConsume0F38XXNaClInstBytes(NaClInstState* state, | |
213 NaClInstPrefixDescriptor* desc) { | |
214 /* Fail if there are no more bytes. Otherwise, read the next | |
215 * byte. | |
216 */ | |
217 if (state->bytes.length >= state->length_limit) { | |
218 desc->matched_prefix = NaClInstPrefixEnumSize; | |
219 return; | |
220 } | |
221 | |
222 desc->opcode_byte = NCInstBytesRead(&state->bytes); | |
223 if (state->prefix_mask & kPrefixREPNE) { | |
224 desc->matched_prefix = PrefixF20F38; | |
225 } | |
226 else if (state->prefix_mask & kPrefixDATA16) { | |
227 desc->matched_prefix = Prefix660F38; | |
228 } else if ((state->prefix_mask & ~kPrefixREX) == 0) { | |
229 desc->matched_prefix = Prefix0F38; | |
230 } else { | |
231 /* Other prefixes like F3 cause an undefined instruction error. */ | |
232 desc->matched_prefix = NaClInstPrefixEnumSize; | |
233 } | |
234 } | |
235 | |
236 /* Assuming we have matched the byte sequence OF 3A, consume the corresponding | |
237 * following (instruction) opcode byte, returning the most specific prefix the | |
238 * patterns can match (or NaClInstPrefixEnumSize if no such patterns exist). | |
239 */ | |
240 static void NaClConsume0F3AXXNaClInstBytes(NaClInstState* state, | |
241 NaClInstPrefixDescriptor* desc) { | |
242 /* Fail if there are no more bytes. Otherwise, read the next | |
243 * byte and choose appropriate prefix. | |
244 */ | |
245 if (state->bytes.length >= state->length_limit) { | |
246 desc->matched_prefix = NaClInstPrefixEnumSize; | |
247 return; | |
248 } | |
249 | |
250 desc->opcode_byte = NCInstBytesRead(&state->bytes); | |
251 if (state->prefix_mask & kPrefixDATA16) { | |
252 desc->matched_prefix = Prefix660F3A; | |
253 } else if ((state->prefix_mask & ~kPrefixREX) == 0) { | |
254 desc->matched_prefix = Prefix0F3A; | |
255 } else { | |
256 /* Other prefixes like F3 cause an undefined instruction error. */ | |
257 desc->matched_prefix = NaClInstPrefixEnumSize; | |
258 } | |
259 } | |
260 | |
261 /* Assuming we have matched byte OF, consume the corresponding | |
262 * following (instruction) opcode byte, returning the most specific | |
263 * prefix the patterns can match (or NaClInstPrefixEnumSize if no such | |
264 * patterns exist). | |
265 */ | |
266 static void NaClConsume0FXXNaClInstBytes(NaClInstState* state, | |
267 NaClInstPrefixDescriptor* desc) { | |
268 if (state->prefix_mask & kPrefixREPNE) { | |
269 desc->matched_prefix = PrefixF20F; | |
270 } else if (state->prefix_mask & kPrefixREP) { | |
271 desc->matched_prefix = PrefixF30F; | |
272 } else if (state->prefix_mask & kPrefixDATA16) { | |
273 desc->matched_prefix = Prefix660F; | |
274 } else { | |
275 desc->matched_prefix = Prefix0F; | |
276 } | |
277 } | |
278 | |
279 /* Consume one of the x87 instructions that begin with D8-Df, and | |
280 * match the most specific prefix pattern the opcode bytes can match. | |
281 */ | |
282 static void NaClConsumeX87NaClInstBytes(NaClInstState* state, | |
283 NaClInstPrefixDescriptor* desc) { | |
284 if (state->bytes.length < state->length_limit) { | |
285 /* Can be two byte opcode. */ | |
286 desc->matched_prefix = PrefixD8 + | |
287 (((unsigned) desc->opcode_byte) - 0xD8); | |
288 desc->opcode_byte = NCInstBytesRead(&state->bytes); | |
289 return; | |
290 } | |
291 | |
292 /* If reached, can only be single byte opcode, match as such. */ | |
293 desc->matched_prefix = NoPrefix; | |
294 } | |
295 | |
296 /* Consume the opcode bytes, and return the most specific prefix pattern | |
297 * the opcode bytes can match (or NaClInstPrefixEnumSize if no such pattern | |
298 * exists). | |
299 */ | |
300 static void NaClConsumeInstBytes(NaClInstState* state, | |
301 NaClInstPrefixDescriptor* desc) { | |
302 | |
303 /* Initialize descriptor to the fail state. */ | |
304 desc->opcode_byte = 0x0; | |
305 desc->matched_prefix = NaClInstPrefixEnumSize; | |
306 desc->next_length_adjustment = 0; | |
307 | |
308 /* Be sure that we don't exceed the segment length. */ | |
309 if (state->bytes.length >= state->length_limit) return; | |
310 | |
311 desc->opcode_byte = NCInstBytesRead(&state->bytes); | |
312 switch (desc->opcode_byte) { | |
313 case 0x0F: | |
314 if (state->bytes.length >= state->length_limit) return; | |
315 desc->opcode_byte = NCInstBytesRead(&state->bytes); | |
316 switch (desc->opcode_byte) { | |
317 case 0x38: | |
318 NaClConsume0F38XXNaClInstBytes(state, desc); | |
319 break; | |
320 case 0x3a: | |
321 NaClConsume0F3AXXNaClInstBytes(state, desc); | |
322 break; | |
323 default: | |
324 NaClConsume0FXXNaClInstBytes(state, desc); | |
325 break; | |
326 } | |
327 break; | |
328 case 0xD8: | |
329 case 0xD9: | |
330 case 0xDA: | |
331 case 0xDB: | |
332 case 0xDC: | |
333 case 0xDD: | |
334 case 0xDE: | |
335 case 0xDF: | |
336 NaClConsumeX87NaClInstBytes(state, desc); | |
337 break; | |
338 default: | |
339 desc->matched_prefix = NoPrefix; | |
340 break; | |
341 } | |
342 DEBUG(NaClLog(LOG_INFO, | |
343 "matched prefix = %s\n", | |
344 NaClInstPrefixName(desc->matched_prefix))); | |
345 } | |
346 | |
347 /* Compute the operand and address sizes for the instruction. Then, verify | |
348 * that the opcode (instruction) pattern allows for such sizes. Aborts | |
349 * the pattern match if any problems. | |
350 */ | |
351 static Bool NaClConsumeAndCheckOperandSize(NaClInstState* state) { | |
352 state->operand_size = NaClExtractOpSize(state); | |
353 DEBUG(NaClLog(LOG_INFO, | |
354 "operand size = %"NACL_PRIu8"\n", state->operand_size)); | |
355 if (state->inst->flags & | |
356 (NACL_IFLAG(OperandSize_w) | NACL_IFLAG(OperandSize_v) | | |
357 NACL_IFLAG(OperandSize_o))) { | |
358 NaClIFlags good = 1; | |
359 switch (state->operand_size) { | |
360 case 2: | |
361 good = (state->inst->flags & NACL_IFLAG(OperandSize_w)); | |
362 break; | |
363 case 4: | |
364 good = (state->inst->flags & NACL_IFLAG(OperandSize_v)); | |
365 break; | |
366 case 8: | |
367 good = (state->inst->flags & NACL_IFLAG(OperandSize_o)); | |
368 break; | |
369 default: | |
370 good = 0; | |
371 break; | |
372 } | |
373 if (!good) { | |
374 /* The flags associated with the opcode (instruction) don't | |
375 * allow the computed sizes, abort the match of the instruction. | |
376 */ | |
377 DEBUG(NaClLog(LOG_INFO, | |
378 "Operand size %"NACL_PRIu8 | |
379 " doesn't match flag requirement!\n", | |
380 state->operand_size)); | |
381 return FALSE; | |
382 } | |
383 } | |
384 return TRUE; | |
385 } | |
386 | |
387 static Bool NaClConsumeAndCheckAddressSize(NaClInstState* state) { | |
388 state->address_size = NaClExtractAddressSize(state); | |
389 DEBUG(NaClLog(LOG_INFO, | |
390 "Address size = %"NACL_PRIu8"\n", state->address_size)); | |
391 if (state->inst->flags & | |
392 (NACL_IFLAG(AddressSize_w) | NACL_IFLAG(AddressSize_v) | | |
393 NACL_IFLAG(AddressSize_o))) { | |
394 NaClIFlags good = 1; | |
395 switch (state->address_size) { | |
396 case 16: | |
397 good = (state->inst->flags & NACL_IFLAG(AddressSize_w)); | |
398 break; | |
399 case 32: | |
400 good = (state->inst->flags & NACL_IFLAG(AddressSize_v)); | |
401 break; | |
402 case 64: | |
403 good = (state->inst->flags & NACL_IFLAG(AddressSize_o)); | |
404 break; | |
405 default: | |
406 good = 0; | |
407 break; | |
408 } | |
409 if (!good) { | |
410 /* The flags associated with the opcode (instruction) don't | |
411 * allow the computed sizes, abort the match of the instruction. | |
412 */ | |
413 DEBUG(NaClLog(LOG_INFO, | |
414 "Address size %"NACL_PRIu8 | |
415 " doesn't match flag requirement!\n", | |
416 state->address_size)); | |
417 return FALSE; | |
418 } | |
419 } | |
420 return TRUE; | |
421 } | |
422 | |
423 /* Returns true if the instruction requires a ModRm bytes. */ | |
424 static Bool NaClInstRequiresModRm(NaClInstState* state) { | |
425 return | |
426 (NACL_EMPTY_IFLAGS != | |
427 (state->inst->flags & NACL_IFLAG(OpcodeUsesModRm))); | |
428 } | |
429 | |
430 /* Consume the Mod/Rm byte of the instruction, if applicable. | |
431 * Aborts the pattern match if any problems. | |
432 */ | |
433 static Bool NaClConsumeModRm(NaClInstState* state) { | |
434 /* First check if the opcode (instruction) pattern specifies that | |
435 * a Mod/Rm byte is needed, and that reading it will not walk | |
436 * past the end of the code segment. | |
437 */ | |
438 if (NaClInstRequiresModRm(state)) { | |
439 uint8_t byte; | |
440 /* Has modrm byte. */ | |
441 if (state->bytes.length >= state->length_limit) { | |
442 DEBUG(NaClLog(LOG_INFO, "Can't read mod/rm, no more bytes!\n")); | |
443 return FALSE; | |
444 } | |
445 byte = NCInstBytesPeek(&state->bytes, 0); | |
446 | |
447 /* Note: Some instructions only allow values where the ModRm mod field | |
448 * is 0x3. Others only allow values where the ModRm mod field isn't 0x3. | |
449 */ | |
450 if (modrm_mod(byte) == 0x3) { | |
451 if (state->inst->flags & NACL_IFLAG(ModRmModIsnt0x3)) { | |
452 DEBUG(NaClLog(LOG_INFO, "Can't match, modrm mod field is 0x3\n")); | |
453 return FALSE; | |
454 } | |
455 } else { | |
456 if (state->inst->flags & NACL_IFLAG(ModRmModIs0x3)) { | |
457 DEBUG(NaClLog(LOG_INFO, "Can't match, modrm mod field not 0x3\n")); | |
458 return FALSE; | |
459 } | |
460 } | |
461 if ((state->inst->flags & NACL_IFLAG(ModRmRegSOperand)) && | |
462 (modrm_reg(byte) > 5)) { | |
463 DEBUG(NaClLog(LOG_INFO, | |
464 "Can't match, modrm reg field doesn't index segment\n")); | |
465 return FALSE; | |
466 } | |
467 state->modrm = NCInstBytesRead(&state->bytes); | |
468 state->num_disp_bytes = 0; | |
469 state->first_disp_byte = 0; | |
470 state->sib = 0; | |
471 state->has_sib = FALSE; | |
472 DEBUG(NaClLog(LOG_INFO, "consume modrm = %02"NACL_PRIx8"\n", state->modrm)); | |
473 | |
474 /* Consume the remaining opcode value in the mod/rm byte | |
475 * if applicable. | |
476 */ | |
477 if (state->inst->flags & NACL_IFLAG(OpcodeInModRm)) { | |
478 const NaClInst* inst = state->inst; | |
479 if (modrm_opcode(state->modrm) != inst->opcode[inst->num_opcode_bytes]) { | |
480 DEBUG( | |
481 NaClLog(LOG_INFO, | |
482 "Discarding, opcode in mrm byte (%02"NACL_PRIx8") " | |
483 "does not match\n", | |
484 modrm_opcode(state->modrm))); | |
485 return FALSE; | |
486 } | |
487 if (state->inst->flags & NACL_IFLAG(OpcodeInModRmRm)) { | |
488 if (modrm_rm(state->modrm) != | |
489 state->inst->opcode[state->inst->num_opcode_bytes+1]) { | |
490 DEBUG(NaClLog(LOG_INFO, | |
491 "Discarding, opcode in mrm rm field (%02"NACL_PRIx8") " | |
492 "does not match\n", | |
493 modrm_rm(state->modrm))); | |
494 return FALSE; | |
495 } | |
496 } | |
497 } | |
498 } | |
499 return TRUE; | |
500 } | |
501 | |
502 /* Returns true if the instruction requires a SIB bytes. */ | |
503 static Bool NaClInstRequiresSib(NaClInstState* state) { | |
504 /* Note: in 64-bit mode, 64-bit addressing is treated the same as 32-bit | |
505 * addressing. Hence, required for all but 16-bit addressing, when | |
506 * the right modrm bytes are specified. | |
507 */ | |
508 return NaClInstRequiresModRm(state) && (16 != state->address_size) && | |
509 (modrm_rm(state->modrm) == 0x04 && modrm_mod(state->modrm) != 0x3); | |
510 } | |
511 | |
512 /* Consume the SIB byte of the instruction, if applicable. Aborts the pattern | |
513 * match if any problems are found. | |
514 */ | |
515 static Bool NaClConsumeSib(NaClInstState* state) { | |
516 /* First check that the opcode (instruction) pattern specifies that | |
517 * a SIB byte is needed, and that reading it will not walk past | |
518 * the end of the code segment. | |
519 */ | |
520 state->sib = 0; | |
521 state->has_sib = NaClInstRequiresSib(state); | |
522 DEBUG(NaClLog(LOG_INFO, "has sib = %d\n", (int) state->has_sib)); | |
523 if (state->has_sib) { | |
524 if (state->bytes.length >= state->length_limit) { | |
525 DEBUG(NaClLog(LOG_INFO, "Can't consume sib, no more bytes!\n")); | |
526 return FALSE; | |
527 } | |
528 /* Read the SIB byte and record. */ | |
529 state->sib = NCInstBytesRead(&state->bytes); | |
530 DEBUG(NaClLog(LOG_INFO, "sib = %02"NACL_PRIx8"\n", state->sib)); | |
531 if (sib_base(state->sib) == 0x05 && modrm_mod(state->modrm) > 2) { | |
532 DEBUG(NaClLog(LOG_INFO, | |
533 "Sib byte implies modrm.mod field <= 2, match fails\n")); | |
534 return FALSE; | |
535 } | |
536 } | |
537 return TRUE; | |
538 } | |
539 | |
540 static int NaClGetNumDispBytes(NaClInstState* state) { | |
541 if (NaClInstRequiresModRm(state)) { | |
542 if (16 == state->address_size) { | |
543 /* Corresponding to table 2-1 of the Intel manual. */ | |
544 switch (modrm_mod(state->modrm)) { | |
545 case 0x0: | |
546 if (modrm_rm(state->modrm) == 0x06) { | |
547 return 4; /* disp16 */ | |
548 } | |
549 break; | |
550 case 0x1: | |
551 return 1; /* disp8 */ | |
552 case 0x2: | |
553 return 2; /* disp16 */ | |
554 default: | |
555 break; | |
556 } | |
557 } else { | |
558 /* Note: in 64-bit mode, 64-bit addressing is treated the same as 32-bit | |
559 * addressing. Hence, this section covers the 32-bit addressing. | |
560 */ | |
561 switch(modrm_mod(state->modrm)) { | |
562 case 0x0: | |
563 if (modrm_rm(state->modrm) == 0x05) { | |
564 return 4; /* disp32 */ | |
565 } else if (state->has_sib && sib_base(state->sib) == 0x5) { | |
566 return 4; | |
567 } | |
568 break; | |
569 case 0x1: | |
570 return 1; /* disp8 */ | |
571 case 0x2: | |
572 return 4; /* disp32 */ | |
573 default: | |
574 break; | |
575 } | |
576 } | |
577 } | |
578 return 0; | |
579 } | |
580 | |
581 /* Consume the needed displacement bytes, if applicable. Abort the | |
582 * pattern match if any problems are found. | |
583 */ | |
584 static Bool NaClConsumeDispBytes(NaClInstState* state) { | |
585 /* First check if the opcode (instruction) pattern specifies that | |
586 * displacement bytes should be read, and that reading it will not | |
587 * walk past the end of the code segment. | |
588 */ | |
589 state->num_disp_bytes = NaClGetNumDispBytes(state); | |
590 DEBUG(NaClLog(LOG_INFO, | |
591 "num disp bytes = %"NACL_PRIu8"\n", state->num_disp_bytes)); | |
592 state->first_disp_byte = state->bytes.length; | |
593 if (state->num_disp_bytes > 0) { | |
594 int new_length = state->bytes.length + state->num_disp_bytes; | |
595 if (new_length > state->length_limit) { | |
596 DEBUG(NaClLog(LOG_INFO, "Can't consume disp, no more bytes!\n")); | |
597 return FALSE; | |
598 } | |
599 /* Read the displacement bytes. */ | |
600 state->first_disp_byte = state->bytes.length; | |
601 NCInstBytesReadBytes(state->num_disp_bytes, &state->bytes); | |
602 } | |
603 return TRUE; | |
604 } | |
605 | |
606 /* Returns the number of immediate bytes to parse. */ | |
607 static int NaClGetNumImmedBytes(NaClInstState* state) { | |
608 if (state->inst->flags & NACL_IFLAG(OpcodeHasImmed)) { | |
609 return state->operand_size; | |
610 } | |
611 if (state->inst->flags & NACL_IFLAG(OpcodeHasImmed_v)) { | |
612 return 4; | |
613 } else if (state->inst->flags & NACL_IFLAG(OpcodeHasImmed_b)) { | |
614 return 1; | |
615 } else if (state->inst->flags & NACL_IFLAG(OpcodeHasImmed_w)) { | |
616 return 2; | |
617 } else if (state->inst->flags & NACL_IFLAG(OpcodeHasImmed_o)) { | |
618 return 8; | |
619 } else if (state->inst->flags & NACL_IFLAG(OpcodeHasImmed_Addr)) { | |
620 return NaClExtractAddressSize(state) / 8; | |
621 } else if (state->inst->flags & NACL_IFLAG(OpcodeHasImmed_z)) { | |
622 if (state->operand_size == 2) { | |
623 return 2; | |
624 } else { | |
625 return 4; | |
626 } | |
627 } else { | |
628 return 0; | |
629 } | |
630 } | |
631 | |
632 /* Returns the number of immedidate bytes to parse if a second immediate | |
633 * number appears in the instruction (zero if no second immediate value). | |
634 */ | |
635 static int NaClGetNumImmed2Bytes(NaClInstState* state) { | |
636 if (state->inst->flags & NACL_IFLAG(OpcodeHasImmed2_b)) { | |
637 return 1; | |
638 } else if (state->inst->flags & NACL_IFLAG(OpcodeHasImmed2_w)) { | |
639 return 2; | |
640 } else if (state->inst->flags & NACL_IFLAG(OpcodeHasImmed2_v)) { | |
641 return 4; | |
642 } else { | |
643 return 0; | |
644 } | |
645 } | |
646 | |
647 /* Consume the needed immediate bytes, if applicable. Abort the | |
648 * pattern match if any problems are found. | |
649 */ | |
650 static Bool NaClConsumeImmediateBytes(NaClInstState* state) { | |
651 /* find out how many immediate bytes are expected. */ | |
652 state->num_imm_bytes = NaClGetNumImmedBytes(state); | |
653 DEBUG(NaClLog(LOG_INFO, | |
654 "num immediate bytes = %"NACL_PRIu8"\n", state->num_imm_bytes)); | |
655 state->first_imm_byte = 0; | |
656 if (state->num_imm_bytes > 0) { | |
657 int new_length; | |
658 /* Before reading immediate bytes, be sure that we won't walk | |
659 * past the end of the code segment. | |
660 */ | |
661 new_length = state->bytes.length + state->num_imm_bytes; | |
662 if (new_length > state->length_limit) { | |
663 DEBUG(NaClLog(LOG_INFO, "Can't consume immediate, no more bytes!\n")); | |
664 return FALSE; | |
665 } | |
666 /* Read the immediate bytes. */ | |
667 state->first_imm_byte = state->bytes.length; | |
668 NCInstBytesReadBytes(state->num_imm_bytes, &state->bytes); | |
669 } | |
670 /* Before returning, see if second immediate value specified. */ | |
671 state->num_imm2_bytes = NaClGetNumImmed2Bytes(state); | |
672 DEBUG(NaClLog(LOG_INFO, "num immediate 2 bytes = %"NACL_PRIu8"\n", | |
673 state->num_imm2_bytes)); | |
674 if (state->num_imm2_bytes > 0) { | |
675 int new_length; | |
676 /* Before reading immediate bytes, be sure that we don't walk | |
677 * past the end of the code segment. | |
678 */ | |
679 new_length = state->bytes.length + state->num_imm2_bytes; | |
680 if (new_length > state->length_limit) { | |
681 DEBUG(NaClLog(LOG_INFO, "Can't consume 2nd immediate, no more bytes!\n")); | |
682 return FALSE; | |
683 } | |
684 /* Read the immediate bytes. */ | |
685 NCInstBytesReadBytes(state->num_imm2_bytes, &state->bytes); | |
686 } | |
687 return TRUE; | |
688 } | |
689 | |
690 /* Validate that any opcode (instruction) pattern prefix assumptions are | |
691 * met by prefix bits. If not, abort the pattern match. | |
692 */ | |
693 static Bool NaClValidatePrefixFlags(NaClInstState* state) { | |
694 /* Check lock prefix assumptions. */ | |
695 if (state->prefix_mask & kPrefixLOCK) { | |
696 if (state->inst->flags & NACL_IFLAG(OpcodeLockable)) { | |
697 /* Only allow if all destination operands are memory stores. */ | |
698 uint32_t i; | |
699 Bool has_lockable_dest = FALSE; | |
700 NaClExpVector* vector = NaClInstStateExpVector(state); | |
701 DEBUG(NaClLog(LOG_INFO, "checking if lock valid on:\n"); | |
702 NaClExpVectorPrint(NaClLogGetGio(), vector)); | |
703 for (i = 0; i < vector->number_expr_nodes; ++i) { | |
704 NaClExp* node = &vector->node[i]; | |
705 DEBUG(NaClLog(LOG_INFO, " checking node %d\n", i)); | |
706 if ((NACL_EMPTY_EFLAGS != (node->flags & NACL_EFLAG(ExprDest))) && | |
707 (node->kind == ExprMemOffset)) { | |
708 has_lockable_dest = TRUE; | |
709 break; | |
710 } | |
711 } | |
712 if (!has_lockable_dest) { | |
713 DEBUG(NaClLog(LOG_INFO, "Instruction doesn't allow lock prefix " | |
714 "on non-memory destination")); | |
715 return FALSE; | |
716 } | |
717 } else { | |
718 DEBUG(NaClLog(LOG_INFO, "Instruction doesn't allow lock prefix\n")); | |
719 return FALSE; | |
720 } | |
721 } | |
722 /* Check REX prefix assumptions. */ | |
723 if (NACL_TARGET_SUBARCH == 64 && | |
724 (state->prefix_mask & kPrefixREX)) { | |
725 if (state->inst->flags & | |
726 (NACL_IFLAG(OpcodeUsesRexW) | NACL_IFLAG(OpcodeHasRexR) | | |
727 NACL_IFLAG(OpcodeRex))) { | |
728 if (((state->inst->flags & NACL_IFLAG(OpcodeUsesRexW)) && | |
729 0 == (state->rexprefix & 0x8)) || | |
730 ((state->inst->flags & NACL_IFLAG(OpcodeHasRexR)) && | |
731 0 == (state->rexprefix & 0x4))) { | |
732 DEBUG(NaClLog(LOG_INFO, "can't match REX prefix requirement\n")); | |
733 return FALSE; | |
734 } | |
735 } | |
736 } | |
737 return TRUE; | |
738 } | |
739 | |
740 static void NaClClearInstState(NaClInstState* state, uint8_t opcode_length) { | |
741 if (state->bytes.length != opcode_length) { | |
742 NCInstBytesReset(&state->bytes); | |
743 NCInstBytesReadBytes(opcode_length, &state->bytes); | |
744 } | |
745 state->modrm = 0; | |
746 state->has_sib = FALSE; | |
747 state->sib = 0; | |
748 state->num_disp_bytes = 0; | |
749 state->first_disp_byte = 0; | |
750 state->num_imm_bytes = 0; | |
751 state->first_imm_byte = 0; | |
752 state->num_imm2_bytes = 0; | |
753 state->operand_size = 32; | |
754 state->address_size = 32; | |
755 state->nodes.is_defined = FALSE; | |
756 state->nodes.number_expr_nodes = 0; | |
757 } | |
758 | |
759 /* | |
760 * Given the opcode prefix descriptor, return the list of candidate opcodes to | |
761 * try and match against the byte stream in the given state. Before returning, | |
762 * this function automatically advances the opcode prefix descriptor to describe | |
763 * the next list to use if the returned list doesn't provide any matches. | |
764 * | |
765 * Parameters: | |
766 * state - The state of the instruction being decoded. | |
767 * desc - The description of how the opcode bytes have been matched. | |
768 * The value passed in is the currrent match, the value at exit is | |
769 * the value to be used the next time this function is called (to | |
770 * get the next set of possible instructions). | |
771 * opcode_length - The length (in bytes) of the opcode for the returned | |
772 * candidate opcodes. | |
773 */ | |
774 static const NaClInst* NaClGetNextInstCandidates( | |
775 NaClInstState* state, NaClInstPrefixDescriptor* desc, | |
776 uint8_t* opcode_length) { | |
777 const NaClInst* cand_insts; | |
778 if (desc->next_length_adjustment) { | |
779 (*opcode_length) += desc->next_length_adjustment; | |
780 desc->opcode_byte = state->bytes.byte[*opcode_length - 1]; | |
781 } | |
782 cand_insts = g_OpcodeTable[desc->matched_prefix][desc->opcode_byte]; | |
783 DEBUG(NaClLog(LOG_INFO, "Lookup candidates using [%s][%x]\n", | |
784 NaClInstPrefixName(desc->matched_prefix), desc->opcode_byte)); | |
785 switch (desc->matched_prefix) { | |
786 case Prefix660F: | |
787 desc->matched_prefix = Prefix0F; | |
788 break; | |
789 case Prefix660F38: | |
790 desc->matched_prefix = Prefix0F38; | |
791 break; | |
792 case Prefix660F3A: | |
793 desc->matched_prefix = Prefix0F3A; | |
794 break; | |
795 case PrefixD8: | |
796 case PrefixD9: | |
797 case PrefixDA: | |
798 case PrefixDB: | |
799 case PrefixDC: | |
800 case PrefixDD: | |
801 case PrefixDE: | |
802 case PrefixDF: | |
803 desc->matched_prefix = NoPrefix; | |
804 desc->next_length_adjustment = -1; | |
805 break; | |
806 default: | |
807 /* No more simplier prefices, give up search after current lookup. */ | |
808 desc->matched_prefix = NaClInstPrefixEnumSize; | |
809 break; | |
810 } | |
811 return cand_insts; | |
812 } | |
813 | |
814 static Bool NaClConsumeOpcodeSequence(NaClInstState* state) { | |
815 uint8_t next_byte; | |
816 const NaClInstNode* next; | |
817 uint8_t next_length = 0; | |
818 const NaClInst* matching_inst = NULL; | |
819 uint8_t matching_length = 0; | |
820 | |
821 /* Cut quick if first byte not applicable. */ | |
822 if (state->bytes.length + next_length >= state->length_limit) return FALSE; | |
823 next_byte = NCInstBytesPeek(&state->bytes, next_length); | |
824 next = g_OpcodeSeq + 0; | |
825 | |
826 /* Find maximal match in trie. */ | |
827 while (NULL != next) { | |
828 if (next_byte == next->matching_byte) { | |
829 DEBUG(NaClLog(LOG_INFO, | |
830 "NaClConsume opcode char: %"NACL_PRIx8"\n", next_byte)); | |
831 next_length++; | |
832 if (NULL != next->matching_inst) { | |
833 matching_inst = next->matching_inst; | |
834 matching_length = next_length; | |
835 } | |
836 if (next_length < state->length_limit) { | |
837 next_byte = NCInstBytesPeek(&state->bytes, next_length); | |
838 next = next->success; | |
839 } else { | |
840 break; | |
841 } | |
842 } else if (next->matching_byte < next_byte) { | |
843 next = next->fail; | |
844 } else { | |
845 break; | |
846 } | |
847 } | |
848 if (NULL == matching_inst) { | |
849 return FALSE; | |
850 } else { | |
851 /* TODO(karl) Make this more general. Currently assumes that no | |
852 * additional processing (other than opcode selection) is needed. | |
853 * This is currently safe only because all instructions modeled | |
854 * using opcode sequences have no (useful) operands, and hence | |
855 * no additional information is needed. | |
856 */ | |
857 state->inst = matching_inst; | |
858 NCInstBytesReadBytes(matching_length, &state->bytes); | |
859 DEBUG(NaClLog(LOG_INFO, "matched inst sequence [%d]!\n", matching_length)); | |
860 return TRUE; | |
861 } | |
862 } | |
863 | 23 |
864 /* Given the current location of the (relative) pc of the given instruction | 24 /* Given the current location of the (relative) pc of the given instruction |
865 * iterator, update the given state to hold the (found) matched opcode | 25 * iterator, update the given state to hold the (found) matched opcode |
866 * (instruction) pattern. If no matching pattern exists, set the state | 26 * (instruction) pattern. If no matching pattern exists, set the state |
867 * to a matched undefined opcode (instruction) pattern. In all cases, | 27 * to a matched undefined opcode (instruction) pattern. In all cases, |
868 * update the state to hold all information on the matched bytes of the | 28 * update the state to hold all information on the matched bytes of the |
869 * instruction. Note: The iterator expects that the opcode field is | 29 * instruction. Note: The iterator expects that the opcode field is |
870 * changed from NULL to non-NULL by this fuction. | 30 * changed from NULL to non-NULL by this fuction. |
871 */ | 31 */ |
872 void NaClDecodeInst(NaClInstIter* iter, NaClInstState* state) { | 32 void NaClDecodeInst(NaClInstIter* iter, NaClInstState* state) { |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1002 void NaClChangeOpcodesToXedsModel() { | 162 void NaClChangeOpcodesToXedsModel() { |
1003 /* Changes opcodes to match xed. That is change: | 163 /* Changes opcodes to match xed. That is change: |
1004 * 0f0f..1c: Pf2iw $Pq, $Qq => 0f0f..2c: Pf2iw $Pq, $Qq | 164 * 0f0f..1c: Pf2iw $Pq, $Qq => 0f0f..2c: Pf2iw $Pq, $Qq |
1005 * 0f0f..1d: Pf2id $Pq, $Qq => 0f0f..2d: Pf2id $Pq, $Qq | 165 * 0f0f..1d: Pf2id $Pq, $Qq => 0f0f..2d: Pf2id $Pq, $Qq |
1006 */ | 166 */ |
1007 g_OpcodeTable[Prefix0F0F][0x2c] = g_OpcodeTable[Prefix0F0F][0x1c]; | 167 g_OpcodeTable[Prefix0F0F][0x2c] = g_OpcodeTable[Prefix0F0F][0x1c]; |
1008 g_OpcodeTable[Prefix0F0F][0x1c] = NULL; | 168 g_OpcodeTable[Prefix0F0F][0x1c] = NULL; |
1009 g_OpcodeTable[Prefix0F0F][0x2d] = g_OpcodeTable[Prefix0F0F][0x1d]; | 169 g_OpcodeTable[Prefix0F0F][0x2d] = g_OpcodeTable[Prefix0F0F][0x1d]; |
1010 g_OpcodeTable[Prefix0F0F][0x1d] = NULL; | 170 g_OpcodeTable[Prefix0F0F][0x1d] = NULL; |
1011 } | 171 } |
OLD | NEW |