From: Julian Seward Date: Tue, 26 Oct 2004 00:50:52 +0000 (+0000) Subject: Simulate bit 21 of eflags (ID), so that CPUID tests work properly. X-Git-Tag: svn/VALGRIND_3_0_1^2~904 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b69096c4a58cf461f32a9b7a2bf917126bb296e9;p=thirdparty%2Fvalgrind.git Simulate bit 21 of eflags (ID), so that CPUID tests work properly. git-svn-id: svn://svn.valgrind.org/vex/trunk@430 --- diff --git a/VEX/priv/guest-x86/ghelpers.c b/VEX/priv/guest-x86/ghelpers.c index 577241f394..e61ba92347 100644 --- a/VEX/priv/guest-x86/ghelpers.c +++ b/VEX/priv/guest-x86/ghelpers.c @@ -1317,6 +1317,8 @@ void LibVEX_GuestX86_put_eflags ( UInt eflags_native, { vex_state->guest_DFLAG = (eflags_native & (1<<10)) ? 0xFFFFFFFF : 0x00000001; + vex_state->guest_IDFLAG + = (eflags_native & (1<<21)) ? 1 : 0; /* Mask out everything except O S Z A C P. */ eflags_native @@ -1341,6 +1343,8 @@ UInt LibVEX_GuestX86_get_eflags ( /*IN*/VexGuestX86State* vex_state ) vassert(dflag == 1 || dflag == 0xFFFFFFFF); if (dflag == 0xFFFFFFFF) eflags |= (1<<10); + if (vex_state->guest_IDFLAG == 1) + eflags |= (1<<21); return eflags; } @@ -1363,6 +1367,7 @@ void LibVEX_GuestX86_initialise ( /*OUT*/VexGuestX86State* vex_state ) vex_state->guest_CC_SRC = 0; vex_state->guest_CC_DST = 0; vex_state->guest_DFLAG = 1; /* forwards */ + vex_state->guest_IDFLAG = 0; vex_state->guest_EIP = 0; diff --git a/VEX/priv/guest-x86/toIR.c b/VEX/priv/guest-x86/toIR.c index 6da101ec2f..18623db6c3 100644 --- a/VEX/priv/guest-x86/toIR.c +++ b/VEX/priv/guest-x86/toIR.c @@ -214,6 +214,7 @@ IRBB* bbToIR_X86Instr ( UChar* x86code, #define OFFB_CC_SRC offsetof(VexGuestX86State,guest_CC_SRC) #define OFFB_CC_DST offsetof(VexGuestX86State,guest_CC_DST) #define OFFB_DFLAG offsetof(VexGuestX86State,guest_DFLAG) +#define OFFB_IDFLAG offsetof(VexGuestX86State,guest_IDFLAG) #define OFFB_FTOP offsetof(VexGuestX86State,guest_FTOP) #define OFFB_FC3210 offsetof(VexGuestX86State,guest_FC3210) #define OFFB_FPUCW offsetof(VexGuestX86State,guest_FPUCW) @@ -8218,6 +8219,18 @@ static DisResult disInstr ( /*IN*/ Bool resteerOK, mkU32(0xFFFFFFFF))) ); + /* And set the ID flag */ + stmt( IRStmt_Put( + OFFB_IDFLAG, + IRExpr_Mux0X( + unop(Iop_32to8, + binop(Iop_And32, + binop(Iop_Shr32, mkexpr(t1), mkU8(21)), + mkU32(1))), + mkU32(0), + mkU32(1))) + ); + DIP("popf%c\n", nameISize(sz)); break; @@ -8348,7 +8361,7 @@ static DisResult disInstr ( /*IN*/ Bool resteerOK, break; case 0x9C: /* PUSHF */ { - IRTemp t3; + IRTemp t3, t4; vassert(sz == 2 || sz == 4); vassert(sz == 4); // wait for sz==2 test case @@ -8368,11 +8381,22 @@ static DisResult disInstr ( /*IN*/ Bool resteerOK, unop(Iop_Not32, IRExpr_Get(OFFB_DFLAG,Ity_I32)), mkU32(1<<10))) ); + + /* And patch in the ID flag. */ + t4 = newTemp(Ity_I32); + assign( t4, binop(Iop_Or32, + mkexpr(t3), + binop(Iop_And32, + binop(Iop_Shl32, IRExpr_Get(OFFB_IDFLAG,Ity_I32), + mkU8(21)), + mkU32(1<<21))) + ); + /* if sz==2, the stored value needs to be narrowed. */ if (sz == 2) - storeLE( mkexpr(t1), unop(Iop_32to16,mkexpr(t3)) ); + storeLE( mkexpr(t1), unop(Iop_32to16,mkexpr(t4)) ); else - storeLE( mkexpr(t1), mkexpr(t3) ); + storeLE( mkexpr(t1), mkexpr(t4) ); DIP("pushf%c\n", nameISize(sz)); break; diff --git a/VEX/pub/libvex_guest_x86.h b/VEX/pub/libvex_guest_x86.h index 7b683bb0fa..ababaad358 100644 --- a/VEX/pub/libvex_guest_x86.h +++ b/VEX/pub/libvex_guest_x86.h @@ -87,6 +87,8 @@ typedef UInt guest_CC_DST; /* The D flag is stored here, as either -1 or +1 */ UInt guest_DFLAG; + /* Bit 21 (ID) of eflags stored here, as either 0 or 1. */ + UInt guest_IDFLAG; /* EIP */ UInt guest_EIP; /* FPU */ @@ -103,7 +105,7 @@ typedef UShort guest_GS; UShort guest_SS; /* Padding to make it have an 8-aligned size */ - UInt padding; + /* UInt padding; */ } VexGuestX86State;