This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH][Kasan] Allow to override Asan shadow offset from command line
- From: Yury Gribov <y dot gribov at samsung dot com>
- To: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Cc: Konstantin Serebryany <konstantin dot s dot serebryany at gmail dot com>, Dmitry Vyukov <dvyukov at google dot com>, Andrey Ryabinin <a dot ryabinin at samsung dot com>
- Date: Mon, 08 Sep 2014 18:29:11 +0400
- Subject: [PATCH][Kasan] Allow to override Asan shadow offset from command line
- Authentication-results: sourceware.org; auth=none
Hi all,
Kasan developers has asked for an option to override offset of Asan
shadow memory region. This should simplify experimenting with memory
layouts on 64-bit architectures.
I've bootstrapped and regtested this on x64.
Ok to commit?
-Y
commit 95d37bbfcb9f7e35c64f3b708b120d70f220e1d2
Author: Yury Gribov <y.gribov@samsung.com>
Date: Fri Aug 29 11:58:03 2014 +0400
Allow to override Asan shadow offset.
2014-09-08 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.
* doc/invoke.texi (fasan-shadow-offset): Describe new option.
* 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.
diff --git a/gcc/asan.c b/gcc/asan.c
index cf5de27..e6820ea 100644
--- a/gcc/asan.c
+++ b/gcc/asan.c
@@ -235,6 +235,39 @@ 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;
+ asan_shadow_offset_value = strtoul (val, &endp, 0);
+ 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
@@ -1121,7 +1154,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);
@@ -1499,7 +1532,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,
@@ -1516,7 +1549,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);
diff --git a/gcc/asan.h b/gcc/asan.h
index 198433f..eadf029 100644
--- a/gcc/asan.h
+++ b/gcc/asan.h
@@ -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 */
diff --git a/gcc/common.opt b/gcc/common.opt
index 7d78803..36c8310 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -879,6 +879,10 @@ fsanitize=
Common Driver Report Joined
Select what to sanitize
+fasan-shadow-offset=
+Common Joined RejectNegative Var(common_deferred_options) Defer
+-fasan-shadow-offset=<string> Use custom shadow memory offset.
+
fsanitize-recover
Common Report Var(flag_sanitize_recover) Init(1)
After diagnosing undefined behavior attempt to continue execution
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 55e6d56..98e3eab 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -296,7 +296,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 @gol
--fsanitize-undefined-trap-on-error @gol
+-fasan-shadow-offset=@var{string} -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
@@ -5584,6 +5584,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{string}
+@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
@opindex fsanitize-recover
By default @option{-fsanitize=undefined} sanitization (and its suboptions
diff --git a/gcc/opts-global.c b/gcc/opts-global.c
index 111884b..6ce8612 100644
--- a/gcc/opts-global.c
+++ b/gcc/opts-global.c
@@ -42,6 +42,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. */
@@ -426,6 +427,11 @@ handle_common_deferred_options (void)
stack_limit_rtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (opt->arg));
break;
+ case OPT_fasan_shadow_offset_:
+ if (!set_asan_shadow_offset (opt->arg))
+ error ("unrecognized shadow offset %qs", opt->arg);
+ break;
+
default:
gcc_unreachable ();
}
diff --git a/gcc/opts.c b/gcc/opts.c
index 337e6cc..496c073 100644
--- a/gcc/opts.c
+++ b/gcc/opts.c
@@ -1566,6 +1566,10 @@ common_handle_option (struct gcc_options *opts,
break;
}
+ case OPT_fasan_shadow_offset_:
+ /* Deferred. */
+ break;
+
case OPT_O:
case OPT_Os:
case OPT_Ofast:
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
index 0000000..3b642bf
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/asan/shadow-offset-1.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-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" } } */