Skip to content

Commit

Permalink
x86: handle tricky instructions related to MULPD at http://habrahabr.…
Browse files Browse the repository at this point in the history
  • Loading branch information
aquynh committed May 7, 2014
1 parent 5c7f0c3 commit 45c77ae
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 37 deletions.
1 change: 1 addition & 0 deletions MCInst.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
4 changes: 4 additions & 0 deletions arch/X86/X86Disassembler.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
21 changes: 2 additions & 19 deletions arch/X86/X86GenAsmWriter.inc
Original file line number Diff line number Diff line change
Expand Up @@ -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


Expand Down
20 changes: 2 additions & 18 deletions arch/X86/X86GenAsmWriter1.inc
Original file line number Diff line number Diff line change
Expand Up @@ -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


Expand Down
41 changes: 41 additions & 0 deletions arch/X86/X86Mapping.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
6 changes: 6 additions & 0 deletions arch/X86/X86Mapping.h
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit 45c77ae

Please sign in to comment.