add X86_COMPACT option. also add CS_SUPPORT_X86_COMPACT. made Python support this change

This commit is contained in:
Nguyen Anh Quynh 2014-03-25 23:20:41 +08:00
parent e2bdcf064c
commit 9518148e6f
15 changed files with 121015 additions and 185 deletions

View File

@ -156,11 +156,18 @@ ifneq (,$(findstring systemz,$(CAPSTONE_ARCHS)))
endif
# by default, we compile full X86 instruction sets
X86_COMPACT =
ifneq (,$(findstring yes,$(CAPSTONE_X86_COMPACT)))
X86_COMPACT = _compact
CFLAGS += -DCAPSTONE_X86_COMPACT
endif
DEP_X86 =
DEP_X86 += arch/X86/X86GenAsmWriter.inc
DEP_X86 += arch/X86/X86GenAsmWriter1.inc
DEP_X86 += arch/X86/X86GenDisassemblerTables.inc
DEP_X86 += arch/X86/X86GenInstrInfo.inc
DEP_X86 += arch/X86/X86GenAsmWriter$(X86_COMPACT).inc
DEP_X86 += arch/X86/X86GenAsmWriter1$(X86_COMPACT).inc
DEP_X86 += arch/X86/X86GenDisassemblerTables$(X86_COMPACT).inc
DEP_X86 += arch/X86/X86GenInstrInfo$(X86_COMPACT).inc
DEP_X86 += arch/X86/X86GenRegisterInfo.inc
LIBOBJ_X86 =

View File

