Index: lib/asan/asan_rtl.cc =================================================================== --- lib/asan/asan_rtl.cc +++ lib/asan/asan_rtl.cc @@ -420,6 +420,8 @@ __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(); Index: lib/sanitizer_common/sanitizer_common.h =================================================================== --- lib/sanitizer_common/sanitizer_common.h +++ lib/sanitizer_common/sanitizer_common.h @@ -897,6 +897,7 @@ bool IsMemoryAccess() const; }; +void InitializePlatformEarly(); void MaybeReexec(); template Index: lib/sanitizer_common/sanitizer_fuchsia.cc =================================================================== --- lib/sanitizer_common/sanitizer_fuchsia.cc +++ lib/sanitizer_common/sanitizer_fuchsia.cc @@ -86,6 +86,7 @@ *stack_top = *stack_bottom + size; } +void InitializePlatformEarly() {} void MaybeReexec() {} void CheckASLR() {} void PlatformPrepareForSandboxing(__sanitizer_sandbox_arguments *args) {} Index: lib/sanitizer_common/sanitizer_linux.cc =================================================================== --- lib/sanitizer_common/sanitizer_linux.cc +++ lib/sanitizer_common/sanitizer_linux.cc @@ -1987,6 +1987,10 @@ void SignalContext::InitPcSpBp() { GetPcSpBp(context, &pc, &sp, &bp); } +void InitializePlatformEarly() { + // Do nothing. +} + void MaybeReexec() { // No need to re-exec on Linux. } Index: lib/sanitizer_common/sanitizer_mac.cc =================================================================== --- lib/sanitizer_common/sanitizer_mac.cc +++ lib/sanitizer_common/sanitizer_mac.cc @@ -108,9 +108,20 @@ #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 @@ 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; Index: lib/sanitizer_common/sanitizer_rtems.cc =================================================================== --- lib/sanitizer_common/sanitizer_rtems.cc +++ lib/sanitizer_common/sanitizer_rtems.cc @@ -95,6 +95,7 @@ *tls_addr = *tls_size = 0; } +void InitializePlatformEarly() {} void MaybeReexec() {} void CheckASLR() {} void DisableCoreDumperIfNecessary() {} Index: lib/sanitizer_common/sanitizer_win.cc =================================================================== --- lib/sanitizer_common/sanitizer_win.cc +++ lib/sanitizer_common/sanitizer_win.cc @@ -1008,6 +1008,10 @@ // Do nothing. } +void InitializePlatformEarly() { + // Do nothing. +} + void MaybeReexec() { // No need to re-exec on Windows. } Index: lib/tsan/rtl/tsan_rtl.cc =================================================================== --- lib/tsan/rtl/tsan_rtl.cc +++ lib/tsan/rtl/tsan_rtl.cc @@ -359,7 +359,9 @@ 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();