Rizin
unix-like reverse engineering framework and cli tools
X86Disassembler.c
Go to the documentation of this file.
1 //===-- X86Disassembler.cpp - Disassembler for x86 and x86_64 -------------===//
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 code to translate the data produced by the decoder into
12 // MCInsts.
13 // Documentation for the disassembler can be found in X86Disassembler.h.
14 //
15 //===----------------------------------------------------------------------===//
16 
17 /* Capstone Disassembly Engine */
18 /* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2015 */
19 
20 #ifdef CAPSTONE_HAS_X86
21 
22 #if defined (WIN32) || defined (WIN64) || defined (_WIN32) || defined (_WIN64)
23 #pragma warning(disable:4996) // disable MSVC's warning on strncpy()
24 #pragma warning(disable:28719) // disable MSVC's warning on strncpy()
25 #endif
26 
27 #include <capstone/platform.h>
28 
29 #if defined(CAPSTONE_HAS_OSXKERNEL)
30 #include <Availability.h>
31 #endif
32 
33 #include <string.h>
34 
35 #include "../../cs_priv.h"
36 
37 #include "X86Disassembler.h"
39 #include "X86DisassemblerDecoder.h"
40 #include "../../MCInst.h"
41 #include "../../utils.h"
42 #include "X86Mapping.h"
43 
44 #define GET_REGINFO_ENUM
45 #define GET_REGINFO_MC_DESC
46 #include "X86GenRegisterInfo.inc"
47 
48 #define GET_INSTRINFO_ENUM
49 #ifdef CAPSTONE_X86_REDUCE
51 #else
52 #include "X86GenInstrInfo.inc"
53 #endif
54 
55 // Fill-ins to make the compiler happy. These constants are never actually
56 // assigned; they are just filler to make an automatically-generated switch
57 // statement work.
58 enum {
59  X86_BX_SI = 500,
60  X86_BX_DI = 501,
61  X86_BP_SI = 502,
62  X86_BP_DI = 503,
63  X86_sib = 504,
64  X86_sib64 = 505
65 };
66 
67 //
68 // Private code that translates from struct InternalInstructions to MCInsts.
69 //
70 
76 static void translateRegister(MCInst *mcInst, Reg reg)
77 {
78 #define ENTRY(x) X86_##x,
79  static const uint8_t llvmRegnums[] = {
80  ALL_REGS
81  0
82  };
83 #undef ENTRY
84 
85  uint8_t llvmRegnum = llvmRegnums[reg];
86  MCOperand_CreateReg0(mcInst, llvmRegnum);
87 }
88 
89 static const uint8_t segmentRegnums[SEG_OVERRIDE_max] = {
90  0, // SEG_OVERRIDE_NONE
91  X86_CS,
92  X86_SS,
93  X86_DS,
94  X86_ES,
95  X86_FS,
96  X86_GS
97 };
98 
103 static bool translateSrcIndex(MCInst *mcInst, InternalInstruction *insn)
104 {
105  unsigned baseRegNo;
106 
107  if (insn->mode == MODE_64BIT)
108  baseRegNo = insn->isPrefix67 ? X86_ESI : X86_RSI;
109  else if (insn->mode == MODE_32BIT)
110  baseRegNo = insn->isPrefix67 ? X86_SI : X86_ESI;
111  else {
112  // assert(insn->mode == MODE_16BIT);
113  baseRegNo = insn->isPrefix67 ? X86_ESI : X86_SI;
114  }
115 
116  MCOperand_CreateReg0(mcInst, baseRegNo);
117 
118  MCOperand_CreateReg0(mcInst, segmentRegnums[insn->segmentOverride]);
119 
120  return false;
121 }
122 
127 static bool translateDstIndex(MCInst *mcInst, InternalInstruction *insn)
128 {
129  unsigned baseRegNo;
130 
131  if (insn->mode == MODE_64BIT)
132  baseRegNo = insn->isPrefix67 ? X86_EDI : X86_RDI;
133  else if (insn->mode == MODE_32BIT)
134  baseRegNo = insn->isPrefix67 ? X86_DI : X86_EDI;
135  else {
136  // assert(insn->mode == MODE_16BIT);
137  baseRegNo = insn->isPrefix67 ? X86_EDI : X86_DI;
138  }
139 
140  MCOperand_CreateReg0(mcInst, baseRegNo);
141 
142  return false;
143 }
144 
151 static void translateImmediate(MCInst *mcInst, uint64_t immediate,
153 {
155 
156  type = (OperandType)operand->type;
157  if (type == TYPE_RELv) {
158  //isBranch = true;
159  //pcrel = insn->startLocation + insn->immediateOffset + insn->immediateSize;
160  switch (insn->displacementSize) {
161  case 1:
162  if (immediate & 0x80)
163  immediate |= ~(0xffull);
164  break;
165  case 2:
166  if (immediate & 0x8000)
167  immediate |= ~(0xffffull);
168  break;
169  case 4:
170  if (immediate & 0x80000000)
171  immediate |= ~(0xffffffffull);
172  break;
173  case 8:
174  break;
175  default:
176  break;
177  }
178  } // By default sign-extend all X86 immediates based on their encoding.
179  else if (type == TYPE_IMM8 || type == TYPE_IMM16 || type == TYPE_IMM32 ||
180  type == TYPE_IMM64 || type == TYPE_IMMv) {
181 
182  switch (operand->encoding) {
183  default:
184  break;
185  case ENCODING_IB:
186  if(immediate & 0x80)
187  immediate |= ~(0xffull);
188  break;
189  case ENCODING_IW:
190  if(immediate & 0x8000)
191  immediate |= ~(0xffffull);
192  break;
193  case ENCODING_ID:
194  if(immediate & 0x80000000)
195  immediate |= ~(0xffffffffull);
196  break;
197  case ENCODING_IO:
198  break;
199  }
200  } else if (type == TYPE_IMM3) {
201 #ifndef CAPSTONE_X86_REDUCE
202  // Check for immediates that printSSECC can't handle.
203  if (immediate >= 8) {
204  unsigned NewOpc = 0;
205 
206  switch (MCInst_getOpcode(mcInst)) {
207  default: break; // never reach
208  case X86_CMPPDrmi: NewOpc = X86_CMPPDrmi_alt; break;
209  case X86_CMPPDrri: NewOpc = X86_CMPPDrri_alt; break;
210  case X86_CMPPSrmi: NewOpc = X86_CMPPSrmi_alt; break;
211  case X86_CMPPSrri: NewOpc = X86_CMPPSrri_alt; break;
212  case X86_CMPSDrm: NewOpc = X86_CMPSDrm_alt; break;
213  case X86_CMPSDrr: NewOpc = X86_CMPSDrr_alt; break;
214  case X86_CMPSSrm: NewOpc = X86_CMPSSrm_alt; break;
215  case X86_CMPSSrr: NewOpc = X86_CMPSSrr_alt; break;
216  case X86_VPCOMBri: NewOpc = X86_VPCOMBri_alt; break;
217  case X86_VPCOMBmi: NewOpc = X86_VPCOMBmi_alt; break;
218  case X86_VPCOMWri: NewOpc = X86_VPCOMWri_alt; break;
219  case X86_VPCOMWmi: NewOpc = X86_VPCOMWmi_alt; break;
220  case X86_VPCOMDri: NewOpc = X86_VPCOMDri_alt; break;
221  case X86_VPCOMDmi: NewOpc = X86_VPCOMDmi_alt; break;
222  case X86_VPCOMQri: NewOpc = X86_VPCOMQri_alt; break;
223  case X86_VPCOMQmi: NewOpc = X86_VPCOMQmi_alt; break;
224  case X86_VPCOMUBri: NewOpc = X86_VPCOMUBri_alt; break;
225  case X86_VPCOMUBmi: NewOpc = X86_VPCOMUBmi_alt; break;
226  case X86_VPCOMUWri: NewOpc = X86_VPCOMUWri_alt; break;
227  case X86_VPCOMUWmi: NewOpc = X86_VPCOMUWmi_alt; break;
228  case X86_VPCOMUDri: NewOpc = X86_VPCOMUDri_alt; break;
229  case X86_VPCOMUDmi: NewOpc = X86_VPCOMUDmi_alt; break;
230  case X86_VPCOMUQri: NewOpc = X86_VPCOMUQri_alt; break;
231  case X86_VPCOMUQmi: NewOpc = X86_VPCOMUQmi_alt; break;
232  }
233  // Switch opcode to the one that doesn't get special printing.
234  if (NewOpc != 0) {
235  MCInst_setOpcode(mcInst, NewOpc);
236  }
237  }
238 #endif
239  } else if (type == TYPE_IMM5) {
240 #ifndef CAPSTONE_X86_REDUCE
241  // Check for immediates that printAVXCC can't handle.
242  if (immediate >= 32) {
243  unsigned NewOpc = 0;
244 
245  switch (MCInst_getOpcode(mcInst)) {
246  default: break; // unexpected opcode
247  case X86_VCMPPDrmi: NewOpc = X86_VCMPPDrmi_alt; break;
248  case X86_VCMPPDrri: NewOpc = X86_VCMPPDrri_alt; break;
249  case X86_VCMPPSrmi: NewOpc = X86_VCMPPSrmi_alt; break;
250  case X86_VCMPPSrri: NewOpc = X86_VCMPPSrri_alt; break;
251  case X86_VCMPSDrm: NewOpc = X86_VCMPSDrm_alt; break;
252  case X86_VCMPSDrr: NewOpc = X86_VCMPSDrr_alt; break;
253  case X86_VCMPSSrm: NewOpc = X86_VCMPSSrm_alt; break;
254  case X86_VCMPSSrr: NewOpc = X86_VCMPSSrr_alt; break;
255  case X86_VCMPPDYrmi: NewOpc = X86_VCMPPDYrmi_alt; break;
256  case X86_VCMPPDYrri: NewOpc = X86_VCMPPDYrri_alt; break;
257  case X86_VCMPPSYrmi: NewOpc = X86_VCMPPSYrmi_alt; break;
258  case X86_VCMPPSYrri: NewOpc = X86_VCMPPSYrri_alt; break;
259  case X86_VCMPPDZrmi: NewOpc = X86_VCMPPDZrmi_alt; break;
260  case X86_VCMPPDZrri: NewOpc = X86_VCMPPDZrri_alt; break;
261  case X86_VCMPPDZrrib: NewOpc = X86_VCMPPDZrrib_alt; break;
262  case X86_VCMPPSZrmi: NewOpc = X86_VCMPPSZrmi_alt; break;
263  case X86_VCMPPSZrri: NewOpc = X86_VCMPPSZrri_alt; break;
264  case X86_VCMPPSZrrib: NewOpc = X86_VCMPPSZrrib_alt; break;
265  case X86_VCMPSDZrm: NewOpc = X86_VCMPSDZrmi_alt; break;
266  case X86_VCMPSDZrr: NewOpc = X86_VCMPSDZrri_alt; break;
267  case X86_VCMPSSZrm: NewOpc = X86_VCMPSSZrmi_alt; break;
268  case X86_VCMPSSZrr: NewOpc = X86_VCMPSSZrri_alt; break;
269  }
270  // Switch opcode to the one that doesn't get special printing.
271  if (NewOpc != 0) {
272  MCInst_setOpcode(mcInst, NewOpc);
273  }
274  }
275 #endif
276  } else if (type == TYPE_AVX512ICC) {
277 #ifndef CAPSTONE_X86_REDUCE
278  if (immediate >= 8 || ((immediate & 0x3) == 3)) {
279  unsigned NewOpc = 0;
280  switch (MCInst_getOpcode(mcInst)) {
281  default: // llvm_unreachable("unexpected opcode");
282  case X86_VPCMPBZ128rmi: NewOpc = X86_VPCMPBZ128rmi_alt; break;
283  case X86_VPCMPBZ128rmik: NewOpc = X86_VPCMPBZ128rmik_alt; break;
284  case X86_VPCMPBZ128rri: NewOpc = X86_VPCMPBZ128rri_alt; break;
285  case X86_VPCMPBZ128rrik: NewOpc = X86_VPCMPBZ128rrik_alt; break;
286  case X86_VPCMPBZ256rmi: NewOpc = X86_VPCMPBZ256rmi_alt; break;
287  case X86_VPCMPBZ256rmik: NewOpc = X86_VPCMPBZ256rmik_alt; break;
288  case X86_VPCMPBZ256rri: NewOpc = X86_VPCMPBZ256rri_alt; break;
289  case X86_VPCMPBZ256rrik: NewOpc = X86_VPCMPBZ256rrik_alt; break;
290  case X86_VPCMPBZrmi: NewOpc = X86_VPCMPBZrmi_alt; break;
291  case X86_VPCMPBZrmik: NewOpc = X86_VPCMPBZrmik_alt; break;
292  case X86_VPCMPBZrri: NewOpc = X86_VPCMPBZrri_alt; break;
293  case X86_VPCMPBZrrik: NewOpc = X86_VPCMPBZrrik_alt; break;
294  case X86_VPCMPDZ128rmi: NewOpc = X86_VPCMPDZ128rmi_alt; break;
295  case X86_VPCMPDZ128rmib: NewOpc = X86_VPCMPDZ128rmib_alt; break;
296  case X86_VPCMPDZ128rmibk: NewOpc = X86_VPCMPDZ128rmibk_alt; break;
297  case X86_VPCMPDZ128rmik: NewOpc = X86_VPCMPDZ128rmik_alt; break;
298  case X86_VPCMPDZ128rri: NewOpc = X86_VPCMPDZ128rri_alt; break;
299  case X86_VPCMPDZ128rrik: NewOpc = X86_VPCMPDZ128rrik_alt; break;
300  case X86_VPCMPDZ256rmi: NewOpc = X86_VPCMPDZ256rmi_alt; break;
301  case X86_VPCMPDZ256rmib: NewOpc = X86_VPCMPDZ256rmib_alt; break;
302  case X86_VPCMPDZ256rmibk: NewOpc = X86_VPCMPDZ256rmibk_alt; break;
303  case X86_VPCMPDZ256rmik: NewOpc = X86_VPCMPDZ256rmik_alt; break;
304  case X86_VPCMPDZ256rri: NewOpc = X86_VPCMPDZ256rri_alt; break;
305  case X86_VPCMPDZ256rrik: NewOpc = X86_VPCMPDZ256rrik_alt; break;
306  case X86_VPCMPDZrmi: NewOpc = X86_VPCMPDZrmi_alt; break;
307  case X86_VPCMPDZrmib: NewOpc = X86_VPCMPDZrmib_alt; break;
308  case X86_VPCMPDZrmibk: NewOpc = X86_VPCMPDZrmibk_alt; break;
309  case X86_VPCMPDZrmik: NewOpc = X86_VPCMPDZrmik_alt; break;
310  case X86_VPCMPDZrri: NewOpc = X86_VPCMPDZrri_alt; break;
311  case X86_VPCMPDZrrik: NewOpc = X86_VPCMPDZrrik_alt; break;
312  case X86_VPCMPQZ128rmi: NewOpc = X86_VPCMPQZ128rmi_alt; break;
313  case X86_VPCMPQZ128rmib: NewOpc = X86_VPCMPQZ128rmib_alt; break;
314  case X86_VPCMPQZ128rmibk: NewOpc = X86_VPCMPQZ128rmibk_alt; break;
315  case X86_VPCMPQZ128rmik: NewOpc = X86_VPCMPQZ128rmik_alt; break;
316  case X86_VPCMPQZ128rri: NewOpc = X86_VPCMPQZ128rri_alt; break;
317  case X86_VPCMPQZ128rrik: NewOpc = X86_VPCMPQZ128rrik_alt; break;
318  case X86_VPCMPQZ256rmi: NewOpc = X86_VPCMPQZ256rmi_alt; break;
319  case X86_VPCMPQZ256rmib: NewOpc = X86_VPCMPQZ256rmib_alt; break;
320  case X86_VPCMPQZ256rmibk: NewOpc = X86_VPCMPQZ256rmibk_alt; break;
321  case X86_VPCMPQZ256rmik: NewOpc = X86_VPCMPQZ256rmik_alt; break;
322  case X86_VPCMPQZ256rri: NewOpc = X86_VPCMPQZ256rri_alt; break;
323  case X86_VPCMPQZ256rrik: NewOpc = X86_VPCMPQZ256rrik_alt; break;
324  case X86_VPCMPQZrmi: NewOpc = X86_VPCMPQZrmi_alt; break;
325  case X86_VPCMPQZrmib: NewOpc = X86_VPCMPQZrmib_alt; break;
326  case X86_VPCMPQZrmibk: NewOpc = X86_VPCMPQZrmibk_alt; break;
327  case X86_VPCMPQZrmik: NewOpc = X86_VPCMPQZrmik_alt; break;
328  case X86_VPCMPQZrri: NewOpc = X86_VPCMPQZrri_alt; break;
329  case X86_VPCMPQZrrik: NewOpc = X86_VPCMPQZrrik_alt; break;
330  case X86_VPCMPUBZ128rmi: NewOpc = X86_VPCMPUBZ128rmi_alt; break;
331  case X86_VPCMPUBZ128rmik: NewOpc = X86_VPCMPUBZ128rmik_alt; break;
332  case X86_VPCMPUBZ128rri: NewOpc = X86_VPCMPUBZ128rri_alt; break;
333  case X86_VPCMPUBZ128rrik: NewOpc = X86_VPCMPUBZ128rrik_alt; break;
334  case X86_VPCMPUBZ256rmi: NewOpc = X86_VPCMPUBZ256rmi_alt; break;
335  case X86_VPCMPUBZ256rmik: NewOpc = X86_VPCMPUBZ256rmik_alt; break;
336  case X86_VPCMPUBZ256rri: NewOpc = X86_VPCMPUBZ256rri_alt; break;
337  case X86_VPCMPUBZ256rrik: NewOpc = X86_VPCMPUBZ256rrik_alt; break;
338  case X86_VPCMPUBZrmi: NewOpc = X86_VPCMPUBZrmi_alt; break;
339  case X86_VPCMPUBZrmik: NewOpc = X86_VPCMPUBZrmik_alt; break;
340  case X86_VPCMPUBZrri: NewOpc = X86_VPCMPUBZrri_alt; break;
341  case X86_VPCMPUBZrrik: NewOpc = X86_VPCMPUBZrrik_alt; break;
342  case X86_VPCMPUDZ128rmi: NewOpc = X86_VPCMPUDZ128rmi_alt; break;
343  case X86_VPCMPUDZ128rmib: NewOpc = X86_VPCMPUDZ128rmib_alt; break;
344  case X86_VPCMPUDZ128rmibk: NewOpc = X86_VPCMPUDZ128rmibk_alt; break;
345  case X86_VPCMPUDZ128rmik: NewOpc = X86_VPCMPUDZ128rmik_alt; break;
346  case X86_VPCMPUDZ128rri: NewOpc = X86_VPCMPUDZ128rri_alt; break;
347  case X86_VPCMPUDZ128rrik: NewOpc = X86_VPCMPUDZ128rrik_alt; break;
348  case X86_VPCMPUDZ256rmi: NewOpc = X86_VPCMPUDZ256rmi_alt; break;
349  case X86_VPCMPUDZ256rmib: NewOpc = X86_VPCMPUDZ256rmib_alt; break;
350  case X86_VPCMPUDZ256rmibk: NewOpc = X86_VPCMPUDZ256rmibk_alt; break;
351  case X86_VPCMPUDZ256rmik: NewOpc = X86_VPCMPUDZ256rmik_alt; break;
352  case X86_VPCMPUDZ256rri: NewOpc = X86_VPCMPUDZ256rri_alt; break;
353  case X86_VPCMPUDZ256rrik: NewOpc = X86_VPCMPUDZ256rrik_alt; break;
354  case X86_VPCMPUDZrmi: NewOpc = X86_VPCMPUDZrmi_alt; break;
355  case X86_VPCMPUDZrmib: NewOpc = X86_VPCMPUDZrmib_alt; break;
356  case X86_VPCMPUDZrmibk: NewOpc = X86_VPCMPUDZrmibk_alt; break;
357  case X86_VPCMPUDZrmik: NewOpc = X86_VPCMPUDZrmik_alt; break;
358  case X86_VPCMPUDZrri: NewOpc = X86_VPCMPUDZrri_alt; break;
359  case X86_VPCMPUDZrrik: NewOpc = X86_VPCMPUDZrrik_alt; break;
360  case X86_VPCMPUQZ128rmi: NewOpc = X86_VPCMPUQZ128rmi_alt; break;
361  case X86_VPCMPUQZ128rmib: NewOpc = X86_VPCMPUQZ128rmib_alt; break;
362  case X86_VPCMPUQZ128rmibk: NewOpc = X86_VPCMPUQZ128rmibk_alt; break;
363  case X86_VPCMPUQZ128rmik: NewOpc = X86_VPCMPUQZ128rmik_alt; break;
364  case X86_VPCMPUQZ128rri: NewOpc = X86_VPCMPUQZ128rri_alt; break;
365  case X86_VPCMPUQZ128rrik: NewOpc = X86_VPCMPUQZ128rrik_alt; break;
366  case X86_VPCMPUQZ256rmi: NewOpc = X86_VPCMPUQZ256rmi_alt; break;
367  case X86_VPCMPUQZ256rmib: NewOpc = X86_VPCMPUQZ256rmib_alt; break;
368  case X86_VPCMPUQZ256rmibk: NewOpc = X86_VPCMPUQZ256rmibk_alt; break;
369  case X86_VPCMPUQZ256rmik: NewOpc = X86_VPCMPUQZ256rmik_alt; break;
370  case X86_VPCMPUQZ256rri: NewOpc = X86_VPCMPUQZ256rri_alt; break;
371  case X86_VPCMPUQZ256rrik: NewOpc = X86_VPCMPUQZ256rrik_alt; break;
372  case X86_VPCMPUQZrmi: NewOpc = X86_VPCMPUQZrmi_alt; break;
373  case X86_VPCMPUQZrmib: NewOpc = X86_VPCMPUQZrmib_alt; break;
374  case X86_VPCMPUQZrmibk: NewOpc = X86_VPCMPUQZrmibk_alt; break;
375  case X86_VPCMPUQZrmik: NewOpc = X86_VPCMPUQZrmik_alt; break;
376  case X86_VPCMPUQZrri: NewOpc = X86_VPCMPUQZrri_alt; break;
377  case X86_VPCMPUQZrrik: NewOpc = X86_VPCMPUQZrrik_alt; break;
378  case X86_VPCMPUWZ128rmi: NewOpc = X86_VPCMPUWZ128rmi_alt; break;
379  case X86_VPCMPUWZ128rmik: NewOpc = X86_VPCMPUWZ128rmik_alt; break;
380  case X86_VPCMPUWZ128rri: NewOpc = X86_VPCMPUWZ128rri_alt; break;
381  case X86_VPCMPUWZ128rrik: NewOpc = X86_VPCMPUWZ128rrik_alt; break;
382  case X86_VPCMPUWZ256rmi: NewOpc = X86_VPCMPUWZ256rmi_alt; break;
383  case X86_VPCMPUWZ256rmik: NewOpc = X86_VPCMPUWZ256rmik_alt; break;
384  case X86_VPCMPUWZ256rri: NewOpc = X86_VPCMPUWZ256rri_alt; break;
385  case X86_VPCMPUWZ256rrik: NewOpc = X86_VPCMPUWZ256rrik_alt; break;
386  case X86_VPCMPUWZrmi: NewOpc = X86_VPCMPUWZrmi_alt; break;
387  case X86_VPCMPUWZrmik: NewOpc = X86_VPCMPUWZrmik_alt; break;
388  case X86_VPCMPUWZrri: NewOpc = X86_VPCMPUWZrri_alt; break;
389  case X86_VPCMPUWZrrik: NewOpc = X86_VPCMPUWZrrik_alt; break;
390  case X86_VPCMPWZ128rmi: NewOpc = X86_VPCMPWZ128rmi_alt; break;
391  case X86_VPCMPWZ128rmik: NewOpc = X86_VPCMPWZ128rmik_alt; break;
392  case X86_VPCMPWZ128rri: NewOpc = X86_VPCMPWZ128rri_alt; break;
393  case X86_VPCMPWZ128rrik: NewOpc = X86_VPCMPWZ128rrik_alt; break;
394  case X86_VPCMPWZ256rmi: NewOpc = X86_VPCMPWZ256rmi_alt; break;
395  case X86_VPCMPWZ256rmik: NewOpc = X86_VPCMPWZ256rmik_alt; break;
396  case X86_VPCMPWZ256rri: NewOpc = X86_VPCMPWZ256rri_alt; break;
397  case X86_VPCMPWZ256rrik: NewOpc = X86_VPCMPWZ256rrik_alt; break;
398  case X86_VPCMPWZrmi: NewOpc = X86_VPCMPWZrmi_alt; break;
399  case X86_VPCMPWZrmik: NewOpc = X86_VPCMPWZrmik_alt; break;
400  case X86_VPCMPWZrri: NewOpc = X86_VPCMPWZrri_alt; break;
401  case X86_VPCMPWZrrik: NewOpc = X86_VPCMPWZrrik_alt; break;
402  }
403  // Switch opcode to the one that doesn't get special printing.
404  if (NewOpc != 0) {
405  MCInst_setOpcode(mcInst, NewOpc);
406  }
407  }
408 #endif
409  }
410 
411  switch (type) {
412  case TYPE_XMM32:
413  case TYPE_XMM64:
414  case TYPE_XMM128:
415  MCOperand_CreateReg0(mcInst, X86_XMM0 + ((uint32_t)immediate >> 4));
416  return;
417  case TYPE_XMM256:
418  MCOperand_CreateReg0(mcInst, X86_YMM0 + ((uint32_t)immediate >> 4));
419  return;
420  case TYPE_XMM512:
421  MCOperand_CreateReg0(mcInst, X86_ZMM0 + ((uint32_t)immediate >> 4));
422  return;
423  case TYPE_REL8:
424  if(immediate & 0x80)
425  immediate |= ~(0xffull);
426  break;
427  case TYPE_REL32:
428  case TYPE_REL64:
429  if(immediate & 0x80000000)
430  immediate |= ~(0xffffffffull);
431  break;
432  default:
433  // operand is 64 bits wide. Do nothing.
434  break;
435  }
436 
437  MCOperand_CreateImm0(mcInst, immediate);
438 
439  if (type == TYPE_MOFFS8 || type == TYPE_MOFFS16 ||
440  type == TYPE_MOFFS32 || type == TYPE_MOFFS64) {
441  MCOperand_CreateReg0(mcInst, segmentRegnums[insn->segmentOverride]);
442  }
443 }
444 
451 static bool translateRMRegister(MCInst *mcInst, InternalInstruction *insn)
452 {
453  if (insn->eaBase == EA_BASE_sib || insn->eaBase == EA_BASE_sib64) {
454  //debug("A R/M register operand may not have a SIB byte");
455  return true;
456  }
457 
458  switch (insn->eaBase) {
459  case EA_BASE_NONE:
460  //debug("EA_BASE_NONE for ModR/M base");
461  return true;
462 #define ENTRY(x) case EA_BASE_##x:
464 #undef ENTRY
465  //debug("A R/M register operand may not have a base; "
466  // "the operand must be a register.");
467  return true;
468 #define ENTRY(x) \
469  case EA_REG_##x: \
470  MCOperand_CreateReg0(mcInst, X86_##x); break;
471  ALL_REGS
472 #undef ENTRY
473  default:
474  //debug("Unexpected EA base register");
475  return true;
476  }
477 
478  return false;
479 }
480 
489 static bool translateRMMemory(MCInst *mcInst, InternalInstruction *insn)
490 {
491  // Addresses in an MCInst are represented as five operands:
492  // 1. basereg (register) The R/M base, or (if there is a SIB) the
493  // SIB base
494  // 2. scaleamount (immediate) 1, or (if there is a SIB) the specified
495  // scale amount
496  // 3. indexreg (register) x86_registerNONE, or (if there is a SIB)
497  // the index (which is multiplied by the
498  // scale amount)
499  // 4. displacement (immediate) 0, or the displacement if there is one
500  // 5. segmentreg (register) x86_registerNONE for now, but could be set
501  // if we have segment overrides
502 
503  bool IndexIs512, IndexIs128, IndexIs256;
504  int scaleAmount, indexReg;
505 #ifndef CAPSTONE_X86_REDUCE
507 #endif
508 
509  if (insn->eaBase == EA_BASE_sib || insn->eaBase == EA_BASE_sib64) {
510  if (insn->sibBase != SIB_BASE_NONE) {
511  switch (insn->sibBase) {
512 #define ENTRY(x) \
513  case SIB_BASE_##x: \
514  MCOperand_CreateReg0(mcInst, X86_##x); break;
516 #undef ENTRY
517  default:
518  //debug("Unexpected sibBase");
519  return true;
520  }
521  } else {
522  MCOperand_CreateReg0(mcInst, 0);
523  }
524 
525  // Check whether we are handling VSIB addressing mode for GATHER.
526  // If sibIndex was set to SIB_INDEX_NONE, index offset is 4 and
527  // we should use SIB_INDEX_XMM4|YMM4 for VSIB.
528  // I don't see a way to get the correct IndexReg in readSIB:
529  // We can tell whether it is VSIB or SIB after instruction ID is decoded,
530  // but instruction ID may not be decoded yet when calling readSIB.
531 #ifndef CAPSTONE_X86_REDUCE
532  Opcode = MCInst_getOpcode(mcInst);
533 #endif
534  IndexIs128 = (
535 #ifndef CAPSTONE_X86_REDUCE
536  Opcode == X86_VGATHERDPDrm ||
537  Opcode == X86_VGATHERDPDYrm ||
538  Opcode == X86_VGATHERQPDrm ||
539  Opcode == X86_VGATHERDPSrm ||
540  Opcode == X86_VGATHERQPSrm ||
541  Opcode == X86_VPGATHERDQrm ||
542  Opcode == X86_VPGATHERDQYrm ||
543  Opcode == X86_VPGATHERQQrm ||
544  Opcode == X86_VPGATHERDDrm ||
545  Opcode == X86_VPGATHERQDrm ||
546 #endif
547  false
548  );
549  IndexIs256 = (
550 #ifndef CAPSTONE_X86_REDUCE
551  Opcode == X86_VGATHERQPDYrm ||
552  Opcode == X86_VGATHERDPSYrm ||
553  Opcode == X86_VGATHERQPSYrm ||
554  Opcode == X86_VGATHERDPDZrm ||
555  Opcode == X86_VPGATHERDQZrm ||
556  Opcode == X86_VPGATHERQQYrm ||
557  Opcode == X86_VPGATHERDDYrm ||
558  Opcode == X86_VPGATHERQDYrm ||
559 #endif
560  false
561  );
562  IndexIs512 = (
563 #ifndef CAPSTONE_X86_REDUCE
564  Opcode == X86_VGATHERQPDZrm ||
565  Opcode == X86_VGATHERDPSZrm ||
566  Opcode == X86_VGATHERQPSZrm ||
567  Opcode == X86_VPGATHERQQZrm ||
568  Opcode == X86_VPGATHERDDZrm ||
569  Opcode == X86_VPGATHERQDZrm ||
570 #endif
571  false
572  );
573 
574  if (IndexIs128 || IndexIs256 || IndexIs512) {
575  unsigned IndexOffset = insn->sibIndex -
576  (insn->addressSize == 8 ? SIB_INDEX_RAX:SIB_INDEX_EAX);
577  SIBIndex IndexBase = IndexIs512 ? SIB_INDEX_ZMM0 :
578  IndexIs256 ? SIB_INDEX_YMM0 : SIB_INDEX_XMM0;
579 
580  insn->sibIndex = (SIBIndex)(IndexBase + (insn->sibIndex == SIB_INDEX_NONE ? 4 : IndexOffset));
581  }
582 
583  if (insn->sibIndex != SIB_INDEX_NONE) {
584  switch (insn->sibIndex) {
585  default:
586  //debug("Unexpected sibIndex");
587  return true;
588 #define ENTRY(x) \
589  case SIB_INDEX_##x: \
590  indexReg = X86_##x; break;
593  REGS_XMM
594  REGS_YMM
595  REGS_ZMM
596 #undef ENTRY
597  }
598  } else {
599  indexReg = 0;
600  }
601 
602  scaleAmount = insn->sibScale;
603  } else {
604  switch (insn->eaBase) {
605  case EA_BASE_NONE:
606  if (insn->eaDisplacement == EA_DISP_NONE) {
607  //debug("EA_BASE_NONE and EA_DISP_NONE for ModR/M base");
608  return true;
609  }
610  if (insn->mode == MODE_64BIT) {
611  if (insn->prefix3 == 0x67) // address-size prefix overrides RIP relative addressing
612  MCOperand_CreateReg0(mcInst, X86_EIP);
613  else
614  MCOperand_CreateReg0(mcInst, X86_RIP); // Section 2.2.1.6
615  } else {
616  MCOperand_CreateReg0(mcInst, 0);
617  }
618 
619  indexReg = 0;
620  break;
621  case EA_BASE_BX_SI:
622  MCOperand_CreateReg0(mcInst, X86_BX);
623  indexReg = X86_SI;
624  break;
625  case EA_BASE_BX_DI:
626  MCOperand_CreateReg0(mcInst, X86_BX);
627  indexReg = X86_DI;
628  break;
629  case EA_BASE_BP_SI:
630  MCOperand_CreateReg0(mcInst, X86_BP);
631  indexReg = X86_SI;
632  break;
633  case EA_BASE_BP_DI:
634  MCOperand_CreateReg0(mcInst, X86_BP);
635  indexReg = X86_DI;
636  break;
637  default:
638  indexReg = 0;
639  switch (insn->eaBase) {
640  default:
641  //debug("Unexpected eaBase");
642  return true;
643  // Here, we will use the fill-ins defined above. However,
644  // BX_SI, BX_DI, BP_SI, and BP_DI are all handled above and
645  // sib and sib64 were handled in the top-level if, so they're only
646  // placeholders to keep the compiler happy.
647 #define ENTRY(x) \
648  case EA_BASE_##x: \
649  MCOperand_CreateReg0(mcInst, X86_##x); break;
651 #undef ENTRY
652 #define ENTRY(x) case EA_REG_##x:
653  ALL_REGS
654 #undef ENTRY
655  //debug("A R/M memory operand may not be a register; "
656  // "the base field must be a base.");
657  return true;
658  }
659  }
660 
661  scaleAmount = 1;
662  }
663 
664  MCOperand_CreateImm0(mcInst, scaleAmount);
665  MCOperand_CreateReg0(mcInst, indexReg);
666  MCOperand_CreateImm0(mcInst, insn->displacement);
667 
668  MCOperand_CreateReg0(mcInst, segmentRegnums[insn->segmentOverride]);
669 
670  return false;
671 }
672 
681 static bool translateRM(MCInst *mcInst, const OperandSpecifier *operand,
682  InternalInstruction *insn)
683 {
684  switch (operand->type) {
685  case TYPE_R8:
686  case TYPE_R16:
687  case TYPE_R32:
688  case TYPE_R64:
689  case TYPE_Rv:
690  case TYPE_MM64:
691  case TYPE_XMM:
692  case TYPE_XMM32:
693  case TYPE_XMM64:
694  case TYPE_XMM128:
695  case TYPE_XMM256:
696  case TYPE_XMM512:
697  case TYPE_VK1:
698  case TYPE_VK8:
699  case TYPE_VK16:
700  case TYPE_DEBUGREG:
701  case TYPE_CONTROLREG:
702  return translateRMRegister(mcInst, insn);
703  case TYPE_M:
704  case TYPE_M8:
705  case TYPE_M16:
706  case TYPE_M32:
707  case TYPE_M64:
708  case TYPE_M128:
709  case TYPE_M256:
710  case TYPE_M512:
711  case TYPE_Mv:
712  case TYPE_M32FP:
713  case TYPE_M64FP:
714  case TYPE_M80FP:
715  case TYPE_M1616:
716  case TYPE_M1632:
717  case TYPE_M1664:
718  case TYPE_LEA:
719  return translateRMMemory(mcInst, insn);
720  default:
721  //debug("Unexpected type for a R/M operand");
722  return true;
723  }
724 }
725 
731 static void translateFPRegister(MCInst *mcInst, uint8_t stackPos)
732 {
733  MCOperand_CreateReg0(mcInst, X86_ST0 + stackPos);
734 }
735 
742 static bool translateMaskRegister(MCInst *mcInst, uint8_t maskRegNum)
743 {
744  if (maskRegNum >= 8) {
745  // debug("Invalid mask register number");
746  return true;
747  }
748 
749  MCOperand_CreateReg0(mcInst, X86_K0 + maskRegNum);
750 
751  return false;
752 }
753 
761 static bool translateOperand(MCInst *mcInst, const OperandSpecifier *operand, InternalInstruction *insn)
762 {
763  switch (operand->encoding) {
764  case ENCODING_REG:
765  translateRegister(mcInst, insn->reg);
766  return false;
767  case ENCODING_WRITEMASK:
768  return translateMaskRegister(mcInst, insn->writemask);
770  return translateRM(mcInst, operand, insn);
771  case ENCODING_CB:
772  case ENCODING_CW:
773  case ENCODING_CD:
774  case ENCODING_CP:
775  case ENCODING_CO:
776  case ENCODING_CT:
777  //debug("Translation of code offsets isn't supported.");
778  return true;
779  case ENCODING_IB:
780  case ENCODING_IW:
781  case ENCODING_ID:
782  case ENCODING_IO:
783  case ENCODING_Iv:
784  case ENCODING_Ia:
785  translateImmediate(mcInst, insn->immediates[insn->numImmediatesTranslated++], operand, insn);
786  return false;
787  case ENCODING_SI:
788  return translateSrcIndex(mcInst, insn);
789  case ENCODING_DI:
790  return translateDstIndex(mcInst, insn);
791  case ENCODING_RB:
792  case ENCODING_RW:
793  case ENCODING_RD:
794  case ENCODING_RO:
795  case ENCODING_Rv:
796  translateRegister(mcInst, insn->opcodeRegister);
797  return false;
798  case ENCODING_FP:
799  translateFPRegister(mcInst, insn->modRM & 7);
800  return false;
801  case ENCODING_VVVV:
802  translateRegister(mcInst, insn->vvvv);
803  return false;
804  case ENCODING_DUP:
805  return translateOperand(mcInst, &insn->operands[operand->type - TYPE_DUP0], insn);
806  default:
807  //debug("Unhandled operand encoding during translation");
808  return true;
809  }
810 }
811 
812 static bool translateInstruction(MCInst *mcInst, InternalInstruction *insn)
813 {
814  int index;
815 
816  if (!insn->spec) {
817  //debug("Instruction has no specification");
818  return true;
819  }
820 
821  MCInst_setOpcode(mcInst, insn->instructionID);
822 
823  // If when reading the prefix bytes we determined the overlapping 0xf2 or 0xf3
824  // prefix bytes should be disassembled as xrelease and xacquire then set the
825  // opcode to those instead of the rep and repne opcodes.
826 #ifndef CAPSTONE_X86_REDUCE
827  if (insn->xAcquireRelease) {
828  if (MCInst_getOpcode(mcInst) == X86_REP_PREFIX)
829  MCInst_setOpcode(mcInst, X86_XRELEASE_PREFIX);
830  else if (MCInst_getOpcode(mcInst) == X86_REPNE_PREFIX)
831  MCInst_setOpcode(mcInst, X86_XACQUIRE_PREFIX);
832  }
833 #endif
834 
835  insn->numImmediatesTranslated = 0;
836 
837  for (index = 0; index < X86_MAX_OPERANDS; ++index) {
838  if (insn->operands[index].encoding != ENCODING_NONE) {
839  if (translateOperand(mcInst, &insn->operands[index], insn)) {
840  return true;
841  }
842  }
843  }
844 
845  return false;
846 }
847 
848 static int reader(const struct reader_info *info, uint8_t *byte, uint64_t address)
849 {
850  if (address - info->offset >= info->size)
851  // out of buffer range
852  return -1;
853 
854  *byte = info->code[address - info->offset];
855 
856  return 0;
857 }
858 
859 // copy x86 detail information from internal structure to public structure
860 static void update_pub_insn(cs_insn *pub, InternalInstruction *inter)
861 {
862  if (inter->vectorExtensionType != 0)
863  memcpy(pub->detail->x86.opcode, inter->vectorExtensionPrefix, sizeof(pub->detail->x86.opcode));
864  else {
865  if (inter->twoByteEscape) {
866  if (inter->threeByteEscape) {
867  pub->detail->x86.opcode[0] = inter->twoByteEscape;
868  pub->detail->x86.opcode[1] = inter->threeByteEscape;
869  pub->detail->x86.opcode[2] = inter->opcode;
870  } else {
871  pub->detail->x86.opcode[0] = inter->twoByteEscape;
872  pub->detail->x86.opcode[1] = inter->opcode;
873  }
874  } else {
875  pub->detail->x86.opcode[0] = inter->opcode;
876  }
877  }
878 
879  pub->detail->x86.rex = inter->rexPrefix;
880 
881  pub->detail->x86.addr_size = inter->addressSize;
882 
883  pub->detail->x86.modrm = inter->orgModRM;
884  pub->detail->x86.encoding.modrm_offset = inter->modRMOffset;
885 
886  pub->detail->x86.sib = inter->sib;
887  pub->detail->x86.sib_index = x86_map_sib_index(inter->sibIndex);
888  pub->detail->x86.sib_scale = inter->sibScale;
889  pub->detail->x86.sib_base = x86_map_sib_base(inter->sibBase);
890 
891  pub->detail->x86.disp = inter->displacement;
892  if (inter->consumedDisplacement) {
893  pub->detail->x86.encoding.disp_offset = inter->displacementOffset;
894  pub->detail->x86.encoding.disp_size = inter->displacementSize;
895  }
896 
897  pub->detail->x86.encoding.imm_offset = inter->immediateOffset;
898  if (pub->detail->x86.encoding.imm_size == 0 && inter->immediateOffset != 0)
899  pub->detail->x86.encoding.imm_size = inter->immediateSize;
900 }
901 
902 void X86_init(MCRegisterInfo *MRI)
903 {
904  /*
905  InitMCRegisterInfo(X86RegDesc, 234,
906  RA, PC,
907  X86MCRegisterClasses, 79,
908  X86RegUnitRoots, 119, X86RegDiffLists, X86RegStrings,
909  X86SubRegIdxLists, 7,
910  X86SubRegIdxRanges, X86RegEncodingTable);
911  */
912 
913  MCRegisterInfo_InitMCRegisterInfo(MRI, X86RegDesc, 234,
914  0, 0,
915  X86MCRegisterClasses, 79,
916  0, 0, X86RegDiffLists, 0,
917  X86SubRegIdxLists, 7,
918  0);
919 }
920 
921 // Public interface for the disassembler
922 bool X86_getInstruction(csh ud, const uint8_t *code, size_t code_len,
923  MCInst *instr, uint16_t *size, uint64_t address, void *_info)
924 {
926  InternalInstruction insn = {0};
927  struct reader_info info;
928  int ret;
929  bool result;
930 
931  info.code = code;
932  info.size = code_len;
933  info.offset = address;
934 
935  if (instr->flat_insn->detail) {
936  // instr->flat_insn->detail initialization: 3 alternatives
937 
938  // 1. The whole structure, this is how it's done in other arch disassemblers
939  // Probably overkill since cs_detail is huge because of the 36 operands of ARM
940 
941  //memset(instr->flat_insn->detail, 0, sizeof(cs_detail));
942 
943  // 2. Only the part relevant to x86
944  memset(instr->flat_insn->detail, 0, offsetof(cs_detail, x86) + sizeof(cs_x86));
945 
946  // 3. The relevant part except for x86.operands
947  // sizeof(cs_x86) is 0x1c0, sizeof(x86.operands) is 0x180
948  // marginally faster, should be okay since x86.op_count is set to 0
949 
950  //memset(instr->flat_insn->detail, 0, offsetof(cs_detail, x86)+offsetof(cs_x86, operands));
951  }
952 
953  if (handle->mode & CS_MODE_16)
954  ret = decodeInstruction(&insn,
955  reader, &info,
956  address,
957  MODE_16BIT);
958  else if (handle->mode & CS_MODE_32)
959  ret = decodeInstruction(&insn,
960  reader, &info,
961  address,
962  MODE_32BIT);
963  else
964  ret = decodeInstruction(&insn,
965  reader, &info,
966  address,
967  MODE_64BIT);
968 
969  if (ret) {
970  *size = (uint16_t)(insn.readerCursor - address);
971  // handle some special cases here.
972  // FIXME: fix this in the next major update.
973  switch(*size) {
974  default:
975  break;
976  case 2: {
977  unsigned char b1 = 0, b2 = 0;
978 
979  reader(&info, &b1, address);
980  reader(&info, &b2, address + 1);
981  if (b1 == 0x0f && b2 == 0xff) {
982  instr->Opcode = X86_UD0;
983  instr->OpcodePub = X86_INS_UD0;
984  strncpy(instr->assembly, "ud0", 4);
985  if (instr->flat_insn->detail) {
986  instr->flat_insn->detail->x86.opcode[0] = b1;
987  instr->flat_insn->detail->x86.opcode[1] = b2;
988  }
989  return true;
990  }
991  }
992  return false;
993  case 4: {
994 #ifndef CAPSTONE_X86_REDUCE
995  if (handle->mode != CS_MODE_16) {
996  unsigned char b1 = 0, b2 = 0, b3 = 0, b4 = 0;
997 
998  reader(&info, &b1, address);
999  reader(&info, &b2, address + 1);
1000  reader(&info, &b3, address + 2);
1001  reader(&info, &b4, address + 3);
1002 
1003  if (b1 == 0xf3 && b2 == 0x0f && b3 == 0x1e && b4 == 0xfa) {
1004  instr->Opcode = X86_ENDBR64;
1005  instr->OpcodePub = X86_INS_ENDBR64;
1006  strncpy(instr->assembly, "endbr64", 8);
1007  if (instr->flat_insn->detail) {
1008  instr->flat_insn->detail->x86.opcode[0] = b1;
1009  instr->flat_insn->detail->x86.opcode[1] = b2;
1010  instr->flat_insn->detail->x86.opcode[2] = b3;
1011  instr->flat_insn->detail->x86.opcode[3] = b4;
1012  }
1013  return true;
1014  } else if (b1 == 0xf3 && b2 == 0x0f && b3 == 0x1e && b4 == 0xfb) {
1015  instr->Opcode = X86_ENDBR32;
1016  instr->OpcodePub = X86_INS_ENDBR32;
1017  strncpy(instr->assembly, "endbr32", 8);
1018  if (instr->flat_insn->detail) {
1019  instr->flat_insn->detail->x86.opcode[0] = b1;
1020  instr->flat_insn->detail->x86.opcode[1] = b2;
1021  instr->flat_insn->detail->x86.opcode[2] = b3;
1022  instr->flat_insn->detail->x86.opcode[3] = b4;
1023  }
1024  return true;
1025  }
1026  }
1027 #endif
1028  }
1029  return false;
1030  }
1031 
1032  return false;
1033  } else {
1034  *size = (uint16_t)insn.length;
1035 
1036  result = (!translateInstruction(instr, &insn)) ? true : false;
1037  if (result) {
1038  // quick fix for #904. TODO: fix this properly in the next update
1039  if (handle->mode & CS_MODE_64) {
1040  if (instr->Opcode == X86_LES16rm || instr->Opcode == X86_LES32rm)
1041  // LES is invalid in x64
1042  return false;
1043  if (instr->Opcode == X86_LDS16rm || instr->Opcode == X86_LDS32rm)
1044  // LDS is invalid in x64
1045  return false;
1046  }
1047 
1048  instr->imm_size = insn.immSize;
1049 
1050  // copy all prefixes
1051  instr->x86_prefix[0] = insn.prefix0;
1052  instr->x86_prefix[1] = insn.prefix1;
1053  instr->x86_prefix[2] = insn.prefix2;
1054  instr->x86_prefix[3] = insn.prefix3;
1055  instr->xAcquireRelease = insn.xAcquireRelease;
1056 
1057  if (handle->detail) {
1058  update_pub_insn(instr->flat_insn, &insn);
1059  }
1060  }
1061 
1062  return result;
1063  }
1064 }
1065 
1066 #endif
unsigned MCInst_getOpcode(const MCInst *inst)
Definition: MCInst.c:68
void MCOperand_CreateReg0(MCInst *mcInst, unsigned Reg)
Definition: MCInst.c:158
void MCInst_setOpcode(MCInst *inst, unsigned Op)
Definition: MCInst.c:58
void MCOperand_CreateImm0(MCInst *mcInst, int64_t Val)
Definition: MCInst.c:177
void MCRegisterInfo_InitMCRegisterInfo(MCRegisterInfo *RI, const MCRegisterDesc *D, unsigned NR, unsigned RA, unsigned PC, const MCRegisterClass *C, unsigned NC, uint16_t(*RURoots)[2], unsigned NRU, const MCPhysReg *DL, const char *Strings, const uint16_t *SubIndices, unsigned NumIndices, const uint16_t *RET)
#define CASE_ENCODING_RM
#define X86_MAX_OPERANDS
@ SIB_INDEX_NONE
int decodeInstruction(struct InternalInstruction *insn, byteReader_t reader, const void *readerArg, uint64_t startLoc, DisassemblerMode mode)
@ SEG_OVERRIDE_max
#define EA_BASES_64BIT
#define REGS_YMM
#define REGS_XMM
#define ALL_REGS
#define ALL_SIB_BASES
#define EA_BASES_32BIT
#define REGS_ZMM
#define ALL_EA_BASES
void X86_init(MCRegisterInfo *MRI)
bool X86_getInstruction(csh handle, const uint8_t *code, size_t code_len, MCInst *instr, uint16_t *size, uint64_t address, void *info)
x86_reg x86_map_sib_index(int r)
x86_reg x86_map_sib_base(int r)
operand
Definition: arc-opc.c:39
static mcore_handle handle
Definition: asm_mcore.c:8
struct Opcode_t Opcode
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
size_t csh
Definition: capstone.h:71
@ X86_INS_UD0
Definition: x86.h:1894
@ X86_INS_ENDBR64
Definition: x86.h:1896
@ X86_INS_ENDBR32
Definition: x86.h:1895
#define false
voidpf void uLong size
Definition: ioapi.h:138
#define offsetof(type, member)
#define reg(n)
return memset(p, 0, total)
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
int type
Definition: mipsasm.c:17
const char * code
Definition: pal.c:98
unsigned short uint16_t
Definition: sftypes.h:30
unsigned int uint32_t
Definition: sftypes.h:29
unsigned long uint64_t
Definition: sftypes.h:28
unsigned char uint8_t
Definition: sftypes.h:31
_W64 unsigned int uintptr_t
const struct InstructionSpecifier * spec
VectorExtensionType vectorExtensionType
const struct OperandSpecifier * operands
SegmentOverride segmentOverride
Definition: MCInst.h:88
cs_insn * flat_insn
Definition: MCInst.h:95
uint8_t imm_size
Definition: MCInst.h:104
char assembly[8]
Definition: MCInst.h:109
uint8_t xAcquireRelease
Definition: MCInst.h:111
unsigned OpcodePub
Definition: MCInst.h:89
uint8_t x86_prefix[4]
Definition: MCInst.h:103
unsigned Opcode
Definition: MCInst.h:93
Definition: inftree9.h:24
Instruction structure.
Definition: x86.h:312
void reader(void *n)
Definition: main.c:8
if(dbg->bits==RZ_SYS_BITS_64)
Definition: windows-arm64.h:4