X86DisassemblerDecoder.c
Go to the documentation of this file.
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 
36 struct ModRMDecision {
37  uint8_t modrm_type;
38  uint16_t instructionIDs;
39 };
40 
43 struct OpcodeDecision {
44  struct ModRMDecision modRMDecisions[256];
45 };
46 
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  */
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  */
94 static int modRMRequired(OpcodeType type,
95  InstructionContext insnContext,
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  */
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  */
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  */
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  */
298 static int lookAtByte(struct InternalInstruction *insn, uint8_t *byte)
299 {
300  return insn->reader(insn->readerArg, byte, insn->readerCursor);
301 }
302 
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  */
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  */
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  */
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 */
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 */
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 */
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 */
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 */
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 */
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 
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) {
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) {
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) {
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. */
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  */
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, &current))
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, &current))
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, &current))
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, &current))
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, &current))
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  */
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  */
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  */
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  */
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 &&
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  */
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  */
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  */
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  */
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;
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  */
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  */
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  */
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 |
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  */
2000 static int readMaskRegister(struct InternalInstruction *insn)
2001 {
2002  // dbgprintf(insn, "readMaskRegister()");
2003 
2004  if (insn->vectorExtensionType != TYPE_EVEX)
2005  return -1;
2006 
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  */
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:
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.
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  */
2361 int decodeInstruction(struct InternalInstruction *insn,
2363  const void *readerArg,
2364  uint64_t startLoc,
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 
TYPE_NO_VEX_XOP
@ TYPE_NO_VEX_XOP
Definition: X86DisassemblerDecoder.h:513
vvvvFromVEX3of3
#define vvvvFromVEX3of3(vex)
Definition: X86DisassemblerDecoder.h:64
bFromXOP2of3
#define bFromXOP2of3(xop)
Definition: X86DisassemblerDecoder.h:75
baseFromSIB
#define baseFromSIB(sib)
Definition: X86DisassemblerDecoder.h:38
MODE_16BIT
@ MODE_16BIT
Definition: X86DisassemblerDecoderCommon.h:512
InternalInstruction::modRMOffset
uint8_t modRMOffset
Definition: X86DisassemblerDecoder.h:617
InternalInstruction::displacementOffset
uint8_t displacementOffset
Definition: X86DisassemblerDecoder.h:615
DisassemblerMode
DisassemblerMode
Definition: X86DisassemblerDecoderCommon.h:511
xFromXOP2of3
#define xFromXOP2of3(xop)
Definition: X86DisassemblerDecoder.h:74
InternalInstruction::necessaryPrefixLocation
uint64_t necessaryPrefixLocation
Definition: X86DisassemblerDecoder.h:650
lFromVEX2of2
#define lFromVEX2of2(vex)
Definition: X86DisassemblerDecoder.h:70
InternalInstruction::prefix67
uint64_t prefix67
Definition: X86DisassemblerDecoder.h:582
OperandType
OperandType
Definition: X86DisassemblerDecoderCommon.h:489
wFromVEX3of3
#define wFromVEX3of3(vex)
Definition: X86DisassemblerDecoder.h:63
InternalInstruction::eaBaseBase
EABase eaBaseBase
Definition: X86DisassemblerDecoder.h:703
rFromEVEX2of4
#define rFromEVEX2of4(evex)
Definition: X86DisassemblerDecoder.h:44
InternalInstruction::isPrefixf0
bool isPrefixf0
Definition: X86DisassemblerDecoder.h:571
X86_MAX_OPERANDS
#define X86_MAX_OPERANDS
Definition: X86DisassemblerDecoderCommon.h:504
T3DNOW_MAP
@ T3DNOW_MAP
Definition: X86DisassemblerDecoderCommon.h:295
InternalInstruction::sibScale
uint8_t sibScale
Definition: X86DisassemblerDecoder.h:604
mmFromEVEX2of4
#define mmFromEVEX2of4(evex)
Definition: X86DisassemblerDecoder.h:48
ppFromXOP3of3
#define ppFromXOP3of3(xop)
Definition: X86DisassemblerDecoder.h:80
EA_DISP_NONE
@ EA_DISP_NONE
Definition: X86DisassemblerDecoder.h:457
InternalInstruction::isPrefixf2
bool isPrefixf2
Definition: X86DisassemblerDecoder.h:572
InternalInstruction::isPrefix26
bool isPrefix26
Definition: X86DisassemblerDecoder.h:563
InternalInstruction::prefix36
uint64_t prefix36
Definition: X86DisassemblerDecoder.h:577
CASE_ENCODING_RM
#define CASE_ENCODING_RM
Definition: X86DisassemblerDecoderCommon.h:343
VEX_LOB_0F38
@ VEX_LOB_0F38
Definition: X86DisassemblerDecoder.h:492
EA_DISP_32
@ EA_DISP_32
Definition: X86DisassemblerDecoder.h:460
InternalInstruction::length
size_t length
Definition: X86DisassemblerDecoder.h:641
InternalInstruction::reg
Reg reg
Definition: X86DisassemblerDecoder.h:712
InternalInstruction::consumedDisplacement
bool consumedDisplacement
Definition: X86DisassemblerDecoder.h:596
mmmmmFromVEX2of3
#define mmmmmFromVEX2of3(vex)
Definition: X86DisassemblerDecoder.h:62
uint16_t
unsigned short uint16_t
Definition: stdint-msvc2008.h:79
InternalInstruction::prefix64
uint64_t prefix64
Definition: X86DisassemblerDecoder.h:579
EA_DISP_16
@ EA_DISP_16
Definition: X86DisassemblerDecoder.h:459
InternalInstruction::startLocation
uint64_t startLocation
Definition: X86DisassemblerDecoder.h:639
ppFromVEX2of2
#define ppFromVEX2of2(vex)
Definition: X86DisassemblerDecoder.h:71
EA_DISP_8
@ EA_DISP_8
Definition: X86DisassemblerDecoder.h:458
THREEBYTE_3A
@ THREEBYTE_3A
Definition: X86DisassemblerDecoderCommon.h:291
InternalInstruction::prefix26
uint64_t prefix26
Definition: X86DisassemblerDecoder.h:575
modFromModRM
#define modFromModRM(modRM)
Definition: X86DisassemblerDecoder.h:33
scaleFromSIB
#define scaleFromSIB(sib)
Definition: X86DisassemblerDecoder.h:36
OperandSpecifier
Definition: X86DisassemblerDecoderCommon.h:499
printf
_Use_decl_annotations_ int __cdecl printf(const char *_Format,...)
Definition: cs_driver.c:91
InternalInstruction::segmentOverride
SegmentOverride segmentOverride
Definition: X86DisassemblerDecoder.h:589
InternalInstruction::prefix2
uint8_t prefix2
Definition: X86DisassemblerDecoder.h:561
rFromXOP2of3
#define rFromXOP2of3(xop)
Definition: X86DisassemblerDecoder.h:73
X86DisassemblerDecoder.h
rFromVEX2of3
#define rFromVEX2of3(vex)
Definition: X86DisassemblerDecoder.h:59
InternalInstruction::rexPrefix
uint8_t rexPrefix
Definition: X86DisassemblerDecoder.h:587
vvvvFromVEX2of2
#define vvvvFromVEX2of2(vex)
Definition: X86DisassemblerDecoder.h:69
XOPA_MAP
@ XOPA_MAP
Definition: X86DisassemblerDecoderCommon.h:294
InternalInstruction::vectorExtensionType
VectorExtensionType vectorExtensionType
Definition: X86DisassemblerDecoder.h:646
mode
const char int mode
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:135
InternalInstruction::addressSize
uint8_t addressSize
Definition: X86DisassemblerDecoder.h:654
InternalInstruction::opcode
uint8_t opcode
Definition: X86DisassemblerDecoder.h:663
rFromVEX2of2
#define rFromVEX2of2(vex)
Definition: X86DisassemblerDecoder.h:68
InternalInstruction::readerArg
const void * readerArg
Definition: X86DisassemblerDecoder.h:625
second
StrT second
Definition: cxa_demangle.cpp:4885
OpcodeType
OpcodeType
Definition: X86DisassemblerDecoderCommon.h:287
uint8_t
unsigned char uint8_t
Definition: stdint-msvc2008.h:78
bFromREX
#define bFromREX(rex)
Definition: X86DisassemblerDecoder.h:42
InternalInstruction::isPrefixf3
bool isPrefixf3
Definition: X86DisassemblerDecoder.h:573
TYPE_XOP
@ TYPE_XOP
Definition: X86DisassemblerDecoder.h:517
run_interop_tests.spec
def spec
Definition: run_interop_tests.py:1394
xFromREX
#define xFromREX(rex)
Definition: X86DisassemblerDecoder.h:41
SEG_OVERRIDE_DS
@ SEG_OVERRIDE_DS
Definition: X86DisassemblerDecoder.h:480
r2FromEVEX2of4
#define r2FromEVEX2of4(evex)
Definition: X86DisassemblerDecoder.h:47
IC_max
@ IC_max
Definition: X86DisassemblerDecoderCommon.h:279
lFromVEX3of3
#define lFromVEX3of3(vex)
Definition: X86DisassemblerDecoder.h:65
InternalInstruction::prefix3
uint8_t prefix3
Definition: X86DisassemblerDecoder.h:561
wFromEVEX3of4
#define wFromEVEX3of4(evex)
Definition: X86DisassemblerDecoder.h:49
uint32_t
unsigned int uint32_t
Definition: stdint-msvc2008.h:80
InternalInstruction::xAcquireRelease
bool xAcquireRelease
Definition: X86DisassemblerDecoder.h:608
VEX_PREFIX_66
@ VEX_PREFIX_66
Definition: X86DisassemblerDecoder.h:507
InternalInstruction::displacementSize
uint8_t displacementSize
Definition: X86DisassemblerDecoder.h:655
vvvvFromEVEX3of4
#define vvvvFromEVEX3of4(evex)
Definition: X86DisassemblerDecoder.h:50
ONEBYTE
@ ONEBYTE
Definition: X86DisassemblerDecoderCommon.h:288
XOP8_MAP_SYM
#define XOP8_MAP_SYM
Definition: X86DisassemblerDecoderCommon.h:34
InternalInstruction::vectorExtensionPrefix
uint8_t vectorExtensionPrefix[4]
Definition: X86DisassemblerDecoder.h:611
SEG_OVERRIDE_CS
@ SEG_OVERRIDE_CS
Definition: X86DisassemblerDecoder.h:478
InternalInstruction::prefix0
uint8_t prefix0
Definition: X86DisassemblerDecoder.h:561
int16_t
signed short int16_t
Definition: stdint-msvc2008.h:76
TYPE_VEX_2B
@ TYPE_VEX_2B
Definition: X86DisassemblerDecoder.h:514
InternalInstruction::prefixf0
uint64_t prefixf0
Definition: X86DisassemblerDecoder.h:583
ppFromVEX3of3
#define ppFromVEX3of3(vex)
Definition: X86DisassemblerDecoder.h:66
int64_t
signed __int64 int64_t
Definition: stdint-msvc2008.h:89
InstructionSpecifier
Definition: X86DisassemblerDecoder.h:551
InternalInstruction::reader
byteReader_t reader
Definition: X86DisassemblerDecoder.h:622
T3DNOW_MAP_SYM
#define T3DNOW_MAP_SYM
Definition: X86DisassemblerDecoderCommon.h:37
InternalInstruction::isPrefix65
bool isPrefix65
Definition: X86DisassemblerDecoder.h:568
InternalInstruction::numImmediatesConsumed
uint8_t numImmediatesConsumed
Definition: X86DisassemblerDecoder.h:606
bFromVEX2of3
#define bFromVEX2of3(vex)
Definition: X86DisassemblerDecoder.h:61
wFromREX
#define wFromREX(rex)
Definition: X86DisassemblerDecoder.h:39
InternalInstruction::instructionID
uint16_t instructionID
Definition: X86DisassemblerDecoder.h:670
InternalInstruction
Definition: X86DisassemblerDecoder.h:558
InternalInstruction::isPrefix67
bool isPrefix67
Definition: X86DisassemblerDecoder.h:570
InternalInstruction::prefix66
uint64_t prefix66
Definition: X86DisassemblerDecoder.h:581
InternalInstruction::immediates
uint64_t immediates[2]
Definition: X86DisassemblerDecoder.h:694
InternalInstruction::opcodeRegister
Reg opcodeRegister
Definition: X86DisassemblerDecoder.h:697
ONEBYTE_SYM
#define ONEBYTE_SYM
Definition: X86DisassemblerDecoderCommon.h:30
uint64_t
unsigned __int64 uint64_t
Definition: stdint-msvc2008.h:90
CONTEXTS_SYM
#define CONTEXTS_SYM
Definition: X86DisassemblerDecoderCommon.h:29
InternalInstruction::registerSize
uint8_t registerSize
Definition: X86DisassemblerDecoder.h:653
SEG_OVERRIDE_FS
@ SEG_OVERRIDE_FS
Definition: X86DisassemblerDecoder.h:482
valid
@ valid
Definition: base64_test.cc:37
InstructionSpecifier::operands
uint16_t operands
Definition: X86DisassemblerDecoder.h:552
lFromXOP3of3
#define lFromXOP3of3(xop)
Definition: X86DisassemblerDecoder.h:79
regFromModRM
#define regFromModRM(modRM)
Definition: X86DisassemblerDecoder.h:34
InternalInstruction::vvvv
Reg vvvv
Definition: X86DisassemblerDecoder.h:680
MODE_32BIT
@ MODE_32BIT
Definition: X86DisassemblerDecoderCommon.h:513
InternalInstruction::modRM
uint8_t modRM
Definition: X86DisassemblerDecoder.h:687
XOP_MAP_SELECT_8
@ XOP_MAP_SELECT_8
Definition: X86DisassemblerDecoder.h:497
gen_synthetic_protos.base
base
Definition: gen_synthetic_protos.py:31
VEX_PREFIX_F3
@ VEX_PREFIX_F3
Definition: X86DisassemblerDecoder.h:508
vvvvFromXOP3of3
#define vvvvFromXOP3of3(vex)
Definition: X86DisassemblerDecoder.h:78
rm
static bool rm(upb_table *t, lookupkey_t key, upb_value *val, upb_tabkey *removed, uint32_t hash, eqlfunc_t *eql)
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.c:1477
mmmmmFromXOP2of3
#define mmmmmFromXOP2of3(xop)
Definition: X86DisassemblerDecoder.h:76
ppFromEVEX3of4
#define ppFromEVEX3of4(evex)
Definition: X86DisassemblerDecoder.h:51
rmFromModRM
#define rmFromModRM(modRM)
Definition: X86DisassemblerDecoder.h:35
SIB_BASE_NONE
@ SIB_BASE_NONE
Definition: X86DisassemblerDecoder.h:445
InternalInstruction::orgModRM
uint8_t orgModRM
Definition: X86DisassemblerDecoder.h:591
setup.idx
idx
Definition: third_party/bloaty/third_party/capstone/bindings/python/setup.py:197
InternalInstruction::eaRegBase
EABase eaRegBase
Definition: X86DisassemblerDecoder.h:704
MODE_64BIT
@ MODE_64BIT
Definition: X86DisassemblerDecoderCommon.h:514
InternalInstruction::readerCursor
uint64_t readerCursor
Definition: X86DisassemblerDecoder.h:627
InternalInstruction::opcodeType
OpcodeType opcodeType
Definition: X86DisassemblerDecoder.h:668
InternalInstruction::threeByteEscape
uint8_t threeByteEscape
Definition: X86DisassemblerDecoder.h:601
InternalInstruction::twoByteEscape
uint8_t twoByteEscape
Definition: X86DisassemblerDecoder.h:599
InternalInstruction::writemask
Reg writemask
Definition: X86DisassemblerDecoder.h:683
zFromEVEX4of4
#define zFromEVEX4of4(evex)
Definition: X86DisassemblerDecoder.h:52
InternalInstruction::prefixf3
uint64_t prefixf3
Definition: X86DisassemblerDecoder.h:585
InternalInstruction::immSize
uint8_t immSize
Definition: X86DisassemblerDecoder.h:658
InternalInstruction::operands
const struct OperandSpecifier * operands
Definition: X86DisassemblerDecoder.h:714
ares::byte
unsigned char byte
Definition: ares-test.h:33
InternalInstruction::immediateOffset
uint8_t immediateOffset
Definition: X86DisassemblerDecoder.h:616
SIBIndex
SIBIndex
Definition: X86DisassemblerDecoder.h:430
InternalInstruction::isPrefix2e
bool isPrefix2e
Definition: X86DisassemblerDecoder.h:564
bFromEVEX2of4
#define bFromEVEX2of4(evex)
Definition: X86DisassemblerDecoder.h:46
InternalInstruction::displacement
int64_t displacement
Definition: X86DisassemblerDecoder.h:597
XOP9_MAP
@ XOP9_MAP
Definition: X86DisassemblerDecoderCommon.h:293
VEX_LOB_0F
@ VEX_LOB_0F
Definition: X86DisassemblerDecoder.h:491
SEG_OVERRIDE_ES
@ SEG_OVERRIDE_ES
Definition: X86DisassemblerDecoder.h:481
TWOBYTE
@ TWOBYTE
Definition: X86DisassemblerDecoderCommon.h:289
InstructionContext
InstructionContext
Definition: X86DisassemblerDecoderCommon.h:277
rFromREX
#define rFromREX(rex)
Definition: X86DisassemblerDecoder.h:40
TYPE_EVEX
@ TYPE_EVEX
Definition: X86DisassemblerDecoder.h:516
TWOBYTE_SYM
#define TWOBYTE_SYM
Definition: X86DisassemblerDecoderCommon.h:31
v2FromEVEX4of4
#define v2FromEVEX4of4(evex)
Definition: X86DisassemblerDecoder.h:56
x86
Definition: test_winkernel.cpp:83
aaaFromEVEX4of4
#define aaaFromEVEX4of4(evex)
Definition: X86DisassemblerDecoder.h:57
index
int index
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/protobuf.h:1184
ret
UniquePtr< SSL_SESSION > ret
Definition: ssl_x509.cc:1029
EA_BASE_NONE
@ EA_BASE_NONE
Definition: X86DisassemblerDecoder.h:414
InternalInstruction::regBase
Reg regBase
Definition: X86DisassemblerDecoder.h:705
InternalInstruction::sibBase
SIBBase sibBase
Definition: X86DisassemblerDecoder.h:605
XOPA_MAP_SYM
#define XOPA_MAP_SYM
Definition: X86DisassemblerDecoderCommon.h:36
grpc._common.decode
def decode(b)
Definition: grpc/_common.py:75
THREEBYTE38_SYM
#define THREEBYTE38_SYM
Definition: X86DisassemblerDecoderCommon.h:32
SIB_INDEX_NONE
@ SIB_INDEX_NONE
Definition: X86DisassemblerDecoder.h:431
XOP_MAP_SELECT_9
@ XOP_MAP_SELECT_9
Definition: X86DisassemblerDecoder.h:498
XOP9_MAP_SYM
#define XOP9_MAP_SYM
Definition: X86DisassemblerDecoderCommon.h:35
prefix
static const char prefix[]
Definition: head_of_line_blocking.cc:28
TYPE_VEX_3B
@ TYPE_VEX_3B
Definition: X86DisassemblerDecoder.h:515
EABase
EABase
Definition: X86DisassemblerDecoder.h:413
lFromEVEX4of4
#define lFromEVEX4of4(evex)
Definition: X86DisassemblerDecoder.h:54
InternalInstruction::prefix2e
uint64_t prefix2e
Definition: X86DisassemblerDecoder.h:576
InternalInstruction::operandSize
uint8_t operandSize
Definition: X86DisassemblerDecoder.h:560
OperandEncoding
OperandEncoding
Definition: X86DisassemblerDecoderCommon.h:393
InternalInstruction::mode
DisassemblerMode mode
Definition: X86DisassemblerDecoder.h:637
InternalInstruction::prefix1
uint8_t prefix1
Definition: X86DisassemblerDecoder.h:561
wFromXOP3of3
#define wFromXOP3of3(xop)
Definition: X86DisassemblerDecoder.h:77
InternalInstruction::prefix3e
uint64_t prefix3e
Definition: X86DisassemblerDecoder.h:578
Reg
Reg
Definition: X86DisassemblerDecoder.h:466
THREEBYTE3A_SYM
#define THREEBYTE3A_SYM
Definition: X86DisassemblerDecoderCommon.h:33
InternalInstruction::sibIndex
SIBIndex sibIndex
Definition: X86DisassemblerDecoder.h:603
SEG_OVERRIDE_GS
@ SEG_OVERRIDE_GS
Definition: X86DisassemblerDecoder.h:483
InternalInstruction::firstByte
uint8_t firstByte
Definition: X86DisassemblerDecoder.h:690
XOP_MAP_SELECT_A
@ XOP_MAP_SELECT_A
Definition: X86DisassemblerDecoder.h:499
l2FromEVEX4of4
#define l2FromEVEX4of4(evex)
Definition: X86DisassemblerDecoder.h:53
INSTRUCTIONS_SYM
#define INSTRUCTIONS_SYM
Definition: X86DisassemblerDecoderCommon.h:28
int8_t
signed char int8_t
Definition: stdint-msvc2008.h:75
asyncio_get_stats.type
type
Definition: asyncio_get_stats.py:37
byteReader_t
int(* byteReader_t)(const struct reader_info *arg, uint8_t *byte, uint64_t address)
Definition: X86DisassemblerDecoder.h:537
InternalInstruction::consumedModRM
bool consumedModRM
Definition: X86DisassemblerDecoder.h:590
InternalInstruction::immediateSize
uint8_t immediateSize
Definition: X86DisassemblerDecoder.h:656
InternalInstruction::eaDisplacement
EADisplacement eaDisplacement
Definition: X86DisassemblerDecoder.h:710
InternalInstruction::spec
const struct InstructionSpecifier * spec
Definition: X86DisassemblerDecoder.h:672
VEX_LOB_0F3A
@ VEX_LOB_0F3A
Definition: X86DisassemblerDecoder.h:493
size
voidpf void uLong size
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:136
InternalInstruction::consumedSIB
bool consumedSIB
Definition: X86DisassemblerDecoder.h:593
InternalInstruction::prefixf2
uint64_t prefixf2
Definition: X86DisassemblerDecoder.h:584
InternalInstruction::isPrefix36
bool isPrefix36
Definition: X86DisassemblerDecoder.h:565
bFromEVEX4of4
#define bFromEVEX4of4(evex)
Definition: X86DisassemblerDecoder.h:55
int32_t
signed int int32_t
Definition: stdint-msvc2008.h:77
xFromEVEX2of4
#define xFromEVEX2of4(evex)
Definition: X86DisassemblerDecoder.h:45
InternalInstruction::isPrefix3e
bool isPrefix3e
Definition: X86DisassemblerDecoder.h:566
xFromVEX2of3
#define xFromVEX2of3(vex)
Definition: X86DisassemblerDecoder.h:60
SEG_OVERRIDE_SS
@ SEG_OVERRIDE_SS
Definition: X86DisassemblerDecoder.h:479
opcode
opcode
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/upb.h:6290
XOP8_MAP
@ XOP8_MAP
Definition: X86DisassemblerDecoderCommon.h:292
op
static grpc_op * op
Definition: test/core/fling/client.cc:47
indexFromSIB
#define indexFromSIB(sib)
Definition: X86DisassemblerDecoder.h:37
InternalInstruction::isPrefix64
bool isPrefix64
Definition: X86DisassemblerDecoder.h:567
InternalInstruction::sib
uint8_t sib
Definition: X86DisassemblerDecoder.h:594
InternalInstruction::eaBase
EABase eaBase
Definition: X86DisassemblerDecoder.h:709
SIBBase
SIBBase
Definition: X86DisassemblerDecoder.h:444
reader
void reader(void *n)
Definition: libuv/docs/code/locks/main.c:8
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230
decodeInstruction
int decodeInstruction(struct InternalInstruction *insn, byteReader_t reader, const void *readerArg, uint64_t startLoc, DisassemblerMode mode)
THREEBYTE_38
@ THREEBYTE_38
Definition: X86DisassemblerDecoderCommon.h:290
InternalInstruction::isPrefix66
bool isPrefix66
Definition: X86DisassemblerDecoder.h:569
id
uint32_t id
Definition: flow_control_fuzzer.cc:70
InternalInstruction::prefix65
uint64_t prefix65
Definition: X86DisassemblerDecoder.h:580
VEX_PREFIX_F2
@ VEX_PREFIX_F2
Definition: X86DisassemblerDecoder.h:509
ARR_SIZE
#define ARR_SIZE(a)
Definition: ocaml.c:13
InstrUID
uint16_t InstrUID
Definition: X86DisassemblerDecoderCommon.h:308


grpc
Author(s):
autogenerated on Thu Mar 13 2025 03:01:54