blob: 2c643035e41fb63fa6bd387a7f6c9f7aa801debd [file] [log] [blame]
Kostya Serebryany1e172b42011-11-30 01:07:02 +00001//===-- asan_internal.h -----------------------------------------*- 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// ASan-private header which defines various general utilities.
13//===----------------------------------------------------------------------===//
14#ifndef ASAN_INTERNAL_H
15#define ASAN_INTERNAL_H
16
17#include <stdint.h> // for __WORDSIZE
18#include <stdlib.h> // for size_t
19#include <unistd.h> // for _exit
20
21#ifdef ANDROID
22#include <sys/atomics.h>
23#endif
24
25#ifdef ADDRESS_SANITIZER
26# error "The AddressSanitizer run-time should not be"
27 " instrumented by AddressSanitizer"
28#endif
29
30// All internal functions in asan reside inside the __asan namespace
31// to avoid namespace collisions with the user programs.
32// Seperate namespace also makes it simpler to distinguish the asan run-time
33// functions from the instrumented user code in a profile.
34namespace __asan {
35
36class AsanThread;
37struct AsanStackTrace;
38
Kostya Serebryany218a9b72011-11-30 18:50:23 +000039// asan_rtl.cc
Kostya Serebryany1e172b42011-11-30 01:07:02 +000040void CheckFailed(const char *cond, const char *file, int line);
41void ShowStatsAndAbort();
42
Kostya Serebryany218a9b72011-11-30 18:50:23 +000043// asan_globals.cc
Kostya Serebryany1e172b42011-11-30 01:07:02 +000044bool DescribeAddrIfGlobal(uintptr_t addr);
45
Kostya Serebryany218a9b72011-11-30 18:50:23 +000046// asan_malloc_linux.cc / asan_malloc_mac.cc
Kostya Serebryany1e172b42011-11-30 01:07:02 +000047void ReplaceSystemMalloc();
48
Kostya Serebryany218a9b72011-11-30 18:50:23 +000049// asan_linux.cc / asan_mac.cc
Kostya Serebryany1e172b42011-11-30 01:07:02 +000050void *AsanDoesNotSupportStaticLinkage();
51void *asan_mmap(void *addr, size_t length, int prot, int flags,
52 int fd, uint64_t offset);
53ssize_t asan_write(int fd, const void *buf, size_t count);
54
Kostya Serebryany218a9b72011-11-30 18:50:23 +000055// asan_printf.cc
Kostya Serebryany1e172b42011-11-30 01:07:02 +000056void RawWrite(const char *buffer);
57int SNPrint(char *buffer, size_t length, const char *format, ...);
58void Printf(const char *format, ...);
59void Report(const char *format, ...);
60
Kostya Serebryany218a9b72011-11-30 18:50:23 +000061// asan_poisoning.cc
62// Poisons the shadow memory for "size" bytes starting from "addr".
63void PoisonShadow(uintptr_t addr, size_t size, uint8_t value);
64// Poisons the shadow memory for "redzone_size" bytes starting from
65// "addr + size".
66void PoisonShadowPartialRightRedzone(uintptr_t addr,
67 uintptr_t size,
68 uintptr_t redzone_size,
69 uint8_t value);
70
71
Kostya Serebryany1e172b42011-11-30 01:07:02 +000072extern size_t FLAG_quarantine_size;
73extern int FLAG_demangle;
74extern bool FLAG_symbolize;
75extern int FLAG_v;
76extern bool FLAG_mt;
77extern size_t FLAG_redzone;
78extern int FLAG_debug;
79extern bool FLAG_poison_shadow;
80extern int FLAG_report_globals;
81extern size_t FLAG_malloc_context_size;
82extern bool FLAG_stats;
83extern bool FLAG_replace_str;
84extern bool FLAG_replace_intrin;
85extern bool FLAG_replace_cfallocator;
86extern bool FLAG_fast_unwind;
87extern bool FLAG_use_fake_stack;
88extern size_t FLAG_max_malloc_fill_size;
89extern int FLAG_exitcode;
90extern bool FLAG_allow_user_poisoning;
91
92extern int asan_inited;
93// Used to avoid infinite recursion in __asan_init().
94extern bool asan_init_is_running;
95
96enum LinkerInitialized { LINKER_INITIALIZED = 0 };
97
98#ifndef ASAN_DIE
99#define ASAN_DIE _exit(FLAG_exitcode)
100#endif // ASAN_DIE
101
102#define CHECK(cond) do { if (!(cond)) { \
103 CheckFailed(#cond, __FILE__, __LINE__); \
104}}while(0)
105
106#define RAW_CHECK_MSG(expr, msg) do { \
107 if (!(expr)) { \
108 RawWrite(msg); \
109 ASAN_DIE; \
110 } \
111} while (0)
112
113#define RAW_CHECK(expr) RAW_CHECK_MSG(expr, #expr)
114
115#define UNIMPLEMENTED() CHECK("unimplemented" && 0)
116
117#define ASAN_ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0]))
118
119const size_t kWordSize = __WORDSIZE / 8;
120const size_t kWordSizeInBits = 8 * kWordSize;
121const size_t kPageSizeBits = 12;
122const size_t kPageSize = 1UL << kPageSizeBits;
123
124#define GET_CALLER_PC() (uintptr_t)__builtin_return_address(0)
125#define GET_CURRENT_FRAME() (uintptr_t)__builtin_frame_address(0)
126
127#define GET_BP_PC_SP \
128 uintptr_t bp = GET_CURRENT_FRAME(); \
129 uintptr_t pc = GET_CALLER_PC(); \
130 uintptr_t local_stack; \
131 uintptr_t sp = (uintptr_t)&local_stack;
132
133// These magic values are written to shadow for better error reporting.
134const int kAsanHeapLeftRedzoneMagic = 0xfa;
135const int kAsanHeapRightRedzoneMagic = 0xfb;
136const int kAsanHeapFreeMagic = 0xfd;
137const int kAsanStackLeftRedzoneMagic = 0xf1;
138const int kAsanStackMidRedzoneMagic = 0xf2;
139const int kAsanStackRightRedzoneMagic = 0xf3;
140const int kAsanStackPartialRedzoneMagic = 0xf4;
141const int kAsanStackAfterReturnMagic = 0xf5;
142const int kAsanUserPoisonedMemoryMagic = 0xf7;
143const int kAsanGlobalRedzoneMagic = 0xf9;
144
145static const uintptr_t kCurrentStackFrameMagic = 0x41B58AB3;
146static const uintptr_t kRetiredStackFrameMagic = 0x45E0360E;
147
Kostya Serebryany1e172b42011-11-30 01:07:02 +0000148// -------------------------- Atomic ---------------- {{{1
149static inline int AtomicInc(int *a) {
150 if (!FLAG_mt) return ++(*a);
151#ifdef ANDROID
152 return __atomic_inc(a) + 1;
153#else
154 return __sync_add_and_fetch(a, 1);
155#endif
156}
157
158static inline int AtomicDec(int *a) {
159 if (!FLAG_mt) return --(*a);
160#ifdef ANDROID
161 return __atomic_dec(a) - 1;
162#else
163 return __sync_add_and_fetch(a, -1);
164#endif
165}
166
167} // namespace __asan
168
169#endif // ASAN_INTERNAL_H