lackey: Take possible condition invertion for Jccs into account
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@6591 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/lackey/lk_main.c b/lackey/lk_main.c
index 2716d27..d6a5fdc 100644
--- a/lackey/lk_main.c
+++ b/lackey/lk_main.c
@@ -240,6 +240,8 @@
static ULong n_guest_instrs = 0;
static ULong n_Jccs = 0;
static ULong n_Jccs_untaken = 0;
+static ULong n_IJccs = 0;
+static ULong n_IJccs_untaken = 0;
static void add_one_func_call(void)
{
@@ -276,6 +278,16 @@
n_Jccs_untaken++;
}
+static void add_one_inverted_Jcc(void)
+{
+ n_IJccs++;
+}
+
+static void add_one_inverted_Jcc_untaken(void)
+{
+ n_IJccs_untaken++;
+}
+
/*------------------------------------------------------------*/
/*--- Stuff for --detailed-counts ---*/
/*------------------------------------------------------------*/
@@ -600,6 +612,9 @@
Char fnname[100];
IRType type;
IRTypeEnv* tyenv = sbIn->tyenv;
+ Addr iaddr = 0, dst;
+ UInt ilen = 0;
+ Bool condition_inverted = False;
if (gWordTy != hWordTy) {
/* We don't currently support this case. */
@@ -661,6 +676,10 @@
case Ist_IMark:
if (clo_basic_counts) {
+ /* Needed to be able to check for inverted condition in Ist_Exit */
+ iaddr = st->Ist.IMark.addr;
+ ilen = st->Ist.IMark.len;
+
/* Count guest instruction. */
di = unsafeIRDirty_0_N( 0, "add_one_guest_instr",
VG_(fnptr_to_fnentry)( &add_one_guest_instr ),
@@ -770,10 +789,23 @@
case Ist_Exit:
if (clo_basic_counts) {
+ // The condition of a branch was inverted by VEX if a taken
+ // branch is in fact a fall trough according to client address
+ tl_assert(iaddr != 0);
+ dst = (sizeof(Addr) == 4) ? st->Ist.Exit.dst->Ico.U32 :
+ st->Ist.Exit.dst->Ico.U64;
+ condition_inverted = (dst == iaddr + ilen);
+
/* Count Jcc */
- di = unsafeIRDirty_0_N( 0, "add_one_Jcc",
+ if (!condition_inverted)
+ di = unsafeIRDirty_0_N( 0, "add_one_Jcc",
VG_(fnptr_to_fnentry)( &add_one_Jcc ),
mkIRExprVec_0() );
+ else
+ di = unsafeIRDirty_0_N( 0, "add_one_inverted_Jcc",
+ VG_(fnptr_to_fnentry)( &add_one_inverted_Jcc ),
+ mkIRExprVec_0() );
+
addStmtToIRSB( sbOut, IRStmt_Dirty(di) );
}
if (clo_trace_mem) {
@@ -784,10 +816,17 @@
if (clo_basic_counts) {
/* Count non-taken Jcc */
- di = unsafeIRDirty_0_N( 0, "add_one_Jcc_untaken",
+ if (!condition_inverted)
+ di = unsafeIRDirty_0_N( 0, "add_one_Jcc_untaken",
VG_(fnptr_to_fnentry)(
&add_one_Jcc_untaken ),
mkIRExprVec_0() );
+ else
+ di = unsafeIRDirty_0_N( 0, "add_one_inverted_Jcc_untaken",
+ VG_(fnptr_to_fnentry)(
+ &add_one_inverted_Jcc_untaken ),
+ mkIRExprVec_0() );
+
addStmtToIRSB( sbOut, IRStmt_Dirty(di) );
}
break;
@@ -823,16 +862,19 @@
tl_assert(clo_fnname[0]);
if (clo_basic_counts) {
+ ULong total_Jccs = n_Jccs + n_IJccs;
+ ULong taken_Jccs = (n_Jccs - n_Jccs_untaken) + n_IJccs_untaken;
+
VG_(message)(Vg_UserMsg,
"Counted %,llu calls to %s()", n_func_calls, clo_fnname);
VG_(message)(Vg_UserMsg, "");
VG_(message)(Vg_UserMsg, "Jccs:");
- VG_(message)(Vg_UserMsg, " total: %,llu", n_Jccs);
- VG_(percentify)((n_Jccs - n_Jccs_untaken), (n_Jccs ? n_Jccs : 1),
+ VG_(message)(Vg_UserMsg, " total: %,llu", total_Jccs);
+ VG_(percentify)(taken_Jccs, (total_Jccs ? total_Jccs : 1),
percentify_decs, percentify_size, percentify_buf);
VG_(message)(Vg_UserMsg, " taken: %,llu (%s)",
- (n_Jccs - n_Jccs_untaken), percentify_buf);
+ taken_Jccs, percentify_buf);
VG_(message)(Vg_UserMsg, "");
VG_(message)(Vg_UserMsg, "Executed:");