x86: handle tricky instructions related to MULPD at http://habrahabr.ru/company/intel/blog/200658/

This commit is contained in:
Nguyen Anh Quynh 2014-05-07 11:39:41 +08:00
parent 5c7f0c3e0d
commit 45c77aeadd
6 changed files with 56 additions and 37 deletions

View File

@ -150,6 +150,7 @@ struct MCInst {
// A prefix byte gets value 0 when irrelevant.
// This is copied from cs_x86 struct
uint8_t x86_prefix[5];
bool x86_lock_rep; // does this X86 insn contain LOCK/REP prefix?
};
void MCInst_Init(MCInst *inst);

View File

@ -800,6 +800,10 @@ bool X86_getInstruction(csh ud, const uint8_t *code, size_t code_len,
}
}
if (insn.prefixPresent[0xf0] || insn.prefixPresent[0xf2] ||
insn.prefixPresent[0xf3])
instr->x86_lock_rep = true;
// save immediate size to print immediate properly
instr->x86_imm_size = insn.immediateSize;
}

View File

@ -12498,25 +12498,8 @@ static void printInstruction(MCInst *MI, SStream *O, MCRegisterInfo *MRI)
uint64_t Bits = (Bits2 << 32) | Bits1;
// assert(Bits != 0 && "Cannot print this instruction.");
#ifndef CAPSTONE_DIET
int i;
for(i = 0; i < ARR_SIZE(MI->x86_prefix); i++) {
switch(MI->x86_prefix[i]) {
default:
break;
case 0xf0:
SStream_concat(O, "lock|");
break;
case 0xf2:
SStream_concat(O, "repne|");
break;
case 0xf3:
SStream_concat(O, "rep|");
break;
}
}
SStream_concat(O, "%s", AsmStrs+(Bits & 16383)-1);
if (!X86_lockrep(MI, O))
SStream_concat(O, "%s", AsmStrs+(Bits & 16383)-1);
#endif

View File

@ -12202,24 +12202,8 @@ static void printInstruction(MCInst *MI, SStream *O, MCRegisterInfo *MRI)
uint64_t Bits = (Bits2 << 32) | Bits1;
// assert(Bits != 0 && "Cannot print this instruction.");
#ifndef CAPSTONE_DIET
int i;
for(i = 0; i < ARR_SIZE(MI->x86_prefix); i++) {
switch(MI->x86_prefix[i]) {
default:
break;
case 0xf0:
SStream_concat(O, "lock|");
break;
case 0xf2:
SStream_concat(O, "repne|");
break;
case 0xf3:
SStream_concat(O, "rep|");
break;
}
}
SStream_concat(O, "%s", AsmStrs+(Bits & 16383)-1);
if (!X86_lockrep(MI, O))
SStream_concat(O, "%s", AsmStrs+(Bits & 16383)-1);
#endif

View File

@ -41706,3 +41706,44 @@ x86_reg X86_insn_reg(unsigned int id)
return 0;
}
#ifndef CAPSTONE_DIET
// return true if we patch the mnemonic
bool X86_lockrep(MCInst *MI, SStream *O)
{
int i;
if (MI->x86_lock_rep) {
for(i = 0; i < ARR_SIZE(MI->x86_prefix); i++) {
switch(MI->x86_prefix[i]) {
default:
break;
case 0xf0:
SStream_concat(O, "lock|");
break;
case 0xf2:
if (MI->Opcode == X86_MULPDrr) {
MI->Opcode = X86_MULSDrr;
SStream_concat(O, "mulsd\t");
MI->x86_prefix[i] = 0;
// notify that we already patched mnemonic
return true;
} else
SStream_concat(O, "repne|");
break;
case 0xf3:
if (MI->Opcode == X86_MULPDrr) {
MI->Opcode = X86_MULSSrr;
SStream_concat(O, "mulss\t");
MI->x86_prefix[i] = 0;
// notify that we already patched mnemonic
return true;
} else
SStream_concat(O, "rep|");
break;
}
}
}
return false;
}
#endif

View File

@ -39,4 +39,10 @@ x86_reg X86_insn_reg(unsigned int id);
extern uint64_t arch_masks[9];
#ifndef CAPSTONE_DIET
// handle LOCK/REP/REPNE prefixes
// return True if we patch mnemonic, like in MULPD case
bool X86_lockrep(MCInst *MI, SStream *O);
#endif
#endif