Skip to content

Commit

Permalink
x86: more simplification on managing MCOperand. this also fixes a bug…
Browse files Browse the repository at this point in the history
… in handling memory reference instructions
  • Loading branch information
aquynh committed Jun 5, 2014
1 parent e70a043 commit cf08138
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 79 deletions.
43 changes: 22 additions & 21 deletions MCInst.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand All @@ -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++;
Expand Down Expand Up @@ -187,6 +166,7 @@ MCOperand *MCOperand_CreateReg(unsigned Reg)
return op;
}

/*
MCOperand *MCOperand_CreateReg0(MCInst *mcInst, unsigned Reg)
{
MCOperand *op = &(mcInst->Operands[MCINST_CACHE]);
Expand All @@ -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)
{
Expand All @@ -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]);
Expand All @@ -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)
{
Expand Down
8 changes: 3 additions & 5 deletions MCInst.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);

Expand Down
89 changes: 36 additions & 53 deletions arch/X86/X86Disassembler.c
Original file line number Diff line number Diff line change
Expand Up @@ -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] = {
Expand All @@ -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;
Expand All @@ -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;
}
Expand All @@ -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;
Expand All @@ -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;
}
Expand All @@ -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) {
Expand Down Expand Up @@ -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)
Expand All @@ -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]);
}
}

Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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
Expand All @@ -331,15 +319,15 @@ 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:
//debug("Unexpected sibBase");
return true;
}
} else {
baseReg = MCOperand_CreateReg0(mcInst, 0);
MCOperand_CreateReg0(mcInst, 0);
}

// Check whether we are handling VSIB addressing mode for GATHER.
Expand Down Expand Up @@ -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
Expand All @@ -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:
Expand All @@ -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");
Expand All @@ -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:
Expand All @@ -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;
}
Expand Down Expand Up @@ -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
Expand All @@ -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;
}
Expand Down

0 comments on commit cf08138

Please sign in to comment.