From: Julian Seward Date: Mon, 25 Mar 2002 00:07:36 +0000 (+0000) Subject: Add experimental omission of V-bits for address values, using X-Git-Tag: svn/VALGRIND_1_0_3~414 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2ec0ebd9dcf14917b9584cf29f25815e8e6674f1;p=thirdparty%2Fvalgrind.git Add experimental omission of V-bits for address values, using --check-addrVs=no. The default behaviour, =yes, is the original behaviour. So far this is undocumented. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@32 --- diff --git a/coregrind/valgrind.in b/coregrind/valgrind.in index f791c663ad..0b566c94cf 100755 --- a/coregrind/valgrind.in +++ b/coregrind/valgrind.in @@ -40,6 +40,8 @@ do --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;; @@ -130,6 +132,8 @@ if [ z"$argopts" = z -o z"$dousage" = z1 ]; then echo " --suppressions= suppress errors described in" echo " suppressions file " 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= level of sanity checking to do [1]" diff --git a/coregrind/vg_include.h b/coregrind/vg_include.h index cf0237ec9c..3181fd8f8f 100644 --- a/coregrind/vg_include.h +++ b/coregrind/vg_include.h @@ -165,6 +165,8 @@ typedef unsigned char Bool; #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. */ diff --git a/coregrind/vg_main.c b/coregrind/vg_main.c index da674106ab..2fb92cf204 100644 --- a/coregrind/vg_main.c +++ b/coregrind/vg_main.c @@ -433,6 +433,7 @@ UInt VG_(sanity_slow_count) = 0; Values derived from command-line options. ------------------------------------------------------------------ */ +Bool VG_(clo_check_addrVs); Bool VG_(clo_GDB_attach); Int VG_(sanity_level); Int VG_(clo_verbosity); @@ -685,6 +686,7 @@ static void process_cmd_line_options ( void ) # 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; @@ -852,6 +854,11 @@ static void process_cmd_line_options ( void ) 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")) diff --git a/coregrind/vg_translate.c b/coregrind/vg_translate.c index 18749ac40c..1423b8d3da 100644 --- a/coregrind/vg_translate.c +++ b/coregrind/vg_translate.c @@ -2113,20 +2113,31 @@ static UCodeBlock* vg_instrument ( UCodeBlock* cb_in ) 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); @@ -2654,6 +2665,40 @@ static void vg_delete_redundant_SETVs ( UCodeBlock* cb ) 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 diff --git a/valgrind.in b/valgrind.in index f791c663ad..0b566c94cf 100755 --- a/valgrind.in +++ b/valgrind.in @@ -40,6 +40,8 @@ do --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;; @@ -130,6 +132,8 @@ if [ z"$argopts" = z -o z"$dousage" = z1 ]; then echo " --suppressions= suppress errors described in" echo " suppressions file " 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= level of sanity checking to do [1]" diff --git a/vg_include.h b/vg_include.h index cf0237ec9c..3181fd8f8f 100644 --- a/vg_include.h +++ b/vg_include.h @@ -165,6 +165,8 @@ typedef unsigned char Bool; #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. */ diff --git a/vg_main.c b/vg_main.c index da674106ab..2fb92cf204 100644 --- a/vg_main.c +++ b/vg_main.c @@ -433,6 +433,7 @@ UInt VG_(sanity_slow_count) = 0; Values derived from command-line options. ------------------------------------------------------------------ */ +Bool VG_(clo_check_addrVs); Bool VG_(clo_GDB_attach); Int VG_(sanity_level); Int VG_(clo_verbosity); @@ -685,6 +686,7 @@ static void process_cmd_line_options ( void ) # 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; @@ -852,6 +854,11 @@ static void process_cmd_line_options ( void ) 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")) diff --git a/vg_translate.c b/vg_translate.c index 18749ac40c..1423b8d3da 100644 --- a/vg_translate.c +++ b/vg_translate.c @@ -2113,20 +2113,31 @@ static UCodeBlock* vg_instrument ( UCodeBlock* cb_in ) 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); @@ -2654,6 +2665,40 @@ static void vg_delete_redundant_SETVs ( UCodeBlock* cb ) 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