Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions MCInst.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ void MCInst_Init(MCInst *inst, cs_arch arch)
inst->size = 0;
inst->has_imm = false;
inst->op1_size = 0;
inst->x86_writemask_op = -1;
inst->x86_writemask_detail_op = -1;
inst->ac_idx = 0;
inst->popcode_adjust = 0;
inst->assembly[0] = '\0';
Expand All @@ -52,6 +54,8 @@ void MCInst_Init(MCInst *inst, cs_arch arch)
void MCInst_clear(MCInst *inst)
{
inst->size = 0;
inst->x86_writemask_op = -1;
inst->x86_writemask_detail_op = -1;
}

// does not free @Op
Expand Down Expand Up @@ -320,6 +324,8 @@ void MCInst_updateWithTmpMI(MCInst *MI, MCInst *TmpMI)
{
MI->size = TmpMI->size;
MI->Opcode = TmpMI->Opcode;
MI->x86_writemask_op = TmpMI->x86_writemask_op;
MI->x86_writemask_detail_op = TmpMI->x86_writemask_detail_op;
assert(MI->size < MAX_MC_OPS);
memcpy(MI->Operands, TmpMI->Operands,
sizeof(MI->Operands[0]) * MI->size);
Expand Down
2 changes: 2 additions & 0 deletions MCInst.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,8 @@ struct MCInst {
uint64_t address; // address of this insn
cs_struct *csh; // save the main csh
uint8_t x86opsize; // opsize for [mem] operand
int8_t x86_writemask_op; // MCInst operand from ENCODING_WRITEMASK
int8_t x86_writemask_detail_op; // corresponding cs_x86_op index

// These flags could be used to pass some info from one target subcomponent
// to another, for example, from disassembler to asm printer. The values of
Expand Down
46 changes: 36 additions & 10 deletions arch/X86/X86ATTInstPrinter.c
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,19 @@ static void get_op_access(cs_struct *h, unsigned int id, uint8_t *access,
}
}

static uint8_t get_detail_op_access(const MCInst *MI, const uint8_t *access,
unsigned int detail_op)
{
if (MI->x86_writemask_detail_op >= 0) {
unsigned int writemask_op = MI->x86_writemask_detail_op;
if (detail_op == writemask_op)
return CS_AC_READ;
if (detail_op > writemask_op)
detail_op--;
}
return detail_op < CS_X86_MAXIMUM_OPERAND_SIZE ? access[detail_op] : 0;
}

static void printSrcIdx(MCInst *MI, unsigned Op, SStream *O)
{
MCOperand *SegReg;
Expand Down Expand Up @@ -349,7 +362,8 @@ static void printSrcIdx(MCInst *MI, unsigned Op, SStream *O)
&MI->flat_insn->detail->x86.eflags);
MI->flat_insn->detail->x86
.operands[MI->flat_insn->detail->x86.op_count]
.access = access[MI->flat_insn->detail->x86.op_count];
.access = get_detail_op_access(
MI, access, MI->flat_insn->detail->x86.op_count);
}

SegReg = MCInst_getOperand(MI, Op + 1);
Expand Down Expand Up @@ -406,7 +420,8 @@ static void printDstIdx(MCInst *MI, unsigned Op, SStream *O)
&MI->flat_insn->detail->x86.eflags);
MI->flat_insn->detail->x86
.operands[MI->flat_insn->detail->x86.op_count]
.access = access[MI->flat_insn->detail->x86.op_count];
.access = get_detail_op_access(
MI, access, MI->flat_insn->detail->x86.op_count);
}

// DI accesses are always ES-based on non-64bit mode
Expand Down Expand Up @@ -511,7 +526,8 @@ static void printMemOffset(MCInst *MI, unsigned Op, SStream *O)
&MI->flat_insn->detail->x86.eflags);
MI->flat_insn->detail->x86
.operands[MI->flat_insn->detail->x86.op_count]
.access = access[MI->flat_insn->detail->x86.op_count];
.access = get_detail_op_access(
MI, access, MI->flat_insn->detail->x86.op_count);
}

// If this has a segment register, print it.
Expand Down Expand Up @@ -661,16 +677,19 @@ static void printOperand(MCInst *MI, unsigned OpNo, SStream *O)
.size =
MI->csh->regsize_map[X86_register_map(
reg)];

if (OpNo == MI->x86_writemask_op)
MI->x86_writemask_detail_op =
MI->flat_insn->detail->x86
.op_count;
get_op_access(
MI->csh, MCInst_getOpcode(MI), access,
&MI->flat_insn->detail->x86.eflags);
MI->flat_insn->detail->x86
.operands[MI->flat_insn->detail->x86
.op_count]
.access =
access[MI->flat_insn->detail->x86
.op_count];
.access = get_detail_op_access(
MI, access,
MI->flat_insn->detail->x86.op_count);

