asan_malloc_linux.cc revision 709a33e1cf20eb7f00653fe32dc07714b3f2c633
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#include "asan_thread_registry.h" 23#include "sanitizer/asan_interface.h" 24 25#if ASAN_ANDROID 26DECLARE_REAL_AND_INTERCEPTOR(void*, malloc, uptr size) 27DECLARE_REAL_AND_INTERCEPTOR(void, free, void *ptr) 28DECLARE_REAL_AND_INTERCEPTOR(void*, calloc, uptr nmemb, uptr size) 29DECLARE_REAL_AND_INTERCEPTOR(void*, realloc, void *ptr, uptr size) 30DECLARE_REAL_AND_INTERCEPTOR(void*, memalign, uptr boundary, uptr size) 31 32struct MallocDebug { 33 void* (*malloc)(uptr bytes); 34 void (*free)(void* mem); 35 void* (*calloc)(uptr n_elements, uptr elem_size); 36 void* (*realloc)(void* oldMem, uptr bytes); 37 void* (*memalign)(uptr alignment, uptr bytes); 38}; 39 40const MallocDebug asan_malloc_dispatch ALIGNED(32) = { 41 WRAP(malloc), WRAP(free), WRAP(calloc), WRAP(realloc), WRAP(memalign) 42}; 43 44extern "C" const MallocDebug* __libc_malloc_dispatch; 45 46namespace __asan { 47void ReplaceSystemMalloc() { 48 __libc_malloc_dispatch = &asan_malloc_dispatch; 49} 50} // namespace __asan 51 52#else // ANDROID 53 54namespace __asan { 55void ReplaceSystemMalloc() { 56} 57} // namespace __asan 58#endif // ANDROID 59 60// ---------------------- Replacement functions ---------------- {{{1 61using namespace __asan; // NOLINT 62 63INTERCEPTOR(void, free, void *ptr) { 64 GET_STACK_TRACE_FREE; 65 asan_free(ptr, &stack, FROM_MALLOC); 66} 67 68INTERCEPTOR(void, cfree, void *ptr) { 69 GET_STACK_TRACE_FREE; 70 asan_free(ptr, &stack, FROM_MALLOC); 71} 72 73INTERCEPTOR(void*, malloc, uptr size) { 74 GET_STACK_TRACE_MALLOC; 75 return asan_malloc(size, &stack); 76} 77 78INTERCEPTOR(void*, calloc, uptr nmemb, uptr size) { 79 if (!asan_inited) { 80 // Hack: dlsym calls calloc before REAL(calloc) is retrieved from dlsym. 81 const uptr kCallocPoolSize = 1024; 82 static uptr calloc_memory_for_dlsym[kCallocPoolSize]; 83 static uptr allocated; 84 uptr size_in_words = ((nmemb * size) + kWordSize - 1) / kWordSize; 85 void *mem = (void*)&calloc_memory_for_dlsym[allocated]; 86 allocated += size_in_words; 87 CHECK(allocated < kCallocPoolSize); 88 return mem; 89 } 90 GET_STACK_TRACE_MALLOC; 91 return asan_calloc(nmemb, size, &stack); 92} 93 94INTERCEPTOR(void*, realloc, void *ptr, uptr size) { 95 GET_STACK_TRACE_MALLOC; 96 return asan_realloc(ptr, size, &stack); 97} 98 99INTERCEPTOR(void*, memalign, uptr boundary, uptr size) { 100 GET_STACK_TRACE_MALLOC; 101 return asan_memalign(boundary, size, &stack, FROM_MALLOC); 102} 103 104INTERCEPTOR(void*, __libc_memalign, uptr align, uptr s) 105 ALIAS("memalign"); 106 107INTERCEPTOR(uptr, malloc_usable_size, void *ptr) { 108 GET_STACK_TRACE_MALLOC; 109 return asan_malloc_usable_size(ptr, &stack); 110} 111 112// We avoid including malloc.h for portability reasons. 113// man mallinfo says the fields are "long", but the implementation uses int. 114// It doesn't matter much -- we just need to make sure that the libc's mallinfo 115// is not called. 116struct fake_mallinfo { 117 int x[10]; 118}; 119 120INTERCEPTOR(struct fake_mallinfo, mallinfo, void) { 121 struct fake_mallinfo res; 122 REAL(memset)(&res, 0, sizeof(res)); 123 return res; 124} 125 126INTERCEPTOR(int, mallopt, int cmd, int value) { 127 return -1; 128} 129 130INTERCEPTOR(int, posix_memalign, void **memptr, uptr alignment, uptr size) { 131 GET_STACK_TRACE_MALLOC; 132 // Printf("posix_memalign: %zx %zu\n", alignment, size); 133 return asan_posix_memalign(memptr, alignment, size, &stack); 134} 135 136INTERCEPTOR(void*, valloc, uptr size) { 137 GET_STACK_TRACE_MALLOC; 138 return asan_valloc(size, &stack); 139} 140 141INTERCEPTOR(void*, pvalloc, uptr size) { 142 GET_STACK_TRACE_MALLOC; 143 return asan_pvalloc(size, &stack); 144} 145 146INTERCEPTOR(void, malloc_stats, void) { 147 __asan_print_accumulated_stats(); 148} 149 150#endif // __linux__ 151