]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Various changes needed to get Addrcheck supported:
authorJulian Seward <jseward@acm.org>
Thu, 28 Oct 2004 22:11:04 +0000 (22:11 +0000)
committerJulian Seward <jseward@acm.org>
Thu, 28 Oct 2004 22:11:04 +0000 (22:11 +0000)
* Rearrange iropt pipeline so that tree-building is
  no longer anything to do with optimisation, but is
  instead done post-instrumentation

* Allow two instrumentation functions to be passed to
  LibVEX_Translate, not one, so that valgrind can also
  do an sp-update pass

* Add a type VexGuestLayoutInfo for describing the guest
  state, for the benefit of instrumenters.

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

VEX/priv/guest-x86/gdefs.h
VEX/priv/guest-x86/ghelpers.c
VEX/priv/ir/irdefs.c
VEX/priv/ir/iropt.c
VEX/priv/ir/iropt.h
VEX/priv/main/vex_main.c
VEX/pub/libvex.h
VEX/pub/libvex_ir.h

index a7476a029159f616faf2eb055e2da89a5cb15706..ab43597f69fa09bf285695dfb6f5685922bde423 100644 (file)
@@ -42,6 +42,9 @@ IRExpr* x86guest_spechelper ( Char* function_name,
 extern 
 Bool guest_x86_state_requires_precise_mem_exns ( Int, Int );
 
+extern
+VexGuestLayoutInfo x86guest_layout;
+
 
 /*---------------------------------------------------------*/
 /*--- Condition code stuff                              ---*/
index 7e370bef2f5d4e349598477c9b9ef80494fb37df..b564bab3538f2c164485422fa6017f7a5ca79f11 100644 (file)
@@ -9,6 +9,7 @@
 #include "libvex_basictypes.h"
 #include "libvex_guest_x86.h"
 #include "libvex_ir.h"
+#include "libvex.h"
 
 #include "main/vex_util.h"
 #include "guest-x86/gdefs.h"
@@ -1495,6 +1496,12 @@ Bool guest_x86_state_requires_precise_mem_exns ( Int minoff,
 }
 
 
+VexGuestLayoutInfo 
+   x86guest_layout 
+      = { .offset_SP = offsetof(VexGuestX86State, guest_ESP),
+          .sizeof_SP   = 4 };
+
+
 /*---------------------------------------------------------------*/
 /*--- end                                guest-x86/ghelpers.c ---*/
 /*---------------------------------------------------------------*/
index 4a1acdabe4399ac65450b30be6be4dde9d1bfb47..935d36815664fc06bbfdbee67f16682f1a3c961a 100644 (file)
@@ -278,14 +278,16 @@ void ppIRDirty ( IRDirty* d )
    if (d->needsBBP)
       vex_printf(" NeedsBBP");
    if (d->mFx != Ifx_None) {
+      vex_printf(" ");
       ppIREffect(d->mFx);
       vex_printf("-mem(");
       ppIRExpr(d->mAddr);
-      vex_printf(",%d) ", d->mSize);
+      vex_printf(",%d)", d->mSize);
    }
    for (i = 0; i < d->nFxState; i++) {
+      vex_printf(" ");
       ppIREffect(d->fxState[i].fx);
-      vex_printf("-gst(%d,%d) ", d->fxState[i].offset, d->fxState[i].size);
+      vex_printf("-gst(%d,%d)", d->fxState[i].offset, d->fxState[i].size);
    }
    vex_printf(" ::: ");
    if (d->tmp != INVALID_IRTEMP) {
@@ -1506,12 +1508,22 @@ Int sizeofIRType ( IRType ty )
       case Ity_I8:  return 1;
       case Ity_I16: return 2;
       case Ity_I32: return 4;
+      case Ity_I64: return 8;
+      case Ity_F32: return 4;
       case Ity_F64: return 8;
       default: vex_printf("\n"); ppIRType(ty); vex_printf("\n");
                vpanic("sizeofIRType");
    }
 }
 
+IRExpr* mkIRExpr_HWord ( HWord hw )
+{
+   if (sizeof(HWord) == 4)
+      return IRExpr_Const(IRConst_U32((UInt)hw));
+   if (sizeof(HWord) == 8)
+      return IRExpr_Const(IRConst_U64((Long)hw));
+   vpanic("mkIRExpr_HWord");
+}
 
 /*---------------------------------------------------------------*/
 /*--- end                                         ir/irdefs.c ---*/
index 6ddd5766989b8fd3b976400e1f6c106689282059..b31814c3c48f713a2780249e87baa2f017ca2445 100644 (file)
@@ -151,13 +151,6 @@ static void addToHHW ( HashHW* h, HWord key, HWord val )
 /*--- Flattening out a BB into pure SSA form                  ---*/
 /*---------------------------------------------------------------*/
 
-inline
-static Bool isAtom ( IRExpr* e )
-{
-   return e->tag == Iex_Tmp || e->tag == Iex_Const;
-}
-
-
 /* Non-critical helper, heuristic for reducing the number of tmp-tmp
    copies made by flattening.  If in doubt return False. */
 
