blob: c4f3ebd38003b691b0c7752ea3d67911674c8fd9 [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
17#ifndef __x86_64__
18# error "The Scudo hardened allocator currently only supports x86_64."
19#endif
20
21#include "scudo_flags.h"
22
23#include "sanitizer_common/sanitizer_allocator.h"
24
Kostya Kortchinsky71dcc332016-10-26 16:16:58 +000025#include <atomic>
26
Kostya Serebryany712fc982016-06-07 01:20:26 +000027namespace __scudo {
28
29enum AllocType : u8 {
30 FromMalloc = 0, // Memory block came from malloc, realloc, calloc, etc.
31 FromNew = 1, // Memory block came from operator new.
32 FromNewArray = 2, // Memory block came from operator new [].
33 FromMemalign = 3, // Memory block came from memalign, posix_memalign, etc.
34};
35
Kostya Kortchinsky71dcc332016-10-26 16:16:58 +000036enum ChunkState : u8 {
37 ChunkAvailable = 0,
38 ChunkAllocated = 1,
39 ChunkQuarantine = 2
40};
41
42#if SANITIZER_WORDSIZE == 64
43// Our header requires 128 bits of storage on 64-bit platforms, which fits
44// nicely with the alignment requirements. Having the offset saves us from
45// using functions such as GetBlockBegin, that is fairly costly. Our first
46// implementation used the MetaData as well, which offers the advantage of
47// being stored away from the chunk itself, but accessing it was costly as
48// well. The header will be atomically loaded and stored using the 16-byte
49// primitives offered by the platform (likely requires cmpxchg16b support).
50typedef unsigned __int128 PackedHeader;
51struct UnpackedHeader {
52 u16 Checksum : 16;
53 uptr RequestedSize : 40; // Needed for reallocation purposes.
54 u8 State : 2; // available, allocated, or quarantined
55 u8 AllocType : 2; // malloc, new, new[], or memalign
56 u8 Unused_0_ : 4;
57 uptr Offset : 12; // Offset from the beginning of the backend
58 // allocation to the beginning of the chunk itself,
59 // in multiples of MinAlignment. See comment about
60 // its maximum value and test in init().
61 u64 Unused_1_ : 36;
62 u16 Salt : 16;
63};
64#elif SANITIZER_WORDSIZE == 32
65// On 32-bit platforms, our header requires 64 bits.
66typedef u64 PackedHeader;
67struct UnpackedHeader {
68 u16 Checksum : 12;
69 uptr RequestedSize : 32; // Needed for reallocation purposes.
70 u8 State : 2; // available, allocated, or quarantined
71 u8 AllocType : 2; // malloc, new, new[], or memalign
72 uptr Offset : 12; // Offset from the beginning of the backend
73 // allocation to the beginning of the chunk itself,
74 // in multiples of MinAlignment. See comment about
75 // its maximum value and test in Allocator::init().
76 u16 Salt : 4;
77};
78#else
79# error "Unsupported SANITIZER_WORDSIZE."
80#endif // SANITIZER_WORDSIZE
81
82typedef std::atomic<PackedHeader> AtomicPackedHeader;
83COMPILER_CHECK(sizeof(UnpackedHeader) == sizeof(PackedHeader));
84
85const uptr ChunkHeaderSize = sizeof(PackedHeader);
86
87// Minimum alignment of 8 bytes for 32-bit, 16 for 64-bit
88const uptr MinAlignmentLog = FIRST_32_SECOND_64(3, 4);
89const uptr MaxAlignmentLog = 24; // 16 MB
90const uptr MinAlignment = 1 << MinAlignmentLog;
91const uptr MaxAlignment = 1 << MaxAlignmentLog;
92
Kostya Serebryany712fc982016-06-07 01:20:26 +000093struct AllocatorOptions {
94 u32 QuarantineSizeMb;
95 u32 ThreadLocalQuarantineSizeKb;
96 bool MayReturnNull;
97 bool DeallocationTypeMismatch;
98 bool DeleteSizeMismatch;
99 bool ZeroContents;
100
101 void setFrom(const Flags *f, const CommonFlags *cf);
102 void copyTo(Flags *f, CommonFlags *cf) const;
103};
104
105void initAllocator(const AllocatorOptions &options);
106void drainQuarantine();
107
108void *scudoMalloc(uptr Size, AllocType Type);
109void scudoFree(void *Ptr, AllocType Type);
110void scudoSizedFree(void *Ptr, uptr Size, AllocType Type);
111void *scudoRealloc(void *Ptr, uptr Size);
112void *scudoCalloc(uptr NMemB, uptr Size);
113void *scudoMemalign(uptr Alignment, uptr Size);
114void *scudoValloc(uptr Size);
115void *scudoPvalloc(uptr Size);
116int scudoPosixMemalign(void **MemPtr, uptr Alignment, uptr Size);
117void *scudoAlignedAlloc(uptr Alignment, uptr Size);
118uptr scudoMallocUsableSize(void *Ptr);
119
Kostya Kortchinsky71dcc332016-10-26 16:16:58 +0000120#include "scudo_allocator_secondary.h"
121
Kostya Serebryany712fc982016-06-07 01:20:26 +0000122} // namespace __scudo
123
124#endif // SCUDO_ALLOCATOR_H_