x86: handle tricky instructions related to MULPD at http://habrahabr.ru/company/intel/blog/200658/
This commit is contained in:
parent
5c7f0c3e0d
commit
45c77aeadd
1
MCInst.h
1
MCInst.h
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue