2014-06-05 Julian Brown <julian@codesourcery.com>
[official-gcc.git] / libsanitizer / asan / asan_allocator.h
blob174a5997d4bb1b2f1152b595debf5cb7c75075a9
1 //===-- asan_allocator.h ----------------------------------------*- C++ -*-===//
2 //
3 // This file is distributed under the University of Illinois Open Source
4 // License. See LICENSE.TXT for details.
5 //
6 //===----------------------------------------------------------------------===//
7 //
8 // This file is a part of AddressSanitizer, an address sanity checker.
9 //
10 // ASan-private header for asan_allocator2.cc.
11 //===----------------------------------------------------------------------===//
13 #ifndef ASAN_ALLOCATOR_H
14 #define ASAN_ALLOCATOR_H
16 #include "asan_internal.h"
17 #include "asan_interceptors.h"
18 #include "sanitizer_common/sanitizer_allocator.h"
19 #include "sanitizer_common/sanitizer_list.h"
21 namespace __asan {
23 enum AllocType {
24 FROM_MALLOC = 1, // Memory block came from malloc, calloc, realloc, etc.
25 FROM_NEW = 2, // Memory block came from operator new.
26 FROM_NEW_BR = 3 // Memory block came from operator new [ ]
29 static const uptr kNumberOfSizeClasses = 255;
30 struct AsanChunk;
32 void InitializeAllocator();
33 void ReInitializeAllocator();
35 class AsanChunkView {
36 public:
37 explicit AsanChunkView(AsanChunk *chunk) : chunk_(chunk) {}
38 bool IsValid(); // Checks if AsanChunkView points to a valid allocated
39 // or quarantined chunk.
40 uptr Beg(); // First byte of user memory.
41 uptr End(); // Last byte of user memory.
42 uptr UsedSize(); // Size requested by the user.
43 uptr AllocTid();
44 uptr FreeTid();
45 bool Eq(const AsanChunkView &c) const { return chunk_ == c.chunk_; }
46 void GetAllocStack(StackTrace *stack);
47 void GetFreeStack(StackTrace *stack);
48 bool AddrIsInside(uptr addr, uptr access_size, sptr *offset) {
49 if (addr >= Beg() && (addr + access_size) <= End()) {
50 *offset = addr - Beg();
51 return true;
53 return false;
55 bool AddrIsAtLeft(uptr addr, uptr access_size, sptr *offset) {
56 (void)access_size;
57 if (addr < Beg()) {
58 *offset = Beg() - addr;
59 return true;
61 return false;
63 bool AddrIsAtRight(uptr addr, uptr access_size, sptr *offset) {
64 if (addr + access_size > End()) {
65 *offset = addr - End();
66 return true;
68 return false;
71 private:
72 AsanChunk *const chunk_;
75 AsanChunkView FindHeapChunkByAddress(uptr address);
77 // List of AsanChunks with total size.
78 class AsanChunkFifoList: public IntrusiveList<AsanChunk> {
79 public:
80 explicit AsanChunkFifoList(LinkerInitialized) { }
81 AsanChunkFifoList() { clear(); }
82 void Push(AsanChunk *n);
83 void PushList(AsanChunkFifoList *q);
84 AsanChunk *Pop();
85 uptr size() { return size_; }
86 void clear() {
87 IntrusiveList<AsanChunk>::clear();
88 size_ = 0;
90 private:
91 uptr size_;
94 struct AsanMapUnmapCallback {
95 void OnMap(uptr p, uptr size) const;
96 void OnUnmap(uptr p, uptr size) const;
99 #if SANITIZER_CAN_USE_ALLOCATOR64
100 # if defined(__powerpc64__)
101 const uptr kAllocatorSpace = 0xa0000000000ULL;
102 const uptr kAllocatorSize = 0x20000000000ULL; // 2T.
103 # else
104 const uptr kAllocatorSpace = 0x600000000000ULL;
105 const uptr kAllocatorSize = 0x40000000000ULL; // 4T.
106 # endif
107 typedef DefaultSizeClassMap SizeClassMap;
108 typedef SizeClassAllocator64<kAllocatorSpace, kAllocatorSize, 0 /*metadata*/,
109 SizeClassMap, AsanMapUnmapCallback> PrimaryAllocator;
110 #else // Fallback to SizeClassAllocator32.
111 static const uptr kRegionSizeLog = 20;
112 static const uptr kNumRegions = SANITIZER_MMAP_RANGE_SIZE >> kRegionSizeLog;
113 # if SANITIZER_WORDSIZE == 32
114 typedef FlatByteMap<kNumRegions> ByteMap;
115 # elif SANITIZER_WORDSIZE == 64
116 typedef TwoLevelByteMap<(kNumRegions >> 12), 1 << 12> ByteMap;
117 # endif
118 typedef CompactSizeClassMap SizeClassMap;
119 typedef SizeClassAllocator32<0, SANITIZER_MMAP_RANGE_SIZE, 16,
120 SizeClassMap, kRegionSizeLog,
121 ByteMap,
122 AsanMapUnmapCallback> PrimaryAllocator;
123 #endif // SANITIZER_CAN_USE_ALLOCATOR64
125 typedef SizeClassAllocatorLocalCache<PrimaryAllocator> AllocatorCache;
126 typedef LargeMmapAllocator<AsanMapUnmapCallback> SecondaryAllocator;
127 typedef CombinedAllocator<PrimaryAllocator, AllocatorCache,
128 SecondaryAllocator> Allocator;
131 struct AsanThreadLocalMallocStorage {
132 uptr quarantine_cache[16];
133 AllocatorCache allocator2_cache;
134 void CommitBack();
135 private:
136 // These objects are allocated via mmap() and are zero-initialized.
137 AsanThreadLocalMallocStorage() {}
140 void *asan_memalign(uptr alignment, uptr size, StackTrace *stack,
141 AllocType alloc_type);
142 void asan_free(void *ptr, StackTrace *stack, AllocType alloc_type);
144 void *asan_malloc(uptr size, StackTrace *stack);
145 void *asan_calloc(uptr nmemb, uptr size, StackTrace *stack);
146 void *asan_realloc(void *p, uptr size, StackTrace *stack);
147 void *asan_valloc(uptr size, StackTrace *stack);
148 void *asan_pvalloc(uptr size, StackTrace *stack);
150 int asan_posix_memalign(void **memptr, uptr alignment, uptr size,
151 StackTrace *stack);
152 uptr asan_malloc_usable_size(void *ptr, uptr pc, uptr bp);
154 uptr asan_mz_size(const void *ptr);
155 void asan_mz_force_lock();
156 void asan_mz_force_unlock();
158 void PrintInternalAllocatorStats();
160 } // namespace __asan
161 #endif // ASAN_ALLOCATOR_H