]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/compiler-rt/lib/scudo/scudo_allocator.h
Upgrade to OpenSSH 7.4p1.
[FreeBSD/FreeBSD.git] / contrib / compiler-rt / lib / scudo / scudo_allocator.h
1 //===-- scudo_allocator.h ---------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 ///
10 /// Header for scudo_allocator.cpp.
11 ///
12 //===----------------------------------------------------------------------===//
13
14 #ifndef SCUDO_ALLOCATOR_H_
15 #define SCUDO_ALLOCATOR_H_
16
17 #include "scudo_flags.h"
18
19 #include "sanitizer_common/sanitizer_allocator.h"
20
21 #include <atomic>
22
23 namespace __scudo {
24
25 enum AllocType : u8 {
26   FromMalloc    = 0, // Memory block came from malloc, realloc, calloc, etc.
27   FromNew       = 1, // Memory block came from operator new.
28   FromNewArray  = 2, // Memory block came from operator new [].
29   FromMemalign  = 3, // Memory block came from memalign, posix_memalign, etc.
30 };
31
32 enum ChunkState : u8 {
33   ChunkAvailable  = 0,
34   ChunkAllocated  = 1,
35   ChunkQuarantine = 2
36 };
37
38 // Our header requires 64 bits of storage. Having the offset saves us from
39 // using functions such as GetBlockBegin, that is fairly costly. Our first
40 // implementation used the MetaData as well, which offers the advantage of
41 // being stored away from the chunk itself, but accessing it was costly as
42 // well. The header will be atomically loaded and stored using the 16-byte
43 // primitives offered by the platform (likely requires cmpxchg16b support).
44 typedef u64 PackedHeader;
45 struct UnpackedHeader {
46   u64 Checksum    : 16;
47   u64 UnusedBytes : 20; // Needed for reallocation purposes.
48   u64 State       : 2;  // available, allocated, or quarantined
49   u64 AllocType   : 2;  // malloc, new, new[], or memalign
50   u64 Offset      : 16; // Offset from the beginning of the backend
51                         // allocation to the beginning of the chunk itself,
52                         // in multiples of MinAlignment. See comment about
53                         // its maximum value and test in init().
54   u64 Salt        : 8;
55 };
56
57 typedef std::atomic<PackedHeader> AtomicPackedHeader;
58 COMPILER_CHECK(sizeof(UnpackedHeader) == sizeof(PackedHeader));
59
60 // Minimum alignment of 8 bytes for 32-bit, 16 for 64-bit
61 const uptr MinAlignmentLog = FIRST_32_SECOND_64(3, 4);
62 const uptr MaxAlignmentLog = 24; // 16 MB
63 const uptr MinAlignment = 1 << MinAlignmentLog;
64 const uptr MaxAlignment = 1 << MaxAlignmentLog;
65
66 const uptr ChunkHeaderSize = sizeof(PackedHeader);
67 const uptr AlignedChunkHeaderSize =
68     (ChunkHeaderSize + MinAlignment - 1) & ~(MinAlignment - 1);
69
70 struct AllocatorOptions {
71   u32 QuarantineSizeMb;
72   u32 ThreadLocalQuarantineSizeKb;
73   bool MayReturnNull;
74   s32 ReleaseToOSIntervalMs;
75   bool DeallocationTypeMismatch;
76   bool DeleteSizeMismatch;
77   bool ZeroContents;
78
79   void setFrom(const Flags *f, const CommonFlags *cf);
80   void copyTo(Flags *f, CommonFlags *cf) const;
81 };
82
83 void initAllocator(const AllocatorOptions &options);
84 void drainQuarantine();
85
86 void *scudoMalloc(uptr Size, AllocType Type);
87 void scudoFree(void *Ptr, AllocType Type);
88 void scudoSizedFree(void *Ptr, uptr Size, AllocType Type);
89 void *scudoRealloc(void *Ptr, uptr Size);
90 void *scudoCalloc(uptr NMemB, uptr Size);
91 void *scudoMemalign(uptr Alignment, uptr Size);
92 void *scudoValloc(uptr Size);
93 void *scudoPvalloc(uptr Size);
94 int scudoPosixMemalign(void **MemPtr, uptr Alignment, uptr Size);
95 void *scudoAlignedAlloc(uptr Alignment, uptr Size);
96 uptr scudoMallocUsableSize(void *Ptr);
97
98 #include "scudo_allocator_secondary.h"
99
100 }  // namespace __scudo
101
102 #endif  // SCUDO_ALLOCATOR_H_