--verbose) vgopts="$vgopts -v"; shift;;
-q) vgopts="$vgopts $arg"; shift;;
--quiet) vgopts="$vgopts $arg"; shift;;
+ --check-addrVs=no) vgopts="$vgopts $arg"; shift;;
+ --check-addrVs=yes) vgopts="$vgopts $arg"; shift;;
--gdb-attach=no) vgopts="$vgopts $arg"; shift;;
--gdb-attach=yes) vgopts="$vgopts $arg"; shift;;
--demangle=no) vgopts="$vgopts $arg"; shift;;
echo " --suppressions=<filename> suppress errors described in"
echo " suppressions file <filename>"
echo " --client-perms=no|yes handle client VG_MAKE_* requests? [no]"
+ echo " --check-addrVs=no|yes experimental lighterweight checking? [yes]"
+ echo " yes == Valgrind's original behaviour"
echo
echo " options for debugging Valgrind itself are:"
echo " --sanity-level=<number> level of sanity checking to do [1]"
#define VG_CLO_MAX_SFILES 10
+/* Shall we V-check addrs (they are always A checked too): default: YES */
+extern Bool VG_(clo_check_addrVs);
/* Enquire about whether to attach to GDB at errors? default: NO */
extern Bool VG_(clo_GDB_attach);
/* Sanity-check level: 0 = none, 1 (default), > 1 = expensive. */
Values derived from command-line options.
------------------------------------------------------------------ */
+Bool VG_(clo_check_addrVs);
Bool VG_(clo_GDB_attach);
Int VG_(sanity_level);
Int VG_(clo_verbosity);
# define STREQN(nn,s1,s2) (0==VG_(strncmp_ws)((s1),(s2),(nn)))
/* Set defaults. */
+ VG_(clo_check_addrVs) = True;
VG_(clo_GDB_attach) = False;
VG_(sanity_level) = 1;
VG_(clo_verbosity) = 1;
else if (STREQ(argv[i], "-q") || STREQ(argv[i], "--quiet"))
VG_(clo_verbosity)--;
+ else if (STREQ(argv[i], "--check-addrVs=yes"))
+ VG_(clo_check_addrVs) = True;
+ else if (STREQ(argv[i], "--check-addrVs=no"))
+ VG_(clo_check_addrVs) = False;
+
else if (STREQ(argv[i], "--gdb-attach=yes"))
VG_(clo_GDB_attach) = True;
else if (STREQ(argv[i], "--gdb-attach=no"))
copyUInstr(cb, u_in);
break;
- /* Loads and stores. Test the V bits for the address.
+ /* Loads and stores. Test the V bits for the address. 24
+ Mar 02: since the address is A-checked anyway, there's not
+ really much point in doing the V-check too, unless you
+ think that you might use addresses which are undefined but
+ still addressible. Hence the optionalisation of the V
+ check.
+
The LOADV/STOREV does an addressibility check for the
address. */
+
case LOAD:
- uInstr1(cb, TESTV, 4, TempReg, SHADOW(u_in->val1));
- uInstr1(cb, SETV, 4, TempReg, SHADOW(u_in->val1));
+ if (VG_(clo_check_addrVs)) {
+ uInstr1(cb, TESTV, 4, TempReg, SHADOW(u_in->val1));
+ uInstr1(cb, SETV, 4, TempReg, SHADOW(u_in->val1));
+ }
uInstr2(cb, LOADV, u_in->size,
TempReg, u_in->val1,
TempReg, SHADOW(u_in->val2));
copyUInstr(cb, u_in);
break;
case STORE:
- uInstr1(cb, TESTV, 4, TempReg, SHADOW(u_in->val2));
- uInstr1(cb, SETV, 4, TempReg, SHADOW(u_in->val2));
+ if (VG_(clo_check_addrVs)) {
+ uInstr1(cb, TESTV, 4, TempReg, SHADOW(u_in->val2));
+ uInstr1(cb, SETV, 4, TempReg, SHADOW(u_in->val2));
+ }
uInstr2(cb, STOREV, u_in->size,
TempReg, SHADOW(u_in->val1),
TempReg, u_in->val2);
for (i = cb->used-1; i >= 0; i--) {
u = &cb->instrs[i];
+ /* If we're not checking address V bits, there will be a lot of
+ GETVs, TAG1s and TAG2s calculating values which are never
+ used. These first three cases get rid of them. */
+
+ if (u->opcode == GETV && VGC_IS_SHADOW(u->val2)
+ && next_is_write[u->val2]
+ && !VG_(clo_check_addrVs)) {
+ u->opcode = NOP;
+ u->size = 0;
+ if (VG_(disassemble))
+ VG_(printf)("at %d: delete GETV\n", i);
+ } else
+
+ if (u->opcode == TAG1 && VGC_IS_SHADOW(u->val1)
+ && next_is_write[u->val1]
+ && !VG_(clo_check_addrVs)) {
+ u->opcode = NOP;
+ u->size = 0;
+ if (VG_(disassemble))
+ VG_(printf)("at %d: delete TAG1\n", i);
+ } else
+
+ if (u->opcode == TAG2 && VGC_IS_SHADOW(u->val2)
+ && next_is_write[u->val2]
+ && !VG_(clo_check_addrVs)) {
+ u->opcode = NOP;
+ u->size = 0;
+ if (VG_(disassemble))
+ VG_(printf)("at %d: delete TAG2\n", i);
+ } else
+
+ /* We do the rest of these regardless of whether or not
+ addresses are V-checked. */
+
if (u->opcode == MOV && VGC_IS_SHADOW(u->val2)
&& next_is_write[u->val2]) {
/* This MOV is pointless because the target is dead at this
--verbose) vgopts="$vgopts -v"; shift;;
-q) vgopts="$vgopts $arg"; shift;;
--quiet) vgopts="$vgopts $arg"; shift;;
+ --check-addrVs=no) vgopts="$vgopts $arg"; shift;;
+ --check-addrVs=yes) vgopts="$vgopts $arg"; shift;;
--gdb-attach=no) vgopts="$vgopts $arg"; shift;;
--gdb-attach=yes) vgopts="$vgopts $arg"; shift;;
--demangle=no) vgopts="$vgopts $arg"; shift;;
echo " --suppressions=<filename> suppress errors described in"
echo " suppressions file <filename>"
echo " --client-perms=no|yes handle client VG_MAKE_* requests? [no]"
+ echo " --check-addrVs=no|yes experimental lighterweight checking? [yes]"
+ echo " yes == Valgrind's original behaviour"
echo
echo " options for debugging Valgrind itself are:"
echo " --sanity-level=<number> level of sanity checking to do [1]"
#define VG_CLO_MAX_SFILES 10
+/* Shall we V-check addrs (they are always A checked too): default: YES */
+extern Bool VG_(clo_check_addrVs);
/* Enquire about whether to attach to GDB at errors? default: NO */
extern Bool VG_(clo_GDB_attach);
/* Sanity-check level: 0 = none, 1 (default), > 1 = expensive. */
Values derived from command-line options.
------------------------------------------------------------------ */
+Bool VG_(clo_check_addrVs);
Bool VG_(clo_GDB_attach);
Int VG_(sanity_level);
Int VG_(clo_verbosity);
# define STREQN(nn,s1,s2) (0==VG_(strncmp_ws)((s1),(s2),(nn)))
/* Set defaults. */
+ VG_(clo_check_addrVs) = True;
VG_(clo_GDB_attach) = False;
VG_(sanity_level) = 1;
VG_(clo_verbosity) = 1;
else if (STREQ(argv[i], "-q") || STREQ(argv[i], "--quiet"))
VG_(clo_verbosity)--;
+ else if (STREQ(argv[i], "--check-addrVs=yes"))
+ VG_(clo_check_addrVs) = True;
+ else if (STREQ(argv[i], "--check-addrVs=no"))
+ VG_(clo_check_addrVs) = False;
+
else if (STREQ(argv[i], "--gdb-attach=yes"))
VG_(clo_GDB_attach) = True;
else if (STREQ(argv[i], "--gdb-attach=no"))
copyUInstr(cb, u_in);
break;
- /* Loads and stores. Test the V bits for the address.
+ /* Loads and stores. Test the V bits for the address. 24
+ Mar 02: since the address is A-checked anyway, there's not
+ really much point in doing the V-check too, unless you
+ think that you might use addresses which are undefined but
+ still addressible. Hence the optionalisation of the V
+ check.
+
The LOADV/STOREV does an addressibility check for the
address. */
+
case LOAD:
- uInstr1(cb, TESTV, 4, TempReg, SHADOW(u_in->val1));
- uInstr1(cb, SETV, 4, TempReg, SHADOW(u_in->val1));
+ if (VG_(clo_check_addrVs)) {
+ uInstr1(cb, TESTV, 4, TempReg, SHADOW(u_in->val1));
+ uInstr1(cb, SETV, 4, TempReg, SHADOW(u_in->val1));
+ }
uInstr2(cb, LOADV, u_in->size,
TempReg, u_in->val1,
TempReg, SHADOW(u_in->val2));
copyUInstr(cb, u_in);
break;
case STORE:
- uInstr1(cb, TESTV, 4, TempReg, SHADOW(u_in->val2));
- uInstr1(cb, SETV, 4, TempReg, SHADOW(u_in->val2));
+ if (VG_(clo_check_addrVs)) {
+ uInstr1(cb, TESTV, 4, TempReg, SHADOW(u_in->val2));
+ uInstr1(cb, SETV, 4, TempReg, SHADOW(u_in->val2));
+ }
uInstr2(cb, STOREV, u_in->size,
TempReg, SHADOW(u_in->val1),
TempReg, u_in->val2);
for (i = cb->used-1; i >= 0; i--) {
u = &cb->instrs[i];
+ /* If we're not checking address V bits, there will be a lot of
+ GETVs, TAG1s and TAG2s calculating values which are never
+ used. These first three cases get rid of them. */
+
+ if (u->opcode == GETV && VGC_IS_SHADOW(u->val2)
+ && next_is_write[u->val2]
+ && !VG_(clo_check_addrVs)) {
+ u->opcode = NOP;
+ u->size = 0;
+ if (VG_(disassemble))
+ VG_(printf)("at %d: delete GETV\n", i);
+ } else
+
+ if (u->opcode == TAG1 && VGC_IS_SHADOW(u->val1)
+ && next_is_write[u->val1]
+ && !VG_(clo_check_addrVs)) {
+ u->opcode = NOP;
+ u->size = 0;
+ if (VG_(disassemble))
+ VG_(printf)("at %d: delete TAG1\n", i);
+ } else
+
+ if (u->opcode == TAG2 && VGC_IS_SHADOW(u->val2)
+ && next_is_write[u->val2]
+ && !VG_(clo_check_addrVs)) {
+ u->opcode = NOP;
+ u->size = 0;
+ if (VG_(disassemble))
+ VG_(printf)("at %d: delete TAG2\n", i);
+ } else
+
+ /* We do the rest of these regardless of whether or not
+ addresses are V-checked. */
+
if (u->opcode == MOV && VGC_IS_SHADOW(u->val2)
&& next_is_write[u->val2]) {
/* This MOV is pointless because the target is dead at this