Пример #1
0
/* 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) );
  }

}
Пример #2
0
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));
}
Пример #3
0
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; 
}
Пример #4
0
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));
}
Пример #5
0
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;
} 
Пример #6
0
/*
    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));
    }
}
Пример #7
0
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));
}
Пример #8
0
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));
}
Пример #9
0
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;    
}
Пример #10
0
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));
}
Пример #11
0
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));
}
Пример #12
0
/* 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) );
}
Пример #13
0
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;
}
Пример #14
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) );
}
Пример #15
0
IRStmt* pyvex_deepCopyIRStmt ( IRStmt* s )
{
   switch (s->tag) {
      case Ist_NoOp:
         return IRStmt_NoOp();
      case Ist_AbiHint:
         return IRStmt_AbiHint(pyvex_deepCopyIRExpr(s->Ist.AbiHint.base),
                               s->Ist.AbiHint.len,
                               pyvex_deepCopyIRExpr(s->Ist.AbiHint.nia));
      case Ist_IMark:
         return IRStmt_IMark(s->Ist.IMark.addr,
                             s->Ist.IMark.len,
                             s->Ist.IMark.delta);
      case Ist_Put: 
         return IRStmt_Put(s->Ist.Put.offset, 
                           pyvex_deepCopyIRExpr(s->Ist.Put.data));
      case Ist_PutI: 
         return IRStmt_PutI(pyvex_deepCopyIRPutI(s->Ist.PutI.details));
      case Ist_WrTmp:
         return IRStmt_WrTmp(s->Ist.WrTmp.tmp,
                             pyvex_deepCopyIRExpr(s->Ist.WrTmp.data));
      case Ist_Store: 
         return IRStmt_Store(s->Ist.Store.end,
                             pyvex_deepCopyIRExpr(s->Ist.Store.addr),
                             pyvex_deepCopyIRExpr(s->Ist.Store.data));
      case Ist_CAS:
         return IRStmt_CAS(pyvex_deepCopyIRCAS(s->Ist.CAS.details));
      case Ist_LLSC:
         return IRStmt_LLSC(s->Ist.LLSC.end,
                            s->Ist.LLSC.result,
                            pyvex_deepCopyIRExpr(s->Ist.LLSC.addr),
                            s->Ist.LLSC.storedata
                               ? pyvex_deepCopyIRExpr(s->Ist.LLSC.storedata)
                               : NULL);
      case Ist_Dirty: 
         return IRStmt_Dirty(pyvex_deepCopyIRDirty(s->Ist.Dirty.details));
      case Ist_MBE:
         return IRStmt_MBE(s->Ist.MBE.event);
      case Ist_Exit: 
         return IRStmt_Exit(pyvex_deepCopyIRExpr(s->Ist.Exit.guard),
                            s->Ist.Exit.jk,
                            pyvex_deepCopyIRConst(s->Ist.Exit.dst),
                            s->Ist.Exit.offsIP);
      default: 
         vpanic("pyvex_deepCopyIRStmt");
   }
}
Пример #16
0
//-----------------------------------------------------------------
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) );
}
Пример #17
0
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) );
}
Пример #18
0
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;
}
Пример #19
0
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;
}
Пример #20
0
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));
}
Пример #21
0
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));
}
Пример #22
0
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));
}
Пример #23
0
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));
}
Пример #24
0
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));
}
Пример #25
0
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));
}
Пример #26
0
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));
}
Пример #27
0
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));
}
Пример #28
0
/*
    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));
}
Пример #29
0
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);
}
Пример #30
0
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));
}