summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdhemerval Zanella <adhemerval.zanella@linaro.org>2015-08-05 15:17:59 +0000
committerAdhemerval Zanella <adhemerval.zanella@linaro.org>2015-08-05 15:17:59 +0000
commit925201613a92897de9019c1b5fd0199622820012 (patch)
treede96d35ac1091b384743fdc90c0ec645a666d35e
parent05e761714b3b67a43cc9a0c67bc6750d7994d7ef (diff)
[tsan] Enable tsan for aarch64
This patch enabled TSAN for aarch64 with 39-bit VMA layout. As defined by tsan_platform.h the layout used is: 0000 4000 00 - 0200 0000 00: main binary 2000 0000 00 - 4000 0000 00: shadow memory 4000 0000 00 - 5000 0000 00: metainfo 5000 0000 00 - 6000 0000 00: - 6000 0000 00 - 6200 0000 00: traces 6200 0000 00 - 7d00 0000 00: - 7d00 0000 00 - 7e00 0000 00: heap 7e00 0000 00 - 7fff ffff ff: modules and main thread stack Which gives it about 8GB for main binary, 4GB for heap and 8GB for modules and main thread stack. Most of tests are passing, with the exception of: * ignore_lib0, ignore_lib1, ignore_lib3 due a kernel limitation for no support to make mmap page non-executable. * longjmp tests due missing specialized assembly routines. These tests are xfail for now. The only tsan issue still showing is: rtl/TsanRtlTest/Posix.ThreadLocalAccesses Which still required further investigation. The test is disable for aarch64 for now. git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@244055 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--cmake/config-ix.cmake2
-rw-r--r--lib/sanitizer_common/sanitizer_linux.cc51
-rw-r--r--lib/sanitizer_common/sanitizer_linux.h2
-rw-r--r--lib/sanitizer_common/sanitizer_linux_libcdep.cc18
-rw-r--r--lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc27
-rw-r--r--lib/tsan/rtl/tsan_interceptors.cc18
-rw-r--r--lib/tsan/rtl/tsan_platform.h27
-rw-r--r--lib/tsan/rtl/tsan_platform_linux.cc3
-rw-r--r--lib/tsan/rtl/tsan_rtl.h2
-rw-r--r--lib/tsan/tests/rtl/tsan_posix.cc6
-rw-r--r--test/tsan/ignore_lib0.cc3
-rw-r--r--test/tsan/ignore_lib1.cc2
-rw-r--r--test/tsan/ignore_lib3.cc3
-rw-r--r--test/tsan/longjmp.cc3
-rw-r--r--test/tsan/longjmp2.cc3
-rw-r--r--test/tsan/longjmp3.cc3
-rw-r--r--test/tsan/longjmp4.cc3
-rw-r--r--test/tsan/map32bit.cc1
-rw-r--r--test/tsan/mmap_large.cc2
-rw-r--r--test/tsan/signal_longjmp.cc3
-rw-r--r--test/tsan/test.h2
21 files changed, 161 insertions, 23 deletions
diff --git a/cmake/config-ix.cmake b/cmake/config-ix.cmake
index 1fc442430..f5695a279 100644
--- a/cmake/config-ix.cmake
+++ b/cmake/config-ix.cmake
@@ -260,7 +260,7 @@ filter_available_targets(LSAN_SUPPORTED_ARCH x86_64 mips64 mips64el)
filter_available_targets(MSAN_SUPPORTED_ARCH x86_64 mips64 mips64el)
filter_available_targets(PROFILE_SUPPORTED_ARCH x86_64 i386 i686 arm mips mips64
mipsel mips64el aarch64 powerpc64 powerpc64le)
-filter_available_targets(TSAN_SUPPORTED_ARCH x86_64 mips64 mips64el)
+filter_available_targets(TSAN_SUPPORTED_ARCH x86_64 mips64 mips64el aarch64)
filter_available_targets(UBSAN_SUPPORTED_ARCH x86_64 i386 i686 arm aarch64 mips
mipsel mips64 mips64el powerpc64 powerpc64le)
filter_available_targets(SAFESTACK_SUPPORTED_ARCH x86_64 i386 i686)
diff --git a/lib/sanitizer_common/sanitizer_linux.cc b/lib/sanitizer_common/sanitizer_linux.cc
index 681b6f3fa..3da165dc5 100644
--- a/lib/sanitizer_common/sanitizer_linux.cc
+++ b/lib/sanitizer_common/sanitizer_linux.cc
@@ -926,6 +926,57 @@ uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg,
: "memory", "$29" );
return res;
}
+#elif defined(__aarch64__)
+uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg,
+ int *parent_tidptr, void *newtls, int *child_tidptr) {
+ long long res;
+ if (!fn || !child_stack)
+ return -EINVAL;
+ CHECK_EQ(0, (uptr)child_stack % 16);
+ child_stack = (char *)child_stack - 2 * sizeof(unsigned long long);
+ ((unsigned long long *)child_stack)[0] = (uptr)fn;
+ ((unsigned long long *)child_stack)[1] = (uptr)arg;
+
+ register int (*__fn)(void *) __asm__("x0") = fn;
+ register void *__stack __asm__("x1") = child_stack;
+ register int __flags __asm__("x2") = flags;
+ register void *__arg __asm__("x3") = arg;
+ register int *__ptid __asm__("x4") = parent_tidptr;
+ register void *__tls __asm__("x5") = newtls;
+ register int *__ctid __asm__("x6") = child_tidptr;
+
+ __asm__ __volatile__(
+ "mov x0,x2\n" /* flags */
+ "mov x2,x4\n" /* ptid */
+ "mov x3,x5\n" /* tls */
+ "mov x4,x6\n" /* ctid */
+ "mov x8,%9\n" /* clone */
+
+ "svc 0x0\n"
+
+ /* if (%r0 != 0)
+ * return %r0;
+ */
+ "cmp x0, #0\n"
+ "bne 1f\n"
+
+ /* In the child, now. Call "fn(arg)". */
+ "ldp x1, x0, [sp], #16\n"
+ "blr x1\n"
+
+ /* Call _exit(%r0). */
+ "mov x8, %10\n"
+ "svc 0x0\n"
+ "1:\n"
+
+ : "=r" (res)
+ : "i"(-EINVAL),
+ "r"(__fn), "r"(__stack), "r"(__flags), "r"(__arg),
+ "r"(__ptid), "r"(__tls), "r"(__ctid),
+ "i"(__NR_clone), "i"(__NR_exit)
+ : "x30", "memory");
+ return res;
+}
#endif // defined(__x86_64__) && SANITIZER_LINUX
#if SANITIZER_ANDROID
diff --git a/lib/sanitizer_common/sanitizer_linux.h b/lib/sanitizer_common/sanitizer_linux.h
index e9fc4ad44..d996f8c32 100644
--- a/lib/sanitizer_common/sanitizer_linux.h
+++ b/lib/sanitizer_common/sanitizer_linux.h
@@ -44,7 +44,7 @@ uptr internal_prctl(int option, uptr arg2, uptr arg3, uptr arg4, uptr arg5);
// internal_sigaction instead.
int internal_sigaction_norestorer(int signum, const void *act, void *oldact);
void internal_sigdelset(__sanitizer_sigset_t *set, int signum);
-#if defined(__x86_64__) || defined(__mips__)
+#if defined(__x86_64__) || defined(__mips__) || defined(__aarch64__)
uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg,
int *parent_tidptr, void *newtls, int *child_tidptr);
#endif
diff --git a/lib/sanitizer_common/sanitizer_linux_libcdep.cc b/lib/sanitizer_common/sanitizer_linux_libcdep.cc
index c17180fd8..77b6e422d 100644
--- a/lib/sanitizer_common/sanitizer_linux_libcdep.cc
+++ b/lib/sanitizer_common/sanitizer_linux_libcdep.cc
@@ -194,6 +194,8 @@ static uptr TlsPreTcbSize() {
void InitTlsSize() {
#if !SANITIZER_FREEBSD && !SANITIZER_ANDROID && !SANITIZER_GO
+// all current supported platforms have 16 bytes stack alignment
+ const size_t kStackAlign = 16;
typedef void (*get_tls_func)(size_t*, size_t*) DL_INTERNAL_FUNCTION;
get_tls_func get_tls;
void *get_tls_static_info_ptr = dlsym(RTLD_NEXT, "_dl_get_tls_static_info");
@@ -204,11 +206,14 @@ void InitTlsSize() {
size_t tls_size = 0;
size_t tls_align = 0;
get_tls(&tls_size, &tls_align);
- g_tls_size = tls_size;
+ if (tls_align < kStackAlign)
+ tls_align = kStackAlign;
+ g_tls_size = RoundUpTo(tls_size, tls_align);
#endif // !SANITIZER_FREEBSD && !SANITIZER_ANDROID && !SANITIZER_GO
}
-#if (defined(__x86_64__) || defined(__i386__) || defined(__mips__)) \
+#if (defined(__x86_64__) || defined(__i386__) || defined(__mips__) \
+ || defined(__aarch64__)) \
&& SANITIZER_LINUX
// sizeof(struct thread) from glibc.
static atomic_uintptr_t kThreadDescriptorSize;
@@ -256,6 +261,11 @@ uptr ThreadDescriptorSize() {
if (val)
atomic_store(&kThreadDescriptorSize, val, memory_order_relaxed);
return val;
+#elif defined(__aarch64__)
+ // The sizeof (struct pthread) is the same from GLIBC 2.17 to 2.22.
+ val = 1776;
+ atomic_store(&kThreadDescriptorSize, val, memory_order_relaxed);
+ return val;
#endif
return 0;
}
@@ -285,6 +295,8 @@ uptr ThreadSelf() {
rdhwr %0,$29;\
.set pop" : "=r" (thread_pointer));
descr_addr = thread_pointer - kTlsTcbOffset - TlsPreTcbSize();
+# elif defined(__aarch64__)
+ descr_addr = reinterpret_cast<uptr>(__builtin_thread_pointer());
# else
# error "unsupported CPU arch"
# endif
@@ -315,7 +327,7 @@ uptr ThreadSelf() {
#if !SANITIZER_GO
static void GetTls(uptr *addr, uptr *size) {
#if SANITIZER_LINUX
-# if defined(__x86_64__) || defined(__i386__)
+# if defined(__x86_64__) || defined(__i386__) || defined(__aarch64__)
*addr = ThreadSelf();
*size = GetTlsSize();
*addr -= *size;
diff --git a/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc b/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc
index 47b27e7e5..b5139ecad 100644
--- a/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc
+++ b/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc
@@ -14,7 +14,8 @@
#include "sanitizer_platform.h"
-#if SANITIZER_LINUX && (defined(__x86_64__) || defined(__mips__))
+#if SANITIZER_LINUX && (defined(__x86_64__) || defined(__mips__) || \
+ defined(__aarch64__))
#include "sanitizer_stoptheworld.h"
@@ -27,6 +28,8 @@
#include <sys/prctl.h> // for PR_* definitions
#include <sys/ptrace.h> // for PTRACE_* definitions
#include <sys/types.h> // for pid_t
+#include <sys/uio.h> // for iovec
+#include <elf.h> // for NT_PRSTATUS
#if SANITIZER_ANDROID && defined(__arm__)
# include <linux/user.h> // for pt_regs
#else
@@ -469,6 +472,11 @@ typedef pt_regs regs_struct;
typedef struct user regs_struct;
#define REG_SP regs[EF_REG29]
+#elif defined(__aarch64__)
+typedef struct user_pt_regs regs_struct;
+#define REG_SP sp
+#define ARCH_IOVEC_FOR_GETREGSET
+
#else
#error "Unsupported architecture"
#endif // SANITIZER_ANDROID && defined(__arm__)
@@ -479,8 +487,18 @@ int SuspendedThreadsList::GetRegistersAndSP(uptr index,
pid_t tid = GetThreadID(index);
regs_struct regs;
int pterrno;
- if (internal_iserror(internal_ptrace(PTRACE_GETREGS, tid, NULL, &regs),
- &pterrno)) {
+#ifdef ARCH_IOVEC_FOR_GETREGSET
+ struct iovec regset_io;
+ regset_io.iov_base = &regs;
+ regset_io.iov_len = sizeof(regs_struct);
+ bool isErr = internal_iserror(internal_ptrace(PTRACE_GETREGSET, tid,
+ (void*)NT_PRSTATUS, (void*)&regset_io),
+ &pterrno);
+#else
+ bool isErr = internal_iserror(internal_ptrace(PTRACE_GETREGS, tid, NULL,
+ &regs), &pterrno);
+#endif
+ if (isErr) {
VReport(1, "Could not get registers from thread %d (errno %d).\n", tid,
pterrno);
return -1;
@@ -496,4 +514,5 @@ uptr SuspendedThreadsList::RegisterCount() {
}
} // namespace __sanitizer
-#endif // SANITIZER_LINUX && (defined(__x86_64__) || defined(__mips__))
+#endif // SANITIZER_LINUX && (defined(__x86_64__) || defined(__mips__)
+ // || defined(__aarch64__)
diff --git a/lib/tsan/rtl/tsan_interceptors.cc b/lib/tsan/rtl/tsan_interceptors.cc
index e4a9d23e0..06025a4e5 100644
--- a/lib/tsan/rtl/tsan_interceptors.cc
+++ b/lib/tsan/rtl/tsan_interceptors.cc
@@ -67,6 +67,12 @@ struct ucontext_t {
};
#endif
+#if defined(__x86_64__) || defined(__mips__)
+#define PTHREAD_ABI_BASE "GLIBC_2.3.2"
+#elif defined(__aarch64__)
+#define PTHREAD_ABI_BASE "GLIBC_2.17"
+#endif
+
extern "C" int pthread_attr_init(void *attr);
extern "C" int pthread_attr_destroy(void *attr);
DECLARE_REAL(int, pthread_attr_getdetachstate, void *, void *)
@@ -2504,12 +2510,12 @@ void InitializeInterceptors() {
TSAN_INTERCEPT(pthread_join);
TSAN_INTERCEPT(pthread_detach);
- TSAN_INTERCEPT_VER(pthread_cond_init, "GLIBC_2.3.2");
- TSAN_INTERCEPT_VER(pthread_cond_signal, "GLIBC_2.3.2");
- TSAN_INTERCEPT_VER(pthread_cond_broadcast, "GLIBC_2.3.2");
- TSAN_INTERCEPT_VER(pthread_cond_wait, "GLIBC_2.3.2");
- TSAN_INTERCEPT_VER(pthread_cond_timedwait, "GLIBC_2.3.2");
- TSAN_INTERCEPT_VER(pthread_cond_destroy, "GLIBC_2.3.2");
+ TSAN_INTERCEPT_VER(pthread_cond_init, PTHREAD_ABI_BASE);
+ TSAN_INTERCEPT_VER(pthread_cond_signal, PTHREAD_ABI_BASE);
+ TSAN_INTERCEPT_VER(pthread_cond_broadcast, PTHREAD_ABI_BASE);
+ TSAN_INTERCEPT_VER(pthread_cond_wait, PTHREAD_ABI_BASE);
+ TSAN_INTERCEPT_VER(pthread_cond_timedwait, PTHREAD_ABI_BASE);
+ TSAN_INTERCEPT_VER(pthread_cond_destroy, PTHREAD_ABI_BASE);
TSAN_INTERCEPT(pthread_mutex_init);
TSAN_INTERCEPT(pthread_mutex_destroy);
diff --git a/lib/tsan/rtl/tsan_platform.h b/lib/tsan/rtl/tsan_platform.h
index 135e16027..d50301035 100644
--- a/lib/tsan/rtl/tsan_platform.h
+++ b/lib/tsan/rtl/tsan_platform.h
@@ -86,6 +86,33 @@ const uptr kHiAppMemEnd = 0xffffffffffull;
const uptr kAppMemMsk = 0xfc00000000ull;
const uptr kAppMemXor = 0x0400000000ull;
const uptr kVdsoBeg = 0xfffff00000ull;
+#elif defined(__aarch64__)
+/*
+C/C++ on linux/aarch64 (39-bit VMA)
+0000 4000 00 - 0200 0000 00: main binary
+2000 0000 00 - 4000 0000 00: shadow memory
+4000 0000 00 - 5000 0000 00: metainfo
+5000 0000 00 - 6000 0000 00: -
+6000 0000 00 - 6200 0000 00: traces
+6200 0000 00 - 7d00 0000 00: -
+7d00 0000 00 - 7e00 0000 00: heap
+7e00 0000 00 - 7fff ffff ff: modules and main thread stack
+*/
+const uptr kLoAppMemBeg = 0x0000400000ull;
+const uptr kLoAppMemEnd = 0x0200000000ull;
+const uptr kShadowBeg = 0x2000000000ull;
+const uptr kShadowEnd = 0x4000000000ull;
+const uptr kMetaShadowBeg = 0x4000000000ull;
+const uptr kMetaShadowEnd = 0x5000000000ull;
+const uptr kTraceMemBeg = 0x6000000000ull;
+const uptr kTraceMemEnd = 0x6200000000ull;
+const uptr kHeapMemBeg = 0x7d00000000ull;
+const uptr kHeapMemEnd = 0x7e00000000ull;
+const uptr kHiAppMemBeg = 0x7e00000000ull;
+const uptr kHiAppMemEnd = 0x7fffffffffull;
+const uptr kAppMemMsk = 0x7800000000ull;
+const uptr kAppMemXor = 0x0800000000ull;
+const uptr kVdsoBeg = 0x7f00000000ull;
#endif
ALWAYS_INLINE
diff --git a/lib/tsan/rtl/tsan_platform_linux.cc b/lib/tsan/rtl/tsan_platform_linux.cc
index 130905821..51637ad80 100644
--- a/lib/tsan/rtl/tsan_platform_linux.cc
+++ b/lib/tsan/rtl/tsan_platform_linux.cc
@@ -221,6 +221,9 @@ void InitializeShadowMemory() {
#elif defined(__mips64)
const uptr kMadviseRangeBeg = 0xff00000000ull;
const uptr kMadviseRangeSize = 0x0100000000ull;
+#elif defined(__aarch64__)
+ const uptr kMadviseRangeBeg = 0x7e00000000ull;
+ const uptr kMadviseRangeSize = 0x0100000000ull;
#endif
NoHugePagesInRegion(MemToShadow(kMadviseRangeBeg),
kMadviseRangeSize * kShadowMultiplier);
diff --git a/lib/tsan/rtl/tsan_rtl.h b/lib/tsan/rtl/tsan_rtl.h
index a13e4b637..d37f2d495 100644
--- a/lib/tsan/rtl/tsan_rtl.h
+++ b/lib/tsan/rtl/tsan_rtl.h
@@ -54,7 +54,7 @@ namespace __tsan {
#ifndef SANITIZER_GO
struct MapUnmapCallback;
-#ifdef __mips64
+#if defined(__mips64) || defined(__aarch64__)
static const uptr kAllocatorSpace = 0;
static const uptr kAllocatorSize = SANITIZER_MMAP_RANGE_SIZE;
static const uptr kAllocatorRegionSizeLog = 20;
diff --git a/lib/tsan/tests/rtl/tsan_posix.cc b/lib/tsan/tests/rtl/tsan_posix.cc
index 0caedd720..71fb05c22 100644
--- a/lib/tsan/tests/rtl/tsan_posix.cc
+++ b/lib/tsan/tests/rtl/tsan_posix.cc
@@ -71,6 +71,7 @@ TEST(Posix, ThreadSpecificDtors) {
EXPECT_EQ(6, cnt);
}
+#ifndef __aarch64__
static __thread int local_var;
static void *local_thread(void *p) {
@@ -87,9 +88,14 @@ static void *local_thread(void *p) {
EXPECT_EQ(pthread_join(th[i], 0), 0);
return 0;
}
+#endif
TEST(Posix, ThreadLocalAccesses) {
+// The test is failing with high thread count for aarch64.
+// FIXME: track down the issue and re-enable the test.
+#ifndef __aarch64__
local_thread((void*)2);
+#endif
}
struct CondContext {
diff --git a/test/tsan/ignore_lib0.cc b/test/tsan/ignore_lib0.cc
index 63c9340e9..13d0fb92f 100644
--- a/test/tsan/ignore_lib0.cc
+++ b/test/tsan/ignore_lib0.cc
@@ -8,6 +8,9 @@
// Tests that interceptors coming from a library specified in called_from_lib
// suppression are ignored.
+// Some aarch64 kernels do not support non executable write pages
+// XFAIL: aarch64
+
#ifndef LIB
extern "C" void libfunc();
diff --git a/test/tsan/ignore_lib1.cc b/test/tsan/ignore_lib1.cc
index ef1f97379..cd4c023dc 100644
--- a/test/tsan/ignore_lib1.cc
+++ b/test/tsan/ignore_lib1.cc
@@ -8,6 +8,8 @@
// Tests that interceptors coming from a dynamically loaded library specified
// in called_from_lib suppression are ignored.
+// XFAIL: aarch64
+
#ifndef LIB
#include <dlfcn.h>
diff --git a/test/tsan/ignore_lib3.cc b/test/tsan/ignore_lib3.cc
index 96bf313f4..69e0f893d 100644
--- a/test/tsan/ignore_lib3.cc
+++ b/test/tsan/ignore_lib3.cc
@@ -5,6 +5,9 @@
// Tests that unloading of a library matched against called_from_lib suppression
// causes program crash (this is not supported).
+// Some aarch64 kernels do not support non executable write pages
+// XFAIL: aarch64
+
#ifndef LIB
#include <dlfcn.h>
diff --git a/test/tsan/longjmp.cc b/test/tsan/longjmp.cc
index d64206739..9ac6b99c2 100644
--- a/test/tsan/longjmp.cc
+++ b/test/tsan/longjmp.cc
@@ -1,7 +1,8 @@
// RUN: %clang_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
-// Longjmp assembly has not been implemented for mips64 yet
+// Longjmp assembly has not been implemented for mips64 or aarch64 yet
// XFAIL: mips64
+// XFAIL: aarch64
#include <stdio.h>
#include <stdlib.h>
diff --git a/test/tsan/longjmp2.cc b/test/tsan/longjmp2.cc
index eee423dc5..dfbd84b49 100644
--- a/test/tsan/longjmp2.cc
+++ b/test/tsan/longjmp2.cc
@@ -1,7 +1,8 @@
// RUN: %clang_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
-// Longjmp assembly has not been implemented for mips64 yet
+// Longjmp assembly has not been implemented for mips64 or aarch64 yet
// XFAIL: mips64
+// XFAIL: aarch64
#include <stdio.h>
#include <stdlib.h>
diff --git a/test/tsan/longjmp3.cc b/test/tsan/longjmp3.cc
index 79965c419..df426fac2 100644
--- a/test/tsan/longjmp3.cc
+++ b/test/tsan/longjmp3.cc
@@ -1,7 +1,8 @@
// RUN: %clang_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-// Longjmp assembly has not been implemented for mips64 yet
+// Longjmp assembly has not been implemented for mips64 or aarch64 yet
// XFAIL: mips64
+// XFAIL: aarch64
#include <pthread.h>
#include <stdio.h>
diff --git a/test/tsan/longjmp4.cc b/test/tsan/longjmp4.cc
index c85839973..9f5d6d1a8 100644
--- a/test/tsan/longjmp4.cc
+++ b/test/tsan/longjmp4.cc
@@ -1,7 +1,8 @@
// RUN: %clang_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s
-// Longjmp assembly has not been implemented for mips64 yet
+// Longjmp assembly has not been implemented for mips64 or aarch64 yet
// XFAIL: mips64
+// XFAIL: aarch64
#include <pthread.h>
#include <stdio.h>
diff --git a/test/tsan/map32bit.cc b/test/tsan/map32bit.cc
index d9a04655d..f23d7f76e 100644
--- a/test/tsan/map32bit.cc
+++ b/test/tsan/map32bit.cc
@@ -9,6 +9,7 @@
// MAP_32BIT flag for mmap is supported only for x86_64.
// XFAIL: mips64
+// XFAIL: aarch64
void *Thread(void *ptr) {
*(int*)ptr = 42;
diff --git a/test/tsan/mmap_large.cc b/test/tsan/mmap_large.cc
index 098530475..d31ea3603 100644
--- a/test/tsan/mmap_large.cc
+++ b/test/tsan/mmap_large.cc
@@ -14,7 +14,7 @@
int main() {
#ifdef __x86_64__
const size_t kLog2Size = 39;
-#elif defined(__mips64)
+#elif defined(__mips64) || defined(__aarch64__)
const size_t kLog2Size = 32;
#endif
const uintptr_t kLocation = 0x40ULL << kLog2Size;
diff --git a/test/tsan/signal_longjmp.cc b/test/tsan/signal_longjmp.cc
index 2525c8988..c02917f49 100644
--- a/test/tsan/signal_longjmp.cc
+++ b/test/tsan/signal_longjmp.cc
@@ -3,8 +3,9 @@
// Test case for longjumping out of signal handler:
// https://code.google.com/p/thread-sanitizer/issues/detail?id=75
-// Longjmp assembly has not been implemented for mips64 yet
+// Longjmp assembly has not been implemented for mips64 or aarch64 yet
// XFAIL: mips64
+// XFAIL: aarch64
#include <setjmp.h>
#include <signal.h>
diff --git a/test/tsan/test.h b/test/tsan/test.h
index 4e877f6d8..b441ba13d 100644
--- a/test/tsan/test.h
+++ b/test/tsan/test.h
@@ -40,7 +40,7 @@ void print_address(void *address) {
// to the format used in the diagnotic message.
#ifdef __x86_64__
fprintf(stderr, "0x%012lx", (unsigned long) address);
-#elif defined(__mips64)
+#elif defined(__mips64) || defined(__aarch64__)
fprintf(stderr, "0x%010lx", (unsigned long) address);
#endif
}