[ASan/Win] Add DLL thunks for the fake stack interface
[blocksruntime.git] / lib / asan / asan_allocator.h
blob6b2324ae34a9451d8efd0fc4717e29da48ea1781
1 //===-- asan_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 // This file is a part of AddressSanitizer, an address sanity checker.
12 // ASan-private header for asan_allocator2.cc.
13 //===----------------------------------------------------------------------===//
15 #ifndef ASAN_ALLOCATOR_H
16 #define ASAN_ALLOCATOR_H
18 #include "asan_internal.h"
19 #include "asan_interceptors.h"
20 #include "sanitizer_common/sanitizer_allocator.h"
21 #include "sanitizer_common/sanitizer_list.h"
23 namespace __asan {
25 enum AllocType {
26 FROM_MALLOC = 1, // Memory block came from malloc, calloc, realloc, etc.
27 FROM_NEW = 2, // Memory block came from operator new.
28 FROM_NEW_BR = 3 // Memory block came from operator new [ ]
31 static const uptr kNumberOfSizeClasses = 255;
32 struct AsanChunk;
34 void InitializeAllocator();
35 void ReInitializeAllocator();
37 class AsanChunkView {
38 public:
39 explicit AsanChunkView(AsanChunk *chunk) : chunk_(chunk) {}
40 bool IsValid(); // Checks if AsanChunkView points to a valid allocated
41 // or quarantined chunk.
42 uptr Beg(); // First byte of user memory.
43 uptr End(); // Last byte of user memory.
44 uptr UsedSize(); // Size requested by the user.
45 uptr AllocTid();
46 uptr FreeTid();
47 bool Eq(const AsanChunkView &c) const { return chunk_ == c.chunk_; }
48 void GetAllocStack(StackTrace *stack);
49 void GetFreeStack(StackTrace *stack);
50 bool AddrIsInside(uptr addr, uptr access_size, sptr *offset) {
51 if (addr >= Beg() && (addr + access_size) <= End()) {
52 *offset = addr - Beg();
53 return true;
55 return false;
57 bool AddrIsAtLeft(uptr addr, uptr access_size, sptr *offset) {
58 (void)access_size;
59 if (addr < Beg()) {
60 *offset = Beg() - addr;
61 return true;
63 return false;
65 bool AddrIsAtRight(uptr addr, uptr access_size, sptr *offset) {
66 if (addr + access_size > End()) {
67 *offset = addr - End();
68 return true;
70 return false;
73 private:
74 AsanChunk *const chunk_;
77 AsanChunkView FindHeapChunkByAddress(uptr address);
79 // List of AsanChunks with total size.
80 class AsanChunkFifoList: public IntrusiveList<AsanChunk> {
81 public:
82 explicit AsanChunkFifoList(LinkerInitialized) { }
83 AsanChunkFifoList() { clear(); }
84 void Push(AsanChunk *n);
85 void PushList(AsanChunkFifoList *q);
86 AsanChunk *Pop();
87 uptr size() { return size_; }
88 void clear() {
89 IntrusiveList<AsanChunk>::clear();
90 size_ = 0;
92 private:
93 uptr size_;
96 struct AsanMapUnmapCallback {
97 void OnMap(uptr p, uptr size) const;
98 void OnUnmap(uptr p, uptr size) const;
101 #if SANITIZER_CAN_USE_ALLOCATOR64
102 # if defined(__powerpc64__)
103 const uptr kAllocatorSpace = 0xa0000000000ULL;
104 const uptr kAllocatorSize = 0x20000000000ULL; // 2T.
105 # else
106 const uptr kAllocatorSpace = 0x600000000000ULL;
107 const uptr kAllocatorSize = 0x40000000000ULL; // 4T.
108 # endif
109 typedef DefaultSizeClassMap SizeClassMap;
110 typedef SizeClassAllocator64<kAllocatorSpace, kAllocatorSize, 0 /*metadata*/,
111 SizeClassMap, AsanMapUnmapCallback> PrimaryAllocator;
112 #else // Fallback to SizeClassAllocator32.
113 static const uptr kRegionSizeLog = 20;
114 static const uptr kNumRegions = SANITIZER_MMAP_RANGE_SIZE >> kRegionSizeLog;
115 # if SANITIZER_WORDSIZE == 32
116 typedef FlatByteMap<kNumRegions> ByteMap;
117 # elif SANITIZER_WORDSIZE == 64
118 typedef TwoLevelByteMap<(kNumRegions >> 12), 1 << 12> ByteMap;
119 # endif
120 typedef CompactSizeClassMap SizeClassMap;
121 typedef SizeClassAllocator32<0, SANITIZER_MMAP_RANGE_SIZE, 16,
122 SizeClassMap, kRegionSizeLog,
123 ByteMap,
124 AsanMapUnmapCallback> PrimaryAllocator;
125 #endif // SANITIZER_CAN_USE_ALLOCATOR64
127 typedef SizeClassAllocatorLocalCache<PrimaryAllocator> AllocatorCache;
128 typedef LargeMmapAllocator<AsanMapUnmapCallback> SecondaryAllocator;
129 typedef CombinedAllocator<PrimaryAllocator, AllocatorCache,
130 SecondaryAllocator> Allocator;
133 struct AsanThreadLocalMallocStorage {
134 uptr quarantine_cache[16];
135 AllocatorCache allocator2_cache;
136 void CommitBack();
137 private:
138 // These objects are allocated via mmap() and are zero-initialized.
139 AsanThreadLocalMallocStorage() {}
142 void *asan_memalign(uptr alignment, uptr size, StackTrace *stack,
143 AllocType alloc_type);
144 void asan_free(void *ptr, StackTrace *stack, AllocType alloc_type);
146 void *asan_malloc(uptr size, StackTrace *stack);
147 void *asan_calloc(uptr nmemb, uptr size, StackTrace *stack);
148 void *asan_realloc(void *p, uptr size, StackTrace *stack);
149 void *asan_valloc(uptr size, StackTrace *stack);
150 void *asan_pvalloc(uptr size, StackTrace *stack);
152 int asan_posix_memalign(void **memptr, uptr alignment, uptr size,
153 StackTrace *stack);
154 uptr asan_malloc_usable_size(void *ptr, uptr pc, uptr bp);
156 uptr asan_mz_size(const void *ptr);
157 void asan_mz_force_lock();
158 void asan_mz_force_unlock();
160 void PrintInternalAllocatorStats();
162 } // namespace __asan
163 #endif // ASAN_ALLOCATOR_H