summaryrefslogtreecommitdiff
path: root/lib/lsan
diff options
context:
space:
mode:
authorMaxim Ostapenko <chefmax7@gmail.com>2017-04-11 14:58:26 +0000
committerMaxim Ostapenko <chefmax7@gmail.com>2017-04-11 14:58:26 +0000
commit8d8e5f3b6c3f6c74c0ddcdbdd169ffe3fefadfe3 (patch)
tree1d7b57f83768f06bbdc6cfcf5833b16fc4ede564 /lib/lsan
parent056881d0b45d6148ab00fa12cb58cd75e4f64e48 (diff)
Reapply "Enable LSan for arm Linux"
This patch reapplies r299923 with typo fixed in BLX macros. git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@299948 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/lsan')
-rw-r--r--lib/lsan/lsan_allocator.cc2
-rw-r--r--lib/lsan/lsan_allocator.h3
-rw-r--r--lib/lsan/lsan_common.h34
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.