]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Track the status of the %EFLAGS.AC (alignment check) bit, but
authorJulian Seward <jseward@acm.org>
Sat, 6 Aug 2005 11:45:02 +0000 (11:45 +0000)
committerJulian Seward <jseward@acm.org>
Sat, 6 Aug 2005 11:45:02 +0000 (11:45 +0000)
otherwise ignore it.  This fixes a crash induced by incorrect CPU
identification.

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

VEX/priv/guest-x86/ghelpers.c
VEX/priv/guest-x86/toIR.c
VEX/priv/main/vex_main.c
VEX/pub/libvex.h
VEX/pub/libvex_emwarn.h
VEX/pub/libvex_guest_x86.h

index ef3b4baa0dbf25339f426d50d1790d5bce72abe8..db3487f11aad63bb36c7472297f3860cbe79476e 100644 (file)
@@ -737,6 +737,8 @@ UInt LibVEX_GuestX86_get_eflags ( /*IN*/VexGuestX86State* vex_state )
       eflags |= (1<<10);
    if (vex_state->guest_IDFLAG == 1)
       eflags |= (1<<21);
+   if (vex_state->guest_ACFLAG == 1)
+      eflags |= (1<<18);
                                             
    return eflags;
 }
@@ -1973,6 +1975,7 @@ void LibVEX_GuestX86_initialise ( /*OUT*/VexGuestX86State* vex_state )
    vex_state->guest_CC_NDEP = 0;
    vex_state->guest_DFLAG   = 1; /* forwards */
    vex_state->guest_IDFLAG  = 0;
+   vex_state->guest_ACFLAG  = 0;
 
    vex_state->guest_EIP = 0;
 
@@ -2072,7 +2075,7 @@ VexGuestLayout
 
           /* Describe any sections to be regarded by Memcheck as
              'always-defined'. */
-          .n_alwaysDefd = 21,
+          .n_alwaysDefd = 22,
 
           /* flags thunk: OP and NDEP are always defd, whereas DEP1
              and DEP2 have to be tracked.  See detailed comment in
@@ -2082,23 +2085,24 @@ VexGuestLayout
                  /*  1 */ ALWAYSDEFD(guest_CC_NDEP),
                  /*  2 */ ALWAYSDEFD(guest_DFLAG),
                  /*  3 */ ALWAYSDEFD(guest_IDFLAG),
-                 /*  4 */ ALWAYSDEFD(guest_EIP),
-                 /*  5 */ ALWAYSDEFD(guest_FTOP),
-                 /*  6 */ ALWAYSDEFD(guest_FPTAG),
-                 /*  7 */ ALWAYSDEFD(guest_FPROUND),
-                 /*  8 */ ALWAYSDEFD(guest_FC3210),
-                 /*  9 */ ALWAYSDEFD(guest_CS),
-                 /* 10 */ ALWAYSDEFD(guest_DS),
-                 /* 11 */ ALWAYSDEFD(guest_ES),
-                 /* 12 */ ALWAYSDEFD(guest_FS),
-                 /* 13 */ ALWAYSDEFD(guest_GS),
-                 /* 14 */ ALWAYSDEFD(guest_SS),
-                 /* 15 */ ALWAYSDEFD(guest_LDT),
-                 /* 16 */ ALWAYSDEFD(guest_GDT),
-                 /* 17 */ ALWAYSDEFD(guest_EMWARN),
-                 /* 18 */ ALWAYSDEFD(guest_SSEROUND),
-                 /* 19 */ ALWAYSDEFD(guest_TISTART),
-                 /* 20 */ ALWAYSDEFD(guest_TILEN)
+                 /*  4 */ ALWAYSDEFD(guest_ACFLAG),
+                 /*  5 */ ALWAYSDEFD(guest_EIP),
+                 /*  6 */ ALWAYSDEFD(guest_FTOP),
+                 /*  7 */ ALWAYSDEFD(guest_FPTAG),
+                 /*  8 */ ALWAYSDEFD(guest_FPROUND),
+                 /*  9 */ ALWAYSDEFD(guest_FC3210),
+                 /* 10 */ ALWAYSDEFD(guest_CS),
+                 /* 11 */ ALWAYSDEFD(guest_DS),
+                 /* 12 */ ALWAYSDEFD(guest_ES),
+                 /* 13 */ ALWAYSDEFD(guest_FS),
+                 /* 14 */ ALWAYSDEFD(guest_GS),
+                 /* 15 */ ALWAYSDEFD(guest_SS),
+                 /* 16 */ ALWAYSDEFD(guest_LDT),
+                 /* 17 */ ALWAYSDEFD(guest_GDT),
+                 /* 18 */ ALWAYSDEFD(guest_EMWARN),
+                 /* 19 */ ALWAYSDEFD(guest_SSEROUND),
+                 /* 20 */ ALWAYSDEFD(guest_TISTART),
+                 /* 21 */ ALWAYSDEFD(guest_TILEN)
                }
         };
 
