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