]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
x86 guest: implement more convincing version of CPUID, using a dirty
authorJulian Seward <jseward@acm.org>
Sun, 24 Oct 2004 22:31:25 +0000 (22:31 +0000)
committerJulian Seward <jseward@acm.org>
Sun, 24 Oct 2004 22:31:25 +0000 (22:31 +0000)
helper to modify guest state.  Fix the oversight that dirty helpers
don't currently have access to guest state by passing a pointer to it
as the first argument to all dirty helpers.

git-svn-id: svn://svn.valgrind.org/vex/trunk@409

VEX/priv/guest-x86/ghelpers.c
VEX/priv/guest-x86/toIR.c
VEX/priv/host-x86/isel.c

index 7dea804603e2670ef8d46711fbda72eb0c8d37ca..8ba9b31b3d8e1d4e15be18dbc6a678aea2209618 100644 (file)
@@ -24,8 +24,9 @@ static UInt  calculate_FXAM ( UInt tag, ULong dbl );
 static ULong calculate_RCR  ( UInt arg, UInt rot_amt, UInt eflags_in, UInt sz );
 
 /* --- DIRTY HELPERS --- */
-static ULong loadF80le ( UInt );
-static void  storeF80le ( UInt, ULong );
+static ULong loadF80le  ( VexGuestX86State*, UInt );
+static void  storeF80le ( VexGuestX86State*, UInt, ULong );
+static void  dirtyhelper_CPUID ( VexGuestX86State* st );
 
 
 /* This file contains helper functions for x86 guest code.
@@ -617,6 +618,8 @@ Addr64 x86guest_findhelper ( Char* function_name )
       return (Addr64)(Addr32)(& loadF80le);
    if (vex_streq(function_name, "calculate_RCR"))
       return (Addr64)(Addr32)(& calculate_RCR);
+   if (vex_streq(function_name, "dirtyhelper_CPUID"))
+      return (Addr64)(Addr32)(& dirtyhelper_CPUID);
    vex_printf("\nx86 guest: can't find helper: %s\n", function_name);
    vpanic("x86guest_findhelper");
 }
@@ -1195,7 +1198,7 @@ static void convert_f80le_to_f64le ( /*IN*/UChar* f80, /*OUT*/UChar* f64 )
 
 /* CALLED FROM GENERATED CODE */
 /* DIRTY HELPER (reads guest memory) */
-static ULong loadF80le ( UInt addrU )
+static ULong loadF80le ( VexGuestX86State* st, UInt addrU )
 {
    ULong f64;
    convert_f80le_to_f64le ( (UChar*)addrU, (UChar*)&f64 );
@@ -1204,7 +1207,7 @@ static ULong loadF80le ( UInt addrU )
 
 /* CALLED FROM GENERATED CODE */
 /* DIRTY HELPER (writes guest memory) */
-static void storeF80le ( UInt addrU, ULong f64 )
+static void storeF80le ( VexGuestX86State* st, UInt addrU, ULong f64 )
 {
    convert_f64le_to_f80le( (UChar*)&f64, (UChar*)addrU );
 }
@@ -1417,7 +1420,25 @@ static ULong calculate_RCR ( UInt arg, UInt rot_amt, UInt eflags_in, UInt sz )
    return (((ULong)eflags_in) << 32) | ((ULong)arg);
 }
 
+
+/* CALLED FROM GENERATED CODE */
+/* DIRTY HELPER (modifies guest state) */
+/* Claim to be a P54C P133 (pre-MMX Pentium) */
+static void dirtyhelper_CPUID ( VexGuestX86State* st )
+{
+   if (st->guest_EAX == 0) {
+      st->guest_EAX = 0x1;
+      st->guest_EBX = 0x756e6547;
+      st->guest_ECX = 0x6c65746e;
+      st->guest_EDX = 0x49656e69;
+   } else {
+      st->guest_EAX = 0x52b;
+      st->guest_EBX = 0x0;
+      st->guest_ECX = 0x0;
+      st->guest_EDX = 0x1bf;
+   }
+}
+
 /*---------------------------------------------------------------*/
 /*--- end                                guest-x86/ghelpers.c ---*/
 /*---------------------------------------------------------------*/
