blob: 4547041fd3232cbd97e6b8170615da4b239c6ca4 [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//===----------------------------------------------------------------------===//
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
23#include <malloc.h>
24
Kostya Serebryany019b76f2011-11-30 01:07:02 +000025#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 __attribute__((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
Alexey Samsonov15965f92012-02-02 10:39:40 +000057INTERCEPTOR(void, free, void *ptr) {
Kostya Serebryany019b76f2011-11-30 01:07:02 +000058 GET_STACK_TRACE_HERE_FOR_FREE(ptr);
59 asan_free(ptr, &stack);
60}
61
Alexey Samsonov15965f92012-02-02 10:39:40 +000062INTERCEPTOR(void, cfree, void *ptr) {
Kostya Serebryany019b76f2011-11-30 01:07:02 +000063 GET_STACK_TRACE_HERE_FOR_FREE(ptr);
64 asan_free(ptr, &stack);
65}
66
Alexey Samsonov15965f92012-02-02 10:39:40 +000067INTERCEPTOR(void*, malloc, size_t size) {
Kostya Serebryany019b76f2011-11-30 01:07:02 +000068 GET_STACK_TRACE_HERE_FOR_MALLOC;
69 return asan_malloc(size, &stack);
70}
71
Alexey Samsonov15965f92012-02-02 10:39:40 +000072INTERCEPTOR(void*, calloc, size_t nmemb, size_t size) {
Kostya Serebryany019b76f2011-11-30 01:07:02 +000073 if (!asan_inited) {
74 // Hack: dlsym calls calloc before real_calloc is retrieved from dlsym.
75 const size_t kCallocPoolSize = 1024;
76 static uintptr_t 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
Alexey Samsonov15965f92012-02-02 10:39:40 +000088INTERCEPTOR(void*, realloc, void *ptr, size_t size) {
Kostya Serebryany019b76f2011-11-30 01:07:02 +000089 GET_STACK_TRACE_HERE_FOR_MALLOC;
90 return asan_realloc(ptr, size, &stack);
91}
92
Alexey Samsonov15965f92012-02-02 10:39:40 +000093INTERCEPTOR(void*, memalign, size_t boundary, size_t size) {
Kostya Serebryany019b76f2011-11-30 01:07:02 +000094 GET_STACK_TRACE_HERE_FOR_MALLOC;
95 return asan_memalign(boundary, size, &stack);
96}
97
Alexey Samsonov15965f92012-02-02 10:39:40 +000098INTERCEPTOR(void*, __libc_memalign, size_t align, size_t s)
Kostya Serebryany019b76f2011-11-30 01:07:02 +000099 __attribute__((alias("memalign")));
100
Alexey Samsonov15965f92012-02-02 10:39:40 +0000101INTERCEPTOR(size_t, malloc_usable_size, void *ptr) {
Alexey Samsonov209c5142012-01-17 06:39:10 +0000102 GET_STACK_TRACE_HERE_FOR_MALLOC;
103 return asan_malloc_usable_size(ptr, &stack);
104}
105
Alexey Samsonov15965f92012-02-02 10:39:40 +0000106INTERCEPTOR(struct mallinfo, mallinfo) {
Kostya Serebryany019b76f2011-11-30 01:07:02 +0000107 struct mallinfo res;
108 real_memset(&res, 0, sizeof(res));
109 return res;
110}
111
Alexey Samsonov15965f92012-02-02 10:39:40 +0000112INTERCEPTOR(int, mallopt, int cmd, int value) {
Kostya Serebryany019b76f2011-11-30 01:07:02 +0000113 return -1;
114}
115
Alexey Samsonov15965f92012-02-02 10:39:40 +0000116INTERCEPTOR(int, posix_memalign, void **memptr, size_t alignment, size_t size) {
Kostya Serebryany019b76f2011-11-30 01:07:02 +0000117 GET_STACK_TRACE_HERE_FOR_MALLOC;
118 // Printf("posix_memalign: %lx %ld\n", alignment, size);
119 return asan_posix_memalign(memptr, alignment, size, &stack);
120}
121
Alexey Samsonov15965f92012-02-02 10:39:40 +0000122INTERCEPTOR(void*, valloc, size_t size) {
Kostya Serebryany019b76f2011-11-30 01:07:02 +0000123 GET_STACK_TRACE_HERE_FOR_MALLOC;
124 return asan_valloc(size, &stack);
125}
126
Alexey Samsonov15965f92012-02-02 10:39:40 +0000127INTERCEPTOR(void*, pvalloc, size_t size) {
Kostya Serebryany019b76f2011-11-30 01:07:02 +0000128 GET_STACK_TRACE_HERE_FOR_MALLOC;
129 return asan_pvalloc(size, &stack);
130}
Kostya Serebryany5dfa4da2011-12-01 21:40:52 +0000131
132#endif // __linux__