x86: more simplification on managing MCOperand. this also fixes a bug in handling memory reference instructions

This commit is contained in:
Nguyen Anh Quynh 2014-06-06 00:56:46 +08:00
parent e70a043a04
commit cf0813809a
3 changed files with 61 additions and 79 deletions

View File

@ -80,10 +80,6 @@ unsigned MCInst_getNumOperands(const MCInst *inst)
// NOTE: this will free @Op argument // NOTE: this will free @Op argument
int MCInst_addOperand(MCInst *inst, MCOperand *Op) int MCInst_addOperand(MCInst *inst, MCOperand *Op)
{ {
if (inst->size == ARR_SIZE(inst->Operands))
// full
return -1;
inst->Operands[inst->size] = *Op; inst->Operands[inst->size] = *Op;
cs_mem_free(Op); cs_mem_free(Op);
@ -92,26 +88,9 @@ int MCInst_addOperand(MCInst *inst, MCOperand *Op)
return 0; return 0;
} }
int MCInst_addOperand0(MCInst *inst, MCOperand *Op)
{
if (inst->size == ARR_SIZE(inst->Operands))
// full
return -1;
inst->Operands[inst->size] = *Op;
inst->size++;
return 0;
}
// This addOperand2 function doesnt free Op // This addOperand2 function doesnt free Op
int MCInst_addOperand2(MCInst *inst, MCOperand *Op) int MCInst_addOperand2(MCInst *inst, MCOperand *Op)
{ {
if (inst->size == ARR_SIZE(inst->Operands))
// full
return -1;
inst->Operands[inst->size] = *Op; inst->Operands[inst->size] = *Op;
inst->size++; inst->size++;
@ -187,6 +166,7 @@ MCOperand *MCOperand_CreateReg(unsigned Reg)
return op; return op;
} }
/*
MCOperand *MCOperand_CreateReg0(MCInst *mcInst, unsigned Reg) MCOperand *MCOperand_CreateReg0(MCInst *mcInst, unsigned Reg)
{ {
MCOperand *op = &(mcInst->Operands[MCINST_CACHE]); MCOperand *op = &(mcInst->Operands[MCINST_CACHE]);
@ -196,6 +176,16 @@ MCOperand *MCOperand_CreateReg0(MCInst *mcInst, unsigned Reg)
return op; return op;
} }
*/
void MCOperand_CreateReg0(MCInst *mcInst, unsigned Reg)
{
MCOperand *op = &(mcInst->Operands[mcInst->size]);
mcInst->size++;
op->Kind = kRegister;
op->RegVal = Reg;
}
MCOperand *MCOperand_CreateImm(int64_t Val) MCOperand *MCOperand_CreateImm(int64_t Val)
{ {
@ -207,6 +197,7 @@ MCOperand *MCOperand_CreateImm(int64_t Val)
return op; return op;
} }
/*
MCOperand *MCOperand_CreateImm0(MCInst *mcInst, int64_t Val) MCOperand *MCOperand_CreateImm0(MCInst *mcInst, int64_t Val)
{ {
MCOperand *op = &(mcInst->Operands[MCINST_CACHE]); MCOperand *op = &(mcInst->Operands[MCINST_CACHE]);
@ -216,6 +207,16 @@ MCOperand *MCOperand_CreateImm0(MCInst *mcInst, int64_t Val)
return op; return op;
} }
*/
void MCOperand_CreateImm0(MCInst *mcInst, int64_t Val)
{
MCOperand *op = &(mcInst->Operands[mcInst->size]);
mcInst->size++;
op->Kind = kImmediate;
op->ImmVal = Val;
}
MCOperand *MCOperand_CreateFPImm(double Val) MCOperand *MCOperand_CreateFPImm(double Val)
{ {

View File

@ -81,9 +81,9 @@ MCOperand *MCOperand_CreateImm(int64_t Val);
MCOperand *MCOperand_CreateFPImm(double Val); MCOperand *MCOperand_CreateFPImm(double Val);
MCOperand *MCOperand_CreateReg0(MCInst *inst, unsigned Reg); void MCOperand_CreateReg0(MCInst *inst, unsigned Reg);
MCOperand *MCOperand_CreateImm0(MCInst *inst, int64_t Val); void MCOperand_CreateImm0(MCInst *inst, int64_t Val);
// NOTE: this structure is a flatten version of cs_insn struct // NOTE: this structure is a flatten version of cs_insn struct
// Detail information of disassembled instruction // Detail information of disassembled instruction
@ -141,7 +141,7 @@ typedef struct cs_insn_flat {
/// instruction. /// instruction.
struct MCInst { struct MCInst {
unsigned Opcode; unsigned Opcode;
MCOperand Operands[32]; MCOperand Operands[34];
unsigned size; // number of operands unsigned size; // number of operands
cs_insn_flat flat_insn; // insn to be exposed to public cs_insn_flat flat_insn; // insn to be exposed to public
unsigned OpcodePub; unsigned OpcodePub;
@ -177,8 +177,6 @@ unsigned MCInst_getNumOperands(const MCInst *inst);
int MCInst_addOperand(MCInst *inst, MCOperand *Op); int MCInst_addOperand(MCInst *inst, MCOperand *Op);
int MCInst_addOperand0(MCInst *inst, MCOperand *Op);
// This addOperand2 function doesnt free Op // This addOperand2 function doesnt free Op
int MCInst_addOperand2(MCInst *inst, MCOperand *Op); int MCInst_addOperand2(MCInst *inst, MCOperand *Op);

View File

@ -77,7 +77,7 @@ static void translateRegister(MCInst *mcInst, Reg reg)
#undef ENTRY #undef ENTRY
uint8_t llvmRegnum = llvmRegnums[reg]; uint8_t llvmRegnum = llvmRegnums[reg];
MCInst_addOperand0(mcInst, MCOperand_CreateReg0(mcInst, llvmRegnum)); MCOperand_CreateReg0(mcInst, llvmRegnum);
} }
static const uint8_t segmentRegnums[SEG_OVERRIDE_max] = { static const uint8_t segmentRegnums[SEG_OVERRIDE_max] = {
@ -97,8 +97,6 @@ static const uint8_t segmentRegnums[SEG_OVERRIDE_max] = {
static bool translateSrcIndex(MCInst *mcInst, InternalInstruction *insn) static bool translateSrcIndex(MCInst *mcInst, InternalInstruction *insn)
{ {
unsigned baseRegNo; unsigned baseRegNo;
MCOperand *segmentReg;
MCOperand *baseReg;
if (insn->mode == MODE_64BIT) if (insn->mode == MODE_64BIT)
baseRegNo = insn->prefixPresent[0x67] ? X86_ESI : X86_RSI; baseRegNo = insn->prefixPresent[0x67] ? X86_ESI : X86_RSI;
@ -109,11 +107,9 @@ static bool translateSrcIndex(MCInst *mcInst, InternalInstruction *insn)
baseRegNo = insn->prefixPresent[0x67] ? X86_ESI : X86_SI; baseRegNo = insn->prefixPresent[0x67] ? X86_ESI : X86_SI;
} }
baseReg = MCOperand_CreateReg0(mcInst, baseRegNo); MCOperand_CreateReg0(mcInst, baseRegNo);
MCInst_addOperand0(mcInst, baseReg);
segmentReg = MCOperand_CreateReg0(mcInst, segmentRegnums[insn->segmentOverride]); MCOperand_CreateReg0(mcInst, segmentRegnums[insn->segmentOverride]);
MCInst_addOperand0(mcInst, segmentReg);
return false; return false;
} }
@ -125,7 +121,6 @@ static bool translateSrcIndex(MCInst *mcInst, InternalInstruction *insn)
static bool translateDstIndex(MCInst *mcInst, InternalInstruction *insn) static bool translateDstIndex(MCInst *mcInst, InternalInstruction *insn)
{ {
unsigned baseRegNo; unsigned baseRegNo;
MCOperand *baseReg;
if (insn->mode == MODE_64BIT) if (insn->mode == MODE_64BIT)
baseRegNo = insn->prefixPresent[0x67] ? X86_EDI : X86_RDI; baseRegNo = insn->prefixPresent[0x67] ? X86_EDI : X86_RDI;
@ -136,8 +131,7 @@ static bool translateDstIndex(MCInst *mcInst, InternalInstruction *insn)
baseRegNo = insn->prefixPresent[0x67] ? X86_EDI : X86_DI; baseRegNo = insn->prefixPresent[0x67] ? X86_EDI : X86_DI;
} }
baseReg = MCOperand_CreateReg0(mcInst, baseRegNo); MCOperand_CreateReg0(mcInst, baseRegNo);
MCInst_addOperand0(mcInst, baseReg);
return false; return false;
} }
@ -152,7 +146,6 @@ static void translateImmediate(MCInst *mcInst, uint64_t immediate,
const OperandSpecifier *operand, InternalInstruction *insn) const OperandSpecifier *operand, InternalInstruction *insn)
{ {
OperandType type; OperandType type;
MCOperand *segmentReg;
type = (OperandType)operand->type; type = (OperandType)operand->type;
if (type == TYPE_RELv) { if (type == TYPE_RELv) {
@ -227,13 +220,13 @@ static void translateImmediate(MCInst *mcInst, uint64_t immediate,
case TYPE_XMM32: case TYPE_XMM32:
case TYPE_XMM64: case TYPE_XMM64:
case TYPE_XMM128: case TYPE_XMM128:
MCInst_addOperand0(mcInst, MCOperand_CreateReg0(mcInst, X86_XMM0 + ((uint32_t)immediate >> 4))); MCOperand_CreateReg0(mcInst, X86_XMM0 + ((uint32_t)immediate >> 4));
return; return;
case TYPE_XMM256: case TYPE_XMM256:
MCInst_addOperand0(mcInst, MCOperand_CreateReg0(mcInst, X86_YMM0 + ((uint32_t)immediate >> 4))); MCOperand_CreateReg0(mcInst, X86_YMM0 + ((uint32_t)immediate >> 4));
return; return;
case TYPE_XMM512: case TYPE_XMM512:
MCInst_addOperand0(mcInst, MCOperand_CreateReg0(mcInst, X86_ZMM0 + ((uint32_t)immediate >> 4))); MCOperand_CreateReg0(mcInst, X86_ZMM0 + ((uint32_t)immediate >> 4));
return; return;
case TYPE_REL8: case TYPE_REL8:
if(immediate & 0x80) if(immediate & 0x80)
@ -249,12 +242,11 @@ static void translateImmediate(MCInst *mcInst, uint64_t immediate,
break; break;
} }
MCInst_addOperand0(mcInst, MCOperand_CreateImm0(mcInst, immediate)); MCOperand_CreateImm0(mcInst, immediate);
if (type == TYPE_MOFFS8 || type == TYPE_MOFFS16 || if (type == TYPE_MOFFS8 || type == TYPE_MOFFS16 ||
type == TYPE_MOFFS32 || type == TYPE_MOFFS64) { type == TYPE_MOFFS32 || type == TYPE_MOFFS64) {
segmentReg = MCOperand_CreateReg0(mcInst, segmentRegnums[insn->segmentOverride]); MCOperand_CreateReg0(mcInst, segmentRegnums[insn->segmentOverride]);
MCInst_addOperand0(mcInst, segmentReg);
} }
} }
@ -283,7 +275,7 @@ static bool translateRMRegister(MCInst *mcInst, InternalInstruction *insn)
return true; return true;
#define ENTRY(x) \ #define ENTRY(x) \
case EA_REG_##x: \ case EA_REG_##x: \
MCInst_addOperand0(mcInst, MCOperand_CreateReg0(mcInst, X86_##x)); break; MCOperand_CreateReg0(mcInst, X86_##x); break;
ALL_REGS ALL_REGS
#undef ENTRY #undef ENTRY
default: default:
@ -316,12 +308,8 @@ static bool translateRMMemory(MCInst *mcInst, InternalInstruction *insn)
// 5. segmentreg (register) x86_registerNONE for now, but could be set // 5. segmentreg (register) x86_registerNONE for now, but could be set
// if we have segment overrides // if we have segment overrides
MCOperand *baseReg;
MCOperand *scaleAmount;
MCOperand *indexReg;
MCOperand *displacement;
MCOperand *segmentReg;
bool IndexIs512, IndexIs128, IndexIs256; bool IndexIs512, IndexIs128, IndexIs256;
int scaleAmount, indexReg;
#ifndef CAPSTONE_X86_REDUCE #ifndef CAPSTONE_X86_REDUCE
uint32_t Opcode; uint32_t Opcode;
#endif #endif
@ -331,7 +319,7 @@ static bool translateRMMemory(MCInst *mcInst, InternalInstruction *insn)
switch (insn->sibBase) { switch (insn->sibBase) {
#define ENTRY(x) \ #define ENTRY(x) \
case SIB_BASE_##x: \ case SIB_BASE_##x: \
baseReg = MCOperand_CreateReg0(mcInst, X86_##x); break; MCOperand_CreateReg0(mcInst, X86_##x); break;
ALL_SIB_BASES ALL_SIB_BASES
#undef ENTRY #undef ENTRY
default: default:
@ -339,7 +327,7 @@ static bool translateRMMemory(MCInst *mcInst, InternalInstruction *insn)
return true; return true;
} }
} else { } else {
baseReg = MCOperand_CreateReg0(mcInst, 0); MCOperand_CreateReg0(mcInst, 0);
} }
// Check whether we are handling VSIB addressing mode for GATHER. // Check whether we are handling VSIB addressing mode for GATHER.
@ -407,7 +395,7 @@ static bool translateRMMemory(MCInst *mcInst, InternalInstruction *insn)
return true; return true;
#define ENTRY(x) \ #define ENTRY(x) \
case SIB_INDEX_##x: \ case SIB_INDEX_##x: \
indexReg = MCOperand_CreateReg0(mcInst, X86_##x); break; indexReg = X86_##x; break;
EA_BASES_32BIT EA_BASES_32BIT
EA_BASES_64BIT EA_BASES_64BIT
REGS_XMM REGS_XMM
@ -416,10 +404,10 @@ static bool translateRMMemory(MCInst *mcInst, InternalInstruction *insn)
#undef ENTRY #undef ENTRY
} }
} else { } else {
indexReg = MCOperand_CreateReg0(mcInst, 0); indexReg = 0;
} }
scaleAmount = MCOperand_CreateImm0(mcInst, insn->sibScale); scaleAmount = insn->sibScale;
} else { } else {
switch (insn->eaBase) { switch (insn->eaBase) {
case EA_BASE_NONE: case EA_BASE_NONE:
@ -428,30 +416,30 @@ static bool translateRMMemory(MCInst *mcInst, InternalInstruction *insn)
return true; return true;
} }
if (insn->mode == MODE_64BIT) { if (insn->mode == MODE_64BIT) {
baseReg = MCOperand_CreateReg0(mcInst, X86_RIP); // Section 2.2.1.6 MCOperand_CreateReg0(mcInst, X86_RIP); // Section 2.2.1.6
} else } else
baseReg = MCOperand_CreateReg0(mcInst, 0); MCOperand_CreateReg0(mcInst, 0);
indexReg = MCOperand_CreateReg0(mcInst, 0); indexReg = 0;
break; break;
case EA_BASE_BX_SI: case EA_BASE_BX_SI:
baseReg = MCOperand_CreateReg0(mcInst, X86_BX); MCOperand_CreateReg0(mcInst, X86_BX);
indexReg = MCOperand_CreateReg0(mcInst, X86_SI); indexReg = X86_SI;
break; break;
case EA_BASE_BX_DI: case EA_BASE_BX_DI:
baseReg = MCOperand_CreateReg0(mcInst, X86_BX); MCOperand_CreateReg0(mcInst, X86_BX);
indexReg = MCOperand_CreateReg0(mcInst, X86_DI); indexReg = X86_DI;
break; break;
case EA_BASE_BP_SI: case EA_BASE_BP_SI:
baseReg = MCOperand_CreateReg0(mcInst, X86_BP); MCOperand_CreateReg0(mcInst, X86_BP);
indexReg = MCOperand_CreateReg0(mcInst, X86_SI); indexReg = X86_SI;
break; break;
case EA_BASE_BP_DI: case EA_BASE_BP_DI:
baseReg = MCOperand_CreateReg0(mcInst, X86_BP); MCOperand_CreateReg0(mcInst, X86_BP);
indexReg = MCOperand_CreateReg0(mcInst, X86_DI); indexReg = X86_DI;
break; break;
default: default:
indexReg = MCOperand_CreateReg0(mcInst, 0); indexReg = 0;
switch (insn->eaBase) { switch (insn->eaBase) {
default: default:
//debug("Unexpected eaBase"); //debug("Unexpected eaBase");
@ -462,7 +450,7 @@ static bool translateRMMemory(MCInst *mcInst, InternalInstruction *insn)
// placeholders to keep the compiler happy. // placeholders to keep the compiler happy.
#define ENTRY(x) \ #define ENTRY(x) \
case EA_BASE_##x: \ case EA_BASE_##x: \
baseReg = MCOperand_CreateReg0(mcInst, X86_##x); break; MCOperand_CreateReg0(mcInst, X86_##x); break;
ALL_EA_BASES ALL_EA_BASES
#undef ENTRY #undef ENTRY
#define ENTRY(x) case EA_REG_##x: #define ENTRY(x) case EA_REG_##x:
@ -474,19 +462,14 @@ static bool translateRMMemory(MCInst *mcInst, InternalInstruction *insn)
} }
} }
scaleAmount = MCOperand_CreateImm0(mcInst, 1); scaleAmount = 1;
} }
displacement = MCOperand_CreateImm0(mcInst, insn->displacement); MCOperand_CreateImm0(mcInst, scaleAmount);
MCOperand_CreateReg0(mcInst, indexReg);
MCOperand_CreateImm0(mcInst, insn->displacement);
segmentReg = MCOperand_CreateReg0(mcInst, segmentRegnums[insn->segmentOverride]); MCOperand_CreateReg0(mcInst, segmentRegnums[insn->segmentOverride]);
MCInst_addOperand0(mcInst, baseReg);
MCInst_addOperand0(mcInst, scaleAmount);
MCInst_addOperand0(mcInst, indexReg);
MCInst_addOperand0(mcInst, displacement);
MCInst_addOperand0(mcInst, segmentReg);
return false; return false;
} }
@ -556,7 +539,7 @@ static bool translateRM(MCInst *mcInst, const OperandSpecifier *operand,
/// @param stackPos - The stack position to translate. /// @param stackPos - The stack position to translate.
static void translateFPRegister(MCInst *mcInst, uint8_t stackPos) static void translateFPRegister(MCInst *mcInst, uint8_t stackPos)
{ {
MCInst_addOperand0(mcInst, MCOperand_CreateReg0(mcInst, X86_ST0 + stackPos)); MCOperand_CreateReg0(mcInst, X86_ST0 + stackPos);
} }
/// translateMaskRegister - Translates a 3-bit mask register number to /// translateMaskRegister - Translates a 3-bit mask register number to
@ -572,7 +555,7 @@ static bool translateMaskRegister(MCInst *mcInst, uint8_t maskRegNum)
return true; return true;
} }
MCInst_addOperand0(mcInst, MCOperand_CreateReg0(mcInst, X86_K0 + maskRegNum)); MCOperand_CreateReg0(mcInst, X86_K0 + maskRegNum);
return false; return false;
} }