|
From: Emre C. S. <ec...@nc...> - 2006-09-05 17:32:12
|
>
>> 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 all 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);
}
}
Here is the instrument code:
...
case Ist_Store:
{
IRExpr* data = st->Ist.Store.data;
IRExpr* addr = st->Ist.Store.addr;
if (addr!=NULL && data !=NULL)
{
Change here -> 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;
I get the following error with this code.
IN STATEMENT:
DIRTY 1:I1 ::: check_write[rp=2]{0x38000080}(t27,8Uto32(t24))
ERROR = IRStmt: is not flat
The code works fine if I only work with Ity_I32 type IRExpr's and don't
use widening. Does this error mean that I'm creating an IRExpr tree
instead of just a single expression?
Thank you in advance,
John
PS. Sorry for the double post. The previous email was incomplete.
|