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: 14clang++ -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 17LD_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 35namespace { 36static const uptr kAllocatorSpace = 0x600000000000ULL; 37static const uptr kAllocatorSize = 0x10000000000ULL; // 1T. 38 39typedef SizeClassAllocator64<kAllocatorSpace, kAllocatorSize, 0, 40 CompactSizeClassMap> PrimaryAllocator; 41typedef SizeClassAllocatorLocalCache<PrimaryAllocator> AllocatorCache; 42typedef LargeMmapAllocator<> SecondaryAllocator; 43typedef CombinedAllocator<PrimaryAllocator, AllocatorCache, 44 SecondaryAllocator> Allocator; 45 46static Allocator allocator; 47static bool global_inited; 48static THREADLOCAL AllocatorCache cache; 49static THREADLOCAL bool thread_inited; 50static pthread_key_t pkey; 51 52static 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 60static 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 72extern "C" { 73void *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 81void free(void *p) { 82 if (UNLIKELY(!thread_inited)) 83 thread_init(); 84 SANITIZER_FREE_HOOK(p); 85 allocator.Deallocate(&cache, p); 86} 87 88void *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 98void *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 111void *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 119int 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 127void *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 137void cfree(void *p) ALIAS("free"); 138void *pvalloc(size_t size) ALIAS("valloc"); 139void *__libc_memalign(size_t alignment, size_t size) ALIAS("memalign"); 140 141void malloc_usable_size() { 142} 143 144void mallinfo() { 145} 146 147void mallopt() { 148} 149} // extern "C" 150 151namespace std { 152 struct nothrow_t; 153} 154 155void *operator new(size_t size) ALIAS("malloc"); 156void *operator new[](size_t size) ALIAS("malloc"); 157void *operator new(size_t size, std::nothrow_t const&) ALIAS("malloc"); 158void *operator new[](size_t size, std::nothrow_t const&) ALIAS("malloc"); 159void operator delete(void *ptr) throw() ALIAS("free"); 160void operator delete[](void *ptr) throw() ALIAS("free"); 161void operator delete(void *ptr, std::nothrow_t const&) ALIAS("free"); 162void operator delete[](void *ptr, std::nothrow_t const&) ALIAS("free"); 163