Grow the frame downward when ASan is enabled, as Alpha already does for
the stack protector; otherwise process_options disables ASan with a
warning.
Use a fixed shadow offset of 1T, matching libsanitizer. Alpha's user
address space ends at TASK_SIZE (4T), so this leaves LowMem below 1T
and HighMem from 1.5T.
alpha/linux.h doesn't include gnu-user.h, so copy its
LIBASAN_EARLY_SPEC, which links libasan first as the runtime requires.
gcc/ChangeLog:
* config/alpha/alpha.h (FRAME_GROWS_DOWNWARD): Also for
-fsanitize=address.
* config/alpha/alpha.cc (alpha_asan_shadow_offset): New.
(TARGET_ASAN_SHADOW_OFFSET): Define.
* config/alpha/linux.h (LIBASAN_EARLY_SPEC): Define.
---
gcc/config/alpha/alpha.cc | 11 +++++++++++
gcc/config/alpha/alpha.h | 8 +++++---
gcc/config/alpha/linux.h | 9 +++++++++
3 files changed, 25 insertions(+), 3 deletions(-)
diff --git a/gcc/config/alpha/alpha.cc b/gcc/config/alpha/alpha.cc
index 7355f05182c..8103c78552a 100644
--- a/gcc/config/alpha/alpha.cc
+++ b/gcc/config/alpha/alpha.cc
@@ -10956,6 +10956,17 @@ alpha_c_mode_for_floating_type (enum tree_index ti)
#undef TARGET_C_MODE_FOR_FLOATING_TYPE
#define TARGET_C_MODE_FOR_FLOATING_TYPE alpha_c_mode_for_floating_type
+/* Must match ASAN_SHADOW_OFFSET_CONST in libsanitizer/asan/asan_mapping.h. */
+
+static unsigned HOST_WIDE_INT
+alpha_asan_shadow_offset (void)
+{
+ return HOST_WIDE_INT_1U << 40;
+}
+
+#undef TARGET_ASAN_SHADOW_OFFSET
+#define TARGET_ASAN_SHADOW_OFFSET alpha_asan_shadow_offset
+
struct gcc_target targetm = TARGET_INITIALIZER;
diff --git a/gcc/config/alpha/alpha.h b/gcc/config/alpha/alpha.h
index 405e40fcee0..742062ceca7 100644
--- a/gcc/config/alpha/alpha.h
+++ b/gcc/config/alpha/alpha.h
@@ -483,9 +483,11 @@ enum reg_class {
The stack protector requires that the canary be placed above the
local arrays it protects, which only happens with a downward-growing
- frame. Alpha otherwise grows the frame upward, so switch the
- direction only when the stack protector is in use. */
-#define FRAME_GROWS_DOWNWARD (flag_stack_protect != 0)
+ frame. AddressSanitizer needs a downward-growing frame too.
+ Alpha otherwise grows the frame upward, so switch the direction only
+ when one of them is in use. */
+#define FRAME_GROWS_DOWNWARD (flag_stack_protect != 0 \
+ || (flag_sanitize & SANITIZE_ADDRESS) != 0)
/* If we generate an insn to push BYTES bytes,
this says how many the stack pointer really advances by.
diff --git a/gcc/config/alpha/linux.h b/gcc/config/alpha/linux.h
index 71724dded7e..6837bfe88fc 100644
--- a/gcc/config/alpha/linux.h
+++ b/gcc/config/alpha/linux.h
@@ -83,6 +83,15 @@ along with GCC; see the file COPYING3. If not see
#define TARGET_POSIX_IO
+/* As in gnu-user.h, which Alpha doesn't include. */
+#ifdef 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}"
+#endif
+
/* Provide a STARTFILE_SPEC appropriate for ELF. Here we add the
(even more) magical crtbegin.o file which provides part of the
support for getting C++ file-scope static object constructed
--
2.56.1