blob: 1b96714536c23407a03fecaac50403c5b8286de7 [file] [log] [blame]
Kostya Serebryany019b76f2011-11-30 01:07:02 +00001//===-- asan_malloc_linux.cc ------------------------------------*- C++ -*-===//
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
17#include "asan_allocator.h"
18#include "asan_interceptors.h"
19#include "asan_internal.h"
20#include "asan_stack.h"
21
22#include <malloc.h>
23
24#define INTERCEPTOR_ATTRIBUTE __attribute__((visibility("default")))
25
26#ifdef ANDROID
27struct MallocDebug {
28 void* (*malloc)(size_t bytes);
29 void (*free)(void* mem);
30 void* (*calloc)(size_t n_elements, size_t elem_size);
31 void* (*realloc)(void* oldMem, size_t bytes);
32 void* (*memalign)(size_t alignment, size_t bytes);
33};
34
35const MallocDebug asan_malloc_dispatch __attribute__((aligned(32))) = {
36 malloc, free, calloc, realloc, memalign
37};
38
39extern "C" const MallocDebug* __libc_malloc_dispatch;
40
41namespace __asan {
42void ReplaceSystemMalloc() {
43 __libc_malloc_dispatch = &asan_malloc_dispatch;
44}
45} // namespace __asan
46
47#else // ANDROID
48
49namespace __asan {
50void ReplaceSystemMalloc() {
51}
52} // namespace __asan
53#endif // ANDROID
54
55// ---------------------- Replacement functions ---------------- {{{1
56using namespace __asan; // NOLINT
57
58extern "C" {
59INTERCEPTOR_ATTRIBUTE
60void free(void *ptr) {
61 GET_STACK_TRACE_HERE_FOR_FREE(ptr);
62 asan_free(ptr, &stack);
63}
64
65INTERCEPTOR_ATTRIBUTE
66void cfree(void *ptr) {
67 GET_STACK_TRACE_HERE_FOR_FREE(ptr);
68 asan_free(ptr, &stack);
69}
70
71INTERCEPTOR_ATTRIBUTE
72void *malloc(size_t size) {
73 GET_STACK_TRACE_HERE_FOR_MALLOC;
74 return asan_malloc(size, &stack);
75}
76
77INTERCEPTOR_ATTRIBUTE
78void *calloc(size_t nmemb, size_t size) {
79 if (!asan_inited) {
80 // Hack: dlsym calls calloc before real_calloc is retrieved from dlsym.
81 const size_t kCallocPoolSize = 1024;
82 static uintptr_t calloc_memory_for_dlsym[kCallocPoolSize];
83 static size_t allocated;
84 size_t 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_HERE_FOR_MALLOC;
91 return asan_calloc(nmemb, size, &stack);
92}
93
94INTERCEPTOR_ATTRIBUTE
95void *realloc(void *ptr, size_t size) {
96 GET_STACK_TRACE_HERE_FOR_MALLOC;
97 return asan_realloc(ptr, size, &stack);
98}
99
100INTERCEPTOR_ATTRIBUTE
101void *memalign(size_t boundary, size_t size) {
102 GET_STACK_TRACE_HERE_FOR_MALLOC;
103 return asan_memalign(boundary, size, &stack);
104}
105
106void* __libc_memalign(size_t align, size_t s)
107 __attribute__((alias("memalign")));
108
109INTERCEPTOR_ATTRIBUTE
110struct mallinfo mallinfo() {
111 struct mallinfo res;
112 real_memset(&res, 0, sizeof(res));
113 return res;
114}
115
116INTERCEPTOR_ATTRIBUTE
117int mallopt(int cmd, int value) {
118 return -1;
119}
120
121INTERCEPTOR_ATTRIBUTE
122int posix_memalign(void **memptr, size_t alignment, size_t size) {
123 GET_STACK_TRACE_HERE_FOR_MALLOC;
124 // Printf("posix_memalign: %lx %ld\n", alignment, size);
125 return asan_posix_memalign(memptr, alignment, size, &stack);
126}
127
128INTERCEPTOR_ATTRIBUTE
129void *valloc(size_t size) {
130 GET_STACK_TRACE_HERE_FOR_MALLOC;
131 return asan_valloc(size, &stack);
132}
133
134INTERCEPTOR_ATTRIBUTE
135void *pvalloc(size_t size) {
136 GET_STACK_TRACE_HERE_FOR_MALLOC;
137 return asan_pvalloc(size, &stack);
138}
139} // extern "C"