1 //===-- scudo_allocator.h ---------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 /// Header for scudo_allocator.cpp.
12 //===----------------------------------------------------------------------===//
14 #ifndef SCUDO_ALLOCATOR_H_
15 #define SCUDO_ALLOCATOR_H_
17 #include "scudo_flags.h"
19 #include "sanitizer_common/sanitizer_allocator.h"
22 # error "The Scudo hardened allocator is currently only supported on Linux."
28 FromMalloc = 0, // Memory block came from malloc, realloc, calloc, etc.
29 FromNew = 1, // Memory block came from operator new.
30 FromNewArray = 2, // Memory block came from operator new [].
31 FromMemalign = 3, // Memory block came from memalign, posix_memalign, etc.
34 enum ChunkState : u8 {
40 // Our header requires 64 bits of storage. Having the offset saves us from
41 // using functions such as GetBlockBegin, that is fairly costly. Our first
42 // implementation used the MetaData as well, which offers the advantage of
43 // being stored away from the chunk itself, but accessing it was costly as
44 // well. The header will be atomically loaded and stored.
45 typedef u64 PackedHeader;
46 struct UnpackedHeader {
48 u64 SizeOrUnusedBytes : 19; // Size for Primary backed allocations, amount of
49 // unused bytes in the chunk for Secondary ones.
51 u64 State : 2; // available, allocated, or quarantined
52 u64 AllocType : 2; // malloc, new, new[], or memalign
53 u64 Offset : 16; // Offset from the beginning of the backend
54 // allocation to the beginning of the chunk
55 // itself, in multiples of MinAlignment. See
56 // comment about its maximum value and in init().
60 typedef atomic_uint64_t AtomicPackedHeader;
61 COMPILER_CHECK(sizeof(UnpackedHeader) == sizeof(PackedHeader));
63 // Minimum alignment of 8 bytes for 32-bit, 16 for 64-bit
64 const uptr MinAlignmentLog = FIRST_32_SECOND_64(3, 4);
65 const uptr MaxAlignmentLog = 24; // 16 MB
66 const uptr MinAlignment = 1 << MinAlignmentLog;
67 const uptr MaxAlignment = 1 << MaxAlignmentLog;
69 const uptr ChunkHeaderSize = sizeof(PackedHeader);
70 const uptr AlignedChunkHeaderSize =
71 (ChunkHeaderSize + MinAlignment - 1) & ~(MinAlignment - 1);
73 #if SANITIZER_CAN_USE_ALLOCATOR64
74 const uptr AllocatorSpace = ~0ULL;
75 # if defined(__aarch64__) && SANITIZER_ANDROID
76 const uptr AllocatorSize = 0x4000000000ULL; // 256G.
77 # elif defined(__aarch64__)
78 const uptr AllocatorSize = 0x10000000000ULL; // 1T.
80 const uptr AllocatorSize = 0x40000000000ULL; // 4T.
82 typedef DefaultSizeClassMap SizeClassMap;
84 static const uptr kSpaceBeg = AllocatorSpace;
85 static const uptr kSpaceSize = AllocatorSize;
86 static const uptr kMetadataSize = 0;
87 typedef __scudo::SizeClassMap SizeClassMap;
88 typedef NoOpMapUnmapCallback MapUnmapCallback;
89 static const uptr kFlags =
90 SizeClassAllocator64FlagMasks::kRandomShuffleChunks;
92 typedef SizeClassAllocator64<AP64> PrimaryAllocator;
94 // Currently, the 32-bit Sanitizer allocator has not yet benefited from all the
95 // security improvements brought to the 64-bit one. This makes the 32-bit
96 // version of Scudo slightly less toughened.
97 static const uptr RegionSizeLog = 20;
98 static const uptr NumRegions = SANITIZER_MMAP_RANGE_SIZE >> RegionSizeLog;
99 # if SANITIZER_WORDSIZE == 32
100 typedef FlatByteMap<NumRegions> ByteMap;
101 # elif SANITIZER_WORDSIZE == 64
102 typedef TwoLevelByteMap<(NumRegions >> 12), 1 << 12> ByteMap;
103 # endif // SANITIZER_WORDSIZE
104 typedef DefaultSizeClassMap SizeClassMap;
106 static const uptr kSpaceBeg = 0;
107 static const u64 kSpaceSize = SANITIZER_MMAP_RANGE_SIZE;
108 static const uptr kMetadataSize = 0;
109 typedef __scudo::SizeClassMap SizeClassMap;
110 static const uptr kRegionSizeLog = RegionSizeLog;
111 typedef __scudo::ByteMap ByteMap;
112 typedef NoOpMapUnmapCallback MapUnmapCallback;
113 static const uptr kFlags =
114 SizeClassAllocator32FlagMasks::kRandomShuffleChunks;
116 typedef SizeClassAllocator32<AP32> PrimaryAllocator;
117 #endif // SANITIZER_CAN_USE_ALLOCATOR64
119 #include "scudo_allocator_secondary.h"
120 #include "scudo_allocator_combined.h"
122 typedef SizeClassAllocatorLocalCache<PrimaryAllocator> AllocatorCache;
123 typedef ScudoLargeMmapAllocator SecondaryAllocator;
124 typedef ScudoCombinedAllocator<PrimaryAllocator, AllocatorCache,
125 SecondaryAllocator> ScudoBackendAllocator;
129 void *scudoMalloc(uptr Size, AllocType Type);
130 void scudoFree(void *Ptr, AllocType Type);
131 void scudoSizedFree(void *Ptr, uptr Size, AllocType Type);
132 void *scudoRealloc(void *Ptr, uptr Size);
133 void *scudoCalloc(uptr NMemB, uptr Size);
134 void *scudoMemalign(uptr Alignment, uptr Size);
135 void *scudoValloc(uptr Size);
136 void *scudoPvalloc(uptr Size);
137 int scudoPosixMemalign(void **MemPtr, uptr Alignment, uptr Size);
138 void *scudoAlignedAlloc(uptr Alignment, uptr Size);
139 uptr scudoMallocUsableSize(void *Ptr);
141 } // namespace __scudo
143 #endif // SCUDO_ALLOCATOR_H_