asan_malloc_linux.cc revision e5f5895bda30f374b0b51412fd4d837fa59aed66
1//===-- asan_malloc_linux.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// 10// This file is a part of AddressSanitizer, an address sanity checker. 11// 12// Linux-specific malloc interception. 13// We simply define functions like malloc, free, realloc, etc. 14// They will replace the corresponding libc functions automagically. 15//===----------------------------------------------------------------------===// 16#ifdef __linux__ 17 18#include "asan_allocator.h" 19#include "asan_interceptors.h" 20#include "asan_internal.h" 21#include "asan_stack.h" 22 23#include <malloc.h> 24 25#ifdef ANDROID 26struct MallocDebug { 27 void* (*malloc)(size_t bytes); 28 void (*free)(void* mem); 29 void* (*calloc)(size_t n_elements, size_t elem_size); 30 void* (*realloc)(void* oldMem, size_t bytes); 31 void* (*memalign)(size_t alignment, size_t bytes); 32}; 33 34const MallocDebug asan_malloc_dispatch ALIGNED(32) = { 35 malloc, free, calloc, realloc, memalign 36}; 37 38extern "C" const MallocDebug* __libc_malloc_dispatch; 39 40namespace __asan { 41void ReplaceSystemMalloc() { 42 __libc_malloc_dispatch = &asan_malloc_dispatch; 43} 44} // namespace __asan 45 46#else // ANDROID 47 48namespace __asan { 49void ReplaceSystemMalloc() { 50} 51} // namespace __asan 52#endif // ANDROID 53 54// ---------------------- Replacement functions ---------------- {{{1 55using namespace __asan; // NOLINT 56 57INTERCEPTOR(void, free, void *ptr) { 58 GET_STACK_TRACE_HERE_FOR_FREE(ptr); 59 asan_free(ptr, &stack); 60} 61 62INTERCEPTOR(void, cfree, void *ptr) { 63 GET_STACK_TRACE_HERE_FOR_FREE(ptr); 64 asan_free(ptr, &stack); 65} 66 67INTERCEPTOR(void*, malloc, size_t size) { 68 GET_STACK_TRACE_HERE_FOR_MALLOC; 69 return asan_malloc(size, &stack); 70} 71 72INTERCEPTOR(void*, calloc, size_t nmemb, size_t size) { 73 if (!asan_inited) { 74 // Hack: dlsym calls calloc before REAL(calloc) is retrieved from dlsym. 75 const size_t kCallocPoolSize = 1024; 76 static uptr calloc_memory_for_dlsym[kCallocPoolSize]; 77 static size_t allocated; 78 size_t size_in_words = ((nmemb * size) + kWordSize - 1) / kWordSize; 79 void *mem = (void*)&calloc_memory_for_dlsym[allocated]; 80 allocated += size_in_words; 81 CHECK(allocated < kCallocPoolSize); 82 return mem; 83 } 84 GET_STACK_TRACE_HERE_FOR_MALLOC; 85 return asan_calloc(nmemb, size, &stack); 86} 87 88INTERCEPTOR(void*, realloc, void *ptr, size_t size) { 89 GET_STACK_TRACE_HERE_FOR_MALLOC; 90 return asan_realloc(ptr, size, &stack); 91} 92 93INTERCEPTOR(void*, memalign, size_t boundary, size_t size) { 94 GET_STACK_TRACE_HERE_FOR_MALLOC; 95 return asan_memalign(boundary, size, &stack); 96} 97 98INTERCEPTOR(void*, __libc_memalign, size_t align, size_t s) 99 ALIAS("memalign"); 100 101INTERCEPTOR(size_t, malloc_usable_size, void *ptr) { 102 GET_STACK_TRACE_HERE_FOR_MALLOC; 103 return asan_malloc_usable_size(ptr, &stack); 104} 105 106INTERCEPTOR(struct mallinfo, mallinfo) { 107 struct mallinfo res; 108 REAL(memset)(&res, 0, sizeof(res)); 109 return res; 110} 111 112INTERCEPTOR(int, mallopt, int cmd, int value) { 113 return -1; 114} 115 116INTERCEPTOR(int, posix_memalign, void **memptr, size_t alignment, size_t size) { 117 GET_STACK_TRACE_HERE_FOR_MALLOC; 118 // Printf("posix_memalign: %zx %zu\n", alignment, size); 119 return asan_posix_memalign(memptr, alignment, size, &stack); 120} 121 122INTERCEPTOR(void*, valloc, size_t size) { 123 GET_STACK_TRACE_HERE_FOR_MALLOC; 124 return asan_valloc(size, &stack); 125} 126 127INTERCEPTOR(void*, pvalloc, size_t size) { 128 GET_STACK_TRACE_HERE_FOR_MALLOC; 129 return asan_pvalloc(size, &stack); 130} 131 132#endif // __linux__ 133