index 4976847c1546102bf502ffd43ac4b94bbaeb032a..d8e8ba90f41cab334ea195b41cef3ae393bbc985 100644 (file)
    only way to observe eflags[1], a proper fix would be to make that
    bit be set by PUSHF.
 
+   The state of %eflags.AC (alignment check, bit 18) is recorded by
+   the simulation (viz, if you set it with popf then a pushf produces
+   the value you set it to), but it is otherwise ignored.  In
+   particular, setting it to 1 does NOT cause alignment checking to
+   happen.  Programs that set it to 1 and then rely on the resulting
+   SIGBUSs to inform them of misaligned accesses will not work.
+
    This module uses global variables and so is not MT-safe (if that
    should ever become relevant).
 
@@ -181,6 +188,7 @@ static IRBB* irbb;
 #define OFFB_FPTAGS    offsetof(VexGuestX86State,guest_FPTAG[0])
 #define OFFB_DFLAG     offsetof(VexGuestX86State,guest_DFLAG)
 #define OFFB_IDFLAG    offsetof(VexGuestX86State,guest_IDFLAG)
+#define OFFB_ACFLAG    offsetof(VexGuestX86State,guest_ACFLAG)
 #define OFFB_FTOP      offsetof(VexGuestX86State,guest_FTOP)
 #define OFFB_FC3210    offsetof(VexGuestX86State,guest_FC3210)
 #define OFFB_FPROUND   offsetof(VexGuestX86State,guest_FPROUND)
@@ -10944,7 +10952,7 @@ DisResult disInstr_X86_WRK (
                   mkU32(0xFFFFFFFF))) 
           );
 
-      /* And set the ID flag */
+      /* Set the ID flag */
       stmt( IRStmt_Put( 
                OFFB_IDFLAG,
                IRExpr_Mux0X( 
@@ -10956,6 +10964,30 @@ DisResult disInstr_X86_WRK (
                   mkU32(1))) 
           );
 
+      /* And set the AC flag.  If setting it 1 to, emit an emulation
+         warning. */
+      stmt( IRStmt_Put( 
+               OFFB_ACFLAG,
+               IRExpr_Mux0X( 
+                  unop(Iop_32to8,
+                       binop(Iop_And32, 
+                             binop(Iop_Shr32, mkexpr(t1), mkU8(18)), 
+                             mkU32(1))),
+                  mkU32(0), 
+                  mkU32(1))) 
+          );
+
+      put_emwarn( mkU32(EmWarn_X86_acFlag) );
+      stmt( 
+         IRStmt_Exit(
+            binop( Iop_CmpNE32, 
+                   binop(Iop_And32, mkexpr(t1), mkU32(1<<18)), 
+                   mkU32(0) ),
+            Ijk_EmWarn,
+            IRConst_U32( ((Addr32)guest_EIP_bbstart)+delta)
+         )
+      );
+
       DIP("popf%c\n", nameISize(sz));
       break;
 
@@ -11100,11 +11132,21 @@ DisResult disInstr_X86_WRK (
                               mkU32(1<<21)))
             );
 
+      /* And patch in the AC flag. */
+      t5 = newTemp(Ity_I32);
+      assign( t5, binop(Iop_Or32,
+                        mkexpr(t4),
+                        binop(Iop_And32,
+                              binop(Iop_Shl32, IRExpr_Get(OFFB_ACFLAG,Ity_I32), 
+                                               mkU8(18)),
+                              mkU32(1<<18)))
+            );
+
       /* if sz==2, the stored value needs to be narrowed. */
       if (sz == 2)
