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.
|
// A prefix byte gets value 0 when irrelevant.
|
||||||
// This is copied from cs_x86 struct
|
// This is copied from cs_x86 struct
|
||||||
uint8_t x86_prefix[5];
|
uint8_t x86_prefix[5];
|
||||||
|
bool x86_lock_rep; // does this X86 insn contain LOCK/REP prefix?
|
||||||
};
|
};
|
||||||
|
|
||||||
void MCInst_Init(MCInst *inst);
|
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
|
// save immediate size to print immediate properly
|
||||||
instr->x86_imm_size = insn.immediateSize;
|
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;
|
uint64_t Bits = (Bits2 << 32) | Bits1;
|
||||||
// assert(Bits != 0 && "Cannot print this instruction.");
|
// assert(Bits != 0 && "Cannot print this instruction.");
|
||||||
#ifndef CAPSTONE_DIET
|
#ifndef CAPSTONE_DIET
|
||||||
int i;
|
if (!X86_lockrep(MI, O))
|
||||||
|
SStream_concat(O, "%s", AsmStrs+(Bits & 16383)-1);
|
||||||
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);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -12202,24 +12202,8 @@ static void printInstruction(MCInst *MI, SStream *O, MCRegisterInfo *MRI)
|
||||||
uint64_t Bits = (Bits2 << 32) | Bits1;
|
uint64_t Bits = (Bits2 << 32) | Bits1;
|
||||||
// assert(Bits != 0 && "Cannot print this instruction.");
|
// assert(Bits != 0 && "Cannot print this instruction.");
|
||||||
#ifndef CAPSTONE_DIET
|
#ifndef CAPSTONE_DIET
|
||||||
int i;
|
if (!X86_lockrep(MI, O))
|
||||||
for(i = 0; i < ARR_SIZE(MI->x86_prefix); i++) {
|
SStream_concat(O, "%s", AsmStrs+(Bits & 16383)-1);
|
||||||
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);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -41706,3 +41706,44 @@ x86_reg X86_insn_reg(unsigned int id)
|
||||||
return 0;
|
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];
|
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
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue