aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/common.opt5
-rw-r--r--gcc/config/aarch64/aarch64.c12
-rw-r--r--gcc/config/gnu-user.h8
-rw-r--r--gcc/cppbuiltin.c3
-rw-r--r--gcc/doc/invoke.texi83
-rw-r--r--gcc/doc/tm.texi9
-rw-r--r--gcc/doc/tm.texi.in2
-rw-r--r--gcc/flag-types.h3
-rw-r--r--gcc/gcc.c25
-rw-r--r--gcc/opts.c98
-rw-r--r--gcc/params.opt24
-rw-r--r--gcc/target.def15
-rw-r--r--gcc/targhooks.c6
-rw-r--r--gcc/targhooks.h1
-rw-r--r--gcc/toplev.c9
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
diff --git a/gcc/gcc.c b/gcc/gcc.c
index d78b5f5..16a6ee5 100644
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -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)
diff --git a/gcc/opts.c b/gcc/opts.c
index 5777491..cc1d0cc 100644
--- a/gcc/opts.c
+++ b/gcc/opts.c
@@ -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. */