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