-        storeLE( mkexpr(t1), unop(Iop_32to16,mkexpr(t4)) );
+        storeLE( mkexpr(t1), unop(Iop_32to16,mkexpr(t5)) );
       else 
-        storeLE( mkexpr(t1), mkexpr(t4) );
+        storeLE( mkexpr(t1), mkexpr(t5) );
 
       DIP("pushf%c\n", nameISize(sz));
       break;
index 609375c01f66ad61395f99bea8c846656025ebb2..f1589c39e91d431c24c32dd207ea23f292dd2cc7 100644 (file)
@@ -614,6 +614,8 @@ HChar* LibVEX_EmWarn_string ( VexEmWarn ew )
         return "Setting %mxcsr.fz (SSE flush-underflows-to-zero mode)";
      case EmWarn_X86_daz:
         return "Setting %mxcsr.daz (SSE treat-denormals-as-zero mode)";
+     case EmWarn_X86_acFlag:
+        return "Setting %eflags.ac (setting noted but ignored)";
      case EmWarn_PPC32exns:
         return "Unmasking PPC32 FP exceptions";
      default: 
index bd87bd13b4196f07375de7d015cabd814faa2399..97cb8aa9dcafb74660381a1801265b53dfc1b441 100644 (file)
@@ -182,7 +182,7 @@ extern void LibVEX_ShowAllocStats ( void );
 
 /* The max number of guest state chunks which we can describe as
    always defined (for the benefit of Memcheck). */
-#define VEXGLO_N_ALWAYSDEFD  21
+#define VEXGLO_N_ALWAYSDEFD  22
 
 typedef
    struct {
index 51abcbf27b1a87d5b650ce9996b452d8e0e3dea8..8ef6c8d8df876f37f827fe49f7660bf4fbea888e 100644 (file)
@@ -83,6 +83,9 @@ typedef
       
       /* setting mxcsr.daz is not supported */
       EmWarn_X86_daz,
+
+      /* settings to %eflags.ac (alignment check) are noted but ignored */
+      EmWarn_X86_acFlag,
       
       /* unmasking PPC32 FP exceptions is not supported */
       EmWarn_PPC32exns,
index 377064cad521042f647fe16ceaad2dd091cdbb40..5bfa36838e204c1d04580532f5f7cd3a2ac26303 100644 (file)
@@ -160,6 +160,7 @@ typedef
       UInt  guest_EBP;
       UInt  guest_ESI;
       UInt  guest_EDI;         /* 28 */
+
       /* 4-word thunk used to calculate O S Z A C P flags. */
       UInt  guest_CC_OP;       /* 32 */
       UInt  guest_CC_DEP1;
@@ -169,17 +170,22 @@ typedef
       UInt  guest_DFLAG;       /* 48 */
       /* Bit 21 (ID) of eflags stored here, as either 0 or 1. */
       UInt  guest_IDFLAG;      /* 52 */
+      /* Bit 18 (AC) of eflags stored here, as either 0 or 1. */
+      UInt  guest_ACFLAG;      /* 56 */
+
       /* EIP */
-      UInt  guest_EIP;         /* 56 */
+      UInt  guest_EIP;         /* 60 */
+
       /* FPU */
-      UInt  guest_FTOP;        /* 60 */
       ULong guest_FPREG[8];    /* 64 */
       UChar guest_FPTAG[8];   /* 128 */
       UInt  guest_FPROUND;    /* 136 */
       UInt  guest_FC3210;     /* 140 */
+      UInt  guest_FTOP;       /* 144 */
+
       /* SSE */
-      UInt  guest_SSEROUND;   /* 144 */
-      U128  guest_XMM0;       /* 148 */
+      UInt  guest_SSEROUND;   /* 148 */
+      U128  guest_XMM0;       /* 152 */
       U128  guest_XMM1;
       U128  guest_XMM2;
       U128  guest_XMM3;
@@ -187,6 +193,7 @@ typedef
       U128  guest_XMM5;
       U128  guest_XMM6;
       U128  guest_XMM7;
+
       /* Segment registers. */
       UShort guest_CS;
       UShort guest_DS;
@@ -212,7 +219,7 @@ typedef
       UInt guest_TILEN;
 
       /* Padding to make it have an 8-aligned size */
-      UInt   padding;
+      /* UInt   padding; */
    }
    VexGuestX86State;