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<AP> 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;
105 typedef SizeClassAllocator32<0, SANITIZER_MMAP_RANGE_SIZE, 0, SizeClassMap,
106 RegionSizeLog, ByteMap> PrimaryAllocator;
107 #endif // SANITIZER_CAN_USE_ALLOCATOR64
109 #include "scudo_allocator_secondary.h"
111 typedef SizeClassAllocatorLocalCache<PrimaryAllocator> AllocatorCache;
112 typedef ScudoLargeMmapAllocator SecondaryAllocator;
113 typedef CombinedAllocator<PrimaryAllocator, AllocatorCache, SecondaryAllocator>
114 ScudoBackendAllocator;
118 void *scudoMalloc(uptr Size, AllocType Type);
119 void scudoFree(void *Ptr, AllocType Type);
120 void scudoSizedFree(void *Ptr, uptr Size, AllocType Type);
121 void *scudoRealloc(void *Ptr, uptr Size);
122 void *scudoCalloc(uptr NMemB, uptr Size);
123 void *scudoMemalign(uptr Alignment, uptr Size);
124 void *scudoValloc(uptr Size);
125 void *scudoPvalloc(uptr Size);
126 int scudoPosixMemalign(void **MemPtr, uptr Alignment, uptr Size);
127 void *scudoAlignedAlloc(uptr Alignment, uptr Size);
128 uptr scudoMallocUsableSize(void *Ptr);
130 } // namespace __scudo
132 #endif // SCUDO_ALLOCATOR_H_