diff options
Diffstat (limited to 'compiler-rt')
69 files changed, 596 insertions, 230 deletions
diff --git a/compiler-rt/lib/asan/asan_allocator.cpp b/compiler-rt/lib/asan/asan_allocator.cpp index d3c0288..9ebe4d0 100644 --- a/compiler-rt/lib/asan/asan_allocator.cpp +++ b/compiler-rt/lib/asan/asan_allocator.cpp @@ -1007,13 +1007,8 @@ void PrintInternalAllocatorStats() { instance.PrintStats(); } -void asan_free(void *ptr, BufferedStackTrace *stack, AllocType alloc_type) { - instance.Deallocate(ptr, 0, 0, stack, alloc_type); -} - -void asan_delete(void *ptr, uptr size, uptr alignment, - BufferedStackTrace *stack, AllocType alloc_type) { - instance.Deallocate(ptr, size, alignment, stack, alloc_type); +void asan_free(void *ptr, BufferedStackTrace *stack) { + instance.Deallocate(ptr, 0, 0, stack, FROM_MALLOC); } void *asan_malloc(uptr size, BufferedStackTrace *stack) { @@ -1068,8 +1063,7 @@ void *asan_pvalloc(uptr size, BufferedStackTrace *stack) { instance.Allocate(size, PageSize, stack, FROM_MALLOC, true)); } -void *asan_memalign(uptr alignment, uptr size, BufferedStackTrace *stack, - AllocType alloc_type) { +void *asan_memalign(uptr alignment, uptr size, BufferedStackTrace *stack) { if (UNLIKELY(!IsPowerOfTwo(alignment))) { errno = errno_EINVAL; if (AllocatorMayReturnNull()) @@ -1077,7 +1071,7 @@ void *asan_memalign(uptr alignment, uptr size, BufferedStackTrace *stack, ReportInvalidAllocationAlignment(alignment, stack); } return SetErrnoOnNull( - instance.Allocate(size, alignment, stack, alloc_type, true)); + instance.Allocate(size, alignment, stack, FROM_MALLOC, true)); } void *asan_aligned_alloc(uptr alignment, uptr size, BufferedStackTrace *stack) { @@ -1117,6 +1111,99 @@ uptr asan_malloc_usable_size(const void *ptr, uptr pc, uptr bp) { return usable_size; } +namespace { + +void *asan_new(uptr size, BufferedStackTrace *stack, bool array) { + return SetErrnoOnNull( + instance.Allocate(size, 0, stack, array ? FROM_NEW_BR : FROM_NEW, true)); +} + +void *asan_new_aligned(uptr size, uptr alignment, BufferedStackTrace *stack, + bool array) { + if (UNLIKELY(alignment == 0 || !IsPowerOfTwo(alignment))) { + errno = errno_EINVAL; + if (AllocatorMayReturnNull()) + return nullptr; + ReportInvalidAllocationAlignment(alignment, stack); + } + return SetErrnoOnNull(instance.Allocate( + size, alignment, stack, array ? FROM_NEW_BR : FROM_NEW, true)); +} + +void asan_delete(void *ptr, BufferedStackTrace *stack, bool array) { + instance.Deallocate(ptr, 0, 0, stack, array ? FROM_NEW_BR : FROM_NEW); +} + +void asan_delete_aligned(void *ptr, uptr alignment, BufferedStackTrace *stack, + bool array) { + instance.Deallocate(ptr, 0, alignment, stack, array ? FROM_NEW_BR : FROM_NEW); +} + +void asan_delete_sized(void *ptr, uptr size, BufferedStackTrace *stack, + bool array) { + instance.Deallocate(ptr, size, 0, stack, array ? FROM_NEW_BR : FROM_NEW); +} + +void asan_delete_sized_aligned(void *ptr, uptr size, uptr alignment, + BufferedStackTrace *stack, bool array) { + instance.Deallocate(ptr, size, alignment, stack, + array ? FROM_NEW_BR : FROM_NEW); +} + +} // namespace + +void *asan_new(uptr size, BufferedStackTrace *stack) { + return asan_new(size, stack, /*array=*/false); +} + +void *asan_new_aligned(uptr size, uptr alignment, BufferedStackTrace *stack) { + return asan_new_aligned(size, alignment, stack, /*array=*/false); +} + +void *asan_new_array(uptr size, BufferedStackTrace *stack) { + return asan_new(size, stack, /*array=*/true); +} + +void *asan_new_array_aligned(uptr size, uptr alignment, + BufferedStackTrace *stack) { + return asan_new_aligned(size, alignment, stack, /*array=*/true); +} + +void asan_delete(void *ptr, BufferedStackTrace *stack) { + asan_delete(ptr, stack, /*array=*/false); +} + +void asan_delete_aligned(void *ptr, uptr alignment, BufferedStackTrace *stack) { + asan_delete_aligned(ptr, alignment, stack, /*array=*/false); +} + +void asan_delete_sized(void *ptr, uptr size, BufferedStackTrace *stack) { + asan_delete_sized(ptr, size, stack, /*array=*/false); +} + +void asan_delete_sized_aligned(void *ptr, uptr size, uptr alignment, + BufferedStackTrace *stack) { + asan_delete_sized_aligned(ptr, size, alignment, stack, /*array=*/false); +} + +void asan_delete_array(void *ptr, BufferedStackTrace *stack) { + asan_delete(ptr, stack, /*array=*/true); +} + +void asan_delete_array_aligned(void *ptr, uptr alignment, + BufferedStackTrace *stack) { + asan_delete_aligned(ptr, alignment, stack, /*array=*/true); +} + +void asan_delete_array_sized(void *ptr, uptr size, BufferedStackTrace *stack) { + asan_delete_sized(ptr, size, stack, /*array=*/true); +} + +void asan_delete_array_sized_aligned(void *ptr, uptr size, uptr alignment, + BufferedStackTrace *stack) { + asan_delete_sized_aligned(ptr, size, alignment, stack, /*array=*/true); +} + uptr asan_mz_size(const void *ptr) { return instance.AllocationSize(reinterpret_cast<uptr>(ptr)); } diff --git a/compiler-rt/lib/asan/asan_allocator.h b/compiler-rt/lib/asan/asan_allocator.h index 247d8bb..fdf4564 100644 --- a/compiler-rt/lib/asan/asan_allocator.h +++ b/compiler-rt/lib/asan/asan_allocator.h @@ -270,11 +270,8 @@ struct AsanThreadLocalMallocStorage { AsanThreadLocalMallocStorage() {} }; -void *asan_memalign(uptr alignment, uptr size, BufferedStackTrace *stack, - AllocType alloc_type); -void asan_free(void *ptr, BufferedStackTrace *stack, AllocType alloc_type); -void asan_delete(void *ptr, uptr size, uptr alignment, - BufferedStackTrace *stack, AllocType alloc_type); +void *asan_memalign(uptr alignment, uptr size, BufferedStackTrace *stack); +void asan_free(void *ptr, BufferedStackTrace *stack); void *asan_malloc(uptr size, BufferedStackTrace *stack); void *asan_calloc(uptr nmemb, uptr size, BufferedStackTrace *stack); @@ -289,6 +286,23 @@ int asan_posix_memalign(void **memptr, uptr alignment, uptr size, BufferedStackTrace *stack); uptr asan_malloc_usable_size(const void *ptr, uptr pc, uptr bp); +void *asan_new(uptr size, BufferedStackTrace *stack); +void *asan_new_aligned(uptr size, uptr alignment, BufferedStackTrace *stack); +void *asan_new_array(uptr size, BufferedStackTrace *stack); +void *asan_new_array_aligned(uptr size, uptr alignment, + BufferedStackTrace *stack); +void asan_delete(void *ptr, BufferedStackTrace *stack); +void asan_delete_aligned(void *ptr, uptr alignment, BufferedStackTrace *stack); +void asan_delete_sized(void *ptr, uptr size, BufferedStackTrace *stack); +void asan_delete_sized_aligned(void *ptr, uptr size, uptr alignment, + BufferedStackTrace *stack); +void asan_delete_array(void *ptr, BufferedStackTrace *stack); +void asan_delete_array_aligned(void *ptr, uptr alignment, + BufferedStackTrace *stack); +void asan_delete_array_sized(void *ptr, uptr size, BufferedStackTrace *stack); +void asan_delete_array_sized_aligned(void *ptr, uptr size, uptr alignment, + BufferedStackTrace *stack); + uptr asan_mz_size(const void *ptr); void asan_mz_force_lock(); void asan_mz_force_unlock(); diff --git a/compiler-rt/lib/asan/asan_mac.cpp b/compiler-rt/lib/asan/asan_mac.cpp index be513a0..1f3c79e 100644 --- a/compiler-rt/lib/asan/asan_mac.cpp +++ b/compiler-rt/lib/asan/asan_mac.cpp @@ -103,6 +103,8 @@ void FlushUnneededASanShadowMemory(uptr p, uptr size) { // dispatch_after() // dispatch_group_async_f() // dispatch_group_async() +// dispatch_apply() +// dispatch_apply_f() // TODO(glider): libdispatch API contains other functions that we don't support // yet. // @@ -176,7 +178,7 @@ void asan_dispatch_call_block_and_release(void *block) { asan_register_worker_thread(context->parent_tid, &stack); // Call the original dispatcher for the block. context->func(context->block); - asan_free(context, &stack, FROM_MALLOC); + asan_free(context, &stack); } } // namespace __asan @@ -243,13 +245,31 @@ INTERCEPTOR(void, dispatch_group_async_f, dispatch_group_t group, asan_dispatch_call_block_and_release); } -#if !defined(MISSING_BLOCKS_SUPPORT) +extern "C" void asan_dispatch_apply_f_work(void *context, size_t iteration) { + GET_STACK_TRACE_THREAD; + asan_block_context_t *asan_ctxt = (asan_block_context_t *)context; + asan_register_worker_thread(asan_ctxt->parent_tid, &stack); + ((void (*)(void *, size_t))asan_ctxt->func)(asan_ctxt->block, iteration); +} + +INTERCEPTOR(void, dispatch_apply_f, size_t iterations, dispatch_queue_t queue, + void *ctxt, void (*work)(void *, size_t)) { + GET_STACK_TRACE_THREAD; + asan_block_context_t *asan_ctxt = + alloc_asan_context(ctxt, (dispatch_function_t)work, &stack); + REAL(dispatch_apply_f)(iterations, queue, (void *)asan_ctxt, + asan_dispatch_apply_f_work); +} + +# if !defined(MISSING_BLOCKS_SUPPORT) extern "C" { void dispatch_async(dispatch_queue_t dq, void(^work)(void)); void dispatch_group_async(dispatch_group_t dg, dispatch_queue_t dq, void(^work)(void)); void dispatch_after(dispatch_time_t when, dispatch_queue_t queue, void(^work)(void)); +void dispatch_apply(size_t iterations, dispatch_queue_t queue, + void (^block)(size_t iteration)); void dispatch_source_set_cancel_handler(dispatch_source_t ds, void(^work)(void)); void dispatch_source_set_event_handler(dispatch_source_t ds, void(^work)(void)); @@ -332,6 +352,20 @@ INTERCEPTOR(void *, dispatch_mach_create_f, const char *label, }); } -#endif +INTERCEPTOR(void, dispatch_apply, size_t iterations, dispatch_queue_t queue, + void (^block)(size_t iteration)) { + ENABLE_FRAME_POINTER; + int parent_tid = GetCurrentTidOrInvalid(); + + void (^asan_block)(size_t) = ^(size_t iteration) { + GET_STACK_TRACE_THREAD; + asan_register_worker_thread(parent_tid, &stack); + block(iteration); + }; + + REAL(dispatch_apply)(iterations, queue, asan_block); +} + +# endif #endif // SANITIZER_APPLE diff --git a/compiler-rt/lib/asan/asan_malloc_linux.cpp b/compiler-rt/lib/asan/asan_malloc_linux.cpp index 3f023d4..add5731 100644 --- a/compiler-rt/lib/asan/asan_malloc_linux.cpp +++ b/compiler-rt/lib/asan/asan_malloc_linux.cpp @@ -49,7 +49,7 @@ INTERCEPTOR(void, free, void *ptr) { if (DlsymAlloc::PointerIsMine(ptr)) return DlsymAlloc::Free(ptr); GET_STACK_TRACE_FREE; - asan_free(ptr, &stack, FROM_MALLOC); + asan_free(ptr, &stack); } #if SANITIZER_INTERCEPT_CFREE @@ -57,7 +57,7 @@ INTERCEPTOR(void, cfree, void *ptr) { if (DlsymAlloc::PointerIsMine(ptr)) return DlsymAlloc::Free(ptr); GET_STACK_TRACE_FREE; - asan_free(ptr, &stack, FROM_MALLOC); + asan_free(ptr, &stack); } #endif // SANITIZER_INTERCEPT_CFREE @@ -93,12 +93,12 @@ INTERCEPTOR(void*, reallocarray, void *ptr, uptr nmemb, uptr size) { #if SANITIZER_INTERCEPT_MEMALIGN INTERCEPTOR(void*, memalign, uptr boundary, uptr size) { GET_STACK_TRACE_MALLOC; - return asan_memalign(boundary, size, &stack, FROM_MALLOC); + return asan_memalign(boundary, size, &stack); } INTERCEPTOR(void*, __libc_memalign, uptr boundary, uptr size) { GET_STACK_TRACE_MALLOC; - return asan_memalign(boundary, size, &stack, FROM_MALLOC); + return asan_memalign(boundary, size, &stack); } #endif // SANITIZER_INTERCEPT_MEMALIGN diff --git a/compiler-rt/lib/asan/asan_malloc_mac.cpp b/compiler-rt/lib/asan/asan_malloc_mac.cpp index f25d7e1..a442bdb 100644 --- a/compiler-rt/lib/asan/asan_malloc_mac.cpp +++ b/compiler-rt/lib/asan/asan_malloc_mac.cpp @@ -31,7 +31,7 @@ using namespace __asan; # define COMMON_MALLOC_FORCE_UNLOCK() asan_mz_force_unlock() # define COMMON_MALLOC_MEMALIGN(alignment, size) \ GET_STACK_TRACE_MALLOC; \ - void *p = asan_memalign(alignment, size, &stack, FROM_MALLOC) + void *p = asan_memalign(alignment, size, &stack) # define COMMON_MALLOC_MALLOC(size) \ GET_STACK_TRACE_MALLOC; \ void *p = asan_malloc(size, &stack) @@ -46,10 +46,10 @@ using namespace __asan; int res = asan_posix_memalign(memptr, alignment, size, &stack); # define COMMON_MALLOC_VALLOC(size) \ GET_STACK_TRACE_MALLOC; \ - void *p = asan_memalign(GetPageSizeCached(), size, &stack, FROM_MALLOC); + void *p = asan_memalign(GetPageSizeCached(), size, &stack); # define COMMON_MALLOC_FREE(ptr) \ GET_STACK_TRACE_FREE; \ - asan_free(ptr, &stack, FROM_MALLOC); + asan_free(ptr, &stack); # define COMMON_MALLOC_SIZE(ptr) uptr size = asan_mz_size(ptr); # define COMMON_MALLOC_FILL_STATS(zone, stats) \ AsanMallocStats malloc_stats; \ diff --git a/compiler-rt/lib/asan/asan_malloc_win.cpp b/compiler-rt/lib/asan/asan_malloc_win.cpp index 3278f07..8d98da9 100644 --- a/compiler-rt/lib/asan/asan_malloc_win.cpp +++ b/compiler-rt/lib/asan/asan_malloc_win.cpp @@ -69,7 +69,7 @@ __declspec(noinline) size_t _msize_base(void *ptr) { return _msize(ptr); } __declspec(noinline) void free(void *ptr) { GET_STACK_TRACE_FREE; - return asan_free(ptr, &stack, FROM_MALLOC); + return asan_free(ptr, &stack); } __declspec(noinline) void _free_dbg(void *ptr, int) { free(ptr); } @@ -252,7 +252,7 @@ INTERCEPTOR_WINAPI(BOOL, HeapFree, HANDLE hHeap, DWORD dwFlags, LPVOID lpMem) { CHECK((HEAP_FREE_UNSUPPORTED_FLAGS & dwFlags) != 0 && "unsupported flags"); } GET_STACK_TRACE_FREE; - asan_free(lpMem, &stack, FROM_MALLOC); + asan_free(lpMem, &stack); return true; } @@ -306,7 +306,7 @@ void *SharedReAlloc(ReAllocFunction reallocFunc, SizeFunction heapSizeFunc, if (replacement_alloc) { size_t old_size = heapSizeFunc(hHeap, dwFlags, lpMem); if (old_size == ((size_t)0) - 1) { - asan_free(replacement_alloc, &stack, FROM_MALLOC); + asan_free(replacement_alloc, &stack); return nullptr; } REAL(memcpy)(replacement_alloc, lpMem, old_size); @@ -331,7 +331,7 @@ void *SharedReAlloc(ReAllocFunction reallocFunc, SizeFunction heapSizeFunc, old_usable_size = asan_malloc_usable_size(lpMem, pc, bp); REAL(memcpy)(replacement_alloc, lpMem, Min<size_t>(dwBytes, old_usable_size)); - asan_free(lpMem, &stack, FROM_MALLOC); + asan_free(lpMem, &stack); } return replacement_alloc; } @@ -429,7 +429,7 @@ INTERCEPTOR_WINAPI(BOOL, RtlFreeHeap, HANDLE HeapHandle, DWORD Flags, return REAL(RtlFreeHeap)(HeapHandle, Flags, BaseAddress); } GET_STACK_TRACE_FREE; - asan_free(BaseAddress, &stack, FROM_MALLOC); + asan_free(BaseAddress, &stack); return true; } diff --git a/compiler-rt/lib/asan/asan_new_delete.cpp b/compiler-rt/lib/asan/asan_new_delete.cpp index 99c7c99..d7ed5b5 100644 --- a/compiler-rt/lib/asan/asan_new_delete.cpp +++ b/compiler-rt/lib/asan/asan_new_delete.cpp @@ -60,42 +60,42 @@ enum class align_val_t: size_t {}; // TODO(alekseyshl): throw std::bad_alloc instead of dying on OOM. // For local pool allocation, align to SHADOW_GRANULARITY to match asan // allocator behavior. -#define OPERATOR_NEW_BODY \ - GET_STACK_TRACE_MALLOC; \ - void *res = asan_memalign(0, size, &stack, FROM_NEW); \ - if (UNLIKELY(!res)) \ - ReportOutOfMemory(size, &stack); \ +#define OPERATOR_NEW_BODY \ + GET_STACK_TRACE_MALLOC; \ + void *res = asan_new(size, &stack); \ + if (UNLIKELY(!res)) \ + ReportOutOfMemory(size, &stack); \ return res #define OPERATOR_NEW_BODY_NOTHROW \ GET_STACK_TRACE_MALLOC; \ - return asan_memalign(0, size, &stack, FROM_NEW) -#define OPERATOR_NEW_BODY_ARRAY \ - GET_STACK_TRACE_MALLOC; \ - void *res = asan_memalign(0, size, &stack, FROM_NEW_BR); \ - if (UNLIKELY(!res)) \ - ReportOutOfMemory(size, &stack); \ + return asan_new(size, &stack) +#define OPERATOR_NEW_BODY_ARRAY \ + GET_STACK_TRACE_MALLOC; \ + void *res = asan_new_array(size, &stack); \ + if (UNLIKELY(!res)) \ + ReportOutOfMemory(size, &stack); \ return res #define OPERATOR_NEW_BODY_ARRAY_NOTHROW \ GET_STACK_TRACE_MALLOC; \ - return asan_memalign(0, size, &stack, FROM_NEW_BR) -#define OPERATOR_NEW_BODY_ALIGN \ - GET_STACK_TRACE_MALLOC; \ - void *res = asan_memalign((uptr)align, size, &stack, FROM_NEW); \ - if (UNLIKELY(!res)) \ - ReportOutOfMemory(size, &stack); \ + return asan_new_array(size, &stack) +#define OPERATOR_NEW_BODY_ALIGN \ + GET_STACK_TRACE_MALLOC; \ + void *res = asan_new_aligned(size, static_cast<uptr>(align), &stack); \ + if (UNLIKELY(!res)) \ + ReportOutOfMemory(size, &stack); \ return res #define OPERATOR_NEW_BODY_ALIGN_NOTHROW \ GET_STACK_TRACE_MALLOC; \ - return asan_memalign((uptr)align, size, &stack, FROM_NEW) -#define OPERATOR_NEW_BODY_ALIGN_ARRAY \ - GET_STACK_TRACE_MALLOC; \ - void *res = asan_memalign((uptr)align, size, &stack, FROM_NEW_BR); \ - if (UNLIKELY(!res)) \ - ReportOutOfMemory(size, &stack); \ + return asan_new_aligned(size, static_cast<uptr>(align), &stack) +#define OPERATOR_NEW_BODY_ALIGN_ARRAY \ + GET_STACK_TRACE_MALLOC; \ + void *res = asan_new_array_aligned(size, static_cast<uptr>(align), &stack); \ + if (UNLIKELY(!res)) \ + ReportOutOfMemory(size, &stack); \ return res #define OPERATOR_NEW_BODY_ALIGN_ARRAY_NOTHROW \ GET_STACK_TRACE_MALLOC; \ - return asan_memalign((uptr)align, size, &stack, FROM_NEW_BR) + return asan_new_array_aligned(size, static_cast<uptr>(align), &stack) // On OS X it's not enough to just provide our own 'operator new' and // 'operator delete' implementations, because they're going to be in the @@ -149,28 +149,28 @@ INTERCEPTOR(void *, _ZnamRKSt9nothrow_t, size_t size, std::nothrow_t const&) { #define OPERATOR_DELETE_BODY \ GET_STACK_TRACE_FREE; \ - asan_delete(ptr, 0, 0, &stack, FROM_NEW) + asan_delete(ptr, &stack) #define OPERATOR_DELETE_BODY_ARRAY \ GET_STACK_TRACE_FREE; \ - asan_delete(ptr, 0, 0, &stack, FROM_NEW_BR) + asan_delete_array(ptr, &stack) #define OPERATOR_DELETE_BODY_ALIGN \ GET_STACK_TRACE_FREE; \ - asan_delete(ptr, 0, static_cast<uptr>(align), &stack, FROM_NEW) + asan_delete_aligned(ptr, static_cast<uptr>(align), &stack) #define OPERATOR_DELETE_BODY_ALIGN_ARRAY \ GET_STACK_TRACE_FREE; \ - asan_delete(ptr, 0, static_cast<uptr>(align), &stack, FROM_NEW_BR) + asan_delete_array_aligned(ptr, static_cast<uptr>(align), &stack) #define OPERATOR_DELETE_BODY_SIZE \ GET_STACK_TRACE_FREE; \ - asan_delete(ptr, size, 0, &stack, FROM_NEW) + asan_delete_sized(ptr, size, &stack) #define OPERATOR_DELETE_BODY_SIZE_ARRAY \ GET_STACK_TRACE_FREE; \ - asan_delete(ptr, size, 0, &stack, FROM_NEW_BR) + asan_delete_array_sized(ptr, size, &stack) #define OPERATOR_DELETE_BODY_SIZE_ALIGN \ GET_STACK_TRACE_FREE; \ - asan_delete(ptr, size, static_cast<uptr>(align), &stack, FROM_NEW) + asan_delete_sized_aligned(ptr, size, static_cast<uptr>(align), &stack) #define OPERATOR_DELETE_BODY_SIZE_ALIGN_ARRAY \ GET_STACK_TRACE_FREE; \ - asan_delete(ptr, size, static_cast<uptr>(align), &stack, FROM_NEW_BR) + asan_delete_array_sized_aligned(ptr, size, static_cast<uptr>(align), &stack) #if !SANITIZER_APPLE CXX_OPERATOR_ATTRIBUTE diff --git a/compiler-rt/lib/asan/asan_thread.cpp b/compiler-rt/lib/asan/asan_thread.cpp index 37fb6f2..2627ae1 100644 --- a/compiler-rt/lib/asan/asan_thread.cpp +++ b/compiler-rt/lib/asan/asan_thread.cpp @@ -282,7 +282,7 @@ void AsanThread::Init(const InitOptions *options) { // asan_fuchsia.c definies CreateMainThread and SetThreadStackAndTls. #if !SANITIZER_FUCHSIA -void AsanThread::ThreadStart(tid_t os_id) { +void AsanThread::ThreadStart(ThreadID os_id) { Init(); asanThreadRegistry().StartThread(tid(), os_id, ThreadType::Regular, nullptr); @@ -469,7 +469,7 @@ void EnsureMainThreadIDIsCorrect() { context->os_id = GetTid(); } -__asan::AsanThread *GetAsanThreadByOsIDLocked(tid_t os_id) { +__asan::AsanThread *GetAsanThreadByOsIDLocked(ThreadID os_id) { __asan::AsanThreadContext *context = static_cast<__asan::AsanThreadContext *>( __asan::asanThreadRegistry().FindThreadContextByOsIDLocked(os_id)); if (!context) @@ -497,7 +497,7 @@ static ThreadRegistry *GetAsanThreadRegistryLocked() { void EnsureMainThreadIDIsCorrect() { __asan::EnsureMainThreadIDIsCorrect(); } -bool GetThreadRangesLocked(tid_t os_id, uptr *stack_begin, uptr *stack_end, +bool GetThreadRangesLocked(ThreadID os_id, uptr *stack_begin, uptr *stack_end, uptr *tls_begin, uptr *tls_end, uptr *cache_begin, uptr *cache_end, DTLS **dtls) { __asan::AsanThread *t = __asan::GetAsanThreadByOsIDLocked(os_id); @@ -516,7 +516,7 @@ bool GetThreadRangesLocked(tid_t os_id, uptr *stack_begin, uptr *stack_end, void GetAllThreadAllocatorCachesLocked(InternalMmapVector<uptr> *caches) {} -void GetThreadExtraStackRangesLocked(tid_t os_id, +void GetThreadExtraStackRangesLocked(ThreadID os_id, InternalMmapVector<Range> *ranges) { __asan::AsanThread *t = __asan::GetAsanThreadByOsIDLocked(os_id); if (!t) @@ -546,11 +546,11 @@ void GetAdditionalThreadContextPtrsLocked(InternalMmapVector<uptr> *ptrs) { __asan::asanThreadArgRetval().GetAllPtrsLocked(ptrs); } -void GetRunningThreadsLocked(InternalMmapVector<tid_t> *threads) { +void GetRunningThreadsLocked(InternalMmapVector<ThreadID> *threads) { GetAsanThreadRegistryLocked()->RunCallbackForEachThreadLocked( [](ThreadContextBase *tctx, void *threads) { if (tctx->status == ThreadStatusRunning) - reinterpret_cast<InternalMmapVector<tid_t> *>(threads)->push_back( + reinterpret_cast<InternalMmapVector<ThreadID> *>(threads)->push_back( tctx->os_id); }, threads); diff --git a/compiler-rt/lib/asan/asan_thread.h b/compiler-rt/lib/asan/asan_thread.h index ad9e03d..12f0cc7 100644 --- a/compiler-rt/lib/asan/asan_thread.h +++ b/compiler-rt/lib/asan/asan_thread.h @@ -75,7 +75,7 @@ class AsanThread { struct InitOptions; void Init(const InitOptions *options = nullptr); - void ThreadStart(tid_t os_id); + void ThreadStart(ThreadID os_id); thread_return_t RunThread(); uptr stack_top(); diff --git a/compiler-rt/lib/asan/tests/asan_mac_test.cpp b/compiler-rt/lib/asan/tests/asan_mac_test.cpp index bd36089..4b21f12 100644 --- a/compiler-rt/lib/asan/tests/asan_mac_test.cpp +++ b/compiler-rt/lib/asan/tests/asan_mac_test.cpp @@ -116,6 +116,12 @@ TEST(AddressSanitizerMac, GCDDispatchAfter) { EXPECT_DEATH(TestGCDDispatchAfter(), "Shadow byte legend"); } +TEST(AddressSanitizerMac, GCDDispatchApply) { + // Make sure the whole ASan report is printed, i.e. that we don't die + // on a CHECK. + EXPECT_DEATH(TestGCDDispatchApply(), "Shadow byte legend"); +} + TEST(AddressSanitizerMac, GCDSourceEvent) { // Make sure the whole ASan report is printed, i.e. that we don't die // on a CHECK. diff --git a/compiler-rt/lib/asan/tests/asan_mac_test.h b/compiler-rt/lib/asan/tests/asan_mac_test.h index 441547a..ec71546 100644 --- a/compiler-rt/lib/asan/tests/asan_mac_test.h +++ b/compiler-rt/lib/asan/tests/asan_mac_test.h @@ -9,6 +9,7 @@ extern "C" { void TestGCDReuseWqthreadsAsync(); void TestGCDReuseWqthreadsSync(); void TestGCDDispatchAfter(); + void TestGCDDispatchApply(); void TestGCDInTSDDestructor(); void TestGCDSourceEvent(); void TestGCDSourceCancel(); diff --git a/compiler-rt/lib/asan/tests/asan_mac_test_helpers.mm b/compiler-rt/lib/asan/tests/asan_mac_test_helpers.mm index 3f8fa26d..ddb50f8 100644 --- a/compiler-rt/lib/asan/tests/asan_mac_test_helpers.mm +++ b/compiler-rt/lib/asan/tests/asan_mac_test_helpers.mm @@ -148,6 +148,16 @@ void TestGCDDispatchAfter() { wait_forever(); } +void TestGCDDispatchApply() { + dispatch_queue_t queue = dispatch_get_global_queue(0, 0); + __block char *buffer = (char *)malloc(4); + dispatch_apply(8, queue, ^(size_t i) { + access_memory(&buffer[i]); + }); + + free(buffer); // not reached +} + void worker_do_deallocate(void *ptr) { free(ptr); } diff --git a/compiler-rt/lib/asan/tests/asan_noinst_test.cpp b/compiler-rt/lib/asan/tests/asan_noinst_test.cpp index f485404..401219ac 100644 --- a/compiler-rt/lib/asan/tests/asan_noinst_test.cpp +++ b/compiler-rt/lib/asan/tests/asan_noinst_test.cpp @@ -71,7 +71,7 @@ static void *MallocStress(void *NumOfItrPtr) { void *ptr = vec[idx]; vec[idx] = vec.back(); vec.pop_back(); - __asan::asan_free(ptr, &stack1, __asan::FROM_MALLOC); + __asan::asan_free(ptr, &stack1); } else { size_t size = my_rand_r(&seed) % 1000 + 1; switch ((my_rand_r(&seed) % 128)) { @@ -80,8 +80,7 @@ static void *MallocStress(void *NumOfItrPtr) { case 2: size += 4096; break; } size_t alignment = 1 << (my_rand_r(&seed) % 10 + 1); - char *ptr = (char *)__asan::asan_memalign(alignment, size, &stack2, - __asan::FROM_MALLOC); + char *ptr = (char *)__asan::asan_memalign(alignment, size, &stack2); EXPECT_EQ(size, __asan::asan_malloc_usable_size(ptr, 0, 0)); vec.push_back(ptr); ptr[0] = 0; @@ -89,8 +88,7 @@ static void *MallocStress(void *NumOfItrPtr) { ptr[size/2] = 0; } } - for (size_t i = 0; i < vec.size(); i++) - __asan::asan_free(vec[i], &stack3, __asan::FROM_MALLOC); + for (size_t i = 0; i < vec.size(); i++) __asan::asan_free(vec[i], &stack3); return nullptr; } @@ -143,12 +141,12 @@ TEST(AddressSanitizer, QuarantineTest) { const int size = 1024; void *p = __asan::asan_malloc(size, &stack); - __asan::asan_free(p, &stack, __asan::FROM_MALLOC); + __asan::asan_free(p, &stack); size_t i; size_t max_i = 1 << 30; for (i = 0; i < max_i; i++) { void *p1 = __asan::asan_malloc(size, &stack); - __asan::asan_free(p1, &stack, __asan::FROM_MALLOC); + __asan::asan_free(p1, &stack); if (p1 == p) break; } EXPECT_GE(i, 10000U); @@ -165,7 +163,7 @@ void *ThreadedQuarantineTestWorker(void *unused) { for (size_t i = 0; i < 1000; i++) { void *p = __asan::asan_malloc(1 + (my_rand_r(&seed) % 4000), &stack); - __asan::asan_free(p, &stack, __asan::FROM_MALLOC); + __asan::asan_free(p, &stack); } return NULL; } @@ -204,7 +202,7 @@ void *ThreadedOneSizeMallocStress(void *unused) { p[i] = __asan::asan_malloc(32, &stack); } for (size_t i = 0; i < kNumMallocs; i++) { - __asan::asan_free(p[i], &stack, __asan::FROM_MALLOC); + __asan::asan_free(p[i], &stack); } } return NULL; @@ -260,7 +258,7 @@ static void TestLoadStoreCallbacks(CB cb[2][5]) { } } } - __asan::asan_free(ptr, &stack, __asan::FROM_MALLOC); + __asan::asan_free(ptr, &stack); } __asan_test_only_reported_buggy_pointer = 0; } diff --git a/compiler-rt/lib/builtins/CMakeLists.txt b/compiler-rt/lib/builtins/CMakeLists.txt index 3ab9240..1dadb6a 100644 --- a/compiler-rt/lib/builtins/CMakeLists.txt +++ b/compiler-rt/lib/builtins/CMakeLists.txt @@ -591,10 +591,16 @@ set(aarch64_SOURCES ${GENERIC_TF_SOURCES} ${GENERIC_SOURCES} cpu_model/aarch64.c - aarch64/emupac.cpp aarch64/fp_mode.c ) +# Append sources specific to AArch64 targets that aren't supported by cl.exe +if(CLANG_CL OR NOT MSVC) + list(APPEND aarch64_SOURCES + aarch64/emupac.cpp + ) +endif() + set(COMPILER_RT_AARCH64_FMV_USES_GLOBAL_CONSTRUCTOR NOT(FUCHSIA OR APPLE)) if (COMPILER_RT_HAS_AARCH64_SME) diff --git a/compiler-rt/lib/builtins/crtbegin.c b/compiler-rt/lib/builtins/crtbegin.c index d5f7756..447474b 100644 --- a/compiler-rt/lib/builtins/crtbegin.c +++ b/compiler-rt/lib/builtins/crtbegin.c @@ -54,22 +54,33 @@ static void __attribute__((used)) __do_init(void) { } #ifdef CRT_HAS_INITFINI_ARRAY -#if __has_feature(ptrauth_init_fini) +# if __has_feature(ptrauth_init_fini) // TODO: use __ptrauth-qualified pointers when they are supported on clang side -#if __has_feature(ptrauth_init_fini_address_discrimination) +# if __has_feature(ptrauth_init_fini_address_discrimination) __attribute__((section(".init_array"), used)) static void *__init = ptrauth_sign_constant(&__do_init, ptrauth_key_init_fini_pointer, ptrauth_blend_discriminator( &__init, __ptrauth_init_fini_discriminator)); -#else +# else __attribute__((section(".init_array"), used)) static void *__init = ptrauth_sign_constant(&__do_init, ptrauth_key_init_fini_pointer, __ptrauth_init_fini_discriminator); -#endif -#else +# endif +# elif __has_feature(ptrauth_calls) +# ifdef __aarch64__ +// If ptrauth_init_fini feature is not present, compiler emits raw unsigned +// pointers in .init_array. Use inline assembly to avoid implicit signing of +// __do_init function pointer with ptrauth_calls enabled. +__asm__(".pushsection .init_array,\"aw\",@init_array\n\t" + ".xword __do_init\n\t" + ".popsection"); +# else +# error "ptrauth_calls is only supported for AArch64" +# endif +# else __attribute__((section(".init_array"), used)) static void (*__init)(void) = __do_init; -#endif +# endif #elif defined(__i386__) || defined(__x86_64__) __asm__(".pushsection .init,\"ax\",@progbits\n\t" "call __do_init\n\t" @@ -125,22 +136,33 @@ static void __attribute__((used)) __do_fini(void) { } #ifdef CRT_HAS_INITFINI_ARRAY -#if __has_feature(ptrauth_init_fini) +# if __has_feature(ptrauth_init_fini) // TODO: use __ptrauth-qualified pointers when they are supported on clang side -#if __has_feature(ptrauth_init_fini_address_discrimination) +# if __has_feature(ptrauth_init_fini_address_discrimination) __attribute__((section(".fini_array"), used)) static void *__fini = ptrauth_sign_constant(&__do_fini, ptrauth_key_init_fini_pointer, ptrauth_blend_discriminator( &__fini, __ptrauth_init_fini_discriminator)); -#else +# else __attribute__((section(".fini_array"), used)) static void *__fini = ptrauth_sign_constant(&__do_fini, ptrauth_key_init_fini_pointer, __ptrauth_init_fini_discriminator); -#endif -#else +# endif +# elif __has_feature(ptrauth_calls) +# ifdef __aarch64__ +// If ptrauth_init_fini feature is not present, compiler emits raw unsigned +// pointers in .fini_array. Use inline assembly to avoid implicit signing of +// __do_fini function pointer with ptrauth_calls enabled. +__asm__(".pushsection .fini_array,\"aw\",@fini_array\n\t" + ".xword __do_fini\n\t" + ".popsection"); +# else +# error "ptrauth_calls is only supported for AArch64" +# endif +# else __attribute__((section(".fini_array"), used)) static void (*__fini)(void) = __do_fini; -#endif +# endif #elif defined(__i386__) || defined(__x86_64__) __asm__(".pushsection .fini,\"ax\",@progbits\n\t" "call __do_fini\n\t" diff --git a/compiler-rt/lib/fuzzer/FuzzerDriver.cpp b/compiler-rt/lib/fuzzer/FuzzerDriver.cpp index 40322e2..ad3a65a 100644 --- a/compiler-rt/lib/fuzzer/FuzzerDriver.cpp +++ b/compiler-rt/lib/fuzzer/FuzzerDriver.cpp @@ -834,6 +834,7 @@ int FuzzerDriver(int *argc, char ***argv, UserCallback Callback) { Options.HandleInt = Flags.handle_int; Options.HandleSegv = Flags.handle_segv; Options.HandleTerm = Flags.handle_term; + Options.HandleTrap = Flags.handle_trap; Options.HandleXfsz = Flags.handle_xfsz; Options.HandleUsr1 = Flags.handle_usr1; Options.HandleUsr2 = Flags.handle_usr2; diff --git a/compiler-rt/lib/fuzzer/FuzzerFlags.def b/compiler-rt/lib/fuzzer/FuzzerFlags.def index b88458a..96282b8 100644 --- a/compiler-rt/lib/fuzzer/FuzzerFlags.def +++ b/compiler-rt/lib/fuzzer/FuzzerFlags.def @@ -152,6 +152,7 @@ FUZZER_FLAG_INT(handle_ill, 1, "If 1, try to intercept SIGILL.") FUZZER_FLAG_INT(handle_fpe, 1, "If 1, try to intercept SIGFPE.") FUZZER_FLAG_INT(handle_int, 1, "If 1, try to intercept SIGINT.") FUZZER_FLAG_INT(handle_term, 1, "If 1, try to intercept SIGTERM.") +FUZZER_FLAG_INT(handle_trap, 1, "If 1, try to intercept SIGTRAP.") FUZZER_FLAG_INT(handle_xfsz, 1, "If 1, try to intercept SIGXFSZ.") FUZZER_FLAG_INT(handle_usr1, 1, "If 1, try to intercept SIGUSR1.") FUZZER_FLAG_INT(handle_usr2, 1, "If 1, try to intercept SIGUSR2.") diff --git a/compiler-rt/lib/fuzzer/FuzzerOptions.h b/compiler-rt/lib/fuzzer/FuzzerOptions.h index 72e2561..6478b63 100644 --- a/compiler-rt/lib/fuzzer/FuzzerOptions.h +++ b/compiler-rt/lib/fuzzer/FuzzerOptions.h @@ -82,6 +82,7 @@ struct FuzzingOptions { bool HandleInt = false; bool HandleSegv = false; bool HandleTerm = false; + bool HandleTrap = false; bool HandleXfsz = false; bool HandleUsr1 = false; bool HandleUsr2 = false; diff --git a/compiler-rt/lib/fuzzer/FuzzerUtilFuchsia.cpp b/compiler-rt/lib/fuzzer/FuzzerUtilFuchsia.cpp index 735d155..7f065c7 100644 --- a/compiler-rt/lib/fuzzer/FuzzerUtilFuchsia.cpp +++ b/compiler-rt/lib/fuzzer/FuzzerUtilFuchsia.cpp @@ -410,7 +410,7 @@ void SetSignalHandler(const FuzzingOptions &Options) { // Early exit if no crash handler needed. if (!Options.HandleSegv && !Options.HandleBus && !Options.HandleIll && - !Options.HandleFpe && !Options.HandleAbrt) + !Options.HandleFpe && !Options.HandleAbrt && !Options.HandleTrap) return; // Set up the crash handler and wait until it is ready before proceeding. diff --git a/compiler-rt/lib/fuzzer/FuzzerUtilPosix.cpp b/compiler-rt/lib/fuzzer/FuzzerUtilPosix.cpp index 392c1e5..ae22ecf 100644 --- a/compiler-rt/lib/fuzzer/FuzzerUtilPosix.cpp +++ b/compiler-rt/lib/fuzzer/FuzzerUtilPosix.cpp @@ -132,6 +132,8 @@ void SetSignalHandler(const FuzzingOptions& Options) { SetSigaction(SIGILL, CrashHandler); if (Options.HandleFpe) SetSigaction(SIGFPE, CrashHandler); + if (Options.HandleTrap) + SetSigaction(SIGTRAP, CrashHandler); if (Options.HandleXfsz) SetSigaction(SIGXFSZ, FileSizeExceedHandler); if (Options.HandleUsr1) diff --git a/compiler-rt/lib/hwasan/hwasan_thread.cpp b/compiler-rt/lib/hwasan/hwasan_thread.cpp index 8b32e4e..5c07522 100644 --- a/compiler-rt/lib/hwasan/hwasan_thread.cpp +++ b/compiler-rt/lib/hwasan/hwasan_thread.cpp @@ -174,7 +174,7 @@ static __hwasan::HwasanThreadList *GetHwasanThreadListLocked() { return &tl; } -static __hwasan::Thread *GetThreadByOsIDLocked(tid_t os_id) { +static __hwasan::Thread *GetThreadByOsIDLocked(ThreadID os_id) { return GetHwasanThreadListLocked()->FindThreadLocked( [os_id](__hwasan::Thread *t) { return t->os_id() == os_id; }); } @@ -191,7 +191,7 @@ void UnlockThreads() { void EnsureMainThreadIDIsCorrect() { __hwasan::EnsureMainThreadIDIsCorrect(); } -bool GetThreadRangesLocked(tid_t os_id, uptr *stack_begin, uptr *stack_end, +bool GetThreadRangesLocked(ThreadID os_id, uptr *stack_begin, uptr *stack_end, uptr *tls_begin, uptr *tls_end, uptr *cache_begin, uptr *cache_end, DTLS **dtls) { auto *t = GetThreadByOsIDLocked(os_id); @@ -210,7 +210,7 @@ bool GetThreadRangesLocked(tid_t os_id, uptr *stack_begin, uptr *stack_end, void GetAllThreadAllocatorCachesLocked(InternalMmapVector<uptr> *caches) {} -void GetThreadExtraStackRangesLocked(tid_t os_id, +void GetThreadExtraStackRangesLocked(ThreadID os_id, InternalMmapVector<Range> *ranges) {} void GetThreadExtraStackRangesLocked(InternalMmapVector<Range> *ranges) {} @@ -218,7 +218,7 @@ void GetAdditionalThreadContextPtrsLocked(InternalMmapVector<uptr> *ptrs) { __hwasan::hwasanThreadArgRetval().GetAllPtrsLocked(ptrs); } -void GetRunningThreadsLocked(InternalMmapVector<tid_t> *threads) { +void GetRunningThreadsLocked(InternalMmapVector<ThreadID> *threads) { // TODO: implement. } void PrintThreads() { diff --git a/compiler-rt/lib/hwasan/hwasan_thread.h b/compiler-rt/lib/hwasan/hwasan_thread.h index 9e1b438..62d6157 100644 --- a/compiler-rt/lib/hwasan/hwasan_thread.h +++ b/compiler-rt/lib/hwasan/hwasan_thread.h @@ -69,8 +69,8 @@ class Thread { Print("Thread: "); } - tid_t os_id() const { return os_id_; } - void set_os_id(tid_t os_id) { os_id_ = os_id; } + ThreadID os_id() const { return os_id_; } + void set_os_id(ThreadID os_id) { os_id_ = os_id; } uptr &vfork_spill() { return vfork_spill_; } @@ -96,7 +96,7 @@ class Thread { u32 unique_id_; // counting from zero. - tid_t os_id_; + ThreadID os_id_; u32 tagging_disabled_; // if non-zero, malloc uses zero tag in this thread. diff --git a/compiler-rt/lib/lsan/lsan_common.cpp b/compiler-rt/lib/lsan/lsan_common.cpp index b17a17e..d9afa45 100644 --- a/compiler-rt/lib/lsan/lsan_common.cpp +++ b/compiler-rt/lib/lsan/lsan_common.cpp @@ -412,7 +412,7 @@ void ScanExtraStackRanges(const InternalMmapVector<Range> &ranges, # if SANITIZER_FUCHSIA // Fuchsia handles all threads together with its own callback. -static void ProcessThreads(SuspendedThreadsList const &, Frontier *, tid_t, +static void ProcessThreads(SuspendedThreadsList const &, Frontier *, ThreadID, uptr) {} # else @@ -445,7 +445,7 @@ static void ProcessThreadRegistry(Frontier *frontier) { // Scans thread data (stacks and TLS) for heap pointers. template <class Accessor> -static void ProcessThread(tid_t os_id, uptr sp, +static void ProcessThread(ThreadID os_id, uptr sp, const InternalMmapVector<uptr> ®isters, InternalMmapVector<Range> &extra_ranges, Frontier *frontier, Accessor &accessor) { @@ -556,16 +556,16 @@ static void ProcessThread(tid_t os_id, uptr sp, } static void ProcessThreads(SuspendedThreadsList const &suspended_threads, - Frontier *frontier, tid_t caller_tid, + Frontier *frontier, ThreadID caller_tid, uptr caller_sp) { - InternalMmapVector<tid_t> done_threads; + InternalMmapVector<ThreadID> done_threads; InternalMmapVector<uptr> registers; InternalMmapVector<Range> extra_ranges; for (uptr i = 0; i < suspended_threads.ThreadCount(); i++) { registers.clear(); extra_ranges.clear(); - const tid_t os_id = suspended_threads.GetThreadID(i); + const ThreadID os_id = suspended_threads.GetThreadID(i); uptr sp = 0; PtraceRegistersStatus have_registers = suspended_threads.GetRegistersAndSP(i, ®isters, &sp); @@ -589,10 +589,10 @@ static void ProcessThreads(SuspendedThreadsList const &suspended_threads, if (flags()->use_detached) { CopyMemoryAccessor accessor; - InternalMmapVector<tid_t> known_threads; + InternalMmapVector<ThreadID> known_threads; GetRunningThreadsLocked(&known_threads); Sort(done_threads.data(), done_threads.size()); - for (tid_t os_id : known_threads) { + for (ThreadID os_id : known_threads) { registers.clear(); extra_ranges.clear(); @@ -712,7 +712,7 @@ static void CollectIgnoredCb(uptr chunk, void *arg) { // Sets the appropriate tag on each chunk. static void ClassifyAllChunks(SuspendedThreadsList const &suspended_threads, - Frontier *frontier, tid_t caller_tid, + Frontier *frontier, ThreadID caller_tid, uptr caller_sp) { const InternalMmapVector<u32> &suppressed_stacks = GetSuppressionContext()->GetSortedSuppressedStacks(); @@ -790,13 +790,13 @@ static bool ReportUnsuspendedThreads(const SuspendedThreadsList &) { static bool ReportUnsuspendedThreads( const SuspendedThreadsList &suspended_threads) { - InternalMmapVector<tid_t> threads(suspended_threads.ThreadCount()); + InternalMmapVector<ThreadID> threads(suspended_threads.ThreadCount()); for (uptr i = 0; i < suspended_threads.ThreadCount(); ++i) threads[i] = suspended_threads.GetThreadID(i); Sort(threads.data(), threads.size()); - InternalMmapVector<tid_t> known_threads; + InternalMmapVector<ThreadID> known_threads; GetRunningThreadsLocked(&known_threads); bool succeded = true; diff --git a/compiler-rt/lib/lsan/lsan_common.h b/compiler-rt/lib/lsan/lsan_common.h index f990c78..39530c2 100644 --- a/compiler-rt/lib/lsan/lsan_common.h +++ b/compiler-rt/lib/lsan/lsan_common.h @@ -102,15 +102,15 @@ void UnlockThreads() SANITIZER_NO_THREAD_SAFETY_ANALYSIS; // where leak checking is initiated from a non-main thread). void EnsureMainThreadIDIsCorrect(); -bool GetThreadRangesLocked(tid_t os_id, uptr *stack_begin, uptr *stack_end, +bool GetThreadRangesLocked(ThreadID os_id, uptr *stack_begin, uptr *stack_end, uptr *tls_begin, uptr *tls_end, uptr *cache_begin, uptr *cache_end, DTLS **dtls); void GetAllThreadAllocatorCachesLocked(InternalMmapVector<uptr> *caches); void GetThreadExtraStackRangesLocked(InternalMmapVector<Range> *ranges); -void GetThreadExtraStackRangesLocked(tid_t os_id, +void GetThreadExtraStackRangesLocked(ThreadID os_id, InternalMmapVector<Range> *ranges); void GetAdditionalThreadContextPtrsLocked(InternalMmapVector<uptr> *ptrs); -void GetRunningThreadsLocked(InternalMmapVector<tid_t> *threads); +void GetRunningThreadsLocked(InternalMmapVector<ThreadID> *threads); void PrintThreads(); //// -------------------------------------------------------------------------- @@ -247,7 +247,7 @@ void ProcessPlatformSpecificAllocations(Frontier *frontier); struct CheckForLeaksParam { Frontier frontier; LeakedChunks leaks; - tid_t caller_tid; + ThreadID caller_tid; uptr caller_sp; bool success = false; }; diff --git a/compiler-rt/lib/lsan/lsan_interceptors.cpp b/compiler-rt/lib/lsan/lsan_interceptors.cpp index f9f83f6..5340c6f 100644 --- a/compiler-rt/lib/lsan/lsan_interceptors.cpp +++ b/compiler-rt/lib/lsan/lsan_interceptors.cpp @@ -385,12 +385,12 @@ INTERCEPTOR(void, _lwp_exit) { #endif #if SANITIZER_INTERCEPT_THR_EXIT -INTERCEPTOR(void, thr_exit, tid_t *state) { +INTERCEPTOR(void, thr_exit, ThreadID *state) { ENSURE_LSAN_INITED; ThreadFinish(); REAL(thr_exit)(state); } -#define LSAN_MAYBE_INTERCEPT_THR_EXIT INTERCEPT_FUNCTION(thr_exit) +# define LSAN_MAYBE_INTERCEPT_THR_EXIT INTERCEPT_FUNCTION(thr_exit) #else #define LSAN_MAYBE_INTERCEPT_THR_EXIT #endif diff --git a/compiler-rt/lib/lsan/lsan_posix.cpp b/compiler-rt/lib/lsan/lsan_posix.cpp index 593000b..ae1590b 100644 --- a/compiler-rt/lib/lsan/lsan_posix.cpp +++ b/compiler-rt/lib/lsan/lsan_posix.cpp @@ -48,7 +48,7 @@ void ThreadContext::OnStarted(void *arg) { dtls_ = args->dtls; } -void ThreadStart(u32 tid, tid_t os_id, ThreadType thread_type) { +void ThreadStart(u32 tid, ThreadID os_id, ThreadType thread_type) { OnStartedArgs args; GetThreadStackAndTls(tid == kMainTid, &args.stack_begin, &args.stack_end, &args.tls_begin, &args.tls_end); @@ -57,7 +57,7 @@ void ThreadStart(u32 tid, tid_t os_id, ThreadType thread_type) { ThreadContextLsanBase::ThreadStart(tid, os_id, thread_type, &args); } -bool GetThreadRangesLocked(tid_t os_id, uptr *stack_begin, uptr *stack_end, +bool GetThreadRangesLocked(ThreadID os_id, uptr *stack_begin, uptr *stack_end, uptr *tls_begin, uptr *tls_end, uptr *cache_begin, uptr *cache_end, DTLS **dtls) { ThreadContext *context = static_cast<ThreadContext *>( diff --git a/compiler-rt/lib/lsan/lsan_posix.h b/compiler-rt/lib/lsan/lsan_posix.h index b1265f2..7587a07c 100644 --- a/compiler-rt/lib/lsan/lsan_posix.h +++ b/compiler-rt/lib/lsan/lsan_posix.h @@ -41,7 +41,7 @@ class ThreadContext final : public ThreadContextLsanBase { DTLS *dtls_ = nullptr; }; -void ThreadStart(u32 tid, tid_t os_id, +void ThreadStart(u32 tid, ThreadID os_id, ThreadType thread_type = ThreadType::Regular); } // namespace __lsan diff --git a/compiler-rt/lib/lsan/lsan_thread.cpp b/compiler-rt/lib/lsan/lsan_thread.cpp index b66ea61..22eb9ee 100644 --- a/compiler-rt/lib/lsan/lsan_thread.cpp +++ b/compiler-rt/lib/lsan/lsan_thread.cpp @@ -66,7 +66,7 @@ u32 ThreadCreate(u32 parent_tid, bool detached, void *arg) { return thread_registry->CreateThread(0, detached, parent_tid, arg); } -void ThreadContextLsanBase::ThreadStart(u32 tid, tid_t os_id, +void ThreadContextLsanBase::ThreadStart(u32 tid, ThreadID os_id, ThreadType thread_type, void *arg) { thread_registry->StartThread(tid, os_id, thread_type, arg); } @@ -80,7 +80,7 @@ void EnsureMainThreadIDIsCorrect() { ///// Interface to the common LSan module. ///// -void GetThreadExtraStackRangesLocked(tid_t os_id, +void GetThreadExtraStackRangesLocked(ThreadID os_id, InternalMmapVector<Range> *ranges) {} void GetThreadExtraStackRangesLocked(InternalMmapVector<Range> *ranges) {} @@ -99,11 +99,11 @@ ThreadRegistry *GetLsanThreadRegistryLocked() { return thread_registry; } -void GetRunningThreadsLocked(InternalMmapVector<tid_t> *threads) { +void GetRunningThreadsLocked(InternalMmapVector<ThreadID> *threads) { GetLsanThreadRegistryLocked()->RunCallbackForEachThreadLocked( [](ThreadContextBase *tctx, void *threads) { if (tctx->status == ThreadStatusRunning) { - reinterpret_cast<InternalMmapVector<tid_t> *>(threads)->push_back( + reinterpret_cast<InternalMmapVector<ThreadID> *>(threads)->push_back( tctx->os_id); } }, diff --git a/compiler-rt/lib/lsan/lsan_thread.h b/compiler-rt/lib/lsan/lsan_thread.h index 222066e..b7262a9e 100644 --- a/compiler-rt/lib/lsan/lsan_thread.h +++ b/compiler-rt/lib/lsan/lsan_thread.h @@ -30,7 +30,7 @@ class ThreadContextLsanBase : public ThreadContextBase { uptr cache_end() { return cache_end_; } // The argument is passed on to the subclass's OnStarted member function. - static void ThreadStart(u32 tid, tid_t os_id, ThreadType thread_type, + static void ThreadStart(u32 tid, ThreadID os_id, ThreadType thread_type, void *onstarted_arg); protected: diff --git a/compiler-rt/lib/memprof/memprof_thread.cpp b/compiler-rt/lib/memprof/memprof_thread.cpp index 4b9665f..11cc481 100644 --- a/compiler-rt/lib/memprof/memprof_thread.cpp +++ b/compiler-rt/lib/memprof/memprof_thread.cpp @@ -131,7 +131,7 @@ void MemprofThread::Init(const InitOptions *options) { } thread_return_t -MemprofThread::ThreadStart(tid_t os_id, +MemprofThread::ThreadStart(ThreadID os_id, atomic_uintptr_t *signal_thread_is_registered) { Init(); memprofThreadRegistry().StartThread(tid(), os_id, ThreadType::Regular, diff --git a/compiler-rt/lib/memprof/memprof_thread.h b/compiler-rt/lib/memprof/memprof_thread.h index fb90dbf..c7009c30 100644 --- a/compiler-rt/lib/memprof/memprof_thread.h +++ b/compiler-rt/lib/memprof/memprof_thread.h @@ -59,7 +59,7 @@ public: struct InitOptions; void Init(const InitOptions *options = nullptr); - thread_return_t ThreadStart(tid_t os_id, + thread_return_t ThreadStart(ThreadID os_id, atomic_uintptr_t *signal_thread_is_registered); uptr stack_top(); diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common.h b/compiler-rt/lib/sanitizer_common/sanitizer_common.h index 120c286..3e82df4 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_common.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common.h @@ -78,8 +78,8 @@ uptr GetMmapGranularity(); uptr GetMaxVirtualAddress(); uptr GetMaxUserVirtualAddress(); // Threads -tid_t GetTid(); -int TgKill(pid_t pid, tid_t tid, int sig); +ThreadID GetTid(); +int TgKill(pid_t pid, ThreadID tid, int sig); uptr GetThreadSelf(); void GetThreadStackTopAndBottom(bool at_initialization, uptr *stack_top, uptr *stack_bottom); diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_ioctl.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_ioctl.inc index 08c2be4..673f284 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_ioctl.inc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_ioctl.inc @@ -344,12 +344,16 @@ static void ioctl_table_fill() { _(SOUND_PCM_WRITE_CHANNELS, WRITE, sizeof(int)); _(SOUND_PCM_WRITE_FILTER, WRITE, sizeof(int)); _(TCFLSH, NONE, 0); +# if SANITIZER_TERMIOS_IOCTL_CONSTANTS _(TCGETS, WRITE, struct_termios_sz); +# endif _(TCSBRK, NONE, 0); _(TCSBRKP, NONE, 0); +# if SANITIZER_TERMIOS_IOCTL_CONSTANTS _(TCSETS, READ, struct_termios_sz); _(TCSETSF, READ, struct_termios_sz); _(TCSETSW, READ, struct_termios_sz); +# endif _(TCXONC, NONE, 0); _(TIOCGLCKTRMIOS, WRITE, struct_termios_sz); _(TIOCGSOFTCAR, WRITE, sizeof(int)); diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_fuchsia.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_fuchsia.cpp index 1ca50eb..625f30c 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_fuchsia.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_fuchsia.cpp @@ -68,7 +68,7 @@ int internal_dlinfo(void *handle, int request, void *p) { UNIMPLEMENTED(); } uptr GetThreadSelf() { return reinterpret_cast<uptr>(thrd_current()); } -tid_t GetTid() { return GetThreadSelf(); } +ThreadID GetTid() { return GetThreadSelf(); } void Abort() { abort(); } diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_haiku.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_haiku.cpp index 7cf2437..7c11441 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_haiku.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_haiku.cpp @@ -231,12 +231,12 @@ uptr internal_execve(const char *filename, char *const argv[], } # if 0 -tid_t GetTid() { +ThreadID GetTid() { DEFINE__REAL(int, _lwp_self); return _REAL(_lwp_self); } -int TgKill(pid_t pid, tid_t tid, int sig) { +int TgKill(pid_t pid, ThreadID tid, int sig) { DEFINE__REAL(int, _lwp_kill, int a, int b); (void)pid; return _REAL(_lwp_kill, tid, sig); diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_internal_defs.h b/compiler-rt/lib/sanitizer_common/sanitizer_internal_defs.h index fff60c9..c719e2a 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_internal_defs.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_internal_defs.h @@ -209,7 +209,7 @@ typedef long ssize; typedef sptr ssize; #endif -typedef u64 tid_t; +typedef u64 ThreadID; // ----------- ATTENTION ------------- // This header should NOT include any other headers to avoid portability issues. diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp index 16caf699..87a18b1 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp @@ -638,7 +638,7 @@ bool DirExists(const char *path) { } # if !SANITIZER_NETBSD -tid_t GetTid() { +ThreadID GetTid() { # if SANITIZER_FREEBSD long Tid; thr_self(&Tid); @@ -652,7 +652,7 @@ tid_t GetTid() { # endif } -int TgKill(pid_t pid, tid_t tid, int sig) { +int TgKill(pid_t pid, ThreadID tid, int sig) { # if SANITIZER_LINUX return internal_syscall(SYSCALL(tgkill), pid, tid, sig); # elif SANITIZER_FREEBSD @@ -1089,7 +1089,7 @@ ThreadLister::ThreadLister(pid_t pid) : buffer_(4096) { } ThreadLister::Result ThreadLister::ListThreads( - InternalMmapVector<tid_t> *threads) { + InternalMmapVector<ThreadID> *threads) { int descriptor = internal_open(task_path_.data(), O_RDONLY | O_DIRECTORY); if (internal_iserror(descriptor)) { Report("Can't open %s for reading.\n", task_path_.data()); @@ -1144,7 +1144,7 @@ ThreadLister::Result ThreadLister::ListThreads( } } -const char *ThreadLister::LoadStatus(tid_t tid) { +const char *ThreadLister::LoadStatus(ThreadID tid) { status_path_.clear(); status_path_.AppendF("%s/%llu/status", task_path_.data(), tid); auto cleanup = at_scope_exit([&] { @@ -1157,7 +1157,7 @@ const char *ThreadLister::LoadStatus(tid_t tid) { return buffer_.data(); } -bool ThreadLister::IsAlive(tid_t tid) { +bool ThreadLister::IsAlive(ThreadID tid) { // /proc/%d/task/%d/status uses same call to detect alive threads as // proc_task_readdir. See task_state implementation in Linux. static const char kPrefix[] = "\nPPid:"; diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux.h b/compiler-rt/lib/sanitizer_common/sanitizer_linux.h index 05b7d2e..e621799 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_linux.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux.h @@ -108,11 +108,11 @@ class ThreadLister { Incomplete, Ok, }; - Result ListThreads(InternalMmapVector<tid_t> *threads); - const char *LoadStatus(tid_t tid); + Result ListThreads(InternalMmapVector<ThreadID> *threads); + const char *LoadStatus(ThreadID tid); private: - bool IsAlive(tid_t tid); + bool IsAlive(ThreadID tid); InternalScopedString task_path_; InternalScopedString status_path_; diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp index bb71af5..3bc24152 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp @@ -394,8 +394,8 @@ bool DirExists(const char *path) { return S_ISDIR(st.st_mode); } -tid_t GetTid() { - tid_t tid; +ThreadID GetTid() { + ThreadID tid; pthread_threadid_np(nullptr, &tid); return tid; } diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_netbsd.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_netbsd.cpp index 5e601bd..737e336 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_netbsd.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_netbsd.cpp @@ -229,12 +229,12 @@ uptr internal_execve(const char *filename, char *const argv[], return _sys_execve(filename, argv, envp); } -tid_t GetTid() { +ThreadID GetTid() { DEFINE__REAL(int, _lwp_self); return _REAL(_lwp_self); } -int TgKill(pid_t pid, tid_t tid, int sig) { +int TgKill(pid_t pid, ThreadID tid, int sig) { DEFINE__REAL(int, _lwp_kill, int a, int b); (void)pid; return _REAL(_lwp_kill, tid, sig); diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform.h index 196c0a9..13099fe 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform.h @@ -482,4 +482,19 @@ # define SANITIZER_START_BACKGROUND_THREAD_IN_ASAN_INTERNAL 0 #endif +#if SANITIZER_LINUX +# if SANITIZER_GLIBC +// Workaround for +// glibc/commit/3d3572f59059e2b19b8541ea648a6172136ec42e +// Linux: Keep termios ioctl constants strictly internal +# if __GLIBC_PREREQ(2, 41) +# define SANITIZER_TERMIOS_IOCTL_CONSTANTS 0 +# else +# define SANITIZER_TERMIOS_IOCTL_CONSTANTS 1 +# endif +# else +# define SANITIZER_TERMIOS_IOCTL_CONSTANTS 1 +# endif +#endif + #endif // SANITIZER_PLATFORM_H diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp index 7a89bf1..ea8cc30 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp @@ -779,16 +779,16 @@ unsigned struct_ElfW_Phdr_sz = sizeof(Elf_Phdr); unsigned IOCTL_SOUND_PCM_WRITE_FILTER = SOUND_PCM_WRITE_FILTER; #endif // SOUND_VERSION unsigned IOCTL_TCFLSH = TCFLSH; - unsigned IOCTL_TCGETA = TCGETA; +# if SANITIZER_TERMIOS_IOCTL_CONSTANTS unsigned IOCTL_TCGETS = TCGETS; +# endif unsigned IOCTL_TCSBRK = TCSBRK; unsigned IOCTL_TCSBRKP = TCSBRKP; - unsigned IOCTL_TCSETA = TCSETA; - unsigned IOCTL_TCSETAF = TCSETAF; - unsigned IOCTL_TCSETAW = TCSETAW; +# if SANITIZER_TERMIOS_IOCTL_CONSTANTS unsigned IOCTL_TCSETS = TCSETS; unsigned IOCTL_TCSETSF = TCSETSF; unsigned IOCTL_TCSETSW = TCSETSW; +# endif unsigned IOCTL_TCXONC = TCXONC; unsigned IOCTL_TIOCGLCKTRMIOS = TIOCGLCKTRMIOS; unsigned IOCTL_TIOCGSOFTCAR = TIOCGSOFTCAR; diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h index 0d12738..2496652 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h @@ -478,6 +478,30 @@ struct __sanitizer_cmsghdr { int cmsg_level; int cmsg_type; }; +# elif SANITIZER_MUSL +struct __sanitizer_msghdr { + void *msg_name; + unsigned msg_namelen; + struct __sanitizer_iovec *msg_iov; + int msg_iovlen; +# if SANITIZER_WORDSIZE == 64 + int __pad1; +# endif + void *msg_control; + unsigned msg_controllen; +# if SANITIZER_WORDSIZE == 64 + int __pad2; +# endif + int msg_flags; +}; +struct __sanitizer_cmsghdr { + unsigned cmsg_len; +# if SANITIZER_WORDSIZE == 64 + int __pad1; +# endif + int cmsg_level; + int cmsg_type; +}; # else // In POSIX, int msg_iovlen; socklen_t msg_controllen; socklen_t cmsg_len; but // many implementations don't conform to the standard. @@ -1314,16 +1338,14 @@ extern unsigned IOCTL_SNDCTL_COPR_SENDMSG; extern unsigned IOCTL_SNDCTL_COPR_WCODE; extern unsigned IOCTL_SNDCTL_COPR_WDATA; extern unsigned IOCTL_TCFLSH; -extern unsigned IOCTL_TCGETA; -extern unsigned IOCTL_TCGETS; extern unsigned IOCTL_TCSBRK; extern unsigned IOCTL_TCSBRKP; -extern unsigned IOCTL_TCSETA; -extern unsigned IOCTL_TCSETAF; -extern unsigned IOCTL_TCSETAW; +# if SANITIZER_TERMIOS_IOCTL_CONSTANTS +extern unsigned IOCTL_TCGETS; extern unsigned IOCTL_TCSETS; extern unsigned IOCTL_TCSETSF; extern unsigned IOCTL_TCSETSW; +# endif extern unsigned IOCTL_TCXONC; extern unsigned IOCTL_TIOCGLCKTRMIOS; extern unsigned IOCTL_TIOCGSOFTCAR; diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld.h b/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld.h index 7891c10..b4ed23a 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld.h @@ -38,7 +38,7 @@ class SuspendedThreadsList { } virtual uptr ThreadCount() const { UNIMPLEMENTED(); } - virtual tid_t GetThreadID(uptr index) const { UNIMPLEMENTED(); } + virtual ThreadID GetThreadID(uptr index) const { UNIMPLEMENTED(); } protected: ~SuspendedThreadsList() {} diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cpp index 24929b8..d119b7a 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cpp @@ -94,17 +94,17 @@ class SuspendedThreadsListLinux final : public SuspendedThreadsList { public: SuspendedThreadsListLinux() { thread_ids_.reserve(1024); } - tid_t GetThreadID(uptr index) const override; + ThreadID GetThreadID(uptr index) const override; uptr ThreadCount() const override; - bool ContainsTid(tid_t thread_id) const; - void Append(tid_t tid); + bool ContainsTid(ThreadID thread_id) const; + void Append(ThreadID tid); PtraceRegistersStatus GetRegistersAndSP(uptr index, InternalMmapVector<uptr> *buffer, uptr *sp) const override; private: - InternalMmapVector<tid_t> thread_ids_; + InternalMmapVector<ThreadID> thread_ids_; }; // Structure for passing arguments into the tracer thread. @@ -137,10 +137,10 @@ class ThreadSuspender { private: SuspendedThreadsListLinux suspended_threads_list_; pid_t pid_; - bool SuspendThread(tid_t thread_id); + bool SuspendThread(ThreadID thread_id); }; -bool ThreadSuspender::SuspendThread(tid_t tid) { +bool ThreadSuspender::SuspendThread(ThreadID tid) { int pterrno; if (internal_iserror(internal_ptrace(PTRACE_ATTACH, tid, nullptr, nullptr), &pterrno)) { @@ -210,7 +210,7 @@ void ThreadSuspender::KillAllThreads() { bool ThreadSuspender::SuspendAllThreads() { ThreadLister thread_lister(pid_); bool retry = true; - InternalMmapVector<tid_t> threads; + InternalMmapVector<ThreadID> threads; threads.reserve(128); for (int i = 0; i < 30 && retry; ++i) { retry = false; @@ -226,7 +226,7 @@ bool ThreadSuspender::SuspendAllThreads() { case ThreadLister::Ok: break; } - for (tid_t tid : threads) { + for (ThreadID tid : threads) { // Are we already attached to this thread? // Currently this check takes linear time, however the number of threads // is usually small. @@ -546,7 +546,7 @@ static constexpr uptr kExtraRegs[] = {0}; #error "Unsupported architecture" #endif // SANITIZER_ANDROID && defined(__arm__) -tid_t SuspendedThreadsListLinux::GetThreadID(uptr index) const { +ThreadID SuspendedThreadsListLinux::GetThreadID(uptr index) const { CHECK_LT(index, thread_ids_.size()); return thread_ids_[index]; } @@ -555,14 +555,14 @@ uptr SuspendedThreadsListLinux::ThreadCount() const { return thread_ids_.size(); } -bool SuspendedThreadsListLinux::ContainsTid(tid_t thread_id) const { +bool SuspendedThreadsListLinux::ContainsTid(ThreadID thread_id) const { for (uptr i = 0; i < thread_ids_.size(); i++) { if (thread_ids_[i] == thread_id) return true; } return false; } -void SuspendedThreadsListLinux::Append(tid_t tid) { +void SuspendedThreadsListLinux::Append(ThreadID tid) { thread_ids_.push_back(tid); } diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_mac.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_mac.cpp index 8136164..d6ef37a 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_mac.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_mac.cpp @@ -23,7 +23,7 @@ namespace __sanitizer { typedef struct { - tid_t tid; + ThreadID tid; thread_t thread; } SuspendedThreadInfo; @@ -31,7 +31,7 @@ class SuspendedThreadsListMac final : public SuspendedThreadsList { public: SuspendedThreadsListMac() = default; - tid_t GetThreadID(uptr index) const override; + ThreadID GetThreadID(uptr index) const override; thread_t GetThread(uptr index) const; uptr ThreadCount() const override; bool ContainsThread(thread_t thread) const; @@ -111,7 +111,7 @@ typedef x86_thread_state32_t regs_struct; #error "Unsupported architecture" #endif -tid_t SuspendedThreadsListMac::GetThreadID(uptr index) const { +ThreadID SuspendedThreadsListMac::GetThreadID(uptr index) const { CHECK_LT(index, threads_.size()); return threads_[index].tid; } diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_netbsd_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_netbsd_libcdep.cpp index 58a0cfd..33d603f 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_netbsd_libcdep.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_netbsd_libcdep.cpp @@ -52,17 +52,17 @@ class SuspendedThreadsListNetBSD final : public SuspendedThreadsList { public: SuspendedThreadsListNetBSD() { thread_ids_.reserve(1024); } - tid_t GetThreadID(uptr index) const; + ThreadID GetThreadID(uptr index) const; uptr ThreadCount() const; - bool ContainsTid(tid_t thread_id) const; - void Append(tid_t tid); + bool ContainsTid(ThreadID thread_id) const; + void Append(ThreadID tid); PtraceRegistersStatus GetRegistersAndSP(uptr index, InternalMmapVector<uptr> *buffer, uptr *sp) const; private: - InternalMmapVector<tid_t> thread_ids_; + InternalMmapVector<ThreadID> thread_ids_; }; struct TracerThreadArgument { @@ -313,7 +313,7 @@ void StopTheWorld(StopTheWorldCallback callback, void *argument) { } } -tid_t SuspendedThreadsListNetBSD::GetThreadID(uptr index) const { +ThreadID SuspendedThreadsListNetBSD::GetThreadID(uptr index) const { CHECK_LT(index, thread_ids_.size()); return thread_ids_[index]; } @@ -322,7 +322,7 @@ uptr SuspendedThreadsListNetBSD::ThreadCount() const { return thread_ids_.size(); } -bool SuspendedThreadsListNetBSD::ContainsTid(tid_t thread_id) const { +bool SuspendedThreadsListNetBSD::ContainsTid(ThreadID thread_id) const { for (uptr i = 0; i < thread_ids_.size(); i++) { if (thread_ids_[i] == thread_id) return true; @@ -330,7 +330,7 @@ bool SuspendedThreadsListNetBSD::ContainsTid(tid_t thread_id) const { return false; } -void SuspendedThreadsListNetBSD::Append(tid_t tid) { +void SuspendedThreadsListNetBSD::Append(ThreadID tid) { thread_ids_.push_back(tid); } diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_win.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_win.cpp index fa15f8a..43df595 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_win.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_stoptheworld_win.cpp @@ -38,7 +38,7 @@ struct SuspendedThreadsListWindows final : public SuspendedThreadsList { InternalMmapVector<uptr> *buffer, uptr *sp) const override; - tid_t GetThreadID(uptr index) const override; + ThreadID GetThreadID(uptr index) const override; uptr ThreadCount() const override; }; @@ -68,7 +68,7 @@ PtraceRegistersStatus SuspendedThreadsListWindows::GetRegistersAndSP( return REGISTERS_AVAILABLE; } -tid_t SuspendedThreadsListWindows::GetThreadID(uptr index) const { +ThreadID SuspendedThreadsListWindows::GetThreadID(uptr index) const { CHECK_LT(index, threadIds.size()); return threadIds[index]; } diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_thread_registry.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_thread_registry.cpp index cdc24f4..d726d28 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_thread_registry.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_thread_registry.cpp @@ -80,7 +80,7 @@ void ThreadContextBase::SetFinished() { OnFinished(); } -void ThreadContextBase::SetStarted(tid_t _os_id, ThreadType _thread_type, +void ThreadContextBase::SetStarted(ThreadID _os_id, ThreadType _thread_type, void *arg) { status = ThreadStatusRunning; os_id = _os_id; @@ -228,7 +228,8 @@ static bool FindThreadContextByOsIdCallback(ThreadContextBase *tctx, tctx->status != ThreadStatusDead); } -ThreadContextBase *ThreadRegistry::FindThreadContextByOsIDLocked(tid_t os_id) { +ThreadContextBase *ThreadRegistry::FindThreadContextByOsIDLocked( + ThreadID os_id) { return FindThreadContextLocked(FindThreadContextByOsIdCallback, (void *)os_id); } @@ -322,8 +323,8 @@ ThreadStatus ThreadRegistry::FinishThread(u32 tid) { return prev_status; } -void ThreadRegistry::StartThread(u32 tid, tid_t os_id, ThreadType thread_type, - void *arg) { +void ThreadRegistry::StartThread(u32 tid, ThreadID os_id, + ThreadType thread_type, void *arg) { ThreadRegistryLock l(this); running_threads_++; ThreadContextBase *tctx = threads_[tid]; diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_thread_registry.h b/compiler-rt/lib/sanitizer_common/sanitizer_thread_registry.h index e06abb3..8adc420 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_thread_registry.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_thread_registry.h @@ -43,7 +43,7 @@ class ThreadContextBase { const u32 tid; // Thread ID. Main thread should have tid = 0. u64 unique_id; // Unique thread ID. u32 reuse_count; // Number of times this tid was reused. - tid_t os_id; // PID (used for reporting). + ThreadID os_id; // PID (used for reporting). uptr user_id; // Some opaque user thread id (e.g. pthread_t). char name[64]; // As annotated by user. @@ -62,7 +62,7 @@ class ThreadContextBase { void SetDead(); void SetJoined(void *arg); void SetFinished(); - void SetStarted(tid_t _os_id, ThreadType _thread_type, void *arg); + void SetStarted(ThreadID _os_id, ThreadType _thread_type, void *arg); void SetCreated(uptr _user_id, u64 _unique_id, bool _detached, u32 _parent_tid, u32 _stack_tid, void *arg); void Reset(); @@ -126,7 +126,7 @@ class SANITIZER_MUTEX ThreadRegistry { // is found. ThreadContextBase *FindThreadContextLocked(FindThreadCallback cb, void *arg); - ThreadContextBase *FindThreadContextByOsIDLocked(tid_t os_id); + ThreadContextBase *FindThreadContextByOsIDLocked(ThreadID os_id); void SetThreadName(u32 tid, const char *name); void SetThreadNameByUserId(uptr user_id, const char *name); @@ -134,7 +134,7 @@ class SANITIZER_MUTEX ThreadRegistry { void JoinThread(u32 tid, void *arg); // Finishes thread and returns previous status. ThreadStatus FinishThread(u32 tid); - void StartThread(u32 tid, tid_t os_id, ThreadType thread_type, void *arg); + void StartThread(u32 tid, ThreadID os_id, ThreadType thread_type, void *arg); u32 ConsumeThreadUserId(uptr user_id); void SetThreadUserId(u32 tid, uptr user_id); diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_win.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_win.cpp index 48ebe78..ed4f60d 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_win.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_win.cpp @@ -108,9 +108,7 @@ int internal_dlinfo(void *handle, int request, void *p) { // In contrast to POSIX, on Windows GetCurrentThreadId() // returns a system-unique identifier. -tid_t GetTid() { - return GetCurrentThreadId(); -} +ThreadID GetTid() { return GetCurrentThreadId(); } uptr GetThreadSelf() { return GetTid(); diff --git a/compiler-rt/lib/sanitizer_common/symbolizer/scripts/build_symbolizer.sh b/compiler-rt/lib/sanitizer_common/symbolizer/scripts/build_symbolizer.sh index 4d43597..567402e 100755 --- a/compiler-rt/lib/sanitizer_common/symbolizer/scripts/build_symbolizer.sh +++ b/compiler-rt/lib/sanitizer_common/symbolizer/scripts/build_symbolizer.sh @@ -87,7 +87,7 @@ AR="${AR}" CC="${CC}" CFLAGS="$FLAGS -Wno-deprecated-non-prototype" RANLIB=/bin/ make -j libz.a # Build and install libcxxabi and libcxx. -if [[ ! -f ${LLVM_BUILD}/build.ninja ]]; then +if [[ ! -f ${LIBCXX_BUILD}/build.ninja ]]; then rm -rf "${LIBCXX_BUILD}" "${LIBCXX_INSTALL}" mkdir -p ${LIBCXX_BUILD} ${LIBCXX_INSTALL} cd ${LIBCXX_BUILD} @@ -120,7 +120,7 @@ ninja cxx cxxabi && ninja install-cxx install-cxxabi FLAGS="${FLAGS} -fno-rtti -fno-exceptions" LLVM_CFLAGS="${FLAGS} -Wno-global-constructors" -LLVM_CXXFLAGS="${LLVM_CFLAGS} -nostdinc++ -I${ZLIB_BUILD} -isystem ${LIBCXX_INSTALL}/include -isystem ${LIBCXX_INSTALL}/include/c++/v1" +LLVM_CXXFLAGS="-isystem ${LIBCXX_INSTALL}/include -isystem ${LIBCXX_INSTALL}/include/c++/v1 ${LLVM_CFLAGS} -nostdinc++ -I${ZLIB_BUILD}" # Build LLVM. if [[ ! -f ${LLVM_BUILD}/build.ninja ]]; then diff --git a/compiler-rt/lib/sanitizer_common/tests/sanitizer_linux_test.cpp b/compiler-rt/lib/sanitizer_common/tests/sanitizer_linux_test.cpp index 70669ab..bcfa31d 100644 --- a/compiler-rt/lib/sanitizer_common/tests/sanitizer_linux_test.cpp +++ b/compiler-rt/lib/sanitizer_common/tests/sanitizer_linux_test.cpp @@ -43,7 +43,7 @@ struct TidReporterArgument { pthread_cond_destroy(&tid_reported_cond); } - tid_t reported_tid; + ThreadID reported_tid; // For signaling to spawned threads that they should terminate. pthread_cond_t terminate_thread_cond; pthread_mutex_t terminate_thread_mutex; @@ -62,7 +62,7 @@ class ThreadListerTest : public ::testing::Test { protected: virtual void SetUp() { pthread_t pthread_id; - tid_t tid; + ThreadID tid; for (uptr i = 0; i < kThreadCount; i++) { SpawnTidReporter(&pthread_id, &tid); pthread_ids_.push_back(pthread_id); @@ -79,12 +79,12 @@ class ThreadListerTest : public ::testing::Test { pthread_join(pthread_ids_[i], NULL); } - void SpawnTidReporter(pthread_t *pthread_id, tid_t *tid); + void SpawnTidReporter(pthread_t *pthread_id, ThreadID *tid); static const uptr kThreadCount = 20; std::vector<pthread_t> pthread_ids_; - std::vector<tid_t> tids_; + std::vector<ThreadID> tids_; TidReporterArgument thread_arg; }; @@ -105,42 +105,43 @@ void *TidReporterThread(void *argument) { return NULL; } -void ThreadListerTest::SpawnTidReporter(pthread_t *pthread_id, tid_t *tid) { +void ThreadListerTest::SpawnTidReporter(pthread_t *pthread_id, ThreadID *tid) { pthread_mutex_lock(&thread_arg.tid_reported_mutex); thread_arg.reported_tid = -1; ASSERT_EQ(0, pthread_create(pthread_id, NULL, TidReporterThread, &thread_arg)); - while (thread_arg.reported_tid == (tid_t)(-1)) + while (thread_arg.reported_tid == (ThreadID)(-1)) pthread_cond_wait(&thread_arg.tid_reported_cond, &thread_arg.tid_reported_mutex); pthread_mutex_unlock(&thread_arg.tid_reported_mutex); *tid = thread_arg.reported_tid; } -static std::vector<tid_t> ReadTidsToVector(ThreadLister *thread_lister) { - std::vector<tid_t> listed_tids; - InternalMmapVector<tid_t> threads(128); +static std::vector<ThreadID> ReadTidsToVector(ThreadLister *thread_lister) { + std::vector<ThreadID> listed_tids; + InternalMmapVector<ThreadID> threads(128); EXPECT_TRUE(thread_lister->ListThreads(&threads)); - return std::vector<tid_t>(threads.begin(), threads.end()); + return std::vector<ThreadID>(threads.begin(), threads.end()); } -static bool Includes(std::vector<tid_t> first, std::vector<tid_t> second) { +static bool Includes(std::vector<ThreadID> first, + std::vector<ThreadID> second) { std::sort(first.begin(), first.end()); std::sort(second.begin(), second.end()); return std::includes(first.begin(), first.end(), second.begin(), second.end()); } -static bool HasElement(const std::vector<tid_t> &vector, tid_t element) { +static bool HasElement(const std::vector<ThreadID> &vector, ThreadID element) { return std::find(vector.begin(), vector.end(), element) != vector.end(); } // ThreadLister's output should include the current thread's TID and the TID of // every thread we spawned. TEST_F(ThreadListerTest, ThreadListerSeesAllSpawnedThreads) { - tid_t self_tid = GetTid(); + ThreadID self_tid = GetTid(); ThreadLister thread_lister(getpid()); - std::vector<tid_t> listed_tids = ReadTidsToVector(&thread_lister); + std::vector<ThreadID> listed_tids = ReadTidsToVector(&thread_lister); ASSERT_TRUE(HasElement(listed_tids, self_tid)); ASSERT_TRUE(Includes(listed_tids, tids_)); @@ -154,7 +155,7 @@ TEST_F(ThreadListerTest, DoNotForgetThreads) { // Run the loop body twice, because ThreadLister might behave differently if // called on a freshly created object. for (uptr i = 0; i < 2; i++) { - std::vector<tid_t> listed_tids = ReadTidsToVector(&thread_lister); + std::vector<ThreadID> listed_tids = ReadTidsToVector(&thread_lister); ASSERT_TRUE(Includes(listed_tids, tids_)); } } @@ -163,10 +164,10 @@ TEST_F(ThreadListerTest, DoNotForgetThreads) { // relisting should cause ThreadLister to recognize their existence. TEST_F(ThreadListerTest, NewThreads) { ThreadLister thread_lister(getpid()); - std::vector<tid_t> threads_before_extra = ReadTidsToVector(&thread_lister); + std::vector<ThreadID> threads_before_extra = ReadTidsToVector(&thread_lister); pthread_t extra_pthread_id; - tid_t extra_tid; + ThreadID extra_tid; SpawnTidReporter(&extra_pthread_id, &extra_tid); // Register the new thread so it gets terminated in TearDown(). pthread_ids_.push_back(extra_pthread_id); @@ -176,7 +177,7 @@ TEST_F(ThreadListerTest, NewThreads) { // so better check for that. ASSERT_FALSE(HasElement(threads_before_extra, extra_tid)); - std::vector<tid_t> threads_after_extra = ReadTidsToVector(&thread_lister); + std::vector<ThreadID> threads_after_extra = ReadTidsToVector(&thread_lister); ASSERT_TRUE(HasElement(threads_after_extra, extra_tid)); } diff --git a/compiler-rt/lib/scudo/standalone/secondary.h b/compiler-rt/lib/scudo/standalone/secondary.h index 286e5d3..f04c5b7 100644 --- a/compiler-rt/lib/scudo/standalone/secondary.h +++ b/compiler-rt/lib/scudo/standalone/secondary.h @@ -269,7 +269,8 @@ public: Entry.MemMap = MemMap; Entry.Time = UINT64_MAX; - if (useMemoryTagging<Config>(Options)) { + bool MemoryTaggingEnabled = useMemoryTagging<Config>(Options); + if (MemoryTaggingEnabled) { if (Interval == 0 && !SCUDO_FUCHSIA) { // Release the memory and make it inaccessible at the same time by // creating a new MAP_NOACCESS mapping on top of the existing mapping. @@ -302,7 +303,7 @@ public: if (Entry.Time != 0) Entry.Time = Time; - if (useMemoryTagging<Config>(Options) && QuarantinePos == -1U) { + if (MemoryTaggingEnabled && !useMemoryTagging<Config>(Options)) { // If we get here then memory tagging was disabled in between when we // read Options and when we locked Mutex. We can't insert our entry into // the quarantine or the cache because the permissions would be wrong so @@ -310,7 +311,8 @@ public: unmapCallBack(Entry.MemMap); break; } - if (Config::getQuarantineSize() && useMemoryTagging<Config>(Options)) { + + if (Config::getQuarantineSize()) { QuarantinePos = (QuarantinePos + 1) % Max(Config::getQuarantineSize(), 1u); if (!Quarantine[QuarantinePos].isValid()) { @@ -513,9 +515,10 @@ public: Quarantine[I].invalidate(); } } + QuarantinePos = -1U; + for (CachedBlock &Entry : LRUEntries) Entry.MemMap.setMemoryPermission(Entry.CommitBase, Entry.CommitSize, 0); - QuarantinePos = -1U; } void disable() NO_THREAD_SAFETY_ANALYSIS { Mutex.lock(); } diff --git a/compiler-rt/lib/scudo/standalone/tests/wrappers_c_test.cpp b/compiler-rt/lib/scudo/standalone/tests/wrappers_c_test.cpp index 0506544..612317b 100644 --- a/compiler-rt/lib/scudo/standalone/tests/wrappers_c_test.cpp +++ b/compiler-rt/lib/scudo/standalone/tests/wrappers_c_test.cpp @@ -183,7 +183,8 @@ TEST_F(ScudoWrappersCDeathTest, Malloc) { // process doing free(P) is not a double free. EXPECT_DEATH( { - void *Ptr = malloc(Size); + // Note: volatile here prevents the calls from being optimized out. + void *volatile Ptr = malloc(Size); free(Ptr); free(Ptr); }, diff --git a/compiler-rt/lib/tsan/rtl/tsan_debugging.cpp b/compiler-rt/lib/tsan/rtl/tsan_debugging.cpp index 41fa293..b3422af 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_debugging.cpp +++ b/compiler-rt/lib/tsan/rtl/tsan_debugging.cpp @@ -165,7 +165,7 @@ int __tsan_get_report_mutex(void *report, uptr idx, uptr *mutex_id, void **addr, } SANITIZER_INTERFACE_ATTRIBUTE -int __tsan_get_report_thread(void *report, uptr idx, int *tid, tid_t *os_id, +int __tsan_get_report_thread(void *report, uptr idx, int *tid, ThreadID *os_id, int *running, const char **name, int *parent_tid, void **trace, uptr trace_size) { const ReportDesc *rep = (ReportDesc *)report; @@ -242,7 +242,7 @@ const char *__tsan_locate_address(uptr addr, char *name, uptr name_size, SANITIZER_INTERFACE_ATTRIBUTE int __tsan_get_alloc_stack(uptr addr, uptr *trace, uptr size, int *thread_id, - tid_t *os_id) { + ThreadID *os_id) { MBlock *b = 0; Allocator *a = allocator(); if (a->PointerIsMine((void *)addr)) { diff --git a/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp b/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp index 14b25a8..795e053 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp +++ b/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp @@ -2888,12 +2888,12 @@ TSAN_INTERCEPTOR(void, _lwp_exit) { #endif #if SANITIZER_FREEBSD -TSAN_INTERCEPTOR(void, thr_exit, tid_t *state) { +TSAN_INTERCEPTOR(void, thr_exit, ThreadID *state) { SCOPED_TSAN_INTERCEPTOR(thr_exit, state); DestroyThreadState(); REAL(thr_exit(state)); } -#define TSAN_MAYBE_INTERCEPT_THR_EXIT TSAN_INTERCEPT(thr_exit) +# define TSAN_MAYBE_INTERCEPT_THR_EXIT TSAN_INTERCEPT(thr_exit) #else #define TSAN_MAYBE_INTERCEPT_THR_EXIT #endif diff --git a/compiler-rt/lib/tsan/rtl/tsan_interface.h b/compiler-rt/lib/tsan/rtl/tsan_interface.h index 6c19744..db94cf4 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_interface.h +++ b/compiler-rt/lib/tsan/rtl/tsan_interface.h @@ -16,7 +16,7 @@ #define TSAN_INTERFACE_H #include <sanitizer_common/sanitizer_internal_defs.h> -using __sanitizer::tid_t; +using __sanitizer::ThreadID; using __sanitizer::uptr; // This header should NOT include any other headers. @@ -175,7 +175,7 @@ int __tsan_get_report_mutex(void *report, uptr idx, uptr *mutex_id, void **addr, // Returns information about threads included in the report. SANITIZER_INTERFACE_ATTRIBUTE -int __tsan_get_report_thread(void *report, uptr idx, int *tid, tid_t *os_id, +int __tsan_get_report_thread(void *report, uptr idx, int *tid, ThreadID *os_id, int *running, const char **name, int *parent_tid, void **trace, uptr trace_size); @@ -192,7 +192,7 @@ const char *__tsan_locate_address(uptr addr, char *name, uptr name_size, // Returns the allocation stack for a heap pointer. SANITIZER_INTERFACE_ATTRIBUTE int __tsan_get_alloc_stack(uptr addr, uptr *trace, uptr size, int *thread_id, - tid_t *os_id); + ThreadID *os_id); #endif // SANITIZER_GO diff --git a/compiler-rt/lib/tsan/rtl/tsan_report.h b/compiler-rt/lib/tsan/rtl/tsan_report.h index bfe47079..8975540 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_report.h +++ b/compiler-rt/lib/tsan/rtl/tsan_report.h @@ -84,7 +84,7 @@ struct ReportLocation { struct ReportThread { Tid id; - tid_t os_id; + ThreadID os_id; bool running; ThreadType thread_type; char *name; diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl.h b/compiler-rt/lib/tsan/rtl/tsan_rtl.h index dc32980..46276f2 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_rtl.h +++ b/compiler-rt/lib/tsan/rtl/tsan_rtl.h @@ -559,7 +559,7 @@ void ThreadIgnoreSyncBegin(ThreadState *thr, uptr pc); void ThreadIgnoreSyncEnd(ThreadState *thr); Tid ThreadCreate(ThreadState *thr, uptr pc, uptr uid, bool detached); -void ThreadStart(ThreadState *thr, Tid tid, tid_t os_id, +void ThreadStart(ThreadState *thr, Tid tid, ThreadID os_id, ThreadType thread_type); void ThreadFinish(ThreadState *thr); Tid ThreadConsumeTid(ThreadState *thr, uptr pc, uptr uid); diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl_thread.cpp b/compiler-rt/lib/tsan/rtl/tsan_rtl_thread.cpp index 8d29e25..c6a8fd2 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_rtl_thread.cpp +++ b/compiler-rt/lib/tsan/rtl/tsan_rtl_thread.cpp @@ -149,7 +149,7 @@ struct OnStartedArgs { uptr tls_size; }; -void ThreadStart(ThreadState *thr, Tid tid, tid_t os_id, +void ThreadStart(ThreadState *thr, Tid tid, ThreadID os_id, ThreadType thread_type) { ctx->thread_registry.StartThread(tid, os_id, thread_type, thr); if (!thr->ignore_sync) { diff --git a/compiler-rt/lib/xray/xray_fdr_controller.h b/compiler-rt/lib/xray/xray_fdr_controller.h index 28a3546..e268906 100644 --- a/compiler-rt/lib/xray/xray_fdr_controller.h +++ b/compiler-rt/lib/xray/xray_fdr_controller.h @@ -32,7 +32,7 @@ template <size_t Version = 5> class FDRController { uint64_t LastFunctionEntryTSC = 0; uint64_t LatestTSC = 0; uint16_t LatestCPU = 0; - tid_t TId = 0; + ThreadID TId = 0; pid_t PId = 0; bool First = true; @@ -84,7 +84,7 @@ template <size_t Version = 5> class FDRController { // buffer, associated with a particular thread, with a new CPU. For the // data, we have 15 bytes to squeeze as much information as we can. At // this point we only write down the following bytes: - // - Thread ID (tid_t, cast to 4 bytes type due to Darwin being 8 + // - Thread ID (ThreadID, cast to 4 bytes type due to Darwin being 8 // bytes) createMetadataRecord<MetadataRecord::RecordKinds::NewBuffer>( static_cast<int32_t>(TId)), diff --git a/compiler-rt/lib/xray/xray_profile_collector.cpp b/compiler-rt/lib/xray/xray_profile_collector.cpp index 3a28240..1de5704 100644 --- a/compiler-rt/lib/xray/xray_profile_collector.cpp +++ b/compiler-rt/lib/xray/xray_profile_collector.cpp @@ -28,7 +28,7 @@ namespace { SpinMutex GlobalMutex; struct ThreadTrie { - tid_t TId; + ThreadID TId; alignas(FunctionCallTrie) std::byte TrieStorage[sizeof(FunctionCallTrie)]; }; @@ -61,7 +61,7 @@ struct ThreadData { FunctionCallTrie::Allocators::Buffers Buffers; FunctionCallTrie::Allocators Allocators; FunctionCallTrie FCT; - tid_t TId; + ThreadID TId; }; using ThreadDataArray = Array<ThreadData>; @@ -105,7 +105,7 @@ static atomic_uint8_t CollectorInitialized{0}; void post(BufferQueue *Q, FunctionCallTrie &&T, FunctionCallTrie::Allocators &&A, FunctionCallTrie::Allocators::Buffers &&B, - tid_t TId) XRAY_NEVER_INSTRUMENT { + ThreadID TId) XRAY_NEVER_INSTRUMENT { DCHECK_NE(Q, nullptr); // Bail out early if the collector has not been initialized. diff --git a/compiler-rt/lib/xray/xray_profile_collector.h b/compiler-rt/lib/xray/xray_profile_collector.h index 6e0f252..81bb190 100644 --- a/compiler-rt/lib/xray/xray_profile_collector.h +++ b/compiler-rt/lib/xray/xray_profile_collector.h @@ -38,7 +38,7 @@ namespace profileCollectorService { /// void post(BufferQueue *Q, FunctionCallTrie &&T, FunctionCallTrie::Allocators &&A, - FunctionCallTrie::Allocators::Buffers &&B, tid_t TId); + FunctionCallTrie::Allocators::Buffers &&B, ThreadID TId); /// The serialize will process all FunctionCallTrie instances in memory, and /// turn those into specifically formatted blocks, each describing the diff --git a/compiler-rt/test/asan/TestCases/Darwin/dispatch_apply_threadno.c b/compiler-rt/test/asan/TestCases/Darwin/dispatch_apply_threadno.c new file mode 100644 index 0000000..5e06615 --- /dev/null +++ b/compiler-rt/test/asan/TestCases/Darwin/dispatch_apply_threadno.c @@ -0,0 +1,54 @@ +// Bugs caught within missing GCD dispatch blocks result in thread being reported as T-1 +// with an empty stack. +// This tests that dispatch_apply blocks can capture valid thread number and stack. + +// RUN: %clang_asan %s -o %t +// RUN: not %run %t func 2>&1 | FileCheck %s --check-prefixes=CHECK-FUNC,CHECK +// RUN: not %run %t block 2>&1 | FileCheck %s --check-prefixes=CHECK-BLOCK,CHECK + +#include <dispatch/dispatch.h> +#include <stdio.h> +#include <stdlib.h> + +__attribute__((noinline)) void access_memory_frame(char *x) { *x = 0; } + +__attribute__((noinline)) void test_dispatch_apply() { + char *x = (char *)malloc(4); + dispatch_apply(8, dispatch_get_global_queue(0, 0), ^(size_t i) { + access_memory_frame(&x[i]); + }); +} + +typedef struct { + char *data; +} Context; + +void da_func(void *ctx, size_t i) { + Context *c = (Context *)ctx; + access_memory_frame(&c->data[i]); +} + +__attribute__((noinline)) void test_dispatch_apply_f() { + Context *ctx = (Context *)malloc(sizeof(Context)); + ctx->data = (char *)malloc(4); + dispatch_apply_f(8, dispatch_get_global_queue(0, 0), ctx, da_func); +} + +int main(int argc, const char *argv[]) { + if (strcmp(argv[1], "func") == 0) { + fprintf(stderr, "Test dispatch_apply with function\n"); + // CHECK-FUNC: dispatch_apply with function + test_dispatch_apply_f(); + } else if (strcmp(argv[1], "block") == 0) { + fprintf(stderr, "Test dispatch_apply with block\n"); + // CHECK-BLOCK: dispatch_apply with block + test_dispatch_apply(); + } else { + abort(); + } + return 0; +} + +// CHECK: ERROR: AddressSanitizer: heap-buffer-overflow +// CHECK: #0 0x{{.*}} in {{.*}}access_memory_frame +// CHECK-NOT: T-1 diff --git a/compiler-rt/test/fuzzer/SigTrapTest.cpp b/compiler-rt/test/fuzzer/SigTrapTest.cpp new file mode 100644 index 0000000..c3019a1 --- /dev/null +++ b/compiler-rt/test/fuzzer/SigTrapTest.cpp @@ -0,0 +1,29 @@ +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +// Simple test for a fuzzer. The fuzzer must find the string "Hi!". +#include <assert.h> +#include <cstddef> +#include <cstdint> +#include <cstdlib> +#include <iostream> +#include <ostream> +#include <signal.h> + +static volatile int Sink; + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { + assert(Data); + if (Size > 0 && Data[0] == 'H') { + Sink = 1; + if (Size > 1 && Data[1] == 'i') { + Sink = 2; + if (Size > 2 && Data[2] == '!') { + std::cout << "BINGO; Found the target, exiting\n" << std::flush; + raise(SIGTRAP); + } + } + } + return 0; +} diff --git a/compiler-rt/test/fuzzer/sig-trap.test b/compiler-rt/test/fuzzer/sig-trap.test new file mode 100644 index 0000000..ee47d2c --- /dev/null +++ b/compiler-rt/test/fuzzer/sig-trap.test @@ -0,0 +1,7 @@ +RUN: %cpp_compiler %S/SigTrapTest.cpp -o %t + +RUN: not %run %t 2>&1 | FileCheck %s +CHECK: BINGO +CHECK: ERROR: libFuzzer: deadly signal + +RUN: trap "%run %t -handle_trap=0" TRAP diff --git a/compiler-rt/test/msan/msan_check_mem_is_initialized.cpp b/compiler-rt/test/msan/msan_check_mem_is_initialized.cpp index aaf5737..aab3189 100644 --- a/compiler-rt/test/msan/msan_check_mem_is_initialized.cpp +++ b/compiler-rt/test/msan/msan_check_mem_is_initialized.cpp @@ -12,7 +12,7 @@ int main(void) { __msan_poison(p + 10, 2); __msan_check_mem_is_initialized(p, 10); - __msan_check_mem_is_initialized(p + 12, 30); + __msan_check_mem_is_initialized(p + 12, 20); #ifdef POSITIVE __msan_check_mem_is_initialized(p + 5, 20); // CHECK: Uninitialized bytes in __msan_check_mem_is_initialized at offset 5 inside [0x{{.*}}, 20) diff --git a/compiler-rt/test/rtsan/pthread_cond_wait.cpp b/compiler-rt/test/rtsan/pthread_cond_wait.cpp new file mode 100644 index 0000000..29afbf4b --- /dev/null +++ b/compiler-rt/test/rtsan/pthread_cond_wait.cpp @@ -0,0 +1,48 @@ +// RUN: %clangxx -fsanitize=realtime %s -o %t +// RUN: %run %t 2>&1 | FileCheck %s + +// UNSUPPORTED: ios + +// Intent: Ensures that pthread_cond_signal does not segfault under rtsan +// See issue #146120 + +#include <condition_variable> +#include <future> +#include <mutex> +#include <thread> + +#include <iostream> + +int main() { + std::cout << "Entry to main!" << std::endl; + + + // TODO: This is disabled because it does cause a test failure + /* + std::mutex mut; + std::condition_variable cv; + bool go{false}; + + const auto fut = std::async(std::launch::async, [&] { + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + { + std::unique_lock<std::mutex> lock(mut); + go = true; + } + cv.notify_one(); + }); + + std::unique_lock<std::mutex> lock(mut); + // normal wait is fine + // cv.wait(lock, [&] { return go; }); + // but timed wait could segfault + + // NOTE: When a fix for the pthread_cond issue #146120 is fixed, uncomment this line + //cv.wait_for(lock, std::chrono::milliseconds(200), [&] { return go; }); + */ + + std::cout << "Exit from main!" << std::endl; +} + +// CHECK: Entry to main! +// CHECK-NEXT: Exit from main! |