x86: more simplification on managing MCOperand. this also fixes a bug in handling memory reference instructions
This commit is contained in:
parent
e70a043a04
commit
cf0813809a
43
MCInst.c
43
MCInst.c
|
@ -80,10 +80,6 @@ unsigned MCInst_getNumOperands(const MCInst *inst)
|
|||
// NOTE: this will free @Op argument
|
||||
int MCInst_addOperand(MCInst *inst, MCOperand *Op)
|
||||
{
|
||||
if (inst->size == ARR_SIZE(inst->Operands))
|
||||
// full
|
||||
return -1;
|
||||
|
||||
inst->Operands[inst->size] = *Op;
|
||||
cs_mem_free(Op);
|
||||
|
||||
|
@ -92,26 +88,9 @@ int MCInst_addOperand(MCInst *inst, MCOperand *Op)
|
|||
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
|
||||
int MCInst_addOperand2(MCInst *inst, MCOperand *Op)
|
||||
{
|
||||
if (inst->size == ARR_SIZE(inst->Operands))
|
||||
// full
|
||||
return -1;
|
||||
|
||||
inst->Operands[inst->size] = *Op;
|
||||
|
||||
inst->size++;
|
||||
|
@ -187,6 +166,7 @@ MCOperand *MCOperand_CreateReg(unsigned Reg)
|
|||
return op;
|
||||
}
|
||||
|
||||
/*
|
||||
MCOperand *MCOperand_CreateReg0(MCInst *mcInst, unsigned Reg)
|
||||
{
|
||||
MCOperand *op = &(mcInst->Operands[MCINST_CACHE]);
|
||||
|
@ -196,6 +176,16 @@ MCOperand *MCOperand_CreateReg0(MCInst *mcInst, unsigned Reg)
|
|||
|
||||
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)
|
||||
{
|
||||
|
@ -207,6 +197,7 @@ MCOperand *MCOperand_CreateImm(int64_t Val)
|
|||
return op;
|
||||
}
|
||||
|
||||
/*
|
||||
MCOperand *MCOperand_CreateImm0(MCInst *mcInst, int64_t Val)
|
||||
{
|
||||
MCOperand *op = &(mcInst->Operands[MCINST_CACHE]);
|
||||
|
@ -216,6 +207,16 @@ MCOperand *MCOperand_CreateImm0(MCInst *mcInst, int64_t Val)
|
|||
|
||||
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)
|
||||
{
|
||||
|
|
8
MCInst.h
8
MCInst.h
|
@ -81,9 +81,9 @@ MCOperand *MCOperand_CreateImm(int64_t 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
|
||||
// Detail information of disassembled instruction
|
||||
|
@ -141,7 +141,7 @@ typedef struct cs_insn_flat {
|
|||
/// instruction.
|
||||
struct MCInst {
|
||||
unsigned Opcode;
|
||||
MCOperand Operands[32];
|
||||
MCOperand Operands[34];
|
||||
unsigned size; // number of operands
|
||||
cs_insn_flat flat_insn; // insn to be exposed to public
|
||||
unsigned OpcodePub;
|
||||
|
@ -177,8 +177,6 @@ unsigned MCInst_getNumOperands(const MCInst *inst);
|
|||
|
||||
int MCInst_addOperand(MCInst *inst, MCOperand *Op);
|
||||
|
||||
int MCInst_addOperand0(MCInst *inst, MCOperand *Op);
|
||||
|
||||
// This addOperand2 function doesnt free Op
|
||||
int MCInst_addOperand2(MCInst *inst, MCOperand *Op);
|
||||
|
||||
|
|
|
@ -77,7 +77,7 @@ static void translateRegister(MCInst *mcInst, Reg reg)
|
|||
#undef ENTRY
|
||||
|
||||
uint8_t llvmRegnum = llvmRegnums[reg];
|
||||
MCInst_addOperand0(mcInst, MCOperand_CreateReg0(mcInst, llvmRegnum));
|
||||
MCOperand_CreateReg0(mcInst, llvmRegnum);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
unsigned baseRegNo;
|
||||
MCOperand *segmentReg;
|
||||
MCOperand *baseReg;
|
||||
|
||||
if (insn->mode == MODE_64BIT)
|
||||
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;
|
||||
}
|
||||
|
||||
baseReg = MCOperand_CreateReg0(mcInst, baseRegNo);
|
||||
MCInst_addOperand0(mcInst, baseReg);
|
||||
MCOperand_CreateReg0(mcInst, baseRegNo);
|
||||
|
||||
segmentReg = MCOperand_CreateReg0(mcInst, segmentRegnums[insn->segmentOverride]);
|
||||
MCInst_addOperand0(mcInst, segmentReg);
|
||||
MCOperand_CreateReg0(mcInst, segmentRegnums[insn->segmentOverride]);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -125,7 +121,6 @@ static bool translateSrcIndex(MCInst *mcInst, InternalInstruction *insn)
|
|||
static bool translateDstIndex(MCInst *mcInst, InternalInstruction *insn)
|
||||
{
|
||||
unsigned baseRegNo;
|
||||
MCOperand *baseReg;
|
||||
|
||||
if (insn->mode == MODE_64BIT)
|
||||
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;
|
||||
}
|
||||
|
||||
baseReg = MCOperand_CreateReg0(mcInst, baseRegNo);
|
||||
MCInst_addOperand0(mcInst, baseReg);
|
||||
MCOperand_CreateReg0(mcInst, baseRegNo);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -152,7 +146,6 @@ static void translateImmediate(MCInst *mcInst, uint64_t immediate,
|
|||
const OperandSpecifier *operand, InternalInstruction *insn)
|
||||
{
|
||||
OperandType type;
|
||||
MCOperand *segmentReg;
|
||||
|
||||
type = (OperandType)operand->type;
|
||||
if (type == TYPE_RELv) {
|
||||
|
@ -227,13 +220,13 @@ static void translateImmediate(MCInst *mcInst, uint64_t immediate,
|
|||
case TYPE_XMM32:
|
||||
case TYPE_XMM64:
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
case TYPE_REL8:
|
||||
if(immediate & 0x80)
|
||||
|
@ -249,12 +242,11 @@ static void translateImmediate(MCInst *mcInst, uint64_t immediate,
|
|||
break;
|
||||
}
|
||||
|
||||
MCInst_addOperand0(mcInst, MCOperand_CreateImm0(mcInst, immediate));
|
||||
MCOperand_CreateImm0(mcInst, immediate);
|
||||
|
||||
if (type == TYPE_MOFFS8 || type == TYPE_MOFFS16 ||
|
||||
type == TYPE_MOFFS32 || type == TYPE_MOFFS64) {
|
||||
segmentReg = MCOperand_CreateReg0(mcInst, segmentRegnums[insn->segmentOverride]);
|
||||
MCInst_addOperand0(mcInst, segmentReg);
|
||||
MCOperand_CreateReg0(mcInst, segmentRegnums[insn->segmentOverride]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -283,7 +275,7 @@ static bool translateRMRegister(MCInst *mcInst, InternalInstruction *insn)
|
|||
return true;
|
||||
#define ENTRY(x) \
|
||||
case EA_REG_##x: \
|
||||
MCInst_addOperand0(mcInst, MCOperand_CreateReg0(mcInst, X86_##x)); break;
|
||||
MCOperand_CreateReg0(mcInst, X86_##x); break;
|
||||
ALL_REGS
|
||||
#undef ENTRY
|
||||
default:
|
||||
|
@ -316,12 +308,8 @@ static bool translateRMMemory(MCInst *mcInst, InternalInstruction *insn)
|
|||
// 5. segmentreg (register) x86_registerNONE for now, but could be set
|
||||
// if we have segment overrides
|
||||
|
||||
MCOperand *baseReg;
|
||||
MCOperand *scaleAmount;
|
||||
MCOperand *indexReg;
|
||||
MCOperand *displacement;
|
||||
MCOperand *segmentReg;
|
||||
bool IndexIs512, IndexIs128, IndexIs256;
|
||||
int scaleAmount, indexReg;
|
||||
#ifndef CAPSTONE_X86_REDUCE
|
||||
uint32_t Opcode;
|
||||
#endif
|
||||
|
@ -331,7 +319,7 @@ static bool translateRMMemory(MCInst *mcInst, InternalInstruction *insn)
|
|||
switch (insn->sibBase) {
|
||||
#define ENTRY(x) \
|
||||
case SIB_BASE_##x: \
|
||||
baseReg = MCOperand_CreateReg0(mcInst, X86_##x); break;
|
||||
MCOperand_CreateReg0(mcInst, X86_##x); break;
|
||||
ALL_SIB_BASES
|
||||
#undef ENTRY
|
||||
default:
|
||||
|
@ -339,7 +327,7 @@ static bool translateRMMemory(MCInst *mcInst, InternalInstruction *insn)
|
|||
return true;
|
||||
}
|
||||
} else {
|
||||
baseReg = MCOperand_CreateReg0(mcInst, 0);
|
||||
MCOperand_CreateReg0(mcInst, 0);
|
||||
}
|
||||
|
||||
// Check whether we are handling VSIB addressing mode for GATHER.
|
||||
|
@ -407,7 +395,7 @@ static bool translateRMMemory(MCInst *mcInst, InternalInstruction *insn)
|
|||
return true;
|
||||
#define ENTRY(x) \
|
||||
case SIB_INDEX_##x: \
|
||||
indexReg = MCOperand_CreateReg0(mcInst, X86_##x); break;
|
||||
indexReg = X86_##x; break;
|
||||
EA_BASES_32BIT
|
||||
EA_BASES_64BIT
|
||||
REGS_XMM
|
||||
|
@ -416,10 +404,10 @@ static bool translateRMMemory(MCInst *mcInst, InternalInstruction *insn)
|
|||
#undef ENTRY
|
||||
}
|
||||
} else {
|
||||
indexReg = MCOperand_CreateReg0(mcInst, 0);
|
||||
indexReg = 0;
|
||||
}
|
||||
|
||||
scaleAmount = MCOperand_CreateImm0(mcInst, insn->sibScale);
|
||||
scaleAmount = insn->sibScale;
|
||||
} else {
|
||||
switch (insn->eaBase) {
|
||||
case EA_BASE_NONE:
|
||||
|
@ -428,30 +416,30 @@ static bool translateRMMemory(MCInst *mcInst, InternalInstruction *insn)
|
|||
return true;
|
||||
}
|
||||
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
|
||||
baseReg = MCOperand_CreateReg0(mcInst, 0);
|
||||
MCOperand_CreateReg0(mcInst, 0);
|
||||
|
||||
indexReg = MCOperand_CreateReg0(mcInst, 0);
|
||||
indexReg = 0;
|
||||
break;
|
||||
case EA_BASE_BX_SI:
|
||||
baseReg = MCOperand_CreateReg0(mcInst, X86_BX);
|
||||
indexReg = MCOperand_CreateReg0(mcInst, X86_SI);
|
||||
MCOperand_CreateReg0(mcInst, X86_BX);
|
||||
indexReg = X86_SI;
|
||||
break;
|
||||
case EA_BASE_BX_DI:
|
||||
baseReg = MCOperand_CreateReg0(mcInst, X86_BX);
|
||||
indexReg = MCOperand_CreateReg0(mcInst, X86_DI);
|
||||
MCOperand_CreateReg0(mcInst, X86_BX);
|
||||
indexReg = X86_DI;
|
||||
break;
|
||||
case EA_BASE_BP_SI:
|
||||
baseReg = MCOperand_CreateReg0(mcInst, X86_BP);
|
||||
indexReg = MCOperand_CreateReg0(mcInst, X86_SI);
|
||||
MCOperand_CreateReg0(mcInst, X86_BP);
|
||||
indexReg = X86_SI;
|
||||
break;
|
||||
case EA_BASE_BP_DI:
|
||||
baseReg = MCOperand_CreateReg0(mcInst, X86_BP);
|
||||
indexReg = MCOperand_CreateReg0(mcInst, X86_DI);
|
||||
MCOperand_CreateReg0(mcInst, X86_BP);
|
||||
indexReg = X86_DI;
|
||||
break;
|
||||
default:
|
||||
indexReg = MCOperand_CreateReg0(mcInst, 0);
|
||||
indexReg = 0;
|
||||
switch (insn->eaBase) {
|
||||
default:
|
||||
//debug("Unexpected eaBase");
|
||||
|
@ -462,7 +450,7 @@ static bool translateRMMemory(MCInst *mcInst, InternalInstruction *insn)
|
|||
// placeholders to keep the compiler happy.
|
||||
#define ENTRY(x) \
|
||||
case EA_BASE_##x: \
|
||||
baseReg = MCOperand_CreateReg0(mcInst, X86_##x); break;
|
||||
MCOperand_CreateReg0(mcInst, X86_##x); break;
|
||||
ALL_EA_BASES
|
||||
#undef ENTRY
|
||||
#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]);
|
||||
|
||||
MCInst_addOperand0(mcInst, baseReg);
|
||||
MCInst_addOperand0(mcInst, scaleAmount);
|
||||
MCInst_addOperand0(mcInst, indexReg);
|
||||
|
||||
MCInst_addOperand0(mcInst, displacement);
|
||||
MCInst_addOperand0(mcInst, segmentReg);
|
||||
MCOperand_CreateReg0(mcInst, segmentRegnums[insn->segmentOverride]);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -556,7 +539,7 @@ static bool translateRM(MCInst *mcInst, const OperandSpecifier *operand,
|
|||
/// @param stackPos - The stack position to translate.
|
||||
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
|
||||
|
@ -572,7 +555,7 @@ static bool translateMaskRegister(MCInst *mcInst, uint8_t maskRegNum)
|
|||
return true;
|
||||
}
|
||||
|
||||
MCInst_addOperand0(mcInst, MCOperand_CreateReg0(mcInst, X86_K0 + maskRegNum));
|
||||
MCOperand_CreateReg0(mcInst, X86_K0 + maskRegNum);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue