Allow to override Asan shadow offset.
authorYury Gribov <y.gribov@samsung.com>
Tue, 28 Oct 2014 09:46:29 +0000 (09:46 +0000)
committerYury Gribov <ygribov@gcc.gnu.org>
Tue, 28 Oct 2014 09:46:29 +0000 (09:46 +0000)
2014-10-28  Yury Gribov  <y.gribov@samsung.com>

gcc/
* asan.c (set_asan_shadow_offset): New function.
(asan_shadow_offset): Likewise.
(asan_emit_stack_protection): Call asan_shadow_offset.
(build_shadow_mem_access): Likewise.
* asan.h (set_asan_shadow_offset): Declare.
* common.opt (fasan-shadow-offset): New option.
(frandom-seed): Fixed parameter name.
* doc/invoke.texi (fasan-shadow-offset): Describe new option.
(frandom-seed): Fixed parameter name.
* opts-global.c (handle_common_deferred_options): Handle
-fasan-shadow-offset.
* opts.c (common_handle_option): Likewise.

gcc/testsuite/
* c-c++-common/asan/shadow-offset-1.c: New test.

From-SVN: r216773

gcc/ChangeLog
gcc/asan.c
gcc/asan.h
gcc/common.opt
gcc/doc/invoke.texi
gcc/opts-global.c
gcc/opts.c
gcc/testsuite/ChangeLog
gcc/testsuite/c-c++-common/asan/shadow-offset-1.c [new file with mode: 0644]

index 9645ddae1c30d9d76ab5a5e3df6082e6eac428f9..6076258968d508e650a130cb165ca312cc2115ee 100644 (file)
@@ -1,3 +1,18 @@
+2014-10-28  Yury Gribov  <y.gribov@samsung.com>
+
+       * asan.c (set_asan_shadow_offset): New function.
+       (asan_shadow_offset): Likewise.
+       (asan_emit_stack_protection): Call asan_shadow_offset.
+       (build_shadow_mem_access): Likewise.
+       * asan.h (set_asan_shadow_offset): Declare.
+       * common.opt (fasan-shadow-offset): New option.
+       (frandom-seed): Fixed parameter name.
+       * doc/invoke.texi (fasan-shadow-offset): Describe new option.
+       (frandom-seed): Fixed parameter name.
+       * opts-global.c (handle_common_deferred_options): Handle
+       -fasan-shadow-offset.
+       * opts.c (common_handle_option): Likewise.
+
 2014-10-27  Jiong Wang <jiong.wang@arm.com>
 
        PR target/63442
index d50e9e001417278e28b366d0f46dc415ae5efe3b..9080fc3a373d55359a2c293342db6fcc497861ce 100644 (file)
@@ -249,6 +249,43 @@ along with GCC; see the file COPYING3.  If not see
    A destructor function that calls the runtime asan library function
    _asan_unregister_globals is also installed.  */
 
