From cf0813809afa76600f8b301a2ff481230f67e90f Mon Sep 17 00:00:00 2001 From: Nguyen Anh Quynh Date: Fri, 6 Jun 2014 00:56:46 +0800 Subject: [PATCH] x86: more simplification on managing MCOperand. this also fixes a bug in handling memory reference instructions --- MCInst.c | 43 +++++++++--------- MCInst.h | 8 ++-- arch/X86/X86Disassembler.c | 89 +++++++++++++++----------------------- 3 files changed, 61 insertions(+), 79 deletions(-) diff --git a/MCInst.c b/MCInst.c index c459171d98..3a70af70c9 100644 --- a/MCInst.c +++ b/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) { diff --git a/MCInst.h b/MCInst.h index c6f9720ca5..34a347dd03 100644 --- a/MCInst.h +++ b/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); diff --git a/arch/X86/X86Disassembler.c b/arch/X86/X86Disassembler.c index abdeaf072e..921cb81df3 100644 --- a/arch/X86/X86Disassembler.c +++ b/arch/X86/X86Disassembler.c @@ -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; }