1 //===-- sanitizer_allocator_dlsym.h -----------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // Hack: Sanitizer initializer calls dlsym which may need to allocate and call 10 // back into uninitialized sanitizer. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef SANITIZER_ALLOCATOR_DLSYM_H 15 #define SANITIZER_ALLOCATOR_DLSYM_H 16 17 #include "sanitizer_allocator_internal.h" 18 #include "sanitizer_common/sanitizer_allocator_checks.h" 19 #include "sanitizer_common/sanitizer_internal_defs.h" 20 21 namespace __sanitizer { 22 23 template <typename Details> 24 struct DlSymAllocator { 25 static bool Use() { 26 // Fuchsia doesn't use dlsym-based interceptors. 27 return !SANITIZER_FUCHSIA && UNLIKELY(Details::UseImpl()); 28 } 29 30 static bool PointerIsMine(const void *ptr) { 31 // Fuchsia doesn't use dlsym-based interceptors. 32 return !SANITIZER_FUCHSIA && 33 UNLIKELY(internal_allocator()->FromPrimary(ptr)); 34 } 35 36 static void *Allocate(uptr size_in_bytes, uptr align = kWordSize) { 37 void *ptr = InternalAlloc(size_in_bytes, nullptr, align); 38 CHECK(internal_allocator()->FromPrimary(ptr)); 39 Details::OnAllocate(ptr, GetSize(ptr)); 40 return ptr; 41 } 42 43 static void *Callocate(usize nmemb, usize size) { 44 void *ptr = InternalCalloc(nmemb, size); 45 CHECK(internal_allocator()->FromPrimary(ptr)); 46 Details::OnAllocate(ptr, GetSize(ptr)); 47 return ptr; 48 } 49 50 static void Free(void *ptr) { 51 uptr size = GetSize(ptr); 52 Details::OnFree(ptr, size); 53 InternalFree(ptr); 54 } 55 56 static void *Realloc(void *ptr, uptr new_size) { 57 if (!ptr) 58 return Allocate(new_size); 59 CHECK(internal_allocator()->FromPrimary(ptr)); 60 if (!new_size) { 61 Free(ptr); 62 return nullptr; 63 } 64 uptr size = GetSize(ptr); 65 uptr memcpy_size = Min(new_size, size); 66 void *new_ptr = Allocate(new_size); 67 if (new_ptr) 68 internal_memcpy(new_ptr, ptr, memcpy_size); 69 Free(ptr); 70 return new_ptr; 71 } 72 73 static void *ReallocArray(void *ptr, uptr count, uptr size) { 74 CHECK(!CheckForCallocOverflow(count, size)); 75 return Realloc(ptr, count * size); 76 } 77 78 static uptr GetSize(void *ptr) { 79 return internal_allocator()->GetActuallyAllocatedSize(ptr); 80 } 81 82 static void OnAllocate(const void *ptr, uptr size) {} 83 static void OnFree(const void *ptr, uptr size) {} 84 }; 85 86 } // namespace __sanitizer 87 88 #endif // SANITIZER_ALLOCATOR_DLSYM_H 89