From: Julian Seward Date: Wed, 18 Sep 2013 18:27:55 +0000 (+0000) Subject: x86 front ends: tighten up decoding of MOV Ib,Eb and MOV Iv,Ev. This X-Git-Tag: svn/VALGRIND_3_9_0^2~27 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c444b889504804a8c185ffa798a2fe532554cfad;p=thirdparty%2Fvalgrind.git x86 front ends: tighten up decoding of MOV Ib,Eb and MOV Iv,Ev. This failed to check the g-register in the modrm byte, with the result that it will mis-decode the AVX2 XABORT and XBEGIN instructions as these instead, with obviously-bizarre consequences. git-svn-id: svn://svn.valgrind.org/vex/trunk@2768 --- diff --git a/VEX/priv/guest_amd64_toIR.c b/VEX/priv/guest_amd64_toIR.c index 522bfbe147..4fa83f9bcb 100644 --- a/VEX/priv/guest_amd64_toIR.c +++ b/VEX/priv/guest_amd64_toIR.c @@ -20035,34 +20035,37 @@ Long dis_ESC_NONE ( DIP(haveF3(pfx) ? "rep ; ret\n" : "ret\n"); return delta; - case 0xC6: /* MOV Ib,Eb */ + case 0xC6: /* C6 /0 = MOV Ib,Eb */ sz = 1; - goto do_Mov_I_E; - case 0xC7: /* MOV Iv,Ev */ - goto do_Mov_I_E; - do_Mov_I_E: - if (haveF2orF3(pfx)) goto decode_failure; + goto maybe_do_Mov_I_E; + case 0xC7: /* C7 /0 = MOV Iv,Ev */ + goto maybe_do_Mov_I_E; + maybe_do_Mov_I_E: modrm = getUChar(delta); - if (epartIsReg(modrm)) { - delta++; /* mod/rm byte */ - d64 = getSDisp(imin(4,sz),delta); - delta += imin(4,sz); - putIRegE(sz, pfx, modrm, - mkU(szToITy(sz), d64 & mkSizeMask(sz))); - DIP("mov%c $%lld, %s\n", nameISize(sz), - (Long)d64, - nameIRegE(sz,pfx,modrm)); - } else { - addr = disAMode ( &alen, vbi, pfx, delta, dis_buf, - /*xtra*/imin(4,sz) ); - delta += alen; - d64 = getSDisp(imin(4,sz),delta); - delta += imin(4,sz); - storeLE(mkexpr(addr), - mkU(szToITy(sz), d64 & mkSizeMask(sz))); - DIP("mov%c $%lld, %s\n", nameISize(sz), (Long)d64, dis_buf); + if (gregLO3ofRM(modrm) == 0) { + if (haveF2orF3(pfx)) goto decode_failure; + if (epartIsReg(modrm)) { + delta++; /* mod/rm byte */ + d64 = getSDisp(imin(4,sz),delta); + delta += imin(4,sz); + putIRegE(sz, pfx, modrm, + mkU(szToITy(sz), d64 & mkSizeMask(sz))); + DIP("mov%c $%lld, %s\n", nameISize(sz), + (Long)d64, + nameIRegE(sz,pfx,modrm)); + } else { + addr = disAMode ( &alen, vbi, pfx, delta, dis_buf, + /*xtra*/imin(4,sz) ); + delta += alen; + d64 = getSDisp(imin(4,sz),delta); + delta += imin(4,sz); + storeLE(mkexpr(addr), + mkU(szToITy(sz), d64 & mkSizeMask(sz))); + DIP("mov%c $%lld, %s\n", nameISize(sz), (Long)d64, dis_buf); + } + return delta; } - return delta; + goto decode_failure; case 0xC8: /* ENTER */ /* Same comments re operand size as for LEAVE below apply. diff --git a/VEX/priv/guest_x86_toIR.c b/VEX/priv/guest_x86_toIR.c index e98f19cb29..d3b93ddb55 100644 --- a/VEX/priv/guest_x86_toIR.c +++ b/VEX/priv/guest_x86_toIR.c @@ -13503,28 +13503,31 @@ DisResult disInstr_X86_WRK ( DIP("mov%c $0x%x,%s\n", nameISize(sz), d32, nameIReg(sz,opc-0xB8)); break; - case 0xC6: /* MOV Ib,Eb */ + case 0xC6: /* C6 /0 = MOV Ib,Eb */ sz = 1; - goto do_Mov_I_E; - case 0xC7: /* MOV Iv,Ev */ - goto do_Mov_I_E; + goto maybe_do_Mov_I_E; + case 0xC7: /* C7 /0 = MOV Iv,Ev */ + goto maybe_do_Mov_I_E; - do_Mov_I_E: + maybe_do_Mov_I_E: modrm = getIByte(delta); - if (epartIsReg(modrm)) { - delta++; /* mod/rm byte */ - d32 = getUDisp(sz,delta); delta += sz; - putIReg(sz, eregOfRM(modrm), mkU(szToITy(sz), d32)); - DIP("mov%c $0x%x, %s\n", nameISize(sz), d32, - nameIReg(sz,eregOfRM(modrm))); - } else { - addr = disAMode ( &alen, sorb, delta, dis_buf ); - delta += alen; - d32 = getUDisp(sz,delta); delta += sz; - storeLE(mkexpr(addr), mkU(szToITy(sz), d32)); - DIP("mov%c $0x%x, %s\n", nameISize(sz), d32, dis_buf); + if (gregOfRM(modrm) == 0) { + if (epartIsReg(modrm)) { + delta++; /* mod/rm byte */ + d32 = getUDisp(sz,delta); delta += sz; + putIReg(sz, eregOfRM(modrm), mkU(szToITy(sz), d32)); + DIP("mov%c $0x%x, %s\n", nameISize(sz), d32, + nameIReg(sz,eregOfRM(modrm))); + } else { + addr = disAMode ( &alen, sorb, delta, dis_buf ); + delta += alen; + d32 = getUDisp(sz,delta); delta += sz; + storeLE(mkexpr(addr), mkU(szToITy(sz), d32)); + DIP("mov%c $0x%x, %s\n", nameISize(sz), d32, dis_buf); + } + break; } - break; + goto decode_failure; /* ------------------------ opl imm, A ----------------- */