Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
107 changes: 97 additions & 10 deletions compiler-rt/lib/asan/asan_allocator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -1068,16 +1063,15 @@ 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())
return nullptr;
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) {
Expand Down Expand Up @@ -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));
}
Expand Down
24 changes: 19 additions & 5 deletions compiler-rt/lib/asan/asan_allocator.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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();
Expand Down
54 changes: 48 additions & 6 deletions compiler-rt/lib/asan/asan_mac.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
//
Expand All @@ -128,6 +130,7 @@ typedef void* dispatch_queue_t;
typedef void* dispatch_source_t;
typedef u64 dispatch_time_t;
typedef void (*dispatch_function_t)(void *block);
typedef void (*dispatch_apply_function_t)(void *, size_t);
typedef void* (*worker_t)(void *block);
typedef unsigned long dispatch_mach_reason;
typedef void *dispatch_mach_msg_t;
Expand All @@ -147,7 +150,11 @@ typedef void (^dispatch_mach_handler_t)(dispatch_mach_reason reason,
// A wrapper for the ObjC blocks used to support libdispatch.
typedef struct {
void *block;
dispatch_function_t func;
union {
dispatch_function_t dispatch_func;
dispatch_apply_function_t dispatch_apply_func;
static_assert(sizeof(dispatch_func) == sizeof(dispatch_apply_func));
};
u32 parent_tid;
} asan_block_context_t;

Expand Down Expand Up @@ -175,8 +182,8 @@ void asan_dispatch_call_block_and_release(void *block) {
block, (void*)pthread_self());
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);
context->dispatch_func(context->block);
asan_free(context, &stack);
}

} // namespace __asan
Expand All @@ -191,7 +198,7 @@ asan_block_context_t *alloc_asan_context(void *ctxt, dispatch_function_t func,
asan_block_context_t *asan_ctxt =
(asan_block_context_t*) asan_malloc(sizeof(asan_block_context_t), stack);
asan_ctxt->block = ctxt;
asan_ctxt->func = func;
asan_ctxt->dispatch_func = func;
asan_ctxt->parent_tid = GetCurrentTidOrInvalid();
return asan_ctxt;
}
Expand Down Expand Up @@ -243,13 +250,34 @@ 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);
asan_ctxt->dispatch_apply_func(asan_ctxt->block, iteration);
}

INTERCEPTOR(void, dispatch_apply_f, size_t iterations, dispatch_queue_t queue,
void *ctxt, dispatch_apply_function_t work) {
GET_STACK_TRACE_THREAD;
asan_block_context_t *asan_ctxt =
(asan_block_context_t *)asan_malloc(sizeof(asan_block_context_t), &stack);
asan_ctxt->block = ctxt;
asan_ctxt->dispatch_apply_func = work;
asan_ctxt->parent_tid = GetCurrentTidOrInvalid();
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));
Expand Down Expand Up @@ -332,6 +360,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
8 changes: 4 additions & 4 deletions compiler-rt/lib/asan/asan_malloc_linux.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,15 @@ 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
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

Expand Down Expand Up @@ -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

Expand Down
6 changes: 3 additions & 3 deletions compiler-rt/lib/asan/asan_malloc_mac.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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; \
Expand Down
10 changes: 5 additions & 5 deletions compiler-rt/lib/asan/asan_malloc_win.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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); }
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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);
Expand All @@ -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;
}
Expand Down Expand Up @@ -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;
}

Expand Down
Loading