diff options
author | Adhemerval Zanella <adhemerval.zanella@linaro.org> | 2015-09-16 15:12:25 +0000 |
---|---|---|
committer | Adhemerval Zanella <adhemerval.zanella@linaro.org> | 2015-09-16 15:12:25 +0000 |
commit | d0966a39a94f91835ab3a311d5499c47a647a2b9 (patch) | |
tree | 993d7f5d08ff5b112fa7e35c814a747391635924 /lib | |
parent | 92c35fedf322f1b799004aa13b7835f14193d790 (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.h | 41 | ||||
-rw-r--r-- | lib/msan/msan_allocator.cc | 10 | ||||
-rw-r--r-- | lib/msan/msan_interceptors.cc | 10 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_common_syscalls.inc | 4 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_platform_interceptors.h | 2 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_platform_limits_posix.cc | 26 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_platform_limits_posix.h | 2 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_stacktrace.h | 3 |
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 |