Rizin
unix-like reverse engineering framework and cli tools
X86ATTInstPrinter.c
Go to the documentation of this file.
1 //===-- X86ATTInstPrinter.cpp - AT&T assembly instruction printing --------===//
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 includes code for rendering MCInst instances as AT&T-style
11 // assembly.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 /* Capstone Disassembly Engine */
16 /* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2015 */
17 
18 // this code is only relevant when DIET mode is disable
19 #if defined(CAPSTONE_HAS_X86) && !defined(CAPSTONE_DIET) && !defined(CAPSTONE_X86_ATT_DISABLE)
20 
21 #if defined (WIN32) || defined (WIN64) || defined (_WIN32) || defined (_WIN64)
22 #pragma warning(disable:4996) // disable MSVC's warning on strncpy()
23 #pragma warning(disable:28719) // disable MSVC's warning on strncpy()
24 #endif
25 
26 #if !defined(CAPSTONE_HAS_OSXKERNEL)
27 #include <ctype.h>
28 #endif
29 #include <capstone/platform.h>
30 
31 #if defined(CAPSTONE_HAS_OSXKERNEL)
32 #include <Availability.h>
33 #include <libkern/libkern.h>
34 #else
35 #include <stdio.h>
36 #include <stdlib.h>
37 #endif
38 
39 #include <string.h>
40 
41 #include "../../utils.h"
42 #include "../../MCInst.h"
43 #include "../../SStream.h"
44 #include "../../MCRegisterInfo.h"
45 #include "X86Mapping.h"
46 #include "X86BaseInfo.h"
47 
48 
49 #define GET_INSTRINFO_ENUM
50 #ifdef CAPSTONE_X86_REDUCE
52 #else
53 #include "X86GenInstrInfo.inc"
54 #endif
55 
56 static void printMemReference(MCInst *MI, unsigned Op, SStream *O);
57 static void printOperand(MCInst *MI, unsigned OpNo, SStream *O);
58 
59 
60 static void set_mem_access(MCInst *MI, bool status)
61 {
62  if (MI->csh->detail != CS_OPT_ON)
63  return;
64 
65  MI->csh->doing_mem = status;
66  if (!status)
67  // done, create the next operand slot
68  MI->flat_insn->detail->x86.op_count++;
69 }
70 
71 static void printopaquemem(MCInst *MI, unsigned OpNo, SStream *O)
72 {
73  switch(MI->csh->mode) {
74  case CS_MODE_16:
75  switch(MI->flat_insn->id) {
76  default:
77  MI->x86opsize = 2;
78  break;
79  case X86_INS_LJMP:
80  case X86_INS_LCALL:
81  MI->x86opsize = 4;
82  break;
83  case X86_INS_SGDT:
84  case X86_INS_SIDT:
85  case X86_INS_LGDT:
86  case X86_INS_LIDT:
87  MI->x86opsize = 6;
88  break;
89  }
90  break;
91  case CS_MODE_32:
92  switch(MI->flat_insn->id) {
93  default:
94  MI->x86opsize = 4;
95  break;
96  case X86_INS_LJMP:
97  case X86_INS_LCALL:
98  case X86_INS_SGDT:
99  case X86_INS_SIDT:
100  case X86_INS_LGDT:
101  case X86_INS_LIDT:
102  MI->x86opsize = 6;
103  break;
104  }
105  break;
106  case CS_MODE_64:
107  switch(MI->flat_insn->id) {
108  default:
109  MI->x86opsize = 8;
110  break;
111  case X86_INS_LJMP:
112  case X86_INS_LCALL:
113  case X86_INS_SGDT:
114  case X86_INS_SIDT:
115  case X86_INS_LGDT:
116  case X86_INS_LIDT:
117  MI->x86opsize = 10;
118  break;
119  }
120  break;
121  default: // never reach
122  break;
123  }
124 
125  printMemReference(MI, OpNo, O);
126 }
127 
128 static void printi8mem(MCInst *MI, unsigned OpNo, SStream *O)
129 {
130  MI->x86opsize = 1;
131  printMemReference(MI, OpNo, O);
132 }
133 
134 static void printi16mem(MCInst *MI, unsigned OpNo, SStream *O)
135 {
136  MI->x86opsize = 2;
137 
138  printMemReference(MI, OpNo, O);
139 }
140 
141 static void printi32mem(MCInst *MI, unsigned OpNo, SStream *O)
142 {
143  MI->x86opsize = 4;
144 
145  printMemReference(MI, OpNo, O);
146 }
147 
148 static void printi64mem(MCInst *MI, unsigned OpNo, SStream *O)
149 {
150  MI->x86opsize = 8;
151  printMemReference(MI, OpNo, O);
152 }
153 
154 static void printi128mem(MCInst *MI, unsigned OpNo, SStream *O)
155 {
156  MI->x86opsize = 16;
157  printMemReference(MI, OpNo, O);
158 }
159 
160 #ifndef CAPSTONE_X86_REDUCE
161 static void printi256mem(MCInst *MI, unsigned OpNo, SStream *O)
162 {
163  MI->x86opsize = 32;
164  printMemReference(MI, OpNo, O);
165 }
166 
167 static void printi512mem(MCInst *MI, unsigned OpNo, SStream *O)
168 {
169  MI->x86opsize = 64;
170  printMemReference(MI, OpNo, O);
171 }
172 
173 static void printf32mem(MCInst *MI, unsigned OpNo, SStream *O)
174 {
175  switch(MCInst_getOpcode(MI)) {
176  default:
177  MI->x86opsize = 4;
178  break;
179  case X86_FBSTPm:
180  case X86_FBLDm:
181  // TODO: fix this in tablegen instead
182  MI->x86opsize = 10;
183  break;
184  case X86_FSTENVm:
185  case X86_FLDENVm:
186  // TODO: fix this in tablegen instead
187  switch(MI->csh->mode) {
188  default: // never reach
189  break;
190  case CS_MODE_16:
191  MI->x86opsize = 14;
192  break;
193  case CS_MODE_32:
194  case CS_MODE_64:
195  MI->x86opsize = 28;
196  break;
197  }
198  break;
199  }
200 
201  printMemReference(MI, OpNo, O);
202 }
203 
204 static void printf64mem(MCInst *MI, unsigned OpNo, SStream *O)
205 {
206  MI->x86opsize = 8;
207  printMemReference(MI, OpNo, O);
208 }
209 
210 static void printf80mem(MCInst *MI, unsigned OpNo, SStream *O)
211 {
212  MI->x86opsize = 10;
213  printMemReference(MI, OpNo, O);
214 }
215 
216 static void printf128mem(MCInst *MI, unsigned OpNo, SStream *O)
217 {
218  MI->x86opsize = 16;
219  printMemReference(MI, OpNo, O);
220 }
221 
222 static void printf256mem(MCInst *MI, unsigned OpNo, SStream *O)
223 {
224  MI->x86opsize = 32;
225  printMemReference(MI, OpNo, O);
226 }
227 
228 static void printf512mem(MCInst *MI, unsigned OpNo, SStream *O)
229 {
230  MI->x86opsize = 64;
231  printMemReference(MI, OpNo, O);
232 }
233 
234 static void printSSECC(MCInst *MI, unsigned Op, SStream *OS)
235 {
236  uint8_t Imm = (uint8_t)(MCOperand_getImm(MCInst_getOperand(MI, Op)) & 7);
237  switch (Imm) {
238  default: break; // never reach
239  case 0: SStream_concat0(OS, "eq"); op_addSseCC(MI, X86_SSE_CC_EQ); break;
240  case 1: SStream_concat0(OS, "lt"); op_addSseCC(MI, X86_SSE_CC_LT); break;
241  case 2: SStream_concat0(OS, "le"); op_addSseCC(MI, X86_SSE_CC_LE); break;
242  case 3: SStream_concat0(OS, "unord"); op_addSseCC(MI, X86_SSE_CC_UNORD); break;
243  case 4: SStream_concat0(OS, "neq"); op_addSseCC(MI, X86_SSE_CC_NEQ); break;
244  case 5: SStream_concat0(OS, "nlt"); op_addSseCC(MI, X86_SSE_CC_NLT); break;
245  case 6: SStream_concat0(OS, "nle"); op_addSseCC(MI, X86_SSE_CC_NLE); break;
246  case 7: SStream_concat0(OS, "ord"); op_addSseCC(MI, X86_SSE_CC_ORD); break;
247  }
248 
249  MI->popcode_adjust = Imm + 1;
250 }
251 
252 static void printAVXCC(MCInst *MI, unsigned Op, SStream *O)
253 {
254  uint8_t Imm = (uint8_t)(MCOperand_getImm(MCInst_getOperand(MI, Op)) & 0x1f);
255  switch (Imm) {
256  default: break;//printf("Invalid avxcc argument!\n"); break;
257  case 0: SStream_concat0(O, "eq"); op_addAvxCC(MI, X86_AVX_CC_EQ); break;
258  case 1: SStream_concat0(O, "lt"); op_addAvxCC(MI, X86_AVX_CC_LT); break;
259  case 2: SStream_concat0(O, "le"); op_addAvxCC(MI, X86_AVX_CC_LE); break;
260  case 3: SStream_concat0(O, "unord"); op_addAvxCC(MI, X86_AVX_CC_UNORD); break;
261  case 4: SStream_concat0(O, "neq"); op_addAvxCC(MI, X86_AVX_CC_NEQ); break;
262  case 5: SStream_concat0(O, "nlt"); op_addAvxCC(MI, X86_AVX_CC_NLT); break;
263  case 6: SStream_concat0(O, "nle"); op_addAvxCC(MI, X86_AVX_CC_NLE); break;
264  case 7: SStream_concat0(O, "ord"); op_addAvxCC(MI, X86_AVX_CC_ORD); break;
265  case 8: SStream_concat0(O, "eq_uq"); op_addAvxCC(MI, X86_AVX_CC_EQ_UQ); break;
266  case 9: SStream_concat0(O, "nge"); op_addAvxCC(MI, X86_AVX_CC_NGE); break;
267  case 0xa: SStream_concat0(O, "ngt"); op_addAvxCC(MI, X86_AVX_CC_NGT); break;
268  case 0xb: SStream_concat0(O, "false"); op_addAvxCC(MI, X86_AVX_CC_FALSE); break;
269  case 0xc: SStream_concat0(O, "neq_oq"); op_addAvxCC(MI, X86_AVX_CC_NEQ_OQ); break;
270  case 0xd: SStream_concat0(O, "ge"); op_addAvxCC(MI, X86_AVX_CC_GE); break;
271  case 0xe: SStream_concat0(O, "gt"); op_addAvxCC(MI, X86_AVX_CC_GT); break;
272  case 0xf: SStream_concat0(O, "true"); op_addAvxCC(MI, X86_AVX_CC_TRUE); break;
273  case 0x10: SStream_concat0(O, "eq_os"); op_addAvxCC(MI, X86_AVX_CC_EQ_OS); break;
274  case 0x11: SStream_concat0(O, "lt_oq"); op_addAvxCC(MI, X86_AVX_CC_LT_OQ); break;
275  case 0x12: SStream_concat0(O, "le_oq"); op_addAvxCC(MI, X86_AVX_CC_LE_OQ); break;
276  case 0x13: SStream_concat0(O, "unord_s"); op_addAvxCC(MI, X86_AVX_CC_UNORD_S); break;
277  case 0x14: SStream_concat0(O, "neq_us"); op_addAvxCC(MI, X86_AVX_CC_NEQ_US); break;
278  case 0x15: SStream_concat0(O, "nlt_uq"); op_addAvxCC(MI, X86_AVX_CC_NLT_UQ); break;
279  case 0x16: SStream_concat0(O, "nle_uq"); op_addAvxCC(MI, X86_AVX_CC_NLE_UQ); break;
280  case 0x17: SStream_concat0(O, "ord_s"); op_addAvxCC(MI, X86_AVX_CC_ORD_S); break;
281  case 0x18: SStream_concat0(O, "eq_us"); op_addAvxCC(MI, X86_AVX_CC_EQ_US); break;
282  case 0x19: SStream_concat0(O, "nge_uq"); op_addAvxCC(MI, X86_AVX_CC_NGE_UQ); break;
283  case 0x1a: SStream_concat0(O, "ngt_uq"); op_addAvxCC(MI, X86_AVX_CC_NGT_UQ); break;
284  case 0x1b: SStream_concat0(O, "false_os"); op_addAvxCC(MI, X86_AVX_CC_FALSE_OS); break;
285  case 0x1c: SStream_concat0(O, "neq_os"); op_addAvxCC(MI, X86_AVX_CC_NEQ_OS); break;
286  case 0x1d: SStream_concat0(O, "ge_oq"); op_addAvxCC(MI, X86_AVX_CC_GE_OQ); break;
287  case 0x1e: SStream_concat0(O, "gt_oq"); op_addAvxCC(MI, X86_AVX_CC_GT_OQ); break;
288  case 0x1f: SStream_concat0(O, "true_us"); op_addAvxCC(MI, X86_AVX_CC_TRUE_US); break;
289  }
290 
291  MI->popcode_adjust = Imm + 1;
292 }
293 
294 static void printXOPCC(MCInst *MI, unsigned Op, SStream *O)
295 {
297 
298  switch (Imm) {
299  default: // llvm_unreachable("Invalid xopcc argument!");
300  case 0: SStream_concat0(O, "lt"); op_addXopCC(MI, X86_XOP_CC_LT); break;
301  case 1: SStream_concat0(O, "le"); op_addXopCC(MI, X86_XOP_CC_LE); break;
302  case 2: SStream_concat0(O, "gt"); op_addXopCC(MI, X86_XOP_CC_GT); break;
303  case 3: SStream_concat0(O, "ge"); op_addXopCC(MI, X86_XOP_CC_GE); break;
304  case 4: SStream_concat0(O, "eq"); op_addXopCC(MI, X86_XOP_CC_EQ); break;
305  case 5: SStream_concat0(O, "neq"); op_addXopCC(MI, X86_XOP_CC_NEQ); break;
306  case 6: SStream_concat0(O, "false"); op_addXopCC(MI, X86_XOP_CC_FALSE); break;
307  case 7: SStream_concat0(O, "true"); op_addXopCC(MI, X86_XOP_CC_TRUE); break;
308  }
309 }
310 
311 static void printRoundingControl(MCInst *MI, unsigned Op, SStream *O)
312 {
313  int64_t Imm = MCOperand_getImm(MCInst_getOperand(MI, Op)) & 0x3;
314  switch (Imm) {
315  case 0: SStream_concat0(O, "{rn-sae}"); op_addAvxSae(MI); op_addAvxRoundingMode(MI, X86_AVX_RM_RN); break;
316  case 1: SStream_concat0(O, "{rd-sae}"); op_addAvxSae(MI); op_addAvxRoundingMode(MI, X86_AVX_RM_RD); break;
317  case 2: SStream_concat0(O, "{ru-sae}"); op_addAvxSae(MI); op_addAvxRoundingMode(MI, X86_AVX_RM_RU); break;
318  case 3: SStream_concat0(O, "{rz-sae}"); op_addAvxSae(MI); op_addAvxRoundingMode(MI, X86_AVX_RM_RZ); break;
319  default: break; // nev0er reach
320  }
321 }
322 
323 #endif
324 
325 static void printRegName(SStream *OS, unsigned RegNo);
326 
327 // local printOperand, without updating public operands
328 static void _printOperand(MCInst *MI, unsigned OpNo, SStream *O)
329 {
330  MCOperand *Op = MCInst_getOperand(MI, OpNo);
331  if (MCOperand_isReg(Op)) {
332  printRegName(O, MCOperand_getReg(Op));
333  } else if (MCOperand_isImm(Op)) {
334  // Print X86 immediates as signed values.
336  uint8_t encsize;
337  uint8_t opsize = X86_immediate_size(MCInst_getOpcode(MI), &encsize);
338 
339  if (imm < 0) {
340  if (MI->csh->imm_unsigned) {
341  if (opsize) {
342  switch(opsize) {
343  default:
344  break;
345  case 1:
346  imm &= 0xff;
347  break;
348  case 2:
349  imm &= 0xffff;
350  break;
351  case 4:
352  imm &= 0xffffffff;
353  break;
354  }
355  }
356 
357  SStream_concat(O, "$0x%"PRIx64, imm);
358  } else {
359  if (imm < -HEX_THRESHOLD)
360  SStream_concat(O, "$-0x%"PRIx64, -imm);
361  else
362  SStream_concat(O, "$-%"PRIu64, -imm);
363  }
364  } else {
365  if (imm > HEX_THRESHOLD)
366  SStream_concat(O, "$0x%"PRIx64, imm);
367  else
368  SStream_concat(O, "$%"PRIu64, imm);
369  }
370  }
371 }
372 
373 // convert Intel access info to AT&T access info
374 static void get_op_access(cs_struct *h, unsigned int id, uint8_t *access, uint64_t *eflags)
375 {
376  uint8_t count, i;
377  uint8_t *arr = X86_get_op_access(h, id, eflags);
378 
379  if (!arr) {
380  access[0] = 0;
381  return;
382  }
383 
384  // find the non-zero last entry
385  for(count = 0; arr[count]; count++);
386 
387  if (count == 0)
388  return;
389 
390  // copy in reverse order this access array from Intel syntax -> AT&T syntax
391  count--;
392  for(i = 0; i <= count; i++) {
393  if (arr[count - i] != CS_AC_IGNORE)
394  access[i] = arr[count - i];
395  else
396  access[i] = 0;
397  }
398 }
399 
400 static void printSrcIdx(MCInst *MI, unsigned Op, SStream *O)
401 {
402  MCOperand *SegReg;
403  int reg;
404 
405  if (MI->csh->detail) {
406  uint8_t access[6];
407 
408  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].type = X86_OP_MEM;
409  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].size = MI->x86opsize;
410  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.segment = X86_REG_INVALID;
411  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.base = X86_REG_INVALID;
412  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.index = X86_REG_INVALID;
413  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.scale = 1;
414  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.disp = 0;
415 
416  get_op_access(MI->csh, MCInst_getOpcode(MI), access, &MI->flat_insn->detail->x86.eflags);
417  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].access = access[MI->flat_insn->detail->x86.op_count];
418  }
419 
420  SegReg = MCInst_getOperand(MI, Op+1);
421  reg = MCOperand_getReg(SegReg);
422 
423  // If this has a segment register, print it.
424  if (reg) {
425  _printOperand(MI, Op+1, O);
426  if (MI->csh->detail) {
427  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.segment = reg;
428  }
429 
430  SStream_concat0(O, ":");
431  }
432 
433  SStream_concat0(O, "(");
434  set_mem_access(MI, true);
435 
436  printOperand(MI, Op, O);
437 
438  SStream_concat0(O, ")");
439  set_mem_access(MI, false);
440 }
441 
442 static void printDstIdx(MCInst *MI, unsigned Op, SStream *O)
443 {
444  if (MI->csh->detail) {
445  uint8_t access[6];
446 
447  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].type = X86_OP_MEM;
448  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].size = MI->x86opsize;
449  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.segment = X86_REG_INVALID;
450  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.base = X86_REG_INVALID;
451  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.index = X86_REG_INVALID;
452  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.scale = 1;
453  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.disp = 0;
454 
455  get_op_access(MI->csh, MCInst_getOpcode(MI), access, &MI->flat_insn->detail->x86.eflags);
456  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].access = access[MI->flat_insn->detail->x86.op_count];
457  }
458 
459  // DI accesses are always ES-based on non-64bit mode
460  if (MI->csh->mode != CS_MODE_64) {
461  SStream_concat0(O, "%es:(");
462  if (MI->csh->detail) {
463  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.segment = X86_REG_ES;
464  }
465  } else
466  SStream_concat0(O, "(");
467 
468  set_mem_access(MI, true);
469 
470  printOperand(MI, Op, O);
471 
472  SStream_concat0(O, ")");
473  set_mem_access(MI, false);
474 }
475 
476 static void printSrcIdx8(MCInst *MI, unsigned OpNo, SStream *O)
477 {
478  MI->x86opsize = 1;
479  printSrcIdx(MI, OpNo, O);
480 }
481 
482 static void printSrcIdx16(MCInst *MI, unsigned OpNo, SStream *O)
483 {
484  MI->x86opsize = 2;
485  printSrcIdx(MI, OpNo, O);
486 }
487 
488 static void printSrcIdx32(MCInst *MI, unsigned OpNo, SStream *O)
489 {
490  MI->x86opsize = 4;
491  printSrcIdx(MI, OpNo, O);
492 }
493 
494 static void printSrcIdx64(MCInst *MI, unsigned OpNo, SStream *O)
495 {
496  MI->x86opsize = 8;
497  printSrcIdx(MI, OpNo, O);
498 }
499 
500 static void printDstIdx8(MCInst *MI, unsigned OpNo, SStream *O)
501 {
502  MI->x86opsize = 1;
503  printDstIdx(MI, OpNo, O);
504 }
505 
506 static void printDstIdx16(MCInst *MI, unsigned OpNo, SStream *O)
507 {
508  MI->x86opsize = 2;
509  printDstIdx(MI, OpNo, O);
510 }
511 
512 static void printDstIdx32(MCInst *MI, unsigned OpNo, SStream *O)
513 {
514  MI->x86opsize = 4;
515  printDstIdx(MI, OpNo, O);
516 }
517 
518 static void printDstIdx64(MCInst *MI, unsigned OpNo, SStream *O)
519 {
520  MI->x86opsize = 8;
521  printDstIdx(MI, OpNo, O);
522 }
523 
524 static void printMemOffset(MCInst *MI, unsigned Op, SStream *O)
525 {
526  MCOperand *DispSpec = MCInst_getOperand(MI, Op);
527  MCOperand *SegReg = MCInst_getOperand(MI, Op+1);
528  int reg;
529 
530  if (MI->csh->detail) {
531  uint8_t access[6];
532 
533  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].type = X86_OP_MEM;
534  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].size = MI->x86opsize;
535  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.segment = X86_REG_INVALID;
536  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.base = X86_REG_INVALID;
537  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.index = X86_REG_INVALID;
538  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.scale = 1;
539  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.disp = 0;
540 
541  get_op_access(MI->csh, MCInst_getOpcode(MI), access, &MI->flat_insn->detail->x86.eflags);
542  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].access = access[MI->flat_insn->detail->x86.op_count];
543  }
544 
545  // If this has a segment register, print it.
546  reg = MCOperand_getReg(SegReg);
547  if (reg) {
548  _printOperand(MI, Op + 1, O);
549  SStream_concat0(O, ":");
550  if (MI->csh->detail) {
551  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.segment = reg;
552  }
553  }
554 
555  if (MCOperand_isImm(DispSpec)) {
556  int64_t imm = MCOperand_getImm(DispSpec);
557  if (MI->csh->detail)
558  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.disp = imm;
559  if (imm < 0) {
560  SStream_concat(O, "0x%"PRIx64, arch_masks[MI->csh->mode] & imm);
561  } else {
562  if (imm > HEX_THRESHOLD)
563  SStream_concat(O, "0x%"PRIx64, imm);
564  else
565  SStream_concat(O, "%"PRIu64, imm);
566  }
567  }
568 
569  if (MI->csh->detail)
570  MI->flat_insn->detail->x86.op_count++;
571 }
572 
573 #ifndef CAPSTONE_X86_REDUCE
574 static void printU8Imm(MCInst *MI, unsigned Op, SStream *O)
575 {
576  uint8_t val = MCOperand_getImm(MCInst_getOperand(MI, Op)) & 0xff;
577 
578  if (val > HEX_THRESHOLD)
579  SStream_concat(O, "$0x%x", val);
580  else
581  SStream_concat(O, "$%u", val);
582 
583  if (MI->csh->detail) {
584  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].type = X86_OP_IMM;
585  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].imm = val;
586  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].size = 1;
587  MI->flat_insn->detail->x86.op_count++;
588  }
589 }
590 #endif
591 
592 static void printMemOffs8(MCInst *MI, unsigned OpNo, SStream *O)
593 {
594  MI->x86opsize = 1;
595  printMemOffset(MI, OpNo, O);
596 }
597 
598 static void printMemOffs16(MCInst *MI, unsigned OpNo, SStream *O)
599 {
600  MI->x86opsize = 2;
601  printMemOffset(MI, OpNo, O);
602 }
603 
604 static void printMemOffs32(MCInst *MI, unsigned OpNo, SStream *O)
605 {
606  MI->x86opsize = 4;
607  printMemOffset(MI, OpNo, O);
608 }
609 
610 static void printMemOffs64(MCInst *MI, unsigned OpNo, SStream *O)
611 {
612  MI->x86opsize = 8;
613  printMemOffset(MI, OpNo, O);
614 }
615 
620 static void printPCRelImm(MCInst *MI, unsigned OpNo, SStream *O)
621 {
622  MCOperand *Op = MCInst_getOperand(MI, OpNo);
623  if (MCOperand_isImm(Op)) {
624  int64_t imm = MCOperand_getImm(Op) + MI->flat_insn->size + MI->address;
625 
626  // truncat imm for non-64bit
627  if (MI->csh->mode != CS_MODE_64) {
628  imm = imm & 0xffffffff;
629  }
630 
631  if (MI->csh->mode == CS_MODE_16 &&
632  (MI->Opcode != X86_JMP_4 && MI->Opcode != X86_CALLpcrel32))
633  imm = imm & 0xffff;
634 
635  // Hack: X86 16bit with opcode X86_JMP_4
636  if (MI->csh->mode == CS_MODE_16 &&
637  (MI->Opcode == X86_JMP_4 && MI->x86_prefix[2] != 0x66))
638  imm = imm & 0xffff;
639 
640  // CALL/JMP rel16 is special
641  if (MI->Opcode == X86_CALLpcrel16 || MI->Opcode == X86_JMP_2)
642  imm = imm & 0xffff;
643 
644  if (MI->csh->mode == CS_MODE_16)
645  imm |= (MI->address >> 16) << 16;
646 
647  if (imm < 0) {
648  SStream_concat(O, "0x%"PRIx64, imm);
649  } else {
650  if (imm > HEX_THRESHOLD)
651  SStream_concat(O, "0x%"PRIx64, imm);
652  else
653  SStream_concat(O, "%"PRIu64, imm);
654  }
655  if (MI->csh->detail) {
656  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].type = X86_OP_IMM;
657  MI->has_imm = true;
658  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].imm = imm;
659  MI->flat_insn->detail->x86.op_count++;
660  }
661  }
662 }
663 
664 static void printOperand(MCInst *MI, unsigned OpNo, SStream *O)
665 {
666  MCOperand *Op = MCInst_getOperand(MI, OpNo);
667  if (MCOperand_isReg(Op)) {
668  unsigned int reg = MCOperand_getReg(Op);
669  printRegName(O, reg);
670  if (MI->csh->detail) {
671  if (MI->csh->doing_mem) {
672  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.base = reg;
673  } else {
674  uint8_t access[6];
675 
676  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].type = X86_OP_REG;
677  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].reg = reg;
678  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].size = MI->csh->regsize_map[reg];
679 
680  get_op_access(MI->csh, MCInst_getOpcode(MI), access, &MI->flat_insn->detail->x86.eflags);
681  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].access = access[MI->flat_insn->detail->x86.op_count];
682 
683  MI->flat_insn->detail->x86.op_count++;
684  }
685  }
686  } else if (MCOperand_isImm(Op)) {
687  // Print X86 immediates as signed values.
688  uint8_t encsize;
690  uint8_t opsize = X86_immediate_size(MCInst_getOpcode(MI), &encsize);
691 
692  if (opsize == 1) // print 1 byte immediate in positive form
693  imm = imm & 0xff;
694 
695  switch(MI->flat_insn->id) {
696  default:
697  if (imm >= 0) {
698  if (imm > HEX_THRESHOLD)
699  SStream_concat(O, "$0x%"PRIx64, imm);
700  else
701  SStream_concat(O, "$%"PRIu64, imm);
702  } else {
703  if (MI->csh->imm_unsigned) {
704  if (opsize) {
705  switch(opsize) {
706  default:
707  break;
708  case 1:
709  imm &= 0xff;
710  break;
711  case 2:
712  imm &= 0xffff;
713  break;
714  case 4:
715  imm &= 0xffffffff;
716  break;
717  }
718  }
719 
720  SStream_concat(O, "$0x%"PRIx64, imm);
721  } else {
722  if (imm == 0x8000000000000000LL) // imm == -imm
723  SStream_concat0(O, "$0x8000000000000000");
724  else if (imm < -HEX_THRESHOLD)
725  SStream_concat(O, "$-0x%"PRIx64, -imm);
726  else
727  SStream_concat(O, "$-%"PRIu64, -imm);
728  }
729  }
730  break;
731 
732  case X86_INS_MOVABS:
733  // do not print number in negative form
734  SStream_concat(O, "$0x%"PRIx64, imm);
735  break;
736 
737  case X86_INS_IN:
738  case X86_INS_OUT:
739  case X86_INS_INT:
740  // do not print number in negative form
741  imm = imm & 0xff;
742  if (imm >= 0 && imm <= HEX_THRESHOLD)
743  SStream_concat(O, "$%u", imm);
744  else {
745  SStream_concat(O, "$0x%x", imm);
746  }
747  break;
748 
749  case X86_INS_LCALL:
750  case X86_INS_LJMP:
751  // always print address in positive form
752  if (OpNo == 1) { // selector is ptr16
753  imm = imm & 0xffff;
754  opsize = 2;
755  }
756  SStream_concat(O, "$0x%"PRIx64, imm);
757  break;
758 
759  case X86_INS_AND:
760  case X86_INS_OR:
761  case X86_INS_XOR:
762  // do not print number in negative form
763  if (imm >= 0 && imm <= HEX_THRESHOLD)
764  SStream_concat(O, "$%u", imm);
765  else {
766  imm = arch_masks[opsize? opsize : MI->imm_size] & imm;
767  SStream_concat(O, "$0x%"PRIx64, imm);
768  }
769  break;
770 
771  case X86_INS_RET:
772  case X86_INS_RETF:
773  // RET imm16
774  if (imm >= 0 && imm <= HEX_THRESHOLD)
775  SStream_concat(O, "$%u", imm);
776  else {
777  imm = 0xffff & imm;
778  SStream_concat(O, "$0x%x", imm);
779  }
780  break;
781  }
782 
783  if (MI->csh->detail) {
784  if (MI->csh->doing_mem) {
785  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].type = X86_OP_MEM;
786  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.disp = imm;
787  } else {
788  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].type = X86_OP_IMM;
789  MI->has_imm = true;
790  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].imm = imm;
791 
792  if (opsize > 0) {
793  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].size = opsize;
794  MI->flat_insn->detail->x86.encoding.imm_size = encsize;
795  } else if (MI->op1_size > 0)
796  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].size = MI->op1_size;
797  else
798  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].size = MI->imm_size;
799 
800  MI->flat_insn->detail->x86.op_count++;
801  }
802  }
803  }
804 }
805 
806 static void printMemReference(MCInst *MI, unsigned Op, SStream *O)
807 {
808  MCOperand *BaseReg = MCInst_getOperand(MI, Op + X86_AddrBaseReg);
809  MCOperand *IndexReg = MCInst_getOperand(MI, Op + X86_AddrIndexReg);
810  MCOperand *DispSpec = MCInst_getOperand(MI, Op + X86_AddrDisp);
811  MCOperand *SegReg = MCInst_getOperand(MI, Op + X86_AddrSegmentReg);
812  uint64_t ScaleVal;
813  int segreg;
814  int64_t DispVal = 1;
815 
816  if (MI->csh->detail) {
817  uint8_t access[6];
818 
819  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].type = X86_OP_MEM;
820  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].size = MI->x86opsize;
821  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.segment = X86_REG_INVALID;
822  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.base = MCOperand_getReg(BaseReg);
823  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.index = MCOperand_getReg(IndexReg);
824  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.scale = 1;
825  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.disp = 0;
826 
827  get_op_access(MI->csh, MCInst_getOpcode(MI), access, &MI->flat_insn->detail->x86.eflags);
828  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].access = access[MI->flat_insn->detail->x86.op_count];
829  }
830 
831  // If this has a segment register, print it.
832  segreg = MCOperand_getReg(SegReg);
833  if (segreg) {
834  _printOperand(MI, Op + X86_AddrSegmentReg, O);
835  if (MI->csh->detail) {
836  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.segment = segreg;
837  }
838 
839  SStream_concat0(O, ":");
840  }
841 
842  if (MCOperand_isImm(DispSpec)) {
843  DispVal = MCOperand_getImm(DispSpec);
844  if (MI->csh->detail)
845  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.disp = DispVal;
846  if (DispVal) {
847  if (MCOperand_getReg(IndexReg) || MCOperand_getReg(BaseReg)) {
848  printInt64(O, DispVal);
849  } else {
850  // only immediate as address of memory
851  if (DispVal < 0) {
852  SStream_concat(O, "0x%"PRIx64, arch_masks[MI->csh->mode] & DispVal);
853  } else {
854  if (DispVal > HEX_THRESHOLD)
855  SStream_concat(O, "0x%"PRIx64, DispVal);
856  else
857  SStream_concat(O, "%"PRIu64, DispVal);
858  }
859  }
860  } else {
861  }
862  }
863 
864  if (MCOperand_getReg(IndexReg) || MCOperand_getReg(BaseReg)) {
865  SStream_concat0(O, "(");
866 
867  if (MCOperand_getReg(BaseReg))
868  _printOperand(MI, Op + X86_AddrBaseReg, O);
869 
870  if (MCOperand_getReg(IndexReg)) {
871  SStream_concat0(O, ", ");
872  _printOperand(MI, Op + X86_AddrIndexReg, O);
874  if (MI->csh->detail)
875  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count].mem.scale = (int)ScaleVal;
876  if (ScaleVal != 1) {
877  SStream_concat(O, ", %u", ScaleVal);
878  }
879  }
880  SStream_concat0(O, ")");
881  } else {
882  if (!DispVal)
883  SStream_concat0(O, "0");
884  }
885 
886  if (MI->csh->detail)
887  MI->flat_insn->detail->x86.op_count++;
888 }
889 
890 static void printanymem(MCInst *MI, unsigned OpNo, SStream *O)
891 {
892  switch(MI->Opcode) {
893  default: break;
894  case X86_LEA16r:
895  MI->x86opsize = 2;
896  break;
897  case X86_LEA32r:
898  case X86_LEA64_32r:
899  MI->x86opsize = 4;
900  break;
901  case X86_LEA64r:
902  MI->x86opsize = 8;
903  break;
904  }
905  printMemReference(MI, OpNo, O);
906 }
907 
908 #include "X86InstPrinter.h"
909 
910 #define GET_REGINFO_ENUM
911 #include "X86GenRegisterInfo.inc"
912 
913 // Include the auto-generated portion of the assembly writer.
914 #define PRINT_ALIAS_INSTR
915 #ifdef CAPSTONE_X86_REDUCE
917 #else
918 #include "X86GenAsmWriter.inc"
919 #endif
920 
921 static void printRegName(SStream *OS, unsigned RegNo)
922 {
923  SStream_concat(OS, "%%%s", getRegisterName(RegNo));
924 }
925 
926 void X86_ATT_printInst(MCInst *MI, SStream *OS, void *info)
927 {
928  char *mnem;
929  x86_reg reg, reg2;
930  enum cs_ac_type access1, access2;
931  int i;
932 
933  // perhaps this instruction does not need printer
934  if (MI->assembly[0]) {
935  strncpy(OS->buffer, MI->assembly, sizeof(OS->buffer));
936  return;
937  }
938 
939  // Output CALLpcrel32 as "callq" in 64-bit mode.
940  // In Intel annotation it's always emitted as "call".
941  //
942  // TODO: Probably this hack should be redesigned via InstAlias in
943  // InstrInfo.td as soon as Requires clause is supported properly
944  // for InstAlias.
945  if (MI->csh->mode == CS_MODE_64 && MCInst_getOpcode(MI) == X86_CALLpcrel32) {
946  SStream_concat0(OS, "callq\t");
948  printPCRelImm(MI, 0, OS);
949  return;
950  }
951 
952  // Try to print any aliases first.
953  mnem = printAliasInstr(MI, OS, info);
954  if (mnem)
955  cs_mem_free(mnem);
956  else
957  printInstruction(MI, OS, info);
958 
959  // HACK TODO: fix this in machine description
960  switch(MI->flat_insn->id) {
961  default: break;
962  case X86_INS_SYSEXIT:
963  SStream_Init(OS);
964  SStream_concat0(OS, "sysexit");
965  break;
966  }
967 
968  if (MI->has_imm) {
969  // if op_count > 1, then this operand's size is taken from the destination op
970  if (MI->flat_insn->detail->x86.op_count > 1) {
971  if (MI->flat_insn->id != X86_INS_LCALL && MI->flat_insn->id != X86_INS_LJMP) {
972  for (i = 0; i < MI->flat_insn->detail->x86.op_count; i++) {
973  if (MI->flat_insn->detail->x86.operands[i].type == X86_OP_IMM)
974  MI->flat_insn->detail->x86.operands[i].size =
975  MI->flat_insn->detail->x86.operands[MI->flat_insn->detail->x86.op_count - 1].size;
976  }
977  }
978  } else
979  MI->flat_insn->detail->x86.operands[0].size = MI->imm_size;
980  }
981 
982  if (MI->csh->detail) {
983  uint8_t access[6] = {0};
984 
985  // some instructions need to supply immediate 1 in the first op
986  switch(MCInst_getOpcode(MI)) {
987  default:
988  break;
989  case X86_SHL8r1:
990  case X86_SHL16r1:
991  case X86_SHL32r1:
992  case X86_SHL64r1:
993  case X86_SAL8r1:
994  case X86_SAL16r1:
995  case X86_SAL32r1:
996  case X86_SAL64r1:
997  case X86_SHR8r1:
998  case X86_SHR16r1:
999  case X86_SHR32r1:
1000  case X86_SHR64r1:
1001  case X86_SAR8r1:
1002  case X86_SAR16r1:
1003  case X86_SAR32r1:
1004  case X86_SAR64r1:
1005  case X86_RCL8r1:
1006  case X86_RCL16r1:
1007  case X86_RCL32r1:
1008  case X86_RCL64r1:
1009  case X86_RCR8r1:
1010  case X86_RCR16r1:
1011  case X86_RCR32r1:
1012  case X86_RCR64r1:
1013  case X86_ROL8r1:
1014  case X86_ROL16r1:
1015  case X86_ROL32r1:
1016  case X86_ROL64r1:
1017  case X86_ROR8r1:
1018  case X86_ROR16r1:
1019  case X86_ROR32r1:
1020  case X86_ROR64r1:
1021  case X86_SHL8m1:
1022  case X86_SHL16m1:
1023  case X86_SHL32m1:
1024  case X86_SHL64m1:
1025  case X86_SAL8m1:
1026  case X86_SAL16m1:
1027  case X86_SAL32m1:
1028  case X86_SAL64m1:
1029  case X86_SHR8m1:
1030  case X86_SHR16m1:
1031  case X86_SHR32m1:
1032  case X86_SHR64m1:
1033  case X86_SAR8m1:
1034  case X86_SAR16m1:
1035  case X86_SAR32m1:
1036  case X86_SAR64m1:
1037  case X86_RCL8m1:
1038  case X86_RCL16m1:
1039  case X86_RCL32m1:
1040  case X86_RCL64m1:
1041  case X86_RCR8m1:
1042  case X86_RCR16m1:
1043  case X86_RCR32m1:
1044  case X86_RCR64m1:
1045  case X86_ROL8m1:
1046  case X86_ROL16m1:
1047  case X86_ROL32m1:
1048  case X86_ROL64m1:
1049  case X86_ROR8m1:
1050  case X86_ROR16m1:
1051  case X86_ROR32m1:
1052  case X86_ROR64m1:
1053  // shift all the ops right to leave 1st slot for this new register op
1054  memmove(&(MI->flat_insn->detail->x86.operands[1]), &(MI->flat_insn->detail->x86.operands[0]),
1055  sizeof(MI->flat_insn->detail->x86.operands[0]) * (ARR_SIZE(MI->flat_insn->detail->x86.operands) - 1));
1056  MI->flat_insn->detail->x86.operands[0].type = X86_OP_IMM;
1057  MI->flat_insn->detail->x86.operands[0].imm = 1;
1058  MI->flat_insn->detail->x86.operands[0].size = 1;
1059  MI->flat_insn->detail->x86.op_count++;
1060  }
1061 
1062  // special instruction needs to supply register op
1063  // first op can be embedded in the asm by llvm.
1064  // so we have to add the missing register as the first operand
1065 
1066  //printf(">>> opcode = %u\n", MCInst_getOpcode(MI));
1067 
1068  reg = X86_insn_reg_att(MCInst_getOpcode(MI), &access1);
1069  if (reg) {
1070  // shift all the ops right to leave 1st slot for this new register op
1071  memmove(&(MI->flat_insn->detail->x86.operands[1]), &(MI->flat_insn->detail->x86.operands[0]),
1072  sizeof(MI->flat_insn->detail->x86.operands[0]) * (ARR_SIZE(MI->flat_insn->detail->x86.operands) - 1));
1073  MI->flat_insn->detail->x86.operands[0].type = X86_OP_REG;
1074  MI->flat_insn->detail->x86.operands[0].reg = reg;
1075  MI->flat_insn->detail->x86.operands[0].size = MI->csh->regsize_map[reg];
1076  MI->flat_insn->detail->x86.operands[0].access = access1;
1077 
1078  MI->flat_insn->detail->x86.op_count++;
1079  } else {
1080  if (X86_insn_reg_att2(MCInst_getOpcode(MI), &reg, &access1, &reg2, &access2)) {
1081 
1082  MI->flat_insn->detail->x86.operands[0].type = X86_OP_REG;
1083  MI->flat_insn->detail->x86.operands[0].reg = reg;
1084  MI->flat_insn->detail->x86.operands[0].size = MI->csh->regsize_map[reg];
1085  MI->flat_insn->detail->x86.operands[0].access = access1;
1086  MI->flat_insn->detail->x86.operands[1].type = X86_OP_REG;
1087  MI->flat_insn->detail->x86.operands[1].reg = reg2;
1088  MI->flat_insn->detail->x86.operands[1].size = MI->csh->regsize_map[reg2];
1089  MI->flat_insn->detail->x86.operands[0].access = access2;
1090  MI->flat_insn->detail->x86.op_count = 2;
1091  }
1092  }
1093 
1094 #ifndef CAPSTONE_DIET
1095  get_op_access(MI->csh, MCInst_getOpcode(MI), access, &MI->flat_insn->detail->x86.eflags);
1096  MI->flat_insn->detail->x86.operands[0].access = access[0];
1097  MI->flat_insn->detail->x86.operands[1].access = access[1];
1098 #endif
1099  }
1100 }
1101 
1102 #endif
#define mnem(n, mn)
unsigned MCInst_getOpcode(const MCInst *inst)
Definition: MCInst.c:68
MCOperand * MCInst_getOperand(MCInst *inst, unsigned i)
Definition: MCInst.c:78
bool MCOperand_isReg(const MCOperand *op)
Definition: MCInst.c:101
void MCInst_setOpcodePub(MCInst *inst, unsigned Op)
Definition: MCInst.c:63
int64_t MCOperand_getImm(MCOperand *op)
Definition: MCInst.c:128
unsigned MCOperand_getReg(const MCOperand *op)
getReg - Returns the register number.
Definition: MCInst.c:117
bool MCOperand_isImm(const MCOperand *op)
Definition: MCInst.c:106
void SStream_Init(SStream *ss)
Definition: SStream.c:25
void printInt64(SStream *O, int64_t val)
Definition: SStream.c:87
void SStream_concat(SStream *ss, const char *fmt,...)
Definition: SStream.c:45
void SStream_concat0(SStream *ss, const char *s)
Definition: SStream.c:31
@ X86_AddrIndexReg
Definition: X86BaseInfo.h:30
@ X86_AddrBaseReg
Definition: X86BaseInfo.h:28
@ X86_AddrSegmentReg
AddrSegmentReg - The operand # of the segment in the memory operand.
Definition: X86BaseInfo.h:34
@ X86_AddrScaleAmt
Definition: X86BaseInfo.h:29
@ X86_AddrDisp
Definition: X86BaseInfo.h:31
void X86_ATT_printInst(MCInst *MI, SStream *OS, void *Info)
uint8_t X86_immediate_size(unsigned int id, uint8_t *enc_size)
const uint64_t arch_masks[9]
bool X86_insn_reg_att2(unsigned int id, x86_reg *reg1, enum cs_ac_type *access1, x86_reg *reg2, enum cs_ac_type *access2)
void op_addSseCC(MCInst *MI, int v)
void op_addAvxRoundingMode(MCInst *MI, int v)
uint8_t * X86_get_op_access(cs_struct *h, unsigned int id, uint64_t *eflags)
void op_addAvxSae(MCInst *MI)
x86_reg X86_insn_reg_att(unsigned int id, enum cs_ac_type *access)
void op_addXopCC(MCInst *MI, int v)
void op_addAvxCC(MCInst *MI, int v)
#define imm
lzma_index ** i
Definition: index.h:629
ut16 val
Definition: armass64_const.h:6
RzBinInfo * info(RzBinFile *bf)
Definition: bin_ne.c:86
@ CS_MODE_64
64-bit mode (X86, PPC)
Definition: capstone.h:107
@ CS_MODE_32
32-bit mode (X86)
Definition: capstone.h:106
@ CS_MODE_16
16-bit mode (X86)
Definition: capstone.h:105
@ CS_OPT_ON
Turn ON an option (CS_OPT_DETAIL, CS_OPT_SKIPDATA).
Definition: capstone.h:183
cs_ac_type
Definition: capstone.h:202
@ X86_AVX_RM_RD
Round down.
Definition: x86.h:241
@ X86_AVX_RM_RN
Round to nearest.
Definition: x86.h:240
@ X86_AVX_RM_RU
Round up.
Definition: x86.h:242
@ X86_AVX_RM_RZ
Round toward zero.
Definition: x86.h:243
@ X86_INS_INT
Definition: x86.h:607
@ X86_INS_LCALL
Definition: x86.h:540
@ X86_INS_RET
Definition: x86.h:533
@ X86_INS_LGDT
Definition: x86.h:713
@ X86_INS_AND
Definition: x86.h:411
@ X86_INS_SGDT
Definition: x86.h:1029
@ X86_INS_XOR
Definition: x86.h:720
@ X86_INS_OUT
Definition: x86.h:882
@ X86_INS_SYSEXIT
Definition: x86.h:1083
@ X86_INS_SIDT
Definition: x86.h:1045
@ X86_INS_CALL
Definition: x86.h:442
@ X86_INS_MOVABS
Definition: x86.h:836
@ X86_INS_OR
Definition: x86.h:718
@ X86_INS_IN
Definition: x86.h:600
@ X86_INS_RETF
Definition: x86.h:728
@ X86_INS_LIDT
Definition: x86.h:715
@ X86_INS_LJMP
Definition: x86.h:541
@ X86_OP_IMM
= CS_OP_IMM (Immediate operand).
Definition: x86.h:161
@ X86_OP_REG
= CS_OP_REG (Register operand).
Definition: x86.h:160
@ X86_OP_MEM
= CS_OP_MEM (Memory operand).
Definition: x86.h:162
x86_reg
X86 registers.
Definition: x86.h:19
@ X86_REG_ES
Definition: x86.h:26
@ X86_REG_INVALID
Definition: x86.h:20
@ X86_XOP_CC_GE
Definition: x86.h:171
@ X86_XOP_CC_GT
Definition: x86.h:170
@ X86_XOP_CC_LT
Definition: x86.h:168
@ X86_XOP_CC_LE
Definition: x86.h:169
@ X86_XOP_CC_FALSE
Definition: x86.h:174
@ X86_XOP_CC_NEQ
Definition: x86.h:173
@ X86_XOP_CC_EQ
Definition: x86.h:172
@ X86_XOP_CC_TRUE
Definition: x86.h:175
@ X86_AVX_CC_UNORD_S
Definition: x86.h:222
@ X86_AVX_CC_EQ_US
Definition: x86.h:227
@ X86_AVX_CC_LE
Definition: x86.h:205
@ X86_AVX_CC_GT
Definition: x86.h:217
@ X86_AVX_CC_NLT_UQ
Definition: x86.h:224
@ X86_AVX_CC_ORD
Definition: x86.h:210
@ X86_AVX_CC_NLE
Definition: x86.h:209
@ X86_AVX_CC_NEQ_OS
Definition: x86.h:231
@ X86_AVX_CC_NGE_UQ
Definition: x86.h:228
@ X86_AVX_CC_NGT_UQ
Definition: x86.h:229
@ X86_AVX_CC_NEQ_OQ
Definition: x86.h:215
@ X86_AVX_CC_ORD_S
Definition: x86.h:226
@ X86_AVX_CC_GE_OQ
Definition: x86.h:232
@ X86_AVX_CC_NEQ
Definition: x86.h:207
@ X86_AVX_CC_TRUE_US
Definition: x86.h:234
@ X86_AVX_CC_LT
Definition: x86.h:204
@ X86_AVX_CC_FALSE
Definition: x86.h:214
@ X86_AVX_CC_EQ_OS
Definition: x86.h:219
@ X86_AVX_CC_LT_OQ
Definition: x86.h:220
@ X86_AVX_CC_EQ
Definition: x86.h:203
@ X86_AVX_CC_UNORD
Definition: x86.h:206
@ X86_AVX_CC_GE
Definition: x86.h:216
@ X86_AVX_CC_EQ_UQ
Definition: x86.h:211
@ X86_AVX_CC_NGE
Definition: x86.h:212
@ X86_AVX_CC_LE_OQ
Definition: x86.h:221
@ X86_AVX_CC_GT_OQ
Definition: x86.h:233
@ X86_AVX_CC_NLT
Definition: x86.h:208
@ X86_AVX_CC_NGT
Definition: x86.h:213
@ X86_AVX_CC_FALSE_OS
Definition: x86.h:230
@ X86_AVX_CC_NEQ_US
Definition: x86.h:223
@ X86_AVX_CC_NLE_UQ
Definition: x86.h:225
@ X86_AVX_CC_TRUE
Definition: x86.h:218
@ X86_SSE_CC_ORD
Definition: x86.h:197
@ X86_SSE_CC_LE
Definition: x86.h:192
@ X86_SSE_CC_NEQ
Definition: x86.h:194
@ X86_SSE_CC_LT
Definition: x86.h:191
@ X86_SSE_CC_EQ
Definition: x86.h:190
@ X86_SSE_CC_NLE
Definition: x86.h:196
@ X86_SSE_CC_NLT
Definition: x86.h:195
@ X86_SSE_CC_UNORD
Definition: x86.h:193
cs_free_t cs_mem_free
Definition: cs.c:351
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void count
Definition: sflib.h:98
@ OS
Definition: inflate.h:24
#define reg(n)
#define PRIu64
Definition: macros.h:18
static static fork const void static count static fd const char static mode const char static pathname const char static path const char static dev const char static group static getpid static getuid void void static data static pause access
Definition: sflib.h:64
static const char struct stat static buf struct stat static buf static vhangup int status
Definition: sflib.h:145
#define ARR_SIZE(a)
Definition: ocaml.c:13
#define O
Definition: rcond.c:14
static int
Definition: sfsocketcall.h:114
long int64_t
Definition: sftypes.h:32
unsigned long uint64_t
Definition: sftypes.h:28
unsigned char uint8_t
Definition: sftypes.h:31
#define h(i)
Definition: sha256.c:48
Definition: MCInst.h:88
cs_insn * flat_insn
Definition: MCInst.h:95
cs_struct * csh
Definition: MCInst.h:97
uint8_t op1_size
Definition: MCInst.h:92
bool has_imm
Definition: MCInst.h:91
uint8_t imm_size
Definition: MCInst.h:104
char assembly[8]
Definition: MCInst.h:109
uint8_t x86_prefix[4]
Definition: MCInst.h:103
unsigned Opcode
Definition: MCInst.h:93
uint8_t popcode_adjust
Definition: MCInst.h:108
uint8_t x86opsize
Definition: MCInst.h:98
uint64_t address
Definition: MCInst.h:96
Definition: SStream.h:9
bool doing_mem
Definition: cs_priv.h:70
cs_mode mode
Definition: cs_priv.h:56
cs_opt_value imm_unsigned
Definition: cs_priv.h:68
cs_opt_value detail
Definition: cs_priv.h:68
const uint8_t * regsize_map
Definition: cs_priv.h:76
#define HEX_THRESHOLD
Definition: utils.h:16
#define CS_AC_IGNORE
Definition: utils.h:64
#define PRIx64
Definition: sysdefs.h:94