@ -69,6 +69,7 @@ static void printi128mem(MCInst *MI, unsigned OpNo, SStream *O)
printMemReference(MI, OpNo, O);
}
#ifndef CAPSTONE_X86_COMPACT
static void printi256mem(MCInst *MI, unsigned OpNo, SStream *O)
{
SStream_concat(O, "ymmword ptr ");
@ -115,6 +116,84 @@ static void printf512mem(MCInst *MI, unsigned OpNo, SStream *O)
printMemReference(MI, OpNo, O);
}
static void printSSECC(MCInst *MI, unsigned Op, SStream *OS)
{
int64_t Imm = MCOperand_getImm(MCInst_getOperand(MI, Op)) & 0xf;
switch (Imm) {
default: break; // never reach
case 0: SStream_concat(OS, "eq"); break;
case 1: SStream_concat(OS, "lt"); break;
case 2: SStream_concat(OS, "le"); break;
case 3: SStream_concat(OS, "unord"); break;
case 4: SStream_concat(OS, "neq"); break;
case 5: SStream_concat(OS, "nlt"); break;
case 6: SStream_concat(OS, "nle"); break;
case 7: SStream_concat(OS, "ord"); break;
case 8: SStream_concat(OS, "eq_uq"); break;
case 9: SStream_concat(OS, "nge"); break;
case 0xa: SStream_concat(OS, "ngt"); break;
case 0xb: SStream_concat(OS, "false"); break;
case 0xc: SStream_concat(OS, "neq_oq"); break;
case 0xd: SStream_concat(OS, "ge"); break;
case 0xe: SStream_concat(OS, "gt"); break;
case 0xf: SStream_concat(OS, "true"); break;
}
}
static void printAVXCC(MCInst *MI, unsigned Op, SStream *O)
{
int64_t Imm = MCOperand_getImm(MCInst_getOperand(MI, Op)) & 0x1f;
switch (Imm) {
default: break;//printf("Invalid avxcc argument!\n"); break;
case 0: SStream_concat(O, "eq"); break;
case 1: SStream_concat(O, "lt"); break;
case 2: SStream_concat(O, "le"); break;
case 3: SStream_concat(O, "unord"); break;
case 4: SStream_concat(O, "neq"); break;
case 5: SStream_concat(O, "nlt"); break;
case 6: SStream_concat(O, "nle"); break;
case 7: SStream_concat(O, "ord"); break;
case 8: SStream_concat(O, "eq_uq"); break;
case 9: SStream_concat(O, "nge"); break;
case 0xa: SStream_concat(O, "ngt"); break;
case 0xb: SStream_concat(O, "false"); break;
case 0xc: SStream_concat(O, "neq_oq"); break;
case 0xd: SStream_concat(O, "ge"); break;
case 0xe: SStream_concat(O, "gt"); break;
case 0xf: SStream_concat(O, "true"); break;
case 0x10: SStream_concat(O, "eq_os"); break;
case 0x11: SStream_concat(O, "lt_oq"); break;
case 0x12: SStream_concat(O, "le_oq"); break;
case 0x13: SStream_concat(O, "unord_s"); break;
case 0x14: SStream_concat(O, "neq_us"); break;
case 0x15: SStream_concat(O, "nlt_uq"); break;
case 0x16: SStream_concat(O, "nle_uq"); break;
case 0x17: SStream_concat(O, "ord_s"); break;
case 0x18: SStream_concat(O, "eq_us"); break;
case 0x19: SStream_concat(O, "nge_uq"); break;
case 0x1a: SStream_concat(O, "ngt_uq"); break;
case 0x1b: SStream_concat(O, "false_os"); break;
case 0x1c: SStream_concat(O, "neq_os"); break;
case 0x1d: SStream_concat(O, "ge_oq"); break;
case 0x1e: SStream_concat(O, "gt_oq"); break;
case 0x1f: SStream_concat(O, "true_us"); break;
}
}
static void printRoundingControl(MCInst *MI, unsigned Op, SStream *O)
{
int64_t Imm = MCOperand_getImm(MCInst_getOperand(MI, Op)) & 0x3;
switch (Imm) {
case 0: SStream_concat(O, "{rn-sae}"); break;
case 1: SStream_concat(O, "{rd-sae}"); break;
case 2: SStream_concat(O, "{ru-sae}"); break;
case 3: SStream_concat(O, "{rz-sae}"); break;
default: break; // never reach
}
}
#endif
static void printSrcIdx(MCInst *MI, unsigned Op, SStream *O)
{
MCOperand *SegReg;
@ -250,82 +329,6 @@ static void printMemOffs64(MCInst *MI, unsigned OpNo, SStream *O)
static void printRegName(SStream *OS, unsigned RegNo);
static void printSSECC(MCInst *MI, unsigned Op, SStream *OS)
{
int64_t Imm = MCOperand_getImm(MCInst_getOperand(MI, Op)) & 0xf;
switch (Imm) {
default: break; // never reach
case 0: SStream_concat(OS, "eq"); break;
case 1: SStream_concat(OS, "lt"); break;
case 2: SStream_concat(OS, "le"); break;
case 3: SStream_concat(OS, "unord"); break;
case 4: SStream_concat(OS, "neq"); break;
case 5: SStream_concat(OS, "nlt"); break;
case 6: SStream_concat(OS, "nle"); break;
case 7: SStream_concat(OS, "ord"); break;
case 8: SStream_concat(OS, "eq_uq"); break;
case 9: SStream_concat(OS, "nge"); break;
case 0xa: SStream_concat(OS, "ngt"); break;
case 0xb: SStream_concat(OS, "false"); break;
case 0xc: SStream_concat(OS, "neq_oq"); break;
case 0xd: SStream_concat(OS, "ge"); break;
case 0xe: SStream_concat(OS, "gt"); break;
case 0xf: SStream_concat(OS, "true"); break;
}
}
static void printAVXCC(MCInst *MI, unsigned Op, SStream *O)
{
int64_t Imm = MCOperand_getImm(MCInst_getOperand(MI, Op)) & 0x1f;
switch (Imm) {
default: break;//printf("Invalid avxcc argument!\n"); break;
case 0: SStream_concat(O, "eq"); break;
case 1: SStream_concat(O, "lt"); break;
case 2: SStream_concat(O, "le"); break;
case 3: SStream_concat(O, "unord"); break;
case 4: SStream_concat(O, "neq"); break;
case 5: SStream_concat(O, "nlt"); break;
case 6: SStream_concat(O, "nle"); break;
case 7: SStream_concat(O, "ord"); break;
case 8: SStream_concat(O, "eq_uq"); break;
case 9: SStream_concat(O, "nge"); break;
case 0xa: SStream_concat(O, "ngt"); break;
case 0xb: SStream_concat(O, "false"); break;
case 0xc: SStream_concat(O, "neq_oq"); break;
case 0xd: SStream_concat(O, "ge"); break;
case 0xe: SStream_concat(O, "gt"); break;
case 0xf: SStream_concat(O, "true"); break;
case 0x10: SStream_concat(O, "eq_os"); break;
case 0x11: SStream_concat(O, "lt_oq"); break;
case 0x12: SStream_concat(O, "le_oq"); break;
case 0x13: SStream_concat(O, "unord_s"); break;
case 0x14: SStream_concat(O, "neq_us"); break;
case 0x15: SStream_concat(O, "nlt_uq"); break;
case 0x16: SStream_concat(O, "nle_uq"); break;
case 0x17: SStream_concat(O, "ord_s"); break;
case 0x18: SStream_concat(O, "eq_us"); break;
case 0x19: SStream_concat(O, "nge_uq"); break;
case 0x1a: SStream_concat(O, "ngt_uq"); break;
case 0x1b: SStream_concat(O, "false_os"); break;
case 0x1c: SStream_concat(O, "neq_os"); break;
case 0x1d: SStream_concat(O, "ge_oq"); break;
case 0x1e: SStream_concat(O, "gt_oq"); break;
case 0x1f: SStream_concat(O, "true_us"); break;
}
}
static void printRoundingControl(MCInst *MI, unsigned Op, SStream *O)
{
int64_t Imm = MCOperand_getImm(MCInst_getOperand(MI, Op)) & 0x3;
switch (Imm) {
case 0: SStream_concat(O, "{rn-sae}"); break;
case 1: SStream_concat(O, "{rd-sae}"); break;
case 2: SStream_concat(O, "{ru-sae}"); break;
case 3: SStream_concat(O, "{rz-sae}"); break;
default: break; // never reach
}
}
/// printPCRelImm - This is used to print an immediate value that ends up
/// being encoded as a pc-relative value (e.g. for jumps and calls). These
/// print slightly differently than normal immediates. For example, a $ is not
@ -479,14 +482,22 @@ static void printMemReference(MCInst *MI, unsigned Op, SStream *O)
#include "X86InstPrinter.h"
#define GET_INSTRINFO_ENUM
#ifdef CAPSTONE_X86_COMPACT
#include "X86GenInstrInfo_compact.inc"
#else
#include "X86GenInstrInfo.inc"
#endif
#define GET_REGINFO_ENUM
#include "X86GenRegisterInfo.inc"
// Include the auto-generated portion of the assembly writer.
#define PRINT_ALIAS_INSTR
#ifdef CAPSTONE_X86_COMPACT
#include "X86GenAsmWriter_compact.inc"
#else
#include "X86GenAsmWriter.inc"
#endif
static void printRegName(SStream *OS, unsigned RegNo)
{

View File

@ -32,7 +32,11 @@
#include "X86GenRegisterInfo.inc"
#define GET_INSTRINFO_ENUM
#ifdef CAPSTONE_X86_COMPACT
#include "X86GenInstrInfo_compact.inc"
#else
#include "X86GenInstrInfo.inc"
#endif
struct reader_info {
const uint8_t *code;
@ -181,15 +185,27 @@ static void translateImmediate(MCInst *mcInst, uint64_t immediate,
case ENCODING_IB:
// Special case those X86 instructions that use the imm8 as a set of
// bits, bit count, etc. and are not sign-extend.
if (Opcode != X86_BLENDPSrri && Opcode != X86_BLENDPDrri &&
Opcode != X86_PBLENDWrri && Opcode != X86_MPSADBWrri &&
Opcode != X86_DPPSrri && Opcode != X86_DPPDrri &&
Opcode != X86_INSERTPSrr && Opcode != X86_VBLENDPSYrri &&
Opcode != X86_VBLENDPSYrmi && Opcode != X86_VBLENDPDYrri &&
Opcode != X86_VBLENDPDYrmi && Opcode != X86_VPBLENDWrri &&
Opcode != X86_VMPSADBWrri && Opcode != X86_VDPPSYrri &&
Opcode != X86_VDPPSYrmi && Opcode != X86_VDPPDrri &&
Opcode != X86_VINSERTPSrr && Opcode != X86_INT)
if (
#ifndef CAPSTONE_X86_COMPACT
Opcode != X86_BLENDPSrri &&
Opcode != X86_BLENDPDrri &&
Opcode != X86_PBLENDWrri &&
Opcode != X86_MPSADBWrri &&
Opcode != X86_DPPSrri &&
Opcode != X86_DPPDrri &&
Opcode != X86_INSERTPSrr &&
Opcode != X86_VBLENDPSYrri &&
Opcode != X86_VBLENDPSYrmi &&
Opcode != X86_VBLENDPDYrri &&
Opcode != X86_VBLENDPDYrmi &&
Opcode != X86_VPBLENDWrri &&
Opcode != X86_VMPSADBWrri &&
Opcode != X86_VDPPSYrri &&
Opcode != X86_VDPPSYrmi &&
Opcode != X86_VDPPDrri &&
Opcode != X86_VINSERTPSrr &&
#endif
Opcode != X86_INT)
if(immediate & 0x80)
immediate |= ~(0xffull);
break;
@ -305,6 +321,9 @@ static bool translateRMMemory(MCInst *mcInst, InternalInstruction *insn)
MCOperand *displacement;
MCOperand *segmentReg;
bool IndexIs512;
#ifndef CAPSTONE_X86_COMPACT
uint32_t Opcode;
#endif
if (insn->eaBase == EA_BASE_sib || insn->eaBase == EA_BASE_sib64) {
if (insn->sibBase != SIB_BASE_NONE) {
@ -328,8 +347,12 @@ static bool translateRMMemory(MCInst *mcInst, InternalInstruction *insn)
// I don't see a way to get the correct IndexReg in readSIB:
// We can tell whether it is VSIB or SIB after instruction ID is decoded,
// but instruction ID may not be decoded yet when calling readSIB.
uint32_t Opcode = MCInst_getOpcode(mcInst);
bool IndexIs128 = (Opcode == X86_VGATHERDPDrm ||
#ifndef CAPSTONE_X86_COMPACT
Opcode = MCInst_getOpcode(mcInst);
#endif
bool IndexIs128 = (
#ifndef CAPSTONE_X86_COMPACT
Opcode == X86_VGATHERDPDrm ||
Opcode == X86_VGATHERDPDYrm ||
Opcode == X86_VGATHERQPDrm ||
Opcode == X86_VGATHERDPSrm ||
@ -338,21 +361,34 @@ static bool translateRMMemory(MCInst *mcInst, InternalInstruction *insn)
Opcode == X86_VPGATHERDQYrm ||
Opcode == X86_VPGATHERQQrm ||
Opcode == X86_VPGATHERDDrm ||
Opcode == X86_VPGATHERQDrm);
bool IndexIs256 = (Opcode == X86_VGATHERQPDYrm ||
Opcode == X86_VPGATHERQDrm ||
#endif
false
);
bool IndexIs256 = (
#ifndef CAPSTONE_X86_COMPACT
Opcode == X86_VGATHERQPDYrm ||
Opcode == X86_VGATHERDPSYrm ||
Opcode == X86_VGATHERQPSYrm ||
Opcode == X86_VGATHERDPDZrm ||
Opcode == X86_VPGATHERDQZrm ||
Opcode == X86_VPGATHERQQYrm ||
Opcode == X86_VPGATHERDDYrm ||
Opcode == X86_VPGATHERQDYrm);
IndexIs512 = (Opcode == X86_VGATHERQPDZrm ||
Opcode == X86_VPGATHERQDYrm ||
#endif
false
);
IndexIs512 = (
#ifndef CAPSTONE_X86_COMPACT
Opcode == X86_VGATHERQPDZrm ||
Opcode == X86_VGATHERDPSZrm ||
Opcode == X86_VGATHERQPSZrm ||
Opcode == X86_VPGATHERQQZrm ||
Opcode == X86_VPGATHERDDZrm ||
Opcode == X86_VPGATHERQDZrm);
Opcode == X86_VPGATHERQDZrm ||
#endif
false
);
if (IndexIs128 || IndexIs256 || IndexIs512) {
unsigned IndexOffset = insn->sibIndex -
@ -612,12 +648,14 @@ static bool translateInstruction(MCInst *mcInst, InternalInstruction *insn)
// If when reading the prefix bytes we determined the overlapping 0xf2 or 0xf3
// prefix bytes should be disassembled as xrelease and xacquire then set the
// opcode to those instead of the rep and repne opcodes.
#ifndef CAPSTONE_X86_COMPACT
if (insn->xAcquireRelease) {
if (MCInst_getOpcode(mcInst) == X86_REP_PREFIX)
MCInst_setOpcode(mcInst, X86_XRELEASE_PREFIX);
else if (MCInst_getOpcode(mcInst) == X86_REPNE_PREFIX)
MCInst_setOpcode(mcInst, X86_XACQUIRE_PREFIX);
}
#endif
insn->numImmediatesTranslated = 0;

View File

@ -24,11 +24,19 @@
#include "X86DisassemblerDecoder.h"
#ifdef CAPSTONE_X86_COMPACT
#include "X86GenDisassemblerTables_compact.inc"
#else
#include "X86GenDisassemblerTables.inc"
#endif
//#define GET_INSTRINFO_ENUM
#define GET_INSTRINFO_MC_DESC
#ifdef CAPSTONE_X86_COMPACT
#include "X86GenInstrInfo_compact.inc"
#else
#include "X86GenInstrInfo.inc"
#endif
static const char *x86DisassemblerGetInstrName(unsigned Opcode)
{
@ -79,6 +87,7 @@ static int modRMRequired(OpcodeType type,
uint8_t index;
switch (type) {
default:
case ONEBYTE:
decision = ONEBYTE_SYM;
indextable = index_x86DisassemblerOneByteOpcodes;
@ -95,6 +104,7 @@ static int modRMRequired(OpcodeType type,
decision = THREEBYTE3A_SYM;
indextable = index_x86DisassemblerThreeByte3AOpcodes;
break;
#ifndef CAPSTONE_X86_COMPACT
case XOP8_MAP:
decision = XOP8_MAP_SYM;
indextable = index_x86DisassemblerXOP8Opcodes;
@ -107,6 +117,7 @@ static int modRMRequired(OpcodeType type,
decision = XOPA_MAP_SYM;
indextable = index_x86DisassemblerXOPAOpcodes;
break;
#endif
}
index = indextable[insnContext];
@ -137,6 +148,7 @@ static InstrUID decode(OpcodeType type,
uint8_t index;
switch (type) {
default:
case ONEBYTE:
indextable = index_x86DisassemblerOneByteOpcodes;
index = indextable[insnContext];
@ -169,6 +181,7 @@ static InstrUID decode(OpcodeType type,
else
dec = &emptyTable.modRMDecisions[opcode];
break;
#ifndef CAPSTONE_X86_COMPACT
case XOP8_MAP:
indextable = index_x86DisassemblerXOP8Opcodes;
index = indextable[insnContext];
@ -193,6 +206,7 @@ static InstrUID decode(OpcodeType type,
else
dec = &emptyTable.modRMDecisions[opcode];
break;
#endif
}
switch (dec->modrm_type) {

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -67,6 +67,7 @@ static void printi128mem(MCInst *MI, unsigned OpNo, SStream *O)
printMemReference(MI, OpNo, O);
}
#ifndef CAPSTONE_X86_COMPACT
static void printi256mem(MCInst *MI, unsigned OpNo, SStream *O)
{
SStream_concat(O, "ymmword ptr ");
@ -115,6 +116,84 @@ static void printf512mem(MCInst *MI, unsigned OpNo, SStream *O)
printMemReference(MI, OpNo, O);
}
static void printSSECC(MCInst *MI, unsigned Op, SStream *OS)
{
int64_t Imm = MCOperand_getImm(MCInst_getOperand(MI, Op)) & 0xf;
switch (Imm) {
default: break; // never reach
case 0: SStream_concat(OS, "eq"); break;
case 1: SStream_concat(OS, "lt"); break;
case 2: SStream_concat(OS, "le"); break;
case 3: SStream_concat(OS, "unord"); break;
case 4: SStream_concat(OS, "neq"); break;
case 5: SStream_concat(OS, "nlt"); break;
case 6: SStream_concat(OS, "nle"); break;
case 7: SStream_concat(OS, "ord"); break;
case 8: SStream_concat(OS, "eq_uq"); break;
case 9: SStream_concat(OS, "nge"); break;
case 0xa: SStream_concat(OS, "ngt"); break;
case 0xb: SStream_concat(OS, "false"); break;
case 0xc: SStream_concat(OS, "neq_oq"); break;
case 0xd: SStream_concat(OS, "ge"); break;
case 0xe: SStream_concat(OS, "gt"); break;
case 0xf: SStream_concat(OS, "true"); break;
}
}
static void printAVXCC(MCInst *MI, unsigned Op, SStream *O)
{
int64_t Imm = MCOperand_getImm(MCInst_getOperand(MI, Op)) & 0x1f;
switch (Imm) {
default: break;//printf("Invalid avxcc argument!\n"); break;
case 0: SStream_concat(O, "eq"); break;
case 1: SStream_concat(O, "lt"); break;
case 2: SStream_concat(O, "le"); break;
case 3: SStream_concat(O, "unord"); break;
case 4: SStream_concat(O, "neq"); break;
case 5: SStream_concat(O, "nlt"); break;
case 6: SStream_concat(O, "nle"); break;
case 7: SStream_concat(O, "ord"); break;
case 8: SStream_concat(O, "eq_uq"); break;
case 9: SStream_concat(O, "nge"); break;
case 0xa: SStream_concat(O, "ngt"); break;
case 0xb: SStream_concat(O, "false"); break;
case 0xc: SStream_concat(O, "neq_oq"); break;
case 0xd: SStream_concat(O, "ge"); break;
case 0xe: SStream_concat(O, "gt"); break;
case 0xf: SStream_concat(O, "true"); break;
case 0x10: SStream_concat(O, "eq_os"); break;
case 0x11: SStream_concat(O, "lt_oq"); break;
case 0x12: SStream_concat(O, "le_oq"); break;
case 0x13: SStream_concat(O, "unord_s"); break;
case 0x14: SStream_concat(O, "neq_us"); break;
case 0x15: SStream_concat(O, "nlt_uq"); break;
case 0x16: SStream_concat(O, "nle_uq"); break;
case 0x17: SStream_concat(O, "ord_s"); break;
case 0x18: SStream_concat(O, "eq_us"); break;
case 0x19: SStream_concat(O, "nge_uq"); break;
case 0x1a: SStream_concat(O, "ngt_uq"); break;
case 0x1b: SStream_concat(O, "false_os"); break;
case 0x1c: SStream_concat(O, "neq_os"); break;
case 0x1d: SStream_concat(O, "ge_oq"); break;
case 0x1e: SStream_concat(O, "gt_oq"); break;
case 0x1f: SStream_concat(O, "true_us"); break;
}
}
static void printRoundingControl(MCInst *MI, unsigned Op, SStream *O)
{
int64_t Imm = MCOperand_getImm(MCInst_getOperand(MI, Op)) & 0x3;
switch (Imm) {
case 0: SStream_concat(O, "{rn-sae}"); break;
case 1: SStream_concat(O, "{rd-sae}"); break;
case 2: SStream_concat(O, "{ru-sae}"); break;
case 3: SStream_concat(O, "{rz-sae}"); break;
default: break; // never reach
}
}
#endif
static void printSrcIdx(MCInst *MI, unsigned Op, SStream *O)
{
MCOperand *SegReg;
@ -290,82 +369,6 @@ void X86_Intel_printInst(MCInst *MI, SStream *O, void *Info)
}
}
static void printSSECC(MCInst *MI, unsigned Op, SStream *OS)
{
int64_t Imm = MCOperand_getImm(MCInst_getOperand(MI, Op)) & 0xf;
switch (Imm) {
default: break; // never reach
case 0: SStream_concat(OS, "eq"); break;
case 1: SStream_concat(OS, "lt"); break;
case 2: SStream_concat(OS, "le"); break;
case 3: SStream_concat(OS, "unord"); break;
case 4: SStream_concat(OS, "neq"); break;
case 5: SStream_concat(OS, "nlt"); break;
case 6: SStream_concat(OS, "nle"); break;
case 7: SStream_concat(OS, "ord"); break;
case 8: SStream_concat(OS, "eq_uq"); break;
case 9: SStream_concat(OS, "nge"); break;
case 0xa: SStream_concat(OS, "ngt"); break;
case 0xb: SStream_concat(OS, "false"); break;
case 0xc: SStream_concat(OS, "neq_oq"); break;
case 0xd: SStream_concat(OS, "ge"); break;
case 0xe: SStream_concat(OS, "gt"); break;
case 0xf: SStream_concat(OS, "true"); break;
}
}
static void printAVXCC(MCInst *MI, unsigned Op, SStream *O)
{
int64_t Imm = MCOperand_getImm(MCInst_getOperand(MI, Op)) & 0x1f;
switch (Imm) {
default: break;//printf("Invalid avxcc argument!\n"); break;
case 0: SStream_concat(O, "eq"); break;
case 1: SStream_concat(O, "lt"); break;
case 2: SStream_concat(O, "le"); break;
case 3: SStream_concat(O, "unord"); break;
case 4: SStream_concat(O, "neq"); break;
case 5: SStream_concat(O, "nlt"); break;
case 6: SStream_concat(O, "nle"); break;
case 7: SStream_concat(O, "ord"); break;
case 8: SStream_concat(O, "eq_uq"); break;
case 9: SStream_concat(O, "nge"); break;
case 0xa: SStream_concat(O, "ngt"); break;
case 0xb: SStream_concat(O, "false"); break;
case 0xc: SStream_concat(O, "neq_oq"); break;
case 0xd: SStream_concat(O, "ge"); break;
case 0xe: SStream_concat(O, "gt"); break;
case 0xf: SStream_concat(O, "true"); break;
case 0x10: SStream_concat(O, "eq_os"); break;
case 0x11: SStream_concat(O, "lt_oq"); break;
case 0x12: SStream_concat(O, "le_oq"); break;
case 0x13: SStream_concat(O, "unord_s"); break;
case 0x14: SStream_concat(O, "neq_us"); break;
case 0x15: SStream_concat(O, "nlt_uq"); break;
case 0x16: SStream_concat(O, "nle_uq"); break;
case 0x17: SStream_concat(O, "ord_s"); break;
case 0x18: SStream_concat(O, "eq_us"); break;
case 0x19: SStream_concat(O, "nge_uq"); break;
case 0x1a: SStream_concat(O, "ngt_uq"); break;
case 0x1b: SStream_concat(O, "false_os"); break;
case 0x1c: SStream_concat(O, "neq_os"); break;
case 0x1d: SStream_concat(O, "ge_oq"); break;
case 0x1e: SStream_concat(O, "gt_oq"); break;
case 0x1f: SStream_concat(O, "true_us"); break;
}
}
static void printRoundingControl(MCInst *MI, unsigned Op, SStream *O)
{
int64_t Imm = MCOperand_getImm(MCInst_getOperand(MI, Op)) & 0x3;
switch (Imm) {
case 0: SStream_concat(O, "{rn-sae}"); break;
case 1: SStream_concat(O, "{rd-sae}"); break;
case 2: SStream_concat(O, "{ru-sae}"); break;
case 3: SStream_concat(O, "{rz-sae}"); break;
default: break; // never reach
}
}
/// printPCRelImm - This is used to print an immediate value that ends up
/// being encoded as a pc-relative value.
static void printPCRelImm(MCInst *MI, unsigned OpNo, SStream *O)
@ -527,8 +530,16 @@ static void printMemReference(MCInst *MI, unsigned Op, SStream *O) // qqq
}
#define GET_INSTRINFO_ENUM
#ifdef CAPSTONE_X86_COMPACT
#include "X86GenInstrInfo_compact.inc"
#else
#include "X86GenInstrInfo.inc"
#endif
#define PRINT_ALIAS_INSTR
#ifdef CAPSTONE_X86_COMPACT
#include "X86GenAsmWriter1_compact.inc"
#else
#include "X86GenAsmWriter1.inc"
#endif

File diff suppressed because it is too large Load Diff

View File

@ -58,6 +58,7 @@ __all__ = [
'CS_ERR_DIET',
'CS_SUPPORT_DIET',
'CS_SUPPORT_X86_COMPACT',
]
# Capstone C interface
@ -119,6 +120,7 @@ CS_ERR_DIET = 10 # Information irrelevant in diet engine
# query id for cs_support()
CS_SUPPORT_DIET = CS_ARCH_ALL+1
CS_SUPPORT_X86_COMPACT = CS_ARCH_ALL+2
import ctypes, ctypes.util, sys
from os.path import split, join, dirname
@ -545,6 +547,7 @@ class Cs(object):
self._detail = False # by default, do not produce instruction details
self._diet = cs_support(CS_SUPPORT_DIET)
self._x86_compact = cs_support(CS_SUPPORT_X86_COMPACT)
# destructor to be called automatically when object is destroyed.
@ -565,6 +568,12 @@ class Cs(object):
return self._diet
# is this engine compiled with X86 compact option?
@property
def x86_compact(self):
return self._x86_compact
# return assembly syntax.
@property
def syntax(self):
@ -678,7 +687,7 @@ def debug():
archs = { "arm": CS_ARCH_ARM, "arm64": CS_ARCH_ARM64, \
"mips": CS_ARCH_MIPS, "ppc": CS_ARCH_PPC, "sparc": CS_ARCH_SPARC, \
"sysz": CS_ARCH_SYSZ, "x86": CS_ARCH_X86 }
"sysz": CS_ARCH_SYSZ }
all_archs = ""
keys = archs.keys()
@ -687,6 +696,11 @@ def debug():
if cs_support(archs[k]):
all_archs += "-%s" %k
if cs_support(CS_ARCH_X86):
all_archs += "-x86"
if cs_support(CS_SUPPORT_X86_COMPACT):
all_archs += "_compact"
(major, minor, _combined) = cs_version()
return "python-%s%s-c%u.%u-b%u.%u" %(diet, all_archs, major, minor, CS_API_MAJOR, CS_API_MINOR)

View File

@ -275,8 +275,7 @@ def debug():
archs = { "arm": capstone.CS_ARCH_ARM, "arm64": capstone.CS_ARCH_ARM64, \
"mips": capstone.CS_ARCH_MIPS, "ppc": capstone.CS_ARCH_PPC, \
"sparc": capstone.CS_ARCH_SPARC, "sysz": capstone.CS_ARCH_SYSZ, \
"x86": capstone.CS_ARCH_X86 }
"sparc": capstone.CS_ARCH_SPARC, "sysz": capstone.CS_ARCH_SYSZ)
all_archs = ""
keys = archs.keys()
@ -285,6 +284,11 @@ def debug():
if cc.cs_support(archs[k]):
all_archs += "-%s" %k
if cs_support(CS_ARCH_X86):
all_archs += "-x86"
if cs_support(CS_SUPPORT_X86_COMPACT):
all_archs += "_compact"
(major, minor, _combined) = capstone.cs_version()
return "Cython-%s%s-c%u.%u-b%u.%u" %(diet, all_archs, major, minor, capstone.CS_API_MAJOR, capstone.CS_API_MINOR)

View File

@ -51,3 +51,22 @@ USE_SYS_DYN_MEM = yes
# will not be updated (i.e empty), thus become irrelevant.
CAPSTONE_DIET = no
################################################################################
# Change 'CAPSTONE_X86_COMPACT = no' to 'CAPSTONE_X86_COMPACT = yes' to remove
# non-critical instruction sets of X86, making the binary size smaller by ~50%.
# This is desired in special cases, such as OS kernel, where these kind of
# instructions are not used.
#
# The list of instruction sets to be removed includes:
# - FPU
# - MMX, SSE, SIMD, 3DNow, AVX, FMA, XOP
# - VMX, SVM
# - TSX
#
# Due to this removal, the related instructions are nolonger supported.
#
# By default, Capstone is compiled with 'CAPSTONE_X86_COMPACT = no'
CAPSTONE_X86_COMPACT = no

8
cs.c
View File

@ -110,6 +110,14 @@ bool cs_support(int query)
#endif
}
if (query == CS_SUPPORT_X86_COMPACT) {
#if defined(CAPSTONE_HAS_X86) && defined(CAPSTONE_X86_COMPACT)
return true;
#else
return false;
#endif
}
// unsupported query
return false;
}

View File

@ -45,8 +45,16 @@ typedef enum cs_arch {
CS_ARCH_ALL = 0xFFFF,
} cs_arch;
// Support value to verify diet mode of the engine.
// If cs_support(CS_SUPPORT_DIET) return True, the engine was compiled
// in diet mode.
#define CS_SUPPORT_DIET (CS_ARCH_ALL + 1)
// Support value to verify X86 compact mode of the engine.
// If cs_support(CS_SUPPORT_X86_COMPACT) return True, the engine was compiled
// in X86 compact mode.
#define CS_SUPPORT_X86_COMPACT (CS_ARCH_ALL + 2)
// Mode type
typedef enum cs_mode {
CS_MODE_LITTLE_ENDIAN = 0, // little endian mode (default mode)