summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorAdhemerval Zanella <adhemerval.zanella@linaro.org>2015-09-16 15:12:25 +0000
committerAdhemerval Zanella <adhemerval.zanella@linaro.org>2015-09-16 15:12:25 +0000
commitd0966a39a94f91835ab3a311d5499c47a647a2b9 (patch)
tree993d7f5d08ff5b112fa7e35c814a747391635924 /lib
parent92c35fedf322f1b799004aa13b7835f14193d790 (diff)
[MSan] Enable MSAN for aarch64
This patch enabled msan for aarch64 with 39-bit VMA and 42-bit VMA. As defined by lib/msan/msan.h the memory layout used is for 39-bit is: 00 0000 0000 - 40 0000 0000: invalid 40 0000 0000 - 43 0000 0000: shadow 43 0000 0000 - 46 0000 0000: origin 46 0000 0000 - 55 0000 0000: invalid 55 0000 0000 - 56 0000 0000: app (low) 56 0000 0000 - 70 0000 0000: invalid 70 0000 0000 - 80 0000 0000: app (high) And for 42-bit VMA: 000 0000 0000 - 100 0000 0000: invalid 100 0000 0000 - 11b 0000 0000: shadow 11b 0000 0000 - 120 0000 0000: invalid 120 0000 0000 - 13b 0000 0000: origin 13b 0000 0000 - 2aa 0000 0000: invalid 2aa 0000 0000 - 2ab 0000 0000: app (low) 2ab 0000 0000 - 3f0 0000 0000: invalid 3f0 0000 0000 - 400 0000 0000: app (high) Most of tests are passing with exception of: * Linux/mallinfo.cc * chained_origin_limits.cc * dlerror.cc * param_tls_limit.cc * signal_stress_test.cc * nonnull-arg.cpp The 'Linux/mallinfo.cc' is due the fact AArch64 returns the sret in 'x8' instead of default first argument 'x1'. So a function prototype that aims to mimic (by using first argument as the return of function) won't work. For GCC one can make a register alias (register var asm ("r8")), but for clang it detects is an unused variable and generate wrong code. The 'chained_origin_limits' is probably due a wrong code generation, since it fails only when origin memory is used (-fsanitize-memory-track-origins=2) and only in the returned code (return buf[50]). The 'signal_streess_test' and 'nonnull-arg' are due currently missing variadic argument handling in memory sanitizer code instrumentation on LLVM side. Both 'dlerror' and 'param_tls_test' are unknown failures that require further investigation. All the failures are XFAIL for aarch64 for now. git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@247809 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/msan/msan.h41
-rw-r--r--lib/msan/msan_allocator.cc10
-rw-r--r--lib/msan/msan_interceptors.cc10
-rw-r--r--lib/sanitizer_common/sanitizer_common_syscalls.inc4
-rw-r--r--lib/sanitizer_common/sanitizer_platform_interceptors.h2
-rw-r--r--lib/sanitizer_common/sanitizer_platform_limits_posix.cc26
-rw-r--r--lib/sanitizer_common/sanitizer_platform_limits_posix.h2
-rw-r--r--lib/sanitizer_common/sanitizer_stacktrace.h3
8 files changed, 84 insertions, 14 deletions
diff --git a/lib/msan/msan.h b/lib/msan/msan.h
index e4344e564..703069e98 100644
--- a/lib/msan/msan.h
+++ b/lib/msan/msan.h
@@ -52,6 +52,47 @@ const MappingDesc kMemoryLayout[] = {
#define MEM_TO_SHADOW(mem) (((uptr)(mem)) & ~0x4000000000ULL)
#define SHADOW_TO_ORIGIN(shadow) (((uptr)(shadow)) + 0x002000000000)
+#elif SANITIZER_LINUX && defined(__aarch64__)
+
+# if SANITIZER_AARCH64_VMA == 39
+const MappingDesc kMemoryLayout[] = {
+ {0x0000000000ULL, 0x4000000000ULL, MappingDesc::INVALID, "invalid"},
+ {0x4000000000ULL, 0x4300000000ULL, MappingDesc::SHADOW, "shadow"},
+ {0x4300000000ULL, 0x4600000000ULL, MappingDesc::ORIGIN, "origin"},
+ {0x4600000000ULL, 0x5500000000ULL, MappingDesc::INVALID, "invalid"},
+ {0x5500000000ULL, 0x5600000000ULL, MappingDesc::APP, "app"},
+ {0x5600000000ULL, 0x7000000000ULL, MappingDesc::INVALID, "invalid"},
+ {0x7000000000ULL, 0x8000000000ULL, MappingDesc::APP, "app"}
+};
+// Maps low and high app ranges to contiguous space with zero base:
+// Low: 55 0000 0000 - 55 ffff ffff -> 1 0000 0000 - 1 ffff ffff
+// High: 70 0000 0000 - 7f ffff ffff -> 0 0000 0000 - f ffff ffff
+# define LINEARIZE_MEM(mem) \
+ (((uptr)(mem) & ~0x7C00000000ULL) ^ 0x100000000ULL)
+# define MEM_TO_SHADOW(mem) (LINEARIZE_MEM((mem)) + 0x4000000000ULL)
+# define SHADOW_TO_ORIGIN(shadow) (((uptr)(shadow)) + 0x300000000ULL)
+
+# elif SANITIZER_AARCH64_VMA == 42
+const MappingDesc kMemoryLayout[] = {
+ {0x00000000000ULL, 0x10000000000ULL, MappingDesc::INVALID, "invalid"},
+ {0x10000000000ULL, 0x11b00000000ULL, MappingDesc::SHADOW, "shadow"},
+ {0x11b00000000ULL, 0x12000000000ULL, MappingDesc::INVALID, "invalid"},
+ {0x12000000000ULL, 0x13b00000000ULL, MappingDesc::ORIGIN, "origin"},
+ {0x13b00000000ULL, 0x2aa00000000ULL, MappingDesc::INVALID, "invalid"},
+ {0x2aa00000000ULL, 0x2ab00000000ULL, MappingDesc::APP, "app"},
+ {0x2ab00000000ULL, 0x3f000000000ULL, MappingDesc::INVALID, "invalid"},
+ {0x3f000000000ULL, 0x40000000000ULL, MappingDesc::APP, "app"},
+};
+// Maps low and high app ranges to contigous space with zero base:
+// 2 aa00 0000 00 - 2 ab00 0000 00: -> 1a00 0000 00 - 1aff ffff ff
+// 3 f000 0000 00 - 4 0000 0000 00: -> 0000 0000 00 - 0fff ffff ff
+# define LINEARIZE_MEM(mem) \
+ (((uptr)(mem) & ~0x3E000000000ULL) ^ 0x1000000000ULL)
+# define MEM_TO_SHADOW(mem) (LINEARIZE_MEM((mem)) + 0x10000000000ULL)
+# define SHADOW_TO_ORIGIN(shadow) (((uptr)(shadow)) + 0x2000000000ULL)
+
+# endif // SANITIZER_AARCH64_VMA
+
#elif SANITIZER_LINUX && defined(__powerpc64__)
const MappingDesc kMemoryLayout[] = {
diff --git a/lib/msan/msan_allocator.cc b/lib/msan/msan_allocator.cc
index 6df356642..b713c66b9 100644
--- a/lib/msan/msan_allocator.cc
+++ b/lib/msan/msan_allocator.cc
@@ -67,6 +67,16 @@ struct MsanMapUnmapCallback {
typedef SizeClassAllocator64<kAllocatorSpace, kAllocatorSize, kMetadataSize,
DefaultSizeClassMap,
MsanMapUnmapCallback> PrimaryAllocator;
+#elif defined(__aarch64__)
+ static const uptr kMaxAllowedMallocSize = 2UL << 30; // 2G
+ static const uptr kRegionSizeLog = 20;
+ static const uptr kNumRegions = SANITIZER_MMAP_RANGE_SIZE >> kRegionSizeLog;
+ typedef TwoLevelByteMap<(kNumRegions >> 12), 1 << 12> ByteMap;
+ typedef CompactSizeClassMap SizeClassMap;
+
+ typedef SizeClassAllocator32<0, SANITIZER_MMAP_RANGE_SIZE, sizeof(Metadata),
+ SizeClassMap, kRegionSizeLog, ByteMap,
+ MsanMapUnmapCallback> PrimaryAllocator;
#endif
typedef SizeClassAllocatorLocalCache<PrimaryAllocator> AllocatorCache;
typedef LargeMmapAllocator<MsanMapUnmapCallback> SecondaryAllocator;
diff --git a/lib/msan/msan_interceptors.cc b/lib/msan/msan_interceptors.cc
index 32aef3038..c42885815 100644
--- a/lib/msan/msan_interceptors.cc
+++ b/lib/msan/msan_interceptors.cc
@@ -245,9 +245,15 @@ INTERCEPTOR(uptr, malloc_usable_size, void *ptr) {
#if !SANITIZER_FREEBSD
// This function actually returns a struct by value, but we can't unpoison a
-// temporary! The following is equivalent on all supported platforms, and we
-// have a test to confirm that.
+// temporary! The following is equivalent on all supported platforms but
+// aarch64 (which uses a different register for sret value). We have a test
+// to confirm that.
INTERCEPTOR(void, mallinfo, __sanitizer_mallinfo *sret) {
+#ifdef __aarch64__
+ uptr r8;
+ asm volatile("mov %0,x8" : "=r" (r8));
+ sret = reinterpret_cast<__sanitizer_mallinfo*>(r8);
+#endif
REAL(memset)(sret, 0, sizeof(*sret));
__msan_unpoison(sret, sizeof(*sret));
}
diff --git a/lib/sanitizer_common/sanitizer_common_syscalls.inc b/lib/sanitizer_common/sanitizer_common_syscalls.inc
index 5d4840f96..008e57745 100644
--- a/lib/sanitizer_common/sanitizer_common_syscalls.inc
+++ b/lib/sanitizer_common/sanitizer_common_syscalls.inc
@@ -2301,7 +2301,7 @@ POST_SYSCALL(ni_syscall)(long res) {}
PRE_SYSCALL(ptrace)(long request, long pid, long addr, long data) {
#if !SANITIZER_ANDROID && \
(defined(__i386) || defined(__x86_64) || defined(__mips64) || \
- defined(__powerpc64__))
+ defined(__powerpc64__) || defined(__aarch64__))
if (data) {
if (request == ptrace_setregs) {
PRE_READ((void *)data, struct_user_regs_struct_sz);
@@ -2322,7 +2322,7 @@ PRE_SYSCALL(ptrace)(long request, long pid, long addr, long data) {
POST_SYSCALL(ptrace)(long res, long request, long pid, long addr, long data) {
#if !SANITIZER_ANDROID && \
(defined(__i386) || defined(__x86_64) || defined(__mips64) || \
- defined(__powerpc64__))
+ defined(__powerpc64__) || defined(__aarch64__))
if (res >= 0 && data) {
// Note that this is different from the interceptor in
// sanitizer_common_interceptors.inc.
diff --git a/lib/sanitizer_common/sanitizer_platform_interceptors.h b/lib/sanitizer_common/sanitizer_platform_interceptors.h
index d46b3938f..af6969bef 100644
--- a/lib/sanitizer_common/sanitizer_platform_interceptors.h
+++ b/lib/sanitizer_common/sanitizer_platform_interceptors.h
@@ -133,7 +133,7 @@
#define SANITIZER_INTERCEPT_READDIR64 SI_LINUX_NOT_ANDROID
#define SANITIZER_INTERCEPT_PTRACE SI_LINUX_NOT_ANDROID && \
(defined(__i386) || defined(__x86_64) || defined(__mips64) || \
- defined(__powerpc64__))
+ defined(__powerpc64__) || defined(__aarch64__))
#define SANITIZER_INTERCEPT_SETLOCALE SI_NOT_WINDOWS
#define SANITIZER_INTERCEPT_GETCWD SI_NOT_WINDOWS
#define SANITIZER_INTERCEPT_GET_CURRENT_DIR_NAME SI_LINUX_NOT_ANDROID
diff --git a/lib/sanitizer_common/sanitizer_platform_limits_posix.cc b/lib/sanitizer_common/sanitizer_platform_limits_posix.cc
index 7c5753d85..d3f695a1b 100644
--- a/lib/sanitizer_common/sanitizer_platform_limits_posix.cc
+++ b/lib/sanitizer_common/sanitizer_platform_limits_posix.cc
@@ -119,7 +119,7 @@
#if SANITIZER_LINUX || SANITIZER_FREEBSD
# include <utime.h>
# include <sys/ptrace.h>
-# if defined(__mips64)
+# if defined(__mips64) || defined(__aarch64__)
# include <asm/ptrace.h>
# endif
#endif
@@ -303,28 +303,42 @@ unsigned struct_ElfW_Phdr_sz = sizeof(Elf_Phdr);
#if SANITIZER_LINUX && !SANITIZER_ANDROID && \
(defined(__i386) || defined(__x86_64) || defined(__mips64) || \
- defined(__powerpc64__))
+ defined(__powerpc64__) || defined(__aarch64__))
#if defined(__mips64) || defined(__powerpc64__)
unsigned struct_user_regs_struct_sz = sizeof(struct pt_regs);
unsigned struct_user_fpregs_struct_sz = sizeof(elf_fpregset_t);
+#elif defined(__aarch64__)
+ unsigned struct_user_regs_struct_sz = sizeof(struct user_pt_regs);
+ unsigned struct_user_fpregs_struct_sz = sizeof(struct user_fpsimd_state);
#else
unsigned struct_user_regs_struct_sz = sizeof(struct user_regs_struct);
unsigned struct_user_fpregs_struct_sz = sizeof(struct user_fpregs_struct);
-#endif // __mips64 || __powerpc64__
-#if defined(__x86_64) || defined(__mips64) || defined(__powerpc64__)
+#endif // __mips64 || __powerpc64__ || __aarch64__
+#if defined(__x86_64) || defined(__mips64) || defined(__powerpc64__) || \
+ defined(__aarch64__)
unsigned struct_user_fpxregs_struct_sz = 0;
#else
unsigned struct_user_fpxregs_struct_sz = sizeof(struct user_fpxregs_struct);
-#endif // __x86_64 || __mips64 || __powerpc64__
+#endif // __x86_64 || __mips64 || __powerpc64__ || __aarch64__
int ptrace_peektext = PTRACE_PEEKTEXT;
int ptrace_peekdata = PTRACE_PEEKDATA;
int ptrace_peekuser = PTRACE_PEEKUSER;
+#if defined(PT_GETREGS) && defined(PT_SETREGS)
int ptrace_getregs = PTRACE_GETREGS;
int ptrace_setregs = PTRACE_SETREGS;
+#else
+ int ptrace_getregs = -1;
+ int ptrace_setregs = -1;
+#endif
+#if defined(PT_GETFPREGS) && defined(PT_SETFPREGS)
int ptrace_getfpregs = PTRACE_GETFPREGS;
int ptrace_setfpregs = PTRACE_SETFPREGS;
-#if defined(PTRACE_GETFPXREGS) && defined(PTRACE_SETFPXREGS)
+#else
+ int ptrace_getfpregs = -1;
+ int ptrace_setfpregs = -1;
+#endif
+#if defined(PT_GETFPXREGS) && defined(PT_SETFPXREGS)
int ptrace_getfpxregs = PTRACE_GETFPXREGS;
int ptrace_setfpxregs = PTRACE_SETFPXREGS;
#else
diff --git a/lib/sanitizer_common/sanitizer_platform_limits_posix.h b/lib/sanitizer_common/sanitizer_platform_limits_posix.h
index babac1e67..a2d01e2f6 100644
--- a/lib/sanitizer_common/sanitizer_platform_limits_posix.h
+++ b/lib/sanitizer_common/sanitizer_platform_limits_posix.h
@@ -724,7 +724,7 @@ namespace __sanitizer {
#if SANITIZER_LINUX && !SANITIZER_ANDROID && \
(defined(__i386) || defined(__x86_64) || defined(__mips64) || \
- defined(__powerpc64__))
+ defined(__powerpc64__) || defined(__aarch64__))
extern unsigned struct_user_regs_struct_sz;
extern unsigned struct_user_fpregs_struct_sz;
extern unsigned struct_user_fpxregs_struct_sz;
diff --git a/lib/sanitizer_common/sanitizer_stacktrace.h b/lib/sanitizer_common/sanitizer_stacktrace.h
index c74a6df85..bf5aa0e7b 100644
--- a/lib/sanitizer_common/sanitizer_stacktrace.h
+++ b/lib/sanitizer_common/sanitizer_stacktrace.h
@@ -19,8 +19,7 @@ namespace __sanitizer {
static const u32 kStackTraceMax = 256;
-#if SANITIZER_LINUX && (defined(__aarch64__) || defined(__sparc__) || \
- defined(__mips__))
+#if SANITIZER_LINUX && (defined(__sparc__) || defined(__mips__))
# define SANITIZER_CAN_FAST_UNWIND 0
#elif SANITIZER_WINDOWS
# define SANITIZER_CAN_FAST_UNWIND 0