mirror of
https://github.com/capstone-engine/capstone.git
synced 2025-03-07 05:47:32 +00:00
arm: support cs_regs_access() API
This commit is contained in:
parent
5f22deb071
commit
29f777bdd9
1
MCInst.c
1
MCInst.c
@ -17,6 +17,7 @@ void MCInst_Init(MCInst *inst)
|
||||
inst->has_imm = false;
|
||||
inst->op1_size = 0;
|
||||
inst->writeback = false;
|
||||
inst->ac_idx = 0;
|
||||
}
|
||||
|
||||
void MCInst_clear(MCInst *inst)
|
||||
|
2
MCInst.h
2
MCInst.h
@ -107,6 +107,8 @@ struct MCInst {
|
||||
uint8_t x86_prefix[4];
|
||||
uint8_t imm_size; // immediate size for X86_OP_IMM operand
|
||||
bool writeback; // writeback for ARM
|
||||
// operand access index for list of registers sharing the same access right (for ARM)
|
||||
uint8_t ac_idx;
|
||||
};
|
||||
|
||||
void MCInst_Init(MCInst *inst);
|
||||
|
1
Makefile
1
Makefile
@ -87,6 +87,7 @@ DEP_ARM += arch/ARM/ARMGenInstrInfo.inc
|
||||
DEP_ARM += arch/ARM/ARMGenRegisterInfo.inc
|
||||
DEP_ARM += arch/ARM/ARMGenSubtargetInfo.inc
|
||||
DEP_ARM += arch/ARM/ARMMappingInsn.inc
|
||||
DEP_ARM += arch/ARM/ARMMappingInsnOp.inc
|
||||
|
||||
LIBOBJ_ARM =
|
||||
ifneq (,$(findstring arm,$(CAPSTONE_ARCHS)))
|
||||
|
@ -472,8 +472,10 @@ static DecodeStatus _ARM_getInstruction(cs_struct *ud, MCInst *MI, const uint8_t
|
||||
|
||||
if (MI->flat_insn->detail) {
|
||||
memset(&MI->flat_insn->detail->arm, 0, sizeof(cs_arm));
|
||||
for (i = 0; i < ARR_SIZE(MI->flat_insn->detail->arm.operands); i++)
|
||||
for (i = 0; i < ARR_SIZE(MI->flat_insn->detail->arm.operands); i++) {
|
||||
MI->flat_insn->detail->arm.operands[i].vector_index = -1;
|
||||
MI->flat_insn->detail->arm.operands[i].neon_lane = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (ud->big_endian)
|
||||
@ -713,8 +715,10 @@ static DecodeStatus _Thumb_getInstruction(cs_struct *ud, MCInst *MI, const uint8
|
||||
|
||||
if (MI->flat_insn->detail) {
|
||||
memset(&MI->flat_insn->detail->arm, 0, sizeof(cs_arm));
|
||||
for (i = 0; i < ARR_SIZE(MI->flat_insn->detail->arm.operands); i++)
|
||||
for (i = 0; i < ARR_SIZE(MI->flat_insn->detail->arm.operands); i++) {
|
||||
MI->flat_insn->detail->arm.operands[i].vector_index = -1;
|
||||
MI->flat_insn->detail->arm.operands[i].neon_lane = -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (ud->big_endian)
|
||||
|
@ -121,6 +121,21 @@ static void printModImmOperand(MCInst *MI, unsigned OpNum, SStream *O);
|
||||
|
||||
static void printInstSyncBOption(MCInst *MI, unsigned OpNum, SStream *O);
|
||||
|
||||
// copy & normalize access info
|
||||
static uint8_t get_op_access(cs_struct *h, unsigned int id, unsigned int index)
|
||||
{
|
||||
#ifndef CAPSTONE_DIET
|
||||
uint8_t *arr = ARM_get_op_access(h, id);
|
||||
|
||||
if (arr[index] == CS_AC_IGNORE)
|
||||
return 0;
|
||||
|
||||
return arr[index];
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void set_mem_access(MCInst *MI, bool status)
|
||||
{
|
||||
if (MI->csh->detail != CS_OPT_ON)
|
||||
@ -128,11 +143,21 @@ static void set_mem_access(MCInst *MI, bool status)
|
||||
|
||||
MI->csh->doing_mem = status;
|
||||
if (status) {
|
||||
#ifndef CAPSTONE_DIET
|
||||
uint8_t access;
|
||||
#endif
|
||||
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_MEM;
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.base = ARM_REG_INVALID;
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.index = ARM_REG_INVALID;
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.scale = 1;
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.disp = 0;
|
||||
|
||||
#ifndef CAPSTONE_DIET
|
||||
access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
|
||||
MI->ac_idx++;
|
||||
#endif
|
||||
} else {
|
||||
// done, create the next operand slot
|
||||
MI->flat_insn->detail->arm.op_count++;
|
||||
@ -391,8 +416,10 @@ void ARM_post_printer(csh ud, cs_insn *insn, char *insn_asm, MCInst *mci)
|
||||
case ARM_MOVPCLR:
|
||||
insn->detail->arm.operands[0].type = ARM_OP_REG;
|
||||
insn->detail->arm.operands[0].reg = ARM_REG_PC;
|
||||
insn->detail->arm.operands[0].access = CS_AC_READ;
|
||||
insn->detail->arm.operands[1].type = ARM_OP_REG;
|
||||
insn->detail->arm.operands[1].reg = ARM_REG_LR;
|
||||
insn->detail->arm.operands[1].access = CS_AC_WRITE;
|
||||
insn->detail->arm.op_count = 2;
|
||||
break;
|
||||
}
|
||||
@ -401,9 +428,9 @@ void ARM_post_printer(csh ud, cs_insn *insn, char *insn_asm, MCInst *mci)
|
||||
void ARM_printInst(MCInst *MI, SStream *O, void *Info)
|
||||
{
|
||||
MCRegisterInfo *MRI = (MCRegisterInfo *)Info;
|
||||
|
||||
unsigned Opcode = MCInst_getOpcode(MI), tmp, i, pubOpcode;
|
||||
|
||||
|
||||
switch(Opcode) {
|
||||
// Check for HINT instructions w/ canonical names.
|
||||
case ARM_HINT:
|
||||
@ -452,6 +479,7 @@ void ARM_printInst(MCInst *MI, SStream *O, void *Info)
|
||||
if (MI->csh->detail) {
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(Dst);
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = CS_AC_WRITE;
|
||||
MI->flat_insn->detail->arm.op_count++;
|
||||
}
|
||||
|
||||
@ -461,6 +489,7 @@ void ARM_printInst(MCInst *MI, SStream *O, void *Info)
|
||||
if (MI->csh->detail) {
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MO1);
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = CS_AC_READ;
|
||||
MI->flat_insn->detail->arm.op_count++;
|
||||
}
|
||||
|
||||
@ -469,6 +498,7 @@ void ARM_printInst(MCInst *MI, SStream *O, void *Info)
|
||||
if (MI->csh->detail) {
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MO2);
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = CS_AC_READ;
|
||||
MI->flat_insn->detail->arm.op_count++;
|
||||
}
|
||||
//assert(ARM_AM_getSORegOffset(MO3.getImm()) == 0);
|
||||
@ -490,6 +520,7 @@ void ARM_printInst(MCInst *MI, SStream *O, void *Info)
|
||||
if (MI->csh->detail) {
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(Dst);
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = CS_AC_WRITE;
|
||||
MI->flat_insn->detail->arm.op_count++;
|
||||
}
|
||||
|
||||
@ -498,6 +529,7 @@ void ARM_printInst(MCInst *MI, SStream *O, void *Info)
|
||||
if (MI->csh->detail) {
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MO1);
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = CS_AC_READ;
|
||||
MI->flat_insn->detail->arm.op_count++;
|
||||
}
|
||||
|
||||
@ -546,8 +578,16 @@ void ARM_printInst(MCInst *MI, SStream *O, void *Info)
|
||||
SStream_concat0(O, "\t{");
|
||||
printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, 1)));
|
||||
if (MI->csh->detail) {
|
||||
#ifndef CAPSTONE_DIET
|
||||
uint8_t access;
|
||||
#endif
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, 1));
|
||||
#ifndef CAPSTONE_DIET
|
||||
access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
|
||||
MI->ac_idx++;
|
||||
#endif
|
||||
MI->flat_insn->detail->arm.op_count++;
|
||||
}
|
||||
SStream_concat0(O, "}");
|
||||
@ -567,6 +607,13 @@ void ARM_printInst(MCInst *MI, SStream *O, void *Info)
|
||||
if (Opcode == ARM_t2LDMIA_UPD)
|
||||
SStream_concat0(O, ".w");
|
||||
SStream_concat0(O, "\t");
|
||||
if (MI->csh->detail) {
|
||||
MI->flat_insn->detail->regs_read[MI->flat_insn->detail->regs_read_count] = ARM_REG_SP;
|
||||
MI->flat_insn->detail->regs_read_count++;
|
||||
MI->flat_insn->detail->regs_write[MI->flat_insn->detail->regs_write_count] = ARM_REG_SP;
|
||||
MI->flat_insn->detail->regs_write_count++;
|
||||
}
|
||||
|
||||
printRegisterList(MI, 4, O);
|
||||
return;
|
||||
}
|
||||
@ -586,6 +633,7 @@ void ARM_printInst(MCInst *MI, SStream *O, void *Info)
|
||||
if (MI->csh->detail) {
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, 0));
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = CS_AC_READ;
|
||||
MI->flat_insn->detail->arm.op_count++;
|
||||
}
|
||||
SStream_concat0(O, "}");
|
||||
@ -638,6 +686,7 @@ void ARM_printInst(MCInst *MI, SStream *O, void *Info)
|
||||
if (MI->csh->detail) {
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = BaseReg;
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = CS_AC_READ;
|
||||
MI->flat_insn->detail->arm.op_count++;
|
||||
}
|
||||
if (Writeback) {
|
||||
@ -721,8 +770,17 @@ static void printOperand(MCInst *MI, unsigned OpNo, SStream *O)
|
||||
else
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.index = Reg;
|
||||
} else {
|
||||
#ifndef CAPSTONE_DIET
|
||||
uint8_t access;
|
||||
#endif
|
||||
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = Reg;
|
||||
#ifndef CAPSTONE_DIET
|
||||
access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
|
||||
MI->ac_idx++;
|
||||
#endif
|
||||
MI->flat_insn->detail->arm.op_count++;
|
||||
}
|
||||
}
|
||||
@ -829,6 +887,7 @@ static void printThumbLdrLabelOperand(MCInst *MI, unsigned OpNum, SStream *O)
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.index = ARM_REG_INVALID;
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.scale = 1;
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.disp = OffImm;
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = CS_AC_READ;
|
||||
MI->flat_insn->detail->arm.op_count++;
|
||||
}
|
||||
}
|
||||
@ -850,6 +909,7 @@ static void printSORegRegOperand(MCInst *MI, unsigned OpNum, SStream *O)
|
||||
if (MI->csh->detail) {
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MO1);
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = CS_AC_READ;
|
||||
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].shift.type = (MCOperand_getImm(MO3) & 7) + ARM_SFT_ASR_REG - 1;
|
||||
MI->flat_insn->detail->arm.op_count++;
|
||||
@ -878,6 +938,7 @@ static void printSORegImmOperand(MCInst *MI, unsigned OpNum, SStream *O)
|
||||
if (MI->csh->detail) {
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MO1);
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = CS_AC_READ;
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].shift.type = MCOperand_getImm(MO2) & 7;
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].shift.value = (unsigned int)MCOperand_getImm(MO2) >> 3;
|
||||
MI->flat_insn->detail->arm.op_count++;
|
||||
@ -1019,6 +1080,7 @@ static void printAddrMode2OffsetOperand(MCInst *MI, unsigned OpNum, SStream *O)
|
||||
if (MI->csh->detail) {
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MO1);
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = CS_AC_READ;
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].subtracted = subtracted == ARM_AM_sub;
|
||||
MI->flat_insn->detail->arm.op_count++;
|
||||
}
|
||||
@ -1109,6 +1171,7 @@ static void printAddrMode3OffsetOperand(MCInst *MI, unsigned OpNum, SStream *O)
|
||||
if (MI->csh->detail) {
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MO1);
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = CS_AC_READ;
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].subtracted = subtracted == ARM_AM_sub;
|
||||
MI->flat_insn->detail->arm.op_count++;
|
||||
}
|
||||
@ -1158,6 +1221,7 @@ static void printPostIdxRegOperand(MCInst *MI, unsigned OpNum, SStream *O)
|
||||
if (MI->csh->detail) {
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MO1);
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = CS_AC_READ;
|
||||
MI->flat_insn->detail->arm.op_count++;
|
||||
}
|
||||
}
|
||||
@ -1194,6 +1258,7 @@ static void printAddrMode5Operand(MCInst *MI, unsigned OpNum, SStream *O,
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.index = ARM_REG_INVALID;
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.scale = 1;
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.disp = 0;
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = CS_AC_READ;
|
||||
}
|
||||
|
||||
ImmOffs = ARM_AM_getAM5Offset((unsigned int)MCOperand_getImm(MO2));
|
||||
@ -1268,6 +1333,7 @@ static void printAddrMode6OffsetOperand(MCInst *MI, unsigned OpNum, SStream *O)
|
||||
if (MI->csh->detail) {
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MO);
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = CS_AC_READ;
|
||||
MI->flat_insn->detail->arm.op_count++;
|
||||
}
|
||||
}
|
||||
@ -1382,17 +1448,37 @@ static void printPKHASRShiftImm(MCInst *MI, unsigned OpNum, SStream *O)
|
||||
static void printRegisterList(MCInst *MI, unsigned OpNum, SStream *O)
|
||||
{
|
||||
unsigned i, e;
|
||||
#ifndef CAPSTONE_DIET
|
||||
uint8_t access;
|
||||
#endif
|
||||
|
||||
SStream_concat0(O, "{");
|
||||
|
||||
#ifndef CAPSTONE_DIET
|
||||
if (MI->csh->detail) {
|
||||
access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
|
||||
}
|
||||
#endif
|
||||
|
||||
for (i = OpNum, e = MCInst_getNumOperands(MI); i != e; ++i) {
|
||||
if (i != OpNum) SStream_concat0(O, ", ");
|
||||
printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, i)));
|
||||
if (MI->csh->detail) {
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, i));
|
||||
#ifndef CAPSTONE_DIET
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
|
||||
#endif
|
||||
MI->flat_insn->detail->arm.op_count++;
|
||||
}
|
||||
}
|
||||
SStream_concat0(O, "}");
|
||||
|
||||
#ifndef CAPSTONE_DIET
|
||||
if (MI->csh->detail) {
|
||||
MI->ac_idx++;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void printGPRPairOperand(MCInst *MI, unsigned OpNum, SStream *O,
|
||||
@ -1688,7 +1774,9 @@ static void printNoHashImmediate(MCInst *MI, unsigned OpNum, SStream *O)
|
||||
SStream_concat(O, "%u", tmp);
|
||||
if (MI->csh->detail) {
|
||||
if (MI->csh->doing_mem) {
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].mem.disp = tmp;
|
||||
MI->flat_insn->detail->arm.op_count--;
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].neon_lane = tmp;
|
||||
MI->ac_idx--; // consecutive operands share the same access right
|
||||
} else {
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_IMM;
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].imm = tmp;
|
||||
@ -1906,6 +1994,7 @@ static void printT2SOOperand(MCInst *MI, unsigned OpNum, SStream *O)
|
||||
if (MI->csh->detail) {
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = Reg;
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = CS_AC_READ;
|
||||
MI->flat_insn->detail->arm.op_count++;
|
||||
}
|
||||
|
||||
@ -2320,9 +2409,9 @@ static void printVectorIndex(MCInst *MI, unsigned OpNum, SStream *O)
|
||||
{
|
||||
unsigned tmp = (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNum));
|
||||
if (tmp > HEX_THRESHOLD)
|
||||
SStream_concat(O, "[0x%x]",tmp);
|
||||
SStream_concat(O, "[0x%x]", tmp);
|
||||
else
|
||||
SStream_concat(O, "[%u]",tmp);
|
||||
SStream_concat(O, "[%u]", tmp);
|
||||
if (MI->csh->detail) {
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count - 1].vector_index = tmp;
|
||||
}
|
||||
@ -2333,9 +2422,22 @@ static void printVectorListOne(MCInst *MI, unsigned OpNum, SStream *O)
|
||||
SStream_concat0(O, "{");
|
||||
printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)));
|
||||
if (MI->csh->detail) {
|
||||
#ifndef CAPSTONE_DIET
|
||||
uint8_t access;
|
||||
|
||||
access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
|
||||
#endif
|
||||
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum));
|
||||
#ifndef CAPSTONE_DIET
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
|
||||
#endif
|
||||
MI->flat_insn->detail->arm.op_count++;
|
||||
|
||||
#ifndef CAPSTONE_DIET
|
||||
MI->ac_idx++;
|
||||
#endif
|
||||
}
|
||||
SStream_concat0(O, "}");
|
||||
}
|
||||
@ -2343,14 +2445,25 @@ static void printVectorListOne(MCInst *MI, unsigned OpNum, SStream *O)
|
||||
static void printVectorListTwo(MCInst *MI, unsigned OpNum,
|
||||
SStream *O, MCRegisterInfo *MRI)
|
||||
{
|
||||
#ifndef CAPSTONE_DIET
|
||||
uint8_t access;
|
||||
#endif
|
||||
unsigned Reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum));
|
||||
unsigned Reg0 = MCRegisterInfo_getSubReg(MRI, Reg, ARM_dsub_0);
|
||||
unsigned Reg1 = MCRegisterInfo_getSubReg(MRI, Reg, ARM_dsub_1);
|
||||
|
||||
#ifndef CAPSTONE_DIET
|
||||
access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
|
||||
#endif
|
||||
|
||||
SStream_concat0(O, "{");
|
||||
printRegName(MI->csh, O, Reg0);
|
||||
if (MI->csh->detail) {
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = Reg0;
|
||||
#ifndef CAPSTONE_DIET
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
|
||||
#endif
|
||||
MI->flat_insn->detail->arm.op_count++;
|
||||
}
|
||||
SStream_concat0(O, ", ");
|
||||
@ -2358,22 +2471,40 @@ static void printVectorListTwo(MCInst *MI, unsigned OpNum,
|
||||
if (MI->csh->detail) {
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = Reg1;
|
||||
#ifndef CAPSTONE_DIET
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
|
||||
#endif
|
||||
MI->flat_insn->detail->arm.op_count++;
|
||||
}
|
||||
SStream_concat0(O, "}");
|
||||
|
||||
#ifndef CAPSTONE_DIET
|
||||
MI->ac_idx++;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void printVectorListTwoSpaced(MCInst *MI, unsigned OpNum,
|
||||
SStream *O, MCRegisterInfo *MRI)
|
||||
{
|
||||
#ifndef CAPSTONE_DIET
|
||||
uint8_t access;
|
||||
#endif
|
||||
unsigned Reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum));
|
||||
unsigned Reg0 = MCRegisterInfo_getSubReg(MRI, Reg, ARM_dsub_0);
|
||||
unsigned Reg1 = MCRegisterInfo_getSubReg(MRI, Reg, ARM_dsub_2);
|
||||
|
||||
#ifndef CAPSTONE_DIET
|
||||
access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
|
||||
#endif
|
||||
|
||||
SStream_concat0(O, "{");
|
||||
printRegName(MI->csh, O, Reg0);
|
||||
if (MI->csh->detail) {
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = Reg0;
|
||||
#ifndef CAPSTONE_DIET
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
|
||||
#endif
|
||||
MI->flat_insn->detail->arm.op_count++;
|
||||
}
|
||||
SStream_concat0(O, ", ");
|
||||
@ -2381,13 +2512,26 @@ static void printVectorListTwoSpaced(MCInst *MI, unsigned OpNum,
|
||||
if (MI->csh->detail) {
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = Reg1;
|
||||
#ifndef CAPSTONE_DIET
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
|
||||
#endif
|
||||
MI->flat_insn->detail->arm.op_count++;
|
||||
}
|
||||
SStream_concat0(O, "}");
|
||||
|
||||
#ifndef CAPSTONE_DIET
|
||||
MI->ac_idx++;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void printVectorListThree(MCInst *MI, unsigned OpNum, SStream *O)
|
||||
{
|
||||
#ifndef CAPSTONE_DIET
|
||||
uint8_t access;
|
||||
|
||||
access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
|
||||
#endif
|
||||
|
||||
// Normally, it's not safe to use register enum values directly with
|
||||
// addition to get the next register, but for VFP registers, the
|
||||
// sort order is guaranteed because they're all of the form D<n>.
|
||||
@ -2396,6 +2540,9 @@ static void printVectorListThree(MCInst *MI, unsigned OpNum, SStream *O)
|
||||
if (MI->csh->detail) {
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum));
|
||||
#ifndef CAPSTONE_DIET
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
|
||||
#endif
|
||||
MI->flat_insn->detail->arm.op_count++;
|
||||
}
|
||||
SStream_concat0(O, ", ");
|
||||
@ -2403,6 +2550,9 @@ static void printVectorListThree(MCInst *MI, unsigned OpNum, SStream *O)
|
||||
if (MI->csh->detail) {
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 1;
|
||||
#ifndef CAPSTONE_DIET
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
|
||||
#endif
|
||||
MI->flat_insn->detail->arm.op_count++;
|
||||
}
|
||||
SStream_concat0(O, ", ");
|
||||
@ -2410,13 +2560,26 @@ static void printVectorListThree(MCInst *MI, unsigned OpNum, SStream *O)
|
||||
if (MI->csh->detail) {
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 2;
|
||||
#ifndef CAPSTONE_DIET
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
|
||||
#endif
|
||||
MI->flat_insn->detail->arm.op_count++;
|
||||
}
|
||||
SStream_concat0(O, "}");
|
||||
|
||||
#ifndef CAPSTONE_DIET
|
||||
MI->ac_idx++;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void printVectorListFour(MCInst *MI, unsigned OpNum, SStream *O)
|
||||
{
|
||||
#ifndef CAPSTONE_DIET
|
||||
uint8_t access;
|
||||
|
||||
access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
|
||||
#endif
|
||||
|
||||
// Normally, it's not safe to use register enum values directly with
|
||||
// addition to get the next register, but for VFP registers, the
|
||||
// sort order is guaranteed because they're all of the form D<n>.
|
||||
@ -2425,6 +2588,9 @@ static void printVectorListFour(MCInst *MI, unsigned OpNum, SStream *O)
|
||||
if (MI->csh->detail) {
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum));
|
||||
#ifndef CAPSTONE_DIET
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
|
||||
#endif
|
||||
MI->flat_insn->detail->arm.op_count++;
|
||||
}
|
||||
SStream_concat0(O, ", ");
|
||||
@ -2432,6 +2598,9 @@ static void printVectorListFour(MCInst *MI, unsigned OpNum, SStream *O)
|
||||
if (MI->csh->detail) {
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 1;
|
||||
#ifndef CAPSTONE_DIET
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
|
||||
#endif
|
||||
MI->flat_insn->detail->arm.op_count++;
|
||||
}
|
||||
SStream_concat0(O, ", ");
|
||||
@ -2439,6 +2608,9 @@ static void printVectorListFour(MCInst *MI, unsigned OpNum, SStream *O)
|
||||
if (MI->csh->detail) {
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 2;
|
||||
#ifndef CAPSTONE_DIET
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
|
||||
#endif
|
||||
MI->flat_insn->detail->arm.op_count++;
|
||||
}
|
||||
SStream_concat0(O, ", ");
|
||||
@ -2446,34 +2618,65 @@ static void printVectorListFour(MCInst *MI, unsigned OpNum, SStream *O)
|
||||
if (MI->csh->detail) {
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 3;
|
||||
#ifndef CAPSTONE_DIET
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
|
||||
#endif
|
||||
MI->flat_insn->detail->arm.op_count++;
|
||||
}
|
||||
SStream_concat0(O, "}");
|
||||
|
||||
#ifndef CAPSTONE_DIET
|
||||
MI->ac_idx++;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void printVectorListOneAllLanes(MCInst *MI, unsigned OpNum, SStream *O)
|
||||
{
|
||||
#ifndef CAPSTONE_DIET
|
||||
uint8_t access;
|
||||
|
||||
access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
|
||||
#endif
|
||||
|
||||
SStream_concat0(O, "{");
|
||||
printRegName(MI->csh, O, MCOperand_getReg(MCInst_getOperand(MI, OpNum)));
|
||||
if (MI->csh->detail) {
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum));
|
||||
#ifndef CAPSTONE_DIET
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
|
||||
#endif
|
||||
MI->flat_insn->detail->arm.op_count++;
|
||||
}
|
||||
SStream_concat0(O, "[]}");
|
||||
|
||||
#ifndef CAPSTONE_DIET
|
||||
MI->ac_idx++;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void printVectorListTwoAllLanes(MCInst *MI, unsigned OpNum,
|
||||
SStream *O, MCRegisterInfo *MRI)
|
||||
{
|
||||
#ifndef CAPSTONE_DIET
|
||||
uint8_t access;
|
||||
#endif
|
||||
unsigned Reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum));
|
||||
unsigned Reg0 = MCRegisterInfo_getSubReg(MRI, Reg, ARM_dsub_0);
|
||||
unsigned Reg1 = MCRegisterInfo_getSubReg(MRI, Reg, ARM_dsub_1);
|
||||
|
||||
#ifndef CAPSTONE_DIET
|
||||
access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
|
||||
#endif
|
||||
|
||||
SStream_concat0(O, "{");
|
||||
printRegName(MI->csh, O, Reg0);
|
||||
if (MI->csh->detail) {
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = Reg0;
|
||||
#ifndef CAPSTONE_DIET
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
|
||||
#endif
|
||||
MI->flat_insn->detail->arm.op_count++;
|
||||
}
|
||||
SStream_concat0(O, "[], ");
|
||||
@ -2481,13 +2684,26 @@ static void printVectorListTwoAllLanes(MCInst *MI, unsigned OpNum,
|
||||
if (MI->csh->detail) {
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = Reg1;
|
||||
#ifndef CAPSTONE_DIET
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
|
||||
#endif
|
||||
MI->flat_insn->detail->arm.op_count++;
|
||||
}
|
||||
SStream_concat0(O, "[]}");
|
||||
|
||||
#ifndef CAPSTONE_DIET
|
||||
MI->ac_idx++;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void printVectorListThreeAllLanes(MCInst *MI, unsigned OpNum, SStream *O)
|
||||
{
|
||||
#ifndef CAPSTONE_DIET
|
||||
uint8_t access;
|
||||
|
||||
access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
|
||||
#endif
|
||||
|
||||
// Normally, it's not safe to use register enum values directly with
|
||||
// addition to get the next register, but for VFP registers, the
|
||||
// sort order is guaranteed because they're all of the form D<n>.
|
||||
@ -2496,6 +2712,9 @@ static void printVectorListThreeAllLanes(MCInst *MI, unsigned OpNum, SStream *O)
|
||||
if (MI->csh->detail) {
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum));
|
||||
#ifndef CAPSTONE_DIET
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
|
||||
#endif
|
||||
MI->flat_insn->detail->arm.op_count++;
|
||||
}
|
||||
SStream_concat0(O, "[], ");
|
||||
@ -2503,6 +2722,9 @@ static void printVectorListThreeAllLanes(MCInst *MI, unsigned OpNum, SStream *O)
|
||||
if (MI->csh->detail) {
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 1;
|
||||
#ifndef CAPSTONE_DIET
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
|
||||
#endif
|
||||
MI->flat_insn->detail->arm.op_count++;
|
||||
}
|
||||
SStream_concat0(O, "[], ");
|
||||
@ -2510,13 +2732,26 @@ static void printVectorListThreeAllLanes(MCInst *MI, unsigned OpNum, SStream *O)
|
||||
if (MI->csh->detail) {
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 2;
|
||||
#ifndef CAPSTONE_DIET
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
|
||||
#endif
|
||||
MI->flat_insn->detail->arm.op_count++;
|
||||
}
|
||||
SStream_concat0(O, "[]}");
|
||||
|
||||
#ifndef CAPSTONE_DIET
|
||||
MI->ac_idx++;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void printVectorListFourAllLanes(MCInst *MI, unsigned OpNum, SStream *O)
|
||||
{
|
||||
#ifndef CAPSTONE_DIET
|
||||
uint8_t access;
|
||||
|
||||
access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
|
||||
#endif
|
||||
|
||||
// Normally, it's not safe to use register enum values directly with
|
||||
// addition to get the next register, but for VFP registers, the
|
||||
// sort order is guaranteed because they're all of the form D<n>.
|
||||
@ -2525,6 +2760,9 @@ static void printVectorListFourAllLanes(MCInst *MI, unsigned OpNum, SStream *O)
|
||||
if (MI->csh->detail) {
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum));
|
||||
#ifndef CAPSTONE_DIET
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
|
||||
#endif
|
||||
MI->flat_insn->detail->arm.op_count++;
|
||||
}
|
||||
SStream_concat0(O, "[], ");
|
||||
@ -2532,6 +2770,9 @@ static void printVectorListFourAllLanes(MCInst *MI, unsigned OpNum, SStream *O)
|
||||
if (MI->csh->detail) {
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 1;
|
||||
#ifndef CAPSTONE_DIET
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
|
||||
#endif
|
||||
MI->flat_insn->detail->arm.op_count++;
|
||||
}
|
||||
SStream_concat0(O, "[], ");
|
||||
@ -2539,6 +2780,9 @@ static void printVectorListFourAllLanes(MCInst *MI, unsigned OpNum, SStream *O)
|
||||
if (MI->csh->detail) {
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 2;
|
||||
#ifndef CAPSTONE_DIET
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
|
||||
#endif
|
||||
MI->flat_insn->detail->arm.op_count++;
|
||||
}
|
||||
SStream_concat0(O, "[], ");
|
||||
@ -2546,22 +2790,40 @@ static void printVectorListFourAllLanes(MCInst *MI, unsigned OpNum, SStream *O)
|
||||
if (MI->csh->detail) {
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 3;
|
||||
#ifndef CAPSTONE_DIET
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
|
||||
#endif
|
||||
MI->flat_insn->detail->arm.op_count++;
|
||||
}
|
||||
SStream_concat0(O, "[]}");
|
||||
|
||||
#ifndef CAPSTONE_DIET
|
||||
MI->ac_idx++;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void printVectorListTwoSpacedAllLanes(MCInst *MI,
|
||||
unsigned OpNum, SStream *O, MCRegisterInfo *MRI)
|
||||
{
|
||||
#ifndef CAPSTONE_DIET
|
||||
uint8_t access;
|
||||
#endif
|
||||
unsigned Reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum));
|
||||
unsigned Reg0 = MCRegisterInfo_getSubReg(MRI, Reg, ARM_dsub_0);
|
||||
unsigned Reg1 = MCRegisterInfo_getSubReg(MRI, Reg, ARM_dsub_2);
|
||||
|
||||
#ifndef CAPSTONE_DIET
|
||||
access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
|
||||
#endif
|
||||
|
||||
SStream_concat0(O, "{");
|
||||
printRegName(MI->csh, O, Reg0);
|
||||
if (MI->csh->detail) {
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = Reg0;
|
||||
#ifndef CAPSTONE_DIET
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
|
||||
#endif
|
||||
MI->flat_insn->detail->arm.op_count++;
|
||||
}
|
||||
SStream_concat0(O, "[], ");
|
||||
@ -2569,14 +2831,27 @@ static void printVectorListTwoSpacedAllLanes(MCInst *MI,
|
||||
if (MI->csh->detail) {
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = Reg1;
|
||||
#ifndef CAPSTONE_DIET
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
|
||||
#endif
|
||||
MI->flat_insn->detail->arm.op_count++;
|
||||
}
|
||||
SStream_concat0(O, "[]}");
|
||||
|
||||
#ifndef CAPSTONE_DIET
|
||||
MI->ac_idx++;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void printVectorListThreeSpacedAllLanes(MCInst *MI,
|
||||
unsigned OpNum, SStream *O)
|
||||
{
|
||||
#ifndef CAPSTONE_DIET
|
||||
uint8_t access;
|
||||
|
||||
access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
|
||||
#endif
|
||||
|
||||
// Normally, it's not safe to use register enum values directly with
|
||||
// addition to get the next register, but for VFP registers, the
|
||||
// sort order is guaranteed because they're all of the form D<n>.
|
||||
@ -2585,6 +2860,9 @@ static void printVectorListThreeSpacedAllLanes(MCInst *MI,
|
||||
if (MI->csh->detail) {
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum));
|
||||
#ifndef CAPSTONE_DIET
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
|
||||
#endif
|
||||
MI->flat_insn->detail->arm.op_count++;
|
||||
}
|
||||
SStream_concat0(O, "[], ");
|
||||
@ -2592,6 +2870,9 @@ static void printVectorListThreeSpacedAllLanes(MCInst *MI,
|
||||
if (MI->csh->detail) {
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 2;
|
||||
#ifndef CAPSTONE_DIET
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
|
||||
#endif
|
||||
MI->flat_insn->detail->arm.op_count++;
|
||||
}
|
||||
SStream_concat0(O, "[], ");
|
||||
@ -2599,14 +2880,27 @@ static void printVectorListThreeSpacedAllLanes(MCInst *MI,
|
||||
if (MI->csh->detail) {
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 4;
|
||||
#ifndef CAPSTONE_DIET
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
|
||||
#endif
|
||||
MI->flat_insn->detail->arm.op_count++;
|
||||
}
|
||||
SStream_concat0(O, "[]}");
|
||||
|
||||
#ifndef CAPSTONE_DIET
|
||||
MI->ac_idx++;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void printVectorListFourSpacedAllLanes(MCInst *MI,
|
||||
unsigned OpNum, SStream *O)
|
||||
{
|
||||
#ifndef CAPSTONE_DIET
|
||||
uint8_t access;
|
||||
|
||||
access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
|
||||
#endif
|
||||
|
||||
// Normally, it's not safe to use register enum values directly with
|
||||
// addition to get the next register, but for VFP registers, the
|
||||
// sort order is guaranteed because they're all of the form D<n>.
|
||||
@ -2615,6 +2909,9 @@ static void printVectorListFourSpacedAllLanes(MCInst *MI,
|
||||
if (MI->csh->detail) {
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum));
|
||||
#ifndef CAPSTONE_DIET
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
|
||||
#endif
|
||||
MI->flat_insn->detail->arm.op_count++;
|
||||
}
|
||||
SStream_concat0(O, "[], ");
|
||||
@ -2622,6 +2919,9 @@ static void printVectorListFourSpacedAllLanes(MCInst *MI,
|
||||
if (MI->csh->detail) {
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 2;
|
||||
#ifndef CAPSTONE_DIET
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
|
||||
#endif
|
||||
MI->flat_insn->detail->arm.op_count++;
|
||||
}
|
||||
SStream_concat0(O, "[], ");
|
||||
@ -2629,6 +2929,9 @@ static void printVectorListFourSpacedAllLanes(MCInst *MI,
|
||||
if (MI->csh->detail) {
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 4;
|
||||
#ifndef CAPSTONE_DIET
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
|
||||
#endif
|
||||
MI->flat_insn->detail->arm.op_count++;
|
||||
}
|
||||
SStream_concat0(O, "[], ");
|
||||
@ -2636,13 +2939,26 @@ static void printVectorListFourSpacedAllLanes(MCInst *MI,
|
||||
if (MI->csh->detail) {
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 6;
|
||||
#ifndef CAPSTONE_DIET
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
|
||||
#endif
|
||||
MI->flat_insn->detail->arm.op_count++;
|
||||
}
|
||||
SStream_concat0(O, "[]}");
|
||||
|
||||
#ifndef CAPSTONE_DIET
|
||||
MI->ac_idx++;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void printVectorListThreeSpaced(MCInst *MI, unsigned OpNum, SStream *O)
|
||||
{
|
||||
#ifndef CAPSTONE_DIET
|
||||
uint8_t access;
|
||||
|
||||
access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
|
||||
#endif
|
||||
|
||||
// Normally, it's not safe to use register enum values directly with
|
||||
// addition to get the next register, but for VFP registers, the
|
||||
// sort order is guaranteed because they're all of the form D<n>.
|
||||
@ -2651,6 +2967,9 @@ static void printVectorListThreeSpaced(MCInst *MI, unsigned OpNum, SStream *O)
|
||||
if (MI->csh->detail) {
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum));
|
||||
#ifndef CAPSTONE_DIET
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
|
||||
#endif
|
||||
MI->flat_insn->detail->arm.op_count++;
|
||||
}
|
||||
SStream_concat0(O, ", ");
|
||||
@ -2658,6 +2977,9 @@ static void printVectorListThreeSpaced(MCInst *MI, unsigned OpNum, SStream *O)
|
||||
if (MI->csh->detail) {
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 2;
|
||||
#ifndef CAPSTONE_DIET
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
|
||||
#endif
|
||||
MI->flat_insn->detail->arm.op_count++;
|
||||
}
|
||||
SStream_concat0(O, ", ");
|
||||
@ -2665,13 +2987,26 @@ static void printVectorListThreeSpaced(MCInst *MI, unsigned OpNum, SStream *O)
|
||||
if (MI->csh->detail) {
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 4;
|
||||
#ifndef CAPSTONE_DIET
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
|
||||
#endif
|
||||
MI->flat_insn->detail->arm.op_count++;
|
||||
}
|
||||
SStream_concat0(O, "}");
|
||||
|
||||
#ifndef CAPSTONE_DIET
|
||||
MI->ac_idx++;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void printVectorListFourSpaced(MCInst *MI, unsigned OpNum, SStream *O)
|
||||
{
|
||||
#ifndef CAPSTONE_DIET
|
||||
uint8_t access;
|
||||
|
||||
access = get_op_access(MI->csh, MCInst_getOpcode(MI), MI->ac_idx);
|
||||
#endif
|
||||
|
||||
// Normally, it's not safe to use register enum values directly with
|
||||
// addition to get the next register, but for VFP registers, the
|
||||
// sort order is guaranteed because they're all of the form D<n>.
|
||||
@ -2680,6 +3015,9 @@ static void printVectorListFourSpaced(MCInst *MI, unsigned OpNum, SStream *O)
|
||||
if (MI->csh->detail) {
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum));
|
||||
#ifndef CAPSTONE_DIET
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
|
||||
#endif
|
||||
MI->flat_insn->detail->arm.op_count++;
|
||||
}
|
||||
SStream_concat0(O, ", ");
|
||||
@ -2687,6 +3025,9 @@ static void printVectorListFourSpaced(MCInst *MI, unsigned OpNum, SStream *O)
|
||||
if (MI->csh->detail) {
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 2;
|
||||
#ifndef CAPSTONE_DIET
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
|
||||
#endif
|
||||
MI->flat_insn->detail->arm.op_count++;
|
||||
}
|
||||
SStream_concat0(O, ", ");
|
||||
@ -2694,6 +3035,9 @@ static void printVectorListFourSpaced(MCInst *MI, unsigned OpNum, SStream *O)
|
||||
if (MI->csh->detail) {
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 4;
|
||||
#ifndef CAPSTONE_DIET
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
|
||||
#endif
|
||||
MI->flat_insn->detail->arm.op_count++;
|
||||
}
|
||||
SStream_concat0(O, ", ");
|
||||
@ -2701,9 +3045,16 @@ static void printVectorListFourSpaced(MCInst *MI, unsigned OpNum, SStream *O)
|
||||
if (MI->csh->detail) {
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].type = ARM_OP_REG;
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].reg = MCOperand_getReg(MCInst_getOperand(MI, OpNum)) + 6;
|
||||
#ifndef CAPSTONE_DIET
|
||||
MI->flat_insn->detail->arm.operands[MI->flat_insn->detail->arm.op_count].access = access;
|
||||
#endif
|
||||
MI->flat_insn->detail->arm.op_count++;
|
||||
}
|
||||
SStream_concat0(O, "}");
|
||||
|
||||
#ifndef CAPSTONE_DIET
|
||||
MI->ac_idx++;
|
||||
#endif
|
||||
}
|
||||
|
||||
void ARM_addVectorDataType(MCInst *MI, arm_vectordata_type vd)
|
||||
|
@ -877,24 +877,83 @@ bool ARM_blx_to_arm_mode(cs_struct *h, unsigned int id) {
|
||||
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
#ifndef CAPSTONE_DIET
|
||||
// map instruction to its characteristics
|
||||
typedef struct insn_op {
|
||||
unsigned int eflags_update; // how this instruction update status flags
|
||||
cs_ac_type operands[4];
|
||||
uint8_t access[7];
|
||||
} insn_op;
|
||||
|
||||
static insn_op insn_ops[] = {
|
||||
{
|
||||
// NULL item
|
||||
0,
|
||||
{ 0 }
|
||||
},
|
||||
|
||||
#include "ARMMappingInsnOp.inc"
|
||||
};
|
||||
|
||||
// given internal insn id, return operand access info
|
||||
uint8_t *ARM_get_op_access(cs_struct *h, unsigned int id)
|
||||
{
|
||||
int i = insn_find(insns, ARR_SIZE(insns), id, &h->insn_cache);
|
||||
if (i != 0) {
|
||||
return insn_ops[i].access;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void ARM_reg_access(const cs_insn *insn,
|
||||
cs_regs regs_read, uint8_t *regs_read_count,
|
||||
cs_regs regs_write, uint8_t *regs_write_count)
|
||||
{
|
||||
uint8_t i;
|
||||
uint8_t read_count, write_count;
|
||||
cs_arm *arm = &(insn->detail->arm);
|
||||
|
||||
read_count = insn->detail->regs_read_count;
|
||||
write_count = insn->detail->regs_write_count;
|
||||
|
||||
// implicit registers
|
||||
memcpy(regs_read, insn->detail->regs_read, read_count * sizeof(insn->detail->regs_read[0]));
|
||||
memcpy(regs_write, insn->detail->regs_write, write_count * sizeof(insn->detail->regs_write[0]));
|
||||
|
||||
// explicit registers
|
||||
for (i = 0; i < arm->op_count; i++) {
|
||||
cs_arm_op *op = &(arm->operands[i]);
|
||||
switch((int)op->type) {
|
||||
case ARM_OP_REG:
|
||||
if ((op->access & CS_AC_READ) && !arr_exist(regs_read, read_count, op->reg)) {
|
||||
regs_read[read_count] = op->reg;
|
||||
read_count++;
|
||||
}
|
||||
if ((op->access & CS_AC_WRITE) && !arr_exist(regs_write, write_count, op->reg)) {
|
||||
regs_write[write_count] = op->reg;
|
||||
write_count++;
|
||||
}
|
||||
break;
|
||||
case ARM_OP_MEM:
|
||||
// registers appeared in memory references always being read
|
||||
if ((op->mem.base != ARM_REG_INVALID) && !arr_exist(regs_read, read_count, op->mem.base)) {
|
||||
regs_read[read_count] = op->mem.base;
|
||||
read_count++;
|
||||
}
|
||||
if ((op->mem.index != ARM_REG_INVALID) && !arr_exist(regs_read, read_count, op->mem.index)) {
|
||||
regs_read[read_count] = op->mem.index;
|
||||
read_count++;
|
||||
}
|
||||
if ((arm->writeback) && (op->mem.base != ARM_REG_INVALID) && !arr_exist(regs_write, write_count, op->mem.base)) {
|
||||
regs_write[write_count] = op->mem.base;
|
||||
write_count++;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
*regs_read_count = read_count;
|
||||
*regs_write_count = write_count;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -23,4 +23,10 @@ bool ARM_rel_branch(cs_struct *h, unsigned int insn_id);
|
||||
|
||||
bool ARM_blx_to_arm_mode(cs_struct *h, unsigned int insn_id);
|
||||
|
||||
uint8_t *ARM_get_op_access(cs_struct *h, unsigned int id);
|
||||
|
||||
void ARM_reg_access(const cs_insn *insn,
|
||||
cs_regs regs_read, uint8_t *regs_read_count,
|
||||
cs_regs regs_write, uint8_t *regs_write_count);
|
||||
|
||||
#endif
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -30,6 +30,9 @@ static cs_err init(cs_struct *ud)
|
||||
ud->insn_name = ARM_insn_name;
|
||||
ud->group_name = ARM_group_name;
|
||||
ud->post_printer = ARM_post_printer;
|
||||
#ifndef CAPSTONE_DIET
|
||||
ud->reg_access = ARM_reg_access;
|
||||
#endif
|
||||
|
||||
if (ud->mode & CS_MODE_THUMB)
|
||||
ud->disasm = Thumb_getInstruction;
|
||||
|
@ -285,7 +285,7 @@ static void _printOperand(MCInst *MI, unsigned OpNo, SStream *O)
|
||||
}
|
||||
|
||||
#ifndef CAPSTONE_DIET
|
||||
// convert Intel access info to AT&T access info
|
||||
// copy & normalize access info
|
||||
static void get_op_access(cs_struct *h, unsigned int id, uint8_t *access, uint64_t *eflags)
|
||||
{
|
||||
#ifndef CAPSTONE_DIET
|
||||
|
@ -262,11 +262,14 @@ typedef struct arm_op_mem {
|
||||
// Instruction operand
|
||||
typedef struct cs_arm_op {
|
||||
int vector_index; // Vector Index for some vector operands (or -1 if irrelevant)
|
||||
|
||||
struct {
|
||||
arm_shifter type;
|
||||
unsigned int value;
|
||||
} shift;
|
||||
|
||||
arm_op_type type; // operand type
|
||||
|
||||
union {
|
||||
unsigned int reg; // register value for REG/SYSREG operand
|
||||
int32_t imm; // immediate value for C-IMM, P-IMM or IMM operand
|
||||
@ -274,9 +277,18 @@ typedef struct cs_arm_op {
|
||||
arm_op_mem mem; // base/index/scale/disp value for MEM operand
|
||||
arm_setend_type setend; // SETEND instruction's operand type
|
||||
};
|
||||
|
||||
// in some instructions, an operand can be subtracted or added to
|
||||
// the base register,
|
||||
bool subtracted; // if TRUE, this operand is subtracted. otherwise, it is added.
|
||||
|
||||
// How is this operand accessed? (READ, WRITE or READ|WRITE)
|
||||
// This field is combined of cs_ac_type.
|
||||
// NOTE: this field is irrelevant if engine is compiled in DIET mode.
|
||||
uint8_t access;
|
||||
|
||||
// Neon lane index for NEON instructions (or -1 if irrelevant)
|
||||
int8_t neon_lane;
|
||||
} cs_arm_op;
|
||||
|
||||
// Instruction structure
|
||||
|
@ -30,10 +30,12 @@ static void print_string_hex(char *comment, unsigned char *str, size_t len)
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
static void print_insn_detail(cs_insn *ins)
|
||||
static void print_insn_detail(csh handle, cs_insn *ins)
|
||||
{
|
||||
cs_arm *arm;
|
||||
int i;
|
||||
cs_regs regs_read, regs_write;
|
||||
uint8_t regs_read_count, regs_write_count;
|
||||
|
||||
// detail can be NULL on "data" instruction if SKIPDATA option is turned ON
|
||||
if (ins->detail == NULL)
|
||||
@ -88,6 +90,24 @@ static void print_insn_detail(cs_insn *ins)
|
||||
break;
|
||||
}
|
||||
|
||||
if (op->neon_lane != -1) {
|
||||
printf("\t\toperands[%u].neon_lane = %u\n", i, op->neon_lane);
|
||||
}
|
||||
|
||||
switch(op->access) {
|
||||
default:
|
||||
break;
|
||||
case CS_AC_READ:
|
||||
printf("\t\toperands[%u].access: READ\n", i);
|
||||
break;
|
||||
case CS_AC_WRITE:
|
||||
printf("\t\toperands[%u].access: WRITE\n", i);
|
||||
break;
|
||||
case CS_AC_READ | CS_AC_WRITE:
|
||||
printf("\t\toperands[%u].access: READ | WRITE\n", i);
|
||||
break;
|
||||
}
|
||||
|
||||
if (op->shift.type != ARM_SFT_INVALID && op->shift.value) {
|
||||
if (op->shift.type < ARM_SFT_ASR_REG)
|
||||
// shift with constant value
|
||||
@ -133,6 +153,27 @@ static void print_insn_detail(cs_insn *ins)
|
||||
if (arm->mem_barrier)
|
||||
printf("\tMemory-barrier: %u\n", arm->mem_barrier);
|
||||
|
||||
// Print out all registers accessed by this instruction (either implicit or explicit)
|
||||
if (!cs_regs_access(handle, ins,
|
||||
regs_read, ®s_read_count,
|
||||
regs_write, ®s_write_count)) {
|
||||
if (regs_read_count) {
|
||||
printf("\tRegisters read:");
|
||||
for(i = 0; i < regs_read_count; i++) {
|
||||
printf(" %s", cs_reg_name(handle, regs_read[i]));
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
if (regs_write_count) {
|
||||
printf("\tRegisters modified:");
|
||||
for(i = 0; i < regs_write_count; i++) {
|
||||
printf(" %s", cs_reg_name(handle, regs_write[i]));
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
@ -184,7 +225,11 @@ static void test()
|
||||
//#define ARM_CODE "\x90\x04\x0E\x00" // muleq lr, r0, r4
|
||||
//#define ARM_CODE "\x90\x24\x0E\x00" // muleq lr, r0, r4
|
||||
//#define ARM_CODE "\xb6\x10\x5f\xe1" // ldrh r1, [pc, #-6]
|
||||
#define ARM_CODE "\xED\xFF\xFF\xEB\x04\xe0\x2d\xe5\x00\x00\x00\x00\xe0\x83\x22\xe5\xf1\x02\x03\x0e\x00\x00\xa0\xe3\x02\x30\xc1\xe7\x00\x00\x53\xe3\x00\x02\x01\xf1\x05\x40\xd0\xe8\xf4\x80\x00\x00"
|
||||
|
||||
#define ARM_CODE "\x86\x48\x60\xf4\x4d\x0f\xe2\xf4\xED\xFF\xFF\xEB\x04\xe0\x2d\xe5\x00\x00\x00\x00\xe0\x83\x22\xe5\xf1\x02\x03\x0e\x00\x00\xa0\xe3\x02\x30\xc1\xe7\x00\x00\x53\xe3\x00\x02\x01\xf1\x05\x40\xd0\xe8\xf4\x80\x00\x00"
|
||||
|
||||
//#define ARM_CODE "\x86\x48\x60\xf4"
|
||||
|
||||
//#define ARM_CODE2 "\xf0\x24"
|
||||
//#define ARM_CODE2 "\x83\xb0"
|
||||
#define ARM_CODE2 "\xd1\xe8\x00\xf0\xf0\x24\x04\x07\x1f\x3c\xf2\xc0\x00\x00\x4f\xf0\x00\x01\x46\x6c"
|
||||
@ -194,7 +239,10 @@ static void test()
|
||||
//#define THUMB_CODE "\x01\x47" // bx r0
|
||||
//#define THUMB_CODE "\x02\x47" // bx r0
|
||||
//#define THUMB_CODE "\x0a\xbf" // itet eq
|
||||
#define THUMB_CODE "\x70\x47\xeb\x46\x83\xb0\xc9\x68\x1f\xb1\x30\xbf\xaf\xf3\x20\x84\x52\xf8\x23\xf0"
|
||||
|
||||
#define THUMB_CODE "\x60\xf9\x1f\x04\xe0\xf9\x4f\x07\x70\x47\xeb\x46\x83\xb0\xc9\x68\x1f\xb1\x30\xbf\xaf\xf3\x20\x84\x52\xf8\x23\xf0"
|
||||
//#define THUMB_CODE "\xe0\xf9\x4f\x07"
|
||||
|
||||
#define THUMB_CODE2 "\x4f\xf0\x00\x01\xbd\xe8\x00\x88\xd1\xe8\x00\xf0\x18\xbf\xad\xbf\xf3\xff\x0b\x0c\x86\xf3\x00\x89\x80\xf3\x00\x8c\x4f\xfa\x99\xf6\xd0\xff\xa2\x01"
|
||||
#define THUMB_MCLASS "\xef\xf3\x02\x80"
|
||||
#define ARMV8 "\xe0\x3b\xb2\xee\x42\x00\x01\xe1\x51\xf0\x7f\xf5"
|
||||
@ -272,7 +320,7 @@ static void test()
|
||||
|
||||
for (j = 0; j < count; j++) {
|
||||
printf("0x%"PRIx64":\t%s\t%s\n", insn[j].address, insn[j].mnemonic, insn[j].op_str);
|
||||
print_insn_detail(&insn[j]);
|
||||
print_insn_detail(handle, &insn[j]);
|
||||
}
|
||||
printf("0x%"PRIx64":\n", insn[j-1].address + insn[j-1].size);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user