|
From: Emre C. S. <ec...@nc...> - 2006-08-28 18:06:12
|
I'm trying to port my code from v2.4.0 to 3.2.0. I want the tool to be
able to track memory writes and for this purpose I'm trying to copy&paste
lackey. It is important that I capture the memory write before it happens
so instead of keeping a list of events and flushing them at the end of the
basic block, I try to deal with them on spot. After some basic blocks I
get the error:
(print outs from check_write_1 helper function)
...
BEFFE75C <- 400ED0D
BEFFE784 <- BEFFE822
BEFFE780 <- 0
vex: priv/host-x86/isel.c:510 (doHelperCall): Assertion
`typeOfIRExpr(env->type_env, args[i]) == Ity_I32' failed.
vex storage: T total 1181960 bytes allocated
valgrind: the 'impossible' happened:
LibVEX called failure_exit().
==25763== at 0x38002E32: report_and_quit (m_libcassert.c:136)
==25763== by 0x38002FFB: panic (m_libcassert.c:210)
==25763== by 0x3800301C: vgPlain_core_panic_at (m_libcassert.c:215)
==25763== by 0x3800302F: vgPlain_core_panic (m_libcassert.c:220)
==25763== by 0x380117B8: failure_exit (m_translate.c:487)
==25763== by 0x3804E232: vex_assert_fail (vex_util.c:218)
==25763== by 0x3805E461: doHelperCall (isel.c:560)
==25763== by 0x380640CD: iselStmt (isel.c:3520)
==25763== by 0x3806438A: iselBB_X86 (isel.c:3665)
==25763== by 0x3804D235: LibVEX_Translate (vex_main.c:561)
==25763== by 0x38011E5A: vgPlain_translate (m_translate.c:1097)
==25763== by 0x3801CAAB: handle_tt_miss (scheduler.c:693)
==25763== by 0x3801CF31: vgPlain_scheduler (scheduler.c:865)
==25763== by 0x3802AD98: thread_wrapper (syswrap-linux.c:87)
==25763== by 0x3802AE54: run_a_thread_NORETURN (syswrap-linux.c:120)
sched status:
running_tid=1
Thread 1: status = VgTs_Runnable
==25763== at 0x400ED3E: _dl_sysdep_start (in /lib/ld-2.3.2.so)
==25763== by 0x4000F22: _dl_start (in /lib/ld-2.3.2.so)
==25763== by 0x4000BE6: (within /lib/ld-2.3.2.so)
******************************************************
I use the same preamble for copying basic blocks in the instrumentation
code as lackey. Here is my helper function and how I call it:
static VG_REGPARM(2) void check_write_1 (Addr addr, UInt val)
{
VG_(printf)("%x <- %x\n", addr, val);
}
IRBB* dl_instrument ( VgCallbackClosure* closure,
IRBB* bbIn,
VexGuestLayout* layout,
VexGuestExtents* vge,
IRType gWordTy, IRType hWordTy )
{
IRDirty* di;
Int i;
IRBB* bbOut;
Char fnname[100];
IRType type;
IRTypeEnv* tyenv = bbIn->tyenv;
if (gWordTy != hWordTy) {
/* We don't currently support this case. */
VG_(tool_panic)("host/guest word size mismatch");
}
/* Set up BB */
bbOut = emptyIRBB();
bbOut->tyenv = dopyIRTypeEnv(bbIn->tyenv);
bbOut->next = dopyIRExpr(bbIn->next);
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( bbOut, bbIn->stmts[i] );
i++;
}
for (/*use current i*/; i < bbIn->stmts_used; i++) {
IRStmt* st = bbIn->stmts[i];
if (!st || st->tag == Ist_NoOp) continue;
switch (st->tag) {
case Ist_NoOp:
case Ist_IMark:
case Ist_AbiHint:
case Ist_Put:
case Ist_PutI:
case Ist_Tmp:
case Ist_MFence:
case Ist_Exit:
case Ist_Dirty:
addStmtToIRBB( bbOut, st );
break;
case Ist_Store:
{
IRExpr* data = st->Ist.Store.data;
IRExpr* addr = st->Ist.Store.addr;
if (addr!=NULL && data !=NULL)
{
IRExpr** argv = mkIRExprVec_2( addr, data );
di = unsafeIRDirty_0_N( /*regparms*/2, "check_write",
VG_(fnptr_to_fnentry)(
&check_write_1 ),
argv );
addStmtToIRBB( bbOut, IRStmt_Dirty(di) );
}
addStmtToIRBB( bbOut, st );
}
break;
...
********************************************
I'd appreciate any help. Also is there any documantation aside from the
example source codes I can look into?
Thank you,
John
|
|
From: Julian S. <js...@ac...> - 2006-08-28 18:50:55
|
> vex: priv/host-x86/isel.c:510 (doHelperCall): Assertion
> `typeOfIRExpr(env->type_env, args[i]) == Ity_I32' failed.
> vex storage: T total 1181960 bytes allocated
> case Ist_Store:
> {
> IRExpr* data = st->Ist.Store.data;
> IRExpr* addr = st->Ist.Store.addr;
> if (addr!=NULL && data !=NULL)
> {
> IRExpr** argv = mkIRExprVec_2( addr, data );
> di = unsafeIRDirty_0_N( /*regparms*/2, "check_write",
> VG_(fnptr_to_fnentry)(
> &check_write_1 ),
> argv );
> addStmtToIRBB( bbOut, IRStmt_Dirty(di) );
> }
> addStmtToIRBB( bbOut, st );
> }
I'd guess your problem is that the store data isn't of 32-bit type
(that is, 'data' in the above fragment has an IR type which isn't
Ity_I32). The VEX code generator only supports a very limited set
of argument types for helper functions - probably only I32
and I64 on x86.
If 'data' has type I8 or I16, I suggest you widen it to I32
by wrapping Iop_8Uto32 or Iop_16Uto32 around it. You may find
this useful:
/* U-widen 8/16/32 bit int expr to 32. */
static IRExpr* widenUto32 ( IRExpr* e )
{
switch (typeOfIRExpr(irbb->tyenv,e)) {
case Ity_I32: return e;
case Ity_I16: return unop(Iop_16Uto32,e);
case Ity_I8: return unop(Iop_8Uto32,e);
default: vpanic("widenUto32");
}
}
If 'data' has type I64, you can probably leave it unchanged.
If 'data' has type F64, I suggest you coerce it to I64 and
then act as I64. If that doesn't make sense, look in
guest-x86/toIR.c for "case 7: { /* FSTP extended-real */", which
passes a 64-bit float to a helper function.
If 'data' has type V128 (128-bit vector), you're probably
hosed :-)
J
|
|
From: Emre C. S. <ec...@nc...> - 2006-09-05 17:23:58
|
>
>> vex: priv/host-x86/isel.c:510 (doHelperCall): Assertion
>> `typeOfIRExpr(env->type_env, args[i]) == Ity_I32' failed.
>> vex storage: T total 1181960 bytes allocated
>
>> case Ist_Store:
>> {
>> IRExpr* data = st->Ist.Store.data;
>> IRExpr* addr = st->Ist.Store.addr;
>> if (addr!=NULL && data !=NULL)
>> {
>> IRExpr** argv = mkIRExprVec_2( addr, data );
>> di = unsafeIRDirty_0_N( /*regparms*/2,
>> "check_write",
>> VG_(fnptr_to_fnentry)(
>> &check_write_1 ),
>> argv );
>> addStmtToIRBB( bbOut, IRStmt_Dirty(di) );
>> }
>> addStmtToIRBB( bbOut, st );
>> }
>
> I'd guess your problem is that the store data isn't of 32-bit type
> (that is, 'data' in the above fragment has an IR type which isn't
> Ity_I32). The VEX code generator only supports a very limited set
> of argument types for helper functions - probably only I32
> and I64 on x86.
>
> If 'data' has type I8 or I16, I suggest you widen it to I32
> by wrapping Iop_8Uto32 or Iop_16Uto32 around it. You may find
> this useful:
>
> /* U-widen 8/16/32 bit int expr to 32. */
> static IRExpr* widenUto32 ( IRExpr* e )
> {
> switch (typeOfIRExpr(irbb->tyenv,e)) {
> case Ity_I32: return e;
> case Ity_I16: return unop(Iop_16Uto32,e);
> case Ity_I8: return unop(Iop_8Uto32,e);
> default: vpanic("widenUto32");
> }
> }
>
> If 'data' has type I64, you can probably leave it unchanged.
> If 'data' has type F64, I suggest you coerce it to I64 and
> then act as I64. If that doesn't make sense, look in
> guest-x86/toIR.c for "case 7: { /* FSTP extended-real */", which
> passes a 64-bit float to a helper function.
>
> If 'data' has type V128 (128-bit vector), you're probably
> hosed :-)
>
> J
>
First of thank you for the valuable reply. I pretty much copy pasted the
procedure with some minor changes (unop was replaced with IRExpr_Unop).
And wrapped the data argument with this function as follows:
static IRExpr* widenUto32 ( IRBB* irbb, IRExpr* e )
{
switch (typeOfIRExpr(irbb->tyenv,e)) {
case Ity_I32: return e;
case Ity_I16: return IRExpr_Unop(Iop_16Uto32,e);
case Ity_I8: return IRExpr_Unop(Iop_8Uto32,e);
default:
VG_(message)(**some error mesage**);
VG_(exit)(0);
}
}
case Ist_Store:
{
IRExpr* data = st->Ist.Store.data;
IRExpr* addr = st->Ist.Store.addr;
if (addr!=NULL && data !=NULL)
{
Only this line changed from previous code:
IRExpr** argv = mkIRExprVec_2( addr, widenUto32(data) );
di = unsafeIRDirty_0_N( /*regparms*/2, "check_write",
VG_(fnptr_to_fnentry)(
&check_write_1 ),
argv );
addStmtToIRBB( bbOut, IRStmt_Dirty(di) );
}
addStmtToIRBB( bbOut, st );
}
break;
Only this line changed from previous code:
IRExpr** argv = mkIRExprVec_2( addr, widenUto32( bbIn, data ) );
|