Skip to content

Commit

Permalink
kmask memory addressing mode now properly parses modr/m byte.
Browse files Browse the repository at this point in the history
  • Loading branch information
John Detter committed Jun 10, 2016
1 parent 1ba51dd commit 368d2da
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 77 deletions.
2 changes: 2 additions & 0 deletions common/h/entryIDs.h
Original file line number Diff line number Diff line change
Expand Up @@ -666,6 +666,8 @@ enum entryID {
e_vfixupimmps,
e_vfixupimmsd,
e_vfixupimmss,
e_vfmaddpd,
e_vfmaddps,
e_vfmadd132pd,
e_vfmadd132ps,
e_vfmadd132sd,
Expand Down
108 changes: 64 additions & 44 deletions common/src/arch-x86.C
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,7 @@ SSET00 = 0, SSET01, SSET02, SSET03, SSET04, SSET05, SSET06,
SSET4A, SSET4B, SSET4C,
SSET50, SSET51, SSET54, SSET55, SSET56, SSET57,
SSET60, SSET61, SSET62, SSET63, SSET66, SSET67,
SSET69,
SSETF0
};
/** END_DYNINST_TABLE_DEF */
Expand Down Expand Up @@ -479,6 +480,7 @@ enum { /** AUTOGENERATED */
SSET57_66,
SSET66_66,
SSET67_66,
SSET69_66,
SSETF0_F2
};
/** END_DYNINST_TABLE_DEF */
Expand Down Expand Up @@ -522,11 +524,11 @@ VEXW00 = 0, VEXW01, VEXW02, VEXW03, VEXW04, VEXW05, VEXW06, VEXW07,
VEXW78, VEXW79, VEXW7A, VEXW7B, VEXW7C, VEXW7D, VEXW7E, VEXW7F,
VEXW80, VEXW81, VEXW82, VEXW83, VEXW84, VEXW85, VEXW86, VEXW87,
VEXW88, VEXW89, VEXW8A, VEXW8B, VEXW8C, VEXW8D, VEXW8E, VEXW8F,
VEXW90, VEXW91, VEXW92, VEXW93, VEXW94
VEXW90, VEXW91, VEXW92, VEXW93, VEXW94, VEXW95, VEXW96
};
/** END_DYNINST_TABLE_DEF */

#define VEXW_MAX VEXW94
#define VEXW_MAX VEXW96

