10b57cec5SDimitry Andric //=-- lsan_allocator.h ----------------------------------------------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file is a part of LeakSanitizer. 100b57cec5SDimitry Andric // Allocator for standalone LSan. 110b57cec5SDimitry Andric // 120b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 130b57cec5SDimitry Andric 140b57cec5SDimitry Andric #ifndef LSAN_ALLOCATOR_H 150b57cec5SDimitry Andric #define LSAN_ALLOCATOR_H 160b57cec5SDimitry Andric 170b57cec5SDimitry Andric #include "sanitizer_common/sanitizer_allocator.h" 180b57cec5SDimitry Andric #include "sanitizer_common/sanitizer_common.h" 190b57cec5SDimitry Andric #include "sanitizer_common/sanitizer_internal_defs.h" 200b57cec5SDimitry Andric #include "lsan_common.h" 210b57cec5SDimitry Andric 220b57cec5SDimitry Andric namespace __lsan { 230b57cec5SDimitry Andric 240b57cec5SDimitry Andric void *Allocate(const StackTrace &stack, uptr size, uptr alignment, 250b57cec5SDimitry Andric bool cleared); 260b57cec5SDimitry Andric void Deallocate(void *p); 270b57cec5SDimitry Andric void *Reallocate(const StackTrace &stack, void *p, uptr new_size, 280b57cec5SDimitry Andric uptr alignment); 290b57cec5SDimitry Andric uptr GetMallocUsableSize(const void *p); 300b57cec5SDimitry Andric 310b57cec5SDimitry Andric template<typename Callable> 320b57cec5SDimitry Andric void ForEachChunk(const Callable &callback); 330b57cec5SDimitry Andric 340b57cec5SDimitry Andric void GetAllocatorCacheRange(uptr *begin, uptr *end); 3506c3fb27SDimitry Andric void AllocatorThreadStart(); 360b57cec5SDimitry Andric void AllocatorThreadFinish(); 370b57cec5SDimitry Andric void InitializeAllocator(); 380b57cec5SDimitry Andric 390b57cec5SDimitry Andric const bool kAlwaysClearMemory = true; 400b57cec5SDimitry Andric 410b57cec5SDimitry Andric struct ChunkMetadata { 420b57cec5SDimitry Andric u8 allocated : 8; // Must be first. 430b57cec5SDimitry Andric ChunkTag tag : 2; 440b57cec5SDimitry Andric #if SANITIZER_WORDSIZE == 64 450b57cec5SDimitry Andric uptr requested_size : 54; 460b57cec5SDimitry Andric #else 470b57cec5SDimitry Andric uptr requested_size : 32; 480b57cec5SDimitry Andric uptr padding : 22; 490b57cec5SDimitry Andric #endif 500b57cec5SDimitry Andric u32 stack_trace_id; 510b57cec5SDimitry Andric }; 520b57cec5SDimitry Andric 5381ad6265SDimitry Andric #if !SANITIZER_CAN_USE_ALLOCATOR64 540b57cec5SDimitry Andric template <typename AddressSpaceViewTy> 550b57cec5SDimitry Andric struct AP32 { 560b57cec5SDimitry Andric static const uptr kSpaceBeg = 0; 570b57cec5SDimitry Andric static const u64 kSpaceSize = SANITIZER_MMAP_RANGE_SIZE; 580b57cec5SDimitry Andric static const uptr kMetadataSize = sizeof(ChunkMetadata); 590b57cec5SDimitry Andric typedef __sanitizer::CompactSizeClassMap SizeClassMap; 600b57cec5SDimitry Andric static const uptr kRegionSizeLog = 20; 610b57cec5SDimitry Andric using AddressSpaceView = AddressSpaceViewTy; 620b57cec5SDimitry Andric typedef NoOpMapUnmapCallback MapUnmapCallback; 630b57cec5SDimitry Andric static const uptr kFlags = 0; 640b57cec5SDimitry Andric }; 650b57cec5SDimitry Andric template <typename AddressSpaceView> 660b57cec5SDimitry Andric using PrimaryAllocatorASVT = SizeClassAllocator32<AP32<AddressSpaceView>>; 670b57cec5SDimitry Andric using PrimaryAllocator = PrimaryAllocatorASVT<LocalAddressSpaceView>; 6881ad6265SDimitry Andric #else 6981ad6265SDimitry Andric # if SANITIZER_FUCHSIA || defined(__powerpc64__) 705ffd83dbSDimitry Andric const uptr kAllocatorSpace = ~(uptr)0; 71*5f757f3fSDimitry Andric # if SANITIZER_RISCV64 72*5f757f3fSDimitry Andric // See the comments in compiler-rt/lib/asan/asan_allocator.h for why these 73*5f757f3fSDimitry Andric // values were chosen. 74*5f757f3fSDimitry Andric const uptr kAllocatorSize = UINT64_C(1) << 33; // 8GB 75*5f757f3fSDimitry Andric using LSanSizeClassMap = SizeClassMap</*kNumBits=*/2, 76*5f757f3fSDimitry Andric /*kMinSizeLog=*/5, 77*5f757f3fSDimitry Andric /*kMidSizeLog=*/8, 78*5f757f3fSDimitry Andric /*kMaxSizeLog=*/18, 79*5f757f3fSDimitry Andric /*kNumCachedHintT=*/8, 80*5f757f3fSDimitry Andric /*kMaxBytesCachedLog=*/10>; 81*5f757f3fSDimitry Andric static_assert(LSanSizeClassMap::kNumClassesRounded <= 32, 82*5f757f3fSDimitry Andric "32 size classes is the optimal number to ensure tests run " 83*5f757f3fSDimitry Andric "effieciently on Fuchsia."); 84*5f757f3fSDimitry Andric # else 855ffd83dbSDimitry Andric const uptr kAllocatorSize = 0x40000000000ULL; // 4T. 86*5f757f3fSDimitry Andric using LSanSizeClassMap = DefaultSizeClassMap; 87*5f757f3fSDimitry Andric # endif 88*5f757f3fSDimitry Andric # elif SANITIZER_RISCV64 89*5f757f3fSDimitry Andric const uptr kAllocatorSpace = ~(uptr)0; 90*5f757f3fSDimitry Andric const uptr kAllocatorSize = 0x2000000000ULL; // 128G. 91*5f757f3fSDimitry Andric using LSanSizeClassMap = DefaultSizeClassMap; 9206c3fb27SDimitry Andric # elif SANITIZER_APPLE 9306c3fb27SDimitry Andric const uptr kAllocatorSpace = 0x600000000000ULL; 945ffd83dbSDimitry Andric const uptr kAllocatorSize = 0x40000000000ULL; // 4T. 95*5f757f3fSDimitry Andric using LSanSizeClassMap = DefaultSizeClassMap; 960b57cec5SDimitry Andric # else 9706c3fb27SDimitry Andric const uptr kAllocatorSpace = 0x500000000000ULL; 980b57cec5SDimitry Andric const uptr kAllocatorSize = 0x40000000000ULL; // 4T. 99*5f757f3fSDimitry Andric using LSanSizeClassMap = DefaultSizeClassMap; 1000b57cec5SDimitry Andric # endif 1010b57cec5SDimitry Andric template <typename AddressSpaceViewTy> 1020b57cec5SDimitry Andric struct AP64 { // Allocator64 parameters. Deliberately using a short name. 1030b57cec5SDimitry Andric static const uptr kSpaceBeg = kAllocatorSpace; 1040b57cec5SDimitry Andric static const uptr kSpaceSize = kAllocatorSize; 1050b57cec5SDimitry Andric static const uptr kMetadataSize = sizeof(ChunkMetadata); 106*5f757f3fSDimitry Andric using SizeClassMap = LSanSizeClassMap; 1070b57cec5SDimitry Andric typedef NoOpMapUnmapCallback MapUnmapCallback; 1080b57cec5SDimitry Andric static const uptr kFlags = 0; 1090b57cec5SDimitry Andric using AddressSpaceView = AddressSpaceViewTy; 1100b57cec5SDimitry Andric }; 1110b57cec5SDimitry Andric 1120b57cec5SDimitry Andric template <typename AddressSpaceView> 1130b57cec5SDimitry Andric using PrimaryAllocatorASVT = SizeClassAllocator64<AP64<AddressSpaceView>>; 1140b57cec5SDimitry Andric using PrimaryAllocator = PrimaryAllocatorASVT<LocalAddressSpaceView>; 1150b57cec5SDimitry Andric #endif 1160b57cec5SDimitry Andric 1170b57cec5SDimitry Andric template <typename AddressSpaceView> 1180b57cec5SDimitry Andric using AllocatorASVT = CombinedAllocator<PrimaryAllocatorASVT<AddressSpaceView>>; 1190b57cec5SDimitry Andric using Allocator = AllocatorASVT<LocalAddressSpaceView>; 1200b57cec5SDimitry Andric using AllocatorCache = Allocator::AllocatorCache; 1210b57cec5SDimitry Andric 1220b57cec5SDimitry Andric Allocator::AllocatorCache *GetAllocatorCache(); 1230b57cec5SDimitry Andric 1240b57cec5SDimitry Andric int lsan_posix_memalign(void **memptr, uptr alignment, uptr size, 1250b57cec5SDimitry Andric const StackTrace &stack); 1260b57cec5SDimitry Andric void *lsan_aligned_alloc(uptr alignment, uptr size, const StackTrace &stack); 1270b57cec5SDimitry Andric void *lsan_memalign(uptr alignment, uptr size, const StackTrace &stack); 1280b57cec5SDimitry Andric void *lsan_malloc(uptr size, const StackTrace &stack); 1290b57cec5SDimitry Andric void lsan_free(void *p); 1300b57cec5SDimitry Andric void *lsan_realloc(void *p, uptr size, const StackTrace &stack); 1310b57cec5SDimitry Andric void *lsan_reallocarray(void *p, uptr nmemb, uptr size, 1320b57cec5SDimitry Andric const StackTrace &stack); 1330b57cec5SDimitry Andric void *lsan_calloc(uptr nmemb, uptr size, const StackTrace &stack); 1340b57cec5SDimitry Andric void *lsan_valloc(uptr size, const StackTrace &stack); 1350b57cec5SDimitry Andric void *lsan_pvalloc(uptr size, const StackTrace &stack); 1360b57cec5SDimitry Andric uptr lsan_mz_size(const void *p); 1370b57cec5SDimitry Andric 1380b57cec5SDimitry Andric } // namespace __lsan 1390b57cec5SDimitry Andric 1400b57cec5SDimitry Andric #endif // LSAN_ALLOCATOR_H 141