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

Reply via email to