Index: lsan/lsan_allocator.cc =================================================================== --- lsan/lsan_allocator.cc +++ lsan/lsan_allocator.cc @@ -24,10 +24,10 @@ namespace __lsan { -static const uptr kMaxAllowedMallocSize = 8UL << 30; +#if SANITIZER_WORDSIZE == 64 static const uptr kAllocatorSpace = 0x600000000000ULL; static const uptr kAllocatorSize = 0x40000000000ULL; // 4T. - +typedef DefaultSizeClassMap SizeClassMap; struct ChunkMetadata { bool allocated : 8; // Must be first. ChunkTag tag : 2; @@ -36,7 +36,29 @@ }; typedef SizeClassAllocator64 PrimaryAllocator; + sizeof(ChunkMetadata), SizeClassMap> PrimaryAllocator; + +#elif SANITIZER_WORDSIZE == 32 +static const u64 kAddressSpaceSize = 1ULL << 32; +typedef CompactSizeClassMap SizeClassMap; +static const uptr kRegionSizeLog = 20; +static const uptr kFlatByteMapSize = kAddressSpaceSize >> kRegionSizeLog; +struct ChunkMetadata { + bool allocated : 8; // Must be first. + ChunkTag tag : 2; + uptr requested_size : 22; + u32 stack_trace_id; +}; + +typedef SizeClassAllocator32<0, kAddressSpaceSize, sizeof(ChunkMetadata), + SizeClassMap, kRegionSizeLog, + FlatByteMap > + PrimaryAllocator; + +#endif + +static const uptr kMaxAllowedMallocSize = FIRST_32_SECOND_64(3UL << 27, 8UL << 30); + typedef SizeClassAllocatorLocalCache AllocatorCache; typedef LargeMmapAllocator<> SecondaryAllocator; typedef CombinedAllocatoruse_tls) { LOG_THREADS("TLS at %p-%p.\n", tls_begin, tls_end); if (cache_begin == cache_end) { @@ -264,6 +265,7 @@ ScanRangeForPointers(cache_end, tls_end, frontier, "TLS", kReachable); } } +#endif } } Index: lsan/lsan_interceptors.cc =================================================================== --- lsan/lsan_interceptors.cc +++ lsan/lsan_interceptors.cc @@ -23,6 +23,7 @@ #include "lsan.h" #include "lsan_allocator.h" #include "lsan_thread.h" +#include using namespace __lsan; @@ -160,13 +161,13 @@ return Allocate(stack, size, 1, kAlwaysClearMemory); INTERCEPTOR_ATTRIBUTE -void *operator new(uptr size) { OPERATOR_NEW_BODY; } +void *operator new(size_t size) { OPERATOR_NEW_BODY; } INTERCEPTOR_ATTRIBUTE -void *operator new[](uptr size) { OPERATOR_NEW_BODY; } +void *operator new[](size_t size) { OPERATOR_NEW_BODY; } INTERCEPTOR_ATTRIBUTE -void *operator new(uptr size, std::nothrow_t const&) { OPERATOR_NEW_BODY; } +void *operator new(size_t size, std::nothrow_t const&) { OPERATOR_NEW_BODY; } INTERCEPTOR_ATTRIBUTE -void *operator new[](uptr size, std::nothrow_t const&) { OPERATOR_NEW_BODY; } +void *operator new[](size_t size, std::nothrow_t const&) { OPERATOR_NEW_BODY; } #define OPERATOR_DELETE_BODY \ ENSURE_LSAN_INITED; \ Index: sanitizer_common/sanitizer_linux.h =================================================================== --- sanitizer_common/sanitizer_linux.h +++ sanitizer_common/sanitizer_linux.h @@ -43,7 +43,7 @@ // internal_sigaction instead. int internal_sigaction_norestorer(int signum, const void *act, void *oldact); void internal_sigdelset(__sanitizer_sigset_t *set, int signum); -#if defined(__x86_64__) +#if defined(__x86_64__) || defined(__arm__) uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg, int *parent_tidptr, void *newtls, int *child_tidptr); #endif Index: sanitizer_common/sanitizer_linux.cc =================================================================== --- sanitizer_common/sanitizer_linux.cc +++ sanitizer_common/sanitizer_linux.cc @@ -794,6 +794,53 @@ : "rsp", "memory", "r11", "rcx"); return res; } +#elif defined(__arm__) && SANITIZER_LINUX +uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg, + int *parent_tidptr, void *newtls, int *child_tidptr) { + unsigned int res; + if (!fn || !child_stack) + return -EINVAL; + CHECK_EQ(0, (uptr)child_stack % 16); + child_stack = (char *)child_stack - 2 * sizeof(unsigned int); + ((unsigned int *)child_stack)[0] = (uptr)fn; + ((unsigned int *)child_stack)[1] = (uptr)arg; + register int r0 __asm__("r0") = flags; + register void *r1 __asm__("r1") = child_stack; + register int *r2 __asm__("r2") = parent_tidptr; + register void *r3 __asm__("r3") = newtls; + register int *r4 __asm__("r4") = child_tidptr; + register int r7 __asm__("r7") = __NR_clone; + __asm__ __volatile__( + "push {r4, r7}\n" + "swi 0x0\n" + "cmp r0, #0\n" + "bne 1f\n" + "ldr r0, [sp, #4]\n" +#if defined(__ARM_ARCH_4T__) && defined(__THUMB_INTERWORK__) + "ldr ip, [sp], #8\n" + "mov lr, pc\n" + "bx ip\n" +#else + "ldr lr, [sp], #8\n" + "blx lr\n" +#endif + "mov r7, %7\n" + "swi 0x0\n" + "1:\n" + "pop {r4, r7}\n" + "mov %0, r0\n" + : "=r" (res) + : "r"(r0), + "r"(r1), + "r"(r2), + "r"(r3), + "r"(r4), + "r"(r7), + "i"(__NR_exit) + : "memory"); + return res; +} + #endif // defined(__x86_64__) && SANITIZER_LINUX #if SANITIZER_ANDROID Index: sanitizer_common/sanitizer_platform_limits_posix.h =================================================================== --- sanitizer_common/sanitizer_platform_limits_posix.h +++ sanitizer_common/sanitizer_platform_limits_posix.h @@ -275,10 +275,15 @@ #endif #if SANITIZER_LINUX && !SANITIZER_ANDROID +#if defined(__x86_64__) || defined(__i386__) + const unsigned xdr_ops_fn_num = 10; +#elif defined(__arm__) + const unsigned xdr_ops_fn_num = 9; +#endif struct __sanitizer_XDR { int x_op; struct xdr_ops { - uptr fns[10]; + uptr fns[xdr_ops_fn_num]; } *x_ops; uptr x_public; uptr x_private; Index: sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc =================================================================== --- sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc +++ sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc @@ -14,7 +14,7 @@ #include "sanitizer_platform.h" -#if SANITIZER_LINUX && defined(__x86_64__) +#if SANITIZER_LINUX && (defined(__x86_64__) || defined(__arm__)) #include "sanitizer_stoptheworld.h" @@ -459,4 +459,4 @@ } } // namespace __sanitizer -#endif // SANITIZER_LINUX && defined(__x86_64__) +#endif // SANITIZER_LINUX && (defined(__x86_64__) || defined(__arm__))