From eccc939e34624cf8bf64dbbde22aad4554a23a04 Mon Sep 17 00:00:00 2001 From: Adhemerval Zanella Date: Thu, 20 Aug 2015 18:49:40 +0000 Subject: [PATCH] [asan] Enable ASan for AArch64/42-bit VMA This patch adds support for asan on aarch64-linux with 42-bit VMA (current default config for 64K pagesize kernels). The support is enabled by defining the SANITIZER_AARCH64_VMA to 42 at build time for both clang/llvm and compiler-rt. The default VMA is 39 bits. For 42-bit VMA aarch64 uses SANITIZIER_CAN_USER_ALLOCATOR64. llvm-svn: 245596 --- compiler-rt/lib/asan/asan_allocator.h | 5 +++++ compiler-rt/lib/asan/asan_mapping.h | 11 ++++++++++ .../lib/sanitizer_common/sanitizer_platform.h | 21 ++++++++++++++++--- 3 files changed, 34 insertions(+), 3 deletions(-) diff --git a/compiler-rt/lib/asan/asan_allocator.h b/compiler-rt/lib/asan/asan_allocator.h index 5ccd00c97bab..e3d53330cd2f 100644 --- a/compiler-rt/lib/asan/asan_allocator.h +++ b/compiler-rt/lib/asan/asan_allocator.h @@ -114,6 +114,11 @@ struct AsanMapUnmapCallback { # if defined(__powerpc64__) const uptr kAllocatorSpace = 0xa0000000000ULL; const uptr kAllocatorSize = 0x20000000000ULL; // 2T. +# elif defined(__aarch64__) +// AArch64/SANITIZIER_CAN_USER_ALLOCATOR64 is only for 42-bit VMA +// so no need to different values for different VMA. +const uptr kAllocatorSpace = 0x10000000000ULL; +const uptr kAllocatorSize = 0x10000000000ULL; // 3T. # else const uptr kAllocatorSpace = 0x600000000000ULL; const uptr kAllocatorSize = 0x40000000000ULL; // 4T. diff --git a/compiler-rt/lib/asan/asan_mapping.h b/compiler-rt/lib/asan/asan_mapping.h index 937c57b28db5..f76ca53c3607 100644 --- a/compiler-rt/lib/asan/asan_mapping.h +++ b/compiler-rt/lib/asan/asan_mapping.h @@ -80,6 +80,13 @@ // || `[0x1000000000, 0x11ffffffff]` || lowshadow || // || `[0x0000000000, 0x0fffffffff]` || lowmem || // +// Default Linux/AArch64 (42-bit VMA) mapping: +// || `[0x10000000000, 0x3ffffffffff]` || highmem || +// || `[0x0a000000000, 0x0ffffffffff]` || highshadow || +// || `[0x09000000000, 0x09fffffffff]` || shadowgap || +// || `[0x08000000000, 0x08fffffffff]` || lowshadow || +// || `[0x00000000000, 0x07fffffffff]` || lowmem || +// // Shadow mapping on FreeBSD/x86-64 with SHADOW_OFFSET == 0x400000000000: // || `[0x500000000000, 0x7fffffffffff]` || HighMem || // || `[0x4a0000000000, 0x4fffffffffff]` || HighShadow || @@ -111,7 +118,11 @@ static const u64 kIosShadowOffset32 = 1ULL << 30; // 0x40000000 static const u64 kIosShadowOffset64 = 0x130000000; static const u64 kIosSimShadowOffset32 = 1ULL << 30; static const u64 kIosSimShadowOffset64 = kDefaultShadowOffset64; +#if SANITIZER_AARCH64_VMA == 39 static const u64 kAArch64_ShadowOffset64 = 1ULL << 36; +#elif SANITIZER_AARCH64_VMA == 42 +static const u64 kAArch64_ShadowOffset64 = 1ULL << 39; +#endif static const u64 kMIPS32_ShadowOffset32 = 0x0aaa0000; static const u64 kMIPS64_ShadowOffset64 = 1ULL << 37; static const u64 kPPC64_ShadowOffset64 = 1ULL << 41; diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform.h index cda80eb1e99f..13e571307cc0 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform.h @@ -81,13 +81,24 @@ # define SANITIZER_X32 0 #endif +// VMA size definition for architecture that support multiple sizes. +// AArch64 has 3 VMA sizes: 39, 42 and 48. +#if SANITIZER_LINUX && defined(__aarch64__) +# if SANITIZER_AARCH64_VMA != 39 && SANITIZER_AARCH64_VMA != 42 +# error "invalid SANITIZER_AARCH64_VMA size" +# endif +# ifndef SANITIZER_AARCH64_VMA +# define SANITIZER_AARCH64_VMA 39 +# endif +#endif + // By default we allow to use SizeClassAllocator64 on 64-bit platform. // But in some cases (e.g. AArch64's 39-bit address space) SizeClassAllocator64 // does not work well and we need to fallback to SizeClassAllocator32. // For such platforms build this code with -DSANITIZER_CAN_USE_ALLOCATOR64=0 or // change the definition of SANITIZER_CAN_USE_ALLOCATOR64 here. #ifndef SANITIZER_CAN_USE_ALLOCATOR64 -# if defined(__aarch64__) || defined(__mips64) +# if defined(__mips64) || (defined(__aarch64__) && SANITIZER_AARCH64_VMA == 39) # define SANITIZER_CAN_USE_ALLOCATOR64 0 # else # define SANITIZER_CAN_USE_ALLOCATOR64 (SANITIZER_WORDSIZE == 64) @@ -99,7 +110,11 @@ // e.g. on AArch64 it is most likely (1ULL << 39). Larger values will still work // but will consume more memory for TwoLevelByteMap. #if defined(__aarch64__) -# define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 39) +# if SANITIZER_AARCH64_VMA == 39 +# define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 39) +# elif SANITIZER_AARCH64_VMA == 42 +# define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 42) +# endif #elif defined(__mips__) # define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 40) #else @@ -130,7 +145,7 @@ #define SANITIZER_USES_UID16_SYSCALLS 0 #endif -#if defined(__mips__) || defined(__aarch64__) +#if defined(__mips__) || (defined(__aarch64__) && SANITIZER_AARCH64_VMA == 39) # define SANITIZER_POINTER_FORMAT_LENGTH FIRST_32_SECOND_64(8, 10) #else # define SANITIZER_POINTER_FORMAT_LENGTH FIRST_32_SECOND_64(8, 12)