@@ -274,8 +267,15 @@ static void flatten_Stmt ( IRBB* bb, IRStmt* st )
    IRDirty *d,  *d2;
    switch (st->tag) {
       case Ist_Put:
-         e1 = flatten_Expr(bb, st->Ist.Put.data);
-         addStmtToIRBB(bb, IRStmt_Put(st->Ist.Put.offset, e1));
+         if (isAtom(st->Ist.Put.data)) {
+            /* optimisation to reduce the amount of heap wasted
+               by the flattener */
+            addStmtToIRBB(bb, st);
+         } else {
+            /* general case, always correct */
+            e1 = flatten_Expr(bb, st->Ist.Put.data);
+            addStmtToIRBB(bb, IRStmt_Put(st->Ist.Put.offset, e1));
+         }
          break;
       case Ist_PutI:
          e1 = flatten_Expr(bb, st->Ist.PutI.off);
@@ -945,7 +945,7 @@ static void addUses_Stmt ( Bool* set, IRStmt* st )
    E', delete the binding if it is not used.  Otherwise, add any temp
    uses to the set and keep on moving backwards. */
 
-static void dead_BB ( IRBB* bb )
+/* notstatic */ void do_deadcode_BB ( IRBB* bb )
 {
    Int     i;
    Int     n_tmps = bb->tyenv->types_used;
@@ -1736,7 +1736,7 @@ static void dumpInvalidated ( TmpInfo** env, IRBB* bb, /*INOUT*/Int* j )
 
 
 
-static void treebuild_BB ( IRBB* bb )
+/* notstatic */ void do_treebuild_BB ( IRBB* bb )
 {
    Int      i, j, k;
    Bool     invPut, invStore;
@@ -3102,14 +3102,14 @@ IRBB* cheap_transformations (
       ppIRBB(bb);
    }
 
-   dead_BB ( bb );
+   do_deadcode_BB ( bb );
    if (iropt_verbose) {
       vex_printf("\n========= DEAD\n\n" );
       ppIRBB(bb);
    }
 
    spec_helpers_BB ( bb, specHelper );
-   dead_BB ( bb );
+   do_deadcode_BB ( bb );
    if (iropt_verbose) {
       vex_printf("\n========= SPECd \n\n" );
       ppIRBB(bb);
@@ -3129,7 +3129,7 @@ IRBB* expensive_transformations( IRBB* bb )
    collapse_AddSub_chains_BB( bb );
    do_PutI_GetI_forwarding_BB( bb );
    do_redundant_PutI_elimination( bb );
-   dead_BB( bb );
+   do_deadcode_BB( bb );
    return flatten_BB( bb );
 }
 
@@ -3255,22 +3255,16 @@ IRBB* do_iropt_BB ( IRBB* bb0,
          } else {
             /* at least do CSE and dead code removal */
             cse_BB( bb );
-            dead_BB( bb );
+            do_deadcode_BB( bb );
          }
          if (0) vex_printf("vex iropt: unrolled a loop\n");
       }
 
    }
 
-   /* Finally, rebuild trees, for the benefit of instruction
-      selection. */
-   dead_BB(bb);
-   treebuild_BB( bb );
-   if (show_res || iropt_verbose) {
-      vex_printf("\n========= TREEd \n\n" );
-      ppIRBB(bb);
-   }
-
+   /* sigh; flatten the block out (yet again) for the benefit of
+      instrumenters. */
+   bb = flatten_BB( bb );
    return bb;
 }
 
index ec47b980635f0f0a16582333337dac01a0f52112..d5a30863bf797712c7a3e779746298db685039d4 100644 (file)
 #include "libvex_ir.h"
 #include "libvex.h"
 
+/* Top level optimiser entry point.  Returns a new BB.  Operates
+   under the control of the global "vex_control" struct. */
+extern 
+IRBB* do_iropt_BB ( IRBB* bb,
+                    IRExpr* (*specHelper) ( Char*, IRExpr**),
+                    Bool (*preciseMemExnsFn)(Int,Int),
+                    Addr64 guest_addr );
 
-extern IRBB* do_iropt_BB ( IRBB* bb,
-                           IRExpr* (*specHelper) ( Char*, IRExpr**),
-                           Bool (*preciseMemExnsFn)(Int,Int),
-                           Addr64 guest_addr );
+/* Do a dead-code removal pass, which is generally needed to avoid
+   crashing the tree-builder. bb is destructively modified. */
+extern
+void do_deadcode_BB ( IRBB* bb );
+
+/* The tree-builder.  Make maximal safe trees.  bb is destructively
+   modified. */
+extern
+void do_treebuild_BB ( IRBB* bb );
 
 /*---------------------------------------------------------------*/
 /*--- end                                          ir/iropt.h ---*/
