From: Julian Seward Date: Sun, 1 Dec 2002 02:07:08 +0000 (+0000) Subject: Merge patch from JeremyF: X-Git-Tag: svn/VALGRIND_1_9_4~107 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=21e9daa5d6febc1d1b87566d43cb8f868ae686e2;p=thirdparty%2Fvalgrind.git Merge patch from JeremyF: 56-chained-accounting Fix accounting for chained blocks, by only counting real unchain events, rather than the unchains used to establish the initial call to VG_(patch_me) at the jump site. Also a minor cleanup of the jump delta calculation in synth_jcond_lit. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@1340 --- diff --git a/coregrind/vg_dispatch.S b/coregrind/vg_dispatch.S index 08ae86ba67..60d031069f 100644 --- a/coregrind/vg_dispatch.S +++ b/coregrind/vg_dispatch.S @@ -181,13 +181,24 @@ dispatch_clientreq: jmp run_innerloop_exit -/* This is the translation chainer, our run-time linker, if you like. - - This enters with %eax pointing to next eip we want. If - we've already compiled that eip (ie, get a fast hit), we - backpatch the call instruction with a jump, and jump there. - Otherwise, we do a slow hit/compile through the normal path - (and get to do a backpatch next time through). +/* + This is the translation chainer, our run-time linker, if you like. + + VG_(patch_me) patches the call instruction in the jump site + with a jump to the generated code for the branch target. %eax + contains the original program's EIP - if we get a hit in + tt_fast, then the call is patched into a jump; otherwise it + simply drops back into the dispatch loop for normal + processing. + + The callsite is expected to look like: + call VG_(patch_me) + it will be transformed into + jmp $TARGETADDR + + The environment we're expecting on entry is: + %eax = branch target address (original code EIP) + *(%esp) = just after call */ .globl VG_(patch_me) VG_(patch_me): diff --git a/coregrind/vg_from_ucode.c b/coregrind/vg_from_ucode.c index 645988cd27..5085b43c97 100644 --- a/coregrind/vg_from_ucode.c +++ b/coregrind/vg_from_ucode.c @@ -1053,6 +1053,17 @@ Bool VG_(is_chained_jumpsite)(Addr a) return (*cp == 0xE9); /* 0xE9 -- jmp */ } +static +Bool is_fresh_jumpsite(UChar *cp) +{ + return + cp[0] == 0x0F && /* UD2 */ + cp[1] == 0x0B && + cp[2] == 0x0F && /* UD2 */ + cp[3] == 0x0B && + cp[4] == 0x90; /* NOP */ +} + /* Predicate used in sanity checks elsewhere - returns true if all jump-sites are calls to VG_(patch_me) */ Bool VG_(is_unchained_jumpsite)(Addr a) @@ -1098,12 +1109,14 @@ void VG_(unchain_jumpsite)(Addr a) if (VG_(is_unchained_jumpsite)(a)) return; /* don't write unnecessarily */ + if (!is_fresh_jumpsite(cp)) + VG_(bb_dechain_count)++; /* update stats */ + *cp++ = 0xE8; /* call */ *cp++ = (delta >> 0) & 0xff; *cp++ = (delta >> 8) & 0xff; *cp++ = (delta >> 16) & 0xff; *cp++ = (delta >> 24) & 0xff; - VG_(bb_dechain_count)++; /* update stats */ } /* This doesn't actually generate a call to VG_(patch_me), but @@ -1569,11 +1582,10 @@ static void synth_jcond_lit ( Condcode cond, Addr addr ) mov $0x4000d190,%eax // 5 mov %eax, VGOFF_(m_eip)(%ebp) // 3 call 0x40050f9a // 5 - $01 // 1 1: mov $0x4000d042,%eax call 0x40050f9a */ - delta = 5+3+5+1 -1; + delta = 5+3+5; } else delta = 5+1;