1 /*===-- X86DisassemblerDecoder.c - Disassembler decoder ------------*- C -*-===*
2 *
3 * The LLVM Compiler Infrastructure
4 *
5 * This file is distributed under the University of Illinois Open Source
6 * License. See LICENSE.TXT for details.
7 *
8 *===----------------------------------------------------------------------===*
9 *
10 * This file is part of the X86 Disassembler.
11 * It contains the implementation of the instruction decoder.
12 * Documentation for the disassembler can be found in X86Disassembler.h.
13 *
14 *===----------------------------------------------------------------------===*/
15
16 /* Capstone Disassembly Engine */
17 /* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2015 */
18
19 #ifdef CAPSTONE_HAS_X86
20
21 #include <stdarg.h> /* for va_*() */
22 #if defined(CAPSTONE_HAS_OSXKERNEL)
23 #include <libkern/libkern.h>
24 #else
25 #include <stdlib.h> /* for exit() */
26 #endif
27
28 #include "../../cs_priv.h"
29 #include "../../utils.h"
30
31 #include "X86DisassemblerDecoder.h"
32
33 /// Specifies whether a ModR/M byte is needed and (if so) which
34 /// instruction each possible value of the ModR/M byte corresponds to. Once
35 /// this information is known, we have narrowed down to a single instruction.
36 struct ModRMDecision {
37 uint8_t modrm_type;
38 uint16_t instructionIDs;
39 };
40
41 /// Specifies which set of ModR/M->instruction tables to look at
42 /// given a particular opcode.
43 struct OpcodeDecision {
44 struct ModRMDecision modRMDecisions[256];
45 };
46
47 /// Specifies which opcode->instruction tables to look at given
48 /// a particular context (set of attributes). Since there are many possible
49 /// contexts, the decoder first uses CONTEXTS_SYM to determine which context
50 /// applies given a specific set of attributes. Hence there are only IC_max
51 /// entries in this table, rather than 2^(ATTR_max).
52 struct ContextDecision {
53 struct OpcodeDecision opcodeDecisions[IC_max];
54 };
55
56 #ifdef CAPSTONE_X86_REDUCE
57 #include "X86GenDisassemblerTables_reduce.inc"
58 #else
59 #include "X86GenDisassemblerTables.inc"
60 #endif
61
62 //#define GET_INSTRINFO_ENUM
63 #define GET_INSTRINFO_MC_DESC
64 #ifdef CAPSTONE_X86_REDUCE
65 #include "X86GenInstrInfo_reduce.inc"
66 #else
67 #include "X86GenInstrInfo.inc"
68 #endif
69
70 /*
71 * contextForAttrs - Client for the instruction context table. Takes a set of
72 * attributes and returns the appropriate decode context.
73 *
74 * @param attrMask - Attributes, from the enumeration attributeBits.
75 * @return - The InstructionContext to use when looking up an
76 * an instruction with these attributes.
77 */
contextForAttrs(uint16_t attrMask)78 static InstructionContext contextForAttrs(uint16_t attrMask)
79 {
80 return CONTEXTS_SYM[attrMask];
81 }
82
83 /*
84 * modRMRequired - Reads the appropriate instruction table to determine whether
85 * the ModR/M byte is required to decode a particular instruction.
86 *
87 * @param type - The opcode type (i.e., how many bytes it has).
88 * @param insnContext - The context for the instruction, as returned by
89 * contextForAttrs.
90 * @param opcode - The last byte of the instruction's opcode, not counting
91 * ModR/M extensions and escapes.
92 * @return - true if the ModR/M byte is required, false otherwise.
93 */
modRMRequired(OpcodeType type,InstructionContext insnContext,uint16_t opcode)94 static int modRMRequired(OpcodeType type,
95 InstructionContext insnContext,
96 uint16_t opcode)
97 {
98 const struct OpcodeDecision *decision = NULL;
99 const uint8_t *indextable = NULL;
100 uint8_t index;
101
102 switch (type) {
103 default:
104 case ONEBYTE:
105 decision = ONEBYTE_SYM;
106 indextable = index_x86DisassemblerOneByteOpcodes;
107 break;
108 case TWOBYTE:
109 decision = TWOBYTE_SYM;
110 indextable = index_x86DisassemblerTwoByteOpcodes;
111 break;
112 case THREEBYTE_38:
113 decision = THREEBYTE38_SYM;
114 indextable = index_x86DisassemblerThreeByte38Opcodes;
115 break;
116 case THREEBYTE_3A:
117 decision = THREEBYTE3A_SYM;
118 indextable = index_x86DisassemblerThreeByte3AOpcodes;
119 break;
120 #ifndef CAPSTONE_X86_REDUCE
121 case XOP8_MAP:
122 decision = XOP8_MAP_SYM;
123 indextable = index_x86DisassemblerXOP8Opcodes;
124 break;
125 case XOP9_MAP:
126 decision = XOP9_MAP_SYM;
127 indextable = index_x86DisassemblerXOP9Opcodes;
128 break;
129 case XOPA_MAP:
130 decision = XOPA_MAP_SYM;
131 indextable = index_x86DisassemblerXOPAOpcodes;
132 break;
133 case T3DNOW_MAP:
134 // 3DNow instructions always have ModRM byte
135 return true;
136 #endif
137 }
138
139 index = indextable[insnContext];
140 if (index)
141 return decision[index - 1].modRMDecisions[opcode].modrm_type != MODRM_ONEENTRY;
142 else
143 return false;
144 }
145
146 /*
147 * decode - Reads the appropriate instruction table to obtain the unique ID of
148 * an instruction.
149 *
150 * @param type - See modRMRequired().
151 * @param insnContext - See modRMRequired().
152 * @param opcode - See modRMRequired().
153 * @param modRM - The ModR/M byte if required, or any value if not.
154 * @return - The UID of the instruction, or 0 on failure.
155 */
decode(OpcodeType type,InstructionContext insnContext,uint8_t opcode,uint8_t modRM)156 static InstrUID decode(OpcodeType type,
157 InstructionContext insnContext,
158 uint8_t opcode,
159 uint8_t modRM)
160 {
161 const struct ModRMDecision *dec = NULL;
162 const uint8_t *indextable = NULL;
163 uint8_t index;
164
165 switch (type) {
166 default:
167 case ONEBYTE:
168 indextable = index_x86DisassemblerOneByteOpcodes;
169 index = indextable[insnContext];
170 if (index)
171 dec = &ONEBYTE_SYM[index - 1].modRMDecisions[opcode];
172 else
173 dec = &emptyTable.modRMDecisions[opcode];
174 break;
175 case TWOBYTE:
176 indextable = index_x86DisassemblerTwoByteOpcodes;
177 index = indextable[insnContext];
178 if (index)
179 dec = &TWOBYTE_SYM[index - 1].modRMDecisions[opcode];
180 else
181 dec = &emptyTable.modRMDecisions[opcode];
182 break;
183 case THREEBYTE_38:
184 indextable = index_x86DisassemblerThreeByte38Opcodes;
185 index = indextable[insnContext];
186 if (index)
187 dec = &THREEBYTE38_SYM[index - 1].modRMDecisions[opcode];
188 else
189 dec = &emptyTable.modRMDecisions[opcode];
190 break;
191 case THREEBYTE_3A:
192 indextable = index_x86DisassemblerThreeByte3AOpcodes;
193 index = indextable[insnContext];
194 if (index)
195 dec = &THREEBYTE3A_SYM[index - 1].modRMDecisions[opcode];
196 else
197 dec = &emptyTable.modRMDecisions[opcode];
198 break;
199 #ifndef CAPSTONE_X86_REDUCE
200 case XOP8_MAP:
201 indextable = index_x86DisassemblerXOP8Opcodes;
202 index = indextable[insnContext];
203 if (index)
204 dec = &XOP8_MAP_SYM[index - 1].modRMDecisions[opcode];
205 else
206 dec = &emptyTable.modRMDecisions[opcode];
207 break;
208 case XOP9_MAP:
209 indextable = index_x86DisassemblerXOP9Opcodes;
210 index = indextable[insnContext];
211 if (index)
212 dec = &XOP9_MAP_SYM[index - 1].modRMDecisions[opcode];
213 else
214 dec = &emptyTable.modRMDecisions[opcode];
215 break;
216 case XOPA_MAP:
217 indextable = index_x86DisassemblerXOPAOpcodes;
218 index = indextable[insnContext];
219 if (index)
220 dec = &XOPA_MAP_SYM[index - 1].modRMDecisions[opcode];
221 else
222 dec = &emptyTable.modRMDecisions[opcode];
223 break;
224 case T3DNOW_MAP:
225 indextable = index_x86DisassemblerT3DNOWOpcodes;
226 index = indextable[insnContext];
227 if (index)
228 dec = &T3DNOW_MAP_SYM[index - 1].modRMDecisions[opcode];
229 else
230 dec = &emptyTable.modRMDecisions[opcode];
231 break;
232 #endif
233 }
234
235 switch (dec->modrm_type) {
236 default:
237 //debug("Corrupt table! Unknown modrm_type");
238 return 0;
239 case MODRM_ONEENTRY:
240 return modRMTable[dec->instructionIDs];
241 case MODRM_SPLITRM:
242 if (modFromModRM(modRM) == 0x3)
243 return modRMTable[dec->instructionIDs+1];
244 return modRMTable[dec->instructionIDs];
245 case MODRM_SPLITREG:
246 if (modFromModRM(modRM) == 0x3)
247 return modRMTable[dec->instructionIDs+((modRM & 0x38) >> 3)+8];
248 return modRMTable[dec->instructionIDs+((modRM & 0x38) >> 3)];
249 case MODRM_SPLITMISC:
250 if (modFromModRM(modRM) == 0x3)
251 return modRMTable[dec->instructionIDs+(modRM & 0x3f)+8];
252 return modRMTable[dec->instructionIDs+((modRM & 0x38) >> 3)];
253 case MODRM_FULL:
254 return modRMTable[dec->instructionIDs+modRM];
255 }
256 }
257
258 /*
259 * specifierForUID - Given a UID, returns the name and operand specification for
260 * that instruction.
261 *
262 * @param uid - The unique ID for the instruction. This should be returned by
263 * decode(); specifierForUID will not check bounds.
264 * @return - A pointer to the specification for that instruction.
265 */
specifierForUID(InstrUID uid)266 static const struct InstructionSpecifier *specifierForUID(InstrUID uid)
267 {
268 return &INSTRUCTIONS_SYM[uid];
269 }
270
271 /*
272 * consumeByte - Uses the reader function provided by the user to consume one
273 * byte from the instruction's memory and advance the cursor.
274 *
275 * @param insn - The instruction with the reader function to use. The cursor
276 * for this instruction is advanced.
277 * @param byte - A pointer to a pre-allocated memory buffer to be populated
278 * with the data read.
279 * @return - 0 if the read was successful; nonzero otherwise.
280 */
consumeByte(struct InternalInstruction * insn,uint8_t * byte)281 static int consumeByte(struct InternalInstruction *insn, uint8_t *byte)
282 {
283 int ret = insn->reader(insn->readerArg, byte, insn->readerCursor);
284
285 if (!ret)
286 ++(insn->readerCursor);
287
288 return ret;
289 }
290
291 /*
292 * lookAtByte - Like consumeByte, but does not advance the cursor.
293 *
294 * @param insn - See consumeByte().
295 * @param byte - See consumeByte().
296 * @return - See consumeByte().
297 */
lookAtByte(struct InternalInstruction * insn,uint8_t * byte)298 static int lookAtByte(struct InternalInstruction *insn, uint8_t *byte)
299 {
300 return insn->reader(insn->readerArg, byte, insn->readerCursor);
301 }
302
unconsumeByte(struct InternalInstruction * insn)303 static void unconsumeByte(struct InternalInstruction *insn)
304 {
305 insn->readerCursor--;
306 }
307
308 #define CONSUME_FUNC(name, type) \
309 static int name(struct InternalInstruction *insn, type *ptr) { \
310 type combined = 0; \
311 unsigned offset; \
312 for (offset = 0; offset < sizeof(type); ++offset) { \
313 uint8_t byte; \
314 int ret = insn->reader(insn->readerArg, \
315 &byte, \
316 insn->readerCursor + offset); \
317 if (ret) \
318 return ret; \
319 combined = combined | (type)((uint64_t)byte << (offset * 8)); \
320 } \
321 *ptr = combined; \
322 insn->readerCursor += sizeof(type); \
323 return 0; \
324 }
325
326 /*
327 * consume* - Use the reader function provided by the user to consume data
328 * values of various sizes from the instruction's memory and advance the
329 * cursor appropriately. These readers perform endian conversion.
330 *
331 * @param insn - See consumeByte().
332 * @param ptr - A pointer to a pre-allocated memory of appropriate size to
333 * be populated with the data read.
334 * @return - See consumeByte().
335 */
CONSUME_FUNC(consumeInt8,int8_t)336 CONSUME_FUNC(consumeInt8, int8_t)
337 CONSUME_FUNC(consumeInt16, int16_t)
338 CONSUME_FUNC(consumeInt32, int32_t)
339 CONSUME_FUNC(consumeUInt16, uint16_t)
340 CONSUME_FUNC(consumeUInt32, uint32_t)
341 CONSUME_FUNC(consumeUInt64, uint64_t)
342
343 /*
344 * setPrefixPresent - Marks that a particular prefix is present at a particular
345 * location.
346 *
347 * @param insn - The instruction to be marked as having the prefix.
348 * @param prefix - The prefix that is present.
349 * @param location - The location where the prefix is located (in the address
350 * space of the instruction's reader).
351 */
352 static void setPrefixPresent(struct InternalInstruction *insn, uint8_t prefix, uint64_t location)
353 {
354 switch (prefix) {
355 case 0x26:
356 insn->isPrefix26 = true;
357 insn->prefix26 = location;
358 break;
359 case 0x2e:
360 insn->isPrefix2e = true;
361 insn->prefix2e = location;
362 break;
363 case 0x36:
364 insn->isPrefix36 = true;
365 insn->prefix36 = location;
366 break;
367 case 0x3e:
368 insn->isPrefix3e = true;
369 insn->prefix3e = location;
370 break;
371 case 0x64:
372 insn->isPrefix64 = true;
373 insn->prefix64 = location;
374 break;
375 case 0x65:
376 insn->isPrefix65 = true;
377 insn->prefix65 = location;
378 break;
379 case 0x66:
380 insn->isPrefix66 = true;
381 insn->prefix66 = location;
382 break;
383 case 0x67:
384 insn->isPrefix67 = true;
385 insn->prefix67 = location;
386 break;
387 case 0xf0:
388 insn->isPrefixf0 = true;
389 insn->prefixf0 = location;
390 break;
391 case 0xf2:
392 insn->isPrefixf2 = true;
393 insn->prefixf2 = location;
394 break;
395 case 0xf3:
396 insn->isPrefixf3 = true;
397 insn->prefixf3 = location;
398 break;
399 default:
400 break;
401 }
402 }
403
404 /*
405 * isPrefixAtLocation - Queries an instruction to determine whether a prefix is
406 * present at a given location.
407 *
408 * @param insn - The instruction to be queried.
409 * @param prefix - The prefix.
410 * @param location - The location to query.
411 * @return - Whether the prefix is at that location.
412 */
isPrefixAtLocation(struct InternalInstruction * insn,uint8_t prefix,uint64_t location)413 static bool isPrefixAtLocation(struct InternalInstruction *insn, uint8_t prefix,
414 uint64_t location)
415 {
416 switch (prefix) {
417 case 0x26:
418 if (insn->isPrefix26 && insn->prefix26 == location)
419 return true;
420 break;
421 case 0x2e:
422 if (insn->isPrefix2e && insn->prefix2e == location)
423 return true;
424 break;
425 case 0x36:
426 if (insn->isPrefix36 && insn->prefix36 == location)
427 return true;
428 break;
429 case 0x3e:
430 if (insn->isPrefix3e && insn->prefix3e == location)
431 return true;
432 break;
433 case 0x64:
434 if (insn->isPrefix64 && insn->prefix64 == location)
435 return true;
436 break;
437 case 0x65:
438 if (insn->isPrefix65 && insn->prefix65 == location)
439 return true;
440 break;
441 case 0x66:
442 if (insn->isPrefix66 && insn->prefix66 == location)
443 return true;
444 break;
445 case 0x67:
446 if (insn->isPrefix67 && insn->prefix67 == location)
447 return true;
448 break;
449 case 0xf0:
450 if (insn->isPrefixf0 && insn->prefixf0 == location)
451 return true;
452 break;
453 case 0xf2:
454 if (insn->isPrefixf2 && insn->prefixf2 == location)
455 return true;
456 break;
457 case 0xf3:
458 if (insn->isPrefixf3 && insn->prefixf3 == location)
459 return true;
460 break;
461 default:
462 break;
463 }
464 return false;
465 }
466
467 /*
468 * readPrefixes - Consumes all of an instruction's prefix bytes, and marks the
469 * instruction as having them. Also sets the instruction's default operand,
470 * address, and other relevant data sizes to report operands correctly.
471 *
472 * @param insn - The instruction whose prefixes are to be read.
473 * @return - 0 if the instruction could be read until the end of the prefix
474 * bytes, and no prefixes conflicted; nonzero otherwise.
475 */
readPrefixes(struct InternalInstruction * insn)476 static int readPrefixes(struct InternalInstruction *insn)
477 {
478 bool isPrefix = true;
479 uint64_t prefixLocation;
480 uint8_t byte = 0, nextByte;
481
482 bool hasAdSize = false;
483 bool hasOpSize = false;
484
485 //initialize to an impossible value
486 insn->necessaryPrefixLocation = insn->readerCursor - 1;
487 while (isPrefix) {
488 if (insn->mode == MODE_64BIT) {
489 // eliminate consecutive redundant REX bytes in front
490 if (consumeByte(insn, &byte))
491 return -1;
492
493 if ((byte & 0xf0) == 0x40) {
494 while(true) {
495 if (lookAtByte(insn, &byte)) // out of input code
496 return -1;
497 if ((byte & 0xf0) == 0x40) {
498 // another REX prefix, but we only remember the last one
499 if (consumeByte(insn, &byte))
500 return -1;
501 } else
502 break;
503 }
504
505 // recover the last REX byte if next byte is not a legacy prefix
506 switch (byte) {
507 case 0xf2: /* REPNE/REPNZ */
508 case 0xf3: /* REP or REPE/REPZ */
509 case 0xf0: /* LOCK */
510 case 0x2e: /* CS segment override -OR- Branch not taken */
511 case 0x36: /* SS segment override -OR- Branch taken */
512 case 0x3e: /* DS segment override */
513 case 0x26: /* ES segment override */
514 case 0x64: /* FS segment override */
515 case 0x65: /* GS segment override */
516 case 0x66: /* Operand-size override */
517 case 0x67: /* Address-size override */
518 break;
519 default: /* Not a prefix byte */
520 unconsumeByte(insn);
521 break;
522 }
523 } else {
524 unconsumeByte(insn);
525 }
526 }
527
528 prefixLocation = insn->readerCursor;
529
530 /* If we fail reading prefixes, just stop here and let the opcode reader deal with it */
531 if (consumeByte(insn, &byte))
532 return -1;
533
534 if (insn->readerCursor - 1 == insn->startLocation
535 && (byte == 0xf2 || byte == 0xf3)) {
536
537 if (lookAtByte(insn, &nextByte))
538 return -1;
539
540 /*
541 * If the byte is 0xf2 or 0xf3, and any of the following conditions are
542 * met:
543 * - it is followed by a LOCK (0xf0) prefix
544 * - it is followed by an xchg instruction
545 * then it should be disassembled as a xacquire/xrelease not repne/rep.
546 */
547 if (((nextByte == 0xf0) ||
548 ((nextByte & 0xfe) == 0x86 || (nextByte & 0xf8) == 0x90)))
549 insn->xAcquireRelease = true;
550 /*
551 * Also if the byte is 0xf3, and the following condition is met:
552 * - it is followed by a "mov mem, reg" (opcode 0x88/0x89) or
553 * "mov mem, imm" (opcode 0xc6/0xc7) instructions.
554 * then it should be disassembled as an xrelease not rep.
555 */
556 if (byte == 0xf3 &&
557 (nextByte == 0x88 || nextByte == 0x89 ||
558 nextByte == 0xc6 || nextByte == 0xc7))
559 insn->xAcquireRelease = true;
560
561 if (insn->mode == MODE_64BIT && (nextByte & 0xf0) == 0x40) {
562 if (consumeByte(insn, &nextByte))
563 return -1;
564 if (lookAtByte(insn, &nextByte))
565 return -1;
566 unconsumeByte(insn);
567 }
568 }
569
570 switch (byte) {
571 case 0xf2: /* REPNE/REPNZ */
572 case 0xf3: /* REP or REPE/REPZ */
573 case 0xf0: /* LOCK */
574 // only accept the last prefix
575 insn->isPrefixf2 = false;
576 insn->isPrefixf3 = false;
577 insn->isPrefixf0 = false;
578 setPrefixPresent(insn, byte, prefixLocation);
579 insn->prefix0 = byte;
580 break;
581 case 0x2e: /* CS segment override -OR- Branch not taken */
582 insn->segmentOverride = SEG_OVERRIDE_CS;
583 // only accept the last prefix
584 insn->isPrefix2e = false;
585 insn->isPrefix36 = false;
586 insn->isPrefix3e = false;
587 insn->isPrefix26 = false;
588 insn->isPrefix64 = false;
589 insn->isPrefix65 = false;
590
591 setPrefixPresent(insn, byte, prefixLocation);
592 insn->prefix1 = byte;
593 break;
594 case 0x36: /* SS segment override -OR- Branch taken */
595 insn->segmentOverride = SEG_OVERRIDE_SS;
596 // only accept the last prefix
597 insn->isPrefix2e = false;
598 insn->isPrefix36 = false;
599 insn->isPrefix3e = false;
600 insn->isPrefix26 = false;
601 insn->isPrefix64 = false;
602 insn->isPrefix65 = false;
603
604 setPrefixPresent(insn, byte, prefixLocation);
605 insn->prefix1 = byte;
606 break;
607 case 0x3e: /* DS segment override */
608 insn->segmentOverride = SEG_OVERRIDE_DS;
609 // only accept the last prefix
610 insn->isPrefix2e = false;
611 insn->isPrefix36 = false;
612 insn->isPrefix3e = false;
613 insn->isPrefix26 = false;
614 insn->isPrefix64 = false;
615 insn->isPrefix65 = false;
616
617 setPrefixPresent(insn, byte, prefixLocation);
618 insn->prefix1 = byte;
619 break;
620 case 0x26: /* ES segment override */
621 insn->segmentOverride = SEG_OVERRIDE_ES;
622 // only accept the last prefix
623 insn->isPrefix2e = false;
624 insn->isPrefix36 = false;
625 insn->isPrefix3e = false;
626 insn->isPrefix26 = false;
627 insn->isPrefix64 = false;
628 insn->isPrefix65 = false;
629
630 setPrefixPresent(insn, byte, prefixLocation);
631 insn->prefix1 = byte;
632 break;
633 case 0x64: /* FS segment override */
634 insn->segmentOverride = SEG_OVERRIDE_FS;
635 // only accept the last prefix
636 insn->isPrefix2e = false;
637 insn->isPrefix36 = false;
638 insn->isPrefix3e = false;
639 insn->isPrefix26 = false;
640 insn->isPrefix64 = false;
641 insn->isPrefix65 = false;
642
643 setPrefixPresent(insn, byte, prefixLocation);
644 insn->prefix1 = byte;
645 break;
646 case 0x65: /* GS segment override */
647 insn->segmentOverride = SEG_OVERRIDE_GS;
648 // only accept the last prefix
649 insn->isPrefix2e = false;
650 insn->isPrefix36 = false;
651 insn->isPrefix3e = false;
652 insn->isPrefix26 = false;
653 insn->isPrefix64 = false;
654 insn->isPrefix65 = false;
655
656 setPrefixPresent(insn, byte, prefixLocation);
657 insn->prefix1 = byte;
658 break;
659 case 0x66: /* Operand-size override */
660 hasOpSize = true;
661 setPrefixPresent(insn, byte, prefixLocation);
662 insn->prefix2 = byte;
663 break;
664 case 0x67: /* Address-size override */
665 hasAdSize = true;
666 setPrefixPresent(insn, byte, prefixLocation);
667 insn->prefix3 = byte;
668 break;
669 default: /* Not a prefix byte */
670 isPrefix = false;
671 break;
672 }
673
674 //if (isPrefix)
675 // dbgprintf(insn, "Found prefix 0x%hhx", byte);
676 }
677
678 insn->vectorExtensionType = TYPE_NO_VEX_XOP;
679
680
681 if (byte == 0x62) {
682 uint8_t byte1, byte2;
683
684 if (consumeByte(insn, &byte1)) {
685 //dbgprintf(insn, "Couldn't read second byte of EVEX prefix");
686 return -1;
687 }
688
689 if ((insn->mode == MODE_64BIT || (byte1 & 0xc0) == 0xc0) &&
690 ((~byte1 & 0xc) == 0xc)) {
691 if (lookAtByte(insn, &byte2)) {
692 //dbgprintf(insn, "Couldn't read third byte of EVEX prefix");
693 return -1;
694 }
695
696 if ((byte2 & 0x4) == 0x4) {
697 insn->vectorExtensionType = TYPE_EVEX;
698 } else {
699 unconsumeByte(insn); /* unconsume byte1 */
700 unconsumeByte(insn); /* unconsume byte */
701 insn->necessaryPrefixLocation = insn->readerCursor - 2;
702 }
703
704 if (insn->vectorExtensionType == TYPE_EVEX) {
705 insn->vectorExtensionPrefix[0] = byte;
706 insn->vectorExtensionPrefix[1] = byte1;
707
708 if (consumeByte(insn, &insn->vectorExtensionPrefix[2])) {
709 //dbgprintf(insn, "Couldn't read third byte of EVEX prefix");
710 return -1;
711 }
712
713 if (consumeByte(insn, &insn->vectorExtensionPrefix[3])) {
714 //dbgprintf(insn, "Couldn't read fourth byte of EVEX prefix");
715 return -1;
716 }
717
718 /* We simulate the REX prefix for simplicity's sake */
719 if (insn->mode == MODE_64BIT) {
720 insn->rexPrefix = 0x40
721 | (wFromEVEX3of4(insn->vectorExtensionPrefix[2]) << 3)
722 | (rFromEVEX2of4(insn->vectorExtensionPrefix[1]) << 2)
723 | (xFromEVEX2of4(insn->vectorExtensionPrefix[1]) << 1)
724 | (bFromEVEX2of4(insn->vectorExtensionPrefix[1]) << 0);
725 }
726 switch (ppFromEVEX3of4(insn->vectorExtensionPrefix[2])) {
727 default:
728 break;
729 case VEX_PREFIX_66:
730 hasOpSize = true;
731 break;
732 }
733 //dbgprintf(insn, "Found EVEX prefix 0x%hhx 0x%hhx 0x%hhx 0x%hhx",
734 // insn->vectorExtensionPrefix[0], insn->vectorExtensionPrefix[1],
735 // insn->vectorExtensionPrefix[2], insn->vectorExtensionPrefix[3]);
736 }
737 } else {
738 // BOUND instruction
739 unconsumeByte(insn); /* unconsume byte1 */
740 unconsumeByte(insn); /* unconsume byte */
741 }
742 } else if (byte == 0xc4) {
743 uint8_t byte1;
744
745 if (lookAtByte(insn, &byte1)) {
746 //dbgprintf(insn, "Couldn't read second byte of VEX");
747 return -1;
748 }
749
750 if (insn->mode == MODE_64BIT || (byte1 & 0xc0) == 0xc0) {
751 insn->vectorExtensionType = TYPE_VEX_3B;
752 insn->necessaryPrefixLocation = insn->readerCursor - 1;
753 } else {
754 unconsumeByte(insn);
755 insn->necessaryPrefixLocation = insn->readerCursor - 1;
756 }
757
758 if (insn->vectorExtensionType == TYPE_VEX_3B) {
759 insn->vectorExtensionPrefix[0] = byte;
760 if (consumeByte(insn, &insn->vectorExtensionPrefix[1]))
761 return -1;
762 if (consumeByte(insn, &insn->vectorExtensionPrefix[2]))
763 return -1;
764
765 /* We simulate the REX prefix for simplicity's sake */
766 if (insn->mode == MODE_64BIT) {
767 insn->rexPrefix = 0x40
768 | (wFromVEX3of3(insn->vectorExtensionPrefix[2]) << 3)
769 | (rFromVEX2of3(insn->vectorExtensionPrefix[1]) << 2)
770 | (xFromVEX2of3(insn->vectorExtensionPrefix[1]) << 1)
771 | (bFromVEX2of3(insn->vectorExtensionPrefix[1]) << 0);
772
773 }
774 switch (ppFromVEX3of3(insn->vectorExtensionPrefix[2])) {
775 default:
776 break;
777 case VEX_PREFIX_66:
778 hasOpSize = true;
779 break;
780 }
781 }
782 } else if (byte == 0xc5) {
783 uint8_t byte1;
784
785 if (lookAtByte(insn, &byte1)) {
786 //dbgprintf(insn, "Couldn't read second byte of VEX");
787 return -1;
788 }
789
790 if (insn->mode == MODE_64BIT || (byte1 & 0xc0) == 0xc0) {
791 insn->vectorExtensionType = TYPE_VEX_2B;
792 } else {
793 unconsumeByte(insn);
794 }
795
796 if (insn->vectorExtensionType == TYPE_VEX_2B) {
797 insn->vectorExtensionPrefix[0] = byte;
798 if (consumeByte(insn, &insn->vectorExtensionPrefix[1]))
799 return -1;
800
801 if (insn->mode == MODE_64BIT) {
802 insn->rexPrefix = 0x40
803 | (rFromVEX2of2(insn->vectorExtensionPrefix[1]) << 2);
804 }
805
806 switch (ppFromVEX2of2(insn->vectorExtensionPrefix[1])) {
807 default:
808 break;
809 case VEX_PREFIX_66:
810 hasOpSize = true;
811 break;
812 }
813 }
814 } else if (byte == 0x8f) {
815 uint8_t byte1;
816
817 if (lookAtByte(insn, &byte1)) {
818 // dbgprintf(insn, "Couldn't read second byte of XOP");
819 return -1;
820 }
821
822 if ((byte1 & 0x38) != 0x0) { /* 0 in these 3 bits is a POP instruction. */
823 insn->vectorExtensionType = TYPE_XOP;
824 insn->necessaryPrefixLocation = insn->readerCursor - 1;
825 } else {
826 unconsumeByte(insn);
827 insn->necessaryPrefixLocation = insn->readerCursor - 1;
828 }
829
830 if (insn->vectorExtensionType == TYPE_XOP) {
831 insn->vectorExtensionPrefix[0] = byte;
832 if (consumeByte(insn, &insn->vectorExtensionPrefix[1]))
833 return -1;
834 if (consumeByte(insn, &insn->vectorExtensionPrefix[2]))
835 return -1;
836
837 /* We simulate the REX prefix for simplicity's sake */
838 if (insn->mode == MODE_64BIT) {
839 insn->rexPrefix = 0x40
840 | (wFromXOP3of3(insn->vectorExtensionPrefix[2]) << 3)
841 | (rFromXOP2of3(insn->vectorExtensionPrefix[1]) << 2)
842 | (xFromXOP2of3(insn->vectorExtensionPrefix[1]) << 1)
843 | (bFromXOP2of3(insn->vectorExtensionPrefix[1]) << 0);
844 }
845
846 switch (ppFromXOP3of3(insn->vectorExtensionPrefix[2])) {
847 default:
848 break;
849 case VEX_PREFIX_66:
850 hasOpSize = true;
851 break;
852 }
853 }
854 } else {
855 if (insn->mode == MODE_64BIT) {
856 if ((byte & 0xf0) == 0x40) {
857 uint8_t opcodeByte;
858
859 while(true) {
860 if (lookAtByte(insn, &opcodeByte)) // out of input code
861 return -1;
862 if ((opcodeByte & 0xf0) == 0x40) {
863 // another REX prefix, but we only remember the last one
864 if (consumeByte(insn, &byte))
865 return -1;
866 } else
867 break;
868 }
869
870 insn->rexPrefix = byte;
871 insn->necessaryPrefixLocation = insn->readerCursor - 2;
872 // dbgprintf(insn, "Found REX prefix 0x%hhx", byte);
873 } else {
874 unconsumeByte(insn);
875 insn->necessaryPrefixLocation = insn->readerCursor - 1;
876 }
877 } else {
878 unconsumeByte(insn);
879 insn->necessaryPrefixLocation = insn->readerCursor - 1;
880 }
881 }
882
883 if (insn->mode == MODE_16BIT) {
884 insn->registerSize = (hasOpSize ? 4 : 2);
885 insn->addressSize = (hasAdSize ? 4 : 2);
886 insn->displacementSize = (hasAdSize ? 4 : 2);
887 insn->immediateSize = (hasOpSize ? 4 : 2);
888 insn->immSize = (hasOpSize ? 4 : 2);
889 } else if (insn->mode == MODE_32BIT) {
890 insn->registerSize = (hasOpSize ? 2 : 4);
891 insn->addressSize = (hasAdSize ? 2 : 4);
892 insn->displacementSize = (hasAdSize ? 2 : 4);
893 insn->immediateSize = (hasOpSize ? 2 : 4);
894 insn->immSize = (hasOpSize ? 2 : 4);
895 } else if (insn->mode == MODE_64BIT) {
896 if (insn->rexPrefix && wFromREX(insn->rexPrefix)) {
897 insn->registerSize = 8;
898 insn->addressSize = (hasAdSize ? 4 : 8);
899 insn->displacementSize = 4;
900 insn->immediateSize = 4;
901 insn->immSize = 4;
902 } else if (insn->rexPrefix) {
903 insn->registerSize = (hasOpSize ? 2 : 4);
904 insn->addressSize = (hasAdSize ? 4 : 8);
905 insn->displacementSize = (hasOpSize ? 2 : 4);
906 insn->immediateSize = (hasOpSize ? 2 : 4);
907 insn->immSize = (hasOpSize ? 2 : 4);
908 } else {
909 insn->registerSize = (hasOpSize ? 2 : 4);
910 insn->addressSize = (hasAdSize ? 4 : 8);
911 insn->displacementSize = (hasOpSize ? 2 : 4);
912 insn->immediateSize = (hasOpSize ? 2 : 4);
913 insn->immSize = (hasOpSize ? 4 : 8);
914 }
915 }
916
917 return 0;
918 }
919
920 static int readModRM(struct InternalInstruction *insn);
921
922 /*
923 * readOpcode - Reads the opcode (excepting the ModR/M byte in the case of
924 * extended or escape opcodes).
925 *
926 * @param insn - The instruction whose opcode is to be read.
927 * @return - 0 if the opcode could be read successfully; nonzero otherwise.
928 */
readOpcode(struct InternalInstruction * insn)929 static int readOpcode(struct InternalInstruction *insn)
930 {
931 /* Determine the length of the primary opcode */
932 uint8_t current;
933
934 // printf(">>> readOpcode() = %x\n", insn->readerCursor);
935
936 insn->opcodeType = ONEBYTE;
937 insn->firstByte = 0x00;
938
939 if (insn->vectorExtensionType == TYPE_EVEX) {
940 switch (mmFromEVEX2of4(insn->vectorExtensionPrefix[1])) {
941 default:
942 // dbgprintf(insn, "Unhandled mm field for instruction (0x%hhx)",
943 // mmFromEVEX2of4(insn->vectorExtensionPrefix[1]));
944 return -1;
945 case VEX_LOB_0F:
946 insn->opcodeType = TWOBYTE;
947 return consumeByte(insn, &insn->opcode);
948 case VEX_LOB_0F38:
949 insn->opcodeType = THREEBYTE_38;
950 return consumeByte(insn, &insn->opcode);
951 case VEX_LOB_0F3A:
952 insn->opcodeType = THREEBYTE_3A;
953 return consumeByte(insn, &insn->opcode);
954 }
955 } else if (insn->vectorExtensionType == TYPE_VEX_3B) {
956 switch (mmmmmFromVEX2of3(insn->vectorExtensionPrefix[1])) {
957 default:
958 // dbgprintf(insn, "Unhandled m-mmmm field for instruction (0x%hhx)",
959 // mmmmmFromVEX2of3(insn->vectorExtensionPrefix[1]));
960 return -1;
961 case VEX_LOB_0F:
962 insn->twoByteEscape = 0x0f;
963 insn->opcodeType = TWOBYTE;
964 return consumeByte(insn, &insn->opcode);
965 case VEX_LOB_0F38:
966 insn->twoByteEscape = 0x0f;
967 insn->threeByteEscape = 0x38;
968 insn->opcodeType = THREEBYTE_38;
969 return consumeByte(insn, &insn->opcode);
970 case VEX_LOB_0F3A:
971 insn->twoByteEscape = 0x0f;
972 insn->threeByteEscape = 0x3a;
973 insn->opcodeType = THREEBYTE_3A;
974 return consumeByte(insn, &insn->opcode);
975 }
976 } else if (insn->vectorExtensionType == TYPE_VEX_2B) {
977 insn->twoByteEscape = 0x0f;
978 insn->opcodeType = TWOBYTE;
979 return consumeByte(insn, &insn->opcode);
980 } else if (insn->vectorExtensionType == TYPE_XOP) {
981 switch (mmmmmFromXOP2of3(insn->vectorExtensionPrefix[1])) {
982 default:
983 // dbgprintf(insn, "Unhandled m-mmmm field for instruction (0x%hhx)",
984 // mmmmmFromVEX2of3(insn->vectorExtensionPrefix[1]));
985 return -1;
986 case XOP_MAP_SELECT_8:
987 // FIXME: twoByteEscape?
988 insn->opcodeType = XOP8_MAP;
989 return consumeByte(insn, &insn->opcode);
990 case XOP_MAP_SELECT_9:
991 // FIXME: twoByteEscape?
992 insn->opcodeType = XOP9_MAP;
993 return consumeByte(insn, &insn->opcode);
994 case XOP_MAP_SELECT_A:
995 // FIXME: twoByteEscape?
996 insn->opcodeType = XOPA_MAP;
997 return consumeByte(insn, &insn->opcode);
998 }
999 }
1000
1001 if (consumeByte(insn, ¤t))
1002 return -1;
1003
1004 // save this first byte for MOVcr, MOVdr, MOVrc, MOVrd
1005 insn->firstByte = current;
1006
1007 if (current == 0x0f) {
1008 // dbgprintf(insn, "Found a two-byte escape prefix (0x%hhx)", current);
1009
1010 insn->twoByteEscape = current;
1011
1012 if (consumeByte(insn, ¤t))
1013 return -1;
1014
1015 if (current == 0x38) {
1016 // dbgprintf(insn, "Found a three-byte escape prefix (0x%hhx)", current);
1017
1018 insn->threeByteEscape = current;
1019
1020 if (consumeByte(insn, ¤t))
1021 return -1;
1022
1023 insn->opcodeType = THREEBYTE_38;
1024 } else if (current == 0x3a) {
1025 // dbgprintf(insn, "Found a three-byte escape prefix (0x%hhx)", current);
1026
1027 insn->threeByteEscape = current;
1028
1029 if (consumeByte(insn, ¤t))
1030 return -1;
1031
1032 insn->opcodeType = THREEBYTE_3A;
1033 } else {
1034 #ifndef CAPSTONE_X86_REDUCE
1035 switch(current) {
1036 default:
1037 // dbgprintf(insn, "Didn't find a three-byte escape prefix");
1038 insn->opcodeType = TWOBYTE;
1039 break;
1040 case 0x0e: // HACK for femms. to be handled properly in next version 3.x
1041 insn->opcodeType = T3DNOW_MAP;
1042 // this encode does not have ModRM
1043 insn->consumedModRM = true;
1044 break;
1045 case 0x0f:
1046 // 3DNow instruction has weird format: ModRM/SIB/displacement + opcode
1047 if (readModRM(insn))
1048 return -1;
1049 // next is 3DNow opcode
1050 if (consumeByte(insn, ¤t))
1051 return -1;
1052 insn->opcodeType = T3DNOW_MAP;
1053 break;
1054 }
1055 #endif
1056 }
1057 }
1058
1059 /*
1060 * At this point we have consumed the full opcode.
1061 * Anything we consume from here on must be unconsumed.
1062 */
1063
1064 insn->opcode = current;
1065
1066 return 0;
1067 }
1068
1069 // Hacky for FEMMS
1070 #define GET_INSTRINFO_ENUM
1071 #ifndef CAPSTONE_X86_REDUCE
1072 #include "X86GenInstrInfo.inc"
1073 #else
1074 #include "X86GenInstrInfo_reduce.inc"
1075 #endif
1076
1077 /*
1078 * getIDWithAttrMask - Determines the ID of an instruction, consuming
1079 * the ModR/M byte as appropriate for extended and escape opcodes,
1080 * and using a supplied attribute mask.
1081 *
1082 * @param instructionID - A pointer whose target is filled in with the ID of the
1083 * instruction.
1084 * @param insn - The instruction whose ID is to be determined.
1085 * @param attrMask - The attribute mask to search.
1086 * @return - 0 if the ModR/M could be read when needed or was not
1087 * needed; nonzero otherwise.
1088 */
getIDWithAttrMask(uint16_t * instructionID,struct InternalInstruction * insn,uint16_t attrMask)1089 static int getIDWithAttrMask(uint16_t *instructionID,
1090 struct InternalInstruction *insn,
1091 uint16_t attrMask)
1092 {
1093 bool hasModRMExtension;
1094
1095 InstructionContext instructionClass;
1096
1097 #ifndef CAPSTONE_X86_REDUCE
1098 // HACK for femms. to be handled properly in next version 3.x
1099 if (insn->opcode == 0x0e && insn->opcodeType == T3DNOW_MAP) {
1100 *instructionID = X86_FEMMS;
1101 return 0;
1102 }
1103 #endif
1104
1105 if (insn->opcodeType == T3DNOW_MAP)
1106 instructionClass = IC_OF;
1107 else
1108 instructionClass = contextForAttrs(attrMask);
1109
1110 hasModRMExtension = modRMRequired(insn->opcodeType,
1111 instructionClass,
1112 insn->opcode) != 0;
1113
1114 if (hasModRMExtension) {
1115 if (readModRM(insn))
1116 return -1;
1117
1118 *instructionID = decode(insn->opcodeType,
1119 instructionClass,
1120 insn->opcode,
1121 insn->modRM);
1122 } else {
1123 *instructionID = decode(insn->opcodeType,
1124 instructionClass,
1125 insn->opcode,
1126 0);
1127 }
1128
1129 return 0;
1130 }
1131
1132 /*
1133 * is16BitEquivalent - Determines whether two instruction names refer to
1134 * equivalent instructions but one is 16-bit whereas the other is not.
1135 *
1136 * @param orig - The instruction ID that is not 16-bit
1137 * @param equiv - The instruction ID that is 16-bit
1138 */
is16BitEquivalent(unsigned orig,unsigned equiv)1139 static bool is16BitEquivalent(unsigned orig, unsigned equiv)
1140 {
1141 size_t i;
1142 uint16_t idx;
1143
1144 if ((idx = x86_16_bit_eq_lookup[orig]) != 0) {
1145 for (i = idx - 1; i < ARR_SIZE(x86_16_bit_eq_tbl) && x86_16_bit_eq_tbl[i].first == orig; i++) {
1146 if (x86_16_bit_eq_tbl[i].second == equiv)
1147 return true;
1148 }
1149 }
1150
1151 return false;
1152 }
1153
1154 /*
1155 * is64Bit - Determines whether this instruction is a 64-bit instruction.
1156 *
1157 * @param name - The instruction that is not 16-bit
1158 */
is64Bit(uint16_t id)1159 static bool is64Bit(uint16_t id)
1160 {
1161 return is_64bit_insn[id];
1162 }
1163
1164 /*
1165 * getID - Determines the ID of an instruction, consuming the ModR/M byte as
1166 * appropriate for extended and escape opcodes. Determines the attributes and
1167 * context for the instruction before doing so.
1168 *
1169 * @param insn - The instruction whose ID is to be determined.
1170 * @return - 0 if the ModR/M could be read when needed or was not needed;
1171 * nonzero otherwise.
1172 */
getID(struct InternalInstruction * insn)1173 static int getID(struct InternalInstruction *insn)
1174 {
1175 uint16_t attrMask;
1176 uint16_t instructionID;
1177
1178 // printf(">>> getID()\n");
1179 attrMask = ATTR_NONE;
1180
1181 if (insn->mode == MODE_64BIT)
1182 attrMask |= ATTR_64BIT;
1183
1184 if (insn->vectorExtensionType != TYPE_NO_VEX_XOP) {
1185 attrMask |= (insn->vectorExtensionType == TYPE_EVEX) ? ATTR_EVEX : ATTR_VEX;
1186
1187 if (insn->vectorExtensionType == TYPE_EVEX) {
1188 switch (ppFromEVEX3of4(insn->vectorExtensionPrefix[2])) {
1189 case VEX_PREFIX_66:
1190 attrMask |= ATTR_OPSIZE;
1191 break;
1192 case VEX_PREFIX_F3:
1193 attrMask |= ATTR_XS;
1194 break;
1195 case VEX_PREFIX_F2:
1196 attrMask |= ATTR_XD;
1197 break;
1198 }
1199
1200 if (zFromEVEX4of4(insn->vectorExtensionPrefix[3]))
1201 attrMask |= ATTR_EVEXKZ;
1202 if (bFromEVEX4of4(insn->vectorExtensionPrefix[3]))
1203 attrMask |= ATTR_EVEXB;
1204 if (aaaFromEVEX4of4(insn->vectorExtensionPrefix[3]))
1205 attrMask |= ATTR_EVEXK;
1206 if (lFromEVEX4of4(insn->vectorExtensionPrefix[3]))
1207 attrMask |= ATTR_EVEXL;
1208 if (l2FromEVEX4of4(insn->vectorExtensionPrefix[3]))
1209 attrMask |= ATTR_EVEXL2;
1210 } else if (insn->vectorExtensionType == TYPE_VEX_3B) {
1211 switch (ppFromVEX3of3(insn->vectorExtensionPrefix[2])) {
1212 case VEX_PREFIX_66:
1213 attrMask |= ATTR_OPSIZE;
1214 break;
1215 case VEX_PREFIX_F3:
1216 attrMask |= ATTR_XS;
1217 break;
1218 case VEX_PREFIX_F2:
1219 attrMask |= ATTR_XD;
1220 break;
1221 }
1222
1223 if (lFromVEX3of3(insn->vectorExtensionPrefix[2]))
1224 attrMask |= ATTR_VEXL;
1225 } else if (insn->vectorExtensionType == TYPE_VEX_2B) {
1226 switch (ppFromVEX2of2(insn->vectorExtensionPrefix[1])) {
1227 case VEX_PREFIX_66:
1228 attrMask |= ATTR_OPSIZE;
1229 break;
1230 case VEX_PREFIX_F3:
1231 attrMask |= ATTR_XS;
1232 break;
1233 case VEX_PREFIX_F2:
1234 attrMask |= ATTR_XD;
1235 break;
1236 }
1237
1238 if (lFromVEX2of2(insn->vectorExtensionPrefix[1]))
1239 attrMask |= ATTR_VEXL;
1240 } else if (insn->vectorExtensionType == TYPE_XOP) {
1241 switch (ppFromXOP3of3(insn->vectorExtensionPrefix[2])) {
1242 case VEX_PREFIX_66:
1243 attrMask |= ATTR_OPSIZE;
1244 break;
1245 case VEX_PREFIX_F3:
1246 attrMask |= ATTR_XS;
1247 break;
1248 case VEX_PREFIX_F2:
1249 attrMask |= ATTR_XD;
1250 break;
1251 }
1252
1253 if (lFromXOP3of3(insn->vectorExtensionPrefix[2]))
1254 attrMask |= ATTR_VEXL;
1255 } else {
1256 return -1;
1257 }
1258 } else {
1259 if (insn->mode != MODE_16BIT && isPrefixAtLocation(insn, 0x66, insn->necessaryPrefixLocation)) {
1260 attrMask |= ATTR_OPSIZE;
1261 } else if (isPrefixAtLocation(insn, 0x67, insn->necessaryPrefixLocation)) {
1262 attrMask |= ATTR_ADSIZE;
1263 } else if (insn->mode != MODE_16BIT && isPrefixAtLocation(insn, 0xf3, insn->necessaryPrefixLocation)) {
1264 attrMask |= ATTR_XS;
1265 } else if (insn->mode != MODE_16BIT && isPrefixAtLocation(insn, 0xf2, insn->necessaryPrefixLocation)) {
1266 attrMask |= ATTR_XD;
1267 }
1268 }
1269
1270 if (insn->rexPrefix & 0x08)
1271 attrMask |= ATTR_REXW;
1272
1273 /*
1274 * JCXZ/JECXZ need special handling for 16-bit mode because the meaning
1275 * of the AdSize prefix is inverted w.r.t. 32-bit mode.
1276 */
1277 if (insn->mode == MODE_16BIT && insn->opcodeType == ONEBYTE &&
1278 insn->opcode == 0xE3)
1279 attrMask ^= ATTR_ADSIZE;
1280
1281 if (getIDWithAttrMask(&instructionID, insn, attrMask))
1282 return -1;
1283
1284 /* The following clauses compensate for limitations of the tables. */
1285 if (insn->mode != MODE_64BIT &&
1286 insn->vectorExtensionType != TYPE_NO_VEX_XOP) {
1287 /*
1288 * The tables can't distinquish between cases where the W-bit is used to
1289 * select register size and cases where its a required part of the opcode.
1290 */
1291 if ((insn->vectorExtensionType == TYPE_EVEX &&
1292 wFromEVEX3of4(insn->vectorExtensionPrefix[2])) ||
1293 (insn->vectorExtensionType == TYPE_VEX_3B &&
1294 wFromVEX3of3(insn->vectorExtensionPrefix[2])) ||
1295 (insn->vectorExtensionType == TYPE_XOP &&
1296 wFromXOP3of3(insn->vectorExtensionPrefix[2]))) {
1297 uint16_t instructionIDWithREXW;
1298 if (getIDWithAttrMask(&instructionIDWithREXW,
1299 insn, attrMask | ATTR_REXW)) {
1300 insn->instructionID = instructionID;
1301 insn->spec = specifierForUID(instructionID);
1302
1303 return 0;
1304 }
1305
1306 // If not a 64-bit instruction. Switch the opcode.
1307 if (!is64Bit(instructionIDWithREXW)) {
1308 insn->instructionID = instructionIDWithREXW;
1309 insn->spec = specifierForUID(instructionIDWithREXW);
1310
1311 return 0;
1312 }
1313 }
1314 }
1315
1316 /*
1317 * Absolute moves need special handling.
1318 * -For 16-bit mode because the meaning of the AdSize and OpSize prefixes are
1319 * inverted w.r.t.
1320 * -For 32-bit mode we need to ensure the ADSIZE prefix is observed in
1321 * any position.
1322 */
1323 if (insn->opcodeType == ONEBYTE && ((insn->opcode & 0xFC) == 0xA0)) {
1324 /* Make sure we observed the prefixes in any position. */
1325 if (insn->isPrefix67)
1326 attrMask |= ATTR_ADSIZE;
1327 if (insn->isPrefix66)
1328 attrMask |= ATTR_OPSIZE;
1329
1330 /* In 16-bit, invert the attributes. */
1331 if (insn->mode == MODE_16BIT)
1332 attrMask ^= ATTR_ADSIZE | ATTR_OPSIZE;
1333
1334 if (getIDWithAttrMask(&instructionID, insn, attrMask))
1335 return -1;
1336
1337 insn->instructionID = instructionID;
1338 insn->spec = specifierForUID(instructionID);
1339
1340 return 0;
1341 }
1342
1343 if ((insn->mode == MODE_16BIT || insn->isPrefix66) &&
1344 !(attrMask & ATTR_OPSIZE)) {
1345 /*
1346 * The instruction tables make no distinction between instructions that
1347 * allow OpSize anywhere (i.e., 16-bit operations) and that need it in a
1348 * particular spot (i.e., many MMX operations). In general we're
1349 * conservative, but in the specific case where OpSize is present but not
1350 * in the right place we check if there's a 16-bit operation.
1351 */
1352
1353 const struct InstructionSpecifier *spec;
1354 uint16_t instructionIDWithOpsize;
1355
1356 spec = specifierForUID(instructionID);
1357
1358 if (getIDWithAttrMask(&instructionIDWithOpsize,
1359 insn, attrMask | ATTR_OPSIZE)) {
1360 /*
1361 * ModRM required with OpSize but not present; give up and return version
1362 * without OpSize set
1363 */
1364
1365 insn->instructionID = instructionID;
1366 insn->spec = spec;
1367 return 0;
1368 }
1369
1370 if (is16BitEquivalent(instructionID, instructionIDWithOpsize) &&
1371 (insn->mode == MODE_16BIT) ^ insn->isPrefix66) {
1372 insn->instructionID = instructionIDWithOpsize;
1373 insn->spec = specifierForUID(instructionIDWithOpsize);
1374 } else {
1375 insn->instructionID = instructionID;
1376 insn->spec = spec;
1377 }
1378 return 0;
1379 }
1380
1381 if (insn->opcodeType == ONEBYTE && insn->opcode == 0x90 &&
1382 insn->rexPrefix & 0x01) {
1383 /*
1384 * NOOP shouldn't decode as NOOP if REX.b is set. Instead
1385 * it should decode as XCHG %r8, %eax.
1386 */
1387
1388 const struct InstructionSpecifier *spec;
1389 uint16_t instructionIDWithNewOpcode;
1390 const struct InstructionSpecifier *specWithNewOpcode;
1391
1392 spec = specifierForUID(instructionID);
1393
1394 /* Borrow opcode from one of the other XCHGar opcodes */
1395 insn->opcode = 0x91;
1396
1397 if (getIDWithAttrMask(&instructionIDWithNewOpcode,
1398 insn,
1399 attrMask)) {
1400 insn->opcode = 0x90;
1401
1402 insn->instructionID = instructionID;
1403 insn->spec = spec;
1404 return 0;
1405 }
1406
1407 specWithNewOpcode = specifierForUID(instructionIDWithNewOpcode);
1408
1409 /* Change back */
1410 insn->opcode = 0x90;
1411
1412 insn->instructionID = instructionIDWithNewOpcode;
1413 insn->spec = specWithNewOpcode;
1414
1415 return 0;
1416 }
1417
1418 insn->instructionID = instructionID;
1419 insn->spec = specifierForUID(insn->instructionID);
1420
1421 return 0;
1422 }
1423
1424 /*
1425 * readSIB - Consumes the SIB byte to determine addressing information for an
1426 * instruction.
1427 *
1428 * @param insn - The instruction whose SIB byte is to be read.
1429 * @return - 0 if the SIB byte was successfully read; nonzero otherwise.
1430 */
readSIB(struct InternalInstruction * insn)1431 static int readSIB(struct InternalInstruction *insn)
1432 {
1433 SIBIndex sibIndexBase = SIB_INDEX_NONE;
1434 SIBBase sibBaseBase = SIB_BASE_NONE;
1435 uint8_t index, base;
1436
1437 // dbgprintf(insn, "readSIB()");
1438
1439 if (insn->consumedSIB)
1440 return 0;
1441
1442 insn->consumedSIB = true;
1443
1444 switch (insn->addressSize) {
1445 case 2:
1446 // dbgprintf(insn, "SIB-based addressing doesn't work in 16-bit mode");
1447 return -1;
1448 case 4:
1449 sibIndexBase = SIB_INDEX_EAX;
1450 sibBaseBase = SIB_BASE_EAX;
1451 break;
1452 case 8:
1453 sibIndexBase = SIB_INDEX_RAX;
1454 sibBaseBase = SIB_BASE_RAX;
1455 break;
1456 }
1457
1458 if (consumeByte(insn, &insn->sib))
1459 return -1;
1460
1461 index = indexFromSIB(insn->sib) | (xFromREX(insn->rexPrefix) << 3);
1462 if (insn->vectorExtensionType == TYPE_EVEX)
1463 index |= v2FromEVEX4of4(insn->vectorExtensionPrefix[3]) << 4;
1464
1465 switch (index) {
1466 case 0x4:
1467 insn->sibIndex = SIB_INDEX_NONE;
1468 break;
1469 default:
1470 insn->sibIndex = (SIBIndex)(sibIndexBase + index);
1471 if (insn->sibIndex == SIB_INDEX_sib ||
1472 insn->sibIndex == SIB_INDEX_sib64)
1473 insn->sibIndex = SIB_INDEX_NONE;
1474 break;
1475 }
1476
1477 switch (scaleFromSIB(insn->sib)) {
1478 case 0:
1479 insn->sibScale = 1;
1480 break;
1481 case 1:
1482 insn->sibScale = 2;
1483 break;
1484 case 2:
1485 insn->sibScale = 4;
1486 break;
1487 case 3:
1488 insn->sibScale = 8;
1489 break;
1490 }
1491
1492 base = baseFromSIB(insn->sib) | (bFromREX(insn->rexPrefix) << 3);
1493
1494 switch (base) {
1495 case 0x5:
1496 case 0xd:
1497 switch (modFromModRM(insn->modRM)) {
1498 case 0x0:
1499 insn->eaDisplacement = EA_DISP_32;
1500 insn->sibBase = SIB_BASE_NONE;
1501 break;
1502 case 0x1:
1503 insn->eaDisplacement = EA_DISP_8;
1504 insn->sibBase = (SIBBase)(sibBaseBase + base);
1505 break;
1506 case 0x2:
1507 insn->eaDisplacement = EA_DISP_32;
1508 insn->sibBase = (SIBBase)(sibBaseBase + base);
1509 break;
1510 case 0x3:
1511 //debug("Cannot have Mod = 0b11 and a SIB byte");
1512 return -1;
1513 }
1514 break;
1515 default:
1516 insn->sibBase = (SIBBase)(sibBaseBase + base);
1517 break;
1518 }
1519
1520 return 0;
1521 }
1522
1523 /*
1524 * readDisplacement - Consumes the displacement of an instruction.
1525 *
1526 * @param insn - The instruction whose displacement is to be read.
1527 * @return - 0 if the displacement byte was successfully read; nonzero
1528 * otherwise.
1529 */
readDisplacement(struct InternalInstruction * insn)1530 static int readDisplacement(struct InternalInstruction *insn)
1531 {
1532 int8_t d8;
1533 int16_t d16;
1534 int32_t d32;
1535
1536 // dbgprintf(insn, "readDisplacement()");
1537
1538 if (insn->consumedDisplacement)
1539 return 0;
1540
1541 insn->consumedDisplacement = true;
1542 insn->displacementOffset = (uint8_t)(insn->readerCursor - insn->startLocation);
1543
1544 switch (insn->eaDisplacement) {
1545 case EA_DISP_NONE:
1546 insn->consumedDisplacement = false;
1547 break;
1548 case EA_DISP_8:
1549 if (consumeInt8(insn, &d8))
1550 return -1;
1551 insn->displacement = d8;
1552 break;
1553 case EA_DISP_16:
1554 if (consumeInt16(insn, &d16))
1555 return -1;
1556 insn->displacement = d16;
1557 break;
1558 case EA_DISP_32:
1559 if (consumeInt32(insn, &d32))
1560 return -1;
1561 insn->displacement = d32;
1562 break;
1563 }
1564
1565 return 0;
1566 }
1567
1568 /*
1569 * readModRM - Consumes all addressing information (ModR/M byte, SIB byte, and
1570 * displacement) for an instruction and interprets it.
1571 *
1572 * @param insn - The instruction whose addressing information is to be read.
1573 * @return - 0 if the information was successfully read; nonzero otherwise.
1574 */
readModRM(struct InternalInstruction * insn)1575 static int readModRM(struct InternalInstruction *insn)
1576 {
1577 uint8_t mod, rm, reg;
1578
1579 // dbgprintf(insn, "readModRM()");
1580
1581 // already got ModRM byte?
1582 if (insn->consumedModRM)
1583 return 0;
1584
1585 insn->modRMOffset = (uint8_t)(insn->readerCursor - insn->startLocation);
1586
1587 if (consumeByte(insn, &insn->modRM))
1588 return -1;
1589
1590 // mark that we already got ModRM
1591 insn->consumedModRM = true;
1592
1593 // save original ModRM for later reference
1594 insn->orgModRM = insn->modRM;
1595
1596 // handle MOVcr, MOVdr, MOVrc, MOVrd by pretending they have MRM.mod = 3
1597 if ((insn->firstByte == 0x0f && insn->opcodeType == TWOBYTE) &&
1598 (insn->opcode >= 0x20 && insn->opcode <= 0x23 ))
1599 insn->modRM |= 0xC0;
1600
1601 mod = modFromModRM(insn->modRM);
1602 rm = rmFromModRM(insn->modRM);
1603 reg = regFromModRM(insn->modRM);
1604
1605 /*
1606 * This goes by insn->registerSize to pick the correct register, which messes
1607 * up if we're using (say) XMM or 8-bit register operands. That gets fixed in
1608 * fixupReg().
1609 */
1610 switch (insn->registerSize) {
1611 case 2:
1612 insn->regBase = MODRM_REG_AX;
1613 insn->eaRegBase = EA_REG_AX;
1614 break;
1615 case 4:
1616 insn->regBase = MODRM_REG_EAX;
1617 insn->eaRegBase = EA_REG_EAX;
1618 break;
1619 case 8:
1620 insn->regBase = MODRM_REG_RAX;
1621 insn->eaRegBase = EA_REG_RAX;
1622 break;
1623 }
1624
1625 reg |= rFromREX(insn->rexPrefix) << 3;
1626 rm |= bFromREX(insn->rexPrefix) << 3;
1627 if (insn->vectorExtensionType == TYPE_EVEX) {
1628 reg |= r2FromEVEX2of4(insn->vectorExtensionPrefix[1]) << 4;
1629 rm |= xFromEVEX2of4(insn->vectorExtensionPrefix[1]) << 4;
1630 }
1631
1632 insn->reg = (Reg)(insn->regBase + reg);
1633
1634 switch (insn->addressSize) {
1635 case 2:
1636 insn->eaBaseBase = EA_BASE_BX_SI;
1637
1638 switch (mod) {
1639 case 0x0:
1640 if (rm == 0x6) {
1641 insn->eaBase = EA_BASE_NONE;
1642 insn->eaDisplacement = EA_DISP_16;
1643 if (readDisplacement(insn))
1644 return -1;
1645 } else {
1646 insn->eaBase = (EABase)(insn->eaBaseBase + rm);
1647 insn->eaDisplacement = EA_DISP_NONE;
1648 }
1649 break;
1650 case 0x1:
1651 insn->eaBase = (EABase)(insn->eaBaseBase + rm);
1652 insn->eaDisplacement = EA_DISP_8;
1653 insn->displacementSize = 1;
1654 if (readDisplacement(insn))
1655 return -1;
1656 break;
1657 case 0x2:
1658 insn->eaBase = (EABase)(insn->eaBaseBase + rm);
1659 insn->eaDisplacement = EA_DISP_16;
1660 if (readDisplacement(insn))
1661 return -1;
1662 break;
1663 case 0x3:
1664 insn->eaBase = (EABase)(insn->eaRegBase + rm);
1665 insn->eaDisplacement = EA_DISP_NONE;
1666 if (readDisplacement(insn))
1667 return -1;
1668 break;
1669 }
1670 break;
1671 case 4:
1672 case 8:
1673 insn->eaBaseBase = (insn->addressSize == 4 ? EA_BASE_EAX : EA_BASE_RAX);
1674
1675 switch (mod) {
1676 case 0x0:
1677 insn->eaDisplacement = EA_DISP_NONE; /* readSIB may override this */
1678 switch (rm) {
1679 case 0x14:
1680 case 0x4:
1681 case 0xc: /* in case REXW.b is set */
1682 insn->eaBase = (insn->addressSize == 4 ?
1683 EA_BASE_sib : EA_BASE_sib64);
1684 if (readSIB(insn) || readDisplacement(insn))
1685 return -1;
1686 break;
1687 case 0x5:
1688 case 0xd:
1689 insn->eaBase = EA_BASE_NONE;
1690 insn->eaDisplacement = EA_DISP_32;
1691 if (readDisplacement(insn))
1692 return -1;
1693 break;
1694 default:
1695 insn->eaBase = (EABase)(insn->eaBaseBase + rm);
1696 break;
1697 }
1698
1699 break;
1700 case 0x1:
1701 insn->displacementSize = 1;
1702 /* FALLTHROUGH */
1703 case 0x2:
1704 insn->eaDisplacement = (mod == 0x1 ? EA_DISP_8 : EA_DISP_32);
1705 switch (rm) {
1706 case 0x14:
1707 case 0x4:
1708 case 0xc: /* in case REXW.b is set */
1709 insn->eaBase = EA_BASE_sib;
1710 if (readSIB(insn) || readDisplacement(insn))
1711 return -1;
1712 break;
1713 default:
1714 insn->eaBase = (EABase)(insn->eaBaseBase + rm);
1715 if (readDisplacement(insn))
1716 return -1;
1717 break;
1718 }
1719 break;
1720 case 0x3:
1721 insn->eaDisplacement = EA_DISP_NONE;
1722 insn->eaBase = (EABase)(insn->eaRegBase + rm);
1723 break;
1724 }
1725 break;
1726 } /* switch (insn->addressSize) */
1727
1728 return 0;
1729 }
1730
1731 #define GENERIC_FIXUP_FUNC(name, base, prefix) \
1732 static uint8_t name(struct InternalInstruction *insn, \
1733 OperandType type, \
1734 uint8_t index, \
1735 uint8_t *valid) { \
1736 *valid = 1; \
1737 switch (type) { \
1738 default: \
1739 *valid = 0; \
1740 return 0; \
1741 case TYPE_Rv: \
1742 return base + index; \
1743 case TYPE_R8: \
1744 if (insn->rexPrefix && \
1745 index >= 4 && index <= 7) { \
1746 return prefix##_SPL + (index - 4); \
1747 } else { \
1748 return prefix##_AL + index; \
1749 } \
1750 case TYPE_R16: \
1751 return prefix##_AX + index; \
1752 case TYPE_R32: \
1753 return prefix##_EAX + index; \
1754 case TYPE_R64: \
1755 return prefix##_RAX + index; \
1756 case TYPE_XMM512: \
1757 return prefix##_ZMM0 + index; \
1758 case TYPE_XMM256: \
1759 return prefix##_YMM0 + index; \
1760 case TYPE_XMM128: \
1761 case TYPE_XMM64: \
1762 case TYPE_XMM32: \
1763 case TYPE_XMM: \
1764 return prefix##_XMM0 + index; \
1765 case TYPE_VK1: \
1766 case TYPE_VK8: \
1767 case TYPE_VK16: \
1768 if (index > 7) \
1769 *valid = 0; \
1770 return prefix##_K0 + index; \
1771 case TYPE_MM64: \
1772 return prefix##_MM0 + (index & 0x7); \
1773 case TYPE_SEGMENTREG: \
1774 if (index > 5) \
1775 *valid = 0; \
1776 return prefix##_ES + index; \
1777 case TYPE_DEBUGREG: \
1778 return prefix##_DR0 + index; \
1779 case TYPE_CONTROLREG: \
1780 return prefix##_CR0 + index; \
1781 } \
1782 }
1783
1784
1785 /*
1786 * fixup*Value - Consults an operand type to determine the meaning of the
1787 * reg or R/M field. If the operand is an XMM operand, for example, an
1788 * operand would be XMM0 instead of AX, which readModRM() would otherwise
1789 * misinterpret it as.
1790 *
1791 * @param insn - The instruction containing the operand.
1792 * @param type - The operand type.
1793 * @param index - The existing value of the field as reported by readModRM().
1794 * @param valid - The address of a uint8_t. The target is set to 1 if the
1795 * field is valid for the register class; 0 if not.
1796 * @return - The proper value.
1797 */
1798 GENERIC_FIXUP_FUNC(fixupRegValue, insn->regBase, MODRM_REG)
1799 GENERIC_FIXUP_FUNC(fixupRMValue, insn->eaRegBase, EA_REG)
1800
1801 /*
1802 * fixupReg - Consults an operand specifier to determine which of the
1803 * fixup*Value functions to use in correcting readModRM()'ss interpretation.
1804 *
1805 * @param insn - See fixup*Value().
1806 * @param op - The operand specifier.
1807 * @return - 0 if fixup was successful; -1 if the register returned was
1808 * invalid for its class.
1809 */
fixupReg(struct InternalInstruction * insn,const struct OperandSpecifier * op)1810 static int fixupReg(struct InternalInstruction *insn,
1811 const struct OperandSpecifier *op)
1812 {
1813 uint8_t valid;
1814
1815 // dbgprintf(insn, "fixupReg()");
1816
1817 switch ((OperandEncoding)op->encoding) {
1818 default:
1819 //debug("Expected a REG or R/M encoding in fixupReg");
1820 return -1;
1821 case ENCODING_VVVV:
1822 insn->vvvv = (Reg)fixupRegValue(insn,
1823 (OperandType)op->type,
1824 insn->vvvv,
1825 &valid);
1826 if (!valid)
1827 return -1;
1828 break;
1829 case ENCODING_REG:
1830 insn->reg = (Reg)fixupRegValue(insn,
1831 (OperandType)op->type,
1832 (uint8_t)(insn->reg - insn->regBase),
1833 &valid);
1834 if (!valid)
1835 return -1;
1836 break;
1837 CASE_ENCODING_RM:
1838 if (insn->eaBase >= insn->eaRegBase) {
1839 insn->eaBase = (EABase)fixupRMValue(insn,
1840 (OperandType)op->type,
1841 (uint8_t)(insn->eaBase - insn->eaRegBase),
1842 &valid);
1843 if (!valid)
1844 return -1;
1845 }
1846 break;
1847 }
1848
1849 return 0;
1850 }
1851
1852 /*
1853 * readOpcodeRegister - Reads an operand from the opcode field of an
1854 * instruction and interprets it appropriately given the operand width.
1855 * Handles AddRegFrm instructions.
1856 *
1857 * @param insn - the instruction whose opcode field is to be read.
1858 * @param size - The width (in bytes) of the register being specified.
1859 * 1 means AL and friends, 2 means AX, 4 means EAX, and 8 means
1860 * RAX.
1861 * @return - 0 on success; nonzero otherwise.
1862 */
readOpcodeRegister(struct InternalInstruction * insn,uint8_t size)1863 static int readOpcodeRegister(struct InternalInstruction *insn, uint8_t size)
1864 {
1865 // dbgprintf(insn, "readOpcodeRegister()");
1866
1867 if (size == 0)
1868 size = insn->registerSize;
1869
1870 insn->operandSize = size;
1871
1872 switch (size) {
1873 case 1:
1874 insn->opcodeRegister = (Reg)(MODRM_REG_AL + ((bFromREX(insn->rexPrefix) << 3)
1875 | (insn->opcode & 7)));
1876 if (insn->rexPrefix &&
1877 insn->opcodeRegister >= MODRM_REG_AL + 0x4 &&
1878 insn->opcodeRegister < MODRM_REG_AL + 0x8) {
1879 insn->opcodeRegister = (Reg)(MODRM_REG_SPL
1880 + (insn->opcodeRegister - MODRM_REG_AL - 4));
1881 }
1882
1883 break;
1884 case 2:
1885 insn->opcodeRegister = (Reg)(MODRM_REG_AX
1886 + ((bFromREX(insn->rexPrefix) << 3)
1887 | (insn->opcode & 7)));
1888 break;
1889 case 4:
1890 insn->opcodeRegister = (Reg)(MODRM_REG_EAX
1891 + ((bFromREX(insn->rexPrefix) << 3)
1892 | (insn->opcode & 7)));
1893 break;
1894 case 8:
1895 insn->opcodeRegister = (Reg)(MODRM_REG_RAX
1896 + ((bFromREX(insn->rexPrefix) << 3)
1897 | (insn->opcode & 7)));
1898 break;
1899 }
1900
1901 return 0;
1902 }
1903
1904 /*
1905 * readImmediate - Consumes an immediate operand from an instruction, given the
1906 * desired operand size.
1907 *
1908 * @param insn - The instruction whose operand is to be read.
1909 * @param size - The width (in bytes) of the operand.
1910 * @return - 0 if the immediate was successfully consumed; nonzero
1911 * otherwise.
1912 */
readImmediate(struct InternalInstruction * insn,uint8_t size)1913 static int readImmediate(struct InternalInstruction *insn, uint8_t size)
1914 {
1915 uint8_t imm8;
1916 uint16_t imm16;
1917 uint32_t imm32;
1918 uint64_t imm64;
1919
1920 // dbgprintf(insn, "readImmediate()");
1921
1922 if (insn->numImmediatesConsumed == 2) {
1923 //debug("Already consumed two immediates");
1924 return -1;
1925 }
1926
1927 if (size == 0)
1928 size = insn->immediateSize;
1929 else
1930 insn->immediateSize = size;
1931 insn->immediateOffset = (uint8_t)(insn->readerCursor - insn->startLocation);
1932
1933 switch (size) {
1934 case 1:
1935 if (consumeByte(insn, &imm8))
1936 return -1;
1937 insn->immediates[insn->numImmediatesConsumed] = imm8;
1938 break;
1939 case 2:
1940 if (consumeUInt16(insn, &imm16))
1941 return -1;
1942 insn->immediates[insn->numImmediatesConsumed] = imm16;
1943 break;
1944 case 4:
1945 if (consumeUInt32(insn, &imm32))
1946 return -1;
1947 insn->immediates[insn->numImmediatesConsumed] = imm32;
1948 break;
1949 case 8:
1950 if (consumeUInt64(insn, &imm64))
1951 return -1;
1952 insn->immediates[insn->numImmediatesConsumed] = imm64;
1953 break;
1954 }
1955
1956 insn->numImmediatesConsumed++;
1957
1958 return 0;
1959 }
1960
1961 /*
1962 * readVVVV - Consumes vvvv from an instruction if it has a VEX prefix.
1963 *
1964 * @param insn - The instruction whose operand is to be read.
1965 * @return - 0 if the vvvv was successfully consumed; nonzero
1966 * otherwise.
1967 */
readVVVV(struct InternalInstruction * insn)1968 static int readVVVV(struct InternalInstruction *insn)
1969 {
1970 int vvvv;
1971 // dbgprintf(insn, "readVVVV()");
1972
1973 if (insn->vectorExtensionType == TYPE_EVEX)
1974 vvvv = (v2FromEVEX4of4(insn->vectorExtensionPrefix[3]) << 4 |
1975 vvvvFromEVEX3of4(insn->vectorExtensionPrefix[2]));
1976 else if (insn->vectorExtensionType == TYPE_VEX_3B)
1977 vvvv = vvvvFromVEX3of3(insn->vectorExtensionPrefix[2]);
1978 else if (insn->vectorExtensionType == TYPE_VEX_2B)
1979 vvvv = vvvvFromVEX2of2(insn->vectorExtensionPrefix[1]);
1980 else if (insn->vectorExtensionType == TYPE_XOP)
1981 vvvv = vvvvFromXOP3of3(insn->vectorExtensionPrefix[2]);
1982 else
1983 return -1;
1984
1985 if (insn->mode != MODE_64BIT)
1986 vvvv &= 0x7;
1987
1988 insn->vvvv = vvvv;
1989
1990 return 0;
1991 }
1992
1993 /*
1994 * readMaskRegister - Reads an mask register from the opcode field of an
1995 * instruction.
1996 *
1997 * @param insn - The instruction whose opcode field is to be read.
1998 * @return - 0 on success; nonzero otherwise.
1999 */
readMaskRegister(struct InternalInstruction * insn)2000 static int readMaskRegister(struct InternalInstruction *insn)
2001 {
2002 // dbgprintf(insn, "readMaskRegister()");
2003
2004 if (insn->vectorExtensionType != TYPE_EVEX)
2005 return -1;
2006
2007 insn->writemask = aaaFromEVEX4of4(insn->vectorExtensionPrefix[3]);
2008
2009 return 0;
2010 }
2011
2012 /*
2013 * readOperands - Consults the specifier for an instruction and consumes all
2014 * operands for that instruction, interpreting them as it goes.
2015 *
2016 * @param insn - The instruction whose operands are to be read and interpreted.
2017 * @return - 0 if all operands could be read; nonzero otherwise.
2018 */
readOperands(struct InternalInstruction * insn)2019 static int readOperands(struct InternalInstruction *insn)
2020 {
2021 int index;
2022 int hasVVVV, needVVVV;
2023 int sawRegImm = 0;
2024
2025 // printf(">>> readOperands(): ID = %u\n", insn->instructionID);
2026 /* If non-zero vvvv specified, need to make sure one of the operands
2027 uses it. */
2028 hasVVVV = !readVVVV(insn);
2029 needVVVV = hasVVVV && (insn->vvvv != 0);
2030
2031 for (index = 0; index < X86_MAX_OPERANDS; ++index) {
2032 //printf(">>> encoding[%u] = %u\n", index, x86OperandSets[insn->spec->operands][index].encoding);
2033 switch (x86OperandSets[insn->spec->operands][index].encoding) {
2034 case ENCODING_NONE:
2035 case ENCODING_SI:
2036 case ENCODING_DI:
2037 break;
2038 case ENCODING_REG:
2039 CASE_ENCODING_RM:
2040 if (readModRM(insn))
2041 return -1;
2042 if (fixupReg(insn, &x86OperandSets[insn->spec->operands][index]))
2043 return -1;
2044 // Apply the AVX512 compressed displacement scaling factor.
2045 if (x86OperandSets[insn->spec->operands][index].encoding != ENCODING_REG && insn->eaDisplacement == EA_DISP_8)
2046 insn->displacement *= (int64_t)1 << (x86OperandSets[insn->spec->operands][index].encoding - ENCODING_RM);
2047 break;
2048 case ENCODING_CB:
2049 case ENCODING_CW:
2050 case ENCODING_CD:
2051 case ENCODING_CP:
2052 case ENCODING_CO:
2053 case ENCODING_CT:
2054 // dbgprintf(insn, "We currently don't hande code-offset encodings");
2055 return -1;
2056 case ENCODING_IB:
2057 if (sawRegImm) {
2058 /* Saw a register immediate so don't read again and instead split the
2059 previous immediate. FIXME: This is a hack. */
2060 insn->immediates[insn->numImmediatesConsumed] =
2061 insn->immediates[insn->numImmediatesConsumed - 1] & 0xf;
2062 ++insn->numImmediatesConsumed;
2063 break;
2064 }
2065 if (readImmediate(insn, 1))
2066 return -1;
2067 if (x86OperandSets[insn->spec->operands][index].type == TYPE_XMM128 ||
2068 x86OperandSets[insn->spec->operands][index].type == TYPE_XMM256)
2069 sawRegImm = 1;
2070 break;
2071 case ENCODING_IW:
2072 if (readImmediate(insn, 2))
2073 return -1;
2074 break;
2075 case ENCODING_ID:
2076 if (readImmediate(insn, 4))
2077 return -1;
2078 break;
2079 case ENCODING_IO:
2080 if (readImmediate(insn, 8))
2081 return -1;
2082 break;
2083 case ENCODING_Iv:
2084 if (readImmediate(insn, insn->immediateSize))
2085 return -1;
2086 break;
2087 case ENCODING_Ia:
2088 if (readImmediate(insn, insn->addressSize))
2089 return -1;
2090 /* Direct memory-offset (moffset) immediate will get mapped
2091 to memory operand later. We want the encoding info to
2092 reflect that as well. */
2093 insn->displacementOffset = insn->immediateOffset;
2094 insn->consumedDisplacement = true;
2095 insn->displacementSize = insn->immediateSize;
2096 insn->displacement = insn->immediates[insn->numImmediatesConsumed - 1];
2097 insn->immediateOffset = 0;
2098 insn->immediateSize = 0;
2099 break;
2100 case ENCODING_RB:
2101 if (readOpcodeRegister(insn, 1))
2102 return -1;
2103 break;
2104 case ENCODING_RW:
2105 if (readOpcodeRegister(insn, 2))
2106 return -1;
2107 break;
2108 case ENCODING_RD:
2109 if (readOpcodeRegister(insn, 4))
2110 return -1;
2111 break;
2112 case ENCODING_RO:
2113 if (readOpcodeRegister(insn, 8))
2114 return -1;
2115 break;
2116 case ENCODING_Rv:
2117 if (readOpcodeRegister(insn, 0))
2118 return -1;
2119 break;
2120 case ENCODING_FP:
2121 break;
2122 case ENCODING_VVVV:
2123 needVVVV = 0; /* Mark that we have found a VVVV operand. */
2124 if (!hasVVVV)
2125 return -1;
2126 if (fixupReg(insn, &x86OperandSets[insn->spec->operands][index]))
2127 return -1;
2128 break;
2129 case ENCODING_WRITEMASK:
2130 if (readMaskRegister(insn))
2131 return -1;
2132 break;
2133 case ENCODING_DUP:
2134 break;
2135 default:
2136 // dbgprintf(insn, "Encountered an operand with an unknown encoding.");
2137 return -1;
2138 }
2139 }
2140
2141 /* If we didn't find ENCODING_VVVV operand, but non-zero vvvv present, fail */
2142 if (needVVVV) return -1;
2143
2144 return 0;
2145 }
2146
2147 // return True if instruction is illegal to use with prefixes
2148 // This also check & fix the isPrefixNN when a prefix is irrelevant.
checkPrefix(struct InternalInstruction * insn)2149 static bool checkPrefix(struct InternalInstruction *insn)
2150 {
2151 // LOCK prefix
2152 if (insn->isPrefixf0) {
2153 switch(insn->instructionID) {
2154 default:
2155 // invalid LOCK
2156 return true;
2157
2158 // nop dword [rax]
2159 case X86_NOOPL:
2160
2161 // DEC
2162 case X86_DEC16m:
2163 case X86_DEC32m:
2164 case X86_DEC64m:
2165 case X86_DEC8m:
2166
2167 // ADC
2168 case X86_ADC16mi:
2169 case X86_ADC16mi8:
2170 case X86_ADC16mr:
2171 case X86_ADC32mi:
2172 case X86_ADC32mi8:
2173 case X86_ADC32mr:
2174 case X86_ADC64mi32:
2175 case X86_ADC64mi8:
2176 case X86_ADC64mr:
2177 case X86_ADC8mi:
2178 case X86_ADC8mi8:
2179 case X86_ADC8mr:
2180
2181 // ADD
2182 case X86_ADD16mi:
2183 case X86_ADD16mi8:
2184 case X86_ADD16mr:
2185 case X86_ADD32mi:
2186 case X86_ADD32mi8:
2187 case X86_ADD32mr:
2188 case X86_ADD64mi32:
2189 case X86_ADD64mi8:
2190 case X86_ADD64mr:
2191 case X86_ADD8mi:
2192 case X86_ADD8mi8:
2193 case X86_ADD8mr:
2194
2195 // AND
2196 case X86_AND16mi:
2197 case X86_AND16mi8:
2198 case X86_AND16mr:
2199 case X86_AND32mi:
2200 case X86_AND32mi8:
2201 case X86_AND32mr:
2202 case X86_AND64mi32:
2203 case X86_AND64mi8:
2204 case X86_AND64mr:
2205 case X86_AND8mi:
2206 case X86_AND8mi8:
2207 case X86_AND8mr:
2208
2209 // BTC
2210 case X86_BTC16mi8:
2211 case X86_BTC16mr:
2212 case X86_BTC32mi8:
2213 case X86_BTC32mr:
2214 case X86_BTC64mi8:
2215 case X86_BTC64mr:
2216
2217 // BTR
2218 case X86_BTR16mi8:
2219 case X86_BTR16mr:
2220 case X86_BTR32mi8:
2221 case X86_BTR32mr:
2222 case X86_BTR64mi8:
2223 case X86_BTR64mr:
2224
2225 // BTS
2226 case X86_BTS16mi8:
2227 case X86_BTS16mr:
2228 case X86_BTS32mi8:
2229 case X86_BTS32mr:
2230 case X86_BTS64mi8:
2231 case X86_BTS64mr:
2232
2233 // CMPXCHG
2234 case X86_CMPXCHG16B:
2235 case X86_CMPXCHG16rm:
2236 case X86_CMPXCHG32rm:
2237 case X86_CMPXCHG64rm:
2238 case X86_CMPXCHG8rm:
2239 case X86_CMPXCHG8B:
2240
2241 // INC
2242 case X86_INC16m:
2243 case X86_INC32m:
2244 case X86_INC64m:
2245 case X86_INC8m:
2246
2247 // NEG
2248 case X86_NEG16m:
2249 case X86_NEG32m:
2250 case X86_NEG64m:
2251 case X86_NEG8m:
2252
2253 // NOT
2254 case X86_NOT16m:
2255 case X86_NOT32m:
2256 case X86_NOT64m:
2257 case X86_NOT8m:
2258
2259 // OR
2260 case X86_OR16mi:
2261 case X86_OR16mi8:
2262 case X86_OR16mr:
2263 case X86_OR32mi:
2264 case X86_OR32mi8:
2265 case X86_OR32mr:
2266 case X86_OR32mrLocked:
2267 case X86_OR64mi32:
2268 case X86_OR64mi8:
2269 case X86_OR64mr:
2270 case X86_OR8mi8:
2271 case X86_OR8mi:
2272 case X86_OR8mr:
2273
2274 // SBB
2275 case X86_SBB16mi:
2276 case X86_SBB16mi8:
2277 case X86_SBB16mr:
2278 case X86_SBB32mi:
2279 case X86_SBB32mi8:
2280 case X86_SBB32mr:
2281 case X86_SBB64mi32:
2282 case X86_SBB64mi8:
2283 case X86_SBB64mr:
2284 case X86_SBB8mi:
2285 case X86_SBB8mi8:
2286 case X86_SBB8mr:
2287
2288 // SUB
2289 case X86_SUB16mi:
2290 case X86_SUB16mi8:
2291 case X86_SUB16mr:
2292 case X86_SUB32mi:
2293 case X86_SUB32mi8:
2294 case X86_SUB32mr:
2295 case X86_SUB64mi32:
2296 case X86_SUB64mi8:
2297 case X86_SUB64mr:
2298 case X86_SUB8mi8:
2299 case X86_SUB8mi:
2300 case X86_SUB8mr:
2301
2302 // XADD
2303 case X86_XADD16rm:
2304 case X86_XADD32rm:
2305 case X86_XADD64rm:
2306 case X86_XADD8rm:
2307
2308 // XCHG
2309 case X86_XCHG16rm:
2310 case X86_XCHG32rm:
2311 case X86_XCHG64rm:
2312 case X86_XCHG8rm:
2313
2314 // XOR
2315 case X86_XOR16mi:
2316 case X86_XOR16mi8:
2317 case X86_XOR16mr:
2318 case X86_XOR32mi:
2319 case X86_XOR32mi8:
2320 case X86_XOR32mr:
2321 case X86_XOR64mi32:
2322 case X86_XOR64mi8:
2323 case X86_XOR64mr:
2324 case X86_XOR8mi8:
2325 case X86_XOR8mi:
2326 case X86_XOR8mr:
2327
2328 // this instruction can be used with LOCK prefix
2329 return false;
2330 }
2331 }
2332
2333 // REPNE prefix
2334 if (insn->isPrefixf2) {
2335 // 0xf2 can be a part of instruction encoding, but not really a prefix.
2336 // In such a case, clear it.
2337 if (insn->twoByteEscape == 0x0f) {
2338 insn->prefix0 = 0;
2339 }
2340 }
2341
2342 // no invalid prefixes
2343 return false;
2344 }
2345
2346 /*
2347 * decodeInstruction - Reads and interprets a full instruction provided by the
2348 * user.
2349 *
2350 * @param insn - A pointer to the instruction to be populated. Must be
2351 * pre-allocated.
2352 * @param reader - The function to be used to read the instruction's bytes.
2353 * @param readerArg - A generic argument to be passed to the reader to store
2354 * any internal state.
2355 * @param startLoc - The address (in the reader's address space) of the first
2356 * byte in the instruction.
2357 * @param mode - The mode (real mode, IA-32e, or IA-32e in 64-bit mode) to
2358 * decode the instruction in.
2359 * @return - 0 if instruction is valid; nonzero if not.
2360 */
decodeInstruction(struct InternalInstruction * insn,byteReader_t reader,const void * readerArg,uint64_t startLoc,DisassemblerMode mode)2361 int decodeInstruction(struct InternalInstruction *insn,
2362 byteReader_t reader,
2363 const void *readerArg,
2364 uint64_t startLoc,
2365 DisassemblerMode mode)
2366 {
2367 insn->reader = reader;
2368 insn->readerArg = readerArg;
2369 insn->startLocation = startLoc;
2370 insn->readerCursor = startLoc;
2371 insn->mode = mode;
2372
2373 if (readPrefixes(insn) ||
2374 readOpcode(insn) ||
2375 getID(insn) ||
2376 insn->instructionID == 0 ||
2377 checkPrefix(insn) ||
2378 readOperands(insn))
2379 return -1;
2380
2381 insn->length = (size_t)(insn->readerCursor - insn->startLocation);
2382
2383 // instruction length must be <= 15 to be valid
2384 if (insn->length > 15)
2385 return -1;
2386
2387 if (insn->operandSize == 0)
2388 insn->operandSize = insn->registerSize;
2389
2390 insn->operands = &x86OperandSets[insn->spec->operands][0];
2391
2392 // dbgprintf(insn, "Read from 0x%llx to 0x%llx: length %zu",
2393 // startLoc, insn->readerCursor, insn->length);
2394
2395 //if (insn->length > 15)
2396 // dbgprintf(insn, "Instruction exceeds 15-byte limit");
2397
2398 #if 0
2399 printf("\n>>> x86OperandSets = %lu\n", sizeof(x86OperandSets));
2400 printf(">>> x86DisassemblerInstrSpecifiers = %lu\n", sizeof(x86DisassemblerInstrSpecifiers));
2401 printf(">>> x86DisassemblerContexts = %lu\n", sizeof(x86DisassemblerContexts));
2402 printf(">>> modRMTable = %lu\n", sizeof(modRMTable));
2403 printf(">>> x86DisassemblerOneByteOpcodes = %lu\n", sizeof(x86DisassemblerOneByteOpcodes));
2404 printf(">>> x86DisassemblerTwoByteOpcodes = %lu\n", sizeof(x86DisassemblerTwoByteOpcodes));
2405 printf(">>> x86DisassemblerThreeByte38Opcodes = %lu\n", sizeof(x86DisassemblerThreeByte38Opcodes));
2406 printf(">>> x86DisassemblerThreeByte3AOpcodes = %lu\n", sizeof(x86DisassemblerThreeByte3AOpcodes));
2407 printf(">>> x86DisassemblerThreeByteA6Opcodes = %lu\n", sizeof(x86DisassemblerThreeByteA6Opcodes));
2408 printf(">>> x86DisassemblerThreeByteA7Opcodes= %lu\n", sizeof(x86DisassemblerThreeByteA7Opcodes));
2409 printf(">>> x86DisassemblerXOP8Opcodes = %lu\n", sizeof(x86DisassemblerXOP8Opcodes));
2410 printf(">>> x86DisassemblerXOP9Opcodes = %lu\n", sizeof(x86DisassemblerXOP9Opcodes));
2411 printf(">>> x86DisassemblerXOPAOpcodes = %lu\n\n", sizeof(x86DisassemblerXOPAOpcodes));
2412 #endif
2413
2414 return 0;
2415 }
2416
2417 #endif
2418
2419