Skip to content

Commit

Permalink
Patch for sseMapTer decoding logic issue.
Browse files Browse the repository at this point in the history
  • Loading branch information
John Detter committed Jun 10, 2016
1 parent 84d23db commit eff25a2
Show file tree
Hide file tree
Showing 2 changed files with 112 additions and 33 deletions.
144 changes: 111 additions & 33 deletions common/src/arch-x86.C
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ enum {
SSE68, SSE69, SSE6A, SSE6B, SSE6C, SSE6D, SSE6E, SSE6F,
SSE70, SSE71, SSE72, SSE73, SSE74, SSE75, SSE76, SSE77,
SSE78, SSE79, SSE7A, SSE7B, SSE7C, SSE7D, SSE7E, SSE7F,
SSE90, SSE91, SSE93,
SSE90, SSE91, SSE92, SSE93,
SSE98, SSE99,
SSEB8, SSEBE,
SSEC2, SSEC4, SSEC5, SSEC6,
Expand All @@ -109,7 +109,7 @@ enum {
SSEVEX4A, SSEVEX4B,
SSEVEX73,
SSEVEX78,
SSEVEX90, SSEVEX91, SSEVEX93,
SSEVEX90, SSEVEX91, SSEVEX92, SSEVEX93,
SSEVEX98, SSEVEX99
};
/** END_DYNINST_TABLE_DEF*/
Expand Down Expand Up @@ -181,6 +181,7 @@ enum { /** AUTOGENERATED */
SSE7F_66,
SSE90_66, SSE90_NO,
SSE91_66, SSE91_NO,
SSE92_NO,
SSE93_66, SSE93_F2, SSE93_NO,
SSE98_66, SSE98_NO,
SSE99_66, SSE99_NO,
Expand Down Expand Up @@ -2181,7 +2182,7 @@ true, { Eb, Gb, Zz }, 0, s1RW2R },
{ e_arpl, t_done, 0, true, { Ew, Gw, Zz }, 0, s1R2R },
{ e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }, // PREFIX_SEG_OVR
{ e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }, // PREFIX_SEG_OVR
{ e_No_Entry, t_prefixedSSE, 2, false, { Zz, Zz, Zz }, 0, 0 }, /* operand size prefix (PREFIX_OPR_SZ)*/
{ e_No_Entry, t_ill, 2, false, { Zz, Zz, Zz }, 0, 0 }, /* operand size prefix (PREFIX_OPR_SZ) (depricated: prefixedSSE)*/
{ e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }, /* address size prefix (PREFIX_ADDR_SZ)*/
/* 68 */
{ e_push, t_done, 0, false, { Iz, eSP, Zz }, 0, s1R2RW },
Expand Down Expand Up @@ -2341,8 +2342,8 @@ true, { Eb, Gb, Zz }, 0, s1RW2R },
/* F0 */
{ e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }, // PREFIX_INSTR
{ e_int1, t_done, 0, false, { Zz, Zz, Zz }, 0, sNONE }, // undocumented
{ e_No_Entry, t_prefixedSSE, 3, false, { Zz, Zz, Zz }, 0, 0 },
{ e_No_Entry, t_prefixedSSE, 1, false, { Zz, Zz, Zz }, 0, 0 },
{ e_No_Entry, t_ill, 3, false, { Zz, Zz, Zz }, 0, 0 }, /* depricated: prefixedSSE */
{ e_No_Entry, t_ill, 1, false, { Zz, Zz, Zz }, 0, 0 }, /* depricated: prefixedSSE */
{ e_hlt, t_done, 0, false, { Zz, Zz, Zz }, PRVLGD, sNONE },
{ e_cmc, t_done, 0, false, { Zz, Zz, Zz }, 0, sNONE },
{ e_No_Entry, t_grp, Grp3a, true, { Zz, Zz, Zz }, 0, sNONE },
Expand Down Expand Up @@ -2531,7 +2532,7 @@ static ia32_entry twoByteMap[256] = {
/* 90 */
{ e_No_Entry, t_sse_vex_mult, SSEVEX90, false, { Zz, Zz, Zz }, 0, 0 },
{ e_No_Entry, t_sse_vex_mult, SSEVEX91, false, { Zz, Zz, Zz }, 0, 0 },
{ e_setb, t_done, 0, true, { Eb, Zz, Zz }, 0, s1W | (fCOND << FPOS) },
{ e_No_Entry, t_sse_vex_mult, SSEVEX92, false, { Zz, Zz, Zz }, 0, 0 },
{ e_No_Entry, t_sse_vex_mult, SSEVEX93, false, { Zz, Zz, Zz }, 0, 0 },
{ e_setz, t_done, 0, true, { Eb, Zz, Zz }, 0, s1W | (fCOND << FPOS) },
{ e_setnz, t_done, 0, true, { Eb, Zz, Zz }, 0, s1W | (fCOND << FPOS) },
Expand Down Expand Up @@ -3816,6 +3817,11 @@ static ia32_entry sseVexMult[][4] = {
{ e_No_Entry, t_sse, SSE91, false, { Zz, Zz, Zz }, 0, 0 },
{ e_No_Entry, t_sse, SSE91, false, { Zz, Zz, Zz }, 0, 0 },
{ e_No_Entry, t_sse, SSE91, false, { Zz, Zz, Zz }, 0, 0 }
}, { /* SSEVEX92 */
{ e_setb, t_done, 0, true, { Eb, Zz, Zz }, 0, s1W | (fCOND << FPOS) },
{ e_No_Entry, t_sse, SSE92, false, { Zz, Zz, Zz }, 0, 0 },
{ e_No_Entry, t_sse, SSE92, false, { Zz, Zz, Zz }, 0, 0 },
{ e_No_Entry, t_sse, SSE92, false, { Zz, Zz, Zz }, 0, 0 }
}, { /* SSEVEX93 */
{ e_setnb, t_done, 0, true, { Eb, Zz, Zz }, 0, s1W | (fCOND << FPOS) },
{ e_No_Entry, t_sse, SSE93, false, { Zz, Zz, Zz }, 0, 0 },
Expand Down Expand Up @@ -4282,6 +4288,12 @@ static ia32_entry sseMap[][4] = {
{ e_No_Entry, t_sse_mult, SSE91_66, false, { Zz, Zz, Zz }, 0, 0 },
{ e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }
},
{ /* SSE92 */
{ e_No_Entry, t_sse_mult, SSE92_NO, false, { Zz, Zz, Zz }, 0, 0 },
{ e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
{ e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
{ e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }
},
{ /* SSE93 */
{ e_No_Entry, t_sse_mult, SSE93_NO, false, { Zz, Zz, Zz }, 0, 0 },
{ e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
Expand Down Expand Up @@ -5659,7 +5671,7 @@ static ia32_entry sseMapTer[][3] =
}, { /* SSET22 */
{ e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
{ e_pinsrd_pinsrq, t_sse_ter_mult, SSET22_66, true, { Vdq, Ey, Ib }, 0, s1W2R3R },
{ e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
{ e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
}, { /* SSET23 */
{ e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
{ e_pinsrd_pinsrq, t_sse_ter_mult, SSET23_66, true, { Vdq, Ey, Ib }, 0, s1W2R3R },
Expand Down Expand Up @@ -5820,7 +5832,7 @@ ia32_entry sseMapMult[][3] =
{ /* SSE10_66 */
{ e_vmovupd, t_done, 0, true, { Vps, Hps, Wps }, 0, s1W2R3R },
{ e_vmovupd, t_done, 0, true, { Vps, Hps, Wps }, 0, s1W2R3R },
{ e_vmovupd, t_done, 0, true, { Vps, Hps, Wps }, 0, s1W2R3R },
{ e_vmovupd, t_done, 0, true, { Vps, Hps, Wps }, 0, s1W2R3R }
}, { /* SSE10_F2 */
{ e_vmovsd, t_done, 0, true, { Vps, Hps, Wps }, 0, s1W2R3R },
{ e_vmovsd, t_done, 0, true, { Vps, Hps, Wps }, 0, s1W2R3R },
Expand Down Expand Up @@ -6068,7 +6080,7 @@ ia32_entry sseMapMult[][3] =
}, { /* SSE59_66 */
{ e_vmulpd, t_done, 0, true, { Vps, Hps, Wps }, 0, s1W2R3R },
{ e_vmulpd, t_done, 0, true, { Vps, Hps, Wps }, 0, s1W2R3R },
{ e_vmulpd, t_done, 0, true, { Vps, Hps, Wps }, 0, s1W2R3R },
{ e_vmulpd, t_done, 0, true, { Vps, Hps, Wps }, 0, s1W2R3R }
}, { /* SSE59_F2 */
{ e_vmulsd, t_done, 0, true, { Vps, Hps, Wps }, 0, s1W2R3R },
{ e_vmulsd, t_done, 0, true, { Vps, Hps, Wps }, 0, s1W2R3R },
Expand Down Expand Up @@ -6357,6 +6369,10 @@ ia32_entry sseMapMult[][3] =
{ e_kmovw, t_done, 0, true, { Vps, Hps, Wps }, 0, s1W2R3R },
{ e_kmovq, t_done, 0, true, { Vps, Hps, Wps }, 0, s1W2R3R },
{ e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }
}, { /* SSE92_NO */
{ e_kmovw, t_done, 0, true, { Vps, Ev, Zz }, 0, s1W2R },
{ e_kmovq, t_done, 0, true, { Vps, Ev, Zz }, 0, s1W2R },
{ e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }
}, { /* SSE93_66 */
{ e_kmovb, t_done, 0, true, { Vps, Hps, Wps }, 0, s1W2R3R },
{ e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
Expand Down Expand Up @@ -8188,11 +8204,6 @@ ia32_instruction& ia32_decode(unsigned int capa, const unsigned char* addr, ia32
}
#endif

if((pref.getOpcodePrefix()) && pref.getCount())
{
idx = pref.getOpcodePrefix();
}

if(instruct.loc)
{
instruct.loc->num_prefixes = pref.getCount();
Expand Down Expand Up @@ -8265,14 +8276,10 @@ ia32_instruction& ia32_decode(unsigned int capa, const unsigned char* addr, ia32
/* Non VEX instruction */
table = t_oneB;

/* Adjust the idx if we haven't already */
if(idx == 0)
{
/* consume opcode */
idx = addr[0];
instruct.size += 1;
addr += 1;
}
/* Adjust the idx */
idx = addr[0];
instruct.size += 1;
addr += 1;

gotit = &oneByteMap[idx];
nxtab = gotit->otable;
Expand Down Expand Up @@ -8318,6 +8325,7 @@ ia32_instruction& ia32_decode(unsigned int capa, const unsigned char* addr, ia32
condbits = idx & 0x0F;
break;
case t_prefixedSSE:
assert(!"Depricated table!!\n");
if(addr[0] != 0x0F)
{
// all valid SSE insns will have 0x0F as their first byte after prefix
Expand All @@ -8335,6 +8343,23 @@ ia32_instruction& ia32_decode(unsigned int capa, const unsigned char* addr, ia32
addr += 2;
break;
case t_sse:
/* Decode the sse prefix for this type */
switch(pref.getOpcodePrefix())
{
case 0x00:
sseidx = 0;
break;
case 0xf3:
sseidx = 1;
break;
case 0x66:
sseidx = 2;
break;
case 0xF2:
sseidx = 3;
break;
}

idx = gotit->tabidx;
gotit = &sseMap[idx][sseidx];
nxtab = gotit->otable;
Expand All @@ -8351,6 +8376,8 @@ ia32_instruction& ia32_decode(unsigned int capa, const unsigned char* addr, ia32
nxtab = t_done;
break;
case t_sse_mult:
if(!pref.vex_present)
assert(!"Entered VEX SSE MULT table when no VEX present.");
idx = gotit->tabidx;
gotit = &sseMapMult[idx][pref.vex_sse_mult];
nxtab = gotit->otable;
Expand All @@ -8363,6 +8390,23 @@ ia32_instruction& ia32_decode(unsigned int capa, const unsigned char* addr, ia32

break;
case t_sse_bis:
/* Decode the sse prefix for this type */
switch(pref.getOpcodePrefix())
{
case 0x00:
sseidx = 0;
break;
case 0xf3:
sseidx = 1;
break;
case 0x66:
sseidx = 2;
break;
case 0xF2:
sseidx = 3;
break;
}

idx = gotit->tabidx;
gotit = &sseMapBis[idx][sseidx];
nxtab = gotit->otable;
Expand All @@ -8376,6 +8420,8 @@ ia32_instruction& ia32_decode(unsigned int capa, const unsigned char* addr, ia32
nxtab = t_done;
break;
case t_sse_bis_mult:
if(!pref.vex_present)
assert(!"Entered VEX BIS MULT table when no VEX present.");
idx = gotit->tabidx;
gotit = &sseMapBisMult[idx][pref.vex_sse_mult];
nxtab = gotit->otable;
Expand All @@ -8385,6 +8431,20 @@ ia32_instruction& ia32_decode(unsigned int capa, const unsigned char* addr, ia32
#endif
break;
case t_sse_ter:
/* Decode the sse prefix for this type */
switch(pref.getOpcodePrefix())
{
case 0x00:
sseidx = 0;
break;
case 0x66:
sseidx = 1;
break;
case 0xF2:
sseidx = 2;
break;
}

idx = gotit->tabidx;
gotit = &sseMapTer[idx][sseidx];
nxtab = gotit->otable;
Expand All @@ -8399,6 +8459,9 @@ ia32_instruction& ia32_decode(unsigned int capa, const unsigned char* addr, ia32
break;

case t_sse_ter_mult:
if(!pref.vex_present)
assert(!"Entered VEX TER MULT table when no VEX present.");

idx = gotit->tabidx;
gotit = &sseMapTerMult[idx][pref.vex_sse_mult];
nxtab = gotit->otable;
Expand Down Expand Up @@ -9983,12 +10046,12 @@ bool ia32_decode_rex(const unsigned char* addr, ia32_prefixes& pref,
{
if (REX_ISREX(addr[0]))
{

// it is an error to have legacy prefixes after a REX prefix
// in particular, ia32_decode will get confused if a prefix
// that could be used as an SSE opcode extension follows our
// REX
// We also must ignore all but the last REX prefix.
/**
* it is an error to have legacy prefixes after a REX prefix
* in particular, ia32_decode will get confused if a prefix
* that could be used as an SSE opcode extension follows our
* REX
*/

switch(addr[1])
{
Expand All @@ -10005,13 +10068,12 @@ bool ia32_decode_rex(const unsigned char* addr, ia32_prefixes& pref,
case PREFIX_SZADDR:
return false;
}


/* We also must ignore all but the last REX prefix. */
if(REX_ISREX(addr[1]))
return false;

++pref.count;
pref.prfx[4] = addr[0];

/* Set the locations for this REX prefix. */
if (loc)
{
loc->rex_byte = addr[0];
Expand All @@ -10021,7 +10083,23 @@ bool ia32_decode_rex(const unsigned char* addr, ia32_prefixes& pref,
loc->rex_b = REX_B(addr[0]);
loc->rex_position = pref.count - 1;
}


/**
* VEX Prefixes are valid after the REX prefix because VEX
* prefixes must be the last prefix before the opcode.
*/
switch(addr[1])
{
case PREFIX_VEX2:
case PREFIX_VEX3:
case PREFIX_EVEX:
return false;
default: break;
}

/* We should be done parsing all prefixes if we get here. */
++pref.count;
pref.prfx[4] = addr[0];
}

return true;
Expand Down
1 change: 1 addition & 0 deletions instructionAPI/src/Instruction.C
Original file line number Diff line number Diff line change
Expand Up @@ -446,6 +446,7 @@ memAccessors.begin()));
}

std::string retVal = m_InsnOp->format();

retVal += " ";
std::list<Operand>::const_iterator curOperand;
for(curOperand = m_Operands.begin();
Expand Down

0 comments on commit eff25a2

Please sign in to comment.