]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
VEX part Implement --vex-iropt-register-updates=sp-at-mem-access
authorPhilippe Waroquiers <philippe.waroquiers@skynet.be>
Tue, 14 Aug 2012 22:29:01 +0000 (22:29 +0000)
committerPhilippe Waroquiers <philippe.waroquiers@skynet.be>
Tue, 14 Aug 2012 22:29:01 +0000 (22:29 +0000)
git-svn-id: svn://svn.valgrind.org/vex/trunk@2468

VEX/priv/guest_amd64_helpers.c
VEX/priv/guest_arm_helpers.c
VEX/priv/guest_mips_helpers.c
VEX/priv/guest_ppc_helpers.c
VEX/priv/guest_s390_helpers.c
VEX/priv/guest_x86_helpers.c
VEX/priv/ir_opt.c
VEX/pub/libvex.h

index 7e67d73f18d67e69b647a9df661755e719fec99c..467702a3111954cbbeb6096338ef2365d71d1f47 100644 (file)
@@ -40,6 +40,7 @@
 #include "libvex.h"
 
 #include "main_util.h"
+#include "main_globals.h"
 #include "guest_generic_bb_to_IR.h"
 #include "guest_amd64_defs.h"
 #include "guest_generic_x87.h"
@@ -3716,11 +3717,13 @@ void LibVEX_GuestAMD64_initialise ( /*OUT*/VexGuestAMD64State* vex_state )
 
 /* Figure out if any part of the guest state contained in minoff
    .. maxoff requires precise memory exceptions.  If in doubt return
-   True (but this is generates significantly slower code).  
+   True (but this generates significantly slower code).  
 
    By default we enforce precise exns for guest %RSP, %RBP and %RIP
    only.  These are the minimum needed to extract correct stack
    backtraces from amd64 code.
+
+   Only %RSP is needed in mode VexRegUpdSpAtMemAccess.   
 */
 Bool guest_amd64_state_requires_precise_mem_exns ( Int minoff,
                                                    Int maxoff)
