blob: 1046f4c843a8ebc759ef6cad782f1327042b83b5 [file] [log] [blame]
Alexey Samsonov485d3dc2012-06-04 13:50:10 +00001//===-- asan_malloc_linux.cc ----------------------------------------------===//
Kostya Serebryany019b76f2011-11-30 01:07:02 +00002//
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//===----------------------------------------------------------------------===//
Kostya Serebryany5dfa4da2011-12-01 21:40:52 +000016#ifdef __linux__
Kostya Serebryany019b76f2011-11-30 01:07:02 +000017
18#include "asan_allocator.h"
19#include "asan_interceptors.h"
20#include "asan_internal.h"
21#include "asan_stack.h"
22
Kostya Serebryany019b76f2011-11-30 01:07:02 +000023#ifdef ANDROID
24struct MallocDebug {
Kostya Serebryany0e0832b2012-06-25 09:58:29 +000025 void* (*malloc)(uptr bytes);
Kostya Serebryany019b76f2011-11-30 01:07:02 +000026 void (*free)(void* mem);
Kostya Serebryany0e0832b2012-06-25 09:58:29 +000027 void* (*calloc)(uptr n_elements, uptr elem_size);
28 void* (*realloc)(void* oldMem, uptr bytes);
29 void* (*memalign)(uptr alignment, uptr bytes);
Kostya Serebryany019b76f2011-11-30 01:07:02 +000030};
31
Alexey Samsonov23e3b902012-02-03 08:37:19 +000032const MallocDebug asan_malloc_dispatch ALIGNED(32) = {
Kostya Serebryany019b76f2011-11-30 01:07:02 +000033 malloc, free, calloc, realloc, memalign
34};
35
36extern "C" const MallocDebug* __libc_malloc_dispatch;
37
38namespace __asan {
39void ReplaceSystemMalloc() {
40 __libc_malloc_dispatch = &asan_malloc_dispatch;
41}
42} // namespace __asan
43
44#else // ANDROID
45
46namespace __asan {
47void ReplaceSystemMalloc() {
48}
49} // namespace __asan
50#endif // ANDROID
51
52// ---------------------- Replacement functions ---------------- {{{1
53using namespace __asan; // NOLINT
54
Alexey Samsonov15965f92012-02-02 10:39:40 +000055INTERCEPTOR(void, free, void *ptr) {
Kostya Serebryany019b76f2011-11-30 01:07:02 +000056 GET_STACK_TRACE_HERE_FOR_FREE(ptr);
57 asan_free(ptr, &stack);
58}
59
Alexey Samsonov15965f92012-02-02 10:39:40 +000060INTERCEPTOR(void, cfree, void *ptr) {
Kostya Serebryany019b76f2011-11-30 01:07:02 +000061 GET_STACK_TRACE_HERE_FOR_FREE(ptr);
62 asan_free(ptr, &stack);
63}
64
Kostya Serebryany0e0832b2012-06-25 09:58:29 +000065INTERCEPTOR(void*, malloc, uptr size) {
Kostya Serebryany019b76f2011-11-30 01:07:02 +000066 GET_STACK_TRACE_HERE_FOR_MALLOC;
67 return asan_malloc(size, &stack);
68}
69
Kostya Serebryany0e0832b2012-06-25 09:58:29 +000070INTERCEPTOR(void*, calloc, uptr nmemb, uptr size) {
Kostya Serebryany019b76f2011-11-30 01:07:02 +000071 if (!asan_inited) {
Alexey Samsonove7254782012-02-08 13:45:31 +000072 // Hack: dlsym calls calloc before REAL(calloc) is retrieved from dlsym.
Kostya Serebryany0e0832b2012-06-25 09:58:29 +000073 const uptr kCallocPoolSize = 1024;
Kostya Serebryany8d032042012-05-31 14:35:53 +000074 static uptr calloc_memory_for_dlsym[kCallocPoolSize];
Kostya Serebryany0e0832b2012-06-25 09:58:29 +000075 static uptr allocated;
76 uptr size_in_words = ((nmemb * size) + kWordSize - 1) / kWordSize;
Kostya Serebryany019b76f2011-11-30 01:07:02 +000077 void *mem = (void*)&calloc_memory_for_dlsym[allocated];
78 allocated += size_in_words;
79 CHECK(allocated < kCallocPoolSize);
80 return mem;
81 }
82 GET_STACK_TRACE_HERE_FOR_MALLOC;
83 return asan_calloc(nmemb, size, &stack);
84}
85
Kostya Serebryany0e0832b2012-06-25 09:58:29 +000086INTERCEPTOR(void*, realloc, void *ptr, uptr size) {
Kostya Serebryany019b76f2011-11-30 01:07:02 +000087 GET_STACK_TRACE_HERE_FOR_MALLOC;
88 return asan_realloc(ptr, size, &stack);
89}
90
Kostya Serebryany0e0832b2012-06-25 09:58:29 +000091INTERCEPTOR(void*, memalign, uptr boundary, uptr size) {
Kostya Serebryany019b76f2011-11-30 01:07:02 +000092 GET_STACK_TRACE_HERE_FOR_MALLOC;
93 return asan_memalign(boundary, size, &stack);
94}
95
Kostya Serebryany0e0832b2012-06-25 09:58:29 +000096INTERCEPTOR(void*, __libc_memalign, uptr align, uptr s)
Alexey Samsonov23e3b902012-02-03 08:37:19 +000097 ALIAS("memalign");
Kostya Serebryany019b76f2011-11-30 01:07:02 +000098
Kostya Serebryany0e0832b2012-06-25 09:58:29 +000099INTERCEPTOR(uptr, malloc_usable_size, void *ptr) {
Alexey Samsonov209c5142012-01-17 06:39:10 +0000100 GET_STACK_TRACE_HERE_FOR_MALLOC;
101 return asan_malloc_usable_size(ptr, &stack);
102}
103
Kostya Serebryany0e0832b2012-06-25 09:58:29 +0000104// We avoid including malloc.h for portability reasons.
105// man mallinfo says the fields are "long", but the implementation uses int.
106// It doesn't matter much -- we just need to make sure that the libc's mallinfo
107// is not called.
108struct fake_mallinfo {
109 int x[10];
110};
111
112INTERCEPTOR(struct fake_mallinfo, mallinfo, void) {
113 struct fake_mallinfo res;
Alexey Samsonove7254782012-02-08 13:45:31 +0000114 REAL(memset)(&res, 0, sizeof(res));
Kostya Serebryany019b76f2011-11-30 01:07:02 +0000115 return res;
116}
117
Alexey Samsonov15965f92012-02-02 10:39:40 +0000118INTERCEPTOR(int, mallopt, int cmd, int value) {
Kostya Serebryany019b76f2011-11-30 01:07:02 +0000119 return -1;
120}
121
Kostya Serebryany0e0832b2012-06-25 09:58:29 +0000122INTERCEPTOR(int, posix_memalign, void **memptr, uptr alignment, uptr size) {
Kostya Serebryany019b76f2011-11-30 01:07:02 +0000123 GET_STACK_TRACE_HERE_FOR_MALLOC;
Evgeniy Stepanov823085a2012-03-21 11:32:46 +0000124 // Printf("posix_memalign: %zx %zu\n", alignment, size);
Kostya Serebryany019b76f2011-11-30 01:07:02 +0000125 return asan_posix_memalign(memptr, alignment, size, &stack);
126}
127
Kostya Serebryany0e0832b2012-06-25 09:58:29 +0000128INTERCEPTOR(void*, valloc, uptr size) {
Kostya Serebryany019b76f2011-11-30 01:07:02 +0000129 GET_STACK_TRACE_HERE_FOR_MALLOC;
130 return asan_valloc(size, &stack);
131}
132
Kostya Serebryany0e0832b2012-06-25 09:58:29 +0000133INTERCEPTOR(void*, pvalloc, uptr size) {
Kostya Serebryany019b76f2011-11-30 01:07:02 +0000134 GET_STACK_TRACE_HERE_FOR_MALLOC;
135 return asan_pvalloc(size, &stack);
136}
Kostya Serebryany5dfa4da2011-12-01 21:40:52 +0000137
138#endif // __linux__