mirror of
https://github.com/capstone-engine/capstone.git
synced 2024-11-23 13:39:46 +00:00
x86: fix SHR, SHL, SAR insn when second op is 1 (Intel syntax). reported by Edgar Barbosa
This commit is contained in:
parent
b8394a47d7
commit
0b6f1bd544
@ -165,8 +165,9 @@ static void printMemOffs64(MCInst *MI, unsigned OpNo, SStream *O)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// get the first op from the asm buffer
|
// get the first op from the asm buffer
|
||||||
|
// return False if there is no op. On True, put fist op in @firstop
|
||||||
// NOTE: make sure firstop is big enough to contain the resulted string
|
// NOTE: make sure firstop is big enough to contain the resulted string
|
||||||
static void get_first_op(char *buffer, char *firstop)
|
static bool get_first_op(char *buffer, char *firstop)
|
||||||
{
|
{
|
||||||
char *tab = strchr(buffer, '\t');
|
char *tab = strchr(buffer, '\t');
|
||||||
if (tab) {
|
if (tab) {
|
||||||
@ -176,8 +177,28 @@ static void get_first_op(char *buffer, char *firstop)
|
|||||||
firstop[comma - tab - 1] = '\0';
|
firstop[comma - tab - 1] = '\0';
|
||||||
} else
|
} else
|
||||||
strcpy(firstop, tab + 1);
|
strcpy(firstop, tab + 1);
|
||||||
|
|
||||||
|
return true;
|
||||||
} else // no op
|
} else // no op
|
||||||
firstop[0] = '\0';
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// hacky: get mnem string from buffer if this insn has only 1 operand
|
||||||
|
// return mnem if True, or False if above condition was not satisfied
|
||||||
|
// NOTE: make sure mnem is big enough to contain the resulted string
|
||||||
|
static bool get_mnem1(char *buffer, char *mnem)
|
||||||
|
{
|
||||||
|
if (strchr(buffer, ','))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
char *tab = strchr(buffer, '\t');
|
||||||
|
if (!tab)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
memcpy(mnem, buffer, tab - buffer);
|
||||||
|
mnem[tab - buffer + 1] = '\0';
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool printAliasInstr(MCInst *MI, SStream *OS);
|
static bool printAliasInstr(MCInst *MI, SStream *OS);
|
||||||
@ -202,23 +223,37 @@ void X86_Intel_printInst(MCInst *MI, SStream *O, void *Info)
|
|||||||
} else
|
} else
|
||||||
printInstruction(MI, O);
|
printInstruction(MI, O);
|
||||||
|
|
||||||
// first op can be embedded in the asm by llvm.
|
// currently LLVM presents "shr reg, 1" as "shr reg"
|
||||||
// so we have to handle that case to not miss the first op.
|
// until that is fixed, we need this hack
|
||||||
char firstop[128];
|
char tmp[128];
|
||||||
get_first_op(O->buffer, firstop);
|
if (get_mnem1(O->buffer, tmp)) {
|
||||||
char *acc_regs[] = {"rax", "eax", "ax", "al", NULL};
|
char *mnems[] = {"shr", "shl", "sar", NULL};
|
||||||
if (firstop[0] != 0 && str_in_list(acc_regs, firstop)) {
|
if (str_in_list(mnems, tmp)) {
|
||||||
// firstop is a register
|
// this insn needs to have op "1"
|
||||||
if (MI->pub_insn.x86.operands[0].type != X86_OP_INVALID &&
|
strcat(O->buffer, ", 1");
|
||||||
MI->pub_insn.x86.operands[0].type != X86_OP_REG) {
|
MI->pub_insn.x86.operands[1].type = X86_OP_IMM;
|
||||||
int i;
|
MI->pub_insn.x86.operands[1].imm = 1;
|
||||||
for (i = MI->pub_insn.x86.op_count; i > 0; i--) {
|
|
||||||
memcpy(&(MI->pub_insn.x86.operands[i]), &(MI->pub_insn.x86.operands[i - 1]),
|
|
||||||
sizeof(MI->pub_insn.x86.operands[0]));
|
|
||||||
}
|
|
||||||
MI->pub_insn.x86.operands[0].type = X86_OP_REG;
|
|
||||||
MI->pub_insn.x86.operands[0].reg = x86_map_regname(firstop);
|
|
||||||
MI->pub_insn.x86.op_count++;
|
MI->pub_insn.x86.op_count++;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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)) {
|
||||||
|
// 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) {
|
||||||
|
int i;
|
||||||
|
for (i = MI->pub_insn.x86.op_count; i > 0; i--) {
|
||||||
|
memcpy(&(MI->pub_insn.x86.operands[i]), &(MI->pub_insn.x86.operands[i - 1]),
|
||||||
|
sizeof(MI->pub_insn.x86.operands[0]));
|
||||||
|
}
|
||||||
|
MI->pub_insn.x86.operands[0].type = X86_OP_REG;
|
||||||
|
MI->pub_insn.x86.operands[0].reg = x86_map_regname(tmp);
|
||||||
|
MI->pub_insn.x86.op_count++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user