Skip to content

Commit

Permalink
x86: avoid duplicating registers returned by cs_regs_access(). also a…
Browse files Browse the repository at this point in the history
…dd *CX registers to regs_read[], regs_write[] for REP* instructions
  • Loading branch information
aquynh committed Apr 2, 2015
1 parent 9239967 commit 58eb073
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 29 deletions.
35 changes: 30 additions & 5 deletions arch/X86/X86Mapping.c
Original file line number Diff line number Diff line change
Expand Up @@ -2799,6 +2799,28 @@ static bool valid_repe(cs_struct *h, unsigned int opcode)
// not found
return false;
}

// add *CX register to regs_read[] & regs_write[]
static void add_cx(MCInst *MI)
{
if (MI->csh->detail) {
x86_reg cx;

if (MI->csh->mode & CS_MODE_16)
cx = X86_REG_CX;
else if (MI->csh->mode & CS_MODE_32)
cx = X86_REG_ECX;
else // 64-bit
cx = X86_REG_RCX;

MI->flat_insn->detail->regs_read[MI->flat_insn->detail->regs_read_count] = cx;
MI->flat_insn->detail->regs_read_count++;

MI->flat_insn->detail->regs_write[MI->flat_insn->detail->regs_write_count] = cx;
MI->flat_insn->detail->regs_write_count++;
}
}

// return true if we patch the mnemonic
bool X86_lockrep(MCInst *MI, SStream *O)
{
Expand All @@ -2818,6 +2840,7 @@ bool X86_lockrep(MCInst *MI, SStream *O)
#ifndef CAPSTONE_DIET // only care about memonic in standard (non-diet) mode
if (valid_repne(MI->csh, opcode)) {
SStream_concat(O, "repne|");
add_cx(MI);
} else {
// invalid prefix
MI->x86_prefix[0] = 0;
Expand Down Expand Up @@ -2849,8 +2872,10 @@ bool X86_lockrep(MCInst *MI, SStream *O)
#ifndef CAPSTONE_DIET // only care about memonic in standard (non-diet) mode
if (valid_rep(MI->csh, opcode)) {
SStream_concat(O, "rep|");
add_cx(MI);
} else if (valid_repe(MI->csh, opcode)) {
SStream_concat(O, "repe|");
add_cx(MI);
} else {
// invalid prefix
MI->x86_prefix[0] = 0;
Expand Down Expand Up @@ -3022,26 +3047,26 @@ void X86_reg_access(const cs_insn *insn,
cs_x86_op *op = &(x86->operands[i]);
switch((int)op->type) {
case X86_OP_REG:
if (op->access & CS_AC_READ) {
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) {
if ((op->access & CS_AC_WRITE) && !arr_exist(regs_write, write_count, op->reg)) {
regs_write[write_count] = op->reg;
write_count++;
}
break;
case X86_OP_MEM:
// registers appeared in memory references always being read
if (op->mem.segment != X86_REG_INVALID) {
if ((op->mem.segment != X86_REG_INVALID)) {
regs_read[read_count] = op->mem.segment;
read_count++;
}
if (op->mem.base != X86_REG_INVALID) {
if ((op->mem.base != X86_REG_INVALID) && !arr_exist(regs_read, read_count, op->mem.base)) {
regs_read[read_count] = op->mem.base;
read_count++;
}
if (op->mem.index != X86_REG_INVALID) {
if ((op->mem.index != X86_REG_INVALID) && !arr_exist(regs_read, read_count, op->mem.index)) {
regs_read[read_count] = op->mem.index;
read_count++;
}
Expand Down
24 changes: 0 additions & 24 deletions cs.c
Original file line number Diff line number Diff line change
Expand Up @@ -774,30 +774,6 @@ const char *cs_group_name(csh ud, unsigned int group)
return handle->group_name(ud, group);
}

static bool arr_exist8(unsigned char *arr, unsigned char max, unsigned int id)
{
int i;

for (i = 0; i < max; i++) {
if (arr[i] == id)
return true;
}

return false;
}

static bool arr_exist(uint16_t *arr, unsigned char max, unsigned int id)
{
int i;

for (i = 0; i < max; i++) {
if (arr[i] == id)
return true;
}

return false;
}

CAPSTONE_EXPORT
bool cs_insn_group(csh ud, const cs_insn *insn, unsigned int group_id)
{
Expand Down
25 changes: 25 additions & 0 deletions utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -93,3 +93,28 @@ int cs_snprintf(char *buffer, size_t size, const char *fmt, ...)

return ret;
}

bool arr_exist8(unsigned char *arr, unsigned char max, unsigned int id)
{
int i;

for (i = 0; i < max; i++) {
if (arr[i] == id)
return true;
}

return false;
}

bool arr_exist(uint16_t *arr, unsigned char max, unsigned int id)
{
int i;

for (i = 0; i < max; i++) {
if (arr[i] == id)
return true;
}

return false;
}

5 changes: 5 additions & 0 deletions utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,5 +54,10 @@ int cs_snprintf(char *buffer, size_t size, const char *fmt, ...);

#define CS_AC_IGNORE (1 << 7)

// check if an id is existent in an array
bool arr_exist8(unsigned char *arr, unsigned char max, unsigned int id);

bool arr_exist(uint16_t *arr, unsigned char max, unsigned int id);

#endif

0 comments on commit 58eb073

Please sign in to comment.