[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
This commit is contained in:
Kuba Mracek 2018-11-06 19:55:19 +00:00
parent cb397461e1
commit c4b8eb53c4
8 changed files with 38 additions and 2 deletions

View File

@ -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();

View File

@ -898,6 +898,7 @@ struct SignalContext {
bool IsMemoryAccess() const;
};
void InitializePlatformEarly();
void MaybeReexec();
template <typename Fn>

View File

@ -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) {}

View File

@ -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.
}

View File

@ -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;

View File

@ -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() {}

View File

@ -1008,6 +1008,10 @@ void CheckVMASize() {
// Do nothing.
}
void InitializePlatformEarly() {
// Do nothing.
}
void MaybeReexec() {
// No need to re-exec on Windows.
}

View File

@ -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();