IRSB* h_instrument ( VgCallbackClosure* closure, IRSB* sbIn, const VexGuestLayout* layout, const VexGuestExtents* vge, const VexArchInfo* archinfo_host, IRType gWordTy, IRType hWordTy ) { Bool verboze = 0||False; Int i /*, j*/; PCEnv pce; struct _SGEnv* sgenv; if (gWordTy != hWordTy) { /* We don't currently support this case. */ VG_(tool_panic)("host/guest word size mismatch"); } /* Check we're not completely nuts */ tl_assert(sizeof(UWord) == sizeof(void*)); tl_assert(sizeof(Word) == sizeof(void*)); tl_assert(sizeof(Addr) == sizeof(void*)); tl_assert(sizeof(ULong) == 8); tl_assert(sizeof(Long) == 8); tl_assert(sizeof(Addr) == sizeof(void*)); tl_assert(sizeof(UInt) == 4); tl_assert(sizeof(Int) == 4); /* Set up the running environment. Both .sb and .tmpMap are modified as we go along. Note that tmps are added to both .sb->tyenv and .tmpMap together, so the valid index-set for those two arrays should always be identical. */ VG_(memset)(&pce, 0, sizeof(pce)); pce.sb = deepCopyIRSBExceptStmts(sbIn); pce.trace = verboze; pce.hWordTy = hWordTy; pce.gWordTy = gWordTy; pce.guest_state_sizeB = layout->total_sizeB; pce.qmpMap = VG_(newXA)( VG_(malloc), "pc.h_instrument.1", VG_(free), sizeof(TempMapEnt)); for (i = 0; i < sbIn->tyenv->types_used; i++) { TempMapEnt ent; ent.kind = NonShad; ent.shadow = IRTemp_INVALID; VG_(addToXA)( pce.qmpMap, &ent ); } tl_assert( VG_(sizeXA)( pce.qmpMap ) == sbIn->tyenv->types_used ); /* Also set up for the sg_ instrumenter. See comments at the top of this instrumentation section for details. The two parameters constitute a closure, which sg_ can use to correctly generate new IRTemps as needed. */ sgenv = sg_instrument_init( for_sg__newIRTemp_cb, (void*)&pce ); /* Copy verbatim any IR preamble preceding the first IMark */ i = 0; while (i < sbIn->stmts_used && sbIn->stmts[i]->tag != Ist_IMark) { IRStmt* st = sbIn->stmts[i]; tl_assert(st); tl_assert(isFlatIRStmt(st)); stmt( 'C', &pce, sbIn->stmts[i] ); i++; } /* Iterate over the remaining stmts to generate instrumentation. */ tl_assert(sbIn->stmts_used > 0); tl_assert(i >= 0); tl_assert(i < sbIn->stmts_used); tl_assert(sbIn->stmts[i]->tag == Ist_IMark); for (/*use current i*/; i < sbIn->stmts_used; i++) { /* generate sg_ instrumentation for this stmt */ sg_instrument_IRStmt( sgenv, pce.sb, sbIn->stmts[i], layout, gWordTy, hWordTy ); stmt( 'C', &pce, sbIn->stmts[i] ); } /* generate sg_ instrumentation for the final jump */ sg_instrument_final_jump( sgenv, pce.sb, sbIn->next, sbIn->jumpkind, layout, gWordTy, hWordTy ); /* and finalise .. */ sg_instrument_fini( sgenv ); /* If this fails, there's been some serious snafu with tmp management, that should be investigated. */ tl_assert( VG_(sizeXA)( pce.qmpMap ) == pce.sb->tyenv->types_used ); VG_(deleteXA)( pce.qmpMap ); return pce.sb; }
IRSB* h_instrument ( VgCallbackClosure* closure, IRSB* sbIn, VexGuestLayout* layout, VexGuestExtents* vge, IRType gWordTy, IRType hWordTy ) { Bool verboze = 0||False; Int i ; PCEnv pce; struct _SGEnv* sgenv; if (gWordTy != hWordTy) { VG_(tool_panic)("host/guest word size mismatch"); } tl_assert(sizeof(UWord) == sizeof(void*)); tl_assert(sizeof(Word) == sizeof(void*)); tl_assert(sizeof(Addr) == sizeof(void*)); tl_assert(sizeof(ULong) == 8); tl_assert(sizeof(Long) == 8); tl_assert(sizeof(Addr64) == 8); tl_assert(sizeof(UInt) == 4); tl_assert(sizeof(Int) == 4); VG_(memset)(&pce, 0, sizeof(pce)); pce.sb = deepCopyIRSBExceptStmts(sbIn); pce.trace = verboze; pce.hWordTy = hWordTy; pce.gWordTy = gWordTy; pce.guest_state_sizeB = layout->total_sizeB; pce.qmpMap = VG_(newXA)( VG_(malloc), "pc.h_instrument.1", VG_(free), sizeof(TempMapEnt)); for (i = 0; i < sbIn->tyenv->types_used; i++) { TempMapEnt ent; ent.kind = NonShad; ent.shadow = IRTemp_INVALID; VG_(addToXA)( pce.qmpMap, &ent ); } tl_assert( VG_(sizeXA)( pce.qmpMap ) == sbIn->tyenv->types_used ); sgenv = sg_instrument_init( for_sg__newIRTemp_cb, (void*)&pce ); i = 0; while (i < sbIn->stmts_used && sbIn->stmts[i]->tag != Ist_IMark) { IRStmt* st = sbIn->stmts[i]; tl_assert(st); tl_assert(isFlatIRStmt(st)); stmt( 'C', &pce, sbIn->stmts[i] ); i++; } tl_assert(sbIn->stmts_used > 0); tl_assert(i >= 0); tl_assert(i < sbIn->stmts_used); tl_assert(sbIn->stmts[i]->tag == Ist_IMark); for (; i < sbIn->stmts_used; i++) { sg_instrument_IRStmt( sgenv, pce.sb, sbIn->stmts[i], layout, gWordTy, hWordTy ); stmt( 'C', &pce, sbIn->stmts[i] ); } sg_instrument_final_jump( sgenv, pce.sb, sbIn->next, sbIn->jumpkind, layout, gWordTy, hWordTy ); sg_instrument_fini( sgenv ); tl_assert( VG_(sizeXA)( pce.qmpMap ) == pce.sb->tyenv->types_used ); VG_(deleteXA)( pce.qmpMap ); return pce.sb; }