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-2014 */
19
20 #ifdef CAPSTONE_HAS_X86
21
22 #include <string.h>
23
24 #include "../../cs_priv.h"
25
26 #include "X86Disassembler.h"
27 #include "X86DisassemblerDecoderCommon.h"
28 #include "X86DisassemblerDecoder.h"
29 #include "../../MCInst.h"
30 #include "../../utils.h"
31 #include "X86Mapping.h"
32
33 #define GET_REGINFO_ENUM
34 #define GET_REGINFO_MC_DESC
35 #include "X86GenRegisterInfo.inc"
36
37 #define GET_INSTRINFO_ENUM
38 #ifdef CAPSTONE_X86_REDUCE
39 #include "X86GenInstrInfo_reduce.inc"
40 #else
41 #include "X86GenInstrInfo.inc"
42 #endif
43
44 // Fill-ins to make the compiler happy. These constants are never actually
45 // assigned; they are just filler to make an automatically-generated switch
46 // statement work.
47 enum {
48 X86_BX_SI = 500,
49 X86_BX_DI = 501,
50 X86_BP_SI = 502,
51 X86_BP_DI = 503,
52 X86_sib = 504,
53 X86_sib64 = 505
54 };
55
56 //
57 // Private code that translates from struct InternalInstructions to MCInsts.
58 //
59
60 /// translateRegister - Translates an internal register to the appropriate LLVM
61 /// register, and appends it as an operand to an MCInst.
62 ///
63 /// @param mcInst - The MCInst to append to.
64 /// @param reg - The Reg to append.
translateRegister(MCInst * mcInst,Reg reg)65 static void translateRegister(MCInst *mcInst, Reg reg)
66 {
67 #define ENTRY(x) X86_##x,
68 uint8_t llvmRegnums[] = {
69 ALL_REGS
70 0
71 };
72 #undef ENTRY
73
74 uint8_t llvmRegnum = llvmRegnums[reg];
75 MCOperand_CreateReg0(mcInst, llvmRegnum);
76 }
77
78 static const uint8_t segmentRegnums[SEG_OVERRIDE_max] = {
79 0, // SEG_OVERRIDE_NONE
80 X86_CS,
81 X86_SS,
82 X86_DS,
83 X86_ES,
84 X86_FS,
85 X86_GS
86 };
87
88 /// translateSrcIndex - Appends a source index operand to an MCInst.
89 ///
90 /// @param mcInst - The MCInst to append to.
91 /// @param insn - The internal instruction.
translateSrcIndex(MCInst * mcInst,InternalInstruction * insn)92 static bool translateSrcIndex(MCInst *mcInst, InternalInstruction *insn)
93 {
94 unsigned baseRegNo;
95
96 if (insn->mode == MODE_64BIT)
97 baseRegNo = insn->isPrefix67 ? X86_ESI : X86_RSI;
98 else if (insn->mode == MODE_32BIT)
99 baseRegNo = insn->isPrefix67 ? X86_SI : X86_ESI;
100 else {
101 // assert(insn->mode == MODE_16BIT);
102 baseRegNo = insn->isPrefix67 ? X86_ESI : X86_SI;
103 }
104
105 MCOperand_CreateReg0(mcInst, baseRegNo);
106
107 MCOperand_CreateReg0(mcInst, segmentRegnums[insn->segmentOverride]);
108
109 return false;
110 }
111
112 /// translateDstIndex - Appends a destination index operand to an MCInst.
113 ///
114 /// @param mcInst - The MCInst to append to.
115 /// @param insn - The internal instruction.
translateDstIndex(MCInst * mcInst,InternalInstruction * insn)116 static bool translateDstIndex(MCInst *mcInst, InternalInstruction *insn)
117 {
118 unsigned baseRegNo;
119
120 if (insn->mode == MODE_64BIT)
121 baseRegNo = insn->isPrefix67 ? X86_EDI : X86_RDI;
122 else if (insn->mode == MODE_32BIT)
123 baseRegNo = insn->isPrefix67 ? X86_DI : X86_EDI;
124 else {
125 // assert(insn->mode == MODE_16BIT);
126 baseRegNo = insn->isPrefix67 ? X86_EDI : X86_DI;
127 }
128
129 MCOperand_CreateReg0(mcInst, baseRegNo);
130
131 return false;
132 }
133
134 /// translateImmediate - Appends an immediate operand to an MCInst.
135 ///
136 /// @param mcInst - The MCInst to append to.
137 /// @param immediate - The immediate value to append.
138 /// @param operand - The operand, as stored in the descriptor table.
139 /// @param insn - The internal instruction.
translateImmediate(MCInst * mcInst,uint64_t immediate,const OperandSpecifier * operand,InternalInstruction * insn)140 static void translateImmediate(MCInst *mcInst, uint64_t immediate,
141 const OperandSpecifier *operand, InternalInstruction *insn)
142 {
143 OperandType type;
144
145 type = (OperandType)operand->type;
146 if (type == TYPE_RELv) {
147 //isBranch = true;
148 //pcrel = insn->startLocation + insn->immediateOffset + insn->immediateSize;
149 switch (insn->displacementSize) {
150 case 1:
151 if (immediate & 0x80)
152 immediate |= ~(0xffull);
153 break;
154 case 2:
155 if (immediate & 0x8000)
156 immediate |= ~(0xffffull);
157 break;
158 case 4:
159 if (immediate & 0x80000000)
160 immediate |= ~(0xffffffffull);
161 break;
162 case 8:
163 break;
164 default:
165 break;
166 }
167 } // By default sign-extend all X86 immediates based on their encoding.
168 else if (type == TYPE_IMM8 || type == TYPE_IMM16 || type == TYPE_IMM32 ||
169 type == TYPE_IMM64 || type == TYPE_IMMv) {
170
171 uint32_t Opcode = MCInst_getOpcode(mcInst);
172 bool check_opcode;
173
174 switch (operand->encoding) {
175 default:
176 break;
177 case ENCODING_IB:
178 // Special case those X86 instructions that use the imm8 as a set of
179 // bits, bit count, etc. and are not sign-extend.
180 check_opcode = (Opcode != X86_INT);
181 #ifndef CAPSTONE_X86_REDUCE
182 check_opcode = ((Opcode != X86_BLENDPSrri &&
183 Opcode != X86_BLENDPDrri &&
184 Opcode != X86_PBLENDWrri &&
185 Opcode != X86_MPSADBWrri &&
186 Opcode != X86_DPPSrri &&
187 Opcode != X86_DPPDrri &&
188 Opcode != X86_INSERTPSrr &&
189 Opcode != X86_VBLENDPSYrri &&
190 Opcode != X86_VBLENDPSYrmi &&
191 Opcode != X86_VBLENDPDYrri &&
192 Opcode != X86_VBLENDPDYrmi &&
193 Opcode != X86_VPBLENDWrri &&
194 Opcode != X86_VMPSADBWrri &&
195 Opcode != X86_VDPPSYrri &&
196 Opcode != X86_VDPPSYrmi &&
197 Opcode != X86_VDPPDrri &&
198 Opcode != X86_VINSERTPSrr) && check_opcode);
199 #endif
200 if (check_opcode)
201 if(immediate & 0x80)
202 immediate |= ~(0xffull);
203 break;
204 case ENCODING_IW:
205 if(immediate & 0x8000)
206 immediate |= ~(0xffffull);
207 break;
208 case ENCODING_ID:
209 if(immediate & 0x80000000)
210 immediate |= ~(0xffffffffull);
211 break;
212 case ENCODING_IO:
213 break;
214 }
215 } else if (type == TYPE_IMM3) {
216 #ifndef CAPSTONE_X86_REDUCE
217 // Check for immediates that printSSECC can't handle.
218 if (immediate >= 8) {
219 unsigned NewOpc = 0;
220
221 switch (MCInst_getOpcode(mcInst)) {
222 default: break; // never reach
223 case X86_CMPPDrmi: NewOpc = X86_CMPPDrmi_alt; break;
224 case X86_CMPPDrri: NewOpc = X86_CMPPDrri_alt; break;
225 case X86_CMPPSrmi: NewOpc = X86_CMPPSrmi_alt; break;
226 case X86_CMPPSrri: NewOpc = X86_CMPPSrri_alt; break;
227 case X86_CMPSDrm: NewOpc = X86_CMPSDrm_alt; break;
228 case X86_CMPSDrr: NewOpc = X86_CMPSDrr_alt; break;
229 case X86_CMPSSrm: NewOpc = X86_CMPSSrm_alt; break;
230 case X86_CMPSSrr: NewOpc = X86_CMPSSrr_alt; break;
231 }
232 // Switch opcode to the one that doesn't get special printing.
233 if (NewOpc != 0) {
234 MCInst_setOpcode(mcInst, NewOpc);
235 }
236 }
237 #endif
238 } else if (type == TYPE_IMM5) {
239 #ifndef CAPSTONE_X86_REDUCE
240 // Check for immediates that printAVXCC can't handle.
241 if (immediate >= 32) {
242 unsigned NewOpc = 0;
243
244 switch (MCInst_getOpcode(mcInst)) {
245 default: break; // unexpected opcode
246 case X86_VCMPPDrmi: NewOpc = X86_VCMPPDrmi_alt; break;
247 case X86_VCMPPDrri: NewOpc = X86_VCMPPDrri_alt; break;
248 case X86_VCMPPSrmi: NewOpc = X86_VCMPPSrmi_alt; break;
249 case X86_VCMPPSrri: NewOpc = X86_VCMPPSrri_alt; break;
250 case X86_VCMPSDrm: NewOpc = X86_VCMPSDrm_alt; break;
251 case X86_VCMPSDrr: NewOpc = X86_VCMPSDrr_alt; break;
252 case X86_VCMPSSrm: NewOpc = X86_VCMPSSrm_alt; break;
253 case X86_VCMPSSrr: NewOpc = X86_VCMPSSrr_alt; break;
254 case X86_VCMPPDYrmi: NewOpc = X86_VCMPPDYrmi_alt; break;
255 case X86_VCMPPDYrri: NewOpc = X86_VCMPPDYrri_alt; break;
256 case X86_VCMPPSYrmi: NewOpc = X86_VCMPPSYrmi_alt; break;
257 case X86_VCMPPSYrri: NewOpc = X86_VCMPPSYrri_alt; break;
258 case X86_VCMPPDZrmi: NewOpc = X86_VCMPPDZrmi_alt; break;
259 case X86_VCMPPDZrri: NewOpc = X86_VCMPPDZrri_alt; break;
260 case X86_VCMPPSZrmi: NewOpc = X86_VCMPPSZrmi_alt; break;
261 case X86_VCMPPSZrri: NewOpc = X86_VCMPPSZrri_alt; break;
262 case X86_VCMPSDZrm: NewOpc = X86_VCMPSDZrmi_alt; break;
263 case X86_VCMPSDZrr: NewOpc = X86_VCMPSDZrri_alt; break;
264 case X86_VCMPSSZrm: NewOpc = X86_VCMPSSZrmi_alt; break;
265 case X86_VCMPSSZrr: NewOpc = X86_VCMPSSZrri_alt; break;
266 }
267 // Switch opcode to the one that doesn't get special printing.
268 if (NewOpc != 0) {
269 MCInst_setOpcode(mcInst, NewOpc);
270 }
271 }
272 #endif
273 }
274
275 switch (type) {
276 case TYPE_XMM32:
277 case TYPE_XMM64:
278 case TYPE_XMM128:
279 MCOperand_CreateReg0(mcInst, X86_XMM0 + ((uint32_t)immediate >> 4));
280 return;
281 case TYPE_XMM256:
282 MCOperand_CreateReg0(mcInst, X86_YMM0 + ((uint32_t)immediate >> 4));
283 return;
284 case TYPE_XMM512:
285 MCOperand_CreateReg0(mcInst, X86_ZMM0 + ((uint32_t)immediate >> 4));
286 return;
287 case TYPE_REL8:
288 if(immediate & 0x80)
289 immediate |= ~(0xffull);
290 break;
291 case TYPE_REL32:
292 case TYPE_REL64:
293 if(immediate & 0x80000000)
294 immediate |= ~(0xffffffffull);
295 break;
296 default:
297 // operand is 64 bits wide. Do nothing.
298 break;
299 }
300
301 MCOperand_CreateImm0(mcInst, immediate);
302
303 if (type == TYPE_MOFFS8 || type == TYPE_MOFFS16 ||
304 type == TYPE_MOFFS32 || type == TYPE_MOFFS64) {
305 MCOperand_CreateReg0(mcInst, segmentRegnums[insn->segmentOverride]);
306 }
307 }
308
309 /// translateRMRegister - Translates a register stored in the R/M field of the
310 /// ModR/M byte to its LLVM equivalent and appends it to an MCInst.
311 /// @param mcInst - The MCInst to append to.
312 /// @param insn - The internal instruction to extract the R/M field
313 /// from.
314 /// @return - 0 on success; -1 otherwise
translateRMRegister(MCInst * mcInst,InternalInstruction * insn)315 static bool translateRMRegister(MCInst *mcInst, InternalInstruction *insn)
316 {
317 if (insn->eaBase == EA_BASE_sib || insn->eaBase == EA_BASE_sib64) {
318 //debug("A R/M register operand may not have a SIB byte");
319 return true;
320 }
321
322 switch (insn->eaBase) {
323 case EA_BASE_NONE:
324 //debug("EA_BASE_NONE for ModR/M base");
325 return true;
326 #define ENTRY(x) case EA_BASE_##x:
327 ALL_EA_BASES
328 #undef ENTRY
329 //debug("A R/M register operand may not have a base; "
330 // "the operand must be a register.");
331 return true;
332 #define ENTRY(x) \
333 case EA_REG_##x: \
334 MCOperand_CreateReg0(mcInst, X86_##x); break;
335 ALL_REGS
336 #undef ENTRY
337 default:
338 //debug("Unexpected EA base register");
339 return true;
340 }
341
342 return false;
343 }
344
345 /// translateRMMemory - Translates a memory operand stored in the Mod and R/M
346 /// fields of an internal instruction (and possibly its SIB byte) to a memory
347 /// operand in LLVM's format, and appends it to an MCInst.
348 ///
349 /// @param mcInst - The MCInst to append to.
350 /// @param insn - The instruction to extract Mod, R/M, and SIB fields
351 /// from.
352 /// @return - 0 on success; nonzero otherwise
translateRMMemory(MCInst * mcInst,InternalInstruction * insn)353 static bool translateRMMemory(MCInst *mcInst, InternalInstruction *insn)
354 {
355 // Addresses in an MCInst are represented as five operands:
356 // 1. basereg (register) The R/M base, or (if there is a SIB) the
357 // SIB base
358 // 2. scaleamount (immediate) 1, or (if there is a SIB) the specified
359 // scale amount
360 // 3. indexreg (register) x86_registerNONE, or (if there is a SIB)
361 // the index (which is multiplied by the
362 // scale amount)
363 // 4. displacement (immediate) 0, or the displacement if there is one
364 // 5. segmentreg (register) x86_registerNONE for now, but could be set
365 // if we have segment overrides
366
367 bool IndexIs512, IndexIs128, IndexIs256;
368 int scaleAmount, indexReg;
369 #ifndef CAPSTONE_X86_REDUCE
370 uint32_t Opcode;
371 #endif
372
373 if (insn->eaBase == EA_BASE_sib || insn->eaBase == EA_BASE_sib64) {
374 if (insn->sibBase != SIB_BASE_NONE) {
375 switch (insn->sibBase) {
376 #define ENTRY(x) \
377 case SIB_BASE_##x: \
378 MCOperand_CreateReg0(mcInst, X86_##x); break;
379 ALL_SIB_BASES
380 #undef ENTRY
381 default:
382 //debug("Unexpected sibBase");
383 return true;
384 }
385 } else {
386 MCOperand_CreateReg0(mcInst, 0);
387 }
388
389 // Check whether we are handling VSIB addressing mode for GATHER.
390 // If sibIndex was set to SIB_INDEX_NONE, index offset is 4 and
391 // we should use SIB_INDEX_XMM4|YMM4 for VSIB.
392 // I don't see a way to get the correct IndexReg in readSIB:
393 // We can tell whether it is VSIB or SIB after instruction ID is decoded,
394 // but instruction ID may not be decoded yet when calling readSIB.
395 #ifndef CAPSTONE_X86_REDUCE
396 Opcode = MCInst_getOpcode(mcInst);
397 #endif
398 IndexIs128 = (
399 #ifndef CAPSTONE_X86_REDUCE
400 Opcode == X86_VGATHERDPDrm ||
401 Opcode == X86_VGATHERDPDYrm ||
402 Opcode == X86_VGATHERQPDrm ||
403 Opcode == X86_VGATHERDPSrm ||
404 Opcode == X86_VGATHERQPSrm ||
405 Opcode == X86_VPGATHERDQrm ||
406 Opcode == X86_VPGATHERDQYrm ||
407 Opcode == X86_VPGATHERQQrm ||
408 Opcode == X86_VPGATHERDDrm ||
409 Opcode == X86_VPGATHERQDrm ||
410 #endif
411 false
412 );
413 IndexIs256 = (
414 #ifndef CAPSTONE_X86_REDUCE
415 Opcode == X86_VGATHERQPDYrm ||
416 Opcode == X86_VGATHERDPSYrm ||
417 Opcode == X86_VGATHERQPSYrm ||
418 Opcode == X86_VGATHERDPDZrm ||
419 Opcode == X86_VPGATHERDQZrm ||
420 Opcode == X86_VPGATHERQQYrm ||
421 Opcode == X86_VPGATHERDDYrm ||
422 Opcode == X86_VPGATHERQDYrm ||
423 #endif
424 false
425 );
426 IndexIs512 = (
427 #ifndef CAPSTONE_X86_REDUCE
428 Opcode == X86_VGATHERQPDZrm ||
429 Opcode == X86_VGATHERDPSZrm ||
430 Opcode == X86_VGATHERQPSZrm ||
431 Opcode == X86_VPGATHERQQZrm ||
432 Opcode == X86_VPGATHERDDZrm ||
433 Opcode == X86_VPGATHERQDZrm ||
434 #endif
435 false
436 );
437
438 if (IndexIs128 || IndexIs256 || IndexIs512) {
439 unsigned IndexOffset = insn->sibIndex -
440 (insn->addressSize == 8 ? SIB_INDEX_RAX:SIB_INDEX_EAX);
441 SIBIndex IndexBase = IndexIs512 ? SIB_INDEX_ZMM0 :
442 IndexIs256 ? SIB_INDEX_YMM0 : SIB_INDEX_XMM0;
443
444 insn->sibIndex = (SIBIndex)(IndexBase + (insn->sibIndex == SIB_INDEX_NONE ? 4 : IndexOffset));
445 }
446
447 if (insn->sibIndex != SIB_INDEX_NONE) {
448 switch (insn->sibIndex) {
449 default:
450 //debug("Unexpected sibIndex");
451 return true;
452 #define ENTRY(x) \
453 case SIB_INDEX_##x: \
454 indexReg = X86_##x; break;
455 EA_BASES_32BIT
456 EA_BASES_64BIT
457 REGS_XMM
458 REGS_YMM
459 REGS_ZMM
460 #undef ENTRY
461 }
462 } else {
463 indexReg = 0;
464 }
465
466 scaleAmount = insn->sibScale;
467 } else {
468 switch (insn->eaBase) {
469 case EA_BASE_NONE:
470 if (insn->eaDisplacement == EA_DISP_NONE) {
471 //debug("EA_BASE_NONE and EA_DISP_NONE for ModR/M base");
472 return true;
473 }
474 if (insn->mode == MODE_64BIT) {
475 if (insn->prefix3 == 0x67) // address-size prefix overrides RIP relative addressing
476 MCOperand_CreateReg0(mcInst, X86_EIP);
477 else
478 MCOperand_CreateReg0(mcInst, X86_RIP); // Section 2.2.1.6
479 } else {
480 MCOperand_CreateReg0(mcInst, 0);
481 }
482
483 indexReg = 0;
484 break;
485 case EA_BASE_BX_SI:
486 MCOperand_CreateReg0(mcInst, X86_BX);
487 indexReg = X86_SI;
488 break;
489 case EA_BASE_BX_DI:
490 MCOperand_CreateReg0(mcInst, X86_BX);
491 indexReg = X86_DI;
492 break;
493 case EA_BASE_BP_SI:
494 MCOperand_CreateReg0(mcInst, X86_BP);
495 indexReg = X86_SI;
496 break;
497 case EA_BASE_BP_DI:
498 MCOperand_CreateReg0(mcInst, X86_BP);
499 indexReg = X86_DI;
500 break;
501 default:
502 indexReg = 0;
503 switch (insn->eaBase) {
504 default:
505 //debug("Unexpected eaBase");
506 return true;
507 // Here, we will use the fill-ins defined above. However,
508 // BX_SI, BX_DI, BP_SI, and BP_DI are all handled above and
509 // sib and sib64 were handled in the top-level if, so they're only
510 // placeholders to keep the compiler happy.
511 #define ENTRY(x) \
512 case EA_BASE_##x: \
513 MCOperand_CreateReg0(mcInst, X86_##x); break;
514 ALL_EA_BASES
515 #undef ENTRY
516 #define ENTRY(x) case EA_REG_##x:
517 ALL_REGS
518 #undef ENTRY
519 //debug("A R/M memory operand may not be a register; "
520 // "the base field must be a base.");
521 return true;
522 }
523 }
524
525 scaleAmount = 1;
526 }
527
528 MCOperand_CreateImm0(mcInst, scaleAmount);
529 MCOperand_CreateReg0(mcInst, indexReg);
530 MCOperand_CreateImm0(mcInst, insn->displacement);
531
532 MCOperand_CreateReg0(mcInst, segmentRegnums[insn->segmentOverride]);
533
534 return false;
535 }
536
537 /// translateRM - Translates an operand stored in the R/M (and possibly SIB)
538 /// byte of an instruction to LLVM form, and appends it to an MCInst.
539 ///
540 /// @param mcInst - The MCInst to append to.
541 /// @param operand - The operand, as stored in the descriptor table.
542 /// @param insn - The instruction to extract Mod, R/M, and SIB fields
543 /// from.
544 /// @return - 0 on success; nonzero otherwise
translateRM(MCInst * mcInst,const OperandSpecifier * operand,InternalInstruction * insn)545 static bool translateRM(MCInst *mcInst, const OperandSpecifier *operand,
546 InternalInstruction *insn)
547 {
548 switch (operand->type) {
549 case TYPE_R8:
550 case TYPE_R16:
551 case TYPE_R32:
552 case TYPE_R64:
553 case TYPE_Rv:
554 case TYPE_MM:
555 case TYPE_MM32:
556 case TYPE_MM64:
557 case TYPE_XMM:
558 case TYPE_XMM32:
559 case TYPE_XMM64:
560 case TYPE_XMM128:
561 case TYPE_XMM256:
562 case TYPE_XMM512:
563 case TYPE_VK1:
564 case TYPE_VK8:
565 case TYPE_VK16:
566 case TYPE_DEBUGREG:
567 case TYPE_CONTROLREG:
568 return translateRMRegister(mcInst, insn);
569 case TYPE_M:
570 case TYPE_M8:
571 case TYPE_M16:
572 case TYPE_M32:
573 case TYPE_M64:
574 case TYPE_M128:
575 case TYPE_M256:
576 case TYPE_M512:
577 case TYPE_Mv:
578 case TYPE_M32FP:
579 case TYPE_M64FP:
580 case TYPE_M80FP:
581 case TYPE_M16INT:
582 case TYPE_M32INT:
583 case TYPE_M64INT:
584 case TYPE_M1616:
585 case TYPE_M1632:
586 case TYPE_M1664:
587 case TYPE_LEA:
588 return translateRMMemory(mcInst, insn);
589 default:
590 //debug("Unexpected type for a R/M operand");
591 return true;
592 }
593 }
594
595 /// translateFPRegister - Translates a stack position on the FPU stack to its
596 /// LLVM form, and appends it to an MCInst.
597 ///
598 /// @param mcInst - The MCInst to append to.
599 /// @param stackPos - The stack position to translate.
translateFPRegister(MCInst * mcInst,uint8_t stackPos)600 static void translateFPRegister(MCInst *mcInst, uint8_t stackPos)
601 {
602 MCOperand_CreateReg0(mcInst, X86_ST0 + stackPos);
603 }
604
605 /// translateMaskRegister - Translates a 3-bit mask register number to
606 /// LLVM form, and appends it to an MCInst.
607 ///
608 /// @param mcInst - The MCInst to append to.
609 /// @param maskRegNum - Number of mask register from 0 to 7.
610 /// @return - false on success; true otherwise.
translateMaskRegister(MCInst * mcInst,uint8_t maskRegNum)611 static bool translateMaskRegister(MCInst *mcInst, uint8_t maskRegNum)
612 {
613 if (maskRegNum >= 8) {
614 // debug("Invalid mask register number");
615 return true;
616 }
617
618 MCOperand_CreateReg0(mcInst, X86_K0 + maskRegNum);
619
620 return false;
621 }
622
623 /// translateOperand - Translates an operand stored in an internal instruction
624 /// to LLVM's format and appends it to an MCInst.
625 ///
626 /// @param mcInst - The MCInst to append to.
627 /// @param operand - The operand, as stored in the descriptor table.
628 /// @param insn - The internal instruction.
629 /// @return - false on success; true otherwise.
translateOperand(MCInst * mcInst,const OperandSpecifier * operand,InternalInstruction * insn)630 static bool translateOperand(MCInst *mcInst, const OperandSpecifier *operand, InternalInstruction *insn)
631 {
632 switch (operand->encoding) {
633 case ENCODING_REG:
634 translateRegister(mcInst, insn->reg);
635 return false;
636 case ENCODING_WRITEMASK:
637 return translateMaskRegister(mcInst, insn->writemask);
638 CASE_ENCODING_RM:
639 return translateRM(mcInst, operand, insn);
640 case ENCODING_CB:
641 case ENCODING_CW:
642 case ENCODING_CD:
643 case ENCODING_CP:
644 case ENCODING_CO:
645 case ENCODING_CT:
646 //debug("Translation of code offsets isn't supported.");
647 return true;
648 case ENCODING_IB:
649 case ENCODING_IW:
650 case ENCODING_ID:
651 case ENCODING_IO:
652 case ENCODING_Iv:
653 case ENCODING_Ia:
654 translateImmediate(mcInst, insn->immediates[insn->numImmediatesTranslated++], operand, insn);
655 return false;
656 case ENCODING_SI:
657 return translateSrcIndex(mcInst, insn);
658 case ENCODING_DI:
659 return translateDstIndex(mcInst, insn);
660 case ENCODING_RB:
661 case ENCODING_RW:
662 case ENCODING_RD:
663 case ENCODING_RO:
664 case ENCODING_Rv:
665 translateRegister(mcInst, insn->opcodeRegister);
666 return false;
667 case ENCODING_FP:
668 translateFPRegister(mcInst, insn->modRM & 7);
669 return false;
670 case ENCODING_VVVV:
671 translateRegister(mcInst, insn->vvvv);
672 return false;
673 case ENCODING_DUP:
674 return translateOperand(mcInst, &insn->operands[operand->type - TYPE_DUP0], insn);
675 default:
676 //debug("Unhandled operand encoding during translation");
677 return true;
678 }
679 }
680
translateInstruction(MCInst * mcInst,InternalInstruction * insn)681 static bool translateInstruction(MCInst *mcInst, InternalInstruction *insn)
682 {
683 int index;
684
685 if (!insn->spec) {
686 //debug("Instruction has no specification");
687 return true;
688 }
689
690 MCInst_setOpcode(mcInst, insn->instructionID);
691
692 // If when reading the prefix bytes we determined the overlapping 0xf2 or 0xf3
693 // prefix bytes should be disassembled as xrelease and xacquire then set the
694 // opcode to those instead of the rep and repne opcodes.
695 #ifndef CAPSTONE_X86_REDUCE
696 if (insn->xAcquireRelease) {
697 if (MCInst_getOpcode(mcInst) == X86_REP_PREFIX)
698 MCInst_setOpcode(mcInst, X86_XRELEASE_PREFIX);
699 else if (MCInst_getOpcode(mcInst) == X86_REPNE_PREFIX)
700 MCInst_setOpcode(mcInst, X86_XACQUIRE_PREFIX);
701 }
702 #endif
703
704 insn->numImmediatesTranslated = 0;
705
706 for (index = 0; index < X86_MAX_OPERANDS; ++index) {
707 if (insn->operands[index].encoding != ENCODING_NONE) {
708 if (translateOperand(mcInst, &insn->operands[index], insn)) {
709 return true;
710 }
711 }
712 }
713
714 return false;
715 }
716
reader(const struct reader_info * info,uint8_t * byte,uint64_t address)717 static int reader(const struct reader_info *info, uint8_t *byte, uint64_t address)
718 {
719 if (address - info->offset >= info->size)
720 // out of buffer range
721 return -1;
722
723 *byte = info->code[address - info->offset];
724
725 return 0;
726 }
727
728 // copy x86 detail information from internal structure to public structure
update_pub_insn(cs_insn * pub,InternalInstruction * inter,uint8_t * prefixes)729 static void update_pub_insn(cs_insn *pub, InternalInstruction *inter, uint8_t *prefixes)
730 {
731 prefixes[0] = inter->prefix0;
732 prefixes[1] = inter->prefix1;
733 prefixes[2] = inter->prefix2;
734 prefixes[3] = inter->prefix3;
735
736 if (inter->vectorExtensionType != 0)
737 memcpy(pub->detail->x86.opcode, inter->vectorExtensionPrefix, sizeof(pub->detail->x86.opcode));
738 else {
739 if (inter->twoByteEscape) {
740 if (inter->threeByteEscape) {
741 pub->detail->x86.opcode[0] = inter->twoByteEscape;
742 pub->detail->x86.opcode[1] = inter->threeByteEscape;
743 pub->detail->x86.opcode[2] = inter->opcode;
744 } else {
745 pub->detail->x86.opcode[0] = inter->twoByteEscape;
746 pub->detail->x86.opcode[1] = inter->opcode;
747 }
748 } else {
749 pub->detail->x86.opcode[0] = inter->opcode;
750 }
751 }
752
753 pub->detail->x86.rex = inter->rexPrefix;
754
755 pub->detail->x86.addr_size = inter->addressSize;
756
757 pub->detail->x86.modrm = inter->orgModRM;
758 pub->detail->x86.sib = inter->sib;
759 pub->detail->x86.disp = inter->displacement;
760
761 pub->detail->x86.sib_index = x86_map_sib_index(inter->sibIndex);
762 pub->detail->x86.sib_scale = inter->sibScale;
763 pub->detail->x86.sib_base = x86_map_sib_base(inter->sibBase);
764 }
765
X86_init(MCRegisterInfo * MRI)766 void X86_init(MCRegisterInfo *MRI)
767 {
768 /*
769 InitMCRegisterInfo(X86RegDesc, 234,
770 RA, PC,
771 X86MCRegisterClasses, 79,
772 X86RegUnitRoots, 119, X86RegDiffLists, X86RegStrings,
773 X86SubRegIdxLists, 7,
774 X86SubRegIdxRanges, X86RegEncodingTable);
775 */
776
777 MCRegisterInfo_InitMCRegisterInfo(MRI, X86RegDesc, 234,
778 0, 0,
779 X86MCRegisterClasses, 79,
780 0, 0, X86RegDiffLists, 0,
781 X86SubRegIdxLists, 7,
782 0);
783 }
784
785 // Public interface for the disassembler
X86_getInstruction(csh ud,const uint8_t * code,size_t code_len,MCInst * instr,uint16_t * size,uint64_t address,void * _info)786 bool X86_getInstruction(csh ud, const uint8_t *code, size_t code_len,
787 MCInst *instr, uint16_t *size, uint64_t address, void *_info)
788 {
789 cs_struct *handle = (cs_struct *)(uintptr_t)ud;
790 InternalInstruction insn;
791 struct reader_info info;
792 int ret;
793 bool result;
794
795 info.code = code;
796 info.size = code_len;
797 info.offset = address;
798
799 memset(&insn, 0, offsetof(InternalInstruction, reader));
800
801 if (instr->flat_insn->detail) {
802 instr->flat_insn->detail->x86.op_count = 0;
803 instr->flat_insn->detail->x86.sse_cc = X86_SSE_CC_INVALID;
804 instr->flat_insn->detail->x86.avx_cc = X86_AVX_CC_INVALID;
805 instr->flat_insn->detail->x86.avx_sae = false;
806 instr->flat_insn->detail->x86.avx_rm = X86_AVX_RM_INVALID;
807
808 memset(instr->flat_insn->detail->x86.prefix, 0, sizeof(instr->flat_insn->detail->x86.prefix));
809 memset(instr->flat_insn->detail->x86.opcode, 0, sizeof(instr->flat_insn->detail->x86.opcode));
810 memset(instr->flat_insn->detail->x86.operands, 0, sizeof(instr->flat_insn->detail->x86.operands));
811 }
812
813 if (handle->mode & CS_MODE_16)
814 ret = decodeInstruction(&insn,
815 reader, &info,
816 address,
817 MODE_16BIT);
818 else if (handle->mode & CS_MODE_32)
819 ret = decodeInstruction(&insn,
820 reader, &info,
821 address,
822 MODE_32BIT);
823 else
824 ret = decodeInstruction(&insn,
825 reader, &info,
826 address,
827 MODE_64BIT);
828
829 if (ret) {
830 *size = (uint16_t)(insn.readerCursor - address);
831
832 return false;
833 } else {
834 *size = (uint16_t)insn.length;
835
836 result = (!translateInstruction(instr, &insn)) ? true : false;
837 if (result) {
838 // quick fix for #904. TODO: fix this properly in the next update
839 if (handle->mode & CS_MODE_64) {
840 if (instr->Opcode == X86_LES16rm || instr->Opcode == X86_LES32rm)
841 // LES is invalid in x64
842 return false;
843 if (instr->Opcode == X86_LDS16rm || instr->Opcode == X86_LDS32rm)
844 // LDS is invalid in x64
845 return false;
846 }
847
848 instr->imm_size = insn.immSize;
849 if (handle->detail) {
850 update_pub_insn(instr->flat_insn, &insn, instr->x86_prefix);
851 } else {
852 // still copy all prefixes
853 instr->x86_prefix[0] = insn.prefix0;
854 instr->x86_prefix[1] = insn.prefix1;
855 instr->x86_prefix[2] = insn.prefix2;
856 instr->x86_prefix[3] = insn.prefix3;
857 }
858 }
859
860 return result;
861 }
862 }
863
864 #endif
865