- Added the --mod-funcname option to cg_diff.
- Further reduction in overheads caused by --smc-check=all, especially
on 64-bit targets.
+- new variant --smc-check=all-non-file
* IBM z/Architecture (s390x) running Linux
Valgrind can analyse 64-bit programs running on z/Architecture.
" part of the path after 'string'. Allows removal\n"
" of path prefixes. Use this flag multiple times\n"
" to specify a set of prefixes to remove.\n"
-" --smc-check=none|stack|all checks for self-modifying code: none,\n"
-" only for code found in stacks, or all [stack]\n"
+" --smc-check=none|stack|all|all-non-file [stack]\n"
+" checks for self-modifying code: none, only for\n"
+" code found in stacks, for all code, or for all\n"
+" code except that from file-backed mappings\n"
" --read-var-info=yes|no read debug info on stack and global variables\n"
" and use it to print better error messages in\n"
" tools that make use of it (Memcheck, Helgrind,\n"
Vg_SmcStack);
else if VG_XACT_CLO(arg, "--smc-check=all", VG_(clo_smc_check),
Vg_SmcAll);
+ else if VG_XACT_CLO(arg, "--smc-check=all-non-file",
+ VG_(clo_smc_check),
+ Vg_SmcAllNonFile);
else if VG_STR_CLO (arg, "--kernel-variant", VG_(clo_kernel_variant)) {}
}
-/* Is a self-check required for a translation of a guest address
- inside segment SEG when requested by thread TID ? */
+/* Produce a bitmask stating which of the supplied extents needs a
+ self-check. See documentation of
+ VexTranslateArgs::needs_self_check for more details about the
+ return convention. */
-static Bool self_check_required ( NSegment const* seg, ThreadId tid )
+static UInt needs_self_check ( void* closureV,
+ VexGuestExtents* vge )
{
-#if defined(VGO_darwin)
- // GrP fixme hack - dyld i386 IMPORT gets rewritten
- // to really do this correctly, we'd need to flush the
- // translation cache whenever a segment became +WX
- if (seg->hasX && seg->hasW) {
- return True;
- }
-#endif
- switch (VG_(clo_smc_check)) {
- case Vg_SmcNone: return False;
- case Vg_SmcAll: return True;
- case Vg_SmcStack:
- return seg
- ? (seg->start <= VG_(get_SP)(tid)
- && VG_(get_SP)(tid)+sizeof(Word)-1 <= seg->end)
- : False;
- break;
- default:
- vg_assert2(0, "unknown VG_(clo_smc_check) value");
+ VgCallbackClosure* closure = (VgCallbackClosure*)closureV;
+ UInt i, bitset;
+
+ vg_assert(vge->n_used >= 1 && vge->n_used <= 3);
+ bitset = 0;
+
+ for (i = 0; i < vge->n_used; i++) {
+ Bool check = False;
+ Addr addr = (Addr)vge->base[i];
+ SizeT len = (SizeT)vge->len[i];
+ NSegment const* segA = NULL;
+
+# if defined(VGO_darwin)
+ // GrP fixme hack - dyld i386 IMPORT gets rewritten.
+ // To really do this correctly, we'd need to flush the
+ // translation cache whenever a segment became +WX.
+ segA = VG_(am_find_nsegment)(addr);
+ if (segA && segA->hasX && segA->hasW)
+ check = True;
+# endif
+
+ if (!check) {
+ switch (VG_(clo_smc_check)) {
+ case Vg_SmcNone:
+ /* never check (except as per Darwin hack above) */
+ break;
+ case Vg_SmcAll:
+ /* always check */
+ check = True;
+ break;
+ case Vg_SmcStack: {
+ /* check if the address is in the same segment as this
+ thread's stack pointer */
+ Addr sp = VG_(get_SP)(closure->tid);
+ if (!segA) {
+ segA = VG_(am_find_nsegment)(addr);
+ }
+ NSegment const* segSP = VG_(am_find_nsegment)(sp);
+ if (segA && segSP && segA == segSP)
+ check = True;
+ break;
+ }
+ case Vg_SmcAllNonFile: {
+ /* check if any part of the extent is not in a
+ file-mapped segment */
+ if (!segA) {
+ segA = VG_(am_find_nsegment)(addr);
+ }
+ if (segA && segA->kind == SkFileC && segA->start <= addr
+ && (len == 0 || addr + len <= segA->end + 1)) {
+ /* in a file-mapped segment; skip the check */
+ } else {
+ check = True;
+ }
+ break;
+ }
+ default:
+ vg_assert(0);
+ }
+ }
+
+ if (check)
+ bitset |= (1 << i);
}
+
+ return bitset;
}
/* This is a callback passed to LibVEX_Translate. It stops Vex from
chasing into function entry points that we wish to redirect.
Chasing across them obviously defeats the redirect mechanism, with
- bad effects for Memcheck, Addrcheck, and possibly others.
-
- Also, we must stop Vex chasing into blocks for which we might want
- to self checking.
+ bad effects for Memcheck, Helgrind, DRD, Massif, and possibly others.
*/
static Bool chase_into_ok ( void* closureV, Addr64 addr64 )
{
Addr64 addr;
T_Kind kind;
Int tmpbuf_used, verbosity, i;
- Bool do_self_check;
Bool (*preamble_fn)(void*,IRSB*);
VexArch vex_arch;
VexArchInfo vex_archinfo;
return False;
}
- /* Do we want a self-checking translation? */
- do_self_check = self_check_required( seg, tid );
-
/* True if a debug trans., or if bit N set in VG_(clo_trace_codegen). */
verbosity = 0;
if (debugging_translation) {
vta.finaltidy = VG_(needs).final_IR_tidy_pass
? VG_(tdict).tool_final_IR_tidy_pass
: NULL;
- vta.do_self_check = do_self_check;
+ vta.needs_self_check = needs_self_check;
vta.traceflags = verbosity;
/* Set up the dispatch-return info. For archs without a link
/* Sheesh. Finally, actually _do_ the translation! */
tres = LibVEX_Translate ( &vta );
- vg_assert(tres == VexTransOK);
+ vg_assert(tres.status == VexTransOK);
+ vg_assert(tres.n_sc_extents >= 0 && tres.n_sc_extents <= 3);
vg_assert(tmpbuf_used <= N_TMPBUF);
vg_assert(tmpbuf_used > 0);
nraddr,
(Addr)(&tmpbuf[0]),
tmpbuf_used,
- do_self_check );
+ tres.n_sc_extents > 0 );
} else {
VG_(add_to_unredir_transtab)( &vge,
nraddr,
Vg_SmcNone, // never generate self-checking translations
Vg_SmcStack, // generate s-c-t's for code found in stacks
// (this is the default)
- Vg_SmcAll // make all translations self-checking.
+ Vg_SmcAll, // make all translations self-checking.
+ Vg_SmcAllNonFile // make all translations derived from
+ // non-file-backed memory self checking
}
VgSmc;
<varlistentry id="opt.smc-check" xreflabel="--smc-check">
<term>
- <option><![CDATA[--smc-check=<none|stack|all> [default: stack] ]]></option>
+ <option><![CDATA[--smc-check=<none|stack|all|all-non-file> [default: stack] ]]></option>
</term>
<listitem>
<para>This option controls Valgrind's detection of self-modifying
continue to execute the translations it made for the old code. This
will likely lead to incorrect behaviour and/or crashes.</para>
- <para>Valgrind has three levels of self-modifying code detection:
+ <para>Valgrind has four levels of self-modifying code detection:
no detection, detect self-modifying code on the stack (which is used by
- GCC to implement nested functions), or detect self-modifying code
- everywhere. Note that the default option will catch the vast majority
+ GCC to implement nested functions), detect self-modifying code
+ everywhere, and detect self-modifying code everywhere except in
+ file-backed mappings.
+
+ Note that the default option will catch the vast majority
of cases. The main case it will not catch is programs such as JIT
compilers that dynamically generate code <emphasis>and</emphasis>
subsequently overwrite part or all of it. Running with
- <varname>all</varname> will slow Valgrind down noticeably. Running with
+ <varname>all</varname> will slow Valgrind down noticeably.
+ Running with
<varname>none</varname> will rarely speed things up, since very little
code gets put on the stack for most programs. The
- <function>VALGRIND_DISCARD_TRANSLATIONS</function> client request is
- an alternative to <option>--smc-check=all</option> that requires more
- effort but is much faster.
+ <function>VALGRIND_DISCARD_TRANSLATIONS</function> client
+ request is an alternative to <option>--smc-check=all</option>
+ that requires more programmer effort but allows Valgrind to run
+ your program faster, by telling it precisely when translations
+ need to be re-made.
<!-- commented out because it causes broken links in the man page
; see <xref
linkend="manual-core-adv.clientreq"/> for more details.
-->
</para>
+ <para><option>--smc-check=all-non-file</option> provides a
+ cheaper but more limited version
+ of <option>--smc-check=all</option>. It adds checks to any
+ translations that do not originate from file-backed memory
+ mappings. Typical applications that generate code, for example
+ JITs in web browsers, generate code into anonymous mmaped areas,
+ whereas the "fixed" code of the browser always lives in
+ file-backed mappings. <option>--smc-check=all-non-file</option>
+ takes advantage of this observation, limiting the overhead of
+ checking to code which is likely to be JIT generated.</para>
+
<para>Some architectures (including ppc32, ppc64 and ARM) require
programs which create code at runtime to flush the instruction
cache in between code generation and first use. Valgrind
observes and honours such instructions. Hence, on ppc32/Linux,
ppc64/Linux and ARM/Linux, Valgrind always provides complete, transparent
support for self-modifying code. It is only on platforms such as
- x86/Linux, AMD64/Linux and x86/Darwin that you need to use this
- option.</para>
+ x86/Linux, AMD64/Linux, x86/Darwin and AMD64/Darwin
+ that you need to use this option.</para>
</listitem>
</varlistentry>
part of the path after 'string'. Allows removal
of path prefixes. Use this flag multiple times
to specify a set of prefixes to remove.
- --smc-check=none|stack|all checks for self-modifying code: none,
- only for code found in stacks, or all [stack]
+ --smc-check=none|stack|all|all-non-file [stack]
+ checks for self-modifying code: none, only for
+ code found in stacks, for all code, or for all
+ code except that from file-backed mappings
--read-var-info=yes|no read debug info on stack and global variables
and use it to print better error messages in
tools that make use of it (Memcheck, Helgrind,
part of the path after 'string'. Allows removal
of path prefixes. Use this flag multiple times
to specify a set of prefixes to remove.
- --smc-check=none|stack|all checks for self-modifying code: none,
- only for code found in stacks, or all [stack]
+ --smc-check=none|stack|all|all-non-file [stack]
+ checks for self-modifying code: none, only for
+ code found in stacks, for all code, or for all
+ code except that from file-backed mappings
--read-var-info=yes|no read debug info on stack and global variables
and use it to print better error messages in
tools that make use of it (Memcheck, Helgrind,