Index: docs/xml/manual-core.xml
===================================================================
--- docs/xml/manual-core.xml (revision 12792)
+++ docs/xml/manual-core.xml (working copy)
@@ -2054,7 +2054,8 @@
If you're using signals in clever ways (for example, catching
SIGSEGV, modifying page state and restarting the instruction), you're
probably relying on precise exceptions. In this case, you will need
-to use .
+to use
+or .
If your program dies as a result of a fatal core-dumping signal,
Index: docs/xml/manual-core-adv.xml
===================================================================
--- docs/xml/manual-core-adv.xml (revision 12792)
+++ docs/xml/manual-core-adv.xml (working copy)
@@ -788,21 +788,28 @@
When Valgrind gdbserver stops on an error, on a breakpoint
or when single stepping, registers and flags values might not be always
up to date due to the optimisations done by the Valgrind core.
- Disabling some optimisations using the following options will increase
+ The default value
+
+ ensures that the registers needed to make a stack trace (typically
+ PC/SP/FP) are up to date at each memory access (i.e. memory exception
+ points).
+ Disabling some optimisations using the following values will increase
the precision of registers and flags values (a typical performance
impact for memcheck is given for each option).
- (+5%) ensures
- that all integer registers are up to date at each memory access.
+ (+10%)
+ ensures that all registers and flags are up to date at each memory
+ access.
- (+100%) ensures that
- all registers and flags values are up to date at each instruction.
+ (+25%)
+ ensures that all registers and flags are up to date at each instruction.
- Note that the above options can be combined with
- (+500%, see above Precision of "stop-at" commands).
+ Note that (+500%, see above
+ Precision of "stop-at" commands) automatically
+ activates .
@@ -898,7 +905,8 @@
On PPC32/PPC64, stack unwinding for leaf functions
(functions that do not call any other functions) works properly
only when you give the option
- .
+
+ or .
You must also pass this option in order to get a precise stack when
a signal is trapped by GDB.
Index: gdbserver_tests/mcsignopass.vgtest
===================================================================
--- gdbserver_tests/mcsignopass.vgtest (revision 12792)
+++ gdbserver_tests/mcsignopass.vgtest (working copy)
@@ -6,7 +6,7 @@
# are eventually passed.
prereq: test -e gdb
prog: ../none/tests/faultstatus
-vgopts: --tool=memcheck --vgdb=full --vex-iropt-precise-memory-exns=yes --vgdb-error=0 --vgdb-prefix=./vgdb-prefix-mcsignopass
+vgopts: --tool=memcheck --vgdb=full --vex-iropt-register-updates=allregs-at-mem-access --vgdb-error=0 --vgdb-prefix=./vgdb-prefix-mcsignopass
stderr_filter: filter_memcheck_monitor
stderr_filter_args: faultstatus.c
progB: gdb
Index: gdbserver_tests/mcsigpass.vgtest
===================================================================
--- gdbserver_tests/mcsigpass.vgtest (revision 12792)
+++ gdbserver_tests/mcsigpass.vgtest (working copy)
@@ -1,7 +1,7 @@
# test the signal handling, when signals are passed to the Valgrind guest.
prereq: test -e gdb
prog: ../none/tests/faultstatus
-vgopts: --tool=memcheck --vgdb=full --vex-iropt-precise-memory-exns=yes --vgdb-error=0 --vgdb-prefix=./vgdb-prefix-mcsigpass
+vgopts: --tool=memcheck --vgdb=full --vex-iropt-register-updates=allregs-at-mem-access --vgdb-error=0 --vgdb-prefix=./vgdb-prefix-mcsigpass
stderr_filter: filter_memcheck_monitor
stderr_filter_args: faultstatus.c
progB: gdb
Index: NEWS
===================================================================
--- NEWS (revision 12792)
+++ NEWS (working copy)
@@ -82,6 +82,15 @@
* Improved DWARF4 support (284124)
+* Option --vex-iropt-precise-memory-exns has been removed.
+ It is replaced by --vex-iropt-register-updates which accepts
+ 3 values : 'unwindregs-at-mem-access' (replacing
+ --vex-iropt-precise-memory-exns=no), 'allregs-at-mem-access'
+ (replacing --vex-iropt-precise-memory-exns=yes)
+ and a new value 'allregs-at-each-insn'.
+ 'allregs-at-each-insn' allows the Valgrind gdbserver to always
+ show up to date values to GDB.
+
* ==================== FIXED BUGS ====================
The following bugs have been fixed or resolved. Note that "n-i-bz"
Index: none/tests/selfrun.vgtest
===================================================================
--- none/tests/selfrun.vgtest (revision 12792)
+++ none/tests/selfrun.vgtest (working copy)
@@ -1,3 +1,3 @@
prog: ../../coregrind/valgrind --tool=none --command-line-only=yes ./selfrun
-vgopts: --vex-iropt-precise-memory-exns=yes
+vgopts: --vex-iropt-register-updates=allregs-at-mem-access
prereq: grep '^#define HAVE_PIE 1' ../../config.h > /dev/null
Index: none/tests/cmdline2.stdout.exp
===================================================================
--- none/tests/cmdline2.stdout.exp (revision 12792)
+++ none/tests/cmdline2.stdout.exp (working copy)
@@ -113,7 +113,9 @@
Vex options for all Valgrind tools:
--vex-iropt-verbosity=<0..9> [0]
--vex-iropt-level=<0..2> [2]
- --vex-iropt-precise-memory-exns=no|yes [no]
+ --vex-iropt-register-updates=unwindregs-at-mem-access
+ |allregs-at-mem-access
+ |allregs-at-each-insn [unwindregs-at-mem-access]
--vex-iropt-unroll-thresh=<0..400> [120]
--vex-guest-max-insns=<1..100> [50]
--vex-guest-chase-thresh=<0..99> [10]
Index: coregrind/m_main.c
===================================================================
--- coregrind/m_main.c (revision 12792)
+++ coregrind/m_main.c (working copy)
@@ -224,7 +224,9 @@
" Vex options for all Valgrind tools:\n"
" --vex-iropt-verbosity=<0..9> [0]\n"
" --vex-iropt-level=<0..2> [2]\n"
-" --vex-iropt-precise-memory-exns=no|yes [no]\n"
+" --vex-iropt-register-updates=unwindregs-at-mem-access\n"
+" |allregs-at-mem-access\n"
+" |allregs-at-each-insn [unwindregs-at-mem-access]\n"
" --vex-iropt-unroll-thresh=<0..400> [120]\n"
" --vex-guest-max-insns=<1..100> [50]\n"
" --vex-guest-chase-thresh=<0..99> [10]\n"
@@ -468,6 +470,13 @@
else if VG_STREQN(11, arg, "--sim-hints") {}
else if VG_STREQN(14, arg, "--profile-heap") {}
+ /* Obsolete option. Report an error and exit */
+ else if VG_STREQN(31, arg, "--vex-iropt-precise-memory-exns") {
+ VG_(fmsg_bad_option)(arg,
+ "--vex-iropt-precise-memory-exns is obsolete\n"
+ "Use --vex-iropt-register-updates instead\n");
+ }
+
// These options are new.
else if (VG_STREQ(arg, "-v") ||
VG_STREQ(arg, "--verbose"))
@@ -483,7 +492,10 @@
else if VG_XACT_CLO(arg, "--vgdb=no", VG_(clo_vgdb), Vg_VgdbNo) {}
else if VG_XACT_CLO(arg, "--vgdb=yes", VG_(clo_vgdb), Vg_VgdbYes) {}
- else if VG_XACT_CLO(arg, "--vgdb=full", VG_(clo_vgdb), Vg_VgdbFull) {}
+ else if VG_XACT_CLO(arg, "--vgdb=full", VG_(clo_vgdb), Vg_VgdbFull) {
+ /* automatically sets register values to exact with --vgdb=full */
+ VG_(clo_vex_control).iropt_register_updates = 2;
+ }
else if VG_INT_CLO (arg, "--vgdb-poll", VG_(clo_vgdb_poll)) {}
else if VG_INT_CLO (arg, "--vgdb-error", VG_(clo_vgdb_error)) {}
else if VG_STR_CLO (arg, "--vgdb-prefix", VG_(clo_vgdb_prefix)) {}
@@ -562,8 +574,18 @@
VG_(clo_vex_control).iropt_verbosity, 0, 10) {}
else if VG_BINT_CLO(arg, "--vex-iropt-level",
VG_(clo_vex_control).iropt_level, 0, 2) {}
- else if VG_BOOL_CLO(arg, "--vex-iropt-precise-memory-exns",
- VG_(clo_vex_control).iropt_precise_memory_exns) {}
+ else if VG_XACT_CLO(arg,
+ "--vex-iropt-register-updates=unwindregs-at-mem-access",
+ VG_(clo_vex_control).iropt_register_updates,
+ VexUnwindregsAtMemAccess);
+ else if VG_XACT_CLO(arg,
+ "--vex-iropt-register-updates=allregs-at-mem-access",
+ VG_(clo_vex_control).iropt_register_updates,
+ VexAllregsAtMemAccess);
+ else if VG_XACT_CLO(arg,
+ "--vex-iropt-register-updates=allregs-at-each-insn",
+ VG_(clo_vex_control).iropt_register_updates,
+ VexAllregsAtEachInsn);
else if VG_BINT_CLO(arg, "--vex-iropt-unroll-thresh",
VG_(clo_vex_control).iropt_unroll_thresh, 0, 400) {}
else if VG_BINT_CLO(arg, "--vex-guest-max-insns",
Index: VEX/priv/main_main.c
===================================================================
--- VEX/priv/main_main.c (revision 2451)
+++ VEX/priv/main_main.c (working copy)
@@ -82,7 +82,7 @@
{
vcon->iropt_verbosity = 0;
vcon->iropt_level = 2;
- vcon->iropt_precise_memory_exns = False;
+ vcon->iropt_register_updates = 0; /* minimal */
vcon->iropt_unroll_thresh = 120;
vcon->guest_max_insns = 60;
vcon->guest_chase_thresh = 10;
Index: VEX/priv/ir_opt.c
===================================================================
--- VEX/priv/ir_opt.c (revision 2451)
+++ VEX/priv/ir_opt.c (working copy)
@@ -69,12 +69,20 @@
not marked as being read or modified by the helper cannot be
assumed to be up-to-date at the point where the helper is called.
- * Immediately prior to any load or store, those parts of the guest
+ * If iropt_register_updates == VexUnwindregsAtMemAccess :
+ Immediately prior to any load or store, those parts of the guest
state marked as requiring precise exceptions will be up to date.
Also, guest memory will be up to date. Parts of the guest state
not marked as requiring precise exceptions cannot be assumed to
be up-to-date at the point of the load/store.
+ If iropt_register_updates == VexAllregsAtMemAccess:
+ Same as minimal, but all the guest state is up to date at memory
+ exception points.
+
+ If iropt_register_updates == VexAllregsAtEachInsn :
+ Guest state is up to date at each instruction.
+
The relative order of loads and stores (including loads/stores of
guest memory done by dirty helpers annotated as such) is not
changed. However, the relative order of loads with no intervening
@@ -769,7 +777,13 @@
vpanic("handle_gets_Stmt");
}
- if (memRW) {
+ if (vex_control.iropt_register_updates == VexAllregsAtEachInsn) {
+ /* Exact register values at each instruction.
+ Flush all guest state. */
+ for (j = 0; j < env->used; j++) {
+ env->inuse[j] = False;
+ }
+ } else if (memRW) {
/* This statement accesses memory. So we need to dump all parts
of the environment corresponding to guest state that may not
be reordered with respect to memory references. That means
@@ -777,8 +791,9 @@
for (j = 0; j < env->used; j++) {
if (!env->inuse[j])
continue;
- if (vex_control.iropt_precise_memory_exns) {
- /* Precise exceptions required. Flush all guest state. */
+ if (vex_control.iropt_register_updates == VexAllregsAtMemAccess) {
+ /* Precise exceptions required at mem access.
+ Flush all guest state. */
env->inuse[j] = False;
} else {
/* Just flush the minimal amount required, as computed by
@@ -5176,7 +5191,9 @@
ppIRSB(bb);
}
- redundant_put_removal_BB ( bb, preciseMemExnsFn );
+ if (vex_control.iropt_register_updates != VexAllregsAtEachInsn) {
+ redundant_put_removal_BB ( bb, preciseMemExnsFn );
+ }
if (iropt_verbose) {
vex_printf("\n========= REDUNDANT PUT\n\n" );
ppIRSB(bb);
@@ -5214,7 +5231,9 @@
(void)do_cse_BB( bb );
collapse_AddSub_chains_BB( bb );
do_redundant_GetI_elimination( bb );
- do_redundant_PutI_elimination( bb );
+ if (vex_control.iropt_register_updates != VexAllregsAtEachInsn) {
+ do_redundant_PutI_elimination( bb );
+ }
do_deadcode_BB( bb );
return bb;
}
Index: VEX/pub/libvex.h
===================================================================
--- VEX/pub/libvex.h (revision 2451)
+++ VEX/pub/libvex.h (working copy)
@@ -307,6 +307,22 @@
/*--- Control of Vex's optimiser (iropt). ---*/
/*-------------------------------------------------------*/
+
+/* VexRegisterUpdates specifies when to ensure that the guest state is
+ up to date.
+
+ VexUnwindregsAtMemAccess = registers needed to make a stack trace are
+ up to date at memory exception points. Typically, these are PC/SP/FP. The
+ minimal registers are described by the arch specific functions
+ guest__state_requires_precise_mem_exns.
+
+ VexAllregsAtMemAccess = all registers up to date at memory exception points.
+
+ VexAllregsAtEachInsn = all registers up to date at each instruction. */
+typedef enum { VexUnwindregsAtMemAccess,
+ VexAllregsAtMemAccess,
+ VexAllregsAtEachInsn } VexRegisterUpdates;
+
/* Control of Vex's optimiser. */
typedef
@@ -316,10 +332,8 @@
/* Control aggressiveness of iropt. 0 = no opt, 1 = simple
opts, 2 (default) = max optimisation. */
Int iropt_level;
- /* Ensure all integer registers are up to date at potential
- memory exception points? True(default)=yes, False=no, only
- the guest's stack pointer. */
- Bool iropt_precise_memory_exns;
+ /* Controls when registers are updated in guest state. */
+ VexRegisterUpdates iropt_register_updates;
/* How aggressive should iropt be in unrolling loops? Higher
numbers make it more enthusiastic about loop unrolling.
Default=120. A setting of zero disables unrolling. */