Index: compiler-rt/trunk/lib/asan/asan_malloc_linux.cc =================================================================== --- compiler-rt/trunk/lib/asan/asan_malloc_linux.cc +++ compiler-rt/trunk/lib/asan/asan_malloc_linux.cc @@ -24,6 +24,7 @@ #include "asan_allocator.h" #include "asan_interceptors.h" #include "asan_internal.h" +#include "asan_malloc_local.h" #include "asan_stack.h" // ---------------------- Replacement functions ---------------- {{{1 @@ -67,12 +68,19 @@ return 0; } -// On RTEMS, we use the local pool to handle memory allocation before -// the ASan run-time has been initialized. -static INLINE bool EarlyMalloc() { - return SANITIZER_RTEMS && (!asan_inited || asan_init_is_running); +#if SANITIZER_RTEMS +void* MemalignFromLocalPool(uptr alignment, uptr size) { + void *ptr = nullptr; + alignment = Max(alignment, kWordSize); + PosixMemalignFromLocalPool(&ptr, alignment, size); + return ptr; } +bool IsFromLocalPool(const void *ptr) { + return IsInDlsymAllocPool(ptr); +} +#endif + static INLINE bool MaybeInDlsym() { // Fuchsia doesn't use dlsym-based interceptors. return !SANITIZER_FUCHSIA && asan_init_is_running; Index: compiler-rt/trunk/lib/asan/asan_malloc_local.h =================================================================== --- compiler-rt/trunk/lib/asan/asan_malloc_local.h +++ compiler-rt/trunk/lib/asan/asan_malloc_local.h @@ -0,0 +1,44 @@ +//===-- asan_malloc_local.h -------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file is a part of AddressSanitizer, an address sanity checker. +// +// Provide interfaces to check for and handle local pool memory allocation. +//===----------------------------------------------------------------------===// + +#ifndef ASAN_MALLOC_LOCAL_H +#define ASAN_MALLOC_LOCAL_H + +#include "sanitizer_common/sanitizer_platform.h" +#include "asan_internal.h" + +// On RTEMS, we use the local pool to handle memory allocation when the ASan +// run-time is not up. +static INLINE bool EarlyMalloc() { + return SANITIZER_RTEMS && (!__asan::asan_inited || + __asan::asan_init_is_running); +} + +void* MemalignFromLocalPool(uptr alignment, uptr size); + +#if SANITIZER_RTEMS + +bool IsFromLocalPool(const void *ptr); + +#define ALLOCATE_FROM_LOCAL_POOL UNLIKELY(EarlyMalloc()) +#define IS_FROM_LOCAL_POOL(ptr) UNLIKELY(IsFromLocalPool(ptr)) + +#else // SANITIZER_RTEMS + +#define ALLOCATE_FROM_LOCAL_POOL 0 +#define IS_FROM_LOCAL_POOL(ptr) 0 + +#endif // SANITIZER_RTEMS + +#endif // ASAN_MALLOC_LOCAL_H Index: compiler-rt/trunk/lib/asan/asan_new_delete.cc =================================================================== --- compiler-rt/trunk/lib/asan/asan_new_delete.cc +++ compiler-rt/trunk/lib/asan/asan_new_delete.cc @@ -14,6 +14,7 @@ #include "asan_allocator.h" #include "asan_internal.h" +#include "asan_malloc_local.h" #include "asan_report.h" #include "asan_stack.h" @@ -69,12 +70,24 @@ } // namespace std // 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(type, nothrow) \ + if (ALLOCATE_FROM_LOCAL_POOL) {\ + void *res = MemalignFromLocalPool(SHADOW_GRANULARITY, size);\ + if (!nothrow) CHECK(res);\ + return res;\ + }\ GET_STACK_TRACE_MALLOC;\ void *res = asan_memalign(0, size, &stack, type);\ if (!nothrow && UNLIKELY(!res)) ReportOutOfMemory(size, &stack);\ return res; #define OPERATOR_NEW_BODY_ALIGN(type, nothrow) \ + if (ALLOCATE_FROM_LOCAL_POOL) {\ + void *res = MemalignFromLocalPool((uptr)align, size);\ + if (!nothrow) CHECK(res);\ + return res;\ + }\ GET_STACK_TRACE_MALLOC;\ void *res = asan_memalign((uptr)align, size, &stack, type);\ if (!nothrow && UNLIKELY(!res)) ReportOutOfMemory(size, &stack);\ @@ -129,18 +142,22 @@ #endif // !SANITIZER_MAC #define OPERATOR_DELETE_BODY(type) \ + if (IS_FROM_LOCAL_POOL(ptr)) return;\ GET_STACK_TRACE_FREE;\ asan_delete(ptr, 0, 0, &stack, type); #define OPERATOR_DELETE_BODY_SIZE(type) \ + if (IS_FROM_LOCAL_POOL(ptr)) return;\ GET_STACK_TRACE_FREE;\ asan_delete(ptr, size, 0, &stack, type); #define OPERATOR_DELETE_BODY_ALIGN(type) \ + if (IS_FROM_LOCAL_POOL(ptr)) return;\ GET_STACK_TRACE_FREE;\ asan_delete(ptr, 0, static_cast(align), &stack, type); #define OPERATOR_DELETE_BODY_SIZE_ALIGN(type) \ + if (IS_FROM_LOCAL_POOL(ptr)) return;\ GET_STACK_TRACE_FREE;\ asan_delete(ptr, size, static_cast(align), &stack, type);