+static unsigned HOST_WIDE_INT asan_shadow_offset_value;
+static bool asan_shadow_offset_computed;
+
+/* Sets shadow offset to value in string VAL.  */
+
+bool
+set_asan_shadow_offset (const char *val)
+{
+  char *endp;
+  
+  errno = 0;
+#ifdef HAVE_LONG_LONG
+  asan_shadow_offset_value = strtoull (val, &endp, 0);
+#else
+  asan_shadow_offset_value = strtoul (val, &endp, 0);
+#endif
+  if (!(*val != '\0' && *endp == '\0' && errno == 0))
+    return false;
+
+  asan_shadow_offset_computed = true;
+
+  return true;
+}
+
+/* Returns Asan shadow offset.  */
+
+static unsigned HOST_WIDE_INT
+asan_shadow_offset ()
+{
+  if (!asan_shadow_offset_computed)
+    {
+      asan_shadow_offset_computed = true;
+      asan_shadow_offset_value = targetm.asan_shadow_offset ();
+    }
+  return asan_shadow_offset_value;
+}
+
 alias_set_type asan_shadow_set = -1;
 
 /* Pointer types to 1 resp. 2 byte integers in shadow memory.  A separate
@@ -1135,7 +1172,7 @@ asan_emit_stack_protection (rtx base, rtx pbase, unsigned int alignb,
                              NULL_RTX, 1, OPTAB_DIRECT);
   shadow_base
     = plus_constant (Pmode, shadow_base,
-                    targetm.asan_shadow_offset ()
+                    asan_shadow_offset ()
                     + (base_align_bias >> ASAN_SHADOW_SHIFT));
   gcc_assert (asan_shadow_set != -1
              && (ASAN_RED_ZONE_SIZE >> ASAN_SHADOW_SHIFT) == 4);
@@ -1514,7 +1551,7 @@ insert_if_then_before_iter (gimple cond,
 }
 
 /* Build
-   (base_addr >> ASAN_SHADOW_SHIFT) + targetm.asan_shadow_offset ().  */
+   (base_addr >> ASAN_SHADOW_SHIFT) + asan_shadow_offset ().  */
 
 static tree
 build_shadow_mem_access (gimple_stmt_iterator *gsi, location_t location,
@@ -1531,7 +1568,7 @@ build_shadow_mem_access (gimple_stmt_iterator *gsi, location_t location,
   gimple_set_location (g, location);
   gsi_insert_after (gsi, g, GSI_NEW_STMT);
 
-  t = build_int_cst (uintptr_type, targetm.asan_shadow_offset ());
+  t = build_int_cst (uintptr_type, asan_shadow_offset ());
   g = gimple_build_assign_with_ops (PLUS_EXPR,
                                    make_ssa_name (uintptr_type, NULL),
                                    gimple_assign_lhs (g), t);
index 198433f399213990da9d322ed45e260a8a40ad46..eadf0290d1cd62b2b786cc6cc56f7836424b7133 100644 (file)
@@ -36,7 +36,7 @@ extern gimple_stmt_iterator create_cond_insert_point
 extern alias_set_type asan_shadow_set;
 
 /* Shadow memory is found at
-   (address >> ASAN_SHADOW_SHIFT) + targetm.asan_shadow_offset ().  */
+   (address >> ASAN_SHADOW_SHIFT) + asan_shadow_offset ().  */
 #define ASAN_SHADOW_SHIFT      3
 
 /* Red zone size, stack and global variables are padded by ASAN_RED_ZONE_SIZE
@@ -76,4 +76,6 @@ asan_red_zone_size (unsigned int size)
   return c ? 2 * ASAN_RED_ZONE_SIZE - c : ASAN_RED_ZONE_SIZE;
 }
 
+extern bool set_asan_shadow_offset (const char *);
+
 #endif /* TREE_ASAN */
index da5250b1a27c3f9bfe31df8dec5f9ab0d5e1c274..334d586d2027ebca2de3e20cfa6dedca58c2ea83 100644 (file)
@@ -883,6 +883,10 @@ fsanitize=
 Common Driver Report Joined
 Select what to sanitize
 
+fasan-shadow-offset=
+Common Joined RejectNegative Var(common_deferred_options) Defer
+-fasan-shadow-offset=<number>  Use custom shadow memory offset.
+
 fsanitize-recover=
 Common Report Joined
 After diagnosing undefined behavior attempt to continue execution
@@ -1808,7 +1812,7 @@ Common Var(common_deferred_options) Defer
 
 frandom-seed=
 Common Joined RejectNegative Var(common_deferred_options) Defer
--frandom-seed=<string> Make compile reproducible using <string>
+-frandom-seed=<number> Make compile reproducible using <number>
 
 ; This switch causes the command line that was used to create an
 ; object file to be recorded into the object file.  The exact format
index 9f21c9623a9348777c6c7b9d8f2a7e506dd841c9..a4901f6fbacbd784494414a83debc92e66f24885 100644 (file)
@@ -297,7 +297,7 @@ Objective-C and Objective-C++ Dialects}.
 @xref{Debugging Options,,Options for Debugging Your Program or GCC}.
 @gccoptlist{-d@var{letters}  -dumpspecs  -dumpmachine  -dumpversion @gol
 -fsanitize=@var{style} -fsanitize-recover -fsanitize-recover=@var{style} @gol
--fsanitize-undefined-trap-on-error @gol
+-fasan-shadow-offset=@var{number} -fsanitize-undefined-trap-on-error @gol
 -fdbg-cnt-list -fdbg-cnt=@var{counter-value-list} @gol
 -fdisable-ipa-@var{pass_name} @gol
 -fdisable-rtl-@var{pass_name} @gol
@@ -342,7 +342,7 @@ Objective-C and Objective-C++ Dialects}.
 -fmem-report -fpre-ipa-mem-report -fpost-ipa-mem-report -fprofile-arcs @gol
 -fopt-info @gol
 -fopt-info-@var{options}@r{[}=@var{file}@r{]} @gol
--frandom-seed=@var{string} -fsched-verbose=@var{n} @gol
+-frandom-seed=@var{number} -fsched-verbose=@var{n} @gol
 -fsel-sched-verbose -fsel-sched-dump-cfg -fsel-sched-pipelining-verbose @gol
 -fstack-usage  -ftest-coverage  -ftime-report -fvar-tracking @gol
 -fvar-tracking-assignments  -fvar-tracking-assignments-toggle @gol
@@ -5641,6 +5641,12 @@ While @option{-ftrapv} causes traps for signed overflows to be emitted,
 @option{-fsanitize=undefined} gives a diagnostic message.
 This currently works only for the C family of languages.
 
+@item -fasan-shadow-offset=@var{number}
+@opindex fasan-shadow-offset
+This option forces GCC to use custom shadow offset in AddressSanitizer checks.
+It is useful for experimenting with different shadow memory layouts in
+Kernel AddressSanitizer.
+
 @item -fsanitize-recover@r{[}=@var{opts}@r{]}
 @opindex fsanitize-recover
 @opindex fno-sanitize-recover
@@ -6804,7 +6810,7 @@ the first option takes effect and the subsequent options are
 ignored. Thus only the @file{vec.miss} is produced which contains
 dumps from the vectorizer about missed opportunities.
 
-@item -frandom-seed=@var{string}
+@item -frandom-seed=@var{number}
 @opindex frandom-seed
 This option provides a seed that GCC uses in place of
 random numbers in generating certain symbol names
@@ -6813,7 +6819,7 @@ place unique stamps in coverage data files and the object files that
 produce them.  You can use the @option{-frandom-seed} option to produce
 reproducibly identical object files.
 
-The @var{string} should be different for every file you compile.
+The @var{number} should be different for every file you compile.
 
 @item -fsched-verbose=@var{n}
 @opindex fsched-verbose
index 1eb4de3adaa717406ba30e0ac4094deb0dae21d0..149abc41a16929ac80aeb8f25e7a545361c0cb75 100644 (file)
@@ -50,6 +50,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "toplev.h"
 #include "tree-pass.h"
 #include "context.h"
+#include "asan.h"
 
 typedef const char *const_char_p; /* For DEF_VEC_P.  */
 
@@ -434,6 +435,14 @@ handle_common_deferred_options (void)
          stack_limit_rtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (opt->arg));
          break;
 
