1 //===-- scudo_allocator.h ---------------------------------------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 /// Header for scudo_allocator.cpp.
11 //===----------------------------------------------------------------------===//
13 #ifndef SCUDO_ALLOCATOR_H_
14 #define SCUDO_ALLOCATOR_H_
16 #include "scudo_platform.h"
21 FromMalloc = 0, // Memory block came from malloc, realloc, calloc, etc.
22 FromNew = 1, // Memory block came from operator new.
23 FromNewArray = 2, // Memory block came from operator new [].
24 FromMemalign = 3, // Memory block came from memalign, posix_memalign, etc.
27 enum ChunkState : u8 {
33 // Our header requires 64 bits of storage. Having the offset saves us from
34 // using functions such as GetBlockBegin, that is fairly costly. Our first
35 // implementation used the MetaData as well, which offers the advantage of
36 // being stored away from the chunk itself, but accessing it was costly as
37 // well. The header will be atomically loaded and stored.
38 typedef u64 PackedHeader;
39 struct UnpackedHeader {
42 u64 SizeOrUnusedBytes : 20; // Size for Primary backed allocations, amount of
43 // unused bytes in the chunk for Secondary ones.
44 u64 State : 2; // available, allocated, or quarantined
45 u64 AllocType : 2; // malloc, new, new[], or memalign
46 u64 Offset : 16; // Offset from the beginning of the backend
47 // allocation to the beginning of the chunk
48 // itself, in multiples of MinAlignment. See
49 // comment about its maximum value and in init().
52 typedef atomic_uint64_t AtomicPackedHeader;
53 COMPILER_CHECK(sizeof(UnpackedHeader) == sizeof(PackedHeader));
55 // Minimum alignment of 8 bytes for 32-bit, 16 for 64-bit
56 const uptr MinAlignmentLog = FIRST_32_SECOND_64(3, 4);
57 const uptr MaxAlignmentLog = 24; // 16 MB
58 const uptr MinAlignment = 1 << MinAlignmentLog;
59 const uptr MaxAlignment = 1 << MaxAlignmentLog;
61 // constexpr version of __sanitizer::RoundUp without the extraneous CHECK.
62 // This way we can use it in constexpr variables and functions declarations.
63 constexpr uptr RoundUpTo(uptr Size, uptr Boundary) {
64 return (Size + Boundary - 1) & ~(Boundary - 1);
68 constexpr uptr getHeaderSize() {
69 return RoundUpTo(sizeof(PackedHeader), MinAlignment);
73 #if SANITIZER_CAN_USE_ALLOCATOR64
74 const uptr AllocatorSpace = ~0ULL;
76 static const uptr kSpaceBeg = AllocatorSpace;
77 static const uptr kSpaceSize = AllocatorSize;
78 static const uptr kMetadataSize = 0;
79 typedef __scudo::SizeClassMap SizeClassMap;
80 typedef NoOpMapUnmapCallback MapUnmapCallback;
81 static const uptr kFlags =
82 SizeClassAllocator64FlagMasks::kRandomShuffleChunks;
83 using AddressSpaceView = LocalAddressSpaceView;
85 typedef SizeClassAllocator64<AP64> PrimaryT;
88 static const uptr kSpaceBeg = 0;
89 static const u64 kSpaceSize = SANITIZER_MMAP_RANGE_SIZE;
90 static const uptr kMetadataSize = 0;
91 typedef __scudo::SizeClassMap SizeClassMap;
92 static const uptr kRegionSizeLog = RegionSizeLog;
93 using AddressSpaceView = LocalAddressSpaceView;
94 typedef NoOpMapUnmapCallback MapUnmapCallback;
95 static const uptr kFlags =
96 SizeClassAllocator32FlagMasks::kRandomShuffleChunks |
97 SizeClassAllocator32FlagMasks::kUseSeparateSizeClassForBatch;
99 typedef SizeClassAllocator32<AP32> PrimaryT;
100 #endif // SANITIZER_CAN_USE_ALLOCATOR64
102 #include "scudo_allocator_secondary.h"
104 typedef LargeMmapAllocator SecondaryT;
106 #include "scudo_allocator_combined.h"
108 typedef CombinedAllocator BackendT;
109 typedef CombinedAllocator::AllocatorCache AllocatorCacheT;
113 void *scudoAllocate(uptr Size, uptr Alignment, AllocType Type);
114 void scudoDeallocate(void *Ptr, uptr Size, uptr Alignment, AllocType Type);
115 void *scudoRealloc(void *Ptr, uptr Size);
116 void *scudoCalloc(uptr NMemB, uptr Size);
117 void *scudoValloc(uptr Size);
118 void *scudoPvalloc(uptr Size);
119 int scudoPosixMemalign(void **MemPtr, uptr Alignment, uptr Size);
120 void *scudoAlignedAlloc(uptr Alignment, uptr Size);
121 uptr scudoMallocUsableSize(void *Ptr);
123 } // namespace __scudo
125 #endif // SCUDO_ALLOCATOR_H_