|
From: <sv...@va...> - 2006-10-19 13:22:23
|
Author: sewardj
Date: 2006-10-19 14:22:16 +0100 (Thu, 19 Oct 2006)
New Revision: 6322
Log:
Fix bug in memcheck's instrumenter introduced in r6319. Big comment
in the code explains it. Sigh. Why can't anything be simple?
Modified:
trunk/include/pub_tool_tooliface.h
trunk/memcheck/mc_translate.c
Modified: trunk/include/pub_tool_tooliface.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/include/pub_tool_tooliface.h 2006-10-18 23:46:26 UTC (rev 6321)
+++ trunk/include/pub_tool_tooliface.h 2006-10-19 13:22:16 UTC (rev 6322)
@@ -226,6 +226,11 @@
{x86,amd64,ppc32}-linux; on those platforms, wrappers can
longjump and recurse arbitrarily and everything should work
fine.
+
+ Note that copying the preamble verbatim may cause complications
+ for your instrumenter if you shadow IR temporaries. See big
+ comment in MC_(instrument) in memcheck/mc_translate.c for
+ details.
*/
IRBB*(*instrument)(VgCallbackClosure* closure,=20
IRBB* bb_in,=20
Modified: trunk/memcheck/mc_translate.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/memcheck/mc_translate.c 2006-10-18 23:46:26 UTC (rev 6321)
+++ trunk/memcheck/mc_translate.c 2006-10-19 13:22:16 UTC (rev 6322)
@@ -117,7 +117,7 @@
that, and the tmpMap is updated to reflect the new binding.
=20
A corollary is that if the tmpMap maps a given tmp to
- INVALID_IRTEMP and we are hoping to read that shadow tmp, it means
+ IRTemp_INVALID and we are hoping to read that shadow tmp, it means
there's a read-before-write error in the original tmps. The IR
sanity checker should catch all such anomalies, however. =20
*/
@@ -233,7 +233,7 @@
case Ity_I32: return IRExpr_Const(IRConst_U32(0));
case Ity_I64: return IRExpr_Const(IRConst_U64(0));
case Ity_V128: return IRExpr_Const(IRConst_V128(0x0000));
- default: VG_(tool_panic)("memcheck:definedOfType");
+ default: VG_(tool_panic)("memcheck:definedOfType");
}
}
=20
@@ -3281,7 +3281,7 @@
=20
bogus =3D False;
=20
- for (i =3D 0; i < bb_in->stmts_used; i++) {
+ for (i =3D 0; i < bb_in->stmts_used; i++) {
=20
st =3D bb_in->stmts[i];
tl_assert(st);
@@ -3302,6 +3302,8 @@
=20
/* Copy verbatim any IR preamble preceding the first IMark */
=20
+ tl_assert(mce.bb =3D=3D bb);
+
i =3D 0;
while (i < bb_in->stmts_used && bb_in->stmts[i]->tag !=3D Ist_IMark) =
{
=20
@@ -3313,6 +3315,40 @@
i++;
}
=20
+ /* Nasty problem. IR optimisation of the pre-instrumented IR may
+ cause the IR following the preamble to contain references to IR
+ temporaries defined in the preamble. Because the preamble isn't
+ instrumented, these temporaries don't have any shadows.
+ Nevertheless uses of them following the preamble will cause
+ memcheck to generate references to their shadows. End effect is
+ to cause IR sanity check failures, due to references to
+ non-existent shadows. This is only evident for the complex
+ preambles used for function wrapping on TOC-afflicted platforms
+ (ppc64-linux, ppc32-aix5, ppc64-aix5).
+
+ The following loop therefore scans the preamble looking for
+ assignments to temporaries. For each one found it creates an
+ assignment to the corresponding shadow temp, marking it as
+ 'defined'. This is the same resulting IR as if the main
+ instrumentation loop before had been applied to the statement
+ 'tmp =3D CONSTANT'.
+ */
+ for (j =3D 0; j < i; j++) {
+ if (bb_in->stmts[j]->tag =3D=3D Ist_Tmp) {
+ /* findShadowTmp checks its arg is an original tmp;
+ no need to assert that here. */
+ IRTemp tmp_o =3D bb_in->stmts[j]->Ist.Tmp.tmp;
+ IRTemp tmp_s =3D findShadowTmp(&mce, tmp_o);
+ IRType ty_s =3D typeOfIRTemp(bb->tyenv, tmp_s);
+ assign( bb, tmp_s, definedOfType( ty_s ) );
+ if (0) {
+ VG_(printf)("create shadow tmp for preamble tmp [%d] ty ", j=
);
+ ppIRType( ty_s );
+ VG_(printf)("\n");
+ }
+ }
+ }
+
/* Iterate over the remaining stmts to generate instrumentation. */
=20
tl_assert(bb_in->stmts_used > 0);
|