diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/common.opt | 5 | ||||
-rw-r--r-- | gcc/config/aarch64/aarch64.c | 12 | ||||
-rw-r--r-- | gcc/config/gnu-user.h | 8 | ||||
-rw-r--r-- | gcc/cppbuiltin.c | 3 | ||||
-rw-r--r-- | gcc/doc/invoke.texi | 83 | ||||
-rw-r--r-- | gcc/doc/tm.texi | 9 | ||||
-rw-r--r-- | gcc/doc/tm.texi.in | 2 | ||||
-rw-r--r-- | gcc/flag-types.h | 3 | ||||
-rw-r--r-- | gcc/gcc.c | 25 | ||||
-rw-r--r-- | gcc/opts.c | 98 | ||||
-rw-r--r-- | gcc/params.opt | 24 | ||||
-rw-r--r-- | gcc/target.def | 15 | ||||
-rw-r--r-- | gcc/targhooks.c | 6 | ||||
-rw-r--r-- | gcc/targhooks.h | 1 | ||||
-rw-r--r-- | gcc/toplev.c | 9 |
15 files changed, 283 insertions, 20 deletions
diff --git a/gcc/common.opt b/gcc/common.opt index ca8a269..582e2aa 100644 --- a/gcc/common.opt +++ b/gcc/common.opt @@ -218,7 +218,7 @@ unsigned int flag_sanitize ; What sanitizers should recover from errors Variable -unsigned int flag_sanitize_recover = (SANITIZE_UNDEFINED | SANITIZE_UNDEFINED_NONDEFAULT | SANITIZE_KERNEL_ADDRESS) & ~(SANITIZE_UNREACHABLE | SANITIZE_RETURN) +unsigned int flag_sanitize_recover = (SANITIZE_UNDEFINED | SANITIZE_UNDEFINED_NONDEFAULT | SANITIZE_KERNEL_ADDRESS | SANITIZE_KERNEL_HWADDRESS) & ~(SANITIZE_UNREACHABLE | SANITIZE_RETURN) ; What the coverage sanitizers should instrument Variable @@ -3448,6 +3448,9 @@ Driver static-libasan Driver +static-libhwasan +Driver + static-libtsan Driver diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c index 3189dfb..140ee79 100644 --- a/gcc/config/aarch64/aarch64.c +++ b/gcc/config/aarch64/aarch64.c @@ -23321,6 +23321,15 @@ aarch64_invalid_binary_op (int op ATTRIBUTE_UNUSED, const_tree type1, return NULL; } +/* Implement TARGET_MEMTAG_CAN_TAG_ADDRESSES. Here we tell the rest of the + compiler that we automatically ignore the top byte of our pointers, which + allows using -fsanitize=hwaddress. */ +bool +aarch64_can_tag_addresses () +{ + return !TARGET_ILP32; +} + /* Implement TARGET_ASM_FILE_END for AArch64. This adds the AArch64 GNU NOTE section at the end if needed. */ #define GNU_PROPERTY_AARCH64_FEATURE_1_AND 0xc0000000 @@ -24140,6 +24149,9 @@ aarch64_libgcc_floating_mode_supported_p #undef TARGET_FNTYPE_ABI #define TARGET_FNTYPE_ABI aarch64_fntype_abi +#undef TARGET_MEMTAG_CAN_TAG_ADDRESSES +#define TARGET_MEMTAG_CAN_TAG_ADDRESSES aarch64_can_tag_addresses + #if CHECKING_P #undef TARGET_RUN_TARGET_SELFTESTS #define TARGET_RUN_TARGET_SELFTESTS selftest::aarch64_run_selftests diff --git a/gcc/config/gnu-user.h b/gcc/config/gnu-user.h index ff2e880..9295024 100644 --- a/gcc/config/gnu-user.h +++ b/gcc/config/gnu-user.h @@ -129,14 +129,18 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see /* Link -lasan early on the command line. For -static-libasan, don't link it for -shared link, the executable should be compiled with -static-libasan in that case, and for executable link with --{,no-}whole-archive around - it to force everything into the executable. And similarly for -ltsan - and -llsan. */ + it to force everything into the executable. And similarly for -ltsan, + -lhwasan, and -llsan. */ #if defined(HAVE_LD_STATIC_DYNAMIC) #undef LIBASAN_EARLY_SPEC #define LIBASAN_EARLY_SPEC "%{!shared:libasan_preinit%O%s} " \ "%{static-libasan:%{!shared:" \ LD_STATIC_OPTION " --whole-archive -lasan --no-whole-archive " \ LD_DYNAMIC_OPTION "}}%{!static-libasan:-lasan}" +#undef LIBHWASAN_EARLY_SPEC +#define LIBHWASAN_EARLY_SPEC "%{static-libhwasan:%{!shared:" \ + LD_STATIC_OPTION " --whole-archive -lhwasan --no-whole-archive " \ + LD_DYNAMIC_OPTION "}}%{!static-libhwasan:-lhwasan}" #undef LIBTSAN_EARLY_SPEC #define LIBTSAN_EARLY_SPEC "%{!shared:libtsan_preinit%O%s} " \ "%{static-libtsan:%{!shared:" \ diff --git a/gcc/cppbuiltin.c b/gcc/cppbuiltin.c index 61efe9b..fc61c78 100644 --- a/gcc/cppbuiltin.c +++ b/gcc/cppbuiltin.c @@ -93,6 +93,9 @@ define_builtin_macros_for_compilation_flags (cpp_reader *pfile) if (flag_sanitize & SANITIZE_ADDRESS) cpp_define (pfile, "__SANITIZE_ADDRESS__"); + if (flag_sanitize & SANITIZE_HWADDRESS) + cpp_define (pfile, "__SANITIZE_HWADDRESS__"); + if (flag_sanitize & SANITIZE_THREAD) cpp_define (pfile, "__SANITIZE_THREAD__"); diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 26372a2..0621d47 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -13829,6 +13829,53 @@ is greater or equal to this number, use callbacks instead of inline checks. E.g. to disable inline code use @option{--param asan-instrumentation-with-call-threshold=0}. +@item hwasan-instrument-stack +Enable hwasan instrumentation of statically sized stack-allocated variables. +This kind of instrumentation is enabled by default when using +@option{-fsanitize=hwaddress} and disabled by default when using +@option{-fsanitize=kernel-hwaddress}. +To disable stack instrumentation use +@option{--param hwasan-instrument-stack=0}, and to enable it use +@option{--param hwasan-instrument-stack=1}. + +@item hwasan-random-frame-tag +When using stack instrumentation, decide tags for stack variables using a +deterministic sequence beginning at a random tag for each frame. With this +parameter unset tags are chosen using the same sequence but beginning from 1. +This is enabled by default for @option{-fsanitize=hwaddress} and unavailable +for @option{-fsanitize=kernel-hwaddress}. +To disable it use @option{--param hwasan-random-frame-tag=0}. + +@item hwasan-instrument-allocas +Enable hwasan instrumentation of dynamically sized stack-allocated variables. +This kind of instrumentation is enabled by default when using +@option{-fsanitize=hwaddress} and disabled by default when using +@option{-fsanitize=kernel-hwaddress}. +To disable instrumentation of such variables use +@option{--param hwasan-instrument-allocas=0}, and to enable it use +@option{--param hwasan-instrument-allocas=1}. + +@item hwasan-instrument-reads +Enable hwasan checks on memory reads. Instrumentation of reads is enabled by +default for both @option{-fsanitize=hwaddress} and +@option{-fsanitize=kernel-hwaddress}. +To disable checking memory reads use +@option{--param hwasan-instrument-reads=0}. + +@item hwasan-instrument-writes +Enable hwasan checks on memory writes. Instrumentation of writes is enabled by +default for both @option{-fsanitize=hwaddress} and +@option{-fsanitize=kernel-hwaddress}. +To disable checking memory writes use +@option{--param hwasan-instrument-writes=0}. + +@item hwasan-instrument-mem-intrinsics +Enable hwasan instrumentation of builtin functions. Instrumentation of these +builtin functions is enabled by default for both @option{-fsanitize=hwaddress} +and @option{-fsanitize=kernel-hwaddress}. +To disable instrumentation of builtin functions use +@option{--param hwasan-instrument-mem-intrinsics=0}. + @item use-after-scope-direct-emission-threshold If the size of a local variable in bytes is smaller or equal to this number, directly poison (or unpoison) shadow memory instead of using @@ -14391,13 +14438,47 @@ more details. The run-time behavior can be influenced using the the available options are shown at startup of the instrumented program. See @url{https://github.com/google/sanitizers/wiki/AddressSanitizerFlags#run-time-flags} for a list of supported options. -The option cannot be combined with @option{-fsanitize=thread}. +The option cannot be combined with @option{-fsanitize=thread} or +@option{-fsanitize=hwaddress}. Note that the only target this option is +currently supported on is AArch64. @item -fsanitize=kernel-address @opindex fsanitize=kernel-address Enable AddressSanitizer for Linux kernel. See @uref{https://github.com/google/kasan/wiki} for more details. +@item -fsanitize=hwaddress +@opindex fsanitize=hwaddress +Enable Hardware-assisted AddressSanitizer, which uses a hardware ability to +ignore the top byte of a pointer to allow the detection of memory errors with +a low memory overhead. +Memory access instructions are instrumented to detect out-of-bounds and +use-after-free bugs. +The option enables @option{-fsanitize-address-use-after-scope}. +See +@uref{https://clang.llvm.org/docs/HardwareAssistedAddressSanitizerDesign.html} +for more details. The run-time behavior can be influenced using the +@env{HWASAN_OPTIONS} environment variable. When set to @code{help=1}, +the available options are shown at startup of the instrumented program. +The option cannot be combined with @option{-fsanitize=thread} or +@option{-fsanitize=address}, and is currently only available on AArch64. + +@item -fsanitize=kernel-hwaddress +@opindex fsanitize=kernel-hwaddress +Enable Hardware-assisted AddressSanitizer for compilation of the Linux kernel. +Similar to @option{-fsanitize=kernel-address} but using an alternate +instrumentation method, and similar to @option{-fsanitize=hwaddress} but with +instrumentation differences necessary for compiling the Linux kernel. +These differences are to avoid hwasan library initialization calls and to +account for the stack pointer having a different value in its top byte. + +@emph{Note:} This option has different defaults to the @option{-fsanitize=hwaddress}. +Instrumenting the stack and alloca calls are not on by default but are still +possible by specifying the command-line options +@option{--param hwasan-instrument-stack=1} and +@option{--param hwasan-instrument-allocas=1} respectively. Using a random frame +tag is not implemented for kernel instrumentation. + @item -fsanitize=pointer-compare @opindex fsanitize=pointer-compare Instrument comparison operation (<, <=, >, >=) with pointer operands. diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index 2b88f78..dda71bb 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -12222,3 +12222,12 @@ This target hook can be used to generate a target-specific code @deftypefn {Target Hook} void TARGET_RUN_TARGET_SELFTESTS (void) If selftests are enabled, run any selftests for this target. @end deftypefn + +@deftypefn {Target Hook} bool TARGET_MEMTAG_CAN_TAG_ADDRESSES () +True if the backend architecture naturally supports ignoring some region +of pointers. This feature means that @option{-fsanitize=hwaddress} can +work. + +At preset, this feature does not support address spaces. It also requires +@code{Pmode} to be the same as @code{ptr_mode}. +@end deftypefn diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in index 897f289..8fbd36e 100644 --- a/gcc/doc/tm.texi.in +++ b/gcc/doc/tm.texi.in @@ -8184,3 +8184,5 @@ maintainer is familiar with. @hook TARGET_SPECULATION_SAFE_VALUE @hook TARGET_RUN_TARGET_SELFTESTS + +@hook TARGET_MEMTAG_CAN_TAG_ADDRESSES diff --git a/gcc/flag-types.h b/gcc/flag-types.h index 0dbab19..9342bd8 100644 --- a/gcc/flag-types.h +++ b/gcc/flag-types.h @@ -276,6 +276,9 @@ enum sanitize_code { SANITIZE_BUILTIN = 1UL << 25, SANITIZE_POINTER_COMPARE = 1UL << 26, SANITIZE_POINTER_SUBTRACT = 1UL << 27, + SANITIZE_HWADDRESS = 1UL << 28, + SANITIZE_USER_HWADDRESS = 1UL << 29, + SANITIZE_KERNEL_HWADDRESS = 1UL << 30, SANITIZE_SHIFT = SANITIZE_SHIFT_BASE | SANITIZE_SHIFT_EXPONENT, SANITIZE_UNDEFINED = SANITIZE_SHIFT | SANITIZE_DIVIDE | SANITIZE_UNREACHABLE | SANITIZE_VLA | SANITIZE_NULL | SANITIZE_RETURN @@ -749,6 +749,24 @@ proper position among the other output files. */ #define LIBASAN_EARLY_SPEC "" #endif +#ifndef LIBHWASAN_SPEC +#define STATIC_LIBHWASAN_LIBS \ + " %{static-libhwasan|static:%:include(libsanitizer.spec)%(link_libhwasan)}" +#ifdef LIBHWASAN_EARLY_SPEC +#define LIBHWASAN_SPEC STATIC_LIBHWASAN_LIBS +#elif defined(HAVE_LD_STATIC_DYNAMIC) +#define LIBHWASAN_SPEC "%{static-libhwasan:" LD_STATIC_OPTION \ + "} -lhwasan %{static-libhwasan:" LD_DYNAMIC_OPTION "}" \ + STATIC_LIBHWASAN_LIBS +#else +#define LIBHWASAN_SPEC "-lhwasan" STATIC_LIBHWASAN_LIBS +#endif +#endif + +#ifndef LIBHWASAN_EARLY_SPEC +#define LIBHWASAN_EARLY_SPEC "" +#endif + #ifndef LIBTSAN_SPEC #define STATIC_LIBTSAN_LIBS \ " %{static-libtsan|static:%:include(libsanitizer.spec)%(link_libtsan)}" @@ -1071,6 +1089,7 @@ proper position among the other output files. */ #ifndef SANITIZER_EARLY_SPEC #define SANITIZER_EARLY_SPEC "\ %{!nostdlib:%{!r:%{!nodefaultlibs:%{%:sanitize(address):" LIBASAN_EARLY_SPEC "} \ + %{%:sanitize(hwaddress):" LIBHWASAN_EARLY_SPEC "} \ %{%:sanitize(thread):" LIBTSAN_EARLY_SPEC "} \ %{%:sanitize(leak):" LIBLSAN_EARLY_SPEC "}}}}" #endif @@ -1080,6 +1099,8 @@ proper position among the other output files. */ #define SANITIZER_SPEC "\ %{!nostdlib:%{!r:%{!nodefaultlibs:%{%:sanitize(address):" LIBASAN_SPEC "\ %{static:%ecannot specify -static with -fsanitize=address}}\ + %{%:sanitize(hwaddress):" LIBHWASAN_SPEC "\ + %{static:%ecannot specify -static with -fsanitize=hwaddress}}\ %{%:sanitize(thread):" LIBTSAN_SPEC "\ %{static:%ecannot specify -static with -fsanitize=thread}}\ %{%:sanitize(undefined):" LIBUBSAN_SPEC "}\ @@ -10131,8 +10152,12 @@ sanitize_spec_function (int argc, const char **argv) if (strcmp (argv[0], "address") == 0) return (flag_sanitize & SANITIZE_USER_ADDRESS) ? "" : NULL; + if (strcmp (argv[0], "hwaddress") == 0) + return (flag_sanitize & SANITIZE_USER_HWADDRESS) ? "" : NULL; if (strcmp (argv[0], "kernel-address") == 0) return (flag_sanitize & SANITIZE_KERNEL_ADDRESS) ? "" : NULL; + if (strcmp (argv[0], "kernel-hwaddress") == 0) + return (flag_sanitize & SANITIZE_KERNEL_HWADDRESS) ? "" : NULL; if (strcmp (argv[0], "thread") == 0) return (flag_sanitize & SANITIZE_THREAD) ? "" : NULL; if (strcmp (argv[0], "undefined") == 0) @@ -823,6 +823,57 @@ control_options_for_live_patching (struct gcc_options *opts, /* --help option argument if set. */ vec<const char *> help_option_arguments; +/* Return the string name describing a sanitizer argument which has been + provided on the command line and has set this particular flag. */ +const char * +find_sanitizer_argument (struct gcc_options *opts, unsigned int flags) +{ + for (int i = 0; sanitizer_opts[i].name != NULL; ++i) + { + /* Need to find the sanitizer_opts element which: + a) Could have set the flags requested. + b) Has been set on the command line. + + Can have (a) without (b) if the flag requested is e.g. + SANITIZE_ADDRESS, since both -fsanitize=address and + -fsanitize=kernel-address set this flag. + + Can have (b) without (a) by requesting more than one sanitizer on the + command line. */ + if ((sanitizer_opts[i].flag & opts->x_flag_sanitize) + != sanitizer_opts[i].flag) + continue; + if ((sanitizer_opts[i].flag & flags) != flags) + continue; + return sanitizer_opts[i].name; + } + return NULL; +} + + +/* Report an error to the user about sanitizer options they have requested + which have set conflicting flags. + + LEFT and RIGHT indicate sanitizer flags which conflict with each other, this + function reports an error if both have been set in OPTS->x_flag_sanitize and + ensures the error identifies the requested command line options that have + set these flags. */ +static void +report_conflicting_sanitizer_options (struct gcc_options *opts, location_t loc, + unsigned int left, unsigned int right) +{ + unsigned int left_seen = (opts->x_flag_sanitize & left); + unsigned int right_seen = (opts->x_flag_sanitize & right); + if (left_seen && right_seen) + { + const char* left_arg = find_sanitizer_argument (opts, left_seen); + const char* right_arg = find_sanitizer_argument (opts, right_seen); + gcc_assert (left_arg && right_arg); + error_at (loc, + "%<-fsanitize=%s%> is incompatible with %<-fsanitize=%s%>", + left_arg, right_arg); + } +} /* After all options at LOC have been read into OPTS and OPTS_SET, finalize settings of those options and diagnose incompatible @@ -1074,22 +1125,22 @@ finish_options (struct gcc_options *opts, struct gcc_options *opts_set, "%<-fsanitize=address%> or %<-fsanitize=kernel-address%>"); } - /* Userspace and kernel ASan conflict with each other. */ - if ((opts->x_flag_sanitize & SANITIZE_USER_ADDRESS) - && (opts->x_flag_sanitize & SANITIZE_KERNEL_ADDRESS)) - error_at (loc, "%qs is incompatible with %qs", - "-fsanitize=address", "-fsanitize=kernel-address"); + /* Address sanitizers conflict with the thread sanitizer. */ + report_conflicting_sanitizer_options (opts, loc, SANITIZE_THREAD, + SANITIZE_ADDRESS | SANITIZE_HWADDRESS); + /* The leak sanitizer conflicts with the thread sanitizer. */ + report_conflicting_sanitizer_options (opts, loc, SANITIZE_LEAK, + SANITIZE_THREAD); - /* And with TSan. */ - if ((opts->x_flag_sanitize & SANITIZE_ADDRESS) - && (opts->x_flag_sanitize & SANITIZE_THREAD)) - error_at (loc, "%qs is incompatible with %qs", - "-fsanitize=thread", "-fsanitize=address|kernel-address"); + /* No combination of HWASAN and ASAN work together. */ + report_conflicting_sanitizer_options (opts, loc, + SANITIZE_HWADDRESS, SANITIZE_ADDRESS); - if ((opts->x_flag_sanitize & SANITIZE_LEAK) - && (opts->x_flag_sanitize & SANITIZE_THREAD)) - error_at (loc, "%qs is incompatible with %qs", - "-fsanitize=leak", "-fsanitize=thread"); + /* The userspace and kernel address sanitizers conflict with each other. */ + report_conflicting_sanitizer_options (opts, loc, SANITIZE_USER_HWADDRESS, + SANITIZE_KERNEL_HWADDRESS); + report_conflicting_sanitizer_options (opts, loc, SANITIZE_USER_ADDRESS, + SANITIZE_KERNEL_ADDRESS); /* Check error recovery for -fsanitize-recover option. */ for (int i = 0; sanitizer_opts[i].name != NULL; ++i) @@ -1108,9 +1159,10 @@ finish_options (struct gcc_options *opts, struct gcc_options *opts_set, if (opts->x_flag_sanitize & ~(SANITIZE_LEAK | SANITIZE_UNREACHABLE)) opts->x_flag_aggressive_loop_optimizations = 0; - /* Enable -fsanitize-address-use-after-scope if address sanitizer is + /* Enable -fsanitize-address-use-after-scope if either address sanitizer is enabled. */ - if (opts->x_flag_sanitize & SANITIZE_USER_ADDRESS) + if (opts->x_flag_sanitize + & (SANITIZE_USER_ADDRESS | SANITIZE_USER_HWADDRESS)) SET_OPTION_IF_UNSET (opts, opts_set, flag_sanitize_address_use_after_scope, true); @@ -1724,8 +1776,13 @@ const struct sanitizer_opts_s sanitizer_opts[] = #define SANITIZER_OPT(name, flags, recover) \ { #name, flags, sizeof #name - 1, recover } SANITIZER_OPT (address, (SANITIZE_ADDRESS | SANITIZE_USER_ADDRESS), true), + SANITIZER_OPT (hwaddress, (SANITIZE_HWADDRESS | SANITIZE_USER_HWADDRESS), + true), SANITIZER_OPT (kernel-address, (SANITIZE_ADDRESS | SANITIZE_KERNEL_ADDRESS), true), + SANITIZER_OPT (kernel-hwaddress, + (SANITIZE_HWADDRESS | SANITIZE_KERNEL_HWADDRESS), + true), SANITIZER_OPT (pointer-compare, SANITIZE_POINTER_COMPARE, true), SANITIZER_OPT (pointer-subtract, SANITIZE_POINTER_SUBTRACT, true), SANITIZER_OPT (thread, SANITIZE_THREAD, false), @@ -2304,6 +2361,15 @@ common_handle_option (struct gcc_options *opts, SET_OPTION_IF_UNSET (opts, opts_set, param_asan_protect_allocas, 0); SET_OPTION_IF_UNSET (opts, opts_set, param_asan_use_after_return, 0); } + if (opts->x_flag_sanitize & SANITIZE_KERNEL_HWADDRESS) + { + SET_OPTION_IF_UNSET (opts, opts_set, + param_hwasan_instrument_stack, 0); + SET_OPTION_IF_UNSET (opts, opts_set, + param_hwasan_random_frame_tag, 0); + SET_OPTION_IF_UNSET (opts, opts_set, + param_hwasan_instrument_allocas, 0); + } break; case OPT_fsanitize_recover_: diff --git a/gcc/params.opt b/gcc/params.opt index 202d92f..ec15357 100644 --- a/gcc/params.opt +++ b/gcc/params.opt @@ -62,6 +62,30 @@ Enable asan stack protection. Common Joined UInteger Var(param_asan_use_after_return) Init(1) IntegerRange(0, 1) Param Optimization Enable asan detection of use-after-return bugs. +-param=hwasan-instrument-stack= +Common Joined UInteger Var(param_hwasan_instrument_stack) Init(1) IntegerRange(0, 1) Param Optimization +Enable hwasan instrumentation of statically sized stack-allocated variables. + +-param=hwasan-random-frame-tag= +Common Joined UInteger Var(param_hwasan_random_frame_tag) Init(1) IntegerRange(0, 1) Param Optimization +Use random base tag for each frame, as opposed to base always zero. + +-param=hwasan-instrument-allocas= +Common Joined UInteger Var(param_hwasan_instrument_allocas) Init(1) IntegerRange(0, 1) Param Optimization +Enable hwasan instrumentation of allocas/VLAs. + +-param=hwasan-instrument-reads= +Common Joined UInteger Var(param_hwasan_instrument_reads) Init(1) IntegerRange(0, 1) Param Optimization +Enable hwasan instrumentation of load operations. + +-param=hwasan-instrument-writes= +Common Joined UInteger Var(param_hwasan_instrument_writes) Init(1) IntegerRange(0, 1) Param Optimization +Enable hwasan instrumentation of store operations. + +-param=hwasan-instrument-mem-intrinsics= +Common Joined UInteger Var(param_hwasan_instrument_mem_intrinsics) Init(1) IntegerRange(0, 1) Param Optimization +Enable hwasan instrumentation of builtin functions. + -param=avg-loop-niter= Common Joined UInteger Var(param_avg_loop_niter) Init(10) IntegerRange(1, 65536) Param Optimization Average number of iterations of a loop. diff --git a/gcc/target.def b/gcc/target.def index 810d554..31e33ec 100644 --- a/gcc/target.def +++ b/gcc/target.def @@ -6863,6 +6863,21 @@ DEFHOOK HOOK_VECTOR_END (mode_switching) #undef HOOK_PREFIX +#define HOOK_PREFIX "TARGET_MEMTAG_" +HOOK_VECTOR (TARGET_MEMTAG_, memtag) + +DEFHOOK +(can_tag_addresses, + "True if the backend architecture naturally supports ignoring some region\n\ +of pointers. This feature means that @option{-fsanitize=hwaddress} can\n\ +work.\n\ +\n\ +At preset, this feature does not support address spaces. It also requires\n\ +@code{Pmode} to be the same as @code{ptr_mode}.", + bool, (), default_memtag_can_tag_addresses) + +HOOK_VECTOR_END (memtag) +#undef HOOK_PREFIX #define HOOK_PREFIX "TARGET_" #define DEF_TARGET_INSN(NAME, PROTO) \ diff --git a/gcc/targhooks.c b/gcc/targhooks.c index 5b68a2a..46cb536 100644 --- a/gcc/targhooks.c +++ b/gcc/targhooks.c @@ -2415,4 +2415,10 @@ default_speculation_safe_value (machine_mode mode ATTRIBUTE_UNUSED, return result; } +bool +default_memtag_can_tag_addresses () +{ + return false; +} + #include "gt-targhooks.h" diff --git a/gcc/targhooks.h b/gcc/targhooks.h index e0a925f..0065c68 100644 --- a/gcc/targhooks.h +++ b/gcc/targhooks.h @@ -286,4 +286,5 @@ extern bool default_have_speculation_safe_value (bool); extern bool speculation_safe_value_not_needed (bool); extern rtx default_speculation_safe_value (machine_mode, rtx, rtx, rtx); +extern bool default_memtag_can_tag_addresses (); #endif /* GCC_TARGHOOKS_H */ diff --git a/gcc/toplev.c b/gcc/toplev.c index e0e0e04..2a3e7c0 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -1853,6 +1853,15 @@ process_options (void) flag_sanitize &= ~SANITIZE_ADDRESS; } + /* HWAsan requires top byte ignore feature in the backend. */ + if (flag_sanitize & SANITIZE_HWADDRESS + && ! targetm.memtag.can_tag_addresses ()) + { + warning_at (UNKNOWN_LOCATION, 0, "%qs is not supported for this target", + "-fsanitize=hwaddress"); + flag_sanitize &= ~SANITIZE_HWADDRESS; + } + /* Do not use IPA optimizations for register allocation if profiler is active or patchable function entries are inserted for run-time instrumentation or port does not emit prologue and epilogue as RTL. */ |