diff options
Diffstat (limited to 'lib/lsan')
-rw-r--r-- | lib/lsan/lsan_allocator.cc | 2 | ||||
-rw-r--r-- | lib/lsan/lsan_allocator.h | 3 | ||||
-rw-r--r-- | lib/lsan/lsan_common.h | 34 |
3 files changed, 33 insertions, 6 deletions
diff --git a/lib/lsan/lsan_allocator.cc b/lib/lsan/lsan_allocator.cc index 640497d40..9c8acc186 100644 --- a/lib/lsan/lsan_allocator.cc +++ b/lib/lsan/lsan_allocator.cc @@ -24,7 +24,7 @@ extern "C" void *memset(void *ptr, int value, uptr num); namespace __lsan { -#if defined(__i386__) +#if defined(__i386__) || defined(__arm__) static const uptr kMaxAllowedMallocSize = 1UL << 30; #elif defined(__mips64) || defined(__aarch64__) static const uptr kMaxAllowedMallocSize = 4UL << 30; diff --git a/lib/lsan/lsan_allocator.h b/lib/lsan/lsan_allocator.h index 9c3dce97a..bd19211c4 100644 --- a/lib/lsan/lsan_allocator.h +++ b/lib/lsan/lsan_allocator.h @@ -48,7 +48,8 @@ struct ChunkMetadata { u32 stack_trace_id; }; -#if defined(__mips64) || defined(__aarch64__) || defined(__i386__) +#if defined(__mips64) || defined(__aarch64__) || defined(__i386__) || \ + defined(__arm__) static const uptr kRegionSizeLog = 20; static const uptr kNumRegions = SANITIZER_MMAP_RANGE_SIZE >> kRegionSizeLog; typedef TwoLevelByteMap<(kNumRegions >> 12), 1 << 12> ByteMap; diff --git a/lib/lsan/lsan_common.h b/lib/lsan/lsan_common.h index 082492dec..2851a6672 100644 --- a/lib/lsan/lsan_common.h +++ b/lib/lsan/lsan_common.h @@ -37,6 +37,9 @@ #elif defined(__i386__) && \ (SANITIZER_LINUX && !SANITIZER_ANDROID || SANITIZER_MAC) #define CAN_SANITIZE_LEAKS 1 +#elif defined(__arm__) && \ + SANITIZER_LINUX && !SANITIZER_ANDROID +#define CAN_SANITIZE_LEAKS 1 #else #define CAN_SANITIZE_LEAKS 0 #endif @@ -144,13 +147,36 @@ struct ScopedInterceptorDisabler { ~ScopedInterceptorDisabler() { EnableInThisThread(); } }; +// According to Itanium C++ ABI array cookie is a one word containing +// size of allocated array. +static inline bool IsItaniumABIArrayCookie(uptr chunk_beg, uptr chunk_size, + uptr addr) { + return chunk_size == sizeof(uptr) && chunk_beg + chunk_size == addr && + *reinterpret_cast<uptr *>(chunk_beg) == 0; +} + +// According to ARM C++ ABI array cookie consists of two words: +// struct array_cookie { +// std::size_t element_size; // element_size != 0 +// std::size_t element_count; +// }; +static inline bool IsARMABIArrayCookie(uptr chunk_beg, uptr chunk_size, + uptr addr) { + return chunk_size == 2 * sizeof(uptr) && chunk_beg + chunk_size == addr && + *reinterpret_cast<uptr *>(chunk_beg + sizeof(uptr)) == 0; +} + // Special case for "new T[0]" where T is a type with DTOR. -// new T[0] will allocate one word for the array size (0) and store a pointer -// to the end of allocated chunk. +// new T[0] will allocate a cookie (one or two words) for the array size (0) +// and store a pointer to the end of allocated chunk. The actual cookie layout +// varies between platforms according to their C++ ABI implementation. inline bool IsSpecialCaseOfOperatorNew0(uptr chunk_beg, uptr chunk_size, uptr addr) { - return chunk_size == sizeof(uptr) && chunk_beg + chunk_size == addr && - *reinterpret_cast<uptr *>(chunk_beg) == 0; +#if defined(__arm__) + return IsARMABIArrayCookie(chunk_beg, chunk_size, addr); +#else + return IsItaniumABIArrayCookie(chunk_beg, chunk_size, addr); +#endif } // The following must be implemented in the parent tool. |