Skip to content

Commit

Permalink
x86: calculate op_size properly in special cases regarding rax, eax, …
Browse files Browse the repository at this point in the history
…ax, al registers
  • Loading branch information
aquynh committed Dec 13, 2013
1 parent 94990c9 commit bed9091
Show file tree
Hide file tree
Showing 5 changed files with 21 additions and 12 deletions.
7 changes: 5 additions & 2 deletions arch/X86/X86ATTInstPrinter.c
Original file line number Diff line number Diff line change
Expand Up @@ -446,8 +446,11 @@ void X86_ATT_printInst(MCInst *MI, SStream *OS, void *info)
// so we have to handle that case to not miss the first op.
char lastop[32];
get_last_op(OS->buffer, lastop);
char *acc_regs[] = {"rax", "eax", "ax", "al", NULL};
if (lastop[0] == '%' && str_in_list(acc_regs, lastop+1)) {
char *acc_regs[] = {"al", "ax", "eax", "rax", NULL};
int post;
if (lastop[0] == '%' && ((post = str_in_list(acc_regs, lastop+1)) != -1)) {
// set operand size following register size
MI->pub_insn.x86.op_size = 1 << post;
// this is one of the registers AL, AX, EAX, RAX
// canonicalize the register name first
//int i;
Expand Down
2 changes: 0 additions & 2 deletions arch/X86/X86DisassemblerDecoder.c
Original file line number Diff line number Diff line change
Expand Up @@ -1676,8 +1676,6 @@ static int readOperands(struct InternalInstruction* insn)
int hasVVVV, needVVVV;
int sawRegImm = 0;

//printf(">>> readOperands()\n");

/* If non-zero vvvv specified, need to make sure one of the operands
uses it. */
hasVVVV = !readVVVV(insn);
Expand Down
7 changes: 5 additions & 2 deletions arch/X86/X86IntelInstPrinter.c
Original file line number Diff line number Diff line change
Expand Up @@ -231,8 +231,11 @@ void X86_Intel_printInst(MCInst *MI, SStream *O, void *Info)

char tmp[64];
if (get_first_op(O->buffer, tmp)) {
char *acc_regs[] = {"rax", "eax", "ax", "al", NULL};
if (tmp[0] != 0 && str_in_list(acc_regs, tmp)) {
int post;
char *acc_regs[] = {"al", "ax", "eax", "rax", NULL};
if (tmp[0] != 0 && ((post = str_in_list(acc_regs, tmp)) != -1)) {
// set operand size following register size
MI->pub_insn.x86.op_size = 1 << post;
// tmp is a register
if (MI->pub_insn.x86.operands[0].type != X86_OP_INVALID &&
MI->pub_insn.x86.operands[0].type != X86_OP_REG) {
Expand Down
13 changes: 8 additions & 5 deletions utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,19 @@

#include "utils.h"

// check to see if a string exists in a list of string ...
bool str_in_list(char **list, char *s)
// return the position of a string in a list of strings
// or -1 if given string is not in the list
int str_in_list(char **list, char *s)
{
char **l;

for(l = list; *l; l++)
int c = 0;
for(l = list; *l; c++, l++) {
if (!strcasecmp(*l, s))
return true;
return c;
}

return false;
return -1;
}

// binary searching
Expand Down
4 changes: 3 additions & 1 deletion utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ typedef struct insn_map {
bool indirect_branch; // indirect branch instruction?
} insn_map;

bool str_in_list(char **list, char *s);
// return the position of a string in a list of strings
// or -1 if given string is not in the list
int str_in_list(char **list, char *s);

// binary searching in @m, given its size in @max, and @id
int insn_find(insn_map *m, unsigned int max, unsigned int id);
Expand Down

0 comments on commit bed9091

Please sign in to comment.