From: Julian Seward Date: Thu, 28 Oct 2004 22:11:04 +0000 (+0000) Subject: Various changes needed to get Addrcheck supported: X-Git-Tag: svn/VALGRIND_3_0_1^2~887 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=9393bef2ada1db0cebc8bb59336182ce0dc066c6;p=thirdparty%2Fvalgrind.git Various changes needed to get Addrcheck supported: * 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 --- diff --git a/VEX/priv/guest-x86/gdefs.h b/VEX/priv/guest-x86/gdefs.h index a7476a0291..ab43597f69 100644 --- a/VEX/priv/guest-x86/gdefs.h +++ b/VEX/priv/guest-x86/gdefs.h @@ -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 ---*/ diff --git a/VEX/priv/guest-x86/ghelpers.c b/VEX/priv/guest-x86/ghelpers.c index 7e370bef2f..b564bab353 100644 --- a/VEX/priv/guest-x86/ghelpers.c +++ b/VEX/priv/guest-x86/ghelpers.c @@ -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 ---*/ /*---------------------------------------------------------------*/ diff --git a/VEX/priv/ir/irdefs.c b/VEX/priv/ir/irdefs.c index 4a1acdabe4..935d368156 100644 --- a/VEX/priv/ir/irdefs.c +++ b/VEX/priv/ir/irdefs.c @@ -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 ---*/ diff --git a/VEX/priv/ir/iropt.c b/VEX/priv/ir/iropt.c index 6ddd576698..b31814c3c4 100644 --- a/VEX/priv/ir/iropt.c +++ b/VEX/priv/ir/iropt.c @@ -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; } diff --git a/VEX/priv/ir/iropt.h b/VEX/priv/ir/iropt.h index ec47b98063..d5a30863bf 100644 --- a/VEX/priv/ir/iropt.h +++ b/VEX/priv/ir/iropt.h @@ -10,11 +10,23 @@ #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 ---*/ diff --git a/VEX/priv/main/vex_main.c b/VEX/priv/main/vex_main.c index 0615ecf66f..c1887dff7a 100644 --- a/VEX/priv/main/vex_main.c +++ b/VEX/priv/main/vex_main.c @@ -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) { diff --git a/VEX/pub/libvex.h b/VEX/pub/libvex.h index fb5f3d6386..dd168407d7 100644 --- a/VEX/pub/libvex.h +++ b/VEX/pub/libvex.h @@ -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 ), diff --git a/VEX/pub/libvex_ir.h b/VEX/pub/libvex_ir.h index 8d09ea7fed..3bc311c03b 100644 --- a/VEX/pub/libvex_ir.h +++ b/VEX/pub/libvex_ir.h @@ -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 ------------------ */