xref: /freebsd/contrib/llvm-project/compiler-rt/lib/lsan/lsan_allocator.h (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad)
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