コード例 #1
0
ファイル: fz_main.c プロジェクト: taveso/Concolic-testing
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));
}
コード例 #2
0
ファイル: fz_main.c プロジェクト: taveso/Concolic-testing
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));
}
コード例 #3
0
ファイル: main.c プロジェクト: svn2github/valgrind-3
static Bool loadStoreAddrsMatch(IRExpr* loadAddrExpr, IRExpr* storeAddrExpr)
{
    // I'm assuming that for 'modify' instructions, that Vex always makes
    // the loadAddrExpr and storeAddrExpr be of the same type, ie. both Tmp
    // expressions, or both Const expressions.
    CLG_ASSERT(isIRAtom(loadAddrExpr));
    CLG_ASSERT(isIRAtom(storeAddrExpr));
    return eqIRAtom(loadAddrExpr, storeAddrExpr);
}
コード例 #4
0
ファイル: sh_main.c プロジェクト: gowthamk/Sherlock
static
void addEvent_Dw ( IRSB* sb, char *fnname, IRAtom* daddr, Int dsize )
{
    Event* lastEvt;
    Event* evt;
    tl_assert(clo_trace_mem);
    tl_assert(isIRAtom(daddr));
    tl_assert(dsize >= 1 && dsize <= MAX_DSIZE);
    char *buf = (char *)VG_(malloc)("addEvent_Dw",100*sizeof(char));
    tl_assert(buf!=NULL);
    VG_(strcpy)(buf,fnname);

    /*// Is it possible to merge this write with the preceding read?
    lastEvt = &events[events_used-1];
    if (events_used > 0
    && lastEvt->ekind == Event_Dr
    && lastEvt->size  == dsize
    && eqIRAtom(lastEvt->addr, daddr))
    {
      lastEvt->ekind = Event_Dm;
      return;
    }*/

    // No.  Add as normal.
    tl_assert(events_used >= 0 && events_used < N_EVENTS);
    evt = &events[events_used];
    evt->ekind = Event_Dw;
    evt->size  = dsize;
    evt->addr  = daddr;
    evt->fnname = buf;
    events_used++;
    //if (events_used == N_EVENTS)
      flushEvents(sb);
}
コード例 #5
0
ファイル: lk_main.c プロジェクト: bshafiee/Modified_Valgrind
/* Add an ordinary write event.  Try to merge it with an immediately
   preceding ordinary read event of the same size to the same
   address. */