-
index 181cbd5a38258a57e2d4b271372eb235ef4def02..77febb5759a647903f98b58682410cda3f5180d8 100644 (file)
@@ -211,6 +211,9 @@ IRBB* bbToIR_X86Instr ( UChar* x86code,
 #define OFFB_FPREGS  offsetof(VexGuestX86State,guest_FPREG[0])
 #define OFFB_FPTAGS  offsetof(VexGuestX86State,guest_FPTAG[0])
 #define OFFB_EAX     offsetof(VexGuestX86State,guest_EAX)
+#define OFFB_EBX     offsetof(VexGuestX86State,guest_EBX)
+#define OFFB_ECX     offsetof(VexGuestX86State,guest_ECX)
+#define OFFB_EDX     offsetof(VexGuestX86State,guest_EDX)
 #define OFFB_CC_OP   offsetof(VexGuestX86State,guest_CC_OP)
 #define OFFB_CC_SRC  offsetof(VexGuestX86State,guest_CC_SRC)
 #define OFFB_CC_DST  offsetof(VexGuestX86State,guest_CC_DST)
@@ -3981,8 +3984,9 @@ UInt dis_FPU ( Bool* decode_ok, UChar sorb, UInt delta )
                break;
 
             case 5: { /* FLD extended-real */
-               /* Uses dirty helper: ULong loadF80le ( UInt ) */
-               /* addr holds the address.  First, do a dirty call to
+               /* Uses dirty helper: 
+                     ULong loadF80le ( VexGuestX86State*, UInt )
+                  addr holds the address.  First, do a dirty call to
                   get hold of the data. */
                /* give details of args, and where to call */
                IRDirty* d;
@@ -8858,13 +8862,41 @@ static DisResult disInstr ( /*IN*/  Bool    resteerOK,
 //-- 
       /* =-=-=-=-=-=-=-=-=- CPUID -=-=-=-=-=-=-=-=-=-=-= */
 
-      case 0xA2: /* CPUID */
-         vex_printf("vex x86->IR: hacked CPUID\n");
-         putIReg(4, R_EAX, mkU32(0));
-         putIReg(4, R_EBX, mkU32(0x756e6547));
-         putIReg(4, R_ECX, mkU32(0x49656e69));
-         putIReg(4, R_EDX, mkU32(0x6c65746e));
+      case 0xA2: { /* CPUID */
+         /* Uses dirty helper: 
+               void dirtyhelper_CPUID ( VexGuestX86State* )
+            declared to mod eax, wr ebx, ecx, edx
+         */
+         /* give details of args, and where to call */
+         IRDirty* d;
+         d          = emptyIRDirty();
+         d->name    = "dirtyhelper_CPUID";
+         d->args    = LibVEX_Alloc(1 * sizeof(IRTemp));
+         d->args[0] = NULL;
+         d->tmp     = INVALID_IRTEMP;
+         /* declare that we're not accessing memory */
+         d->mFx   = Ifx_None;
+         d->mAddr = NULL;
+         d->mSize = 0;
+         /* declare guest state effects */
+         d->nFxState = 4;
+         d->fxState[0].fx     = Ifx_Modify;
+         d->fxState[0].offset = OFFB_EAX;
+         d->fxState[0].size   = 4;
+         d->fxState[1].fx     = Ifx_Write;
+         d->fxState[1].offset = OFFB_EBX;
+         d->fxState[1].size   = 4;
+         d->fxState[2].fx     = Ifx_Write;
+         d->fxState[2].offset = OFFB_ECX;
+         d->fxState[2].size   = 4;
+         d->fxState[3].fx     = Ifx_Write;
+         d->fxState[3].offset = OFFB_EDX;
+         d->fxState[3].size   = 4;
+         /* execute the dirty call, side-effecting guest state */
+         stmt( IRStmt_Dirty(d) );
          break;
+      }
+
 //--    if (!VG_(cpu_has_feature)(VG_X86_FEAT_CPUID))
 //--       goto decode_failure;
 //-- 
index 37d26a9d2dced46aec640fb6e0090b70759e4a58..be4436cb27977a0eb5119309fe1ec141f380e76f 100644 (file)
@@ -2134,6 +2134,11 @@ static void iselStmt ( ISelEnv* env, IRStmt* stmt )
       for (i = n_args-1; i >= 0; i--)
          n_arg_ws += pushArg(env, d->args[i]);
 
+      /* and finally the leftmost argument, the guest state pointer,
+         which is in %ebp. */
+      addInstr(env, X86Instr_Push(X86RMI_Reg(hregX86_EBP())));
+      n_arg_ws++;
+
       /* call the helper, and get the args off the stack afterwards. */
       callHelperAndClearArgs( env, d->name, n_arg_ws );