• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===-- sanitizer_allocator_testlib.cc ------------------------------------===//
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 // Malloc replacement library based on CombinedAllocator.
10 // The primary purpose of this file is an end-to-end integration test
11 // for CombinedAllocator.
12 //===----------------------------------------------------------------------===//
13 /* Usage:
14 clang++ -std=c++11 -fno-exceptions  -g -fPIC -I. -I../include -Isanitizer \
15  sanitizer_common/tests/sanitizer_allocator_testlib.cc \
16  $(\ls sanitizer_common/sanitizer_*.cc | grep -v sanitizer_common_nolibc.cc) \
17  -shared -lpthread -o testmalloc.so
18 LD_PRELOAD=`pwd`/testmalloc.so /your/app
19 */
20 #include "sanitizer_common/sanitizer_allocator.h"
21 #include "sanitizer_common/sanitizer_common.h"
22 #include <stddef.h>
23 #include <stdio.h>
24 #include <unistd.h>
25 #include <string.h>
26 #include <pthread.h>
27 
28 #ifndef SANITIZER_MALLOC_HOOK
29 # define SANITIZER_MALLOC_HOOK(p, s)
30 #endif
31 
32 #ifndef SANITIZER_FREE_HOOK
33 # define SANITIZER_FREE_HOOK(p)
34 #endif
35 
36 namespace {
37 static const uptr kAllocatorSpace = 0x600000000000ULL;
38 static const uptr kAllocatorSize  =  0x10000000000ULL;  // 1T.
39 
40 // typedef SizeClassAllocator64<kAllocatorSpace, kAllocatorSize, 0,
41 typedef SizeClassAllocator64<~(uptr)0, kAllocatorSize, 0,
42   CompactSizeClassMap> PrimaryAllocator;
43 typedef SizeClassAllocatorLocalCache<PrimaryAllocator> AllocatorCache;
44 typedef LargeMmapAllocator<> SecondaryAllocator;
45 typedef CombinedAllocator<PrimaryAllocator, AllocatorCache,
46           SecondaryAllocator> Allocator;
47 
48 static Allocator allocator;
49 static bool global_inited;
50 static THREADLOCAL AllocatorCache cache;
51 static THREADLOCAL bool thread_inited;
52 static pthread_key_t pkey;
53 
thread_dtor(void * v)54 static void thread_dtor(void *v) {
55   if ((uptr)v != 3) {
56     pthread_setspecific(pkey, (void*)((uptr)v + 1));
57     return;
58   }
59   allocator.SwallowCache(&cache);
60 }
61 
thread_init()62 static void NOINLINE thread_init() {
63   if (!global_inited) {
64     global_inited = true;
65     allocator.Init(false /*may_return_null*/);
66     pthread_key_create(&pkey, thread_dtor);
67   }
68   thread_inited = true;
69   pthread_setspecific(pkey, (void*)1);
70   cache.Init(nullptr);
71 }
72 }  // namespace
73 
74 extern "C" {
malloc(size_t size)75 void *malloc(size_t size) {
76   if (UNLIKELY(!thread_inited))
77     thread_init();
78   void *p = allocator.Allocate(&cache, size, 8);
79   SANITIZER_MALLOC_HOOK(p, size);
80   return p;
81 }
82 
free(void * p)83 void free(void *p) {
84   if (UNLIKELY(!thread_inited))
85     thread_init();
86   SANITIZER_FREE_HOOK(p);
87   allocator.Deallocate(&cache, p);
88 }
89 
calloc(size_t nmemb,size_t size)90 void *calloc(size_t nmemb, size_t size) {
91   if (UNLIKELY(!thread_inited))
92     thread_init();
93   size *= nmemb;
94   void *p = allocator.Allocate(&cache, size, 8, false);
95   memset(p, 0, size);
96   SANITIZER_MALLOC_HOOK(p, size);
97   return p;
98 }
99 
realloc(void * p,size_t size)100 void *realloc(void *p, size_t size) {
101   if (UNLIKELY(!thread_inited))
102     thread_init();
103   if (p) {
104     SANITIZER_FREE_HOOK(p);
105   }
106   p = allocator.Reallocate(&cache, p, size, 8);
107   if (p) {
108     SANITIZER_MALLOC_HOOK(p, size);
109   }
110   return p;
111 }
112 
memalign(size_t alignment,size_t size)113 void *memalign(size_t alignment, size_t size) {
114   if (UNLIKELY(!thread_inited))
115     thread_init();
116   void *p = allocator.Allocate(&cache, size, alignment);
117   SANITIZER_MALLOC_HOOK(p, size);
118   return p;
119 }
120 
posix_memalign(void ** memptr,size_t alignment,size_t size)121 int posix_memalign(void **memptr, size_t alignment, size_t size) {
122   if (UNLIKELY(!thread_inited))
123     thread_init();
124   *memptr = allocator.Allocate(&cache, size, alignment);
125   SANITIZER_MALLOC_HOOK(*memptr, size);
126   return 0;
127 }
128 
valloc(size_t size)129 void *valloc(size_t size) {
130   if (UNLIKELY(!thread_inited))
131     thread_init();
132   if (size == 0)
133     size = GetPageSizeCached();
134   void *p = allocator.Allocate(&cache, size, GetPageSizeCached());
135   SANITIZER_MALLOC_HOOK(p, size);
136   return p;
137 }
138 
139 void cfree(void *p) ALIAS("free");
140 void *pvalloc(size_t size) ALIAS("valloc");
141 void *__libc_memalign(size_t alignment, size_t size) ALIAS("memalign");
142 
malloc_usable_size()143 void malloc_usable_size() {
144 }
145 
mallinfo()146 void mallinfo() {
147 }
148 
mallopt()149 void mallopt() {
150 }
151 }  // extern "C"
152 
153 namespace std {
154   struct nothrow_t;
155 }
156 
157 void *operator new(size_t size) ALIAS("malloc");
158 void *operator new[](size_t size) ALIAS("malloc");
159 void *operator new(size_t size, std::nothrow_t const&) ALIAS("malloc");
160 void *operator new[](size_t size, std::nothrow_t const&) ALIAS("malloc");
161 void operator delete(void *ptr) throw() ALIAS("free");
162 void operator delete[](void *ptr) throw() ALIAS("free");
163 void operator delete(void *ptr, std::nothrow_t const&) ALIAS("free");
164 void operator delete[](void *ptr, std::nothrow_t const&) ALIAS("free");
165