/* instruments a Binary Operation Expression in a Ist_WrTmp statement */ static void instrument_Triop(IRSB* sb, IRStmt* st, Addr64 cia) { Char thisFct[]="instrument_Triop"; IRDirty* di; IRExpr** argv; IRExpr *op = st->Ist.WrTmp.data; IRExpr* oa_event_expr; IROp irop=op->Iex.Triop.details->op; void* f=callbackFromIROp(irop); if (f == NULL) return; OA_InstrumentContext inscon=contextFor(cia, irop); if (not_worth_watching(inscon)) return; // filter events that can't be attached to source-code location updateStats(inscon->op); oa_event_expr = mkIRExpr_HWord( (HWord)inscon ); IRExpr * args1[2]; packToI32orI64(sb, op->Iex.Triop.details->arg2, args1, irop); IRExpr * args2[2]; packToI32orI64(sb, op->Iex.Triop.details->arg3, args2, irop); argv = mkIRExprVec_3(args1[0], args2[0], oa_event_expr); di = unsafeIRDirty_0_N( 3, thisFct, VG_(fnptr_to_fnentry)( f ), argv); addStmtToIRSB( sb, IRStmt_Dirty(di) ); if (args1[1] != NULL) { // we need a second callback for 64bit types argv = mkIRExprVec_3(args1[1], args2[1], oa_event_expr); di = unsafeIRDirty_0_N( 3, thisFct, VG_(fnptr_to_fnentry)( f ), argv); addStmtToIRSB( sb, IRStmt_Dirty(di) ); } }
static void instrument_store(IRSB* const bb, IRExpr* const addr_expr, const HWord size) { IRExpr* size_expr; IRExpr** argv; IRDirty* di; switch (size) { case 1: argv = mkIRExprVec_1(addr_expr); di = unsafeIRDirty_0_N(/*regparms*/1, "drd_trace_store_1", VG_(fnptr_to_fnentry)(drd_trace_store_1), argv); break; case 2: argv = mkIRExprVec_1(addr_expr); di = unsafeIRDirty_0_N(/*regparms*/1, "drd_trace_store_2", VG_(fnptr_to_fnentry)(drd_trace_store_2), argv); break; case 4: argv = mkIRExprVec_1(addr_expr); di = unsafeIRDirty_0_N(/*regparms*/1, "drd_trace_store_4", VG_(fnptr_to_fnentry)(drd_trace_store_4), argv); break; case 8: argv = mkIRExprVec_1(addr_expr); di = unsafeIRDirty_0_N(/*regparms*/1, "drd_trace_store_8", VG_(fnptr_to_fnentry)(drd_trace_store_8), argv); break; default: size_expr = mkIRExpr_HWord(size); argv = mkIRExprVec_2(addr_expr, size_expr); di = unsafeIRDirty_0_N(/*regparms*/2, "drd_trace_store", VG_(fnptr_to_fnentry)(drd_trace_store), argv); break; } addStmtToIRSB(bb, IRStmt_Dirty(di)); }
static void VG_(add_stmt_call_invalidate_if_not_gdbserved) ( IRSB* sb_in, VexGuestLayout* layout, VexGuestExtents* vge, IRTemp jmp, IRSB* irsb) { void* fn; const HChar* nm; IRExpr** args; Int nargs; IRDirty* di; fn = &VG_(helperc_invalidate_if_not_gdbserved); nm = "VG_(helperc_invalidate_if_not_gdbserved)"; args = mkIRExprVec_1(IRExpr_RdTmp (jmp)); nargs = 1; di = unsafeIRDirty_0_N( nargs/*regparms*/, nm, VG_(fnptr_to_fnentry)( fn ), args ); di->nFxState = 0; addStmtToIRSB(irsb, IRStmt_Dirty(di)); }
void instrument_WrTmp_Mux0X(IRStmt* st, IRSB* sb_out) { IRTemp tmp = st->Ist.WrTmp.tmp; IRExpr* data = st->Ist.WrTmp.data; IRExpr* cond = data->Iex.Mux0X.cond; IRExpr* expr0 = data->Iex.Mux0X.expr0; IRExpr* exprX = data->Iex.Mux0X.exprX; Int size = sizeofIRType_bits(typeOfIRExpr(sb_out->tyenv, expr0)); IRDirty* di; tl_assert(cond->tag == Iex_RdTmp); tl_assert(isIRAtom(expr0)); tl_assert(isIRAtom(exprX)); tl_assert(typeOfIRTemp(sb_out->tyenv, tmp) == typeOfIRExpr(sb_out->tyenv, expr0)); tl_assert(typeOfIRTemp(sb_out->tyenv, tmp) == typeOfIRExpr(sb_out->tyenv, exprX)); di = unsafeIRDirty_0_N(0, "helper_instrument_WrTmp_Mux0X", VG_(fnptr_to_fnentry)(helper_instrument_WrTmp_Mux0X), mkIRExprVec_5(mkIRExpr_HWord(tmp), assignNew_HWord(sb_out, cond), mkIRExpr_HWord((expr0->tag == Iex_RdTmp) ? expr0->Iex.RdTmp.tmp : IRTemp_INVALID), mkIRExpr_HWord((exprX->tag == Iex_RdTmp) ? exprX->Iex.RdTmp.tmp : IRTemp_INVALID), mkIRExpr_HWord(size)) ); addStmtToIRSB(sb_out, IRStmt_Dirty(di)); }
void AddOpRhsTypeHelper(IRSB* sb, IRExpr* arg, IntTyStateHint hint, Addr addr) { IRDirty * d; HWord tmpname; switch (arg->tag) { case(Iex_RdTmp): tmpname = (HWord)arg->Iex.RdTmp.tmp; d = unsafeIRDirty_0_N(0, "EmitTmpHelper", &EmitTmpHelper, mkIRExprVec_4( mkIRExpr_HWord(tmpname), mkIRExpr_HWord(hint), mkIRExpr_HWord(counter), mkIRExpr_HWord(addr) ) ); setHelperAnns(d); addStmtToIRSB(sb,IRStmt_Dirty(d)); break; default: break; } return; }
void AddStoreHelper(IRSB* sb, IRExpr* addr, IRExpr* data) { IRDirty* d; HWord tmpname; switch (addr->tag) { case (Iex_RdTmp): switch (data->tag) { case (Iex_RdTmp): tmpname = (HWord) data->Iex.RdTmp.tmp; d = unsafeIRDirty_0_N(0, "EmitStoreAddr2TmpHelper", &EmitStoreAddr2TmpHelper, mkIRExprVec_3(addr, mkIRExpr_HWord(tmpname), mkIRExpr_HWord(counter) ) ); setHelperAnns(d); addStmtToIRSB(sb, IRStmt_Dirty(d)); break; case (Iex_Const): /* add code to emit new tyvar for memory address */ d = unsafeIRDirty_0_N(0, "EmitStoreAddr2ConstHelper", &EmitStoreAddr2ConstHelper, mkIRExprVec_1(addr ) ); setHelperAnns(d); addStmtToIRSB(sb,IRStmt_Dirty(d)); break; default: /* Should not reach here. */ ppIRExpr(data); vpanic("Bad store address!\n"); break; } break; default: break; } return; }
/* cc_op add/sub/mul adc/sbb shl/Shl/sar tmp = cond(cc_op(cc_dep1, cc_dep2)) and/or/xor inc/dec rol/ror tmp = cond(cc_op(cc_dep1, 0)) The taintness of tmp depends on taintness of both args. (we can't handle and(cc_dep1, 0) which gives an untainted result) cf. valgrind guest_x86_defs.h */ void instrument_WrTmp_CCall(IRStmt* st, IRSB* sb_out) { IRTemp tmp = st->Ist.WrTmp.tmp; IRExpr* data = st->Ist.WrTmp.data; IRCallee* cee = data->Iex.CCall.cee; IRExpr** args = data->Iex.CCall.args; IRDirty* di; if (VG_(strcmp)(cee->name, "x86g_calculate_condition") == 0) { IRExpr* cond = args[0]; IRExpr* cc_op = args[1]; IRExpr* cc_dep1 = args[2]; IRExpr* cc_dep2 = args[3]; tl_assert(cond->tag == Iex_Const && cond->Iex.Const.con->tag == Ico_U32); tl_assert(isIRAtom(cc_op)); tl_assert(isIRAtom(cc_dep1)); tl_assert(isIRAtom(cc_dep2)); if (cc_op->tag == Iex_Const) tl_assert(cc_op->Iex.Const.con->tag == Ico_U32); if (cc_dep1->tag == Iex_Const) tl_assert(cc_dep1->Iex.Const.con->tag == Ico_U32); if (cc_dep2->tag == Iex_Const) tl_assert(cc_dep2->Iex.Const.con->tag == Ico_U32); // typeOf(x86g_calculate_condition) == typeOf(tmp) == I32 di = unsafeIRDirty_0_N(0, "helper_instrument_WrTmp_CCall_x86g_calculate_condition", VG_(fnptr_to_fnentry)(helper_instrument_WrTmp_CCall_x86g_calculate_condition), mkIRExprVec_7(mkIRExpr_HWord(tmp), mkIRExpr_HWord((cc_dep1->tag == Iex_RdTmp) ? cc_dep1->Iex.RdTmp.tmp : IRTemp_INVALID), mkIRExpr_HWord((cc_dep2->tag == Iex_RdTmp) ? cc_dep2->Iex.RdTmp.tmp : IRTemp_INVALID), mkIRExpr_HWord(cond->Iex.Const.con->Ico.U32), (cc_op->tag == Iex_RdTmp) ? assignNew_HWord(sb_out, cc_op) : mkIRExpr_HWord(cc_op->Iex.Const.con->Ico.U32), (cc_dep1->tag == Iex_RdTmp) ? assignNew_HWord(sb_out, cc_dep1) : mkIRExpr_HWord(cc_dep1->Iex.Const.con->Ico.U32), (cc_dep2->tag == Iex_RdTmp) ? assignNew_HWord(sb_out, cc_dep2) : mkIRExpr_HWord(cc_dep2->Iex.Const.con->Ico.U32)) ); addStmtToIRSB(sb_out, IRStmt_Dirty(di)); } else { di = unsafeIRDirty_0_N(0, "helper_instrument_WrTmp_CCall_else", VG_(fnptr_to_fnentry)(helper_instrument_WrTmp_CCall_else), mkIRExprVec_0() ); addStmtToIRSB(sb_out, IRStmt_Dirty(di)); } }
void instrument_WrTmp_Binop(IRStmt* st, IRSB* sb_out) { IRTemp tmp = st->Ist.WrTmp.tmp; IRExpr* data = st->Ist.WrTmp.data; IROp op = data->Iex.Binop.op; IRExpr* arg1 = data->Iex.Binop.arg1; IRExpr* arg2 = data->Iex.Binop.arg2; UInt arg1_value = 0, arg2_value = 0; IRExpr* expr = IRExpr_Binop(op, arg1, arg2); Int size = sizeofIRType_bits(typeOfIRExpr(sb_out->tyenv, expr)); IRDirty* di; // we don't care about floating point and SIMD operations if (op > Iop_AddF64) return; tl_assert(isIRAtom(arg1)); tl_assert(isIRAtom(arg2)); tl_assert(typeOfIRTemp(sb_out->tyenv, tmp) == typeOfIRExpr(sb_out->tyenv, expr)); if (arg1->tag == Iex_Const) { switch (arg1->Iex.Const.con->tag) { case Ico_U1: arg1_value = arg1->Iex.Const.con->Ico.U1; break; case Ico_U8: arg1_value = arg1->Iex.Const.con->Ico.U8; break; case Ico_U16: arg1_value = arg1->Iex.Const.con->Ico.U16; break; case Ico_U32: arg1_value = arg1->Iex.Const.con->Ico.U32; break; case Ico_U64: arg1_value = arg1->Iex.Const.con->Ico.U64; break; default: VG_(tool_panic)("instrument_WrTmp_Binop"); } } if (arg2->tag == Iex_Const) { switch (arg2->Iex.Const.con->tag) { case Ico_U1: arg2_value = arg2->Iex.Const.con->Ico.U1; break; case Ico_U8: arg2_value = arg2->Iex.Const.con->Ico.U8; break; case Ico_U16: arg2_value = arg2->Iex.Const.con->Ico.U16; break; case Ico_U32: arg2_value = arg2->Iex.Const.con->Ico.U32; break; case Ico_U64: arg2_value = arg2->Iex.Const.con->Ico.U64; break; default: VG_(tool_panic)("instrument_WrTmp_Binop"); } } di = unsafeIRDirty_0_N(0, "helper_instrument_WrTmp_Binop", VG_(fnptr_to_fnentry)(helper_instrument_WrTmp_Binop), mkIRExprVec_7(mkIRExpr_HWord(tmp), mkIRExpr_HWord((arg1->tag == Iex_RdTmp) ? arg1->Iex.RdTmp.tmp : IRTemp_INVALID), mkIRExpr_HWord((arg2->tag == Iex_RdTmp) ? arg2->Iex.RdTmp.tmp : IRTemp_INVALID), mkIRExpr_HWord(op), mkIRExpr_HWord(size), (arg1->tag == Iex_RdTmp) ? assignNew_HWord(sb_out, arg1) : mkIRExpr_HWord(arg1_value), (arg2->tag == Iex_RdTmp) ? assignNew_HWord(sb_out, arg2) : mkIRExpr_HWord(arg2_value)) ); addStmtToIRSB(sb_out, IRStmt_Dirty(di)); }
void addDynamicDisownNonNull(IRSB* sbOut, IRTemp idx){ IRDirty* disownDirty = unsafeIRDirty_0_N(1, "disownShadowTempNonNullDynamic", VG_(fnptr_to_fnentry)(disownShadowTempNonNullDynamic), mkIRExprVec_1(mkU64(idx))); disownDirty->mFx = Ifx_Modify; disownDirty->mAddr = mkU64((uintptr_t)&(shadowTemps[idx])); disownDirty->mSize = sizeof(ShadowTemp*); addStmtToIRSB(sbOut, IRStmt_Dirty(disownDirty)); }
void AddPutHelper(IRSB* sb, Int offset, IRExpr* data) { IRDirty * d; HWord h_offset = (HWord)(offset); HWord lhs_name; switch (data->tag) { case(Iex_Const): d = unsafeIRDirty_0_N(0, "EmitPutConstHelper", &EmitPutConstHelper, mkIRExprVec_2(mkIRExpr_HWord(h_offset), mkIRExpr_HWord(counter) ) ); setHelperAnns(d); addStmtToIRSB(sb, IRStmt_Dirty(d)); break; case(Iex_RdTmp): lhs_name = (HWord)data->Iex.RdTmp.tmp; d = unsafeIRDirty_0_N(0, "EmitPutTmpHelper", &EmitPutTmpHelper, mkIRExprVec_3(mkIRExpr_HWord(h_offset), mkIRExpr_HWord(lhs_name), mkIRExpr_HWord(counter) ) ); setHelperAnns(d); addStmtToIRSB(sb, IRStmt_Dirty(d)); break; default: break; } return; }
void instrument_WrTmp_Const(IRStmt* st, IRSB* sb_out) { IRTemp tmp = st->Ist.WrTmp.tmp; IRDirty* di; di = unsafeIRDirty_0_N(0, "helper_instrument_WrTmp_Const", VG_(fnptr_to_fnentry)(helper_instrument_WrTmp_Const), mkIRExprVec_1(mkIRExpr_HWord(tmp)) ); addStmtToIRSB(sb_out, IRStmt_Dirty(di)); }
static void mkCall(IRSB* sb, EventKind ev, IRStmt* stmt, IRExpr* addr) { const HChar* helperName; void* helperAddr; IRExpr** argv = NULL; IRDirty* di = NULL; // Decide on helper fn to call and args to pass it. switch (ev) { case Event_Load: helperName = "trace_load"; helperAddr = trace_load; break; case Event_Store: helperName = "trace_store"; helperAddr = trace_store; break; case Event_Op: helperName = "trace_op"; helperAddr = trace_op; argv = mkIRExprVec_3( mkIRExpr_HWord( (HWord) stmt), mkIRExpr_HWord( 1), mkIRExpr_HWord( 2)); di = unsafeIRDirty_0_N(3, helperName, VG_(fnptr_to_fnentry)( helperAddr ), argv ); break; default: tl_assert(0); } if (!di || !argv) { // Add the helper. argv = mkIRExprVec_3(addr, mkIRExpr_HWord( 0), mkIRExpr_HWord((HWord) stmt)); di = unsafeIRDirty_0_N( 2, helperName, VG_(fnptr_to_fnentry)( helperAddr ), argv ); } IRStmt* a = IRStmt_Dirty(di); addStmtToIRSB( sb, a); }
/* A helper that adds the instrumentation for a detail. */ static void instrument_detail(IRSB* sb, Op op, IRType type) { IRDirty* di; IRExpr** argv; const UInt typeIx = type2index(type); tl_assert(op < N_OPS); tl_assert(typeIx < N_TYPES); argv = mkIRExprVec_1( mkIRExpr_HWord( (HWord)&detailCounts[op][typeIx] ) ); di = unsafeIRDirty_0_N( 1, "increment_detail", VG_(fnptr_to_fnentry)( &increment_detail ), argv); addStmtToIRSB( sb, IRStmt_Dirty(di) ); }
static void flushEvents(IRSB* sb) { Int i; Char* helperName; void* helperAddr; IRExpr** argv; IRDirty* di; Event* ev; for (i = 0; i < events_used; i++) { ev = &events[i]; // Decide on helper fn to call and args to pass it. switch (ev->ekind) { case Event_Ir: helperName = "trace_instr"; helperAddr = trace_instr; break; case Event_Dr: helperName = "trace_load"; helperAddr = trace_load; break; case Event_Dw: helperName = "trace_store"; helperAddr = trace_store; break; case Event_Dm: helperName = "trace_modify"; helperAddr = trace_modify; break; default: tl_assert(0); } // Add the helper. argv = mkIRExprVec_2( ev->addr, mkIRExpr_HWord( ev->size ) ); di = unsafeIRDirty_0_N( /*regparms*/2, helperName, VG_(fnptr_to_fnentry)( helperAddr ), argv ); addStmtToIRSB( sb, IRStmt_Dirty(di) ); } events_used = 0; }
static void addEvent_FnEntry ( IRSB* sb, char *fnname) { IRExpr** argv; IRDirty* di; char *buf = (char *)VG_(malloc)("addEvent_FnEntry",100*sizeof(char)); tl_assert(buf!=NULL); VG_(strcpy)(buf,fnname); argv = mkIRExprVec_1( mkIRExpr_HWord( (HWord) buf )); di = unsafeIRDirty_0_N( /*regparms*/1, "trace_fnentry", VG_(fnptr_to_fnentry)( trace_fnentry ), argv ); if(events_used > 0) flushEvents(sb); addStmtToIRSB( sb, IRStmt_Dirty(di) ); }
//----------------------------------------------------------------- static void instrument_Unop(IRSB* sb, IRStmt* st, Addr64 cia) { Char thisFct[]="instrument_Unop"; IRExpr *op = st->Ist.WrTmp.data; IROp irop=op->Iex.Unop.op; void* f=callbackFromIROp(irop); if (f == NULL) return; OA_InstrumentContext inscon=contextFor(cia, irop); if (not_worth_watching(inscon)) return; // filter events that can't be attached to source-code location updateStats(inscon->op); IRExpr* oa_event_expr = mkIRExpr_HWord( (HWord)inscon ); IRExpr * args[2]; packToI32orI64(sb, op->Iex.Unop.arg, args, irop); IRExpr** argv = mkIRExprVec_2(args[0], oa_event_expr); IRDirty* di = unsafeIRDirty_0_N( 2, thisFct, VG_(fnptr_to_fnentry)( f ), argv); addStmtToIRSB( sb, IRStmt_Dirty(di) ); }
static void addEvent_RegW ( IRSB* sb, char *fnname, Int reg_no, IRAtom* tmp_val) { IRExpr** argv; IRDirty* di; tl_assert(clo_trace_mem); tl_assert(isIRAtom(tmp_val)); char *buf = (char *)VG_(malloc)("addEvent_RegW",100*sizeof(char)); tl_assert(buf!=NULL); VG_(strcpy)(buf,fnname); argv = mkIRExprVec_3( mkIRExpr_HWord( (HWord) buf ), mkIRExpr_HWord( reg_no ), tmp_val ); di = unsafeIRDirty_0_N( /*regparms*/3, "trace_regw", VG_(fnptr_to_fnentry)( trace_regw ), argv ); if(events_used > 0) flushEvents(sb); addStmtToIRSB( sb, IRStmt_Dirty(di) ); }
static IRSB * bcg_instrument(VgCallbackClosure* closure, IRSB* bb, VexGuestLayout* layout, VexGuestExtents* vge, IRType gWordTy, IRType hWordTy) { unsigned long rip = 0; int i; if (bb->jumpkind != Ijk_Ret && bb->next->tag != Iex_Const) { IRTemp tmp; for (i = bb->stmts_used - 1; i >= 0; i--) { if (bb->stmts[i]->tag == Ist_IMark) { rip = bb->stmts[i]->Ist.IMark.addr; break; } } tl_assert(i >= 0); if (bb->next->tag == Iex_RdTmp) { tmp = bb->next->Iex.RdTmp.tmp; } else { tmp = newIRTemp(bb->tyenv, Ity_I64); addStmtToIRSB(bb, IRStmt_WrTmp(tmp, bb->next)); bb->next = IRExpr_RdTmp(tmp); } addStmtToIRSB(bb, IRStmt_Dirty( unsafeIRDirty_0_N( 0, "log_call", log_call, mkIRExprVec_3( IRExpr_Const(IRConst_U64(rip)), IRExpr_Const(IRConst_U64(bb->jumpkind == Ijk_Call)), bb->next)))); } return bb; }
void instrument_Exit(IRStmt* st, IRSB* sb_out) { IRExpr* guard = st->Ist.Exit.guard; Int offsIP = st->Ist.Exit.offsIP; Int size = sizeofIRType_bits(typeOfIRConst(st->Ist.Exit.dst)); IRDirty* di; tl_assert(guard->tag == Iex_RdTmp); di = unsafeIRDirty_0_N(0, "helper_instrument_Exit", VG_(fnptr_to_fnentry)(helper_instrument_Exit), mkIRExprVec_4(assignNew_HWord(sb_out, guard), mkIRExpr_HWord(offsIP), mkIRExpr_HWord(size), mkIRExpr_HWord(guard->Iex.RdTmp.tmp)) ); addStmtToIRSB(sb_out, IRStmt_Dirty(di)); }
void instrument_WrTmp_RdTmp(IRStmt* st, IRSB* sb_out) { IRTemp tmp_lhs = st->Ist.WrTmp.tmp; IRExpr* data = st->Ist.WrTmp.data; IRTemp tmp_rhs = data->Iex.RdTmp.tmp; Int size = sizeofIRType_bits(typeOfIRTemp(sb_out->tyenv, tmp_rhs)); IRDirty* di; tl_assert(typeOfIRTemp(sb_out->tyenv, tmp_lhs) == typeOfIRTemp(sb_out->tyenv, tmp_rhs)); di = unsafeIRDirty_0_N(0, "helper_instrument_WrTmp_RdTmp", VG_(fnptr_to_fnentry)(helper_instrument_WrTmp_RdTmp), mkIRExprVec_3(mkIRExpr_HWord(tmp_lhs), mkIRExpr_HWord(tmp_rhs), mkIRExpr_HWord(size)) ); addStmtToIRSB(sb_out, IRStmt_Dirty(di)); }
void instrument_CAS_double_element(IRStmt* st, IRSB* sb_out) { IRCAS* cas = st->Ist.CAS.details; IRTemp oldHi = cas->oldHi, oldLo = cas->oldLo; IREndness end = cas->end; IRExpr* addr = cas->addr; IRExpr *expdHi = cas->expdHi, *expdLo = cas->expdLo; IRExpr *dataHi = cas->dataHi, *dataLo = cas->dataLo; Int size = sizeofIRType_bits(typeOfIRExpr(sb_out->tyenv, dataLo)); IROp op; IRExpr *expr, *expr2; IRDirty* di; tl_assert(isIRAtom(addr)); tl_assert(end == Iend_LE); // we assume endianness is little endian tl_assert(isIRAtom(dataLo)); tl_assert(isIRAtom(dataHi)); if (addr->tag == Iex_Const) tl_assert(addr->Iex.Const.con->tag == Ico_U32); tl_assert(typeOfIRExpr(sb_out->tyenv, addr) == typeOfIRExpr(sb_out->tyenv, dataLo)); switch (size) { case 8: op = Iop_CasCmpEQ8; break; case 16: op = Iop_CasCmpEQ16; break; case 32: op = Iop_CasCmpEQ32; break; default: VG_(tool_panic)("instrument_CAS_double_element"); } expr = assignNew(sb_out, IRExpr_Binop(op, IRExpr_RdTmp(oldLo), expdLo)); // statement has to be flat expr2 = assignNew(sb_out, IRExpr_Binop(op, IRExpr_RdTmp(oldHi), expdHi)); // statement has to be flat di = unsafeIRDirty_0_N(0, "helper_instrument_CAS_double_element", VG_(fnptr_to_fnentry)(helper_instrument_CAS_double_element), mkIRExprVec_6((addr->tag == Iex_RdTmp) ? assignNew_HWord(sb_out, addr) : mkIRExpr_HWord(addr->Iex.Const.con->Ico.U32), mkIRExpr_HWord((dataLo->tag == Iex_RdTmp) ? dataLo->Iex.RdTmp.tmp : IRTemp_INVALID), mkIRExpr_HWord((dataHi->tag == Iex_RdTmp) ? dataHi->Iex.RdTmp.tmp : IRTemp_INVALID), mkIRExpr_HWord(size), assignNew_HWord(sb_out, expr), assignNew_HWord(sb_out, expr2)) ); addStmtToIRSB(sb_out, IRStmt_Dirty(di)); }
void AddLoadHelper(IRSB* sb, IRTemp lhs, IRExpr* addr) { IRDirty * d; ULong lhs_int; lhs_int = (HWord)lhs; d = unsafeIRDirty_0_N(0, "EmitLoadTmp2AddrHelper", &EmitRdTmpTmp2TmpHelper, mkIRExprVec_3( mkIRExpr_HWord(lhs_int), addr, mkIRExpr_HWord(counter) ) ); setHelperAnns(d); addStmtToIRSB(sb,IRStmt_Dirty(d)); return; }
void instrument_Put(IRStmt* st, IRSB* sb_out) { Int offset = st->Ist.Put.offset; IRExpr* data = st->Ist.Put.data; Int size = sizeofIRType_bits(typeOfIRExpr(sb_out->tyenv, data)); IRDirty* di; tl_assert(isIRAtom(data)); // the data transfer type is the type of data di = unsafeIRDirty_0_N(0, "helper_instrument_Put", VG_(fnptr_to_fnentry)(helper_instrument_Put), mkIRExprVec_3(mkIRExpr_HWord(offset), mkIRExpr_HWord((data->tag == Iex_RdTmp) ? data->Iex.RdTmp.tmp : IRTemp_INVALID), mkIRExpr_HWord(size)) ); addStmtToIRSB(sb_out, IRStmt_Dirty(di)); }
void instrument_LLSC_Load_Linked(IRStmt* st, IRSB* sb_out) { IRTemp result = st->Ist.LLSC.result; IRExpr* addr = st->Ist.LLSC.addr; Int size = sizeofIRType_bits(typeOfIRTemp(sb_out->tyenv, result)); IRDirty* di; tl_assert(isIRAtom(addr)); if (addr->tag == Iex_Const) tl_assert(addr->Iex.Const.con->tag == Ico_U32); // the data transfer type is the type of result di = unsafeIRDirty_0_N(0, "helper_instrument_LLSC_Load_Linked", VG_(fnptr_to_fnentry)(helper_instrument_LLSC_Load_Linked), mkIRExprVec_3(mkIRExpr_HWord(result), (addr->tag == Iex_RdTmp) ? assignNew_HWord(sb_out, addr) : mkIRExpr_HWord(addr->Iex.Const.con->Ico.U32), mkIRExpr_HWord(size)) ); addStmtToIRSB(sb_out, IRStmt_Dirty(di)); }
void instrument_WrTmp_Load(IRStmt* st, IRSB* sb_out) { IRTemp tmp = st->Ist.WrTmp.tmp; IRExpr* data = st->Ist.WrTmp.data; IRExpr* addr = data->Iex.Load.addr; Int size = sizeofIRType_bits(data->Iex.Load.ty); IRDirty* di; tl_assert(isIRAtom(addr)); if (addr->tag == Iex_Const) tl_assert(addr->Iex.Const.con->tag == Ico_U32); tl_assert(typeOfIRTemp(sb_out->tyenv, tmp) == data->Iex.Load.ty); di = unsafeIRDirty_0_N(0, "helper_instrument_WrTmp_Load", VG_(fnptr_to_fnentry)(helper_instrument_WrTmp_Load), mkIRExprVec_3(mkIRExpr_HWord(tmp), (addr->tag == Iex_RdTmp) ? assignNew_HWord(sb_out, addr) : mkIRExpr_HWord(addr->Iex.Const.con->Ico.U32), mkIRExpr_HWord(size)) ); addStmtToIRSB(sb_out, IRStmt_Dirty(di)); }
void instrument_Store(IRStmt* st, IRSB* sb_out) { IRExpr* addr = st->Ist.Store.addr; IRExpr* data = st->Ist.Store.data; Int size = sizeofIRType_bits(typeOfIRExpr(sb_out->tyenv, st->Ist.Store.data)); IRDirty* di; tl_assert(isIRAtom(addr)); tl_assert(isIRAtom(data)); if (addr->tag == Iex_Const) tl_assert(addr->Iex.Const.con->tag == Ico_U32); // the data transfer type is the type of data di = unsafeIRDirty_0_N(0, "helper_instrument_Store", VG_(fnptr_to_fnentry)(helper_instrument_Store), mkIRExprVec_3((addr->tag == Iex_RdTmp) ? assignNew_HWord(sb_out, addr) : mkIRExpr_HWord(addr->Iex.Const.con->Ico.U32), mkIRExpr_HWord((data->tag == Iex_RdTmp) ? data->Iex.RdTmp.tmp : IRTemp_INVALID), mkIRExpr_HWord(size)) ); addStmtToIRSB(sb_out, IRStmt_Dirty(di)); }
/* The GetI expression is used to read guest registers which identity is not known until run time, i.e. not the registers we are shadowing (in principle), no harm in verifying though. */ void instrument_WrTmp_GetI(IRStmt* st, IRSB* sb_out) { IRExpr* data = st->Ist.WrTmp.data; IRRegArray* descr = data->Iex.GetI.descr; Int base = descr->base; Int nElems = descr->nElems; IRExpr* ix = data->Iex.GetI.ix; Int bias = data->Iex.GetI.bias; IRDirty* di; tl_assert(ix->tag == Iex_RdTmp); di = unsafeIRDirty_0_N(0, "helper_instrument_WrTmp_GetI", VG_(fnptr_to_fnentry)(helper_instrument_WrTmp_GetI), mkIRExprVec_4(mkIRExpr_HWord(base), assignNew_HWord(sb_out, ix), mkIRExpr_HWord(bias), mkIRExpr_HWord(nElems)) ); addStmtToIRSB(sb_out, IRStmt_Dirty(di)); }
void cleanupBlockOwnership(IRSB* sbOut, IRExpr* guard){ if (VG_(sizeXA)(tempDebt) == 0){ addStoreGC(sbOut, guard, mkU64(0), &blockStateDirty); return; } IRTemp* curDebtContents = VG_(perm_malloc)(sizeof(IRTemp) * VG_(sizeXA)(tempDebt), vg_alignof(IRTemp)); for(int i = 0; i < VG_(sizeXA)(tempDebt); ++i){ curDebtContents[i] = *(IRTemp*)VG_(indexXA)(tempDebt, i); } IRDirty* dynCleanupDirty = unsafeIRDirty_0_N(2, "dynamicCleanup", VG_(fnptr_to_fnentry)(dynamicCleanup), mkIRExprVec_2(mkU64(VG_(sizeXA)(tempDebt)), mkU64((uintptr_t)curDebtContents))); dynCleanupDirty->mFx = Ifx_Modify; dynCleanupDirty->guard = guard; dynCleanupDirty->mAddr = mkU64((uintptr_t)shadowTemps); dynCleanupDirty->mSize = sizeof(ShadowTemp) * MAX_TEMPS; addStmtToIRSB(sbOut, IRStmt_Dirty(dynCleanupDirty)); }
void instrument_WrTmp_Unop(IRStmt* st, IRSB* sb_out) { IRTemp tmp = st->Ist.WrTmp.tmp; IRExpr* data = st->Ist.WrTmp.data; IROp op = data->Iex.Unop.op; IRExpr* arg = data->Iex.Unop.arg; IRExpr* expr = IRExpr_Unop(op, arg); Int size = sizeofIRType_bits(typeOfIRExpr(sb_out->tyenv, expr)); IRDirty* di; tl_assert(isIRAtom(arg)); tl_assert(typeOfIRTemp(sb_out->tyenv, tmp) == typeOfIRExpr(sb_out->tyenv, expr)); di = unsafeIRDirty_0_N(0, "helper_instrument_WrTmp_Unop", VG_(fnptr_to_fnentry)(helper_instrument_WrTmp_Unop), mkIRExprVec_4(mkIRExpr_HWord(tmp), mkIRExpr_HWord((arg->tag == Iex_RdTmp) ? arg->Iex.RdTmp.tmp : IRTemp_INVALID), mkIRExpr_HWord(op), mkIRExpr_HWord(size)) ); addStmtToIRSB(sb_out, IRStmt_Dirty(di)); }
void instrument_LLSC_Store_Conditional(IRStmt* st, IRSB* sb_out) { IRTemp result = st->Ist.LLSC.result; IRExpr* addr = st->Ist.LLSC.addr; IRExpr* storedata = st->Ist.LLSC.storedata; Int size = sizeofIRType_bits(typeOfIRExpr(sb_out->tyenv, storedata)); IRExpr* result_expr = IRExpr_RdTmp(result); IRDirty* di; tl_assert(isIRAtom(addr)); tl_assert(isIRAtom(storedata)); if (addr->tag == Iex_Const) tl_assert(addr->Iex.Const.con->tag == Ico_U32); // the data transfer type is the type of storedata di = unsafeIRDirty_0_N(0, "helper_instrument_LLSC_Store_Conditional", VG_(fnptr_to_fnentry)(helper_instrument_LLSC_Store_Conditional), mkIRExprVec_4((addr->tag == Iex_RdTmp) ? assignNew_HWord(sb_out, addr) : mkIRExpr_HWord(addr->Iex.Const.con->Ico.U32), mkIRExpr_HWord((storedata->tag == Iex_RdTmp) ? storedata->Iex.RdTmp.tmp : IRTemp_INVALID), mkIRExpr_HWord(size), assignNew_HWord(sb_out, result_expr)) ); addStmtToIRSB(sb_out, IRStmt_Dirty(di)); }