From 0bd785584ef24b84dad0bc44d2034616c43ce967 Mon Sep 17 00:00:00 2001 From: Kamil Rytarowski Date: Fri, 3 Nov 2017 20:39:51 +0000 Subject: Disable detection of on_exit()/TSan on NetBSD Summary: NetBSD does not ship with on_exit() function. Introduce TSAN_MAYBE_INTERCEPT_ON_EXIT. It looks like this addition fixes build for Darwin. Sponsored by Reviewers: vitalybuka, joerg, eugenis, dvyukov, kcc Reviewed By: vitalybuka Subscribers: llvm-commits, kubamracek, #sanitizers Tags: #sanitizers Differential Revision: https://reviews.llvm.org/D39617 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@317361 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/tsan/rtl/tsan_interceptors.cc | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/tsan/rtl/tsan_interceptors.cc b/lib/tsan/rtl/tsan_interceptors.cc index 79e243aef..9fbfef52c 100644 --- a/lib/tsan/rtl/tsan_interceptors.cc +++ b/lib/tsan/rtl/tsan_interceptors.cc @@ -435,7 +435,7 @@ static int setup_at_exit_wrapper(ThreadState *thr, uptr pc, void(*f)(), return res; } -#if !SANITIZER_MAC +#if !SANITIZER_MAC && !SANITIZER_NETBSD static void on_exit_wrapper(int status, void *arg) { ThreadState *thr = cur_thread(); uptr pc = 0; @@ -460,6 +460,9 @@ TSAN_INTERCEPTOR(int, on_exit, void(*f)(int, void*), void *arg) { ThreadIgnoreEnd(thr, pc); return res; } +#define TSAN_MAYBE_INTERCEPT_ON_EXIT TSAN_INTERCEPT(on_exit) +#else +#define TSAN_MAYBE_INTERCEPT_ON_EXIT #endif // Cleanup old bufs. @@ -2605,7 +2608,7 @@ void InitializeInterceptors() { #if !SANITIZER_ANDROID TSAN_INTERCEPT(dl_iterate_phdr); #endif - TSAN_INTERCEPT(on_exit); + TSAN_MAYBE_INTERCEPT_ON_EXIT; TSAN_INTERCEPT(__cxa_atexit); TSAN_INTERCEPT(_exit); -- cgit v1.2.1 From aad2b2b91309ddb2f05cb2c5e3ea3a24ac3684b9 Mon Sep 17 00:00:00 2001 From: Kamil Rytarowski Date: Fri, 3 Nov 2017 20:48:19 +0000 Subject: Correct detection of a thread termination Summary: Stop using the Linux solution with pthread_key_create(3). This approach does not work on NetBSD, because calling the thread destructor is not the latest operation on a POSIX thread entity. NetBSD's libpthread still calls at least pthread_mutex_lock and pthread_mutex_unlock. Detect _lwp_exit(2) call as it is really the latest operation called from a detaching POSIX thread. This resolves one set of crashes observed in the Thread Sanitizer execution. Sponsored by Reviewers: joerg, kcc, vitalybuka, dvyukov, eugenis Reviewed By: vitalybuka Subscribers: llvm-commits, kubamracek, #sanitizers Tags: #sanitizers Differential Revision: https://reviews.llvm.org/D39618 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@317363 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/tsan/rtl/tsan_interceptors.cc | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/lib/tsan/rtl/tsan_interceptors.cc b/lib/tsan/rtl/tsan_interceptors.cc index 9fbfef52c..db92f7528 100644 --- a/lib/tsan/rtl/tsan_interceptors.cc +++ b/lib/tsan/rtl/tsan_interceptors.cc @@ -265,7 +265,7 @@ static ThreadSignalContext *SigCtx(ThreadState *thr) { return ctx; } -#if !SANITIZER_MAC +#if !SANITIZER_MAC && !SANITIZER_NETBSD static unsigned g_thread_finalize_key; #endif @@ -869,7 +869,7 @@ void DestroyThreadState() { } } // namespace __tsan -#if !SANITIZER_MAC +#if !SANITIZER_MAC && !SANITIZER_NETBSD static void thread_finalize(void *v) { uptr iter = (uptr)v; if (iter > 1) { @@ -899,7 +899,7 @@ extern "C" void *__tsan_thread_start_func(void *arg) { ThreadState *thr = cur_thread(); // Thread-local state is not initialized yet. ScopedIgnoreInterceptors ignore; -#if !SANITIZER_MAC +#if !SANITIZER_MAC && !SANITIZER_NETBSD ThreadIgnoreBegin(thr, 0); if (pthread_setspecific(g_thread_finalize_key, (void *)GetPthreadDestructorIterations())) { @@ -2448,6 +2448,17 @@ TSAN_INTERCEPTOR(void *, __tls_get_addr, void *arg) { } #endif +#if SANITIZER_NETBSD +TSAN_INTERCEPTOR(void, _lwp_exit) { + SCOPED_TSAN_INTERCEPTOR(_lwp_exit); + REAL(_lwp_exit)(); + DestroyThreadState(); +} +#define TSAN_MAYBE_INTERCEPT__LWP_EXIT TSAN_INTERCEPT(_lwp_exit) +#else +#define TSAN_MAYBE_INTERCEPT__LWP_EXIT +#endif + namespace __tsan { static void finalize(void *arg) { @@ -2616,6 +2627,8 @@ void InitializeInterceptors() { TSAN_INTERCEPT(__tls_get_addr); #endif + TSAN_MAYBE_INTERCEPT__LWP_EXIT; + #if !SANITIZER_MAC && !SANITIZER_ANDROID // Need to setup it, because interceptors check that the function is resolved. // But atexit is emitted directly into the module, so can't be resolved. @@ -2627,7 +2640,7 @@ void InitializeInterceptors() { Die(); } -#if !SANITIZER_MAC +#if !SANITIZER_MAC && !SANITIZER_NETBSD if (pthread_key_create(&g_thread_finalize_key, &thread_finalize)) { Printf("ThreadSanitizer: failed to create thread key\n"); Die(); -- cgit v1.2.1 From ef40253e3d57a0398fa52dc371c11f383192235f Mon Sep 17 00:00:00 2001 From: Kamil Rytarowski Date: Fri, 3 Nov 2017 21:08:52 +0000 Subject: Late fixup in _lwp_exit on TSan/NetBSD Call DestroyThreadState() before REAL(_lwp_exit)(); This variation is less racy. Sponsored by git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@317369 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/tsan/rtl/tsan_interceptors.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/tsan/rtl/tsan_interceptors.cc b/lib/tsan/rtl/tsan_interceptors.cc index db92f7528..0b4e873a0 100644 --- a/lib/tsan/rtl/tsan_interceptors.cc +++ b/lib/tsan/rtl/tsan_interceptors.cc @@ -2451,8 +2451,8 @@ TSAN_INTERCEPTOR(void *, __tls_get_addr, void *arg) { #if SANITIZER_NETBSD TSAN_INTERCEPTOR(void, _lwp_exit) { SCOPED_TSAN_INTERCEPTOR(_lwp_exit); - REAL(_lwp_exit)(); DestroyThreadState(); + REAL(_lwp_exit)(); } #define TSAN_MAYBE_INTERCEPT__LWP_EXIT TSAN_INTERCEPT(_lwp_exit) #else -- cgit v1.2.1 From 5167a32ff3c3f9c0d99df348610b8e4aaf707be2 Mon Sep 17 00:00:00 2001 From: Alex Shlyapnikov Date: Fri, 3 Nov 2017 23:31:00 +0000 Subject: [Sanitizers] Call NanoTime() conditionally. Summary: Call NanoTime() in primary 64 bit allocator only when necessary, otherwise the unwarranted syscall causes problems in sandbox environments. ReleaseToOSIntervalMs() conditional allows them to turn the feature off with allocator_release_to_os_interval_ms=-1 flag. Reviewers: eugenis Subscribers: kubamracek, llvm-commits Differential Revision: https://reviews.llvm.org/D39624 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@317386 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/sanitizer_common/sanitizer_allocator_primary64.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/sanitizer_common/sanitizer_allocator_primary64.h b/lib/sanitizer_common/sanitizer_allocator_primary64.h index b22f3aba9..630ae358e 100644 --- a/lib/sanitizer_common/sanitizer_allocator_primary64.h +++ b/lib/sanitizer_common/sanitizer_allocator_primary64.h @@ -677,7 +677,10 @@ class SizeClassAllocator64 { // preventing just allocated memory from being released sooner than // necessary and also preventing extraneous ReleaseMemoryPagesToOS calls // for short lived processes. - region->rtoi.last_release_at_ns = NanoTime(); + // Do it only when the feature is turned on, to avoid a potentially + // extraneous syscall. + if (ReleaseToOSIntervalMs() >= 0) + region->rtoi.last_release_at_ns = NanoTime(); } // Do the mmap for the user memory. uptr map_size = kUserMapSize; -- cgit v1.2.1 From 190571e05dde20e57f19acedb4988c00e6ad0b1b Mon Sep 17 00:00:00 2001 From: Kostya Kortchinsky Date: Fri, 3 Nov 2017 23:48:25 +0000 Subject: [scudo] Rearrange #include order Summary: To be compliant with https://llvm.org/docs/CodingStandards.html#include-style, system headers have to come after local headers. Reviewers: alekseyshl Reviewed By: alekseyshl Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D39623 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@317390 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/scudo/scudo_utils.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/scudo/scudo_utils.h b/lib/scudo/scudo_utils.h index 13269195b..cb7300db9 100644 --- a/lib/scudo/scudo_utils.h +++ b/lib/scudo/scudo_utils.h @@ -14,10 +14,10 @@ #ifndef SCUDO_UTILS_H_ #define SCUDO_UTILS_H_ -#include - #include "sanitizer_common/sanitizer_common.h" +#include + namespace __scudo { template @@ -34,7 +34,7 @@ enum CPUFeature { CRC32CPUFeature = 0, MaxCPUFeature, }; -bool testCPUFeature(CPUFeature feature); +bool testCPUFeature(CPUFeature Feature); INLINE u64 rotl(const u64 X, int K) { return (X << K) | (X >> (64 - K)); -- cgit v1.2.1 From 5df11b04709468c4b4ce5c7ed0308eb127023a52 Mon Sep 17 00:00:00 2001 From: Mehdi Amini Date: Sat, 4 Nov 2017 00:07:20 +0000 Subject: Fix CMake definitions of tsan runtime to make it installed by "install-compiler-rt" Summary: The PARENT_TARGET was correctly set under APPLE but not under linux. Reviewers: kubamracek, samsonov Subscribers: dberris, mgorny, llvm-commits Differential Revision: https://reviews.llvm.org/D39621 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@317391 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/tsan/CMakeLists.txt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/tsan/CMakeLists.txt b/lib/tsan/CMakeLists.txt index 08974a467..f7a5d70a3 100644 --- a/lib/tsan/CMakeLists.txt +++ b/lib/tsan/CMakeLists.txt @@ -184,13 +184,15 @@ else() $ $ $ - CFLAGS ${TSAN_RTL_CFLAGS}) + CFLAGS ${TSAN_RTL_CFLAGS} + PARENT_TARGET tsan) add_compiler_rt_runtime(clang_rt.tsan_cxx STATIC ARCHS ${arch} SOURCES ${TSAN_CXX_SOURCES} $ - CFLAGS ${TSAN_RTL_CFLAGS}) + CFLAGS ${TSAN_RTL_CFLAGS} + PARENT_TARGET tsan) list(APPEND TSAN_RUNTIME_LIBRARIES clang_rt.tsan-${arch} clang_rt.tsan_cxx-${arch}) add_sanitizer_rt_symbols(clang_rt.tsan -- cgit v1.2.1 From 46ec7772ac5eaf1bda65cc3cca4f49d95e559a47 Mon Sep 17 00:00:00 2001 From: Alex Shlyapnikov Date: Mon, 6 Nov 2017 17:43:28 +0000 Subject: [Sanitizers] Check pthread_setcancel{state|type} interceptor arguments for != nullptr. Summary: According to man, pthread_setcancelstate's oldstate and pthread_setcanceltype's oldtype parameters can be nullptr. Check these parameters for != nullptr before attempting to access their shadow memory. Reviewers: dvyukov Subscribers: kubamracek, llvm-commits Differential Revision: https://reviews.llvm.org/D39626 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@317494 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/sanitizer_common/sanitizer_common_interceptors.inc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/sanitizer_common/sanitizer_common_interceptors.inc b/lib/sanitizer_common/sanitizer_common_interceptors.inc index 321126c10..16cc07020 100644 --- a/lib/sanitizer_common/sanitizer_common_interceptors.inc +++ b/lib/sanitizer_common/sanitizer_common_interceptors.inc @@ -5835,7 +5835,7 @@ INTERCEPTOR(int, pthread_setcancelstate, int state, int *oldstate) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, pthread_setcancelstate, state, oldstate); int res = REAL(pthread_setcancelstate)(state, oldstate); - if (res == 0) + if (res == 0 && oldstate != nullptr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldstate, sizeof(*oldstate)); return res; } @@ -5844,7 +5844,7 @@ INTERCEPTOR(int, pthread_setcanceltype, int type, int *oldtype) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, pthread_setcanceltype, type, oldtype); int res = REAL(pthread_setcanceltype)(type, oldtype); - if (res == 0) + if (res == 0 && oldtype != nullptr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldtype, sizeof(*oldtype)); return res; } -- cgit v1.2.1 From d234c1caf1fcd86a6c79a11a449d1fc58bb3646a Mon Sep 17 00:00:00 2001 From: Alex Shlyapnikov Date: Mon, 6 Nov 2017 21:27:06 +0000 Subject: [LSan] Detect dynamic loader by its base address. Summary: Relanding D38600, which was reverted due to various PPC bot failures. If it breaks something again, please provide some pointers to broken bots, not just revert it, otherwise it's very hard to reason what's wrong with this commit. Whenever possible (Linux + glibc 2.16+), detect dynamic loader module by its base address, not by the module name matching. The current name matching approach fails on some configurations. Reviewers: eugenis Subscribers: kubamracek, llvm-commits Differential Revision: https://reviews.llvm.org/D39275 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@317512 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/lsan/lsan_common.cc | 5 ++-- lib/lsan/lsan_common_linux.cc | 20 ++++++++++----- lib/sanitizer_common/sanitizer_getauxval.h | 40 ++++++++++++++++++++++++++++++ lib/sanitizer_common/sanitizer_linux.cc | 15 +---------- 4 files changed, 58 insertions(+), 22 deletions(-) create mode 100644 lib/sanitizer_common/sanitizer_getauxval.h diff --git a/lib/lsan/lsan_common.cc b/lib/lsan/lsan_common.cc index 622aae734..651bbe1f3 100644 --- a/lib/lsan/lsan_common.cc +++ b/lib/lsan/lsan_common.cc @@ -411,8 +411,9 @@ static void MarkInvalidPCCb(uptr chunk, void *arg) { } } -// On Linux, handles dynamically allocated TLS blocks by treating all chunks -// allocated from ld-linux.so as reachable. +// On Linux, treats all chunks allocated from ld-linux.so as reachable, which +// covers dynamically allocated TLS blocks, internal dynamic loader's loaded +// modules accounting etc. // Dynamic TLS blocks contain the TLS variables of dynamically loaded modules. // They are allocated with a __libc_memalign() call in allocate_and_init() // (elf/dl-tls.c). Glibc won't tell us the address ranges occupied by those diff --git a/lib/lsan/lsan_common_linux.cc b/lib/lsan/lsan_common_linux.cc index 5042c7b3a..cdd7f032a 100644 --- a/lib/lsan/lsan_common_linux.cc +++ b/lib/lsan/lsan_common_linux.cc @@ -20,6 +20,7 @@ #include "sanitizer_common/sanitizer_common.h" #include "sanitizer_common/sanitizer_flags.h" +#include "sanitizer_common/sanitizer_getauxval.h" #include "sanitizer_common/sanitizer_linux.h" #include "sanitizer_common/sanitizer_stackdepot.h" @@ -30,8 +31,12 @@ static const char kLinkerName[] = "ld"; static char linker_placeholder[sizeof(LoadedModule)] ALIGNED(64); static LoadedModule *linker = nullptr; -static bool IsLinker(const char* full_name) { - return LibraryNameIs(full_name, kLinkerName); +static bool IsLinker(const LoadedModule& module) { +#if SANITIZER_USE_GETAUXVAL + return module.base_address() == getauxval(AT_BASE); +#else + return LibraryNameIs(module.full_name(), kLinkerName); +#endif // SANITIZER_USE_GETAUXVAL } __attribute__((tls_model("initial-exec"))) @@ -49,22 +54,25 @@ void InitializePlatformSpecificModules() { ListOfModules modules; modules.init(); for (LoadedModule &module : modules) { - if (!IsLinker(module.full_name())) continue; + if (!IsLinker(module)) + continue; if (linker == nullptr) { linker = reinterpret_cast(linker_placeholder); *linker = module; module = LoadedModule(); } else { VReport(1, "LeakSanitizer: Multiple modules match \"%s\". " - "TLS will not be handled correctly.\n", kLinkerName); + "TLS and other allocations originating from linker might be " + "falsely reported as leaks.\n", kLinkerName); linker->clear(); linker = nullptr; return; } } if (linker == nullptr) { - VReport(1, "LeakSanitizer: Dynamic linker not found. " - "TLS will not be handled correctly.\n"); + VReport(1, "LeakSanitizer: Dynamic linker not found. TLS and other " + "allocations originating from linker might be falsely reported " + "as leaks.\n"); } } diff --git a/lib/sanitizer_common/sanitizer_getauxval.h b/lib/sanitizer_common/sanitizer_getauxval.h new file mode 100644 index 000000000..d0287f02c --- /dev/null +++ b/lib/sanitizer_common/sanitizer_getauxval.h @@ -0,0 +1,40 @@ +//===-- sanitizer_getauxval.h -----------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Common getauxval() guards and definitions. +// getauxval() is not defined until glbc version 2.16. +// +//===----------------------------------------------------------------------===// + +#ifndef SANITIZER_GETAUXVAL_H +#define SANITIZER_GETAUXVAL_H + +#include "sanitizer_platform.h" + +#if SANITIZER_LINUX + +#include + +#ifndef __GLIBC_PREREQ +#define __GLIBC_PREREQ(x, y) 0 +#endif + +#if __GLIBC_PREREQ(2, 16) +# define SANITIZER_USE_GETAUXVAL 1 +#else +# define SANITIZER_USE_GETAUXVAL 0 +#endif + +#if SANITIZER_USE_GETAUXVAL +#include +#endif + +#endif // SANITIZER_LINUX + +#endif // SANITIZER_GETAUXVAL_H diff --git a/lib/sanitizer_common/sanitizer_linux.cc b/lib/sanitizer_common/sanitizer_linux.cc index 6ea185817..5199aa601 100644 --- a/lib/sanitizer_common/sanitizer_linux.cc +++ b/lib/sanitizer_common/sanitizer_linux.cc @@ -18,6 +18,7 @@ #include "sanitizer_common.h" #include "sanitizer_flags.h" +#include "sanitizer_getauxval.h" #include "sanitizer_internal_defs.h" #include "sanitizer_libc.h" #include "sanitizer_linux.h" @@ -95,20 +96,6 @@ extern struct ps_strings *__ps_strings; #include #endif -#ifndef __GLIBC_PREREQ -#define __GLIBC_PREREQ(x, y) 0 -#endif - -#if SANITIZER_LINUX && __GLIBC_PREREQ(2, 16) -# define SANITIZER_USE_GETAUXVAL 1 -#else -# define SANITIZER_USE_GETAUXVAL 0 -#endif - -#if SANITIZER_USE_GETAUXVAL -#include -#endif - #if SANITIZER_LINUX // struct kernel_timeval { -- cgit v1.2.1 From 8a89783190c37d9e6a3ab639263d1e4ac0131d0e Mon Sep 17 00:00:00 2001 From: Kostya Kortchinsky Date: Tue, 7 Nov 2017 16:19:24 +0000 Subject: Update sanitizer_allocator to use new API. Summary: Update sanitizer_allocator to use new API. Second patch in a series. First patch https://reviews.llvm.org/D39072 Updates MmapNoAccess / MmapFixed call sites in the saniziter_allocator to use the new Init/Map APIs instead. Reviewers: alekseyshl, cryptoad, phosek, mcgrathr, dvyukov Reviewed By: alekseyshl, cryptoad Subscribers: dvyukov, mcgrathr, kubamracek Differential Revision: https://reviews.llvm.org/D38592 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@317586 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/sanitizer_common/sanitizer_allocator_primary64.h | 16 +++++++++------- lib/sanitizer_common/sanitizer_common.h | 3 ++- lib/sanitizer_common/sanitizer_fuchsia.cc | 8 ++++++-- lib/sanitizer_common/sanitizer_posix_libcdep.cc | 17 +++++++++++------ lib/sanitizer_common/sanitizer_win.cc | 10 +++++----- 5 files changed, 33 insertions(+), 21 deletions(-) diff --git a/lib/sanitizer_common/sanitizer_allocator_primary64.h b/lib/sanitizer_common/sanitizer_allocator_primary64.h index 630ae358e..4fb2f929c 100644 --- a/lib/sanitizer_common/sanitizer_allocator_primary64.h +++ b/lib/sanitizer_common/sanitizer_allocator_primary64.h @@ -72,11 +72,10 @@ class SizeClassAllocator64 { void Init(s32 release_to_os_interval_ms) { uptr TotalSpaceSize = kSpaceSize + AdditionalSize(); if (kUsingConstantSpaceBeg) { - CHECK_EQ(kSpaceBeg, reinterpret_cast( - MmapFixedNoAccess(kSpaceBeg, TotalSpaceSize))); + CHECK_EQ(kSpaceBeg, address_range.Init(TotalSpaceSize, AllocatorName(), + kSpaceBeg)); } else { - NonConstSpaceBeg = - reinterpret_cast(MmapNoAccess(TotalSpaceSize)); + NonConstSpaceBeg = address_range.Init(TotalSpaceSize, AllocatorName()); CHECK_NE(NonConstSpaceBeg, ~(uptr)0); } SetReleaseToOSIntervalMs(release_to_os_interval_ms); @@ -544,6 +543,9 @@ class SizeClassAllocator64 { private: friend class MemoryMapper; + ReservedAddressRange address_range; + static const char *AllocatorName() { return "sanitizer_allocator"; } + static const uptr kRegionSize = kSpaceSize / kNumClassesRounded; // FreeArray is the array of free-d chunks (stored as 4-byte offsets). // In the worst case it may reguire kRegionSize/SizeClassMap::kMinSize @@ -625,7 +627,7 @@ class SizeClassAllocator64 { } bool MapWithCallback(uptr beg, uptr size) { - uptr mapped = reinterpret_cast(MmapFixedOrDieOnFatalError(beg, size)); + uptr mapped = address_range.Map(beg, size); if (UNLIKELY(!mapped)) return false; CHECK_EQ(beg, mapped); @@ -634,13 +636,13 @@ class SizeClassAllocator64 { } void MapWithCallbackOrDie(uptr beg, uptr size) { - CHECK_EQ(beg, reinterpret_cast(MmapFixedOrDie(beg, size))); + CHECK_EQ(beg, address_range.MapOrDie(beg, size)); MapUnmapCallback().OnMap(beg, size); } void UnmapWithCallbackOrDie(uptr beg, uptr size) { MapUnmapCallback().OnUnmap(beg, size); - UnmapOrDie(reinterpret_cast(beg), size); + address_range.Unmap(beg, size); } bool EnsureFreeArraySpace(RegionInfo *region, uptr region_beg, diff --git a/lib/sanitizer_common/sanitizer_common.h b/lib/sanitizer_common/sanitizer_common.h index 14b92d9c4..18ebd62be 100644 --- a/lib/sanitizer_common/sanitizer_common.h +++ b/lib/sanitizer_common/sanitizer_common.h @@ -131,7 +131,8 @@ void RunFreeHooks(const void *ptr); class ReservedAddressRange { public: uptr Init(uptr size, const char *name = nullptr, uptr fixed_addr = 0); - uptr Map(uptr fixed_addr, uptr size, bool tolerate_enomem = false); + uptr Map(uptr fixed_addr, uptr size); + uptr MapOrDie(uptr fixed_addr, uptr size); void Unmap(uptr addr, uptr size); void *base() const { return base_; } uptr size() const { return size_; } diff --git a/lib/sanitizer_common/sanitizer_fuchsia.cc b/lib/sanitizer_common/sanitizer_fuchsia.cc index a2a532110..9511ccebf 100644 --- a/lib/sanitizer_common/sanitizer_fuchsia.cc +++ b/lib/sanitizer_common/sanitizer_fuchsia.cc @@ -246,8 +246,12 @@ uptr ReservedAddressRange::Init(uptr init_size, const char* name, // Uses fixed_addr for now. // Will use offset instead once we've implemented this function for real. -uptr ReservedAddressRange::Map(uptr fixed_addr, uptr map_size, - bool tolerate_enomem) { +uptr ReservedAddressRange::Map(uptr fixed_addr, uptr map_size) { + return reinterpret_cast(MmapFixedOrDieOnFatalError(fixed_addr, + map_size)); +} + +uptr ReservedAddressRange::MapOrDie(uptr fixed_addr, uptr map_size) { return reinterpret_cast(MmapFixedOrDie(fixed_addr, map_size)); } diff --git a/lib/sanitizer_common/sanitizer_posix_libcdep.cc b/lib/sanitizer_common/sanitizer_posix_libcdep.cc index 0ba3ad46b..40b5f8a4e 100644 --- a/lib/sanitizer_common/sanitizer_posix_libcdep.cc +++ b/lib/sanitizer_common/sanitizer_posix_libcdep.cc @@ -338,8 +338,13 @@ void *MmapFixedNoReserve(uptr fixed_addr, uptr size, const char *name) { } uptr ReservedAddressRange::Init(uptr size, const char *name, uptr fixed_addr) { + // We don't pass `name` along because, when you enable `decorate_proc_maps` + // AND actually use a named mapping AND are using a sanitizer intercepting + // `open` (e.g. TSAN, ESAN), then you'll get a failure during initialization. + // TODO(flowerhack): Fix the implementation of GetNamedMappingFd to solve + // this problem. if (fixed_addr) { - base_ = MmapFixedNoAccess(fixed_addr, size, name); + base_ = MmapFixedNoAccess(fixed_addr, size); } else { base_ = MmapNoAccess(size); } @@ -350,11 +355,11 @@ uptr ReservedAddressRange::Init(uptr size, const char *name, uptr fixed_addr) { // Uses fixed_addr for now. // Will use offset instead once we've implemented this function for real. -uptr ReservedAddressRange::Map(uptr fixed_addr, uptr size, - bool tolerate_enomem) { - if (tolerate_enomem) { - return reinterpret_cast(MmapFixedOrDieOnFatalError(fixed_addr, size)); - } +uptr ReservedAddressRange::Map(uptr fixed_addr, uptr size) { + return reinterpret_cast(MmapFixedOrDieOnFatalError(fixed_addr, size)); +} + +uptr ReservedAddressRange::MapOrDie(uptr fixed_addr, uptr size) { return reinterpret_cast(MmapFixedOrDie(fixed_addr, size)); } diff --git a/lib/sanitizer_common/sanitizer_win.cc b/lib/sanitizer_common/sanitizer_win.cc index b2fd8baca..718209fcf 100644 --- a/lib/sanitizer_common/sanitizer_win.cc +++ b/lib/sanitizer_common/sanitizer_win.cc @@ -237,11 +237,11 @@ void *MmapFixedOrDie(uptr fixed_addr, uptr size) { // Uses fixed_addr for now. // Will use offset instead once we've implemented this function for real. -uptr ReservedAddressRange::Map(uptr fixed_addr, uptr size, - bool tolerate_enomem) { - if (tolerate_enomem) { - return reinterpret_cast(MmapFixedOrDieOnFatalError(fixed_addr, size)); - } +uptr ReservedAddressRange::Map(uptr fixed_addr, uptr size) { + return reinterpret_cast(MmapFixedOrDieOnFatalError(fixed_addr, size)); +} + +uptr ReservedAddressRange::MapOrDie(uptr fixed_addr, uptr size) { return reinterpret_cast(MmapFixedOrDie(fixed_addr, size)); } -- cgit v1.2.1 From 2e68a0aaed73455ccf62d0a4bced2aad8c3f1c3f Mon Sep 17 00:00:00 2001 From: Dmitry Vyukov Date: Tue, 7 Nov 2017 16:31:08 +0000 Subject: tsan: allow usage of global vars with ctors in interceptors We allow usage of global/per-thread data with non-trivial ctors/dtors throughout tsan code base by placing all global/per-thread data into Context/ThreadState and then explicitly constructing them with placement new. This greatly simplifies code by restricting the "linker initialized plague" to only these 2 objects. Do the same for interceptors data. This allows to use Vector instead of bunch of hand-written code in: https://reviews.llvm.org/D39619 Reviewed in: https://reviews.llvm.org/D39721 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@317587 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/tsan/rtl/tsan_interceptors.cc | 45 ++++++++++++++++++++++++++++----------- 1 file changed, 32 insertions(+), 13 deletions(-) diff --git a/lib/tsan/rtl/tsan_interceptors.cc b/lib/tsan/rtl/tsan_interceptors.cc index 0b4e873a0..976fe2967 100644 --- a/lib/tsan/rtl/tsan_interceptors.cc +++ b/lib/tsan/rtl/tsan_interceptors.cc @@ -213,8 +213,6 @@ const int SIG_SETMASK = 2; #define COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED \ (!cur_thread()->is_inited) -static sigaction_t sigactions[kSigCount]; - namespace __tsan { struct SignalDesc { bool armed; @@ -233,11 +231,31 @@ struct ThreadSignalContext { __sanitizer_sigset_t oldset; }; -// The object is 64-byte aligned, because we want hot data to be located in -// a single cache line if possible (it's accessed in every interceptor). -static ALIGNED(64) char libignore_placeholder[sizeof(LibIgnore)]; +// InterceptorContext holds all global data required for interceptors. +// It's explicitly constructed in InitializeInterceptors with placement new +// and is never destroyed. This allows usage of members with non-trivial +// constructors and destructors. +struct InterceptorContext { + // The object is 64-byte aligned, because we want hot data to be located + // in a single cache line if possible (it's accessed in every interceptor). + ALIGNED(64) LibIgnore libignore; + sigaction_t sigactions[kSigCount]; +#if !SANITIZER_MAC && !SANITIZER_NETBSD + unsigned finalize_key; +#endif + + InterceptorContext() + : libignore(LINKER_INITIALIZED) { + } +}; + +static ALIGNED(64) char interceptor_placeholder[sizeof(InterceptorContext)]; +InterceptorContext *interceptor_ctx() { + return reinterpret_cast(&interceptor_placeholder[0]); +} + LibIgnore *libignore() { - return reinterpret_cast(&libignore_placeholder[0]); + return &interceptor_ctx()->libignore; } void InitializeLibIgnore() { @@ -265,10 +283,6 @@ static ThreadSignalContext *SigCtx(ThreadState *thr) { return ctx; } -#if !SANITIZER_MAC && !SANITIZER_NETBSD -static unsigned g_thread_finalize_key; -#endif - ScopedInterceptor::ScopedInterceptor(ThreadState *thr, const char *fname, uptr pc) : thr_(thr), pc_(pc), in_ignored_lib_(false), ignoring_(false) { @@ -873,7 +887,8 @@ void DestroyThreadState() { static void thread_finalize(void *v) { uptr iter = (uptr)v; if (iter > 1) { - if (pthread_setspecific(g_thread_finalize_key, (void*)(iter - 1))) { + if (pthread_setspecific(interceptor_ctx()->finalize_key, + (void*)(iter - 1))) { Printf("ThreadSanitizer: failed to set thread key\n"); Die(); } @@ -901,7 +916,7 @@ extern "C" void *__tsan_thread_start_func(void *arg) { ScopedIgnoreInterceptors ignore; #if !SANITIZER_MAC && !SANITIZER_NETBSD ThreadIgnoreBegin(thr, 0); - if (pthread_setspecific(g_thread_finalize_key, + if (pthread_setspecific(interceptor_ctx()->finalize_key, (void *)GetPthreadDestructorIterations())) { Printf("ThreadSanitizer: failed to set thread key\n"); Die(); @@ -1802,6 +1817,7 @@ namespace __tsan { static void CallUserSignalHandler(ThreadState *thr, bool sync, bool acquire, bool sigact, int sig, my_siginfo_t *info, void *uctx) { + sigaction_t *sigactions = interceptor_ctx()->sigactions; if (acquire) Acquire(thr, 0, (uptr)&sigactions[sig]); // Signals are generally asynchronous, so if we receive a signals when @@ -1953,6 +1969,7 @@ TSAN_INTERCEPTOR(int, sigaction, int sig, sigaction_t *act, sigaction_t *old) { // the signal handler through rtl_sigaction, very bad things will happen. // The handler will run synchronously and corrupt tsan per-thread state. SCOPED_INTERCEPTOR_RAW(sigaction, sig, act, old); + sigaction_t *sigactions = interceptor_ctx()->sigactions; if (old) internal_memcpy(old, &sigactions[sig], sizeof(*old)); if (act == 0) @@ -2490,6 +2507,8 @@ void InitializeInterceptors() { mallopt(-3, 32*1024); // M_MMAP_THRESHOLD #endif + new(interceptor_ctx()) InterceptorContext(); + InitializeCommonInterceptors(); #if !SANITIZER_MAC @@ -2641,7 +2660,7 @@ void InitializeInterceptors() { } #if !SANITIZER_MAC && !SANITIZER_NETBSD - if (pthread_key_create(&g_thread_finalize_key, &thread_finalize)) { + if (pthread_key_create(&interceptor_ctx()->finalize_key, &thread_finalize)) { Printf("ThreadSanitizer: failed to create thread key\n"); Die(); } -- cgit v1.2.1 From 691098268b2aac4f7c3497ca651cf5fc8815284c Mon Sep 17 00:00:00 2001 From: Sam Clegg Date: Tue, 7 Nov 2017 19:03:11 +0000 Subject: [WebAssembly] Include GENERIC_TF_SOURCES in wasm builds Differential Revision: https://reviews.llvm.org/D39748 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@317601 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/builtins/CMakeLists.txt | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/builtins/CMakeLists.txt b/lib/builtins/CMakeLists.txt index 6128abcbf..3fc1d057f 100644 --- a/lib/builtins/CMakeLists.txt +++ b/lib/builtins/CMakeLists.txt @@ -454,8 +454,12 @@ set(mips64_SOURCES ${GENERIC_TF_SOURCES} set(mips64el_SOURCES ${GENERIC_TF_SOURCES} ${mips_SOURCES}) -set(wasm32_SOURCES ${GENERIC_SOURCES}) -set(wasm64_SOURCES ${GENERIC_SOURCES}) +set(wasm32_SOURCES + ${GENERIC_TF_SOURCES} + ${GENERIC_SOURCES}) +set(wasm64_SOURCES + ${GENERIC_TF_SOURCES} + ${GENERIC_SOURCES}) add_custom_target(builtins) set_target_properties(builtins PROPERTIES FOLDER "Compiler-RT Misc") -- cgit v1.2.1 From 42fd441ec75b92a0ba3fdc4df95715257832cbf3 Mon Sep 17 00:00:00 2001 From: Kostya Kortchinsky Date: Tue, 7 Nov 2017 19:30:08 +0000 Subject: [scudo] Make getNumberOfCPUs Fuchsia compliant Summary: This change allows Fuchsia to boot properly using the Scudo allocator. Reviewers: cryptoad, alekseyshl, krytarowski Reviewed By: cryptoad, krytarowski Subscribers: krytarowski, kubamracek, llvm-commits Differential Revision: https://reviews.llvm.org/D39490 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@317604 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/sanitizer_common/sanitizer_common.h | 3 +++ lib/sanitizer_common/sanitizer_fuchsia.cc | 4 ++++ lib/sanitizer_common/sanitizer_linux_libcdep.cc | 22 ++++++++++++++++++++++ lib/sanitizer_common/sanitizer_mac.cc | 5 +++++ lib/sanitizer_common/sanitizer_win.cc | 5 +++++ lib/scudo/scudo_tsd_shared.cpp | 9 +-------- 6 files changed, 40 insertions(+), 8 deletions(-) diff --git a/lib/sanitizer_common/sanitizer_common.h b/lib/sanitizer_common/sanitizer_common.h index 18ebd62be..f8db41a4b 100644 --- a/lib/sanitizer_common/sanitizer_common.h +++ b/lib/sanitizer_common/sanitizer_common.h @@ -933,6 +933,9 @@ void CheckNoDeepBind(const char *filename, int flag); // be used to seed a PRNG. Defaults to blocking like the underlying syscall. bool GetRandom(void *buffer, uptr length, bool blocking = true); +// Returns the number of logical processors on the system. +u32 GetNumberOfCPUs(); + } // namespace __sanitizer inline void *operator new(__sanitizer::operator_new_size_type size, diff --git a/lib/sanitizer_common/sanitizer_fuchsia.cc b/lib/sanitizer_common/sanitizer_fuchsia.cc index 9511ccebf..17ce97755 100644 --- a/lib/sanitizer_common/sanitizer_fuchsia.cc +++ b/lib/sanitizer_common/sanitizer_fuchsia.cc @@ -520,6 +520,10 @@ bool GetRandom(void *buffer, uptr length, bool blocking) { return true; } +u32 GetNumberOfCPUs() { + return zx_system_get_num_cpus(); +} + } // namespace __sanitizer using namespace __sanitizer; // NOLINT diff --git a/lib/sanitizer_common/sanitizer_linux_libcdep.cc b/lib/sanitizer_common/sanitizer_linux_libcdep.cc index 0dc437585..495fa255d 100644 --- a/lib/sanitizer_common/sanitizer_linux_libcdep.cc +++ b/lib/sanitizer_common/sanitizer_linux_libcdep.cc @@ -37,9 +37,14 @@ #if SANITIZER_FREEBSD #include #include +#include #define pthread_getattr_np pthread_attr_get_np #endif +#if SANITIZER_NETBSD +#include +#endif + #if SANITIZER_LINUX #include #endif @@ -538,6 +543,23 @@ uptr GetRSS() { return rss * GetPageSizeCached(); } +// sysconf(_SC_NPROCESSORS_{CONF,ONLN}) cannot be used as they allocate memory. +u32 GetNumberOfCPUs() { +#if SANITIZER_FREEBSD || SANITIZER_NETBSD + u32 ncpu; + int req[2]; + size_t len = sizeof(ncpu); + req[0] = CTL_HW; + req[1] = HW_NCPU; + CHECK_EQ(sysctl(req, 2, &ncpu, &len, NULL, 0), 0); + return ncpu; +#else + cpu_set_t CPUs; + CHECK_EQ(sched_getaffinity(0, sizeof(cpu_set_t), &CPUs), 0); + return CPU_COUNT(&CPUs); +#endif +} + // 64-bit Android targets don't provide the deprecated __android_log_write. // Starting with the L release, syslog() works and is preferable to // __android_log_write. diff --git a/lib/sanitizer_common/sanitizer_mac.cc b/lib/sanitizer_common/sanitizer_mac.cc index 9fead91b9..13ab6c000 100644 --- a/lib/sanitizer_common/sanitizer_mac.cc +++ b/lib/sanitizer_common/sanitizer_mac.cc @@ -1000,6 +1000,11 @@ bool GetRandom(void *buffer, uptr length, bool blocking) { UNIMPLEMENTED(); } +// FIXME: implement on this platform. +u32 GetNumberOfCPUs() { + UNIMPLEMENTED(); +} + } // namespace __sanitizer #endif // SANITIZER_MAC diff --git a/lib/sanitizer_common/sanitizer_win.cc b/lib/sanitizer_common/sanitizer_win.cc index 718209fcf..e0f72239f 100644 --- a/lib/sanitizer_common/sanitizer_win.cc +++ b/lib/sanitizer_common/sanitizer_win.cc @@ -1093,6 +1093,11 @@ bool GetRandom(void *buffer, uptr length, bool blocking) { UNIMPLEMENTED(); } +// FIXME: implement on this platform. +u32 GetNumberOfCPUs() { + UNIMPLEMENTED(); +} + } // namespace __sanitizer #endif // _WIN32 diff --git a/lib/scudo/scudo_tsd_shared.cpp b/lib/scudo/scudo_tsd_shared.cpp index 191c9ff13..25575afcb 100644 --- a/lib/scudo/scudo_tsd_shared.cpp +++ b/lib/scudo/scudo_tsd_shared.cpp @@ -24,17 +24,10 @@ static atomic_uint32_t CurrentIndex; static ScudoTSD *TSDs; static u32 NumberOfTSDs; -// sysconf(_SC_NPROCESSORS_{CONF,ONLN}) cannot be used as they allocate memory. -static u32 getNumberOfCPUs() { - cpu_set_t CPUs; - CHECK_EQ(sched_getaffinity(0, sizeof(cpu_set_t), &CPUs), 0); - return CPU_COUNT(&CPUs); -} - static void initOnce() { CHECK_EQ(pthread_key_create(&PThreadKey, NULL), 0); initScudo(); - NumberOfTSDs = Min(Max(1U, getNumberOfCPUs()), + NumberOfTSDs = Min(Max(1U, GetNumberOfCPUs()), static_cast(SCUDO_SHARED_TSD_POOL_SIZE)); TSDs = reinterpret_cast( MmapOrDie(sizeof(ScudoTSD) * NumberOfTSDs, "ScudoTSDs")); -- cgit v1.2.1 From 697b8e7e448c385ba289d4cdb1d92e751ec9400f Mon Sep 17 00:00:00 2001 From: Vitaly Buka Date: Tue, 7 Nov 2017 20:10:17 +0000 Subject: [sanitizer] Fix sanitizer_common compile errors on gcc trunk Summary: When testing a merge of compiler-rt r304709 into gcc trunk on x86-64-pc-linux-gnu, I ran into two compile errors: sanitizer_common/sanitizer_symbolizer_libbacktrace.cc:96:73: error: no matching function for call to '__sanitizer::AddressInfo::FillModuleInfo(char*&, __sanitizer::uptr&)' All other files in sanitizer_common (with the exception of sanitizer_malloc_mac.inc which is special) include sanitizer_platform.h without directory name. Patch by Mike Jongen Reviewers: kcc, vitalybuka Reviewed By: kcc Subscribers: kubamracek, fedor.sergeev, llvm-commits Differential Revision: https://reviews.llvm.org/D33933 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@317608 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/sanitizer_common/sanitizer_symbolizer_libbacktrace.cc | 3 ++- lib/sanitizer_common/sanitizer_win_weak_interception.cc | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/sanitizer_common/sanitizer_symbolizer_libbacktrace.cc b/lib/sanitizer_common/sanitizer_symbolizer_libbacktrace.cc index 57354668b..e98fab01d 100644 --- a/lib/sanitizer_common/sanitizer_symbolizer_libbacktrace.cc +++ b/lib/sanitizer_common/sanitizer_symbolizer_libbacktrace.cc @@ -95,7 +95,8 @@ struct SymbolizeCodeCallbackArg { if (frames_symbolized > 0) { SymbolizedStack *cur = SymbolizedStack::New(addr); AddressInfo *info = &cur->info; - info->FillModuleInfo(first->info.module, first->info.module_offset); + info->FillModuleInfo(first->info.module, first->info.module_offset, + first->info.module_arch); last->next = cur; last = cur; } diff --git a/lib/sanitizer_common/sanitizer_win_weak_interception.cc b/lib/sanitizer_common/sanitizer_win_weak_interception.cc index 364319398..5711f5dc8 100644 --- a/lib/sanitizer_common/sanitizer_win_weak_interception.cc +++ b/lib/sanitizer_common/sanitizer_win_weak_interception.cc @@ -12,7 +12,7 @@ // definition is provided. //===----------------------------------------------------------------------===// -#include "sanitizer_common/sanitizer_platform.h" +#include "sanitizer_platform.h" #if SANITIZER_WINDOWS && SANITIZER_DYNAMIC #include "sanitizer_win_weak_interception.h" #include "sanitizer_allocator_interface.h" -- cgit v1.2.1 From c58a938aae7ebeaa26c4552fe4c4586c28dbf1ff Mon Sep 17 00:00:00 2001 From: Evgeniy Stepanov Date: Tue, 7 Nov 2017 23:51:22 +0000 Subject: (NFC) Rename GetMax{,User}VirtualAddress. Future change will introduce GetMaxVirtualAddress that will not take the kernel area into account. git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@317638 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/asan/asan_fuchsia.cc | 2 +- lib/asan/asan_rtl.cc | 2 +- lib/cfi/cfi.cc | 2 +- lib/msan/msan_linux.cc | 2 +- lib/sanitizer_common/sanitizer_common.h | 2 +- lib/sanitizer_common/sanitizer_fuchsia.cc | 2 +- lib/sanitizer_common/sanitizer_linux.cc | 2 +- lib/sanitizer_common/sanitizer_mac.cc | 2 +- lib/sanitizer_common/sanitizer_mac_libcdep.cc | 2 +- lib/sanitizer_common/sanitizer_win.cc | 2 +- lib/tsan/rtl/tsan_platform_mac.cc | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/lib/asan/asan_fuchsia.cc b/lib/asan/asan_fuchsia.cc index 02fb8be4a..0b5bff4f5 100644 --- a/lib/asan/asan_fuchsia.cc +++ b/lib/asan/asan_fuchsia.cc @@ -28,7 +28,7 @@ namespace __asan { // The system already set up the shadow memory for us. -// __sanitizer::GetMaxVirtualAddress has already been called by +// __sanitizer::GetMaxUserVirtualAddress has already been called by // AsanInitInternal->InitializeHighMemEnd (asan_rtl.cc). // Just do some additional sanity checks here. void InitializeShadowMemory() { diff --git a/lib/asan/asan_rtl.cc b/lib/asan/asan_rtl.cc index 8608e4a60..27e4bd842 100644 --- a/lib/asan/asan_rtl.cc +++ b/lib/asan/asan_rtl.cc @@ -307,7 +307,7 @@ static void asan_atexit() { static void InitializeHighMemEnd() { #if !ASAN_FIXED_MAPPING - kHighMemEnd = GetMaxVirtualAddress(); + kHighMemEnd = GetMaxUserVirtualAddress(); // Increase kHighMemEnd to make sure it's properly // aligned together with kHighMemBeg: kHighMemEnd |= SHADOW_GRANULARITY * GetMmapGranularity() - 1; diff --git a/lib/cfi/cfi.cc b/lib/cfi/cfi.cc index f720230a7..f7693b37d 100644 --- a/lib/cfi/cfi.cc +++ b/lib/cfi/cfi.cc @@ -280,7 +280,7 @@ void InitShadow() { CHECK_EQ(0, GetShadow()); CHECK_EQ(0, GetShadowSize()); - uptr vma = GetMaxVirtualAddress(); + uptr vma = GetMaxUserVirtualAddress(); // Shadow is 2 -> 2**kShadowGranularity. SetShadowSize((vma >> (kShadowGranularity - 1)) + 1); VReport(1, "CFI: VMA size %zx, shadow size %zx\n", vma, GetShadowSize()); diff --git a/lib/msan/msan_linux.cc b/lib/msan/msan_linux.cc index a1191a100..4e6321fcb 100644 --- a/lib/msan/msan_linux.cc +++ b/lib/msan/msan_linux.cc @@ -120,7 +120,7 @@ bool InitShadow(bool init_origins) { return false; } - const uptr maxVirtualAddress = GetMaxVirtualAddress(); + const uptr maxVirtualAddress = GetMaxUserVirtualAddress(); for (unsigned i = 0; i < kMemoryLayoutSize; ++i) { uptr start = kMemoryLayout[i].start; diff --git a/lib/sanitizer_common/sanitizer_common.h b/lib/sanitizer_common/sanitizer_common.h index f8db41a4b..b322f4712 100644 --- a/lib/sanitizer_common/sanitizer_common.h +++ b/lib/sanitizer_common/sanitizer_common.h @@ -73,7 +73,7 @@ INLINE uptr GetPageSizeCached() { return PageSizeCached; } uptr GetMmapGranularity(); -uptr GetMaxVirtualAddress(); +uptr GetMaxUserVirtualAddress(); // Threads tid_t GetTid(); uptr GetThreadSelf(); diff --git a/lib/sanitizer_common/sanitizer_fuchsia.cc b/lib/sanitizer_common/sanitizer_fuchsia.cc index 17ce97755..45104e5bc 100644 --- a/lib/sanitizer_common/sanitizer_fuchsia.cc +++ b/lib/sanitizer_common/sanitizer_fuchsia.cc @@ -186,7 +186,7 @@ uptr GetMmapGranularity() { return PAGE_SIZE; } sanitizer_shadow_bounds_t ShadowBounds; -uptr GetMaxVirtualAddress() { +uptr GetMaxUserVirtualAddress() { ShadowBounds = __sanitizer_shadow_bounds(); return ShadowBounds.memory_limit - 1; } diff --git a/lib/sanitizer_common/sanitizer_linux.cc b/lib/sanitizer_common/sanitizer_linux.cc index 5199aa601..8fc9256c4 100644 --- a/lib/sanitizer_common/sanitizer_linux.cc +++ b/lib/sanitizer_common/sanitizer_linux.cc @@ -952,7 +952,7 @@ static uptr GetKernelAreaSize() { } #endif // SANITIZER_WORDSIZE == 32 -uptr GetMaxVirtualAddress() { +uptr GetMaxUserVirtualAddress() { #if SANITIZER_NETBSD && defined(__x86_64__) return 0x7f7ffffff000ULL; // (0x00007f8000000000 - PAGE_SIZE) #elif SANITIZER_WORDSIZE == 64 diff --git a/lib/sanitizer_common/sanitizer_mac.cc b/lib/sanitizer_common/sanitizer_mac.cc index 13ab6c000..fbc8cdd1f 100644 --- a/lib/sanitizer_common/sanitizer_mac.cc +++ b/lib/sanitizer_common/sanitizer_mac.cc @@ -849,7 +849,7 @@ uptr GetTaskInfoMaxAddress() { } #endif -uptr GetMaxVirtualAddress() { +uptr GetMaxUserVirtualAddress() { #if SANITIZER_WORDSIZE == 64 # if defined(__aarch64__) && SANITIZER_IOS && !SANITIZER_IOSSIM // Get the maximum VM address diff --git a/lib/sanitizer_common/sanitizer_mac_libcdep.cc b/lib/sanitizer_common/sanitizer_mac_libcdep.cc index c95daa937..090f17c88 100644 --- a/lib/sanitizer_common/sanitizer_mac_libcdep.cc +++ b/lib/sanitizer_common/sanitizer_mac_libcdep.cc @@ -20,7 +20,7 @@ namespace __sanitizer { void RestrictMemoryToMaxAddress(uptr max_address) { - uptr size_to_mmap = GetMaxVirtualAddress() + 1 - max_address; + uptr size_to_mmap = GetMaxUserVirtualAddress() + 1 - max_address; void *res = MmapFixedNoAccess(max_address, size_to_mmap, "high gap"); CHECK(res != MAP_FAILED); } diff --git a/lib/sanitizer_common/sanitizer_win.cc b/lib/sanitizer_common/sanitizer_win.cc index e0f72239f..7a9a94780 100644 --- a/lib/sanitizer_common/sanitizer_win.cc +++ b/lib/sanitizer_common/sanitizer_win.cc @@ -64,7 +64,7 @@ uptr GetMmapGranularity() { return si.dwAllocationGranularity; } -uptr GetMaxVirtualAddress() { +uptr GetMaxUserVirtualAddress() { SYSTEM_INFO si; GetSystemInfo(&si); return (uptr)si.lpMaximumApplicationAddress; diff --git a/lib/tsan/rtl/tsan_platform_mac.cc b/lib/tsan/rtl/tsan_platform_mac.cc index 4570286b1..f8d7324b7 100644 --- a/lib/tsan/rtl/tsan_platform_mac.cc +++ b/lib/tsan/rtl/tsan_platform_mac.cc @@ -231,7 +231,7 @@ static void my_pthread_introspection_hook(unsigned int event, pthread_t thread, void InitializePlatformEarly() { #if defined(__aarch64__) - uptr max_vm = GetMaxVirtualAddress() + 1; + uptr max_vm = GetMaxUserVirtualAddress() + 1; if (max_vm != Mapping::kHiAppMemEnd) { Printf("ThreadSanitizer: unsupported vm address limit %p, expected %p.\n", max_vm, Mapping::kHiAppMemEnd); -- cgit v1.2.1 From 644af7779f086cb428b7b76da5509348e3a2358f Mon Sep 17 00:00:00 2001 From: Evgeniy Stepanov Date: Wed, 8 Nov 2017 00:15:12 +0000 Subject: [sanitizer] Asm implementation of syscall() for arm32. Summary: These will be used in an ifunc resolver, when the binary may not be completely relocated, and syscall() function from libc could not be used. Reviewers: dvyukov, vitalybuka Subscribers: aemerson, kubamracek, javed.absar, llvm-commits, kristof.beyls Differential Revision: https://reviews.llvm.org/D39701 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@317640 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/sanitizer_common/sanitizer_linux.cc | 2 + .../sanitizer_syscall_linux_arm.inc | 141 +++++++++++++++++++++ 2 files changed, 143 insertions(+) create mode 100644 lib/sanitizer_common/sanitizer_syscall_linux_arm.inc diff --git a/lib/sanitizer_common/sanitizer_linux.cc b/lib/sanitizer_common/sanitizer_linux.cc index 8fc9256c4..ea1e79556 100644 --- a/lib/sanitizer_common/sanitizer_linux.cc +++ b/lib/sanitizer_common/sanitizer_linux.cc @@ -139,6 +139,8 @@ namespace __sanitizer { #include "sanitizer_syscall_linux_x86_64.inc" #elif SANITIZER_LINUX && defined(__aarch64__) #include "sanitizer_syscall_linux_aarch64.inc" +#elif SANITIZER_LINUX && defined(__arm__) +#include "sanitizer_syscall_linux_arm.inc" #else #include "sanitizer_syscall_generic.inc" #endif diff --git a/lib/sanitizer_common/sanitizer_syscall_linux_arm.inc b/lib/sanitizer_common/sanitizer_syscall_linux_arm.inc new file mode 100644 index 000000000..a3fdb9e60 --- /dev/null +++ b/lib/sanitizer_common/sanitizer_syscall_linux_arm.inc @@ -0,0 +1,141 @@ +//===-- sanitizer_syscall_linux_arm.inc -------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Implementations of internal_syscall and internal_iserror for Linux/arm. +// +//===----------------------------------------------------------------------===// + +#define SYSCALL(name) __NR_ ## name + +static uptr __internal_syscall(u32 nr) { + register u32 r8 asm("r7") = nr; + register u32 r0 asm("r0"); + asm volatile("swi #0" + : "=r"(r0) + : "r"(r8) + : "memory", "cc"); + return r0; +} +#define __internal_syscall0(n) \ + (__internal_syscall)(n) + +static uptr __internal_syscall(u32 nr, u32 arg1) { + register u32 r8 asm("r7") = nr; + register u32 r0 asm("r0") = arg1; + asm volatile("swi #0" + : "=r"(r0) + : "r"(r8), "0"(r0) + : "memory", "cc"); + return r0; +} +#define __internal_syscall1(n, a1) \ + (__internal_syscall)(n, (u32)(a1)) + +static uptr __internal_syscall(u32 nr, u32 arg1, long arg2) { + register u32 r8 asm("r7") = nr; + register u32 r0 asm("r0") = arg1; + register u32 r1 asm("r1") = arg2; + asm volatile("swi #0" + : "=r"(r0) + : "r"(r8), "0"(r0), "r"(r1) + : "memory", "cc"); + return r0; +} +#define __internal_syscall2(n, a1, a2) \ + (__internal_syscall)(n, (u32)(a1), (long)(a2)) + +static uptr __internal_syscall(u32 nr, u32 arg1, long arg2, long arg3) { + register u32 r8 asm("r7") = nr; + register u32 r0 asm("r0") = arg1; + register u32 r1 asm("r1") = arg2; + register u32 r2 asm("r2") = arg3; + asm volatile("swi #0" + : "=r"(r0) + : "r"(r8), "0"(r0), "r"(r1), "r"(r2) + : "memory", "cc"); + return r0; +} +#define __internal_syscall3(n, a1, a2, a3) \ + (__internal_syscall)(n, (u32)(a1), (long)(a2), (long)(a3)) + +static uptr __internal_syscall(u32 nr, u32 arg1, long arg2, long arg3, + u32 arg4) { + register u32 r8 asm("r7") = nr; + register u32 r0 asm("r0") = arg1; + register u32 r1 asm("r1") = arg2; + register u32 r2 asm("r2") = arg3; + register u32 r3 asm("r3") = arg4; + asm volatile("swi #0" + : "=r"(r0) + : "r"(r8), "0"(r0), "r"(r1), "r"(r2), "r"(r3) + : "memory", "cc"); + return r0; +} +#define __internal_syscall4(n, a1, a2, a3, a4) \ + (__internal_syscall)(n, (u32)(a1), (long)(a2), (long)(a3), (long)(a4)) + +static uptr __internal_syscall(u32 nr, u32 arg1, long arg2, long arg3, + u32 arg4, long arg5) { + register u32 r8 asm("r7") = nr; + register u32 r0 asm("r0") = arg1; + register u32 r1 asm("r1") = arg2; + register u32 r2 asm("r2") = arg3; + register u32 r3 asm("r3") = arg4; + register u32 r4 asm("r4") = arg5; + asm volatile("swi #0" + : "=r"(r0) + : "r"(r8), "0"(r0), "r"(r1), "r"(r2), "r"(r3), "r"(r4) + : "memory", "cc"); + return r0; +} +#define __internal_syscall5(n, a1, a2, a3, a4, a5) \ + (__internal_syscall)(n, (u32)(a1), (long)(a2), (long)(a3), (long)(a4), \ + (u32)(a5)) + +static uptr __internal_syscall(u32 nr, u32 arg1, long arg2, long arg3, + u32 arg4, long arg5, long arg6) { + register u32 r8 asm("r7") = nr; + register u32 r0 asm("r0") = arg1; + register u32 r1 asm("r1") = arg2; + register u32 r2 asm("r2") = arg3; + register u32 r3 asm("r3") = arg4; + register u32 r4 asm("r4") = arg5; + register u32 r5 asm("r5") = arg6; + asm volatile("swi #0" + : "=r"(r0) + : "r"(r8), "0"(r0), "r"(r1), "r"(r2), "r"(r3), "r"(r4), "r"(r5) + : "memory", "cc"); + return r0; +} +#define __internal_syscall6(n, a1, a2, a3, a4, a5, a6) \ + (__internal_syscall)(n, (u32)(a1), (long)(a2), (long)(a3), (long)(a4), \ + (u32)(a5), (long)(a6)) + +#define __SYSCALL_NARGS_X(a1, a2, a3, a4, a5, a6, a7, a8, n, ...) n +#define __SYSCALL_NARGS(...) \ + __SYSCALL_NARGS_X(__VA_ARGS__, 7, 6, 5, 4, 3, 2, 1, 0, ) +#define __SYSCALL_CONCAT_X(a, b) a##b +#define __SYSCALL_CONCAT(a, b) __SYSCALL_CONCAT_X(a, b) +#define __SYSCALL_DISP(b, ...) \ + __SYSCALL_CONCAT(b, __SYSCALL_NARGS(__VA_ARGS__))(__VA_ARGS__) + +#define internal_syscall(...) __SYSCALL_DISP(__internal_syscall, __VA_ARGS__) + +#define internal_syscall_ptr internal_syscall +#define internal_syscall64 internal_syscall + +// Helper function used to avoid cobbler errno. +bool internal_iserror(uptr retval, int *rverrno) { + if (retval >= (uptr)-4095) { + if (rverrno) + *rverrno = -retval; + return true; + } + return false; +} -- cgit v1.2.1 From 3806f9ea105f0e9554d87862d81caeadb81d44f6 Mon Sep 17 00:00:00 2001 From: Reid Kleckner Date: Wed, 8 Nov 2017 01:33:15 +0000 Subject: Revert "[scudo] Make getNumberOfCPUs Fuchsia compliant" This reverts commit r317604. Android doesn't have cpu_set_t. git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@317655 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/sanitizer_common/sanitizer_common.h | 3 --- lib/sanitizer_common/sanitizer_fuchsia.cc | 4 ---- lib/sanitizer_common/sanitizer_linux_libcdep.cc | 22 ---------------------- lib/sanitizer_common/sanitizer_mac.cc | 5 ----- lib/sanitizer_common/sanitizer_win.cc | 5 ----- lib/scudo/scudo_tsd_shared.cpp | 9 ++++++++- 6 files changed, 8 insertions(+), 40 deletions(-) diff --git a/lib/sanitizer_common/sanitizer_common.h b/lib/sanitizer_common/sanitizer_common.h index b322f4712..d64d3e153 100644 --- a/lib/sanitizer_common/sanitizer_common.h +++ b/lib/sanitizer_common/sanitizer_common.h @@ -933,9 +933,6 @@ void CheckNoDeepBind(const char *filename, int flag); // be used to seed a PRNG. Defaults to blocking like the underlying syscall. bool GetRandom(void *buffer, uptr length, bool blocking = true); -// Returns the number of logical processors on the system. -u32 GetNumberOfCPUs(); - } // namespace __sanitizer inline void *operator new(__sanitizer::operator_new_size_type size, diff --git a/lib/sanitizer_common/sanitizer_fuchsia.cc b/lib/sanitizer_common/sanitizer_fuchsia.cc index 45104e5bc..97dff0d8b 100644 --- a/lib/sanitizer_common/sanitizer_fuchsia.cc +++ b/lib/sanitizer_common/sanitizer_fuchsia.cc @@ -520,10 +520,6 @@ bool GetRandom(void *buffer, uptr length, bool blocking) { return true; } -u32 GetNumberOfCPUs() { - return zx_system_get_num_cpus(); -} - } // namespace __sanitizer using namespace __sanitizer; // NOLINT diff --git a/lib/sanitizer_common/sanitizer_linux_libcdep.cc b/lib/sanitizer_common/sanitizer_linux_libcdep.cc index 495fa255d..0dc437585 100644 --- a/lib/sanitizer_common/sanitizer_linux_libcdep.cc +++ b/lib/sanitizer_common/sanitizer_linux_libcdep.cc @@ -37,14 +37,9 @@ #if SANITIZER_FREEBSD #include #include -#include #define pthread_getattr_np pthread_attr_get_np #endif -#if SANITIZER_NETBSD -#include -#endif - #if SANITIZER_LINUX #include #endif @@ -543,23 +538,6 @@ uptr GetRSS() { return rss * GetPageSizeCached(); } -// sysconf(_SC_NPROCESSORS_{CONF,ONLN}) cannot be used as they allocate memory. -u32 GetNumberOfCPUs() { -#if SANITIZER_FREEBSD || SANITIZER_NETBSD - u32 ncpu; - int req[2]; - size_t len = sizeof(ncpu); - req[0] = CTL_HW; - req[1] = HW_NCPU; - CHECK_EQ(sysctl(req, 2, &ncpu, &len, NULL, 0), 0); - return ncpu; -#else - cpu_set_t CPUs; - CHECK_EQ(sched_getaffinity(0, sizeof(cpu_set_t), &CPUs), 0); - return CPU_COUNT(&CPUs); -#endif -} - // 64-bit Android targets don't provide the deprecated __android_log_write. // Starting with the L release, syslog() works and is preferable to // __android_log_write. diff --git a/lib/sanitizer_common/sanitizer_mac.cc b/lib/sanitizer_common/sanitizer_mac.cc index fbc8cdd1f..7a93c112b 100644 --- a/lib/sanitizer_common/sanitizer_mac.cc +++ b/lib/sanitizer_common/sanitizer_mac.cc @@ -1000,11 +1000,6 @@ bool GetRandom(void *buffer, uptr length, bool blocking) { UNIMPLEMENTED(); } -// FIXME: implement on this platform. -u32 GetNumberOfCPUs() { - UNIMPLEMENTED(); -} - } // namespace __sanitizer #endif // SANITIZER_MAC diff --git a/lib/sanitizer_common/sanitizer_win.cc b/lib/sanitizer_common/sanitizer_win.cc index 7a9a94780..1186971f7 100644 --- a/lib/sanitizer_common/sanitizer_win.cc +++ b/lib/sanitizer_common/sanitizer_win.cc @@ -1093,11 +1093,6 @@ bool GetRandom(void *buffer, uptr length, bool blocking) { UNIMPLEMENTED(); } -// FIXME: implement on this platform. -u32 GetNumberOfCPUs() { - UNIMPLEMENTED(); -} - } // namespace __sanitizer #endif // _WIN32 diff --git a/lib/scudo/scudo_tsd_shared.cpp b/lib/scudo/scudo_tsd_shared.cpp index 25575afcb..191c9ff13 100644 --- a/lib/scudo/scudo_tsd_shared.cpp +++ b/lib/scudo/scudo_tsd_shared.cpp @@ -24,10 +24,17 @@ static atomic_uint32_t CurrentIndex; static ScudoTSD *TSDs; static u32 NumberOfTSDs; +// sysconf(_SC_NPROCESSORS_{CONF,ONLN}) cannot be used as they allocate memory. +static u32 getNumberOfCPUs() { + cpu_set_t CPUs; + CHECK_EQ(sched_getaffinity(0, sizeof(cpu_set_t), &CPUs), 0); + return CPU_COUNT(&CPUs); +} + static void initOnce() { CHECK_EQ(pthread_key_create(&PThreadKey, NULL), 0); initScudo(); - NumberOfTSDs = Min(Max(1U, GetNumberOfCPUs()), + NumberOfTSDs = Min(Max(1U, getNumberOfCPUs()), static_cast(SCUDO_SHARED_TSD_POOL_SIZE)); TSDs = reinterpret_cast( MmapOrDie(sizeof(ScudoTSD) * NumberOfTSDs, "ScudoTSDs")); -- cgit v1.2.1 From c66ad7987f2e2bb1d6bd61c10e87abd4346d3a13 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Wed, 8 Nov 2017 07:25:19 +0000 Subject: Always use prctl(PR_SET_PTRACER) Summary: Sufficiently old Linux kernel headers don't provide the PR_SET_PTRACER, but we can still call prctl with it if the runtime kernel is newer. Even if it's not, prctl will only return EINVAL. Patch by Mike Hommey Reviewers: eugenis Reviewed By: eugenis Subscribers: sylvestre.ledru, cfe-commits, kubamracek Differential Revision: https://reviews.llvm.org/D39717 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@317668 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc b/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc index e1cb6f76f..ea864e59e 100644 --- a/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc +++ b/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc @@ -57,6 +57,14 @@ #include "sanitizer_mutex.h" #include "sanitizer_placement_new.h" +// Sufficiently old kernel headers don't provide this value, but we can still +// call prctl with it. If the runtime kernel is new enough, the prctl call will +// have the desired effect; if the kernel is too old, the call will error and we +// can ignore said error. +#ifndef PR_SET_PTRACER +#define PR_SET_PTRACER 0x59616d61 +#endif + // This module works by spawning a Linux task which then attaches to every // thread in the caller process with ptrace. This suspends the threads, and // PTRACE_GETREGS can then be used to obtain their register state. The callback @@ -433,9 +441,7 @@ void StopTheWorld(StopTheWorldCallback callback, void *argument) { ScopedSetTracerPID scoped_set_tracer_pid(tracer_pid); // On some systems we have to explicitly declare that we want to be traced // by the tracer thread. -#ifdef PR_SET_PTRACER internal_prctl(PR_SET_PTRACER, tracer_pid, 0, 0, 0); -#endif // Allow the tracer thread to start. tracer_thread_argument.mutex.Unlock(); // NOTE: errno is shared between this thread and the tracer thread. -- cgit v1.2.1 From 9a46448f818bd47de8604ec9e0e39ced6a00499e Mon Sep 17 00:00:00 2001 From: Kostya Kortchinsky Date: Wed, 8 Nov 2017 16:42:29 +0000 Subject: [sanitizer] Add Scudo to the sanitizer lint checks. Summary: Scudo abides by the coding style enforced by the sanitizer_common linter, but as of right now, it's not linter-enforced. Add Scudo to the list of directories checked by check_lint.sh. Also: fixes some linter errors found after getting this running. Reviewers: cryptoad Reviewed By: cryptoad Subscribers: llvm-commits, kubamracek Differential Revision: https://reviews.llvm.org/D39757 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@317699 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/sanitizer_common/scripts/check_lint.sh | 6 ++++++ lib/scudo/scudo_allocator_secondary.h | 1 - lib/scudo/scudo_crc32.h | 2 +- lib/scudo/scudo_utils.cpp | 6 ++---- 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/lib/sanitizer_common/scripts/check_lint.sh b/lib/sanitizer_common/scripts/check_lint.sh index 82e4bc84d..ec07138ca 100755 --- a/lib/sanitizer_common/scripts/check_lint.sh +++ b/lib/sanitizer_common/scripts/check_lint.sh @@ -29,6 +29,7 @@ MSAN_RTL_LINT_FILTER=${COMMON_LINT_FILTER} LSAN_RTL_LINT_FILTER=${COMMON_LINT_FILTER} LSAN_LIT_TEST_LINT_FILTER=${LSAN_RTL_LINT_FILTER},-whitespace/line_length DFSAN_RTL_LINT_FILTER=${COMMON_LINT_FILTER},-runtime/int,-runtime/printf,-runtime/references,-readability/function +SCUDO_RTL_LINT_FILTER=${COMMON_LINT_FILTER} COMMON_RTL_INC_LINT_FILTER=${COMMON_LINT_FILTER},-runtime/int,-runtime/sizeof,-runtime/printf,-readability/fn_size SANITIZER_INCLUDES_LINT_FILTER=${COMMON_LINT_FILTER},-runtime/int @@ -112,6 +113,11 @@ run_lint ${DFSAN_RTL_LINT_FILTER} ${DFSAN_RTL}/*.cc \ ${DFSAN_RTL}/*.h & ${DFSAN_RTL}/scripts/check_custom_wrappers.sh >> $ERROR_LOG +# Scudo +SCUDO_RTL=${COMPILER_RT}/lib/scudo +run_lint ${SCUDO_RTL_LINT_FILTER} ${SCUDO_RTL}/*.cpp \ + ${SCUDO_RTL}/*.h & + # Misc files FILES=${COMMON_RTL}/*.inc TMPFILES="" diff --git a/lib/scudo/scudo_allocator_secondary.h b/lib/scudo/scudo_allocator_secondary.h index dbfb22565..5220b7c57 100644 --- a/lib/scudo/scudo_allocator_secondary.h +++ b/lib/scudo/scudo_allocator_secondary.h @@ -23,7 +23,6 @@ class ScudoLargeMmapAllocator { public: - void Init() { PageSize = GetPageSizeCached(); } diff --git a/lib/scudo/scudo_crc32.h b/lib/scudo/scudo_crc32.h index 5ffcc6265..e89e430f4 100644 --- a/lib/scudo/scudo_crc32.h +++ b/lib/scudo/scudo_crc32.h @@ -40,7 +40,7 @@ enum : u8 { CRC32Hardware = 1, }; -const static u32 CRC32Table[] = { +static const u32 CRC32Table[] = { 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, diff --git a/lib/scudo/scudo_utils.cpp b/lib/scudo/scudo_utils.cpp index 093eafe8e..653b6c8fa 100644 --- a/lib/scudo/scudo_utils.cpp +++ b/lib/scudo/scudo_utils.cpp @@ -90,8 +90,7 @@ typedef struct { u32 Edx; } CPUIDRegs; -static void getCPUID(CPUIDRegs *Regs, u32 Level) -{ +static void getCPUID(CPUIDRegs *Regs, u32 Level) { __get_cpuid(Level, &Regs->Eax, &Regs->Ebx, &Regs->Ecx, &Regs->Edx); } @@ -118,8 +117,7 @@ CPUIDRegs getCPUFeatures() { # define bit_SSE4_2 bit_SSE42 // clang and gcc have different defines. # endif -bool testCPUFeature(CPUFeature Feature) -{ +bool testCPUFeature(CPUFeature Feature) { CPUIDRegs FeaturesRegs = getCPUFeatures(); switch (Feature) { -- cgit v1.2.1 From 07e2a968c83c489c5b46efe4973114e78e1804c1 Mon Sep 17 00:00:00 2001 From: Marco Castelluccio Date: Wed, 8 Nov 2017 19:11:54 +0000 Subject: Implement flock for Windows in compiler-rt Summary: This patch implements flock for Windows, needed to make gcda writing work in a multiprocessing scenario. Fixes https://bugs.llvm.org/show_bug.cgi?id=34923. Reviewers: zturner Reviewed By: zturner Subscribers: rnk, zturner, llvm-commits Differential Revision: https://reviews.llvm.org/D38891 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@317705 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/profile/WindowsMMap.c | 58 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 55 insertions(+), 3 deletions(-) diff --git a/lib/profile/WindowsMMap.c b/lib/profile/WindowsMMap.c index f81d7da53..0c534710b 100644 --- a/lib/profile/WindowsMMap.c +++ b/lib/profile/WindowsMMap.c @@ -120,9 +120,61 @@ int msync(void *addr, size_t length, int flags) } COMPILER_RT_VISIBILITY -int flock(int fd, int operation) -{ - return -1; /* Not supported. */ +int lock(HANDLE handle, DWORD lockType, BOOL blocking) { + DWORD flags = lockType; + if (!blocking) + flags |= LOCKFILE_FAIL_IMMEDIATELY; + + OVERLAPPED overlapped; + ZeroMemory(&overlapped, sizeof(OVERLAPPED)); + overlapped.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); + BOOL result = LockFileEx(handle, flags, 0, MAXDWORD, MAXDWORD, &overlapped); + if (!result) { + DWORD dw = GetLastError(); + + // In non-blocking mode, return an error if the file is locked. + if (!blocking && dw == ERROR_LOCK_VIOLATION) + return -1; // EWOULDBLOCK + + // If the error is ERROR_IO_PENDING, we need to wait until the operation + // finishes. Otherwise, we return an error. + if (dw != ERROR_IO_PENDING) + return -1; + + DWORD dwNumBytes; + if (!GetOverlappedResult(handle, &overlapped, &dwNumBytes, TRUE)) + return -1; + } + + return 0; +} + +COMPILER_RT_VISIBILITY +int flock(int fd, int operation) { + HANDLE handle = (HANDLE)_get_osfhandle(fd); + if (handle == INVALID_HANDLE_VALUE) + return -1; + + BOOL blocking = (operation & LOCK_NB) == 0; + int op = operation & ~LOCK_NB; + + switch (op) { + case LOCK_EX: + return lock(handle, LOCKFILE_EXCLUSIVE_LOCK, blocking); + + case LOCK_SH: + return lock(handle, 0, blocking); + + case LOCK_UN: + if (!UnlockFile(handle, 0, 0, MAXDWORD, MAXDWORD)) + return -1; + break; + + default: + return -1; + } + + return 0; } #undef DWORD_HI -- cgit v1.2.1 From 65964b0190520f92123c3b1adb7dce481179909b Mon Sep 17 00:00:00 2001 From: Teresa Johnson Date: Wed, 8 Nov 2017 19:46:25 +0000 Subject: [ThinLTO] Ensure sanitizer passes are run Summary: Test fix to pass manager for ThinLTO. Depends on D39565. Reviewers: pcc Subscribers: kubamracek, mehdi_amini, llvm-commits, inglorion Differential Revision: https://reviews.llvm.org/D39566 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@317715 91177308-0d34-0410-b5e6-96231b3b80d8 --- test/asan/TestCases/contiguous_container_crash.cc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test/asan/TestCases/contiguous_container_crash.cc b/test/asan/TestCases/contiguous_container_crash.cc index af2102e6a..fe9792888 100644 --- a/test/asan/TestCases/contiguous_container_crash.cc +++ b/test/asan/TestCases/contiguous_container_crash.cc @@ -4,6 +4,12 @@ // RUN: not %run %t bad-alignment 2>&1 | FileCheck --check-prefix=CHECK-BAD-ALIGNMENT %s // RUN: %env_asan_opts=detect_container_overflow=0 %run %t crash // +// RUN: %clangxx_asan -flto=thin -O %s -o %t.thinlto +// RUN: not %run %t.thinlto crash 2>&1 | FileCheck --check-prefix=CHECK-CRASH %s +// RUN: not %run %t.thinlto bad-bounds 2>&1 | FileCheck --check-prefix=CHECK-BAD-BOUNDS %s +// RUN: not %run %t.thinlto bad-alignment 2>&1 | FileCheck --check-prefix=CHECK-BAD-ALIGNMENT %s +// RUN: %env_asan_opts=detect_container_overflow=0 %run %t.thinlto crash +// // Test crash due to __sanitizer_annotate_contiguous_container. #include -- cgit v1.2.1