blob: 6431a2aa07d7d361f26bb520e7b96f6555f25723 [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 Kortchinsky71dcc332016-10-26 16:16:58 +000021#include <atomic>
22
Kostya Serebryany712fc982016-06-07 01:20:26 +000023namespace __scudo {
24
25enum 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
Kostya Kortchinsky71dcc332016-10-26 16:16:58 +000032enum ChunkState : u8 {
33 ChunkAvailable = 0,
34 ChunkAllocated = 1,
35 ChunkQuarantine = 2
36};
37
Kostya Kortchinsky1148dc52016-11-30 17:32:20 +000038// Our header requires 64 bits of storage. Having the offset saves us from
Kostya Kortchinsky71dcc332016-10-26 16:16:58 +000039// 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).
Kostya Kortchinsky71dcc332016-10-26 16:16:58 +000044typedef u64 PackedHeader;
45struct UnpackedHeader {
Kostya Kortchinsky1148dc52016-11-30 17:32:20 +000046 u64 Checksum : 16;
Kostya Kortchinsky47be0ed2016-12-15 18:06:55 +000047 u64 UnusedBytes : 20; // Needed for reallocation purposes.
Kostya Kortchinsky1148dc52016-11-30 17:32:20 +000048 u64 State : 2; // available, allocated, or quarantined
49 u64 AllocType : 2; // malloc, new, new[], or memalign
Kostya Kortchinsky47be0ed2016-12-15 18:06:55 +000050 u64 Offset : 16; // Offset from the beginning of the backend
Kostya Kortchinsky1148dc52016-11-30 17:32:20 +000051 // 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;
Kostya Kortchinsky71dcc332016-10-26 16:16:58 +000055};
Kostya Kortchinsky71dcc332016-10-26 16:16:58 +000056
57typedef std::atomic<PackedHeader> AtomicPackedHeader;
58COMPILER_CHECK(sizeof(UnpackedHeader) == sizeof(PackedHeader));
59
Kostya Kortchinsky71dcc332016-10-26 16:16:58 +000060// Minimum alignment of 8 bytes for 32-bit, 16 for 64-bit
61const uptr MinAlignmentLog = FIRST_32_SECOND_64(3, 4);
62const uptr MaxAlignmentLog = 24; // 16 MB
63const uptr MinAlignment = 1 << MinAlignmentLog;
64const uptr MaxAlignment = 1 << MaxAlignmentLog;
65
Kostya Kortchinsky1148dc52016-11-30 17:32:20 +000066const uptr ChunkHeaderSize = sizeof(PackedHeader);
67const uptr AlignedChunkHeaderSize =
68 (ChunkHeaderSize + MinAlignment - 1) & ~(MinAlignment - 1);
69
Kostya Serebryany712fc982016-06-07 01:20:26 +000070struct AllocatorOptions {
71 u32 QuarantineSizeMb;
72 u32 ThreadLocalQuarantineSizeKb;
73 bool MayReturnNull;
Evgeniy Stepanovd3305af2016-11-29 00:22:50 +000074 s32 ReleaseToOSIntervalMs;
Kostya Serebryany712fc982016-06-07 01:20:26 +000075 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
83void initAllocator(const AllocatorOptions &options);
84void drainQuarantine();
85
86void *scudoMalloc(uptr Size, AllocType Type);
87void scudoFree(void *Ptr, AllocType Type);
88void scudoSizedFree(void *Ptr, uptr Size, AllocType Type);
89void *scudoRealloc(void *Ptr, uptr Size);
90void *scudoCalloc(uptr NMemB, uptr Size);
91void *scudoMemalign(uptr Alignment, uptr Size);
92void *scudoValloc(uptr Size);
93void *scudoPvalloc(uptr Size);
94int scudoPosixMemalign(void **MemPtr, uptr Alignment, uptr Size);
95void *scudoAlignedAlloc(uptr Alignment, uptr Size);
96uptr scudoMallocUsableSize(void *Ptr);
97
Kostya Kortchinsky71dcc332016-10-26 16:16:58 +000098#include "scudo_allocator_secondary.h"
99
Kostya Kortchinsky1148dc52016-11-30 17:32:20 +0000100} // namespace __scudo
Kostya Serebryany712fc982016-06-07 01:20:26 +0000101
102#endif // SCUDO_ALLOCATOR_H_