From c4b8eb53c4cdde288284122c1efddde03fcc73b3 Mon Sep 17 00:00:00 2001 From: Kuba Mracek Date: Tue, 6 Nov 2018 19:55:19 +0000 Subject: [PATCH] [sanitizer] Use "fast mmap" kernel flag for shadow memory on macOS 10.13.4+ This speeds up process startup and teardown and also reduces lock contention when running multiple ASanified/TSanified processes simultaneously. Should greatly improve lit testing time. Differential Revision: https://reviews.llvm.org/D48445 llvm-svn: 346262 --- compiler-rt/lib/asan/asan_rtl.cc | 2 ++ .../lib/sanitizer_common/sanitizer_common.h | 1 + .../lib/sanitizer_common/sanitizer_fuchsia.cc | 1 + .../lib/sanitizer_common/sanitizer_linux.cc | 4 ++++ .../lib/sanitizer_common/sanitizer_mac.cc | 23 ++++++++++++++++++- .../lib/sanitizer_common/sanitizer_rtems.cc | 1 + .../lib/sanitizer_common/sanitizer_win.cc | 4 ++++ compiler-rt/lib/tsan/rtl/tsan_rtl.cc | 4 +++- 8 files changed, 38 insertions(+), 2 deletions(-) diff --git a/compiler-rt/lib/asan/asan_rtl.cc b/compiler-rt/lib/asan/asan_rtl.cc index 4cff736f213a..0c6390352a5c 100644 --- a/compiler-rt/lib/asan/asan_rtl.cc +++ b/compiler-rt/lib/asan/asan_rtl.cc @@ -420,6 +420,8 @@ static void AsanInitInternal() { __asan_option_detect_stack_use_after_return = flags()->detect_stack_use_after_return; + __sanitizer::InitializePlatformEarly(); + // Re-exec ourselves if we need to set additional env or command line args. MaybeReexec(); diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common.h b/compiler-rt/lib/sanitizer_common/sanitizer_common.h index 08360a231141..a0615fa87362 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_common.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common.h @@ -898,6 +898,7 @@ struct SignalContext { bool IsMemoryAccess() const; }; +void InitializePlatformEarly(); void MaybeReexec(); template diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_fuchsia.cc b/compiler-rt/lib/sanitizer_common/sanitizer_fuchsia.cc index eea9b18ddefe..5122efd874b0 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_fuchsia.cc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_fuchsia.cc @@ -86,6 +86,7 @@ void GetThreadStackTopAndBottom(bool, uptr *stack_top, uptr *stack_bottom) { *stack_top = *stack_bottom + size; } +void InitializePlatformEarly() {} void MaybeReexec() {} void CheckASLR() {} void PlatformPrepareForSandboxing(__sanitizer_sandbox_arguments *args) {} diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cc b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cc index 7c3da0cb61cf..62851e5f757e 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cc @@ -1966,6 +1966,10 @@ static void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp) { void SignalContext::InitPcSpBp() { GetPcSpBp(context, &pc, &sp, &bp); } +void InitializePlatformEarly() { + // Do nothing. +} + void MaybeReexec() { // No need to re-exec on Linux. } diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_mac.cc b/compiler-rt/lib/sanitizer_common/sanitizer_mac.cc index 96e364ce24c8..95c47babe084 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_mac.cc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_mac.cc @@ -108,9 +108,20 @@ extern "C" int __munmap(void *, size_t) SANITIZER_WEAK_ATTRIBUTE; #define VM_MEMORY_SANITIZER 99 #endif +// XNU on Darwin provides a mmap flag that optimizes allocation/deallocation of +// giant memory regions (i.e. shadow memory regions). +#define kXnuFastMmapFd 0x4 +static size_t kXnuFastMmapThreshold = 2 << 30; // 2 GB +static bool use_xnu_fast_mmap = false; + uptr internal_mmap(void *addr, size_t length, int prot, int flags, int fd, u64 offset) { - if (fd == -1) fd = VM_MAKE_TAG(VM_MEMORY_SANITIZER); + if (fd == -1) { + fd = VM_MAKE_TAG(VM_MEMORY_SANITIZER); + if (length >= kXnuFastMmapThreshold) { + if (use_xnu_fast_mmap) fd |= kXnuFastMmapFd; + } + } if (&__mmap) return (uptr)__mmap(addr, length, prot, flags, fd, offset); return (uptr)mmap(addr, length, prot, flags, fd, offset); } @@ -685,6 +696,16 @@ static void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp) { void SignalContext::InitPcSpBp() { GetPcSpBp(context, &pc, &sp, &bp); } +void InitializePlatformEarly() { + // Only use xnu_fast_mmap when on x86_64 and the OS supports it. + use_xnu_fast_mmap = +#if defined(__x86_64__) + GetMacosVersion() >= MACOS_VERSION_HIGH_SIERRA_DOT_RELEASE_4; +#else + false; +#endif +} + #if !SANITIZER_GO static const char kDyldInsertLibraries[] = "DYLD_INSERT_LIBRARIES"; LowLevelAllocator allocator_for_env; diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_rtems.cc b/compiler-rt/lib/sanitizer_common/sanitizer_rtems.cc index 0141c325f7e9..27078ef90bd2 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_rtems.cc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_rtems.cc @@ -95,6 +95,7 @@ void GetThreadStackAndTls(bool main, uptr *stk_addr, uptr *stk_size, *tls_addr = *tls_size = 0; } +void InitializePlatformEarly() {} void MaybeReexec() {} void CheckASLR() {} void DisableCoreDumperIfNecessary() {} diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_win.cc b/compiler-rt/lib/sanitizer_common/sanitizer_win.cc index ff5fd43559c7..7623d42a8d23 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_win.cc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_win.cc @@ -1008,6 +1008,10 @@ void CheckVMASize() { // Do nothing. } +void InitializePlatformEarly() { + // Do nothing. +} + void MaybeReexec() { // No need to re-exec on Windows. } diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl.cc b/compiler-rt/lib/tsan/rtl/tsan_rtl.cc index 5841222927b3..f038e9682d89 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_rtl.cc +++ b/compiler-rt/lib/tsan/rtl/tsan_rtl.cc @@ -359,7 +359,9 @@ void Initialize(ThreadState *thr) { CheckASLR(); InitializeFlags(&ctx->flags, options); AvoidCVE_2016_2143(); - InitializePlatformEarly(); + __sanitizer::InitializePlatformEarly(); + __tsan::InitializePlatformEarly(); + #if !SANITIZER_GO // Re-exec ourselves if we need to set additional env or command line args. MaybeReexec();