MI->flat_insn->detail->x86.op_count++;
}
Expand Down Expand Up @@ -878,7 +897,8 @@ static void printMemReference(MCInst *MI, unsigned Op, SStream *O)
&MI->flat_insn->detail->x86.eflags);
MI->flat_insn->detail->x86
.operands[MI->flat_insn->detail->x86.op_count]
.access = access[MI->flat_insn->detail->x86.op_count];
.access = get_detail_op_access(
MI, access, MI->flat_insn->detail->x86.op_count);
}

// If this has a segment register, print it.
Expand Down Expand Up @@ -1145,6 +1165,8 @@ void X86_ATT_printInst(MCInst *MI, SStream *OS, void *info)
(ARR_SIZE(MI->flat_insn->detail->x86
.operands) -
1));
if (MI->x86_writemask_detail_op >= 0)
MI->x86_writemask_detail_op++;
memset(&(MI->flat_insn->detail->x86.operands[0]), 0,
sizeof(MI->flat_insn->detail->x86.operands[0]));
MI->flat_insn->detail->x86.operands[0].type =
Expand All @@ -1170,6 +1192,8 @@ void X86_ATT_printInst(MCInst *MI, SStream *OS, void *info)
(ARR_SIZE(MI->flat_insn->detail->x86
.operands) -
1));
if (MI->x86_writemask_detail_op >= 0)
MI->x86_writemask_detail_op++;
memset(&(MI->flat_insn->detail->x86.operands[0]), 0,
sizeof(MI->flat_insn->detail->x86.operands[0]));
MI->flat_insn->detail->x86.operands[0].type =
Expand Down Expand Up @@ -1206,8 +1230,10 @@ void X86_ATT_printInst(MCInst *MI, SStream *OS, void *info)
#ifndef CAPSTONE_DIET
get_op_access(MI->csh, MCInst_getOpcode(MI), access,
&MI->flat_insn->detail->x86.eflags);
MI->flat_insn->detail->x86.operands[0].access = access[0];
MI->flat_insn->detail->x86.operands[1].access = access[1];
MI->flat_insn->detail->x86.operands[0].access =
get_detail_op_access(MI, access, 0);
MI->flat_insn->detail->x86.operands[1].access =
get_detail_op_access(MI, access, 1);
#endif
}
}
Expand Down
1 change: 1 addition & 0 deletions arch/X86/X86Disassembler.c
Original file line number Diff line number Diff line change
Expand Up @@ -1124,6 +1124,7 @@ static bool translateMaskRegister(MCInst *mcInst, uint8_t maskRegNum)
return true;
}

mcInst->x86_writemask_op = MCInst_getNumOperands(mcInst);
MCOperand_CreateReg0(mcInst, X86_K0 + maskRegNum);

return false;
Expand Down
58 changes: 43 additions & 15 deletions arch/X86/X86IntelInstPrinter.c
Original file line number Diff line number Diff line change
Expand Up @@ -461,6 +461,20 @@ static void get_op_access(cs_struct *h, unsigned int id, uint8_t *access,
access[i] = 0;
#endif
}

static uint8_t get_detail_op_access(const MCInst *MI, const uint8_t *access,
unsigned int detail_op)
{
if (MI->x86_writemask_detail_op >= 0) {
unsigned int writemask_op = MI->x86_writemask_detail_op;
if (detail_op == writemask_op)
return CS_AC_READ;
if (detail_op > writemask_op)
detail_op--;
}

return detail_op < CS_X86_MAXIMUM_OPERAND_SIZE ? access[detail_op] : 0;
}
#endif

static void printSrcIdx(MCInst *MI, unsigned Op, SStream *O)
Expand Down Expand Up @@ -500,7 +514,8 @@ static void printSrcIdx(MCInst *MI, unsigned Op, SStream *O)
&MI->flat_insn->detail->x86.eflags);
MI->flat_insn->detail->x86
.operands[MI->flat_insn->detail->x86.op_count]
.access = access[MI->flat_insn->detail->x86.op_count];
.access = get_detail_op_access(
MI, access, MI->flat_insn->detail->x86.op_count);
#endif
}

Expand Down Expand Up @@ -559,7 +574,8 @@ static void printDstIdx(MCInst *MI, unsigned Op, SStream *O)
&MI->flat_insn->detail->x86.eflags);
MI->flat_insn->detail->x86
.operands[MI->flat_insn->detail->x86.op_count]
.access = access[MI->flat_insn->detail->x86.op_count];
.access = get_detail_op_access(
MI, access, MI->flat_insn->detail->x86.op_count);
#endif
}