index 0615ecf66f29ed3465bdc98076f790c128b13ec7..c1887dff7a5eded51a1c7e7e2a47c6a63f493022 100644 (file)
@@ -129,8 +129,9 @@ TranslateResult LibVEX_Translate (
    Int    host_bytes_size,
    /* OUT: how much of the output area is used. */
    Int* host_bytes_used,
-   /* IN: optionally, an instrumentation function. */
-   IRBB* (*instrument) ( IRBB* ),
+   /* IN: optionally, two instrumentation functions. */
+   IRBB* (*instrument1) ( IRBB*, VexGuestLayoutInfo* ),
+   IRBB* (*instrument2) ( IRBB*, VexGuestLayoutInfo* ),
    HWord (*tool_findhelper) ( Char* ),
    /* IN: optionally, an access check function for guest code. */
    Bool (*byte_accessible) ( Addr64 ),
@@ -158,14 +159,16 @@ TranslateResult LibVEX_Translate (
    IRExpr*      (*specHelper)  ( Char*, IRExpr** );
    Bool         (*preciseMemExnsFn) ( Int, Int );
 
-   Bool         host_is_bigendian = False;
-   IRBB*        irbb;
-   HInstrArray* vcode;
-   HInstrArray* rcode;
-   Int          i, j, k, out_used, saved_verbosity, guest_sizeB;
-   UChar        insn_bytes[32];
-   IRType       guest_word_size;
+   VexGuestLayoutInfo* guest_layout;
+   Bool                host_is_bigendian = False;
+   IRBB*               irbb;
+   HInstrArray*        vcode;
+   HInstrArray*        rcode;
+   Int                 i, j, k, out_used, saved_verbosity, guest_sizeB;
+   UChar               insn_bytes[32];
+   IRType              guest_word_size;
 
+   guest_layout           = NULL;
    available_real_regs    = NULL;
    n_available_real_regs  = 0;
    isMove                 = NULL;
@@ -219,6 +222,7 @@ TranslateResult LibVEX_Translate (
          specHelper       = x86guest_spechelper;
          guest_sizeB      = sizeof(VexGuestX86State);
         guest_word_size  = Ity_I32;
+         guest_layout     = &x86guest_layout;
          break;
       default:
          vpanic("LibVEX_Translate: unsupported guest insn set");
@@ -262,12 +266,17 @@ TranslateResult LibVEX_Translate (
    }
 
    /* Get the thing instrumented. */
-   if (instrument) {
-      irbb = (*instrument)(irbb);
+   if (instrument1)
+      irbb = (*instrument1)(irbb, guest_layout);
+   if (instrument2)
+      irbb = (*instrument2)(irbb, guest_layout);
+      
+   if (instrument1 || instrument2)
       sanityCheckIRBB(irbb, guest_word_size);
-   }
 
    /* Turn it into virtual-registerised code. */
+   do_deadcode_BB( irbb );
+   do_treebuild_BB( irbb );
    vcode = iselBB ( irbb, findHelper, tool_findhelper );
 
    if (vex_verbosity > 0) {
index fb5f3d6386fccf28cd19347663aa4ecc2afdd5d4..dd168407d76439c45fd15523685c55f091480d51 100644 (file)
@@ -91,6 +91,18 @@ extern void LibVEX_ClearTemporary ( Bool show_stats );
 extern void* LibVEX_Alloc ( Int nbytes );
 
 
+/* Describe the guest state enough that the instrumentation
+   functions can work. */
+
+typedef
+   struct {
+      /* Whereabouts is the stack pointer? */
+      Int offset_SP;
+      Int sizeof_SP; /* 4 or 8 */
+   }
+   VexGuestLayoutInfo;
+
+
 /* Translate a basic block. */
 
 typedef 
@@ -116,8 +128,9 @@ TranslateResult LibVEX_Translate (
    Int    host_bytes_size,
    /* OUT: how much of the output area is used. */
    Int* host_bytes_used,
-   /* IN: optionally, an instrumentation function. */
-   IRBB* (*instrument) ( IRBB* ),
+   /* IN: optionally, two instrumentation functions. */
+   IRBB* (*instrument1) ( IRBB*, VexGuestLayoutInfo* ),
+   IRBB* (*instrument2) ( IRBB*, VexGuestLayoutInfo* ),
    HWord (*tool_findhelper) ( Char* ),
    /* IN: optionally, an access check function for guest code. */
    Bool (*byte_accessible) ( Addr64 ),
index 8d09ea7feddeb9c3c503263c0479118fbff6c961..3bc311c03bd3315fb703c83910aabc93b52cc5b0 100644 (file)
@@ -416,6 +416,15 @@ extern IRExpr** mkIRExprVec_2 ( IRExpr* arg1, IRExpr* arg2 );
 extern IRExpr** sopyIRExprVec ( IRExpr** );
 extern IRExpr** dopyIRExprVec ( IRExpr** );
 
+/* Make a constant expression from the given host word,
+   taking into account of course the host word size. */
+extern IRExpr* mkIRExpr_HWord ( HWord );
+
+
+inline static Bool isAtom ( IRExpr* e ) {
+   return e->tag == Iex_Tmp || e->tag == Iex_Const;
+}
+
 
 /* ------------------ Dirty helper calls ------------------ */