Teach DRD about IRLoadG and IRStoreG. Includes small bug fix from

trunk r13209.


git-svn-id: svn://svn.valgrind.org/valgrind/branches/COMEM@13210
This commit is contained in:
Julian Seward 2012-12-27 17:47:09 +00:00
parent 701d76bca9
commit eca44c4855

View File

@ -312,7 +312,7 @@ static Bool is_stack_access(IRSB* const bb, IRExpr* const addr_expr)
if (addr_expr->tag == Iex_RdTmp)
{
int i;
for (i = 0; i < bb->stmts_size; i++)
for (i = 0; i < bb->stmts_used; i++)
{
if (bb->stmts[i]
&& bb->stmts[i]->tag == Ist_WrTmp
@ -344,21 +344,22 @@ static const IROp u_widen_irop[5][9] = {
* Instrument the client code to trace a memory load (--trace-addr).
*/
static IRExpr* instr_trace_mem_load(IRSB* const bb, IRExpr* addr_expr,
const HWord size)
const HWord size,
IRExpr* const guard/* NULL => True */)
{
IRTemp tmp;
tmp = newIRTemp(bb->tyenv, typeOfIRExpr(bb->tyenv, addr_expr));
addStmtToIRSB(bb, IRStmt_WrTmp(tmp, addr_expr));
addr_expr = IRExpr_RdTmp(tmp);
addStmtToIRSB(bb,
IRStmt_Dirty(
unsafeIRDirty_0_N(/*regparms*/2,
"drd_trace_mem_load",
VG_(fnptr_to_fnentry)
(drd_trace_mem_load),
mkIRExprVec_2(addr_expr, mkIRExpr_HWord(size)))));
IRDirty* di
= unsafeIRDirty_0_N(/*regparms*/2,
"drd_trace_mem_load",
VG_(fnptr_to_fnentry)
(drd_trace_mem_load),
mkIRExprVec_2(addr_expr, mkIRExpr_HWord(size)));
if (guard) di->guard = guard;
addStmtToIRSB(bb, IRStmt_Dirty(di));
return addr_expr;
}
@ -367,7 +368,8 @@ static IRExpr* instr_trace_mem_load(IRSB* const bb, IRExpr* addr_expr,
* Instrument the client code to trace a memory store (--trace-addr).
*/
static void instr_trace_mem_store(IRSB* const bb, IRExpr* const addr_expr,
IRExpr* data_expr_hi, IRExpr* data_expr_lo)
IRExpr* data_expr_hi, IRExpr* data_expr_lo,
IRExpr* const guard/* NULL => True */)
{
IRType ty_data_expr;
HWord size;
@ -453,18 +455,20 @@ static void instr_trace_mem_store(IRSB* const bb, IRExpr* const addr_expr,
data_expr_lo = mkIRExpr_HWord(0);
}
}
addStmtToIRSB(bb,
IRStmt_Dirty(
unsafeIRDirty_0_N(/*regparms*/3,
"drd_trace_mem_store",
VG_(fnptr_to_fnentry)(drd_trace_mem_store),
mkIRExprVec_4(addr_expr, mkIRExpr_HWord(size),
data_expr_hi ? data_expr_hi
: mkIRExpr_HWord(0), data_expr_lo))));
IRDirty* di
= unsafeIRDirty_0_N(/*regparms*/3,
"drd_trace_mem_store",
VG_(fnptr_to_fnentry)(drd_trace_mem_store),
mkIRExprVec_4(addr_expr, mkIRExpr_HWord(size),
data_expr_hi ? data_expr_hi
: mkIRExpr_HWord(0), data_expr_lo));
if (guard) di->guard = guard;
addStmtToIRSB(bb, IRStmt_Dirty(di) );
}
static void instrument_load(IRSB* const bb, IRExpr* const addr_expr,
const HWord size)
const HWord size,
IRExpr* const guard/* NULL => True */)
{
IRExpr* size_expr;
IRExpr** argv;
@ -512,11 +516,13 @@ static void instrument_load(IRSB* const bb, IRExpr* const addr_expr,
argv);
break;
}
if (guard) di->guard = guard;
addStmtToIRSB(bb, IRStmt_Dirty(di));
}
static void instrument_store(IRSB* const bb, IRExpr* addr_expr,
IRExpr* const data_expr)
IRExpr* const data_expr,
IRExpr* const guard_expr/* NULL => True */)
{
IRExpr* size_expr;
IRExpr** argv;
@ -529,7 +535,7 @@ static void instrument_store(IRSB* const bb, IRExpr* addr_expr,
IRTemp tmp = newIRTemp(bb->tyenv, typeOfIRExpr(bb->tyenv, addr_expr));
addStmtToIRSB(bb, IRStmt_WrTmp(tmp, addr_expr));
addr_expr = IRExpr_RdTmp(tmp);
instr_trace_mem_store(bb, addr_expr, NULL, data_expr);
instr_trace_mem_store(bb, addr_expr, NULL, data_expr, guard_expr);
}
if (!s_check_stack_accesses && is_stack_access(bb, addr_expr))
@ -574,6 +580,7 @@ static void instrument_store(IRSB* const bb, IRExpr* addr_expr,
argv);
break;
}
if (guard_expr) di->guard = guard_expr;
addStmtToIRSB(bb, IRStmt_Dirty(di));
}
@ -631,10 +638,38 @@ IRSB* DRD_(instrument)(VgCallbackClosure* const closure,
case Ist_Store:
if (instrument)
instrument_store(bb, st->Ist.Store.addr, st->Ist.Store.data);
instrument_store(bb, st->Ist.Store.addr, st->Ist.Store.data,
NULL/* no guard */);
addStmtToIRSB(bb, st);
break;
case Ist_StoreG: {
IRStoreG* sg = st->Ist.StoreG.details;
IRExpr* data = sg->data;
IRExpr* addr = sg->addr;
if (instrument)
instrument_store(bb, addr, data, sg->guard);
addStmtToIRSB(bb, st);
break;
}
case Ist_LoadG: {
IRLoadG* lg = st->Ist.LoadG.details;
IRType type = Ity_INVALID; /* loaded type */
IRType typeWide = Ity_INVALID; /* after implicit widening */
IRExpr* addr_expr = lg->addr;
typeOfIRLoadGOp(lg->cvt, &typeWide, &type);
tl_assert(type != Ity_INVALID);
if (UNLIKELY(DRD_(any_address_is_traced)())) {
addr_expr = instr_trace_mem_load(bb, addr_expr,
sizeofIRType(type), lg->guard);
}
instrument_load(bb, lg->addr,
sizeofIRType(type), lg->guard);
addStmtToIRSB(bb, st);
break;
}
case Ist_WrTmp:
if (instrument) {
const IRExpr* const data = st->Ist.WrTmp.data;
@ -642,10 +677,12 @@ IRSB* DRD_(instrument)(VgCallbackClosure* const closure,
if (data->tag == Iex_Load) {
if (UNLIKELY(DRD_(any_address_is_traced)())) {
addr_expr = instr_trace_mem_load(bb, addr_expr,
sizeofIRType(data->Iex.Load.ty));
sizeofIRType(data->Iex.Load.ty),
NULL/* no guard */);
}
instrument_load(bb, data->Iex.Load.addr,
sizeofIRType(data->Iex.Load.ty));
sizeofIRType(data->Iex.Load.ty),
NULL/* no guard */);
}
}
addStmtToIRSB(bb, st);
@ -709,9 +746,10 @@ IRSB* DRD_(instrument)(VgCallbackClosure* const closure,
dataSize *= 2; /* since it's a doubleword-CAS */
if (UNLIKELY(DRD_(any_address_is_traced)()))
instr_trace_mem_store(bb, cas->addr, cas->dataHi, cas->dataLo);
instr_trace_mem_store(bb, cas->addr, cas->dataHi, cas->dataLo,
NULL/* no guard */);
instrument_load(bb, cas->addr, dataSize);
instrument_load(bb, cas->addr, dataSize, NULL/*no guard*/);
}
addStmtToIRSB(bb, st);
break;
@ -730,14 +768,17 @@ IRSB* DRD_(instrument)(VgCallbackClosure* const closure,
IRExpr* addr_expr = st->Ist.LLSC.addr;
if (UNLIKELY(DRD_(any_address_is_traced)()))
addr_expr = instr_trace_mem_load(bb, addr_expr,
sizeofIRType(dataTy));
sizeofIRType(dataTy),
NULL /* no guard */);
instrument_load(bb, addr_expr, sizeofIRType(dataTy));
instrument_load(bb, addr_expr, sizeofIRType(dataTy),
NULL/*no guard*/);
}
} else {
/* SC */
instr_trace_mem_store(bb, st->Ist.LLSC.addr, NULL,
st->Ist.LLSC.storedata);
st->Ist.LLSC.storedata,
NULL/* no guard */);
}
addStmtToIRSB(bb, st);
break;