blob: 5f5225b3628678d776e361ac203d8b2879ff5dd6 [file] [log] [blame]
Kostya Serebryany712fc982016-06-07 01:20:26 +00001//===-- 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
Kostya Serebryany712fc982016-06-07 01:20:26 +000017#include "scudo_flags.h"
18
19#include "sanitizer_common/sanitizer_allocator.h"
20
Kostya Kortchinskyb39dff42017-01-18 17:11:17 +000021#if !SANITIZER_LINUX
22# error "The Scudo hardened allocator is currently only supported on Linux."
23#endif
24
Kostya Serebryany712fc982016-06-07 01:20:26 +000025namespace __scudo {
26
27enum AllocType : u8 {
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.
32};
33
Kostya Kortchinsky71dcc332016-10-26 16:16:58 +000034enum ChunkState : u8 {
35 ChunkAvailable = 0,
36 ChunkAllocated = 1,
37 ChunkQuarantine = 2
38};
39
Kostya Kortchinsky1148dc52016-11-30 17:32:20 +000040// Our header requires 64 bits of storage. Having the offset saves us from
Kostya Kortchinsky71dcc332016-10-26 16:16:58 +000041// 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 using the 16-byte
45// primitives offered by the platform (likely requires cmpxchg16b support).
Kostya Kortchinsky71dcc332016-10-26 16:16:58 +000046typedef u64 PackedHeader;
47struct UnpackedHeader {
Kostya Kortchinsky1148dc52016-11-30 17:32:20 +000048 u64 Checksum : 16;
Kostya Kortchinsky47be0ed2016-12-15 18:06:55 +000049 u64 UnusedBytes : 20; // Needed for reallocation purposes.
Kostya Kortchinsky1148dc52016-11-30 17:32:20 +000050 u64 State : 2; // available, allocated, or quarantined
51 u64 AllocType : 2; // malloc, new, new[], or memalign
Kostya Kortchinsky47be0ed2016-12-15 18:06:55 +000052 u64 Offset : 16; // Offset from the beginning of the backend
Kostya Kortchinsky1148dc52016-11-30 17:32:20 +000053 // allocation to the beginning of the chunk itself,
54 // in multiples of MinAlignment. See comment about
55 // its maximum value and test in init().
56 u64 Salt : 8;
Kostya Kortchinsky71dcc332016-10-26 16:16:58 +000057};
Kostya Kortchinsky71dcc332016-10-26 16:16:58 +000058
Kostya Kortchinskya00b9222017-01-20 18:32:18 +000059typedef atomic_uint64_t AtomicPackedHeader;
Kostya Kortchinsky71dcc332016-10-26 16:16:58 +000060COMPILER_CHECK(sizeof(UnpackedHeader) == sizeof(PackedHeader));
61
Kostya Kortchinsky71dcc332016-10-26 16:16:58 +000062// Minimum alignment of 8 bytes for 32-bit, 16 for 64-bit
63const uptr MinAlignmentLog = FIRST_32_SECOND_64(3, 4);
64const uptr MaxAlignmentLog = 24; // 16 MB
65const uptr MinAlignment = 1 << MinAlignmentLog;
66const uptr MaxAlignment = 1 << MaxAlignmentLog;
67
Kostya Kortchinsky1148dc52016-11-30 17:32:20 +000068const uptr ChunkHeaderSize = sizeof(PackedHeader);
69const uptr AlignedChunkHeaderSize =
70 (ChunkHeaderSize + MinAlignment - 1) & ~(MinAlignment - 1);
71
Kostya Serebryany712fc982016-06-07 01:20:26 +000072struct AllocatorOptions {
73 u32 QuarantineSizeMb;
74 u32 ThreadLocalQuarantineSizeKb;
75 bool MayReturnNull;
Evgeniy Stepanovd3305af2016-11-29 00:22:50 +000076 s32 ReleaseToOSIntervalMs;
Kostya Serebryany712fc982016-06-07 01:20:26 +000077 bool DeallocationTypeMismatch;
78 bool DeleteSizeMismatch;
79 bool ZeroContents;
80
81 void setFrom(const Flags *f, const CommonFlags *cf);
82 void copyTo(Flags *f, CommonFlags *cf) const;
83};
84
85void initAllocator(const AllocatorOptions &options);
86void drainQuarantine();
87
88void *scudoMalloc(uptr Size, AllocType Type);
89void scudoFree(void *Ptr, AllocType Type);
90void scudoSizedFree(void *Ptr, uptr Size, AllocType Type);
91void *scudoRealloc(void *Ptr, uptr Size);
92void *scudoCalloc(uptr NMemB, uptr Size);
93void *scudoMemalign(uptr Alignment, uptr Size);
94void *scudoValloc(uptr Size);
95void *scudoPvalloc(uptr Size);
96int scudoPosixMemalign(void **MemPtr, uptr Alignment, uptr Size);
97void *scudoAlignedAlloc(uptr Alignment, uptr Size);
98uptr scudoMallocUsableSize(void *Ptr);
99
Kostya Kortchinsky71dcc332016-10-26 16:16:58 +0000100#include "scudo_allocator_secondary.h"
101
Kostya Kortchinsky1148dc52016-11-30 17:32:20 +0000102} // namespace __scudo
Kostya Serebryany712fc982016-06-07 01:20:26 +0000103
104#endif // SCUDO_ALLOCATOR_H_