X-Git-Url: https://rtime.felk.cvut.cz/gitweb/l4.git/blobdiff_plain/f4122e6e085938b6d216a9ec724b974a603f6992..983fe7c4ac262f56d38a143b1efab1e4afb77a52:/l4/pkg/valgrind/src/valgrind-3.6.0-svn/VEX/priv/guest_x86_toIR.c diff --git a/l4/pkg/valgrind/src/valgrind-3.6.0-svn/VEX/priv/guest_x86_toIR.c b/l4/pkg/valgrind/src/valgrind-3.6.0-svn/VEX/priv/guest_x86_toIR.c index 761cd7f94..c23890802 100644 --- a/l4/pkg/valgrind/src/valgrind-3.6.0-svn/VEX/priv/guest_x86_toIR.c +++ b/l4/pkg/valgrind/src/valgrind-3.6.0-svn/VEX/priv/guest_x86_toIR.c @@ -998,7 +998,10 @@ static void setFlags_DEP1_DEP2_shift ( IROp op32, widenUto32(mkexpr(resUS)))) ); /* Set NDEP even though it isn't used. This makes redundant-PUT elimination of previous stores to this field work better. */ - stmt( IRStmt_Put( OFFB_CC_NDEP, mkU32(0) )); + stmt( IRStmt_Put( OFFB_CC_NDEP, + IRExpr_Mux0X( mkexpr(guard), + IRExpr_Get(OFFB_CC_NDEP,Ity_I32), + mkU32(0) ))); } @@ -2166,9 +2169,16 @@ UInt dis_movx_E_G ( UChar sorb, { UChar rm = getIByte(delta); if (epartIsReg(rm)) { - putIReg(szd, gregOfRM(rm), - unop(mkWidenOp(szs,szd,sign_extend), - getIReg(szs,eregOfRM(rm)))); + if (szd == szs) { + // mutant case. See #250799 + putIReg(szd, gregOfRM(rm), + getIReg(szs,eregOfRM(rm))); + } else { + // normal case + putIReg(szd, gregOfRM(rm), + unop(mkWidenOp(szs,szd,sign_extend), + getIReg(szs,eregOfRM(rm)))); + } DIP("mov%c%c%c %s,%s\n", sign_extend ? 's' : 'z', nameISize(szs), nameISize(szd), nameIReg(szs,eregOfRM(rm)), @@ -2181,10 +2191,16 @@ UInt dis_movx_E_G ( UChar sorb, Int len; HChar dis_buf[50]; IRTemp addr = disAMode ( &len, sorb, delta, dis_buf ); - - putIReg(szd, gregOfRM(rm), - unop(mkWidenOp(szs,szd,sign_extend), - loadLE(szToITy(szs),mkexpr(addr)))); + if (szd == szs) { + // mutant case. See #250799 + putIReg(szd, gregOfRM(rm), + loadLE(szToITy(szs),mkexpr(addr))); + } else { + // normal case + putIReg(szd, gregOfRM(rm), + unop(mkWidenOp(szs,szd,sign_extend), + loadLE(szToITy(szs),mkexpr(addr)))); + } DIP("mov%c%c%c %s,%s\n", sign_extend ? 's' : 'z', nameISize(szs), nameISize(szd), dis_buf, nameIReg(szd,gregOfRM(rm))); @@ -7947,15 +7963,15 @@ DisResult disInstr_X86_WRK ( } #if 1 /* To make a syscall in L4Re the guest must access its UTCB. - * The address of the UTCB is stored in %gs, so we look for + * The address of the UTCB is stored in %fs, so we look for * the following instructions: - * 65 a1 00 00 00 00 mov %gs:0x0,%eax - * 65 8b 0d 00 00 00 00 mov %gs:0x0,%ecx - * 65 8b 15 00 00 00 00 mov %gs:0x0,%edx - * 65 8b 3d 00 00 00 00 mov %gs:0x0,%edi - * 65 8b 35 00 00 00 00 mov %gs:0x0,%esi + * 64 a1 00 00 00 00 mov %fs:0x0,%eax + * 64 8b 0d 00 00 00 00 mov %fs:0x0,%ecx + * 64 8b 15 00 00 00 00 mov %fs:0x0,%edx + * 64 8b 3d 00 00 00 00 mov %fs:0x0,%edi + * 64 8b 35 00 00 00 00 mov %fs:0x0,%esi */ - if (code[ 0] == 0x65 && code[ 1] == 0xa1 && code[ 2] == 0x0 && + if (code[ 0] == 0x64 && code[ 1] == 0xa1 && code[ 2] == 0x0 && code[ 3] == 0x0 && code[ 4] == 0x0 && code[ 5] == 0x0) { // printf("%x\n", code); // printf("0x%x\n", guest_EIP_bbstart+delta); @@ -7970,7 +7986,7 @@ DisResult disInstr_X86_WRK ( /* utcb -> ebx */ // TODO implement me /* utcb -> ecx */ - if (code[ 0] == 0x65 && code[ 1] == 0x8b && code[ 2] == 0x0d && + if (code[ 0] == 0x64 && code[ 1] == 0x8b && code[ 2] == 0x0d && code[ 3] == 0x0 && code[ 4] == 0x0 && code[ 5] == 0x0 && code[ 6] == 0x0) { delta += 7; jmp_lit(Ijk_l4_utcb_ecx, guest_EIP_bbstart+delta); @@ -7978,7 +7994,7 @@ DisResult disInstr_X86_WRK ( goto decode_success; } /* utcb -> edx */ - if (code[ 0] == 0x65 && code[ 1] == 0x8b && code[ 2] == 0x15 && + if (code[ 0] == 0x64 && code[ 1] == 0x8b && code[ 2] == 0x15 && code[ 3] == 0x0 && code[ 4] == 0x0 && code[ 5] == 0x0 && code[ 6] == 0x0) { delta += 7; jmp_lit(Ijk_l4_utcb_edx, guest_EIP_bbstart+delta); @@ -7986,7 +8002,7 @@ DisResult disInstr_X86_WRK ( goto decode_success; } /* utcb -> edi */ - if (code[ 0] == 0x65 && code[ 1] == 0x8b && code[ 2] == 0x3d && + if (code[ 0] == 0x64 && code[ 1] == 0x8b && code[ 2] == 0x3d && code[ 3] == 0x0 && code[ 4] == 0x0 && code[ 5] == 0x0 && code[ 6] == 0x0) { delta += 7; jmp_lit(Ijk_l4_utcb_edi, guest_EIP_bbstart+delta); @@ -7995,7 +8011,7 @@ DisResult disInstr_X86_WRK ( } /* utcb -> esi */ - if (code[ 0] == 0x65 && code[ 1] == 0x8b && code[ 2] == 0x35 && + if (code[ 0] == 0x64 && code[ 1] == 0x8b && code[ 2] == 0x35 && code[ 3] == 0x0 && code[ 4] == 0x0 && code[ 5] == 0x0 && code[ 6] == 0x0) { delta += 7; jmp_lit(Ijk_l4_utcb_esi, guest_EIP_bbstart+delta); @@ -8166,6 +8182,7 @@ DisResult disInstr_X86_WRK ( addr = disAMode ( &alen, sorb, delta+2, dis_buf ); delta += 2+alen; + gen_SEGV_if_not_16_aligned(addr); DIP("fxsave %s\n", dis_buf); @@ -8236,11 +8253,15 @@ DisResult disInstr_X86_WRK ( addr = disAMode ( &alen, sorb, delta+2, dis_buf ); delta += 2+alen; + gen_SEGV_if_not_16_aligned(addr); DIP("fxrstor %s\n", dis_buf); /* Uses dirty helper: - void x86g_do_FXRSTOR ( VexGuestX86State*, UInt ) */ + VexEmWarn x86g_do_FXRSTOR ( VexGuestX86State*, UInt ) + NOTE: + the VexEmWarn value is simply ignored (unlike for FRSTOR) + */ d = unsafeIRDirty_0_N ( 0/*regparms*/, "x86g_dirtyhelper_FXRSTOR", @@ -8658,6 +8679,8 @@ DisResult disInstr_X86_WRK ( delta += 2+1; } else { addr = disAMode ( &alen, sorb, delta+2, dis_buf ); + if (insn[1] == 0x28/*movaps*/) + gen_SEGV_if_not_16_aligned( addr ); putXMMReg( gregOfRM(modrm), loadLE(Ity_V128, mkexpr(addr)) ); DIP("mov[ua]ps %s,%s\n", dis_buf, @@ -8676,6 +8699,8 @@ DisResult disInstr_X86_WRK ( /* fall through; awaiting test case */ } else { addr = disAMode ( &alen, sorb, delta+2, dis_buf ); + if (insn[1] == 0x29/*movaps*/) + gen_SEGV_if_not_16_aligned( addr ); storeLE( mkexpr(addr), getXMMReg(gregOfRM(modrm)) ); DIP("mov[ua]ps %s,%s\n", nameXMMReg(gregOfRM(modrm)), dis_buf ); @@ -8802,6 +8827,7 @@ DisResult disInstr_X86_WRK ( modrm = getIByte(delta+2); if (!epartIsReg(modrm)) { addr = disAMode ( &alen, sorb, delta+2, dis_buf ); + gen_SEGV_if_not_16_aligned( addr ); storeLE( mkexpr(addr), getXMMReg(gregOfRM(modrm)) ); DIP("movntp%s %s,%s\n", sz==2 ? "d" : "s", dis_buf, @@ -10027,6 +10053,8 @@ DisResult disInstr_X86_WRK ( delta += 2+1; } else { addr = disAMode ( &alen, sorb, delta+2, dis_buf ); + if (insn[1] == 0x28/*movapd*/ || insn[1] == 0x6F/*movdqa*/) + gen_SEGV_if_not_16_aligned( addr ); putXMMReg( gregOfRM(modrm), loadLE(Ity_V128, mkexpr(addr)) ); DIP("mov%s %s,%s\n", wot, dis_buf, @@ -10046,6 +10074,8 @@ DisResult disInstr_X86_WRK ( /* fall through; awaiting test case */ } else { addr = disAMode ( &alen, sorb, delta+2, dis_buf ); + if (insn[1] == 0x29/*movapd*/) + gen_SEGV_if_not_16_aligned( addr ); storeLE( mkexpr(addr), getXMMReg(gregOfRM(modrm)) ); DIP("mov%s %s,%s\n", wot, nameXMMReg(gregOfRM(modrm)), dis_buf ); @@ -10108,6 +10138,7 @@ DisResult disInstr_X86_WRK ( } else { addr = disAMode( &alen, sorb, delta+2, dis_buf ); delta += 2+alen; + gen_SEGV_if_not_16_aligned( addr ); storeLE( mkexpr(addr), getXMMReg(gregOfRM(modrm)) ); DIP("movdqa %s, %s\n", nameXMMReg(gregOfRM(modrm)), dis_buf); } @@ -10319,6 +10350,7 @@ DisResult disInstr_X86_WRK ( modrm = getIByte(delta+2); if (sz == 2 && !epartIsReg(modrm)) { addr = disAMode ( &alen, sorb, delta+2, dis_buf ); + gen_SEGV_if_not_16_aligned( addr ); storeLE( mkexpr(addr), getXMMReg(gregOfRM(modrm)) ); DIP("movntdq %s,%s\n", dis_buf, nameXMMReg(gregOfRM(modrm))); @@ -11621,6 +11653,7 @@ DisResult disInstr_X86_WRK ( delta += 3+1; } else { addr = disAMode ( &alen, sorb, delta+3, dis_buf ); + gen_SEGV_if_not_16_aligned( addr ); assign( sV, loadLE(Ity_V128, mkexpr(addr)) ); DIP("movs%cdup %s,%s\n", isH ? 'h' : 'l', dis_buf, @@ -12966,25 +12999,51 @@ DisResult disInstr_X86_WRK ( } break; -//-- case 0xD4: /* AAM */ -//-- case 0xD5: /* AAD */ -//-- d32 = getIByte(delta); delta++; -//-- if (d32 != 10) VG_(core_panic)("disInstr: AAM/AAD but base not 10 !"); -//-- t1 = newTemp(cb); -//-- uInstr2(cb, GET, 2, ArchReg, R_EAX, TempReg, t1); -//-- /* Widen %AX to 32 bits, so it's all defined when we push it. */ -//-- uInstr1(cb, WIDEN, 4, TempReg, t1); -//-- uWiden(cb, 2, False); -//-- uInstr0(cb, CALLM_S, 0); -//-- uInstr1(cb, PUSH, 4, TempReg, t1); -//-- uInstr1(cb, CALLM, 0, Lit16, -//-- opc == 0xD4 ? VGOFF_(helper_AAM) : VGOFF_(helper_AAD) ); -//-- uFlagsRWU(cb, FlagsEmpty, FlagsSZP, FlagsEmpty); -//-- uInstr1(cb, POP, 4, TempReg, t1); -//-- uInstr0(cb, CALLM_E, 0); -//-- uInstr2(cb, PUT, 2, TempReg, t1, ArchReg, R_EAX); -//-- DIP(opc == 0xD4 ? "aam\n" : "aad\n"); -//-- break; + case 0xD4: /* AAM */ + case 0xD5: /* AAD */ + d32 = getIByte(delta); delta++; + if (sz != 4 || d32 != 10) goto decode_failure; + t1 = newTemp(Ity_I32); + t2 = newTemp(Ity_I32); + /* Make up a 32-bit value (t1), with the old value of AX in the + bottom 16 bits, and the old OSZACP bitmask in the upper 16 + bits. */ + assign(t1, + binop(Iop_16HLto32, + unop(Iop_32to16, + mk_x86g_calculate_eflags_all()), + getIReg(2, R_EAX) + )); + /* Call the helper fn, to get a new AX and OSZACP value, and + poke both back into the guest state. Also pass the helper + the actual opcode so it knows which of the 2 instructions it + is doing the computation for. */ + assign(t2, + mkIRExprCCall( + Ity_I32, 0/*regparm*/, "x86g_calculate_aad_aam", + &x86g_calculate_aad_aam, + mkIRExprVec_2( mkexpr(t1), mkU32( opc & 0xFF) ) + )); + putIReg(2, R_EAX, unop(Iop_32to16, mkexpr(t2) )); + + stmt( IRStmt_Put( OFFB_CC_OP, mkU32(X86G_CC_OP_COPY) )); + stmt( IRStmt_Put( OFFB_CC_DEP2, mkU32(0) )); + stmt( IRStmt_Put( OFFB_CC_DEP1, + binop(Iop_And32, + binop(Iop_Shr32, mkexpr(t2), mkU8(16)), + mkU32( X86G_CC_MASK_C | X86G_CC_MASK_P + | X86G_CC_MASK_A | X86G_CC_MASK_Z + | X86G_CC_MASK_S| X86G_CC_MASK_O ) + ) + ) + ); + /* Set NDEP even though it isn't used. This makes + redundant-PUT elimination of previous stores to this field + work better. */ + stmt( IRStmt_Put( OFFB_CC_NDEP, mkU32(0) )); + + DIP(opc == 0xD4 ? "aam\n" : "aad\n"); + break; /* ------------------------ CWD/CDQ -------------------- */ @@ -14708,9 +14767,9 @@ DisResult disInstr_X86_WRK ( break; case 0xBF: /* MOVSXw Ew,Gv */ - if (sz != 4) + if (sz != 4 && /* accept movsww, sigh, see #250799 */sz != 2) goto decode_failure; - delta = dis_movx_E_G ( sorb, delta, 2, 4, True ); + delta = dis_movx_E_G ( sorb, delta, 2, sz, True ); break; //-- /* =-=-=-=-=-=-=-=-=-=-= MOVNTI -=-=-=-=-=-=-=-=-= */