summaryrefslogtreecommitdiff
path: root/debian/patches/asan-glibc-2.24.diff
diff options
context:
space:
mode:
Diffstat (limited to 'debian/patches/asan-glibc-2.24.diff')
-rw-r--r--debian/patches/asan-glibc-2.24.diff81
1 files changed, 81 insertions, 0 deletions
diff --git a/debian/patches/asan-glibc-2.24.diff b/debian/patches/asan-glibc-2.24.diff
new file mode 100644
index 0000000..133406d
--- /dev/null
+++ b/debian/patches/asan-glibc-2.24.diff
@@ -0,0 +1,81 @@
+Index: llvm-toolchain-3.8-3.8.1/compiler-rt/lib/asan/asan_malloc_linux.cc
+===================================================================
+--- llvm-toolchain-3.8-3.8.1.orig/compiler-rt/lib/asan/asan_malloc_linux.cc
++++ llvm-toolchain-3.8-3.8.1/compiler-rt/lib/asan/asan_malloc_linux.cc
+@@ -26,52 +26,58 @@
+ // ---------------------- Replacement functions ---------------- {{{1
+ using namespace __asan; // NOLINT
+
+-static const uptr kCallocPoolSize = 1024;
+-static uptr calloc_memory_for_dlsym[kCallocPoolSize];
++static uptr allocated_for_dlsym;
++static const uptr kDlsymAllocPoolSize = 1024;
++static uptr alloc_memory_for_dlsym[kDlsymAllocPoolSize];
++
++static bool IsInDlsymAllocPool(const void *ptr) {
++ uptr off = (uptr)ptr - (uptr)alloc_memory_for_dlsym;
++ return off < sizeof(alloc_memory_for_dlsym);
++}
+
+-static bool IsInCallocPool(const void *ptr) {
+- sptr off = (sptr)ptr - (sptr)calloc_memory_for_dlsym;
+- return 0 <= off && off < (sptr)kCallocPoolSize;
++static void *AllocateFromLocalPool(uptr size_in_bytes) {
++ uptr size_in_words = RoundUpTo(size_in_bytes, kWordSize) / kWordSize;
++ void *mem = (void*)&alloc_memory_for_dlsym[allocated_for_dlsym];
++ allocated_for_dlsym += size_in_words;
++ CHECK_LT(allocated_for_dlsym, kDlsymAllocPoolSize);
++ return mem;
+ }
+
+ INTERCEPTOR(void, free, void *ptr) {
+ GET_STACK_TRACE_FREE;
+- if (UNLIKELY(IsInCallocPool(ptr)))
++ if (UNLIKELY(IsInDlsymAllocPool(ptr)))
+ return;
+ asan_free(ptr, &stack, FROM_MALLOC);
+ }
+
+ INTERCEPTOR(void, cfree, void *ptr) {
+ GET_STACK_TRACE_FREE;
+- if (UNLIKELY(IsInCallocPool(ptr)))
++ if (UNLIKELY(IsInDlsymAllocPool(ptr)))
+ return;
+ asan_free(ptr, &stack, FROM_MALLOC);
+ }
+
+ INTERCEPTOR(void*, malloc, uptr size) {
++ if (UNLIKELY(!asan_inited))
++ // Hack: dlsym calls malloc before REAL(malloc) is retrieved from dlsym.
++ return AllocateFromLocalPool(size);
+ GET_STACK_TRACE_MALLOC;
+ return asan_malloc(size, &stack);
+ }
+
+ INTERCEPTOR(void*, calloc, uptr nmemb, uptr size) {
+- if (UNLIKELY(!asan_inited)) {
++ if (UNLIKELY(!asan_inited))
+ // Hack: dlsym calls calloc before REAL(calloc) is retrieved from dlsym.
+- static uptr allocated;
+- uptr size_in_words = ((nmemb * size) + kWordSize - 1) / kWordSize;
+- void *mem = (void*)&calloc_memory_for_dlsym[allocated];
+- allocated += size_in_words;
+- CHECK(allocated < kCallocPoolSize);
+- return mem;
+- }
++ return AllocateFromLocalPool(nmemb * size);
+ GET_STACK_TRACE_MALLOC;
+ return asan_calloc(nmemb, size, &stack);
+ }
+
+ INTERCEPTOR(void*, realloc, void *ptr, uptr size) {
+ GET_STACK_TRACE_MALLOC;
+- if (UNLIKELY(IsInCallocPool(ptr))) {
+- uptr offset = (uptr)ptr - (uptr)calloc_memory_for_dlsym;
+- uptr copy_size = Min(size, kCallocPoolSize - offset);
++ if (UNLIKELY(IsInDlsymAllocPool(ptr))) {
++ uptr offset = (uptr)ptr - (uptr)alloc_memory_for_dlsym;
++ uptr copy_size = Min(size, kDlsymAllocPoolSize - offset);
+ void *new_ptr = asan_malloc(size, &stack);
+ internal_memcpy(new_ptr, ptr, copy_size);
+ return new_ptr;