From fd960af2df5a437302039f248a542354ee4cddcf Mon Sep 17 00:00:00 2001 From: Yury Gribov Date: Tue, 28 Oct 2014 09:46:29 +0000 Subject: [PATCH] Allow to override Asan shadow offset. 2014-10-28 Yury Gribov 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 | 15 ++++++++ gcc/asan.c | 43 +++++++++++++++++++++-- gcc/asan.h | 4 ++- gcc/common.opt | 6 +++- gcc/doc/invoke.texi | 14 +++++--- gcc/opts-global.c | 9 +++++ gcc/opts.c | 4 +++ gcc/testsuite/ChangeLog | 4 +++ gcc/testsuite/c-c++-common/asan/shadow-offset-1.c | 11 ++++++ 9 files changed, 101 insertions(+), 9 deletions(-) create mode 100644 gcc/testsuite/c-c++-common/asan/shadow-offset-1.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9645dda..60762589 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,18 @@ +2014-10-28 Yury Gribov + + * 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 PR target/63442 diff --git a/gcc/asan.c b/gcc/asan.c index d50e9e0..9080fc3 100644 --- a/gcc/asan.c +++ b/gcc/asan.c @@ -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); 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 da5250b..334d586 100644 --- a/gcc/common.opt +++ b/gcc/common.opt @@ -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= 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= Make compile reproducible using +-frandom-seed= Make compile reproducible using ; This switch causes the command line that was used to create an ; object file to be recorded into the object file. The exact format diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 9f21c96..a4901f6 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -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 diff --git a/gcc/opts-global.c b/gcc/opts-global.c index 1eb4de3..149abc4 100644 --- a/gcc/opts-global.c +++ b/gcc/opts-global.c @@ -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 (); } diff --git a/gcc/opts.c b/gcc/opts.c index 25f5235..db30b65 100644 --- a/gcc/opts.c +++ b/gcc/opts.c @@ -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 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index c71ff14..77254a0 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2014-10-28 Yury Gribov + + * c-c++-common/asan/shadow-offset-1.c: New test. + 2014-10-27 Andrew MacLeod * 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 index 0000000..2ca0fd6 --- /dev/null +++ b/gcc/testsuite/c-c++-common/asan/shadow-offset-1.c @@ -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" } } */ -- 2.7.4