1//=-- lsan_allocator.h ----------------------------------------------------===//
2//
3// This file is distributed under the University of Illinois Open Source
4// License. See LICENSE.TXT for details.
5//
6//===----------------------------------------------------------------------===//
7//
8// This file is a part of LeakSanitizer.
9// Allocator for standalone LSan.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LSAN_ALLOCATOR_H
14#define LSAN_ALLOCATOR_H
15
16#include "sanitizer_common/sanitizer_allocator.h"
17#include "sanitizer_common/sanitizer_common.h"
18#include "sanitizer_common/sanitizer_internal_defs.h"
19#include "lsan_common.h"
20
21namespace __lsan {
22
23void *Allocate(const StackTrace &stack, uptr size, uptr alignment,
24               bool cleared);
25void Deallocate(void *p);
26void *Reallocate(const StackTrace &stack, void *p, uptr new_size,
27                 uptr alignment);
28uptr GetMallocUsableSize(const void *p);
29
30template<typename Callable>
31void ForEachChunk(const Callable &callback);
32
33void GetAllocatorCacheRange(uptr *begin, uptr *end);
34void AllocatorThreadFinish();
35void InitializeAllocator();
36
37const bool kAlwaysClearMemory = true;
38
39struct ChunkMetadata {
40  u8 allocated : 8;  // Must be first.
41  ChunkTag tag : 2;
42#if SANITIZER_WORDSIZE == 64
43  uptr requested_size : 54;
44#else
45  uptr requested_size : 32;
46  uptr padding : 22;
47#endif
48  u32 stack_trace_id;
49};
50
51#if defined(__aarch64__) || defined(__i386__) || defined(__arm__) || \
52    ((defined(__sparc__) || \
53      defined(__powerpc__) || \
54      defined(__m68k__) || \
55      defined(__hppa__) || \
56      defined(__sh3__) || \
57      defined(__vax__) || \
58      defined(__riscv) || \
59      defined(__mips__)) && !defined(_LP64))
60static const uptr kRegionSizeLog = 20;
61static const uptr kNumRegions = SANITIZER_MMAP_RANGE_SIZE >> kRegionSizeLog;
62typedef TwoLevelByteMap<(kNumRegions >> 12), 1 << 12> ByteMap;
63
64struct AP32 {
65  static const uptr kSpaceBeg = 0;
66  static const u64 kSpaceSize = SANITIZER_MMAP_RANGE_SIZE;
67  static const uptr kMetadataSize = sizeof(ChunkMetadata);
68  typedef __sanitizer::CompactSizeClassMap SizeClassMap;
69  static const uptr kRegionSizeLog = __lsan::kRegionSizeLog;
70  typedef __lsan::ByteMap ByteMap;
71  typedef NoOpMapUnmapCallback MapUnmapCallback;
72  static const uptr kFlags = 0;
73};
74typedef SizeClassAllocator32<AP32> PrimaryAllocator;
75#elif defined(__x86_64__) || defined(__powerpc64__) || defined(__sparc64__) || \
76      defined(__ia64__) || defined(__alpha__) || \
77      defined(__mips64) || defined(__riscv)
78# if defined(__powerpc64__)
79const uptr kAllocatorSpace = 0xa0000000000ULL;
80const uptr kAllocatorSize  = 0x20000000000ULL;  // 2T.
81# else
82const uptr kAllocatorSpace = 0x600000000000ULL;
83const uptr kAllocatorSize  = 0x40000000000ULL;  // 4T.
84# endif
85struct AP64 {  // Allocator64 parameters. Deliberately using a short name.
86  static const uptr kSpaceBeg = kAllocatorSpace;
87  static const uptr kSpaceSize = kAllocatorSize;
88  static const uptr kMetadataSize = sizeof(ChunkMetadata);
89  typedef DefaultSizeClassMap SizeClassMap;
90  typedef NoOpMapUnmapCallback MapUnmapCallback;
91  static const uptr kFlags = 0;
92};
93
94typedef SizeClassAllocator64<AP64> PrimaryAllocator;
95#else
96#error "unsupported lsan platform"
97#endif
98typedef SizeClassAllocatorLocalCache<PrimaryAllocator> AllocatorCache;
99
100AllocatorCache *GetAllocatorCache();
101
102int lsan_posix_memalign(void **memptr, uptr alignment, uptr size,
103                        const StackTrace &stack);
104void *lsan_aligned_alloc(uptr alignment, uptr size, const StackTrace &stack);
105void *lsan_memalign(uptr alignment, uptr size, const StackTrace &stack);
106void *lsan_malloc(uptr size, const StackTrace &stack);
107void lsan_free(void *p);
108void *lsan_realloc(void *p, uptr size, const StackTrace &stack);
109void *lsan_calloc(uptr nmemb, uptr size, const StackTrace &stack);
110void *lsan_valloc(uptr size, const StackTrace &stack);
111void *lsan_pvalloc(uptr size, const StackTrace &stack);
112uptr lsan_mz_size(const void *p);
113
114}  // namespace __lsan
115
116#endif  // LSAN_ALLOCATOR_H
117