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