+       case OPT_fasan_shadow_offset_:
+         if (!(flag_sanitize & SANITIZE_KERNEL_ADDRESS))
+           error ("-fasan-shadow-offset should only be used "
+                  "with -fsanitize=kernel-address");
+         if (!set_asan_shadow_offset (opt->arg))
+            error ("unrecognized shadow offset %qs", opt->arg);
+         break;
+
        default:
          gcc_unreachable ();
        }
index 25f52353218a30f6ed05ebe5d2769276b2fb1b30..db30b6548fa00ae2e2430d6d2b80906387b2ff92 100644 (file)
@@ -1646,6 +1646,10 @@ common_handle_option (struct gcc_options *opts,
        break;
       }
 
+    case OPT_fasan_shadow_offset_:
+      /* Deferred.  */
+      break;
+
     case OPT_fsanitize_recover:
       if (value)
        opts->x_flag_sanitize_recover
index c71ff14d09596f01e673d9208e05ae21206a4ec3..77254a06d783ea39d6bd8fda807de6cb948fb0ae 100644 (file)
@@ -1,3 +1,7 @@
+2014-10-28  Yury Gribov  <y.gribov@samsung.com>
+
+       * c-c++-common/asan/shadow-offset-1.c: New test.
+
 2014-10-27  Andrew MacLeod  <amacleod@redhat.com>
 
        * gcc.dg/plugin/ggcplug.c: Shuffle includes to include
diff --git a/gcc/testsuite/c-c++-common/asan/shadow-offset-1.c b/gcc/testsuite/c-c++-common/asan/shadow-offset-1.c
new file mode 100644 (file)
index 0000000..2ca0fd6
--- /dev/null
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-fno-sanitize=address -fsanitize=kernel-address --param asan-instrumentation-with-call-threshold=100 -fasan-shadow-offset=12345 -fdump-tree-sanopt" } */
+/* { dg-skip-if "" { *-*-* } { "-flto" } { "" } } */
+int f (int *p)
+{
+  return *p;
+}
+
+/* { dg-final { scan-tree-dump "12345" "sanopt" }  } */
+/* { dg-final { cleanup-tree-dump "sanopt" } } */