forked from OSchip/llvm-project
163 lines
4.3 KiB
C++
163 lines
4.3 KiB
C++
//===-- sanitizer_allocator_testlib.cc ------------------------------------===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
// Malloc replacement library based on CombinedAllocator.
|
|
// The primary purpose of this file is an end-to-end integration test
|
|
// for CombinedAllocator.
|
|
//===----------------------------------------------------------------------===//
|
|
/* Usage:
|
|
clang++ -fno-exceptions -g -fPIC -I. -I../include -Isanitizer \
|
|
sanitizer_common/tests/sanitizer_allocator_testlib.cc \
|
|
sanitizer_common/sanitizer_*.cc -shared -lpthread -o testmalloc.so
|
|
LD_PRELOAD=`pwd`/testmalloc.so /your/app
|
|
*/
|
|
#include "sanitizer_common/sanitizer_allocator.h"
|
|
#include "sanitizer_common/sanitizer_common.h"
|
|
#include <stddef.h>
|
|
#include <stdio.h>
|
|
#include <unistd.h>
|
|
#include <string.h>
|
|
#include <pthread.h>
|
|
|
|
#ifndef SANITIZER_MALLOC_HOOK
|
|
# define SANITIZER_MALLOC_HOOK(p, s)
|
|
#endif
|
|
|
|
#ifndef SANITIZER_FREE_HOOK
|
|
# define SANITIZER_FREE_HOOK(p)
|
|
#endif
|
|
|
|
namespace {
|
|
static const uptr kAllocatorSpace = 0x600000000000ULL;
|
|
static const uptr kAllocatorSize = 0x10000000000ULL; // 1T.
|
|
|
|
typedef SizeClassAllocator64<kAllocatorSpace, kAllocatorSize, 0,
|
|
CompactSizeClassMap> PrimaryAllocator;
|
|
typedef SizeClassAllocatorLocalCache<PrimaryAllocator> AllocatorCache;
|
|
typedef LargeMmapAllocator<> SecondaryAllocator;
|
|
typedef CombinedAllocator<PrimaryAllocator, AllocatorCache,
|
|
SecondaryAllocator> Allocator;
|
|
|
|
static Allocator allocator;
|
|
static bool global_inited;
|
|
static THREADLOCAL AllocatorCache cache;
|
|
static THREADLOCAL bool thread_inited;
|
|
static pthread_key_t pkey;
|
|
|
|
static void thread_dtor(void *v) {
|
|
if ((uptr)v != 3) {
|
|
pthread_setspecific(pkey, (void*)((uptr)v + 1));
|
|
return;
|
|
}
|
|
allocator.SwallowCache(&cache);
|
|
}
|
|
|
|
static void NOINLINE thread_init() {
|
|
if (!global_inited) {
|
|
global_inited = true;
|
|
allocator.Init();
|
|
pthread_key_create(&pkey, thread_dtor);
|
|
}
|
|
thread_inited = true;
|
|
pthread_setspecific(pkey, (void*)1);
|
|
cache.Init();
|
|
}
|
|
} // namespace
|
|
|
|
extern "C" {
|
|
void *malloc(size_t size) {
|
|
if (UNLIKELY(!thread_inited))
|
|
thread_init();
|
|
void *p = allocator.Allocate(&cache, size, 8);
|
|
SANITIZER_MALLOC_HOOK(p, size);
|
|
return p;
|
|
}
|
|
|
|
void free(void *p) {
|
|
if (UNLIKELY(!thread_inited))
|
|
thread_init();
|
|
SANITIZER_FREE_HOOK(p);
|
|
allocator.Deallocate(&cache, p);
|
|
}
|
|
|
|
void *calloc(size_t nmemb, size_t size) {
|
|
if (UNLIKELY(!thread_inited))
|
|
thread_init();
|
|
size *= nmemb;
|
|
void *p = allocator.Allocate(&cache, size, 8, false);
|
|
memset(p, 0, size);
|
|
SANITIZER_MALLOC_HOOK(p, size);
|
|
return p;
|
|
}
|
|
|
|
void *realloc(void *p, size_t size) {
|
|
if (UNLIKELY(!thread_inited))
|
|
thread_init();
|
|
if (p) {
|
|
SANITIZER_FREE_HOOK(p);
|
|
}
|
|
p = allocator.Reallocate(&cache, p, size, 8);
|
|
if (p) {
|
|
SANITIZER_MALLOC_HOOK(p, size);
|
|
}
|
|
return p;
|
|
}
|
|
|
|
void *memalign(size_t alignment, size_t size) {
|
|
if (UNLIKELY(!thread_inited))
|
|
thread_init();
|
|
void *p = allocator.Allocate(&cache, size, alignment);
|
|
SANITIZER_MALLOC_HOOK(p, size);
|
|
return p;
|
|
}
|
|
|
|
int posix_memalign(void **memptr, size_t alignment, size_t size) {
|
|
if (UNLIKELY(!thread_inited))
|
|
thread_init();
|
|
*memptr = allocator.Allocate(&cache, size, alignment);
|
|
SANITIZER_MALLOC_HOOK(*memptr, size);
|
|
return 0;
|
|
}
|
|
|
|
void *valloc(size_t size) {
|
|
if (UNLIKELY(!thread_inited))
|
|
thread_init();
|
|
if (size == 0)
|
|
size = GetPageSizeCached();
|
|
void *p = allocator.Allocate(&cache, size, GetPageSizeCached());
|
|
SANITIZER_MALLOC_HOOK(p, size);
|
|
return p;
|
|
}
|
|
|
|
void cfree(void *p) ALIAS("free");
|
|
void *pvalloc(size_t size) ALIAS("valloc");
|
|
void *__libc_memalign(size_t alignment, size_t size) ALIAS("memalign");
|
|
|
|
void malloc_usable_size() {
|
|
}
|
|
|
|
void mallinfo() {
|
|
}
|
|
|
|
void mallopt() {
|
|
}
|
|
} // extern "C"
|
|
|
|
namespace std {
|
|
struct nothrow_t;
|
|
}
|
|
|
|
void *operator new(size_t size) ALIAS("malloc");
|
|
void *operator new[](size_t size) ALIAS("malloc");
|
|
void *operator new(size_t size, std::nothrow_t const&) ALIAS("malloc");
|
|
void *operator new[](size_t size, std::nothrow_t const&) ALIAS("malloc");
|
|
void operator delete(void *ptr) ALIAS("free");
|
|
void operator delete[](void *ptr) ALIAS("free");
|
|
void operator delete(void *ptr, std::nothrow_t const&) ALIAS("free");
|
|
void operator delete[](void *ptr, std::nothrow_t const&) ALIAS("free");
|