From: Julian Seward Date: Fri, 1 Jun 2012 16:11:41 +0000 (+0000) Subject: Track the change to IRDirty guest state effect annotations introduced X-Git-Tag: svn/VALGRIND_3_8_0~270 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=eadaa025669736c0b3323b6a3f4d1fcbb3157c3d;p=thirdparty%2Fvalgrind.git Track the change to IRDirty guest state effect annotations introduced in vex r2362. mc_translate.c: also do PCast 64->32 a bit more efficiently. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@12598 --- diff --git a/coregrind/m_gdbserver/m_gdbserver.c b/coregrind/m_gdbserver/m_gdbserver.c index 42bb198dd0..3bf7c02ce4 100644 --- a/coregrind/m_gdbserver/m_gdbserver.c +++ b/coregrind/m_gdbserver/m_gdbserver.c @@ -1022,12 +1022,16 @@ static void VG_(add_stmt_call_gdbserver) gdb interactions. */ di->nFxState = 2; - di->fxState[0].fx = Ifx_Read; - di->fxState[0].offset = layout->offset_SP; - di->fxState[0].size = layout->sizeof_SP; - di->fxState[1].fx = Ifx_Modify; - di->fxState[1].offset = layout->offset_IP; - di->fxState[1].size = layout->sizeof_IP; + di->fxState[0].fx = Ifx_Read; + di->fxState[0].offset = layout->offset_SP; + di->fxState[0].size = layout->sizeof_SP; + di->fxState[0].nRepeats = 0; + di->fxState[0].repeatLen = 0; + di->fxState[1].fx = Ifx_Modify; + di->fxState[1].offset = layout->offset_IP; + di->fxState[1].size = layout->sizeof_IP; + di->fxState[1].nRepeats = 0; + di->fxState[1].repeatLen = 0; addStmtToIRSB(irsb, IRStmt_Dirty(di)); diff --git a/coregrind/m_translate.c b/coregrind/m_translate.c index 17d4947a76..d0551019e0 100644 --- a/coregrind/m_translate.c +++ b/coregrind/m_translate.c @@ -262,7 +262,7 @@ IRSB* vg_SP_update_pass ( void* closureV, IRType gWordTy, IRType hWordTy ) { - Int i, j, minoff_ST, maxoff_ST, sizeof_SP, offset_SP; + Int i, j, k, minoff_ST, maxoff_ST, sizeof_SP, offset_SP; Int first_SP, last_SP, first_Put, last_Put; IRDirty *dcall, *d; IRStmt* st; @@ -334,6 +334,8 @@ IRSB* vg_SP_update_pass ( void* closureV, dcall->fxState[0].fx = Ifx_Read; \ dcall->fxState[0].offset = layout->offset_SP; \ dcall->fxState[0].size = layout->sizeof_SP; \ + dcall->fxState[0].nRepeats = 0; \ + dcall->fxState[0].repeatLen = 0; \ \ addStmtToIRSB( bb, IRStmt_Dirty(dcall) ); \ \ @@ -362,6 +364,8 @@ IRSB* vg_SP_update_pass ( void* closureV, dcall->fxState[0].fx = Ifx_Read; \ dcall->fxState[0].offset = layout->offset_SP; \ dcall->fxState[0].size = layout->sizeof_SP; \ + dcall->fxState[0].nRepeats = 0; \ + dcall->fxState[0].repeatLen = 0; \ \ addStmtToIRSB( bb, IRStmt_Dirty(dcall) ); \ \ @@ -597,13 +601,16 @@ IRSB* vg_SP_update_pass ( void* closureV, if (st->tag == Ist_Dirty) { d = st->Ist.Dirty.details; for (j = 0; j < d->nFxState; j++) { - minoff_ST = d->fxState[j].offset; - maxoff_ST = d->fxState[j].offset + d->fxState[j].size - 1; if (d->fxState[j].fx == Ifx_Read || d->fxState[j].fx == Ifx_None) continue; - if (!(offset_SP > maxoff_ST - || (offset_SP + sizeof_SP - 1) < minoff_ST)) - goto complain; + /* Enumerate the described state segments */ + for (k = 0; k < 1 + d->fxState[j].nRepeats; k++) { + minoff_ST = d->fxState[j].offset + k * d->fxState[j].repeatLen; + maxoff_ST = minoff_ST + d->fxState[j].size - 1; + if (!(offset_SP > maxoff_ST + || (offset_SP + sizeof_SP - 1) < minoff_ST)) + goto complain; + } } } diff --git a/memcheck/mc_translate.c b/memcheck/mc_translate.c index 0ddd7abc04..78ea906884 100644 --- a/memcheck/mc_translate.c +++ b/memcheck/mc_translate.c @@ -710,8 +710,8 @@ static IRAtom* mkPCastTo( MCEnv* mce, IRType dst_ty, IRAtom* vbits ) { IRType src_ty; IRAtom* tmp1; + /* Note, dst_ty is a shadow type, not an original type. */ - /* First of all, collapse vbits down to a single bit. */ tl_assert(isShadowAtom(mce,vbits)); src_ty = typeOfIRExpr(mce->sb->tyenv, vbits); @@ -723,11 +723,20 @@ static IRAtom* mkPCastTo( MCEnv* mce, IRType dst_ty, IRAtom* vbits ) return assignNew('V', mce, Ity_I64, unop(Iop_CmpwNEZ64, vbits)); if (src_ty == Ity_I32 && dst_ty == Ity_I64) { + /* PCast the arg, then clone it. */ IRAtom* tmp = assignNew('V', mce, Ity_I32, unop(Iop_CmpwNEZ32, vbits)); return assignNew('V', mce, Ity_I64, binop(Iop_32HLto64, tmp, tmp)); } + if (src_ty == Ity_I64 && dst_ty == Ity_I32) { + /* PCast the arg. This gives all 0s or all 1s. Then throw away + the top half. */ + IRAtom* tmp = assignNew('V', mce, Ity_I64, unop(Iop_CmpwNEZ64, vbits)); + return assignNew('V', mce, Ity_I32, unop(Iop_64to32, tmp)); + } + /* Else do it the slow way .. */ + /* First of all, collapse vbits down to a single bit. */ tmp1 = NULL; switch (src_ty) { case Ity_I1: @@ -1027,12 +1036,16 @@ static IRAtom* schemeE ( MCEnv* mce, IRExpr* e ); /* fwds */ static void setHelperAnns ( MCEnv* mce, IRDirty* di ) { di->nFxState = 2; - di->fxState[0].fx = Ifx_Read; - di->fxState[0].offset = mce->layout->offset_SP; - di->fxState[0].size = mce->layout->sizeof_SP; - di->fxState[1].fx = Ifx_Read; - di->fxState[1].offset = mce->layout->offset_IP; - di->fxState[1].size = mce->layout->sizeof_IP; + di->fxState[0].fx = Ifx_Read; + di->fxState[0].offset = mce->layout->offset_SP; + di->fxState[0].size = mce->layout->sizeof_SP; + di->fxState[0].nRepeats = 0; + di->fxState[0].repeatLen = 0; + di->fxState[1].fx = Ifx_Read; + di->fxState[1].offset = mce->layout->offset_IP; + di->fxState[1].size = mce->layout->sizeof_IP; + di->fxState[1].nRepeats = 0; + di->fxState[1].repeatLen = 0; } @@ -4180,7 +4193,7 @@ static IRType szToITy ( Int n ) static void do_shadow_Dirty ( MCEnv* mce, IRDirty* d ) { - Int i, n, toDo, gSz, gOff; + Int i, k, n, toDo, gSz, gOff; IRAtom *src, *here, *curr; IRType tySrc, tyDst; IRTemp dst; @@ -4217,34 +4230,37 @@ void do_shadow_Dirty ( MCEnv* mce, IRDirty* d ) if (d->fxState[i].fx == Ifx_Write) continue; - /* Ignore any sections marked as 'always defined'. */ - if (isAlwaysDefd(mce, d->fxState[i].offset, d->fxState[i].size )) { - if (0) - VG_(printf)("memcheck: Dirty gst: ignored off %d, sz %d\n", - d->fxState[i].offset, d->fxState[i].size ); - continue; - } + /* Enumerate the described state segments */ + for (k = 0; k < 1 + d->fxState[i].nRepeats; k++) { + gOff = d->fxState[i].offset + k * d->fxState[i].repeatLen; + gSz = d->fxState[i].size; + + /* Ignore any sections marked as 'always defined'. */ + if (isAlwaysDefd(mce, gOff, gSz)) { + if (0) + VG_(printf)("memcheck: Dirty gst: ignored off %d, sz %d\n", + gOff, gSz); + continue; + } - /* This state element is read or modified. So we need to - consider it. If larger than 8 bytes, deal with it in 8-byte - chunks. */ - gSz = d->fxState[i].size; - gOff = d->fxState[i].offset; - tl_assert(gSz > 0); - while (True) { - if (gSz == 0) break; - n = gSz <= 8 ? gSz : 8; - /* update 'curr' with UifU of the state slice - gOff .. gOff+n-1 */ - tySrc = szToITy( n ); - src = assignNew( 'V', mce, tySrc, - shadow_GET(mce, gOff, tySrc ) ); - here = mkPCastTo( mce, Ity_I32, src ); - curr = mkUifU32(mce, here, curr); - gSz -= n; - gOff += n; + /* This state element is read or modified. So we need to + consider it. If larger than 8 bytes, deal with it in + 8-byte chunks. */ + while (True) { + tl_assert(gSz >= 0); + if (gSz == 0) break; + n = gSz <= 8 ? gSz : 8; + /* update 'curr' with UifU of the state slice + gOff .. gOff+n-1 */ + tySrc = szToITy( n ); + src = assignNew( 'V', mce, tySrc, + shadow_GET(mce, gOff, tySrc ) ); + here = mkPCastTo( mce, Ity_I32, src ); + curr = mkUifU32(mce, here, curr); + gSz -= n; + gOff += n; + } } - } /* Inputs: memory. First set up some info needed regardless of @@ -4309,26 +4325,32 @@ void do_shadow_Dirty ( MCEnv* mce, IRDirty* d ) tl_assert(d->fxState[i].fx != Ifx_None); if (d->fxState[i].fx == Ifx_Read) continue; - /* Ignore any sections marked as 'always defined'. */ - if (isAlwaysDefd(mce, d->fxState[i].offset, d->fxState[i].size )) - continue; - /* This state element is written or modified. So we need to - consider it. If larger than 8 bytes, deal with it in 8-byte - chunks. */ - gSz = d->fxState[i].size; - gOff = d->fxState[i].offset; - tl_assert(gSz > 0); - while (True) { - if (gSz == 0) break; - n = gSz <= 8 ? gSz : 8; - /* Write suitably-casted 'curr' to the state slice - gOff .. gOff+n-1 */ - tyDst = szToITy( n ); - do_shadow_PUT( mce, gOff, - NULL, /* original atom */ - mkPCastTo( mce, tyDst, curr ) ); - gSz -= n; - gOff += n; + + /* Enumerate the described state segments */ + for (k = 0; k < 1 + d->fxState[i].nRepeats; k++) { + gOff = d->fxState[i].offset + k * d->fxState[i].repeatLen; + gSz = d->fxState[i].size; + + /* Ignore any sections marked as 'always defined'. */ + if (isAlwaysDefd(mce, gOff, gSz)) + continue; + + /* This state element is written or modified. So we need to + consider it. If larger than 8 bytes, deal with it in + 8-byte chunks. */ + while (True) { + tl_assert(gSz >= 0); + if (gSz == 0) break; + n = gSz <= 8 ? gSz : 8; + /* Write suitably-casted 'curr' to the state slice + gOff .. gOff+n-1 */ + tyDst = szToITy( n ); + do_shadow_PUT( mce, gOff, + NULL, /* original atom */ + mkPCastTo( mce, tyDst, curr ) ); + gSz -= n; + gOff += n; + } } } @@ -5776,7 +5798,7 @@ static IRAtom* schemeE ( MCEnv* mce, IRExpr* e ) static void do_origins_Dirty ( MCEnv* mce, IRDirty* d ) { // This is a hacked version of do_shadow_Dirty - Int i, n, toDo, gSz, gOff; + Int i, k, n, toDo, gSz, gOff; IRAtom *here, *curr; IRTemp dst; @@ -5801,38 +5823,42 @@ static void do_origins_Dirty ( MCEnv* mce, IRDirty* d ) if (d->fxState[i].fx == Ifx_Write) continue; - /* Ignore any sections marked as 'always defined'. */ - if (isAlwaysDefd(mce, d->fxState[i].offset, d->fxState[i].size )) { - if (0) - VG_(printf)("memcheck: Dirty gst: ignored off %d, sz %d\n", - d->fxState[i].offset, d->fxState[i].size ); - continue; - } + /* Enumerate the described state segments */ + for (k = 0; k < 1 + d->fxState[i].nRepeats; k++) { + gOff = d->fxState[i].offset + k * d->fxState[i].repeatLen; + gSz = d->fxState[i].size; + + /* Ignore any sections marked as 'always defined'. */ + if (isAlwaysDefd(mce, gOff, gSz)) { + if (0) + VG_(printf)("memcheck: Dirty gst: ignored off %d, sz %d\n", + gOff, gSz); + continue; + } - /* This state element is read or modified. So we need to - consider it. If larger than 4 bytes, deal with it in 4-byte - chunks. */ - gSz = d->fxState[i].size; - gOff = d->fxState[i].offset; - tl_assert(gSz > 0); - while (True) { - Int b_offset; - if (gSz == 0) break; - n = gSz <= 4 ? gSz : 4; - /* update 'curr' with maxU32 of the state slice - gOff .. gOff+n-1 */ - b_offset = MC_(get_otrack_shadow_offset)(gOff, 4); - if (b_offset != -1) { - here = assignNew( 'B',mce, - Ity_I32, - IRExpr_Get(b_offset + 2*mce->layout->total_sizeB, - Ity_I32)); - curr = gen_maxU32( mce, curr, here ); + /* This state element is read or modified. So we need to + consider it. If larger than 4 bytes, deal with it in + 4-byte chunks. */ + while (True) { + Int b_offset; + tl_assert(gSz >= 0); + if (gSz == 0) break; + n = gSz <= 4 ? gSz : 4; + /* update 'curr' with maxU32 of the state slice + gOff .. gOff+n-1 */ + b_offset = MC_(get_otrack_shadow_offset)(gOff, 4); + if (b_offset != -1) { + here = assignNew( 'B',mce, + Ity_I32, + IRExpr_Get(b_offset + + 2*mce->layout->total_sizeB, + Ity_I32)); + curr = gen_maxU32( mce, curr, here ); + } + gSz -= n; + gOff += n; } - gSz -= n; - gOff += n; } - } /* Inputs: memory */ @@ -5884,28 +5910,33 @@ static void do_origins_Dirty ( MCEnv* mce, IRDirty* d ) if (d->fxState[i].fx == Ifx_Read) continue; - /* Ignore any sections marked as 'always defined'. */ - if (isAlwaysDefd(mce, d->fxState[i].offset, d->fxState[i].size )) - continue; - - /* This state element is written or modified. So we need to - consider it. If larger than 4 bytes, deal with it in 4-byte - chunks. */ - gSz = d->fxState[i].size; - gOff = d->fxState[i].offset; - tl_assert(gSz > 0); - while (True) { - Int b_offset; - if (gSz == 0) break; - n = gSz <= 4 ? gSz : 4; - /* Write 'curr' to the state slice gOff .. gOff+n-1 */ - b_offset = MC_(get_otrack_shadow_offset)(gOff, 4); - if (b_offset != -1) { - stmt( 'B', mce, IRStmt_Put(b_offset + 2*mce->layout->total_sizeB, - curr )); + /* Enumerate the described state segments */ + for (k = 0; k < 1 + d->fxState[i].nRepeats; k++) { + gOff = d->fxState[i].offset + k * d->fxState[i].repeatLen; + gSz = d->fxState[i].size; + + /* Ignore any sections marked as 'always defined'. */ + if (isAlwaysDefd(mce, gOff, gSz)) + continue; + + /* This state element is written or modified. So we need to + consider it. If larger than 4 bytes, deal with it in + 4-byte chunks. */ + while (True) { + Int b_offset; + tl_assert(gSz >= 0); + if (gSz == 0) break; + n = gSz <= 4 ? gSz : 4; + /* Write 'curr' to the state slice gOff .. gOff+n-1 */ + b_offset = MC_(get_otrack_shadow_offset)(gOff, 4); + if (b_offset != -1) { + stmt( 'B', mce, IRStmt_Put(b_offset + + 2*mce->layout->total_sizeB, + curr )); + } + gSz -= n; + gOff += n; } - gSz -= n; - gOff += n; } }