diff options
author | ygribov <ygribov@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-07-31 13:35:18 +0000 |
---|---|---|
committer | ygribov <ygribov@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-07-31 13:35:18 +0000 |
commit | 3e1dd01e64c444733399ba398bb2ace1d59cc4d4 (patch) | |
tree | 635ebf6c3843da8f2869a7802dedfc2941d28cc1 | |
parent | 7c0c95b8530831130b9d4a1acf4cd0311376bc10 (diff) | |
download | gcc-3e1dd01e64c444733399ba398bb2ace1d59cc4d4.tar.gz |
2014-07-31 Yury Gribov <y.gribov@samsung.com>
* doc/cpp.texi (__SANITIZE_ADDRESS__): Updated description.
* doc/invoke.texi (-fsanitize=kernel-address): Describe new option.
* flag-types.h (SANITIZE_USER_ADDRESS, SANITIZE_KERNEL_ADDRESS):
New enums.
* gcc.c (sanitize_spec_function): Support new option.
(SANITIZER_SPEC): Remove now redundant check.
* opts.c (common_handle_option): Support new option.
(finish_options): Check for incompatibilities.
* toplev.c (process_options): Split userspace-specific checks.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@213367 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/ChangeLog | 12 | ||||
-rw-r--r-- | gcc/doc/cpp.texi | 4 | ||||
-rw-r--r-- | gcc/doc/invoke.texi | 5 | ||||
-rw-r--r-- | gcc/flag-types.h | 30 | ||||
-rw-r--r-- | gcc/gcc.c | 7 | ||||
-rw-r--r-- | gcc/opts.c | 38 | ||||
-rw-r--r-- | gcc/toplev.c | 13 |
7 files changed, 87 insertions, 22 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5b24fcd823d..2200cabbba7 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2014-07-31 Yury Gribov <y.gribov@samsung.com> + + * doc/cpp.texi (__SANITIZE_ADDRESS__): Updated description. + * doc/invoke.texi (-fsanitize=kernel-address): Describe new option. + * flag-types.h (SANITIZE_USER_ADDRESS, SANITIZE_KERNEL_ADDRESS): + New enums. + * gcc.c (sanitize_spec_function): Support new option. + (SANITIZER_SPEC): Remove now redundant check. + * opts.c (common_handle_option): Support new option. + (finish_options): Check for incompatibilities. + * toplev.c (process_options): Split userspace-specific checks. + 2014-07-31 Richard Biener <rguenther@suse.de> * lto-streamer.h (struct output_block): Remove global. diff --git a/gcc/doc/cpp.texi b/gcc/doc/cpp.texi index aaed739fb35..0a6e50caac9 100644 --- a/gcc/doc/cpp.texi +++ b/gcc/doc/cpp.texi @@ -2354,8 +2354,8 @@ This macro is defined, with value 3, when @option{-fstack-protector-strong} is in use. @item __SANITIZE_ADDRESS__ -This macro is defined, with value 1, when @option{-fsanitize=address} is -in use. +This macro is defined, with value 1, when @option{-fsanitize=address} +or @option{-fsanitize=kernel-address} are in use. @item __TIMESTAMP__ This macro expands to a string constant that describes the date and time diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 51757f07efa..89f40d7cb90 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -5401,6 +5401,11 @@ more details. The run-time behavior can be influenced using the @url{https://code.google.com/p/address-sanitizer/wiki/Flags#Run-time_flags} for a list of supported options. +@item -fsanitize=kernel-address +@opindex fsanitize=kernel-address +Enable AddressSanitizer for Linux kernel. +See @uref{http://code.google.com/p/address-sanitizer/wiki/AddressSanitizerForKernel} for more details. + @item -fsanitize=thread @opindex fsanitize=thread Enable ThreadSanitizer, a fast data race detector. diff --git a/gcc/flag-types.h b/gcc/flag-types.h index 2849455d793..bf813b6c6b5 100644 --- a/gcc/flag-types.h +++ b/gcc/flag-types.h @@ -214,23 +214,25 @@ enum vect_cost_model { enum sanitize_code { /* AddressSanitizer. */ SANITIZE_ADDRESS = 1 << 0, + SANITIZE_USER_ADDRESS = 1 << 1, + SANITIZE_KERNEL_ADDRESS = 1 << 2, /* ThreadSanitizer. */ - SANITIZE_THREAD = 1 << 1, + SANITIZE_THREAD = 1 << 3, /* LeakSanitizer. */ - SANITIZE_LEAK = 1 << 2, + SANITIZE_LEAK = 1 << 4, /* UndefinedBehaviorSanitizer. */ - SANITIZE_SHIFT = 1 << 3, - SANITIZE_DIVIDE = 1 << 4, - SANITIZE_UNREACHABLE = 1 << 5, - SANITIZE_VLA = 1 << 6, - SANITIZE_NULL = 1 << 7, - SANITIZE_RETURN = 1 << 8, - SANITIZE_SI_OVERFLOW = 1 << 9, - SANITIZE_BOOL = 1 << 10, - SANITIZE_ENUM = 1 << 11, - SANITIZE_FLOAT_DIVIDE = 1 << 12, - SANITIZE_FLOAT_CAST = 1 << 13, - SANITIZE_BOUNDS = 1 << 14, + SANITIZE_SHIFT = 1 << 5, + SANITIZE_DIVIDE = 1 << 6, + SANITIZE_UNREACHABLE = 1 << 7, + SANITIZE_VLA = 1 << 8, + SANITIZE_NULL = 1 << 9, + SANITIZE_RETURN = 1 << 10, + SANITIZE_SI_OVERFLOW = 1 << 11, + SANITIZE_BOOL = 1 << 12, + SANITIZE_ENUM = 1 << 13, + SANITIZE_FLOAT_DIVIDE = 1 << 14, + SANITIZE_FLOAT_CAST = 1 << 15, + SANITIZE_BOUNDS = 1 << 16, SANITIZE_UNDEFINED = SANITIZE_SHIFT | SANITIZE_DIVIDE | SANITIZE_UNREACHABLE | SANITIZE_VLA | SANITIZE_NULL | SANITIZE_RETURN | SANITIZE_SI_OVERFLOW | SANITIZE_BOOL | SANITIZE_ENUM diff --git a/gcc/gcc.c b/gcc/gcc.c index 6cd08eab8b5..c0fde8c8df5 100644 --- a/gcc/gcc.c +++ b/gcc/gcc.c @@ -779,8 +779,7 @@ proper position among the other output files. */ #ifndef SANITIZER_SPEC #define SANITIZER_SPEC "\ %{!nostdlib:%{!nodefaultlibs:%{%:sanitize(address):" LIBASAN_SPEC "\ - %{static:%ecannot specify -static with -fsanitize=address}\ - %{%:sanitize(thread):%e-fsanitize=address is incompatible with -fsanitize=thread}}\ + %{static:%ecannot specify -static with -fsanitize=address}}\ %{%:sanitize(thread):" LIBTSAN_SPEC "\ %{!pie:%{!shared:%e-fsanitize=thread linking must be done with -pie or -shared}}}\ %{%:sanitize(undefined):" LIBUBSAN_SPEC "}\ @@ -8224,7 +8223,9 @@ sanitize_spec_function (int argc, const char **argv) return NULL; if (strcmp (argv[0], "address") == 0) - return (flag_sanitize & SANITIZE_ADDRESS) ? "" : NULL; + return (flag_sanitize & SANITIZE_USER_ADDRESS) ? "" : NULL; + if (strcmp (argv[0], "kernel-address") == 0) + return (flag_sanitize & SANITIZE_KERNEL_ADDRESS) ? "" : NULL; if (strcmp (argv[0], "thread") == 0) return (flag_sanitize & SANITIZE_THREAD) ? "" : NULL; if (strcmp (argv[0], "undefined") == 0) diff --git a/gcc/opts.c b/gcc/opts.c index 5fed6f0ff2c..4b0af82dac1 100644 --- a/gcc/opts.c +++ b/gcc/opts.c @@ -869,6 +869,20 @@ finish_options (struct gcc_options *opts, struct gcc_options *opts_set, /* The -gsplit-dwarf option requires -ggnu-pubnames. */ if (opts->x_dwarf_split_debug_info) opts->x_debug_generate_pub_sections = 2; + + /* Userspace and kernel ASan conflict with each other and with TSan. */ + + if ((flag_sanitize & SANITIZE_USER_ADDRESS) + && (flag_sanitize & SANITIZE_KERNEL_ADDRESS)) + error_at (loc, + "-fsanitize=address is incompatible with " + "-fsanitize=kernel-address"); + + if ((flag_sanitize & SANITIZE_ADDRESS) + && (flag_sanitize & SANITIZE_THREAD)) + error_at (loc, + "-fsanitize=address and -fsanitize=kernel-address " + "are incompatible with -fsanitize=thread"); } #define LEFT_COLUMN 27 @@ -1454,7 +1468,10 @@ common_handle_option (struct gcc_options *opts, size_t len; } spec[] = { - { "address", SANITIZE_ADDRESS, sizeof "address" - 1 }, + { "address", SANITIZE_ADDRESS | SANITIZE_USER_ADDRESS, + sizeof "address" - 1 }, + { "kernel-address", SANITIZE_ADDRESS | SANITIZE_KERNEL_ADDRESS, + sizeof "kernel-address" - 1 }, { "thread", SANITIZE_THREAD, sizeof "thread" - 1 }, { "leak", SANITIZE_LEAK, sizeof "leak" - 1 }, { "shift", SANITIZE_SHIFT, sizeof "shift" - 1 }, @@ -1520,6 +1537,25 @@ common_handle_option (struct gcc_options *opts, the null pointer checks. */ if (flag_sanitize & SANITIZE_NULL) opts->x_flag_delete_null_pointer_checks = 0; + + /* Kernel ASan implies normal ASan but does not yet support + all features. */ + if (flag_sanitize & SANITIZE_KERNEL_ADDRESS) + { + maybe_set_param_value (PARAM_ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD, 0, + opts->x_param_values, + opts_set->x_param_values); + maybe_set_param_value (PARAM_ASAN_GLOBALS, 0, + opts->x_param_values, + opts_set->x_param_values); + maybe_set_param_value (PARAM_ASAN_STACK, 0, + opts->x_param_values, + opts_set->x_param_values); + maybe_set_param_value (PARAM_ASAN_USE_AFTER_RETURN, 0, + opts->x_param_values, + opts_set->x_param_values); + } + break; } diff --git a/gcc/toplev.c b/gcc/toplev.c index 98ea0588013..88d48c2d688 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -1555,9 +1555,18 @@ process_options (void) warn_stack_protect = 0; /* Address Sanitizer needs porting to each target architecture. */ + if ((flag_sanitize & SANITIZE_ADDRESS) - && (targetm.asan_shadow_offset == NULL - || !FRAME_GROWS_DOWNWARD)) + && !FRAME_GROWS_DOWNWARD) + { + warning (0, + "-fsanitize=address and -fsanitize=kernel-address " + "are not supported for this target"); + flag_sanitize &= ~SANITIZE_ADDRESS; + } + + if ((flag_sanitize & SANITIZE_USER_ADDRESS) + && targetm.asan_shadow_offset == NULL) { warning (0, "-fsanitize=address not supported for this target"); flag_sanitize &= ~SANITIZE_ADDRESS; |