Expand Down Expand Up @@ -674,7 +690,8 @@ static void printMemOffset(MCInst *MI, unsigned Op, SStream *O)
&MI->flat_insn->detail->x86.eflags);
MI->flat_insn->detail->x86
.operands[MI->flat_insn->detail->x86.op_count]
.access = access[MI->flat_insn->detail->x86.op_count];
.access = get_detail_op_access(
MI, access, MI->flat_insn->detail->x86.op_count);
#endif
}

Expand Down Expand Up @@ -740,7 +757,8 @@ static void printU8Imm(MCInst *MI, unsigned Op, SStream *O)
&MI->flat_insn->detail->x86.eflags);
MI->flat_insn->detail->x86
.operands[MI->flat_insn->detail->x86.op_count]
.access = access[MI->flat_insn->detail->x86.op_count];
.access = get_detail_op_access(
MI, access, MI->flat_insn->detail->x86.op_count);
#endif

MI->flat_insn->detail->x86.op_count++;
Expand Down Expand Up @@ -810,6 +828,8 @@ void X86_Intel_printInst(MCInst *MI, SStream *O, void *Info)
(ARR_SIZE(MI->flat_insn->detail->x86
.operands) -
1));
if (MI->x86_writemask_detail_op >= 0)
MI->x86_writemask_detail_op++;
MI->flat_insn->detail->x86.operands[0].type =
X86_OP_REG;
MI->flat_insn->detail->x86.operands[0].reg = reg;
Expand Down Expand Up @@ -843,8 +863,10 @@ void X86_Intel_printInst(MCInst *MI, SStream *O, void *Info)
#ifndef CAPSTONE_DIET
get_op_access(MI->csh, MCInst_getOpcode(MI), access,
&MI->flat_insn->detail->x86.eflags);
MI->flat_insn->detail->x86.operands[0].access = access[0];
MI->flat_insn->detail->x86.operands[1].access = access[1];
MI->flat_insn->detail->x86.operands[0].access =
get_detail_op_access(MI, access, 0);
MI->flat_insn->detail->x86.operands[1].access =
get_detail_op_access(MI, access, 1);
#endif
}

Expand Down Expand Up @@ -904,8 +926,9 @@ static void printPCRelImm(MCInst *MI, unsigned OpNo, SStream *O)
&MI->flat_insn->detail->x86.eflags);
MI->flat_insn->detail->x86
.operands[MI->flat_insn->detail->x86.op_count]
.access =
access[MI->flat_insn->detail->x86.op_count];
.access = get_detail_op_access(
MI, access,
MI->flat_insn->detail->x86.op_count);
#endif

MI->flat_insn->detail->x86.op_count++;
Expand Down Expand Up @@ -949,6 +972,10 @@ static void printOperand(MCInst *MI, unsigned OpNo, SStream *O)
.size =
MI->csh->regsize_map[X86_register_map(
reg)];
if (OpNo == MI->x86_writemask_op)
MI->x86_writemask_detail_op =
MI->flat_insn->detail->x86
.op_count;

#ifndef CAPSTONE_DIET
get_op_access(
Expand All @@ -957,9 +984,9 @@ static void printOperand(MCInst *MI, unsigned OpNo, SStream *O)
MI->flat_insn->detail->x86
.operands[MI->flat_insn->detail->x86
.op_count]
.access =
access[MI->flat_insn->detail->x86
.op_count];
.access = get_detail_op_access(
MI, access,
MI->flat_insn->detail->x86.op_count);
#endif

MI->flat_insn->detail->x86.op_count++;
Expand Down Expand Up @@ -1096,9 +1123,9 @@ static void printOperand(MCInst *MI, unsigned OpNo, SStream *O)
MI->flat_insn->detail->x86
.operands[MI->flat_insn->detail->x86
.op_count]
.access =
access[MI->flat_insn->detail->x86
.op_count];
.access = get_detail_op_access(
MI, access,
MI->flat_insn->detail->x86.op_count);
#endif

MI->flat_insn->detail->x86.op_count++;
Expand Down Expand Up @@ -1153,7 +1180,8 @@ static void printMemReference(MCInst *MI, unsigned Op, SStream *O)
&MI->flat_insn->detail->x86.eflags);
MI->flat_insn->detail->x86
.operands[MI->flat_insn->detail->x86.op_count]
.access = access[MI->flat_insn->detail->x86.op_count];
.access = get_detail_op_access(
MI, access, MI->flat_insn->detail->x86.op_count);
#endif
}

Expand Down
Loading
Loading