/* SIMD op conversion table */
static char vex3_simdop_convert[3][4] = {
Expand Down Expand Up @@ -621,7 +623,7 @@ static char vex3_simdop_convert[3][4] = {
#define Ws { am_W, op_s }
#define Wsd { am_W, op_sd }
#define Wss { am_W, op_ss }
#define WK { am_WK, op_b }
#define WK { am_WK, op_ps }
#define Xb { am_X, op_b }
#define Xv { am_X, op_v }
#define Yb { am_Y, op_b }
Expand Down Expand Up @@ -1397,6 +1399,8 @@ COMMON_EXPORT dyn_hash_map<entryID, std::string> entryNames_IAPI = map_list_of
(e_vfixupimmps, "vfixupimmps")
(e_vfixupimmsd, "vfixupimmsd")
(e_vfixupimmss, "vfixupimmss")
(e_vfmaddpd, "vfmaddpd")
(e_vfmaddps, "vfmaddps")
(e_vfmadd132pd, "vfmadd132pd")
(e_vfmadd132ps, "vfmadd132ps")
(e_vfmadd132sd, "vfmadd132sd")
Expand Down Expand Up @@ -3076,7 +3080,7 @@ static ia32_entry threeByteMap2[256] = {
{ e_No_Entry, t_sse_ter, SSET67, true, { Zz, Zz, Zz }, 0, 0 },
/* 68 */
{ 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_sse_ter, SSET69, 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 },
Expand Down Expand Up @@ -3799,9 +3803,9 @@ static ia32_entry sseVexMult[][4] = {
{ e_No_Entry, t_sse, SSE4B, false, { Zz, Zz, Zz }, 0, 0 },
}, { /* SSEVEX73 */
{ e_No_Entry, t_grp, Grp14, false, { Zz, Zz, Zz }, 0, 0 },
{ e_No_Entry, t_sse_mult, SSE73_66, false, { Zz, Zz, Zz }, 0, 0 },
{ e_No_Entry, t_sse_mult, SSE73_66, false, { Zz, Zz, Zz }, 0, 0 },
{ e_No_Entry, t_sse_mult, SSE73_66, false, { Zz, Zz, Zz }, 0, 0 },
{ e_No_Entry, t_sse, SSE73, false, { Zz, Zz, Zz }, 0, 0 },
{ e_No_Entry, t_sse, SSE73, false, { Zz, Zz, Zz }, 0, 0 },
{ e_No_Entry, t_sse, SSE73, false, { Zz, Zz, Zz }, 0, 0 },
}, { /* SSEVEX78 */
{ e_No_Entry, t_grp, Grp17, false, { Zz, Zz, Zz }, 0, 0 },
{ e_No_Entry, t_sse_mult, SSE78_66, false, { Zz, Zz, Zz }, 0, 0 },
Expand Down Expand Up @@ -5614,7 +5618,7 @@ static ia32_entry sseMapTer[][3] =
{ e_pblendw, t_done, 0, true, { Vdq, Wdq, Ib }, 0, s1RW2R3R },
}, { /* SSET0F */
{ e_palignr, t_done, 0, true, { Pq, Qq, Ib }, 0, s1RW2R3R },
{ e_No_Entry, t_sse_ter_mult, SSET0F_66, false, { Zz, Zz, Zz }, 0, 0 },
{ e_palignr, t_sse_ter_mult, SSET0F_66, true, { Pq, Qq, Ib }, 0, s1RW2R3R },
{ e_palignr, t_done, 0, true, { Vdq, Wdq, Ib }, 0, s1RW2R3R },
}, { /* SSET14 */
{ e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
Expand Down Expand Up @@ -5804,6 +5808,10 @@ static ia32_entry sseMapTer[][3] =
{ e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
{ e_No_Entry, t_sse_ter_mult, SSET67_66, false, { Zz, Zz, Zz }, 0, 0 },
{ e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }
}, { /* SSET69 */
{ e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
{ e_No_Entry, t_sse_ter_mult, SSET69_66, false, { Zz, Zz, Zz }, 0, 0 },
{ e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }
}, { /* SSETF0 */
{ e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
{ e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
Expand Down Expand Up @@ -6274,8 +6282,8 @@ ia32_entry sseMapMult[][3] =
{ e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
{ e_No_Entry, t_vexw, VEXW77, false, { Zz, Zz, Zz }, 0, 0 }
}, { /* SSE73_66 */
/**/{ e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }, // COLLISION HERE
{ e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
{ e_vpsrlq, t_done, 0, true, { Vps, Wps, Ib }, 0, s1W2R3R },
{ e_No_Entry, t_vexw, VEXW7C, false, { Zz, Zz, Zz }, 0, 0 },
{ e_No_Entry, t_vexw, VEXW7C, false, { Zz, Zz, Zz }, 0, 0 }
}, { /* SSE74_66 */
{ e_vpcmpeqb, t_done, 0, true, { Vps, Hps, Wps }, 0, s1W2R3R },
Expand Down Expand Up @@ -6351,8 +6359,8 @@ ia32_entry sseMapMult[][3] =
{ e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }
}, { /* SSE7F_66 */
{ e_vmovdqa, t_done, 0, true, { Vps, Wps, Zz }, 0, s1W2R },
{ 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_vmovdqa, t_done, 0, true, { Vps, Wps, Zz }, 0, s1W2R },
{ e_vmovdqa, t_done, 0, true, { Vps, Wps, Zz }, 0, s1W2R },
}, { /* SSE90_66 */
{ e_kmovb, t_done, 0, true, { VK, HK, WK }, 0, s1W2R3R },
{ e_kmovd, t_done, 0, true, { VK, HK, WK }, 0, s1W2R3R },
Expand Down Expand Up @@ -6592,7 +6600,7 @@ ia32_entry sseMapMult[][3] =
}, { /* SSEFA_66 */
{ e_vpsubd, t_done, 0, true, { Vps, Hps, Wps }, 0, s1W2R3R },
{ e_vpsubd, t_done, 0, true, { Vps, Hps, Wps }, 0, s1W2R3R },
{ e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }
{ e_vpsubd, t_done, 0, true, { Vps, Hps, Wps }, 0, s1W2R3R },
}, { /* SSEFB_66 */
{ e_vpsubq, t_done, 0, true, { Vps, Hps, Wps }, 0, s1W2R3R },
{ e_vpsubq, t_done, 0, true, { Vps, Hps, Wps }, 0, s1W2R3R },
Expand Down Expand Up @@ -6712,8 +6720,8 @@ ia32_entry sseMapBisMult[][3] =
{ e_vpmovusqd, t_done, 0, true, { Vps, Hps, Wps }, 0, s1W2R3R }
}, { /* SSEB16_66 */
{ e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
{ e_vpermps, t_done, 0, true, { Vps, Hps, Wps }, 0, s1W2R3R },
{ e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }
{ e_No_Entry, t_vexw, VEXW96, false, { Zz, Zz, Zz }, 0, 0 },
{ e_No_Entry, t_vexw, VEXW96, false, { Zz, Zz, Zz }, 0, 0 },
}, { /* SSEB18_66 */
{ e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
{ e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
Expand Down Expand Up @@ -7044,7 +7052,7 @@ ia32_entry sseMapBisMult[][3] =
{ e_No_Entry, t_vexw, VEXW57, false, { Zz, Zz, Zz }, 0, 0 }
}, { /* SSEB93_66 */
{ 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_vexw, VEXW58, false, { Zz, Zz, Zz }, 0, 0 },
{ e_No_Entry, t_vexw, VEXW58, false, { Zz, Zz, Zz }, 0, 0 }
}, { /* SSEB96_66 */
{ e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
Expand Down Expand Up @@ -7471,6 +7479,10 @@ ia32_entry sseMapTerMult[][3] =
{ 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_vexw, VEXW54, false, { Zz, Zz, Zz }, 0, 0 },
}, { /* SSET69_66 */
{ e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
{ e_No_Entry, t_vexw, VEXW95, false, { Zz, Zz, Zz }, 0, 0 },
{ e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 }
}, { /* SSETF0_F2 */
{ e_No_Entry, t_ill, 0, false, { Zz, Zz, Zz }, 0, 0 },
{ e_rorx, t_done, 0, true, { Gv, Bv, Ib }, 0, s1W2R3R },
Expand Down Expand Up @@ -7889,7 +7901,7 @@ static struct ia32_entry vexWMap[][2] =
{ e_vgatherdpd, t_done, 0, true, { Wsd, Vsd, Zz }, 0, s1RW2R } /* W = 1 */
}, { /* VEXW58 *//* EVEX VERSION */
{ e_vgatherqps, t_done, 0, true, { Wss, Vss, Zz }, 0, s1RW2R }, /* W = 0 */
{ e_vgatherqps, t_done, 0, true, { Wsd, Vsd, Zz }, 0, s1RW2R } /* W = 1 */
{ e_vgatherqpd, t_done, 0, true, { Wsd, Vsd, Zz }, 0, s1RW2R } /* W = 1 */
}, { /* VEXW59 *//* EVEX VERSION */
{ e_vgetexpps, t_done, 0, true, { Wps, Vps, Zz }, 0, s1RW2R }, /* W = 0 */
{ e_vgetexppd, t_done, 0, true, { Wpd, Vpd, Zz }, 0, s1RW2R } /* W = 1 */
Expand Down Expand Up @@ -8070,6 +8082,12 @@ static struct ia32_entry vexWMap[][2] =
}, { /* VEXW94 */
{ e_blendps, t_done, 0, true, { Vdq, Wdq, Ib }, 0, s1RW2R3R }, /* W = 0 */
{ e_blendpd, t_done, 0, true, { Vdq, Wdq, Ib }, 0, s1RW2R3R }, /* W = 1 */
}, { /* VEXW95 */
{ e_vfmaddps, t_done, 0, true, { Vdq, Wdq, Ib }, 0, s1RW2R3R }, /* W = 0 */
{ e_vfmaddpd, t_done, 0, true, { Vdq, Wdq, Ib }, 0, s1RW2R3R }, /* W = 1 */
}, { /* VEXW96 */
{ e_vpermps, t_done, 0, true, { Vps, Hps, Wps }, 0, s1W2R3R }, /* W = 0 */
{ e_vpermpd, t_done, 0, true, { Vps, Hps, Wps }, 0, s1W2R3R } /* W = 1 */
}
};
/** END_DYNINST_TABLE_VERIFICATION */
Expand All @@ -8091,34 +8109,36 @@ ia32_entry seg_mov = { e_mov, t_done, 0, true, {Ev, Sw, Zz}, 0, s1W2R };
static void ia32_translate_for_64(ia32_entry** gotit_ptr)
{
if (*gotit_ptr == &oneByteMap[0x63]) // APRL redefined to MOVSXD
*gotit_ptr = &movsxd;
*gotit_ptr = &movsxd;
if (*gotit_ptr == &oneByteMap[0x06] || // Invalid instructions in 64-bit mode: push es
*gotit_ptr == &oneByteMap[0x07] || // pop es
*gotit_ptr == &oneByteMap[0x0E] || // push cs
*gotit_ptr == &oneByteMap[0x16] || // push ss
*gotit_ptr == &oneByteMap[0x17] || // pop ss
*gotit_ptr == &oneByteMap[0x1E] || // push ds
*gotit_ptr == &oneByteMap[0x1F] || // pop ds
*gotit_ptr == &oneByteMap[0x27] || // daa
*gotit_ptr == &oneByteMap[0x2F] || // das
*gotit_ptr == &oneByteMap[0x37] || // aaa
*gotit_ptr == &oneByteMap[0x3F] || // aas
*gotit_ptr == &oneByteMap[0x60] || // pusha
*gotit_ptr == &oneByteMap[0x61] || // popa
*gotit_ptr == &oneByteMap[0x62] || // bound gv, ma
*gotit_ptr == &oneByteMap[0x82] || // group 1 eb/ib
*gotit_ptr == &oneByteMap[0x9A] || // call ap
*gotit_ptr == &oneByteMap[0xC4] || // les gz, mp
*gotit_ptr == &oneByteMap[0xC5] || // lds gz, mp
*gotit_ptr == &oneByteMap[0xCE] || // into
*gotit_ptr == &oneByteMap[0xD4] || // aam ib
*gotit_ptr == &oneByteMap[0xD5] || // aad ib
*gotit_ptr == &oneByteMap[0xD6] || // salc
*gotit_ptr == &oneByteMap[0xEA]) { // jump ap
*gotit_ptr = &invalid;
*gotit_ptr == &oneByteMap[0x07] || // pop es
*gotit_ptr == &oneByteMap[0x0E] || // push cs
*gotit_ptr == &oneByteMap[0x16] || // push ss
*gotit_ptr == &oneByteMap[0x17] || // pop ss
*gotit_ptr == &oneByteMap[0x1E] || // push ds
*gotit_ptr == &oneByteMap[0x1F] || // pop ds
*gotit_ptr == &oneByteMap[0x27] || // daa
*gotit_ptr == &oneByteMap[0x2F] || // das
*gotit_ptr == &oneByteMap[0x37] || // aaa
*gotit_ptr == &oneByteMap[0x3F] || // aas
*gotit_ptr == &oneByteMap[0x60] || // pusha
*gotit_ptr == &oneByteMap[0x61] || // popa
*gotit_ptr == &oneByteMap[0x62] || // bound gv, ma
*gotit_ptr == &oneByteMap[0x82] || // group 1 eb/ib
*gotit_ptr == &oneByteMap[0x9A] || // call ap
*gotit_ptr == &oneByteMap[0xC4] || // les gz, mp
*gotit_ptr == &oneByteMap[0xC5] || // lds gz, mp
*gotit_ptr == &oneByteMap[0xCE] || // into
*gotit_ptr == &oneByteMap[0xD4] || // aam ib
*gotit_ptr == &oneByteMap[0xD5] || // aad ib
*gotit_ptr == &oneByteMap[0xD6] || // salc
*gotit_ptr == &oneByteMap[0xEA]) // jump ap
{
*gotit_ptr = &invalid;
}

if(*gotit_ptr == &oneByteMap[0x8C]) {
*gotit_ptr = &seg_mov;
*gotit_ptr = &seg_mov;
}

}
Expand Down Expand Up @@ -8672,7 +8692,7 @@ ia32_instruction& ia32_decode(unsigned int capa, const unsigned char* addr, ia32
/* make adjustments for instruction redefined in 64-bit mode */
if(mode_64)
{
ia32_translate_for_64(&gotit);
// ia32_translate_for_64(&gotit);
}

/* Do the operand decoding */
Expand Down Expand Up @@ -9545,7 +9565,6 @@ unsigned int ia32_decode_operands (const ia32_prefixes& pref,
case am_U: /* XMM, YMM or ZMM register (from R/M of ModR/M) */
case am_H: /* XMM, YMM or ZMM register (vvvv of prefix) */
case am_HK: /* K register (vvvv of prefix) */
case am_WK: /* K register (vvvv of prefix) */
case am_VK: /* K register (vvvv of prefix) */
case am_reg: /* register implicitely encoded in opcode */
case am_allgprs:
Expand All @@ -9558,6 +9577,7 @@ unsigned int ia32_decode_operands (const ia32_prefixes& pref,
case am_XW: /* XMM register or memory location */
case am_YW: /* XMM or YMM register or memory location */
case am_W: /* XMM, YMM or ZMM register or memory location */
case am_WK: /* K register (vvvv of prefix) */
if (loc)
{
loc->modrm_position = loc->opcode_size + loc->opcode_position;
Expand Down
40 changes: 7 additions & 33 deletions instructionAPI/src/InstructionDecoder-x86.C
Original file line number Diff line number Diff line change
Expand Up @@ -1402,14 +1402,19 @@ namespace Dyninst
/* Append the operand */
insn_to_complete->appendOperand(makeRegisterExpression(IntelRegTable(m_Arch, bank, bank_index)), isRead, isWritten);
break;
case am_WK: /* Could be a K mask register or memory address*/
case am_W: /* Could be XMM, YMM, or ZMM (or possibly not VEX) */

if(pref.vex_present)
{
if(!AVX_TYPE_OKAY(avx_type))
return false;
return false;
}


// if(operand.admet == am_WK)
// printf("modrm_mod: %d modrm_reg: %d modrm_rm: %d\n",
// locs->modrm_mod, locs->modrm_reg, locs->modrm_rm);

switch(locs->modrm_mod)
{
/* Direct dereference */
Expand Down Expand Up @@ -1493,37 +1498,6 @@ namespace Dyninst
break;
}
break;
case am_WK: /* Must be either YMM or XMM (must be VEX) */

/* Make sure the register class is okay and we have a vex prefix */
if(!AVX_TYPE_OKAY(avx_type) || !pref.vex_present)
return false;

/* Constrain to either XMM or YMM registers */
if(avx_type != AVX_XMM && avx_type != AVX_YMM)
avx_type = AVX_YMM;

switch(locs->modrm_mod)
{
/* Direct dereference */
case 0x00:
case 0x01:
case 0x02:
insn_to_complete->appendOperand(makeModRMExpression(b, makeSizeType(optype)), isRead, isWritten);
break;
case 0x03:
/* Just the register is used */
if(decodeAVX(bank, &bank_index, locs->modrm_rm, avx_type, pref, operand.admet))
return false;

/* Append the operand */
insn_to_complete->appendOperand(makeRegisterExpression(IntelRegTable(m_Arch, bank, bank_index)), isRead, isWritten);
break;
default:
assert(!"2-bit value modrm_mod out of range");
break;
}
break;
case am_X:
{
MachRegister si_reg;
Expand Down

0 comments on commit 368d2da

Please sign in to comment.