static
void addEvent_Dw ( IRSB* sb, IRAtom* daddr, Int dsize )
{
   Event* lastEvt;
   Event* evt;
   tl_assert(clo_trace_mem);
   tl_assert(isIRAtom(daddr));
   tl_assert(dsize >= 1 && dsize <= MAX_DSIZE);

   // Is it possible to merge this write with the preceding read?
   lastEvt = &events[events_used-1];
   if (events_used > 0
       && lastEvt->ekind == Event_Dr
       && lastEvt->size  == dsize
       && lastEvt->guard == NULL
       && eqIRAtom(lastEvt->addr, daddr))
   {
      lastEvt->ekind = Event_Dm;
      return;
   }

   // No.  Add as normal.
   if (events_used == N_EVENTS)
      flushEvents(sb);
   tl_assert(events_used >= 0 && events_used < N_EVENTS);
   evt = &events[events_used];
   evt->ekind = Event_Dw;
   evt->size  = dsize;
   evt->addr  = daddr;
   evt->guard = NULL;
   events_used++;
}
コード例 #6
0
static
void addEvent_Dw ( CgState* cgs, InstrInfo* inode, Int datasize, IRAtom* ea )
{
   Event* lastEvt;
   Event* evt;

   tl_assert(isIRAtom(ea));
   tl_assert(datasize >= 1 && datasize <= MIN_LINE_SIZE);

   /* Is it possible to merge this write with the preceding read? */
   lastEvt = &cgs->events[cgs->events_used-1];
   if (cgs->events_used > 0
    && lastEvt->ekind    == Event_Dr
    && lastEvt->datasize == datasize
    && lastEvt->inode    == inode
    && eqIRAtom(lastEvt->dataEA, ea))
   {
      lastEvt->ekind = Event_Dm;
      return;
   }

   /* No.  Add as normal. */
   if (cgs->events_used == N_EVENTS)
      flushEvents(cgs);
   tl_assert(cgs->events_used >= 0 && cgs->events_used < N_EVENTS);
   evt = &cgs->events[cgs->events_used];
   evt->ekind    = Event_Dw;
   evt->inode    = inode;
   evt->datasize = datasize;
   evt->dataEA   = ea;
   cgs->events_used++;
}
コード例 #7
0
ファイル: fz_main.c プロジェクト: taveso/Concolic-testing
/*
    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));
    }
}
コード例 #8
0
ファイル: fz_main.c プロジェクト: taveso/Concolic-testing
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));
}
コード例 #9
0
ファイル: fz_main.c プロジェクト: taveso/Concolic-testing
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));
}
コード例 #10
0
ファイル: fz_main.c プロジェクト: taveso/Concolic-testing
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));
}
コード例 #11
0
ファイル: el_main.c プロジェクト: Legend/Elune
static
void addEvent_Dr ( IRSB* sb, IRAtom* daddr, Int dsize )
{
    Event* evt;
    tl_assert(isIRAtom(daddr));
    tl_assert(dsize >= 1 && dsize <= MAX_DSIZE);
    if (events_used == N_EVENTS)
        flushEvents(sb);
    tl_assert(events_used >= 0 && events_used < N_EVENTS);
    evt = &events[events_used];
    evt->ekind = Event_Dr;
    evt->addr  = daddr;
    evt->size  = dsize;
    events_used++;
}
コード例 #12
0
static
void addEvent_Dr ( CgState* cgs, InstrInfo* inode, Int datasize, IRAtom* ea )
{
   Event* evt;
   tl_assert(isIRAtom(ea));
   tl_assert(datasize >= 1 && datasize <= MIN_LINE_SIZE);
   if (cgs->events_used == N_EVENTS)
      flushEvents(cgs);
   tl_assert(cgs->events_used >= 0 && cgs->events_used < N_EVENTS);
   evt = &cgs->events[cgs->events_used];
   evt->ekind    = Event_Dr;
   evt->inode    = inode;
   evt->datasize = datasize;
   evt->dataEA   = ea;
   cgs->events_used++;
}
コード例 #13
0
ファイル: lk_main.c プロジェクト: bshafiee/Modified_Valgrind
/* Add a guarded write event. */
static
void addEvent_Dw_guarded ( IRSB* sb, IRAtom* daddr, Int dsize, IRAtom* guard )
{
   Event* evt;
   tl_assert(clo_trace_mem);
   tl_assert(isIRAtom(daddr));
   tl_assert(dsize >= 1 && dsize <= MAX_DSIZE);
   if (events_used == N_EVENTS)
      flushEvents(sb);
   tl_assert(events_used >= 0 && events_used < N_EVENTS);
   evt = &events[events_used];
   evt->ekind = Event_Dw;
   evt->addr  = daddr;
   evt->size  = dsize;
   evt->guard = guard;
   events_used++;
}
コード例 #14
0
ファイル: sh_main.c プロジェクト: gowthamk/Sherlock
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) );
}
コード例 #15
0
ファイル: fz_main.c プロジェクト: taveso/Concolic-testing
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));
}
コード例 #16
0
ファイル: fz_main.c プロジェクト: taveso/Concolic-testing
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));
}
コード例 #17
0
ファイル: sh_main.c プロジェクト: gowthamk/Sherlock
static
void addEvent_Dr ( IRSB* sb, char *fnname, IRAtom* daddr, Int dsize )
{
    Event* evt;
    tl_assert(clo_trace_mem);
    tl_assert(isIRAtom(daddr));
    tl_assert(dsize >= 1 && dsize <= MAX_DSIZE);
    char *buf = (char *)VG_(malloc)("addEvent_Dr",100*sizeof(char));
    tl_assert(buf!=NULL);
    VG_(strcpy)(buf,fnname);
    tl_assert(events_used >= 0 && events_used < N_EVENTS);
    evt = &events[events_used];
    evt->ekind = Event_Dr;
    evt->addr  = daddr;
    evt->size  = dsize;
    evt->fnname = buf;
    events_used++;
    //if (events_used == N_EVENTS)
      flushEvents(sb);
}
コード例 #18
0
ファイル: fz_main.c プロジェクト: taveso/Concolic-testing
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));
}
コード例 #19
0
ファイル: fz_main.c プロジェクト: taveso/Concolic-testing
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));
}
コード例 #20
0
static
IRBB* cg_instrument ( IRBB* bbIn, VexGuestLayout* layout, 
                      Addr64 orig_addr_noredir, VexGuestExtents* vge,
                      IRType gWordTy, IRType hWordTy )
{
   Int        i, isize;
   IRStmt*    st;
   Addr64     cia; /* address of current insn */
   CgState    cgs;
   IRTypeEnv* tyenv = bbIn->tyenv;
   InstrInfo* curr_inode = NULL;

   if (gWordTy != hWordTy) {
      /* We don't currently support this case. */
      VG_(tool_panic)("host/guest word size mismatch");
   }

   /* Set up BB, including copying of the where-next stuff. */
   cgs.bbOut           = emptyIRBB();
   cgs.bbOut->tyenv    = dopyIRTypeEnv(tyenv);
   tl_assert( isIRAtom(bbIn->next) );
   cgs.bbOut->next     = dopyIRExpr(bbIn->next);
   cgs.bbOut->jumpkind = bbIn->jumpkind;

   // Copy verbatim any IR preamble preceding the first IMark
   i = 0;
   while (i < bbIn->stmts_used && bbIn->stmts[i]->tag != Ist_IMark) {
      addStmtToIRBB( cgs.bbOut, bbIn->stmts[i] );
      i++;
   }

   // Get the first statement, and initial cia from it
   tl_assert(bbIn->stmts_used > 0);
   tl_assert(i < bbIn->stmts_used);
   st = bbIn->stmts[i];
   tl_assert(Ist_IMark == st->tag);
   cia = st->Ist.IMark.addr;

   // Set up running state and get block info
   cgs.events_used = 0;
   cgs.bbInfo      = get_BB_info(bbIn, (Addr)orig_addr_noredir);
   cgs.bbInfo_i    = 0;

   if (DEBUG_CG)
      VG_(printf)("\n\n---------- cg_instrument ----------\n");

   // Traverse the block, initialising inodes, adding events and flushing as
   // necessary.
   for (/*use current i*/; i < bbIn->stmts_used; i++) {

      st = bbIn->stmts[i];
      tl_assert(isFlatIRStmt(st));

      switch (st->tag) {
         case Ist_NoOp:
         case Ist_AbiHint:
         case Ist_Put:
         case Ist_PutI:
         case Ist_MFence:
            break;

         case Ist_IMark:
            cia   = st->Ist.IMark.addr;
            isize = st->Ist.IMark.len;

            // If Vex fails to decode an instruction, the size will be zero.
            // Pretend otherwise.
            if (isize == 0) isize = VG_MIN_INSTR_SZB;

            // Sanity-check size.
            tl_assert( (VG_MIN_INSTR_SZB <= isize && isize <= VG_MAX_INSTR_SZB)
                     || VG_CLREQ_SZB == isize );

            // Get space for and init the inode, record it as the current one.
            // Subsequent Dr/Dw/Dm events from the same instruction will 
            // also use it.
            curr_inode = setup_InstrInfo(&cgs, cia, isize);

            addEvent_Ir( &cgs, curr_inode );
            break;

         case Ist_Tmp: {
            IRExpr* data = st->Ist.Tmp.data;
            if (data->tag == Iex_Load) {
               IRExpr* aexpr = data->Iex.Load.addr;
               // Note also, endianness info is ignored.  I guess
               // that's not interesting.
               addEvent_Dr( &cgs, curr_inode, sizeofIRType(data->Iex.Load.ty), 
                                  aexpr );
            }
            break;
         }

         case Ist_Store: {
            IRExpr* data  = st->Ist.Store.data;
            IRExpr* aexpr = st->Ist.Store.addr;
            addEvent_Dw( &cgs, curr_inode, 
                         sizeofIRType(typeOfIRExpr(tyenv, data)), aexpr );
            break;
         }

         case Ist_Dirty: {
            Int      dataSize;
            IRDirty* d = st->Ist.Dirty.details;
            if (d->mFx != Ifx_None) {
               /* This dirty helper accesses memory.  Collect the details. */
               tl_assert(d->mAddr != NULL);
               tl_assert(d->mSize != 0);
               dataSize = d->mSize;
               // Large (eg. 28B, 108B, 512B on x86) data-sized
               // instructions will be done inaccurately, but they're
               // very rare and this avoids errors from hitting more
               // than two cache lines in the simulation.
               if (dataSize > MIN_LINE_SIZE)
                  dataSize = MIN_LINE_SIZE;
               if (d->mFx == Ifx_Read || d->mFx == Ifx_Modify)
                  addEvent_Dr( &cgs, curr_inode, dataSize, d->mAddr );
               if (d->mFx == Ifx_Write || d->mFx == Ifx_Modify)
                  addEvent_Dw( &cgs, curr_inode, dataSize, d->mAddr );
            } else {
               tl_assert(d->mAddr == NULL);
               tl_assert(d->mSize == 0);
            }
            break;
         }

         case Ist_Exit:
            /* We may never reach the next statement, so need to flush
               all outstanding transactions now. */
            flushEvents( &cgs );
            break;

         default:
            tl_assert(0);
            break;
      }

      /* Copy the original statement */
      addStmtToIRBB( cgs.bbOut, st );

      if (DEBUG_CG) {
         ppIRStmt(st);
         VG_(printf)("\n");
      }
   }

   /* At the end of the bb.  Flush outstandings. */
   flushEvents( &cgs );

   /* done.  stay sane ... */
   tl_assert(cgs.bbInfo_i == cgs.bbInfo->n_instrs);

   if (DEBUG_CG) {
      VG_(printf)( "goto {");
      ppIRJumpKind(bbIn->jumpkind);
      VG_(printf)( "} ");
      ppIRExpr( bbIn->next );
      VG_(printf)( "}\n");
   }

   return cgs.bbOut;
}
コード例 #21
0
ファイル: main.c プロジェクト: svn2github/valgrind-3
static
void collectStatementInfo(IRTypeEnv* tyenv, IRBB* bbOut, IRStmt* st,
                          Addr* instrAddr, UInt* instrLen,
                          IRExpr** loadAddrExpr, IRExpr** storeAddrExpr,
                          UInt* dataSize, IRType hWordTy)
{
    CLG_ASSERT(isFlatIRStmt(st));

    switch (st->tag) {
    case Ist_NoOp:
        break;

    case Ist_AbiHint:
        /* ABI hints aren't interesting.  Ignore. */
        break;

    case Ist_IMark:
        /* st->Ist.IMark.addr is a 64-bit int.  ULong_to_Ptr casts this
           to the host's native pointer type; if that is 32 bits then it
           discards the upper 32 bits.  If we are cachegrinding on a
           32-bit host then we are also ensured that the guest word size
           is 32 bits, due to the assertion in cg_instrument that the
           host and guest word sizes must be the same.  Hence
           st->Ist.IMark.addr will have been derived from a 32-bit guest
           code address and truncation of it is safe.  I believe this
           assignment should be correct for both 32- and 64-bit
           machines. */
        *instrAddr = (Addr)ULong_to_Ptr(st->Ist.IMark.addr);
        *instrLen =        st->Ist.IMark.len;
        break;

    case Ist_Tmp: {
        IRExpr* data = st->Ist.Tmp.data;
        if (data->tag == Iex_Load) {
            IRExpr* aexpr = data->Iex.Load.addr;
            CLG_ASSERT( isIRAtom(aexpr) );
            // Note also, endianness info is ignored.  I guess that's not
            // interesting.
            // XXX: repe cmpsb does two loads... the first one is ignored here!
            //tl_assert( NULL == *loadAddrExpr );          // XXX: ???
            *loadAddrExpr = aexpr;
            *dataSize = sizeofIRType(data->Iex.Load.ty);
        }
        break;
    }

    case Ist_Store: {
        IRExpr* data  = st->Ist.Store.data;
        IRExpr* aexpr = st->Ist.Store.addr;
        CLG_ASSERT( isIRAtom(aexpr) );
        if ( NULL == *storeAddrExpr ) {
            /* this is a kludge: ignore all except the first store from
               an instruction. */
            *storeAddrExpr = aexpr;
            *dataSize = sizeofIRType(typeOfIRExpr(tyenv, data));
        }
        break;
    }

    case Ist_Dirty: {
        IRDirty* d = st->Ist.Dirty.details;
        if (d->mFx != Ifx_None) {
            /* This dirty helper accesses memory.  Collect the
               details. */
            CLG_ASSERT(d->mAddr != NULL);
            CLG_ASSERT(d->mSize != 0);
            *dataSize = d->mSize;
            if (d->mFx == Ifx_Read || d->mFx == Ifx_Modify)
                *loadAddrExpr = d->mAddr;
            if (d->mFx == Ifx_Write || d->mFx == Ifx_Modify)
                *storeAddrExpr = d->mAddr;
        } else {
            CLG_ASSERT(d->mAddr == NULL);
            CLG_ASSERT(d->mSize == 0);
        }
        break;
    }

    case Ist_Put:
    case Ist_PutI:
    case Ist_MFence:
    case Ist_Exit:
        break;

    default:
        VG_(printf)("\n");
        ppIRStmt(st);
        VG_(printf)("\n");
        VG_(tool_panic)("Callgrind: unhandled IRStmt");
    }
}
コード例 #22
0
ファイル: main.c プロジェクト: svn2github/valgrind-3
static
EventSet* insert_simcall(IRBB* bbOut, InstrInfo* ii, UInt dataSize,
                         Bool instrIssued,
                         IRExpr* loadAddrExpr, IRExpr* storeAddrExpr)
{
    HChar*    helperName;
    void*     helperAddr;
    Int       argc;
    EventSet* es;
    IRExpr   *arg1, *arg2 = 0, *arg3 = 0, **argv;
    IRDirty* di;

    /* Check type of original instruction regarding memory access,
     * and collect info to be able to generate fitting helper call
     */
    if (!loadAddrExpr && !storeAddrExpr) {
        // no load/store
        CLG_ASSERT(0 == dataSize);
        if (instrIssued) {
            helperName = 0;
            helperAddr = 0;
        }
        else {
            helperName = CLG_(cachesim).log_1I0D_name;
            helperAddr = CLG_(cachesim).log_1I0D;
        }
        argc = 1;
        es = CLG_(sets).D0;

    } else if (loadAddrExpr && !storeAddrExpr) {
        // load
        CLG_ASSERT( isIRAtom(loadAddrExpr) );
        if (instrIssued) {
            helperName = CLG_(cachesim).log_0I1Dr_name;
            helperAddr = CLG_(cachesim).log_0I1Dr;
        }
        else {
            helperName = CLG_(cachesim).log_1I1Dr_name;
            helperAddr = CLG_(cachesim).log_1I1Dr;
        }
        argc = 2;
        arg2 = loadAddrExpr;
        es = CLG_(sets).D1r;

    } else if (!loadAddrExpr && storeAddrExpr) {
        // store
        CLG_ASSERT( isIRAtom(storeAddrExpr) );
        if (instrIssued) {
            helperName = CLG_(cachesim).log_0I1Dw_name;
            helperAddr = CLG_(cachesim).log_0I1Dw;
        }
        else {
            helperName = CLG_(cachesim).log_1I1Dw_name;
            helperAddr = CLG_(cachesim).log_1I1Dw;
        }
        argc = 2;
        arg2 = storeAddrExpr;
        es = CLG_(sets).D1w;

    } else {
        CLG_ASSERT( loadAddrExpr && storeAddrExpr );
        CLG_ASSERT( isIRAtom(loadAddrExpr) );
        CLG_ASSERT( isIRAtom(storeAddrExpr) );

        if ( loadStoreAddrsMatch(loadAddrExpr, storeAddrExpr) ) {
            /* modify: suppose write access, as this is
             * more resource consuming (as in callgrind for VG2)
             * Cachegrind does a read here (!)
             * DISCUSS: Best way depends on simulation model?
             */
            if (instrIssued) {
                helperName = CLG_(cachesim).log_0I1Dw_name;
                helperAddr = CLG_(cachesim).log_0I1Dw;
            }
            else {
                helperName = CLG_(cachesim).log_1I1Dw_name;
                helperAddr = CLG_(cachesim).log_1I1Dw;
            }
            argc = 2;
            arg2 = storeAddrExpr;
            es = CLG_(sets).D1w;

        } else {
            // load/store
            if (instrIssued) {
                helperName = CLG_(cachesim).log_0I2D_name;
                helperAddr = CLG_(cachesim).log_0I2D;
            }
            else {
                helperName = CLG_(cachesim).log_1I2D_name;
                helperAddr = CLG_(cachesim).log_1I2D;
            }
            argc = 3;
            arg2 = loadAddrExpr;
            arg3 = storeAddrExpr;
            es = CLG_(sets).D2;
        }
    }

    /* helper could be unset depending on the simulator used */
    if (helperAddr == 0) return 0;

    /* Setup 1st arg: InstrInfo */
    arg1 = mkIRExpr_HWord( (HWord)ii );

    // Add call to the instrumentation function
    if      (argc == 1)
        argv = mkIRExprVec_1(arg1);
    else if (argc == 2)
        argv = mkIRExprVec_2(arg1, arg2);
    else if (argc == 3)
        argv = mkIRExprVec_3(arg1, arg2, arg3);
    else
        VG_(tool_panic)("argc... not 1 or 2 or 3?");

    di = unsafeIRDirty_0_N( argc, helperName,
                            VG_(fnptr_to_fnentry)( helperAddr ), argv);
    addStmtToIRBB( bbOut, IRStmt_Dirty(di) );

    return es;
}
コード例 #23
0
ファイル: cg_main.c プロジェクト: svn2github/valgrind-3
static 
Bool handleOneStatement(IRTypeEnv* tyenv, IRBB* bbOut, IRStmt* st, IRStmt* st2,
                        Addr* instrAddr, UInt* instrLen,
                        IRExpr** loadAddrExpr, IRExpr** storeAddrExpr,
                        UInt* dataSize)
{
   tl_assert(isFlatIRStmt(st));

   switch (st->tag) {
   case Ist_NoOp:
   case Ist_AbiHint:
   case Ist_Put:
   case Ist_PutI:
   case Ist_MFence:
      break;

   case Ist_Exit: {
      // This is a conditional jump.  Most of the time, we want to add the
      // instrumentation before it, to ensure it gets executed.  Eg, (1) if
      // this conditional jump is just before an IMark:
      //
      //   t108 = Not1(t107)
      //   [add instrumentation here]
      //   if (t108) goto {Boring} 0x3A96637D:I32
      //   ------ IMark(0x3A966370, 7) ------
      //
      // or (2) if this conditional jump is the last thing before the
      // block-ending unconditional jump:
      //
      //   t111 = Not1(t110)
      //   [add instrumentation here]
      //   if (t111) goto {Boring} 0x3A96637D:I32
      //   goto {Boring} 0x3A966370:I32
      //
      // One case (3) where we want the instrumentation after the conditional
      // jump is when the conditional jump is for an x86 REP instruction:
      //
      //   ------ IMark(0x3A967F13, 2) ------
      //   t1 = GET:I32(4)
      //   t6 = CmpEQ32(t1,0x0:I32) 
      //   if (t6) goto {Boring} 0x3A967F15:I32    # ignore this cond jmp
      //   t7 = Sub32(t1,0x1:I32)
      //   PUT(4) = t7
      //   ...
      //   t56 = Not1(t55)
      //   [add instrumentation here]
      //   if (t56) goto {Boring} 0x3A967F15:I32
      //
      // Therefore, we return true if the next statement is an IMark, or if
      // there is no next statement (which matches case (2), as the final
      // unconditional jump is not represented in the IRStmt list).
      //
      // Note that this approach won't do in the long run for supporting
      // PPC, but it's good enough for x86/AMD64 for the 3.0.X series.
      if (NULL == st2 || Ist_IMark == st2->tag)
         return True;
      else
         return False;
   }

   case Ist_IMark:
      /* st->Ist.IMark.addr is a 64-bit int.  ULong_to_Ptr casts this
         to the host's native pointer type; if that is 32 bits then it
         discards the upper 32 bits.  If we are cachegrinding on a
         32-bit host then we are also ensured that the guest word size
         is 32 bits, due to the assertion in cg_instrument that the
         host and guest word sizes must be the same.  Hence
         st->Ist.IMark.addr will have been derived from a 32-bit guest
         code address and truncation of it is safe.  I believe this
         assignment should be correct for both 32- and 64-bit
         machines. */
      *instrAddr = (Addr)ULong_to_Ptr(st->Ist.IMark.addr);
      *instrLen =        st->Ist.IMark.len;
      break;

   case Ist_Tmp: {
      IRExpr* data = st->Ist.Tmp.data;
      if (data->tag == Iex_Load) {
         IRExpr* aexpr = data->Iex.Load.addr;
         tl_assert( isIRAtom(aexpr) );
         // Note also, endianness info is ignored.  I guess that's not
         // interesting.
         // XXX: repe cmpsb does two loads... the first one is ignored here!
         //tl_assert( NULL == *loadAddrExpr );          // XXX: ???
         *loadAddrExpr = aexpr;
         *dataSize = sizeofIRType(data->Iex.Load.ty);
      }
      break;
   }
      
   case Ist_Store: {
      IRExpr* data  = st->Ist.Store.data;
      IRExpr* aexpr = st->Ist.Store.addr;
      tl_assert( isIRAtom(aexpr) );
      tl_assert( NULL == *storeAddrExpr );          // XXX: ???
      *storeAddrExpr = aexpr;
      *dataSize = sizeofIRType(typeOfIRExpr(tyenv, data));
      break;
   }
   
   case Ist_Dirty: {
      IRDirty* d = st->Ist.Dirty.details;
      if (d->mFx != Ifx_None) {
         /* This dirty helper accesses memory.  Collect the
            details. */
         tl_assert(d->mAddr != NULL);
         tl_assert(d->mSize != 0);
         *dataSize = d->mSize;
         if (d->mFx == Ifx_Read || d->mFx == Ifx_Modify)
            *loadAddrExpr = d->mAddr;
         if (d->mFx == Ifx_Write || d->mFx == Ifx_Modify)
            *storeAddrExpr = d->mAddr;
      } else {
         tl_assert(d->mAddr == NULL);
         tl_assert(d->mSize == 0);
      }
      break;
   }

   default:
      VG_(printf)("\n");
      ppIRStmt(st);
      VG_(printf)("\n");
      VG_(tool_panic)("Cachegrind: unhandled IRStmt");
   }

   return False;
}
コード例 #24
0
ファイル: cg_main.c プロジェクト: svn2github/valgrind-3
// Instrumentation for the end of each original instruction.
static
void instrumentInstr(IRBB* bbOut, instr_info* i_node, Bool bbSeenBefore,
                     UInt instrAddr, UInt instrLen, UInt dataSize,
                     IRExpr* loadAddrExpr, IRExpr* storeAddrExpr)
{
   IRDirty* di;
   IRExpr  *arg1, *arg2, *arg3, **argv;
   Int      argc;
   Char*    helperName;
   void*    helperAddr;
   IRType   wordTy;

   // Stay sane ...
   tl_assert(sizeof(HWord) == sizeof(void*));
   if (sizeof(HWord) == 4) {
      wordTy = Ity_I32;
   } else
   if (sizeof(HWord) == 8) {
      wordTy = Ity_I64;
   } else {
      VG_(tool_panic)("instrumentInstr: strange word size");
   }

   if (loadAddrExpr) 
      tl_assert(wordTy == typeOfIRExpr(bbOut->tyenv, loadAddrExpr));
   if (storeAddrExpr) 
      tl_assert(wordTy == typeOfIRExpr(bbOut->tyenv, storeAddrExpr));


   // Nb: instrLen will be zero if Vex failed to decode it.
   tl_assert( 0 == instrLen ||
              (instrLen >= VG_MIN_INSTR_SZB && 
               instrLen <= VG_MAX_INSTR_SZB) );

   // Large (eg. 28B, 108B, 512B on x86) data-sized instructions will be
   // done inaccurately, but they're very rare and this avoids errors from
   // hitting more than two cache lines in the simulation.
   if (dataSize > MIN_LINE_SIZE) dataSize = MIN_LINE_SIZE;

   // Setup 1st arg: instr_info node's address
   // Believed to be 64-bit clean
   do_details(i_node, bbSeenBefore, instrAddr, instrLen, dataSize );
   arg1 = mkIRExpr_HWord( (HWord)i_node );

   if (!loadAddrExpr && !storeAddrExpr) {
      // no load/store
      tl_assert(0 == dataSize);
      helperName = "log_1I_0D_cache_access";
      helperAddr = &log_1I_0D_cache_access;
      argc = 1;
      argv = mkIRExprVec_1(arg1);

   } else if (loadAddrExpr && !storeAddrExpr) {
      // load
      tl_assert( isIRAtom(loadAddrExpr) );
      helperName = "log_1I_1Dr_cache_access";
      helperAddr = &log_1I_1Dr_cache_access;
      argc = 2;
      arg2 = loadAddrExpr;
      argv = mkIRExprVec_2(arg1, arg2);

   } else if (!loadAddrExpr && storeAddrExpr) {
      // store
      tl_assert( isIRAtom(storeAddrExpr) );
      helperName = "log_1I_1Dw_cache_access";
      helperAddr = &log_1I_1Dw_cache_access;
      argc = 2;
      arg2 = storeAddrExpr;
      argv = mkIRExprVec_2(arg1, arg2);
 
   } else {
      tl_assert( loadAddrExpr && storeAddrExpr );
      tl_assert( isIRAtom(loadAddrExpr) );
      tl_assert( isIRAtom(storeAddrExpr) );

      if ( loadStoreAddrsMatch(loadAddrExpr, storeAddrExpr) ) {
         // modify
         helperName = "log_1I_1Dr_cache_access";
         helperAddr = &log_1I_1Dr_cache_access;
         argc = 2;
         arg2 = loadAddrExpr;
         argv = mkIRExprVec_2(arg1, arg2);

      } else {
         // load/store
         helperName = "log_1I_2D_cache_access";
         helperAddr = &log_1I_2D_cache_access;
         argc = 3;
         arg2 = loadAddrExpr;
         arg3 = storeAddrExpr;
         argv = mkIRExprVec_3(arg1, arg2, arg3);
      }
   }

   // Add call to the instrumentation function
   di = unsafeIRDirty_0_N( argc, helperName, helperAddr, argv);
   addStmtToIRBB( bbOut, IRStmt_Dirty(di) );
}