@@ -3732,14 +3735,16 @@ Bool guest_amd64_state_requires_precise_mem_exns ( Int minoff,
    Int rip_min = offsetof(VexGuestAMD64State, guest_RIP);
    Int rip_max = rip_min + 8 - 1;
 
-   if (maxoff < rbp_min || minoff > rbp_max) {
-      /* no overlap with rbp */
+   if (maxoff < rsp_min || minoff > rsp_max) {
+      /* no overlap with rsp */
+      if (vex_control.iropt_register_updates == VexRegUpdSpAtMemAccess)
+         return False; // We only need to check stack pointer.
    } else {
       return True;
    }
 
-   if (maxoff < rsp_min || minoff > rsp_max) {
-      /* no overlap with rsp */
+   if (maxoff < rbp_min || minoff > rbp_max) {
+      /* no overlap with rbp */
    } else {
       return True;
    }
index d31e64a232be5f1d6e49e5b69d4191dfcb04daec..5fc42c72ab4a275cd3024d0275278b415d4c6347 100644 (file)
@@ -35,6 +35,7 @@
 #include "libvex.h"
 
 #include "main_util.h"
+#include "main_globals.h"
 #include "guest_generic_bb_to_IR.h"
 #include "guest_arm_defs.h"
 
@@ -1043,9 +1044,12 @@ void LibVEX_GuestARM_initialise ( /*OUT*/VexGuestARMState* vex_state )
 
 /* Figure out if any part of the guest state contained in minoff
    .. maxoff requires precise memory exceptions.  If in doubt return
-   True (but this is generates significantly slower code).  
+   True (but this generates significantly slower code).  
 
-   We enforce precise exns for guest R13(sp), R15T(pc).
+   We enforce precise exns for guest R13(sp), R15T(pc), R7, R11.
+
+
+   Only R13(sp) is needed in mode VexRegUpdSpAtMemAccess.   
 */
 Bool guest_arm_state_requires_precise_mem_exns ( Int minoff, 
                                                  Int maxoff)
@@ -1057,6 +1061,8 @@ Bool guest_arm_state_requires_precise_mem_exns ( Int minoff,
 
    if (maxoff < sp_min || minoff > sp_max) {
       /* no overlap with sp */
+      if (vex_control.iropt_register_updates == VexRegUpdSpAtMemAccess)
+         return False; // We only need to check stack pointer.
    } else {
       return True;
    }
index d992b9cd36e4540083541bed3404e037f5d42bbd..6951ea71612a11a49f14e72e122184f8ed4ff6b6 100644 (file)
@@ -35,6 +35,7 @@
 #include "libvex.h"
 
 #include "main_util.h"
+#include "main_globals.h"
 #include "guest_generic_bb_to_IR.h"
 #include "guest_mips_defs.h"
 
@@ -160,9 +161,11 @@ void LibVEX_GuestMIPS32_initialise( /*OUT*/ VexGuestMIPS32State * vex_state)
 
 /* Figure out if any part of the guest state contained in minoff
    .. maxoff requires precise memory exceptions.  If in doubt return
-   True (but this is generates significantly slower code).  
+   True (but this generates significantly slower code).  
 
    We enforce precise exns for guest SP, PC.
+
+   Only SP is needed in mode VexRegUpdSpAtMemAccess.   
 */
 Bool guest_mips32_state_requires_precise_mem_exns(Int minoff, Int maxoff)
 {
@@ -173,6 +176,8 @@ Bool guest_mips32_state_requires_precise_mem_exns(Int minoff, Int maxoff)
 
    if (maxoff < sp_min || minoff > sp_max) {
       /* no overlap with sp */
+      if (vex_control.iropt_register_updates == VexRegUpdSpAtMemAccess)
+         return False; // We only need to check stack pointer.
    } else {
       return True;
    }
index 6ffb1eabfd44005568c45de23bb8fc3a5b1cfdf3..d945602a308b26fe14232323a78eb49767afb465 100644 (file)
@@ -41,6 +41,7 @@
 #include "libvex.h"
 
 #include "main_util.h"
+#include "main_globals.h"
 #include "guest_generic_bb_to_IR.h"
 #include "guest_ppc_defs.h"
 
@@ -696,6 +697,8 @@ void LibVEX_GuestPPC64_initialise ( /*OUT*/VexGuestPPC64State* vex_state )
    minimum needed to extract correct stack backtraces from ppc
    code. [[NB: not sure if keeping LR up to date is actually
    necessary.]]
+
+   Only R1 is needed in mode VexRegUpdSpAtMemAccess.   
 */
 Bool guest_ppc32_state_requires_precise_mem_exns ( Int minoff, 
                                                    Int maxoff )
@@ -707,14 +710,16 @@ Bool guest_ppc32_state_requires_precise_mem_exns ( Int minoff,
    Int cia_min = offsetof(VexGuestPPC32State, guest_CIA);
    Int cia_max = cia_min + 4 - 1;
 
-   if (maxoff < lr_min || minoff > lr_max) {
-      /* no overlap with LR */
+   if (maxoff < r1_min || minoff > r1_max) {
+      /* no overlap with R1 */
+      if (vex_control.iropt_register_updates == VexRegUpdSpAtMemAccess)
+         return False; // We only need to check stack pointer.
    } else {
       return True;
    }
 
-   if (maxoff < r1_min || minoff > r1_max) {
-      /* no overlap with R1 */
+   if (maxoff < lr_min || minoff > lr_max) {
+      /* no overlap with LR */
    } else {
       return True;
    }
@@ -744,14 +749,16 @@ Bool guest_ppc64_state_requires_precise_mem_exns ( Int minoff,
    Int cia_min = offsetof(VexGuestPPC64State, guest_CIA);
    Int cia_max = cia_min + 8 - 1;
 
-   if (maxoff < lr_min || minoff > lr_max) {
-      /* no overlap with LR */
+   if (maxoff < r1_min || minoff > r1_max) {
+      /* no overlap with R1 */
+      if (vex_control.iropt_register_updates == VexRegUpdSpAtMemAccess)
+         return False; // We only need to check stack pointer.
    } else {
       return True;
    }
 
-   if (maxoff < r1_min || minoff > r1_max) {
-      /* no overlap with R1 */
+   if (maxoff < lr_min || minoff > lr_max) {
+      /* no overlap with LR */
    } else {
       return True;
    }
index 08deb64d717e11d0071cf582928c5757377ef651..ad726f7011401564ffda31aecceeec35c6e595d4 100644 (file)
@@ -38,6 +38,7 @@
 #include "libvex_s390x_common.h"
 
 #include "main_util.h"
+#include "main_globals.h"
 #include "guest_generic_bb_to_IR.h"
 #include "guest_s390_defs.h"
 
@@ -148,7 +149,7 @@ LibVEX_GuestS390X_initialise(VexGuestS390XState *state)
 
 /* Figure out if any part of the guest state contained in minoff
    .. maxoff requires precise memory exceptions.  If in doubt return
-   True (but this is generates significantly slower code).  */
+   True (but this generates significantly slower code).  */
 Bool
 guest_s390x_state_requires_precise_mem_exns(Int minoff, Int maxoff)
 {
@@ -161,14 +162,16 @@ guest_s390x_state_requires_precise_mem_exns(Int minoff, Int maxoff)
    Int ia_min = S390X_GUEST_OFFSET(guest_IA);
    Int ia_max = ia_min + 8 - 1;
 
-   if (maxoff < lr_min || minoff > lr_max) {
-      /* No overlap with LR */
+   if (maxoff < sp_min || minoff > sp_max) {
+      /* No overlap with SP */
+      if (vex_control.iropt_register_updates == VexRegUpdSpAtMemAccess)
+         return False; // We only need to check stack pointer.
    } else {
       return True;
    }
 
-   if (maxoff < sp_min || minoff > sp_max) {
-      /* No overlap with SP */
+   if (maxoff < lr_min || minoff > lr_max) {
+      /* No overlap with LR */
    } else {
       return True;
    }
index 62c9dd1afbb03f423d9db52a48902382fcbcbbe5..df9c72d6490000346ab0e22c5cb6ca54e4a0f377 100644 (file)
@@ -40,6 +40,7 @@
 #include "libvex.h"
 
 #include "main_util.h"
+#include "main_globals.h"
 #include "guest_generic_bb_to_IR.h"
 #include "guest_x86_defs.h"
 #include "guest_generic_x87.h"
@@ -2739,11 +2740,13 @@ void LibVEX_GuestX86_initialise ( /*OUT*/VexGuestX86State* vex_state )
 
 /* Figure out if any part of the guest state contained in minoff
    .. maxoff requires precise memory exceptions.  If in doubt return
-   True (but this is generates significantly slower code).  
+   True (but this generates significantly slower code).  
 
    By default we enforce precise exns for guest %ESP, %EBP and %EIP
    only.  These are the minimum needed to extract correct stack
    backtraces from x86 code.
+
+   Only %ESP is needed in mode VexRegUpdSpAtMemAccess.   
 */
 Bool guest_x86_state_requires_precise_mem_exns ( Int minoff, 
                                                  Int maxoff)
@@ -2755,14 +2758,16 @@ Bool guest_x86_state_requires_precise_mem_exns ( Int minoff,
    Int eip_min = offsetof(VexGuestX86State, guest_EIP);
    Int eip_max = eip_min + 4 - 1;
 
-   if (maxoff < ebp_min || minoff > ebp_max) {
-      /* no overlap with ebp */
+   if (maxoff < esp_min || minoff > esp_max) {
+      /* no overlap with esp */
+      if (vex_control.iropt_register_updates == VexRegUpdSpAtMemAccess)
+         return False; // We only need to check stack pointer.
    } else {
       return True;
    }
 
-   if (maxoff < esp_min || minoff > esp_max) {
-      /* no overlap with esp */
+   if (maxoff < ebp_min || minoff > ebp_max) {
+      /* no overlap with ebp */
    } else {
       return True;
    }
index 6d93b632ca9a1d75988e8fb61b01317d408c7685..206f80cf93093d17286d1167817305ab9c6ad3a2 100644 (file)
      not marked as being read or modified by the helper cannot be
      assumed to be up-to-date at the point where the helper is called.
 
+   * If iropt_register_updates == VexRegUpdSpAtMemAccess :
+     The guest state is only up to date only as explained above
+     (i.e. at SB exits and as specified by dirty helper call).
+     Also, the stack pointer register is up to date at memory
+     exception points (as this is needed for the stack extension
+     logic in m_signals.c).
+
    * If iropt_register_updates == VexRegUpdUnwindregsAtMemAccess :
      Immediately prior to any load or store, those parts of the guest
      state marked as requiring precise exceptions will be up to date.
      not marked as requiring precise exceptions cannot be assumed to
      be up-to-date at the point of the load/store.
 
-     If iropt_register_updates == VexRegUpdAllregsAtMemAccess:
+   * If iropt_register_updates == VexRegUpdAllregsAtMemAccess:
      Same as minimal, but all the guest state is up to date at memory
      exception points.
 
-     If iropt_register_updates == VexRegUpdAllregsAtEachInsn :
+   * If iropt_register_updates == VexRegUpdAllregsAtEachInsn :
      Guest state is up to date at each instruction.
 
    The relative order of loads and stores (including loads/stores of
@@ -778,7 +785,7 @@ static void handle_gets_Stmt (
    }
 
    if (memRW) {
-      /* This statement accesses memory.  So we need to dump all parts
+      /* This statement accesses memory.  So we might need to dump all parts
          of the environment corresponding to guest state that may not
          be reordered with respect to memory references.  That means
          at least the stack pointer. */
@@ -789,6 +796,12 @@ static void handle_gets_Stmt (
             for (j = 0; j < env->used; j++)
                env->inuse[j] = False;
             break;
+         case VexRegUpdSpAtMemAccess:
+            /* We need to dump the stack pointer
+               (needed for stack extension in m_signals.c).
+               preciseMemExnsFn will use vex_control.iropt_register_updates
+               to verify only the sp is to be checked. */
+            /* fallthrough */
          case VexRegUpdUnwindregsAtMemAccess:
             for (j = 0; j < env->used; j++) {
                if (!env->inuse[j])
@@ -837,9 +850,7 @@ static void redundant_put_removal_BB (
    IRStmt* st;
    UInt    key = 0; /* keep gcc -O happy */
 
-   vassert
-      (vex_control.iropt_register_updates == VexRegUpdUnwindregsAtMemAccess
-       || vex_control.iropt_register_updates == VexRegUpdAllregsAtMemAccess);
+   vassert(vex_control.iropt_register_updates < VexRegUpdAllregsAtEachInsn);
 
    HashHW* env = newHHW();
 
@@ -3958,9 +3969,7 @@ void do_redundant_PutI_elimination ( IRSB* bb )
    Bool   delete;
    IRStmt *st, *stj;
 
-   vassert
-      (vex_control.iropt_register_updates == VexRegUpdUnwindregsAtMemAccess
-       || vex_control.iropt_register_updates == VexRegUpdAllregsAtMemAccess);
+   vassert(vex_control.iropt_register_updates < VexRegUpdAllregsAtEachInsn);
 
    for (i = 0; i < bb->stmts_used; i++) {
       st = bb->stmts[i];
@@ -5201,7 +5210,7 @@ IRSB* cheap_transformations (
       ppIRSB(bb);
    }
 
-   if (vex_control.iropt_register_updates != VexRegUpdAllregsAtEachInsn) {
+   if (vex_control.iropt_register_updates < VexRegUpdAllregsAtEachInsn) {
       redundant_put_removal_BB ( bb, preciseMemExnsFn );
    }
    if (iropt_verbose) {
@@ -5241,7 +5250,7 @@ IRSB* expensive_transformations( IRSB* bb )
    (void)do_cse_BB( bb );
    collapse_AddSub_chains_BB( bb );
    do_redundant_GetI_elimination( bb );
-   if (vex_control.iropt_register_updates != VexRegUpdAllregsAtEachInsn) {
+   if (vex_control.iropt_register_updates < VexRegUpdAllregsAtEachInsn) {
       do_redundant_PutI_elimination( bb );
    }
    do_deadcode_BB( bb );
@@ -5392,7 +5401,7 @@ IRSB* do_iropt_BB(
          work extra hard to get rid of it. */
       bb = cprop_BB(bb);
       bb = spec_helpers_BB ( bb, specHelper );
-      if (vex_control.iropt_register_updates != VexRegUpdAllregsAtEachInsn) {
+      if (vex_control.iropt_register_updates < VexRegUpdAllregsAtEachInsn) {
          redundant_put_removal_BB ( bb, preciseMemExnsFn );
       }
       do_cse_BB( bb );
index 9d7fcb092c6c991389929257aec93cba94683f02..a66a399801aba048bc89b486ddd19bc7286d4de9 100644 (file)
@@ -311,6 +311,10 @@ void LibVEX_default_VexAbiInfo ( /*OUT*/VexAbiInfo* vbi );
 /* VexRegisterUpdates specifies when to ensure that the guest state is
    up to date.
 
+   VexRegUpdSpAtMemAccess : all registers are updated at superblock
+   exits, SP is up to date at memory exception points. The SP is described
+   by the arch specific functions guest_<arch>_state_requires_precise_mem_exns.
+
    VexRegUpdUnwindregsAtMemAccess : registers needed to make a stack trace are
    up to date at memory exception points.  Typically, these are PC/SP/FP. The
    minimal registers are described by the arch specific functions
@@ -320,7 +324,8 @@ void LibVEX_default_VexAbiInfo ( /*OUT*/VexAbiInfo* vbi );
    points.
 
    VexRegUpdAllregsAtEachInsn : all registers up to date at each instruction. */
-typedef enum { VexRegUpdUnwindregsAtMemAccess,
+typedef enum { VexRegUpdSpAtMemAccess,
+               VexRegUpdUnwindregsAtMemAccess,
                VexRegUpdAllregsAtMemAccess,
                VexRegUpdAllregsAtEachInsn } VexRegisterUpdates;