sanitizer_allocator_testlib.cc revision 8b29217930dc4f8730cfecbdcb1c7041e1ea735a
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 THREADLOCAL AllocatorCache cache;
48static THREADLOCAL bool global_inited;
49static THREADLOCAL bool thread_inited;
50static pthread_key_t pkey;
51
52static void thread_dtor(void *v) {
53  if ((long)v != 3) {
54    pthread_setspecific(pkey, (void*)((long)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" {
73
74void *malloc(size_t size) {
75  if (UNLIKELY(!thread_inited))
76    thread_init();
77  void *p = allocator.Allocate(&cache, size, 8);
78  SANITIZER_MALLOC_HOOK(p, size);
79  return p;
80}
81
82void free(void *p) {
83  if (UNLIKELY(!thread_inited))
84    thread_init();
85  SANITIZER_FREE_HOOK(p);
86  allocator.Deallocate(&cache, p);
87}
88
89void *calloc(size_t nmemb, size_t size) {
90  if (UNLIKELY(!thread_inited))
91    thread_init();
92  size *= nmemb;
93  void *p = allocator.Allocate(&cache, size, 8, false);
94  memset(p, 0, size);
95  SANITIZER_MALLOC_HOOK(p, size);
96  return p;
97}
98
99void *realloc(void *p, size_t size) {
100  if (UNLIKELY(!thread_inited))
101    thread_init();
102  if (p) {
103    SANITIZER_FREE_HOOK(p);
104  }
105  p = allocator.Reallocate(&cache, p, size, 8);
106  if (p) {
107    SANITIZER_MALLOC_HOOK(p, size);
108  }
109  return p;
110}
111
112void *memalign(size_t alignment, size_t size) {
113  if (UNLIKELY(!thread_inited))
114    thread_init();
115  void *p = allocator.Allocate(&cache, size, alignment);
116  SANITIZER_MALLOC_HOOK(p, size);
117  return p;
118}
119
120int posix_memalign(void **memptr, size_t alignment, size_t size) {
121  if (UNLIKELY(!thread_inited))
122    thread_init();
123  *memptr = allocator.Allocate(&cache, size, alignment);
124  SANITIZER_MALLOC_HOOK(*memptr, size);
125  return 0;
126}
127
128void *valloc(size_t size) {
129  if (UNLIKELY(!thread_inited))
130    thread_init();
131  if (size == 0)
132    size = GetPageSizeCached();
133  void *p = allocator.Allocate(&cache, size, GetPageSizeCached());
134  SANITIZER_MALLOC_HOOK(p, size);
135  return p;
136}
137
138void cfree(void *p) ALIAS("free");
139void *pvalloc(size_t size) ALIAS("valloc");
140void *__libc_memalign(size_t alignment, size_t size) ALIAS("memalign");
141
142void malloc_usable_size() {
143}
144
145void mallinfo() {
146}
147
148void mallopt() {
149}
150
151}  // extern "C"
152