1 //===-- asan_allocator.h ----------------------------------------*- C++ -*-===//
3 // This file is distributed under the University of Illinois Open Source
4 // License. See LICENSE.TXT for details.
6 //===----------------------------------------------------------------------===//
8 // This file is a part of AddressSanitizer, an address sanity checker.
10 // ASan-private header for asan_allocator.cc.
11 //===----------------------------------------------------------------------===//
13 #ifndef ASAN_ALLOCATOR_H
14 #define ASAN_ALLOCATOR_H
16 #include "asan_internal.h"
17 #include "asan_interceptors.h"
21 static const uptr kNumberOfSizeClasses
= 255;
26 explicit AsanChunkView(AsanChunk
*chunk
) : chunk_(chunk
) {}
27 bool IsValid() { return chunk_
!= 0; }
28 uptr
Beg(); // first byte of user memory.
29 uptr
End(); // last byte of user memory.
30 uptr
UsedSize(); // size requested by the user.
33 void GetAllocStack(StackTrace
*stack
);
34 void GetFreeStack(StackTrace
*stack
);
35 bool AddrIsInside(uptr addr
, uptr access_size
, uptr
*offset
);
36 bool AddrIsAtLeft(uptr addr
, uptr access_size
, uptr
*offset
);
37 bool AddrIsAtRight(uptr addr
, uptr access_size
, uptr
*offset
);
39 AsanChunk
*const chunk_
;
42 AsanChunkView
FindHeapChunkByAddress(uptr address
);
44 class AsanChunkFifoList
{
46 explicit AsanChunkFifoList(LinkerInitialized
) { }
47 AsanChunkFifoList() { clear(); }
48 void Push(AsanChunk
*n
);
49 void PushList(AsanChunkFifoList
*q
);
51 uptr
size() { return size_
; }
62 struct AsanThreadLocalMallocStorage
{
63 explicit AsanThreadLocalMallocStorage(LinkerInitialized x
)
65 AsanThreadLocalMallocStorage() {
67 REAL(memset
)(this, 0, sizeof(AsanThreadLocalMallocStorage
));
70 AsanChunkFifoList quarantine_
;
71 AsanChunk
*free_lists_
[kNumberOfSizeClasses
];
75 // Fake stack frame contains local variables of one function.
76 // This struct should fit into a stack redzone (32 bytes).
78 uptr magic
; // Modified by the instrumented code.
79 uptr descr
; // Modified by the instrumented code.
82 u64 size_minus_one
: 16;
85 struct FakeFrameFifo
{
87 void FifoPush(FakeFrame
*node
);
90 FakeFrame
*first_
, *last_
;
95 void LifoPush(FakeFrame
*node
) {
103 FakeFrame
*top() { return top_
; }
108 // For each thread we create a fake stack and place stack objects on this fake
109 // stack instead of the real stack. The fake stack is not really a stack but
110 // a fast malloc-like allocator so that when a function exits the fake stack
111 // is not poped but remains there for quite some time until gets used again.
112 // So, we poison the objects on the fake stack when function returns.
113 // It helps us find use-after-return bugs.
114 // We can not rely on __asan_stack_free being called on every function exit,
115 // so we maintain a lifo list of all current fake frames and update it on every
116 // call to __asan_stack_malloc.
120 explicit FakeStack(LinkerInitialized
) {}
121 void Init(uptr stack_size
);
122 void StopUsingFakeStack() { alive_
= false; }
124 uptr
AllocateStack(uptr size
, uptr real_stack
);
125 static void OnFree(uptr ptr
, uptr size
, uptr real_stack
);
126 // Return the bottom of the maped region.
127 uptr
AddrIsInFakeStack(uptr addr
);
128 bool StackSize() { return stack_size_
; }
131 static const uptr kMinStackFrameSizeLog
= 9; // Min frame is 512B.
132 static const uptr kMaxStackFrameSizeLog
= 16; // Max stack frame is 64K.
133 static const uptr kMaxStackMallocSize
= 1 << kMaxStackFrameSizeLog
;
134 static const uptr kNumberOfSizeClasses
=
135 kMaxStackFrameSizeLog
- kMinStackFrameSizeLog
+ 1;
137 bool AddrIsInSizeClass(uptr addr
, uptr size_class
);
139 // Each size class should be large enough to hold all frames.
140 uptr
ClassMmapSize(uptr size_class
);
142 uptr
ClassSize(uptr size_class
) {
143 return 1UL << (size_class
+ kMinStackFrameSizeLog
);
146 void DeallocateFrame(FakeFrame
*fake_frame
);
148 uptr
ComputeSizeClass(uptr alloc_size
);
149 void AllocateOneSizeClass(uptr size_class
);
154 uptr allocated_size_classes_
[kNumberOfSizeClasses
];
155 FakeFrameFifo size_classes_
[kNumberOfSizeClasses
];
156 FakeFrameLifo call_stack_
;
159 void *asan_memalign(uptr alignment
, uptr size
, StackTrace
*stack
);
160 void asan_free(void *ptr
, StackTrace
*stack
);
162 void *asan_malloc(uptr size
, StackTrace
*stack
);
163 void *asan_calloc(uptr nmemb
, uptr size
, StackTrace
*stack
);
164 void *asan_realloc(void *p
, uptr size
, StackTrace
*stack
);
165 void *asan_valloc(uptr size
, StackTrace
*stack
);
166 void *asan_pvalloc(uptr size
, StackTrace
*stack
);
168 int asan_posix_memalign(void **memptr
, uptr alignment
, uptr size
,
170 uptr
asan_malloc_usable_size(void *ptr
, StackTrace
*stack
);
172 uptr
asan_mz_size(const void *ptr
);
173 void asan_mz_force_lock();
174 void asan_mz_force_unlock();
176 } // namespace __asan
177 #endif // ASAN_ALLOCATOR_H