diff options
Diffstat (limited to 'abs/extra/llvm/msan-prevent-initialization-failure-with-newer-glibc.patch')
-rw-r--r-- | abs/extra/llvm/msan-prevent-initialization-failure-with-newer-glibc.patch | 103 |
1 files changed, 103 insertions, 0 deletions
diff --git a/abs/extra/llvm/msan-prevent-initialization-failure-with-newer-glibc.patch b/abs/extra/llvm/msan-prevent-initialization-failure-with-newer-glibc.patch new file mode 100644 index 0000000..57387a6 --- /dev/null +++ b/abs/extra/llvm/msan-prevent-initialization-failure-with-newer-glibc.patch @@ -0,0 +1,103 @@ +Index: lib/msan/msan_interceptors.cc +=================================================================== +--- lib/msan/msan_interceptors.cc (revision 282231) ++++ lib/msan/msan_interceptors.cc (revision 282232) +@@ -64,6 +64,23 @@ + return in_interceptor_scope; + } + ++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 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; ++} ++ + #define ENSURE_MSAN_INITED() do { \ + CHECK(!msan_init_is_running); \ + if (!msan_inited) { \ +@@ -227,7 +244,7 @@ + + INTERCEPTOR(void, free, void *ptr) { + GET_MALLOC_STACK_TRACE; +- if (!ptr) return; ++ if (!ptr || UNLIKELY(IsInDlsymAllocPool(ptr))) return; + MsanDeallocate(&stack, ptr); + } + +@@ -234,7 +251,7 @@ + #if !SANITIZER_FREEBSD + INTERCEPTOR(void, cfree, void *ptr) { + GET_MALLOC_STACK_TRACE; +- if (!ptr) return; ++ if (!ptr || UNLIKELY(IsInDlsymAllocPool(ptr))) return; + MsanDeallocate(&stack, ptr); + } + #define MSAN_MAYBE_INTERCEPT_CFREE INTERCEPT_FUNCTION(cfree) +@@ -907,27 +924,29 @@ + + INTERCEPTOR(void *, calloc, SIZE_T nmemb, SIZE_T size) { + GET_MALLOC_STACK_TRACE; +- if (UNLIKELY(!msan_inited)) { ++ if (UNLIKELY(!msan_inited)) + // Hack: dlsym calls calloc before REAL(calloc) is retrieved from dlsym. +- const SIZE_T kCallocPoolSize = 1024; +- static uptr calloc_memory_for_dlsym[kCallocPoolSize]; +- static SIZE_T allocated; +- SIZE_T 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); + return MsanCalloc(&stack, nmemb, size); + } + + INTERCEPTOR(void *, realloc, void *ptr, SIZE_T size) { + GET_MALLOC_STACK_TRACE; ++ if (UNLIKELY(IsInDlsymAllocPool(ptr))) { ++ uptr offset = (uptr)ptr - (uptr)alloc_memory_for_dlsym; ++ uptr copy_size = Min(size, kDlsymAllocPoolSize - offset); ++ void *new_ptr = AllocateFromLocalPool(size); ++ internal_memcpy(new_ptr, ptr, copy_size); ++ return new_ptr; ++ } + return MsanReallocate(&stack, ptr, size, sizeof(u64), false); + } + + INTERCEPTOR(void *, malloc, SIZE_T size) { + GET_MALLOC_STACK_TRACE; ++ if (UNLIKELY(!msan_inited)) ++ // Hack: dlsym calls malloc before REAL(malloc) is retrieved from dlsym. ++ return AllocateFromLocalPool(size); + return MsanReallocate(&stack, nullptr, size, sizeof(u64), false); + } + +Index: lib/asan/asan_malloc_linux.cc +=================================================================== +--- lib/asan/asan_malloc_linux.cc (revision 282231) ++++ lib/asan/asan_malloc_linux.cc (revision 282232) +@@ -78,7 +78,11 @@ + 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); ++ void *new_ptr; ++ if (UNLIKELY(!asan_inited)) ++ new_ptr = AllocateFromLocalPool(size); ++ else ++ new_ptr = asan_malloc(size, &stack); + internal_memcpy(new_ptr, ptr, copy_size); + return new_ptr; + } |