From 53131dfa1ed44ae8cf4bc2ba2db3cc65ad7ff768 Mon Sep 17 00:00:00 2001 From: Julian Seward Date: Tue, 17 Jan 2006 01:48:46 +0000 Subject: [PATCH] Two different sets of changes (hard to disentangle): * Remove from Vex all knowledge about function wrapping. All the IR trickery needed can be done on the Valgrind side, by giving LibVEX_Translate yet another callback. This one is called just before any instructions are disassembled into IR, allowing Valgrind to insert its own IR preamble if it wants. It also allows Valgrind to inhibit any insn disassembly for the block. Effect is that this allows Valgrind to provide any old IR for a given translation, and have Vex process it as usual, yet that IR can be anything and does not have to bear any relationship to any guest insns anywhere. * Consistently pass a void* closure argument as the first parameter to all Valgrind-supplied callbacks. This gets rid of various nasty hacks at the Valgrind side to do with passing instance-specific values to callbacks. git-svn-id: svn://svn.valgrind.org/vex/trunk@1540 --- VEX/priv/guest-amd64/gdefs.h | 3 +- VEX/priv/guest-amd64/toIR.c | 14 ++++--- VEX/priv/guest-generic/bb_to_IR.c | 70 ++++++++++++++++--------------- VEX/priv/guest-generic/bb_to_IR.h | 15 ++++--- VEX/priv/guest-ppc/gdefs.h | 3 +- VEX/priv/guest-ppc/toIR.c | 23 ++++++---- VEX/priv/guest-x86/gdefs.h | 3 +- VEX/priv/guest-x86/toIR.c | 16 +++---- VEX/priv/main/vex_main.c | 25 +++++------ VEX/pub/libvex.h | 40 ++++++++++++------ VEX/test_main.c | 6 +-- 11 files changed, 124 insertions(+), 94 deletions(-) diff --git a/VEX/priv/guest-amd64/gdefs.h b/VEX/priv/guest-amd64/gdefs.h index 7d2e9f6d9f..cae514240d 100644 --- a/VEX/priv/guest-amd64/gdefs.h +++ b/VEX/priv/guest-amd64/gdefs.h @@ -59,7 +59,8 @@ extern DisResult disInstr_AMD64 ( IRBB* irbb, Bool put_IP, - Bool (*resteerOkFn) ( Addr64 ), + Bool (*resteerOkFn) ( void*, Addr64 ), + void* callback_opaque, UChar* guest_code, Long delta, Addr64 guest_IP, diff --git a/VEX/priv/guest-amd64/toIR.c b/VEX/priv/guest-amd64/toIR.c index 079e10cf61..6dcee7b2a7 100644 --- a/VEX/priv/guest-amd64/toIR.c +++ b/VEX/priv/guest-amd64/toIR.c @@ -7927,7 +7927,8 @@ static IRExpr* mk64from16s ( IRTemp t3, IRTemp t2, static DisResult disInstr_AMD64_WRK ( Bool put_IP, - Bool (*resteerOkFn) ( Addr64 ), + Bool (*resteerOkFn) ( /*opaque*/void*, Addr64 ), + void* callback_opaque, Long delta64, VexArchInfo* archinfo ) @@ -11543,7 +11544,7 @@ DisResult disInstr_AMD64_WRK ( putIReg64(R_RSP, mkexpr(t1)); storeLE( mkexpr(t1), mkU64(guest_RIP_bbstart+delta)); make_redzone_AbiHint(t1, "call-d32"); - if (resteerOkFn((Addr64)d64)) { + if (resteerOkFn( callback_opaque, (Addr64)d64) ) { /* follow into the call target. */ dres.whatNext = Dis_Resteer; dres.continueAt = d64; @@ -11755,7 +11756,7 @@ DisResult disInstr_AMD64_WRK ( goto decode_failure; /* JRS added 2004 July 11 */ d64 = (guest_RIP_bbstart+delta+1) + getSDisp8(delta); delta++; - if (resteerOkFn(d64)) { + if (resteerOkFn(callback_opaque,d64)) { dres.whatNext = Dis_Resteer; dres.continueAt = d64; } else { @@ -11771,7 +11772,7 @@ DisResult disInstr_AMD64_WRK ( goto decode_failure; /* JRS added 2004 July 11 */ d64 = (guest_RIP_bbstart+delta+sz) + getSDisp(sz,delta); delta += sz; - if (resteerOkFn(d64)) { + if (resteerOkFn(callback_opaque,d64)) { dres.whatNext = Dis_Resteer; dres.continueAt = d64; } else { @@ -13639,7 +13640,8 @@ DisResult disInstr_AMD64_WRK ( DisResult disInstr_AMD64 ( IRBB* irbb_IN, Bool put_IP, - Bool (*resteerOkFn) ( Addr64 ), + Bool (*resteerOkFn) ( void*, Addr64 ), + void* callback_opaque, UChar* guest_code_IN, Long delta, Addr64 guest_IP, @@ -13659,7 +13661,7 @@ DisResult disInstr_AMD64 ( IRBB* irbb_IN, guest_RIP_next_assumed = 0; guest_RIP_next_mustcheck = False; - dres = disInstr_AMD64_WRK ( put_IP, resteerOkFn, + dres = disInstr_AMD64_WRK ( put_IP, resteerOkFn, callback_opaque, delta, archinfo ); /* If disInstr_AMD64_WRK tried to figure out the next rip, check it diff --git a/VEX/priv/guest-generic/bb_to_IR.c b/VEX/priv/guest-generic/bb_to_IR.c index 290691b74b..ca3d9f9047 100644 --- a/VEX/priv/guest-generic/bb_to_IR.c +++ b/VEX/priv/guest-generic/bb_to_IR.c @@ -57,7 +57,9 @@ __attribute((regparm(2))) static UInt genericg_compute_adler32 ( HWord addr, HWord len ); /* Small helpers */ -static Bool const_False ( Addr64 a ) { return False; } +static Bool const_False ( void* callback_opaque, Addr64 a ) { + return False; +} /* Disassemble a complete basic block, starting at guest_IP_start, returning a new IRBB. The disassembler may chase across basic @@ -73,29 +75,36 @@ static Bool const_False ( Addr64 a ) { return False; } do_self_check indicates that the caller needs a self-checking translation. - do_set_NRADDR indicates that the unredirected guest address for - this BB should be written to the guest's NRADDR pseudo-register. - - offB_TIADDR, offB_TILEN and offB_NRADDR are the offsets of - guest_TIADDR, guest_TILEN and guest_NRADDR. Since this routine has - to work for any guest state, without knowing what it is, those - offsets have to passed in. + preamble_function is a callback which allows the caller to add + its own IR preamble (following the self-check, if any). May be + NULL. If non-NULL, the IRBB under construction is handed to + this function, which presumably adds IR statements to it. The + callback may optionally complete the block and direct bb_to_IR + not to disassemble any instructions into it; this is indicated + by the callback returning True. + + offB_TIADDR and offB_TILEN are the offsets of guest_TIADDR and + guest_TILEN. Since this routine has to work for any guest state, + without knowing what it is, those offsets have to passed in. + + callback_opaque is a caller-supplied pointer to data which the + callbacks may want to see. Vex has no idea what it is. + (In fact it's a VgInstrumentClosure.) */ IRBB* bb_to_IR ( /*OUT*/VexGuestExtents* vge, + /*IN*/ void* callback_opaque, /*IN*/ DisOneInstrFn dis_instr_fn, /*IN*/ UChar* guest_code, /*IN*/ Addr64 guest_IP_bbstart, - /*IN*/ Addr64 guest_IP_bbstart_noredir, - /*IN*/ Bool (*chase_into_ok)(Addr64), + /*IN*/ Bool (*chase_into_ok)(void*,Addr64), /*IN*/ Bool host_bigendian, /*IN*/ VexArchInfo* archinfo_guest, /*IN*/ IRType guest_word_type, /*IN*/ Bool do_self_check, - /*IN*/ Bool do_set_NRADDR, + /*IN*/ Bool (*preamble_function)(void*,IRBB*), /*IN*/ Int offB_TISTART, - /*IN*/ Int offB_TILEN, - /*IN*/ Int offB_NRADDR ) + /*IN*/ Int offB_TILEN ) { Long delta; Int i, n_instrs, first_stmt_idx; @@ -108,9 +117,8 @@ IRBB* bb_to_IR ( /*OUT*/VexGuestExtents* vge, IRBB* irbb; Addr64 guest_IP_curr_instr; IRConst* guest_IP_bbstart_IRConst = NULL; - IRConst* guest_IP_bbstart_noredir_IRConst = NULL; - Bool (*resteerOKfn)(Addr64) = NULL; + Bool (*resteerOKfn)(void*,Addr64) = NULL; debug_print = toBool(vex_traceflags & VEX_TRACE_FE); @@ -149,13 +157,6 @@ IRBB* bb_to_IR ( /*OUT*/VexGuestExtents* vge, : IRConst_U64(guest_IP_bbstart); } - if (do_set_NRADDR) { - guest_IP_bbstart_noredir_IRConst - = guest_word_type==Ity_I32 - ? IRConst_U32(toUInt(guest_IP_bbstart_noredir)) - : IRConst_U64(guest_IP_bbstart_noredir); - } - /* If asked to make a self-checking translation, leave 5 spaces in which to put the check statements. We'll fill them in later when we know the length and adler32 of the area to check. */ @@ -168,16 +169,18 @@ IRBB* bb_to_IR ( /*OUT*/VexGuestExtents* vge, addStmtToIRBB( irbb, IRStmt_NoOp() ); } - /* Set guest_NRADDR if asked to. This records the unredirected - guest address of this bb, so that it can later be read (and so - used by a function wrapper to get to the function itself. */ - if (do_set_NRADDR) { - /* set guest_NRADDR to guest_IP_bbstart_noredir */ - addStmtToIRBB( - irbb, - IRStmt_Put( offB_NRADDR, - IRExpr_Const(guest_IP_bbstart_noredir_IRConst)) - ); + /* If the caller supplied a function to add its own preamble, use + it now. */ + if (preamble_function) { + Bool stopNow = preamble_function( callback_opaque, irbb ); + if (stopNow) { + /* The callback has completed the IR block without any guest + insns being disassembled into it, so just return it at + this point, even if a self-check was requested - as there + is nothing to self-check. The five self-check no-ops will + still be in place, but they are harmless. */ + return irbb; + } } /* Process instructions. */ @@ -224,6 +227,7 @@ IRBB* bb_to_IR ( /*OUT*/VexGuestExtents* vge, dres = dis_instr_fn ( irbb, need_to_put_IP, resteerOKfn, + callback_opaque, guest_code, delta, guest_IP_curr_instr, @@ -308,7 +312,7 @@ IRBB* bb_to_IR ( /*OUT*/VexGuestExtents* vge, vassert(resteerOK); vassert(irbb->next == NULL); /* figure out a new delta to continue at. */ - vassert(resteerOKfn(dres.continueAt)); + vassert(resteerOKfn(callback_opaque,dres.continueAt)); delta = dres.continueAt - guest_IP_bbstart; /* we now have to start a new extent slot. */ vge->n_used++; diff --git a/VEX/priv/guest-generic/bb_to_IR.h b/VEX/priv/guest-generic/bb_to_IR.h index 94d2ddef9b..04af2eb4af 100644 --- a/VEX/priv/guest-generic/bb_to_IR.h +++ b/VEX/priv/guest-generic/bb_to_IR.h @@ -124,7 +124,11 @@ typedef /*IN*/ Bool put_IP, /* Return True iff resteering to the given addr is allowed */ - /*IN*/ Bool (*resteerOkFn) ( Addr64 ), + /*IN*/ Bool (*resteerOkFn) ( /*opaque*/void*, Addr64 ), + + /* Vex-opaque data passed to all caller (valgrind) supplied + callbacks. */ + /*IN*/ void* callback_opaque, /* Where is the guest code? */ /*IN*/ UChar* guest_code, @@ -151,19 +155,18 @@ typedef /* See detailed comment in bb_to_IR.c. */ extern IRBB* bb_to_IR ( /*OUT*/VexGuestExtents* vge, + /*IN*/ void* closure_opaque, /*IN*/ DisOneInstrFn dis_instr_fn, /*IN*/ UChar* guest_code, /*IN*/ Addr64 guest_IP_bbstart, - /*IN*/ Addr64 guest_IP_bbstart_noredir, - /*IN*/ Bool (*chase_into_ok)(Addr64), + /*IN*/ Bool (*chase_into_ok)(void*,Addr64), /*IN*/ Bool host_bigendian, /*IN*/ VexArchInfo* archinfo_guest, /*IN*/ IRType guest_word_type, /*IN*/ Bool do_self_check, - /*IN*/ Bool do_set_NRADDR, + /*IN*/ Bool (*preamble_function)(void*,IRBB*), /*IN*/ Int offB_TISTART, - /*IN*/ Int offB_TILEN, - /*IN*/ Int offB_NRADDR ); + /*IN*/ Int offB_TILEN ); #endif /* ndef GENERIC_BB_TO_IR_H */ diff --git a/VEX/priv/guest-ppc/gdefs.h b/VEX/priv/guest-ppc/gdefs.h index c77dccde72..d427f93f40 100644 --- a/VEX/priv/guest-ppc/gdefs.h +++ b/VEX/priv/guest-ppc/gdefs.h @@ -60,7 +60,8 @@ extern DisResult disInstr_PPC ( IRBB* irbb, Bool put_IP, - Bool (*resteerOkFn) ( Addr64 ), + Bool (*resteerOkFn) ( void*, Addr64 ), + void* callback_opaque, UChar* guest_code, Long delta, Addr64 guest_IP, diff --git a/VEX/priv/guest-ppc/toIR.c b/VEX/priv/guest-ppc/toIR.c index dafbffc8dd..7e7cc5bc3e 100644 --- a/VEX/priv/guest-ppc/toIR.c +++ b/VEX/priv/guest-ppc/toIR.c @@ -358,7 +358,7 @@ static UInt MASK32( UInt begin, UInt end ) vassert(begin < 32); vassert(end < 32); UInt m1 = ((UInt)(-1)) << begin; - UInt m2 = ((UInt)(-1)) << (end + 1); + UInt m2 = ((UInt)(-1)) << end << 1; UInt mask = m1 ^ m2; if (begin > end) mask = ~mask; // wrap mask return mask; @@ -370,7 +370,7 @@ static ULong MASK64( UInt begin, UInt end ) vassert(begin < 64); vassert(end < 64); ULong m1 = ((ULong)(-1)) << begin; - ULong m2 = ((ULong)(-1)) << (end + 1); + ULong m2 = ((ULong)(-1)) << end << 1; ULong mask = m1 ^ m2; if (begin > end) mask = ~mask; // wrap mask return mask; @@ -4144,7 +4144,8 @@ static IRExpr* /* :: Ity_I32 */ branch_cond_ok( UInt BO, UInt BI ) */ static Bool dis_branch ( UInt theInstr, /*OUT*/DisResult* dres, - Bool (*resteerOkFn)(Addr64) ) + Bool (*resteerOkFn)(void*,Addr64), + void* callback_opaque ) { UChar opc1 = ifieldOPC(theInstr); UChar BO = ifieldRegDS(theInstr); @@ -4195,7 +4196,7 @@ static Bool dis_branch ( UInt theInstr, if (flag_LK) putGST( PPC_GST_LR, e_nia ); - if (resteerOkFn(tgt)) { + if (resteerOkFn( callback_opaque, tgt )) { dres->whatNext = Dis_Resteer; dres->continueAt = tgt; } else { @@ -8341,7 +8342,8 @@ static Bool dis_av_fp_convert ( UInt theInstr ) static DisResult disInstr_PPC_WRK ( Bool put_IP, - Bool (*resteerOkFn) ( Addr64 ), + Bool (*resteerOkFn) ( /*opaque*/void*, Addr64 ), + void* callback_opaque, Long delta64, VexArchInfo* archinfo ) @@ -8498,7 +8500,8 @@ DisResult disInstr_PPC_WRK ( /* Branch Instructions */ case 0x12: case 0x10: // b, bc - if (dis_branch(theInstr, &dres, resteerOkFn)) goto decode_success; + if (dis_branch(theInstr, &dres, resteerOkFn, callback_opaque)) + goto decode_success; goto decode_failure; /* System Linkage Instructions */ @@ -8644,7 +8647,8 @@ DisResult disInstr_PPC_WRK ( /* Branch Instructions */ case 0x210: case 0x010: // bcctr, bclr - if (dis_branch(theInstr, &dres, resteerOkFn)) goto decode_success; + if (dis_branch(theInstr, &dres, resteerOkFn, callback_opaque)) + goto decode_success; goto decode_failure; /* Memory Synchronization Instructions */ @@ -9057,7 +9061,8 @@ DisResult disInstr_PPC_WRK ( DisResult disInstr_PPC ( IRBB* irbb_IN, Bool put_IP, - Bool (*resteerOkFn) ( Addr64 ), + Bool (*resteerOkFn) ( void*, Addr64 ), + void* callback_opaque, UChar* guest_code_IN, Long delta, Addr64 guest_IP, @@ -9093,7 +9098,7 @@ DisResult disInstr_PPC ( IRBB* irbb_IN, guest_CIA_curr_instr = mkSzAddr(ty, guest_IP); guest_CIA_bbstart = mkSzAddr(ty, guest_IP - delta); - dres = disInstr_PPC_WRK ( put_IP, resteerOkFn, + dres = disInstr_PPC_WRK ( put_IP, resteerOkFn, callback_opaque, delta, archinfo ); return dres; diff --git a/VEX/priv/guest-x86/gdefs.h b/VEX/priv/guest-x86/gdefs.h index 235befc19b..d41b5ffa1f 100644 --- a/VEX/priv/guest-x86/gdefs.h +++ b/VEX/priv/guest-x86/gdefs.h @@ -59,7 +59,8 @@ extern DisResult disInstr_X86 ( IRBB* irbb, Bool put_IP, - Bool (*resteerOkFn) ( Addr64 ), + Bool (*resteerOkFn) ( void*, Addr64 ), + void* callback_opaque, UChar* guest_code, Long delta, Addr64 guest_IP, diff --git a/VEX/priv/guest-x86/toIR.c b/VEX/priv/guest-x86/toIR.c index 38c925eca9..08cc5defc2 100644 --- a/VEX/priv/guest-x86/toIR.c +++ b/VEX/priv/guest-x86/toIR.c @@ -6994,7 +6994,8 @@ static IRExpr* mk64from16s ( IRTemp t3, IRTemp t2, static DisResult disInstr_X86_WRK ( Bool put_IP, - Bool (*resteerOkFn) ( Addr64 ), + Bool (*resteerOkFn) ( /*opaque*/void*, Addr64 ), + void* callback_opaque, Long delta64, VexArchInfo* archinfo ) @@ -10586,7 +10587,7 @@ DisResult disInstr_X86_WRK ( assign(t1, binop(Iop_Sub32, getIReg(4,R_ESP), mkU32(4))); putIReg(4, R_ESP, mkexpr(t1)); storeLE( mkexpr(t1), mkU32(guest_EIP_bbstart+delta)); - if (resteerOkFn((Addr64)(Addr32)d32)) { + if (resteerOkFn( callback_opaque, (Addr64)(Addr32)d32 )) { /* follow into the call target. */ dres.whatNext = Dis_Resteer; dres.continueAt = (Addr64)(Addr32)d32; @@ -10807,7 +10808,7 @@ DisResult disInstr_X86_WRK ( case 0xEB: /* Jb (jump, byte offset) */ d32 = (((Addr32)guest_EIP_bbstart)+delta+1) + getSDisp8(delta); delta++; - if (resteerOkFn((Addr64)(Addr32)d32)) { + if (resteerOkFn( callback_opaque, (Addr64)(Addr32)d32) ) { dres.whatNext = Dis_Resteer; dres.continueAt = (Addr64)(Addr32)d32; } else { @@ -10821,7 +10822,7 @@ DisResult disInstr_X86_WRK ( vassert(sz == 4); /* JRS added 2004 July 11 */ d32 = (((Addr32)guest_EIP_bbstart)+delta+sz) + getSDisp(sz,delta); delta += sz; - if (resteerOkFn((Addr64)(Addr32)d32)) { + if (resteerOkFn( callback_opaque, (Addr64)(Addr32)d32) ) { dres.whatNext = Dis_Resteer; dres.continueAt = (Addr64)(Addr32)d32; } else { @@ -10849,7 +10850,7 @@ DisResult disInstr_X86_WRK ( case 0x7F: /* JGb/JNLEb (jump greater) */ d32 = (((Addr32)guest_EIP_bbstart)+delta+1) + getSDisp8(delta); delta++; - if (0 && resteerOkFn((Addr64)(Addr32)d32)) { + if (0 && resteerOkFn( callback_opaque, (Addr64)(Addr32)d32) ) { /* Unused experimental hack: speculatively follow one arm of a conditional branch. */ /* Assume the branch is taken. So we need to emit a @@ -12574,7 +12575,8 @@ DisResult disInstr_X86_WRK ( DisResult disInstr_X86 ( IRBB* irbb_IN, Bool put_IP, - Bool (*resteerOkFn) ( Addr64 ), + Bool (*resteerOkFn) ( void*, Addr64 ), + void* callback_opaque, UChar* guest_code_IN, Long delta, Addr64 guest_IP, @@ -12590,7 +12592,7 @@ DisResult disInstr_X86 ( IRBB* irbb_IN, guest_EIP_curr_instr = (Addr32)guest_IP; guest_EIP_bbstart = (Addr32)toUInt(guest_IP - delta); - dres = disInstr_X86_WRK ( put_IP, resteerOkFn, + dres = disInstr_X86_WRK ( put_IP, resteerOkFn, callback_opaque, delta, archinfo ); return dres; diff --git a/VEX/priv/main/vex_main.c b/VEX/priv/main/vex_main.c index a2986d3ac5..311f2845e9 100644 --- a/VEX/priv/main/vex_main.c +++ b/VEX/priv/main/vex_main.c @@ -200,7 +200,7 @@ VexTranslateResult LibVEX_Translate ( VexTranslateArgs* vta ) HInstrArray* vcode; HInstrArray* rcode; Int i, j, k, out_used, guest_sizeB; - Int offB_TISTART, offB_TILEN, offB_NRADDR; + Int offB_TISTART, offB_TILEN; UChar insn_bytes[32]; IRType guest_word_type; IRType host_word_type; @@ -226,7 +226,6 @@ VexTranslateResult LibVEX_Translate ( VexTranslateArgs* vta ) offB_TISTART = 0; offB_TILEN = 0; mode64 = False; - offB_NRADDR = 0; vex_traceflags = vta->traceflags; @@ -336,7 +335,6 @@ VexTranslateResult LibVEX_Translate ( VexTranslateArgs* vta ) guest_layout = &x86guest_layout; offB_TISTART = offsetof(VexGuestX86State,guest_TISTART); offB_TILEN = offsetof(VexGuestX86State,guest_TILEN); - offB_NRADDR = offsetof(VexGuestX86State,guest_NRADDR); vassert(vta->archinfo_guest.subarch == VexSubArchX86_sse0 || vta->archinfo_guest.subarch == VexSubArchX86_sse1 || vta->archinfo_guest.subarch == VexSubArchX86_sse2); @@ -355,7 +353,6 @@ VexTranslateResult LibVEX_Translate ( VexTranslateArgs* vta ) guest_layout = &amd64guest_layout; offB_TISTART = offsetof(VexGuestAMD64State,guest_TISTART); offB_TILEN = offsetof(VexGuestAMD64State,guest_TILEN); - offB_NRADDR = offsetof(VexGuestAMD64State,guest_NRADDR); vassert(vta->archinfo_guest.subarch == VexSubArch_NONE); vassert(0 == sizeof(VexGuestAMD64State) % 8); vassert(sizeof( ((VexGuestAMD64State*)0)->guest_TISTART ) == 8); @@ -372,7 +369,6 @@ VexTranslateResult LibVEX_Translate ( VexTranslateArgs* vta ) guest_layout = &armGuest_layout; offB_TISTART = 0; /* hack ... arm has bitrot */ offB_TILEN = 0; /* hack ... arm has bitrot */ - offB_NRADDR = 0; /* hack ... arm has bitrot */ vassert(vta->archinfo_guest.subarch == VexSubArchARM_v4); break; @@ -385,7 +381,6 @@ VexTranslateResult LibVEX_Translate ( VexTranslateArgs* vta ) guest_layout = &ppc32Guest_layout; offB_TISTART = offsetof(VexGuestPPC32State,guest_TISTART); offB_TILEN = offsetof(VexGuestPPC32State,guest_TILEN); - offB_NRADDR = offsetof(VexGuestPPC32State,guest_NRADDR); vassert(vta->archinfo_guest.subarch == VexSubArchPPC32_I || vta->archinfo_guest.subarch == VexSubArchPPC32_FI || vta->archinfo_guest.subarch == VexSubArchPPC32_VFI); @@ -408,7 +403,8 @@ VexTranslateResult LibVEX_Translate ( VexTranslateArgs* vta ) || vta->archinfo_guest.subarch == VexSubArchPPC64_VFI); vassert(0 == sizeof(VexGuestPPC64State) % 16); vassert(sizeof( ((VexGuestPPC64State*)0)->guest_TISTART ) == 8); - vassert(sizeof( ((VexGuestPPC64State*)0)->guest_TILEN ) == 8); + vassert(sizeof( ((VexGuestPPC64State*)0)->guest_TILEN ) == 8); + vassert(sizeof( ((VexGuestPPC64State*)0)->guest_NRADDR ) == 8); break; default: @@ -431,19 +427,18 @@ VexTranslateResult LibVEX_Translate ( VexTranslateArgs* vta ) "------------------------\n\n"); irbb = bb_to_IR ( vta->guest_extents, + vta->callback_opaque, disInstrFn, vta->guest_bytes, vta->guest_bytes_addr, - vta->guest_bytes_addr_noredir, vta->chase_into_ok, host_is_bigendian, &vta->archinfo_guest, guest_word_type, vta->do_self_check, - vta->do_set_NRADDR, + vta->preamble_function, offB_TISTART, - offB_TILEN, - offB_NRADDR ); + offB_TILEN ); vexAllocSanityCheck(); @@ -499,15 +494,15 @@ VexTranslateResult LibVEX_Translate ( VexTranslateArgs* vta ) /* Get the thing instrumented. */ if (vta->instrument1) - irbb = vta->instrument1(irbb, guest_layout, - vta->guest_bytes_addr_noredir, + irbb = vta->instrument1(vta->callback_opaque, + irbb, guest_layout, vta->guest_extents, guest_word_type, host_word_type); vexAllocSanityCheck(); if (vta->instrument2) - irbb = vta->instrument2(irbb, guest_layout, - vta->guest_bytes_addr_noredir, + irbb = vta->instrument2(vta->callback_opaque, + irbb, guest_layout, vta->guest_extents, guest_word_type, host_word_type); diff --git a/VEX/pub/libvex.h b/VEX/pub/libvex.h index 73eeb2bf13..5dfc5a65fb 100644 --- a/VEX/pub/libvex.h +++ b/VEX/pub/libvex.h @@ -310,20 +310,23 @@ typedef VexArch arch_host; VexArchInfo archinfo_host; + /* IN: an opaque value which is passed as the first arg to all + callback functions supplied in this struct. Vex has no idea + what's at the other end of this pointer. */ + void* callback_opaque; + /* IN: the block to translate, and its guest address. */ /* where are the actual bytes in the host's address space? */ UChar* guest_bytes; /* where do the bytes really come from in the guest's aspace? - This is the post-redirection guest address. */ + This is the post-redirection guest address. Not that Vex + understands anything about redirection; that is all done on + the Valgrind side. */ Addr64 guest_bytes_addr; - /* where do the bytes claim to come from in the guest address - space? (what guest entry point address do they correspond - to?) This is the pre-redirection guest address. */ - Addr64 guest_bytes_addr_noredir; /* Is it OK to chase into this guest address? May not be NULL. */ - Bool (*chase_into_ok) ( Addr64 ); + Bool (*chase_into_ok) ( /*callback_opaque*/void*, Addr64 ); /* OUT: which bits of guest code actually got translated */ VexGuestExtents* guest_extents; @@ -336,17 +339,30 @@ typedef /* IN: optionally, two instrumentation functions. May be NULL. */ - IRBB* (*instrument1) ( IRBB*, VexGuestLayout*, - Addr64, VexGuestExtents*, + IRBB* (*instrument1) ( /*callback_opaque*/void*, + IRBB*, + VexGuestLayout*, + VexGuestExtents*, IRType gWordTy, IRType hWordTy ); - IRBB* (*instrument2) ( IRBB*, VexGuestLayout*, - Addr64, VexGuestExtents*, + IRBB* (*instrument2) ( /*callback_opaque*/void*, + IRBB*, + VexGuestLayout*, + VexGuestExtents*, IRType gWordTy, IRType hWordTy ); /* IN: should this translation be self-checking? default: False */ Bool do_self_check; - /* IN: should this translation set guest_NRADDR? */ - Bool do_set_NRADDR; + + /* IN: optionally, a callback which allows the caller to add its + own IR preamble following the self-check and any other + VEX-generated preamble, if any. May be NULL. If non-NULL, + the IRBB under construction is handed to this function, which + presumably adds IR statements to it. The callback may + optionally complete the block and direct bb_to_IR not to + disassemble any instructions into it; this is indicated by + the callback returning True. + */ + Bool (*preamble_function)(/*callback_opaque*/void*, IRBB*); /* IN: debug: trace vex activity at various points */ Int traceflags; diff --git a/VEX/test_main.c b/VEX/test_main.c index ddc0bb14b9..0ccfec64f0 100644 --- a/VEX/test_main.c +++ b/VEX/test_main.c @@ -53,7 +53,7 @@ static IRBB* ac_instrument ( IRBB*, VexGuestLayout*, IRType ); static IRBB* mc_instrument ( IRBB*, VexGuestLayout*, IRType, IRType ); #endif -static Bool chase_into_not_ok ( Addr64 dst ) { return False; } +static Bool chase_into_not_ok ( void* opaque, Addr64 dst ) { return False; } int main ( int argc, char** argv ) { @@ -155,7 +155,7 @@ int main ( int argc, char** argv ) #endif vta.guest_bytes = origbuf; vta.guest_bytes_addr = (Addr64)orig_addr; - vta.guest_bytes_addr_noredir = (Addr64)orig_addr; + vta.callback_opaque = NULL; vta.chase_into_ok = chase_into_not_ok; vta.guest_extents = &vge; vta.host_bytes = transbuf; @@ -174,7 +174,7 @@ int main ( int argc, char** argv ) vta.instrument2 = NULL; #endif vta.do_self_check = False; - vta.do_set_NRADDR = False; + vta.preamble_function = NULL; vta.traceflags = TEST_FLAGS; #if 1 /* x86, amd64 hosts */ vta.dispatch = (void*)0x12345678; -- 2.47.3