• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===-- 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 #if !defined(__linux__) && !defined(__APPLE__) && !defined(_WIN32)
18 # error "This operating system is not supported by AddressSanitizer"
19 #endif
20 
21 #include <stddef.h>  // for size_t, uintptr_t, etc.
22 
23 #if defined(_WIN32)
24 // There's no <stdint.h> in Visual Studio 9, so we have to define [u]int*_t.
25 typedef unsigned __int8  uint8_t;
26 typedef unsigned __int16 uint16_t;
27 typedef unsigned __int32 uint32_t;
28 typedef unsigned __int64 uint64_t;
29 typedef __int8           int8_t;
30 typedef __int16          int16_t;
31 typedef __int32          int32_t;
32 typedef __int64          int64_t;
33 typedef unsigned long    DWORD;  // NOLINT
34 
35 extern "C" void* _ReturnAddress(void);
36 # pragma intrinsic(_ReturnAddress)
37 
38 # define ALIAS(x)   // TODO(timurrrr): do we need this on Windows?
39 # define ALIGNED(x) __declspec(align(x))
40 # define NOINLINE __declspec(noinline)
41 # define NORETURN __declspec(noreturn)
42 
43 # define ASAN_INTERFACE_ATTRIBUTE  // TODO(timurrrr): do we need this on Win?
44 #else  // defined(_WIN32)
45 # include <stdint.h>  // for __WORDSIZE
46 
47 # define ALIAS(x) __attribute__((alias(x)))
48 # define ALIGNED(x) __attribute__((aligned(x)))
49 # define NOINLINE __attribute__((noinline))
50 # define NORETURN  __attribute__((noreturn))
51 
52 # define ASAN_INTERFACE_ATTRIBUTE __attribute__((visibility("default")))
53 #endif  // defined(_WIN32)
54 
55 // If __WORDSIZE was undefined by the platform, define it in terms of the
56 // compiler built-ins __LP64__ and _WIN64.
57 #ifndef __WORDSIZE
58 #if __LP64__ || defined(_WIN64)
59 #define __WORDSIZE 64
60 #else
61 #define __WORDSIZE 32
62 #endif
63 #endif
64 
65 // Limits for integral types. We have to redefine it in case we don't
66 // have stdint.h (like in Visual Studio 9).
67 #if __WORDSIZE == 64
68 # define __INT64_C(c)  c ## L
69 # define __UINT64_C(c) c ## UL
70 #else
71 # define __INT64_C(c)  c ## LL
72 # define __UINT64_C(c) c ## ULL
73 #endif  // __WORDSIZE == 64
74 #undef INT32_MIN
75 #define INT32_MIN              (-2147483647-1)
76 #undef INT32_MAX
77 #define INT32_MAX              (2147483647)
78 #undef UINT32_MAX
79 #define UINT32_MAX             (4294967295U)
80 #undef INT64_MIN
81 #define INT64_MIN              (-__INT64_C(9223372036854775807)-1)
82 #undef INT64_MAX
83 #define INT64_MAX              (__INT64_C(9223372036854775807))
84 #undef UINT64_MAX
85 #define UINT64_MAX             (__UINT64_C(18446744073709551615))
86 
87 #define ASAN_DEFAULT_FAILURE_EXITCODE 1
88 
89 #if defined(__linux__)
90 # define ASAN_LINUX   1
91 #else
92 # define ASAN_LINUX   0
93 #endif
94 
95 #if defined(__APPLE__)
96 # define ASAN_MAC     1
97 #else
98 # define ASAN_MAC     0
99 #endif
100 
101 #if defined(_WIN32)
102 # define ASAN_WINDOWS 1
103 #else
104 # define ASAN_WINDOWS 0
105 #endif
106 
107 #define ASAN_POSIX (ASAN_LINUX || ASAN_MAC)
108 
109 #if !defined(__has_feature)
110 #define __has_feature(x) 0
111 #endif
112 
113 #if __has_feature(address_sanitizer)
114 # error "The AddressSanitizer run-time should not be"
115         " instrumented by AddressSanitizer"
116 #endif
117 
118 // Build-time configuration options.
119 
120 // If set, asan will install its own SEGV signal handler.
121 #ifndef ASAN_NEEDS_SEGV
122 # define ASAN_NEEDS_SEGV 1
123 #endif
124 
125 // If set, asan will intercept C++ exception api call(s).
126 #ifndef ASAN_HAS_EXCEPTIONS
127 # define ASAN_HAS_EXCEPTIONS 1
128 #endif
129 
130 // If set, asan uses the values of SHADOW_SCALE and SHADOW_OFFSET
131 // provided by the instrumented objects. Otherwise constants are used.
132 #ifndef ASAN_FLEXIBLE_MAPPING_AND_OFFSET
133 # define ASAN_FLEXIBLE_MAPPING_AND_OFFSET 0
134 #endif
135 
136 // If set, values like allocator chunk size, as well as defaults for some flags
137 // will be changed towards less memory overhead.
138 #ifndef ASAN_LOW_MEMORY
139 # define ASAN_LOW_MEMORY 0
140 #endif
141 
142 // All internal functions in asan reside inside the __asan namespace
143 // to avoid namespace collisions with the user programs.
144 // Seperate namespace also makes it simpler to distinguish the asan run-time
145 // functions from the instrumented user code in a profile.
146 namespace __asan {
147 
148 class AsanThread;
149 struct AsanStackTrace;
150 
151 // asan_rtl.cc
152 void NORETURN CheckFailed(const char *cond, const char *file, int line);
153 void NORETURN ShowStatsAndAbort();
154 
155 // asan_globals.cc
156 bool DescribeAddrIfGlobal(uintptr_t addr);
157 
158 void ReplaceOperatorsNewAndDelete();
159 // asan_malloc_linux.cc / asan_malloc_mac.cc
160 void ReplaceSystemMalloc();
161 
162 void OutOfMemoryMessageAndDie(const char *mem_type, size_t size);
163 
164 // asan_linux.cc / asan_mac.cc / asan_win.cc
165 void *AsanDoesNotSupportStaticLinkage();
166 bool AsanShadowRangeIsAvailable();
167 int AsanOpenReadonly(const char* filename);
168 const char *AsanGetEnv(const char *name);
169 void AsanDumpProcessMap();
170 
171 void *AsanMmapFixedNoReserve(uintptr_t fixed_addr, size_t size);
172 void *AsanMmapFixedReserve(uintptr_t fixed_addr, size_t size);
173 void *AsanMprotect(uintptr_t fixed_addr, size_t size);
174 void *AsanMmapSomewhereOrDie(size_t size, const char *where);
175 void AsanUnmapOrDie(void *ptr, size_t size);
176 
177 void AsanDisableCoreDumper();
178 void GetPcSpBp(void *context, uintptr_t *pc, uintptr_t *sp, uintptr_t *bp);
179 
180 size_t AsanRead(int fd, void *buf, size_t count);
181 size_t AsanWrite(int fd, const void *buf, size_t count);
182 int AsanClose(int fd);
183 
184 bool AsanInterceptsSignal(int signum);
185 void SetAlternateSignalStack();
186 void UnsetAlternateSignalStack();
187 void InstallSignalHandlers();
188 int GetPid();
189 uintptr_t GetThreadSelf();
190 int AtomicInc(int *a);
191 uint16_t AtomicExchange(uint16_t *a, uint16_t new_val);
192 
193 // Wrapper for TLS/TSD.
194 void AsanTSDInit(void (*destructor)(void *tsd));
195 void *AsanTSDGet();
196 void AsanTSDSet(void *tsd);
197 
198 // Opens the file 'file_name" and reads up to 'max_len' bytes.
199 // The resulting buffer is mmaped and stored in '*buff'.
200 // The size of the mmaped region is stored in '*buff_size',
201 // Returns the number of read bytes or 0 if file can not be opened.
202 size_t ReadFileToBuffer(const char *file_name, char **buff,
203                         size_t *buff_size, size_t max_len);
204 
205 // asan_printf.cc
206 void RawWrite(const char *buffer);
207 int SNPrintf(char *buffer, size_t length, const char *format, ...);
208 void Printf(const char *format, ...);
209 int SScanf(const char *str, const char *format, ...);
210 void Report(const char *format, ...);
211 
212 // Don't use std::min and std::max, to minimize dependency on libstdc++.
Min(T a,T b)213 template<class T> T Min(T a, T b) { return a < b ? a : b; }
Max(T a,T b)214 template<class T> T Max(T a, T b) { return a > b ? a : b; }
215 
216 void SortArray(uintptr_t *array, size_t size);
217 
218 // asan_poisoning.cc
219 // Poisons the shadow memory for "size" bytes starting from "addr".
220 void PoisonShadow(uintptr_t addr, size_t size, uint8_t value);
221 // Poisons the shadow memory for "redzone_size" bytes starting from
222 // "addr + size".
223 void PoisonShadowPartialRightRedzone(uintptr_t addr,
224                                      uintptr_t size,
225                                      uintptr_t redzone_size,
226                                      uint8_t value);
227 
228 // Platfrom-specific options.
229 #ifdef __APPLE__
230 bool PlatformHasDifferentMemcpyAndMemmove();
231 # define PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE \
232     (PlatformHasDifferentMemcpyAndMemmove())
233 #else
234 # define PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE true
235 #endif  // __APPLE__
236 
237 extern size_t FLAG_quarantine_size;
238 extern int    FLAG_demangle;
239 extern bool   FLAG_symbolize;
240 extern int    FLAG_v;
241 extern size_t FLAG_redzone;
242 extern int    FLAG_debug;
243 extern bool   FLAG_poison_shadow;
244 extern int    FLAG_report_globals;
245 extern size_t FLAG_malloc_context_size;
246 extern bool   FLAG_replace_str;
247 extern bool   FLAG_replace_intrin;
248 extern bool   FLAG_replace_cfallocator;
249 extern bool   FLAG_fast_unwind;
250 extern bool   FLAG_use_fake_stack;
251 extern size_t FLAG_max_malloc_fill_size;
252 extern int    FLAG_exitcode;
253 extern bool   FLAG_allow_user_poisoning;
254 extern int    FLAG_sleep_before_dying;
255 extern bool   FLAG_handle_segv;
256 extern bool   FLAG_use_sigaltstack;
257 
258 extern int asan_inited;
259 // Used to avoid infinite recursion in __asan_init().
260 extern bool asan_init_is_running;
261 
262 enum LinkerInitialized { LINKER_INITIALIZED = 0 };
263 
264 void NORETURN AsanDie();
265 void SleepForSeconds(int seconds);
266 void NORETURN Exit(int exitcode);
267 void NORETURN Abort();
268 int Atexit(void (*function)(void));
269 
270 #define CHECK(cond) do { if (!(cond)) { \
271   CheckFailed(#cond, __FILE__, __LINE__); \
272 }}while(0)
273 
274 #define RAW_CHECK_MSG(expr, msg) do { \
275   if (!(expr)) { \
276     RawWrite(msg); \
277     AsanDie(); \
278   } \
279 } while (0)
280 
281 #define RAW_CHECK(expr) RAW_CHECK_MSG(expr, #expr)
282 
283 #define UNIMPLEMENTED() CHECK("unimplemented" && 0)
284 
285 #define ASAN_ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0]))
286 
287 const size_t kWordSize = __WORDSIZE / 8;
288 const size_t kWordSizeInBits = 8 * kWordSize;
289 const size_t kPageSizeBits = 12;
290 const size_t kPageSize = 1UL << kPageSizeBits;
291 
292 #ifndef _WIN32
293 const size_t kMmapGranularity = kPageSize;
294 # define GET_CALLER_PC() (uintptr_t)__builtin_return_address(0)
295 # define GET_CURRENT_FRAME() (uintptr_t)__builtin_frame_address(0)
296 # define THREAD_CALLING_CONV
297 typedef void* thread_return_t;
298 #else
299 const size_t kMmapGranularity = 1UL << 16;
300 # define GET_CALLER_PC() (uintptr_t)_ReturnAddress()
301 // CaptureStackBackTrace doesn't need to know BP on Windows.
302 // FIXME: This macro is still used when printing error reports though it's not
303 // clear if the BP value is needed in the ASan reports on Windows.
304 # define GET_CURRENT_FRAME() (uintptr_t)0xDEADBEEF
305 # define THREAD_CALLING_CONV __stdcall
306 typedef DWORD thread_return_t;
307 
308 # ifndef ASAN_USE_EXTERNAL_SYMBOLIZER
309 #  define ASAN_USE_EXTERNAL_SYMBOLIZER __asan::WinSymbolize
310 bool WinSymbolize(const void *addr, char *out_buffer, int buffer_size);
311 # endif
312 #endif
313 
314 typedef thread_return_t (THREAD_CALLING_CONV *thread_callback_t)(void* arg);
315 
316 // These magic values are written to shadow for better error reporting.
317 const int kAsanHeapLeftRedzoneMagic = 0xfa;
318 const int kAsanHeapRightRedzoneMagic = 0xfb;
319 const int kAsanHeapFreeMagic = 0xfd;
320 const int kAsanStackLeftRedzoneMagic = 0xf1;
321 const int kAsanStackMidRedzoneMagic = 0xf2;
322 const int kAsanStackRightRedzoneMagic = 0xf3;
323 const int kAsanStackPartialRedzoneMagic = 0xf4;
324 const int kAsanStackAfterReturnMagic = 0xf5;
325 const int kAsanUserPoisonedMemoryMagic = 0xf7;
326 const int kAsanGlobalRedzoneMagic = 0xf9;
327 const int kAsanInternalHeapMagic = 0xfe;
328 
329 static const uintptr_t kCurrentStackFrameMagic = 0x41B58AB3;
330 static const uintptr_t kRetiredStackFrameMagic = 0x45E0360E;
331 
332 // --------------------------- Bit twiddling ------- {{{1
IsPowerOfTwo(size_t x)333 inline bool IsPowerOfTwo(size_t x) {
334   return (x & (x - 1)) == 0;
335 }
336 
RoundUpTo(size_t size,size_t boundary)337 inline size_t RoundUpTo(size_t size, size_t boundary) {
338   CHECK(IsPowerOfTwo(boundary));
339   return (size + boundary - 1) & ~(boundary - 1);
340 }
341 
342 // -------------------------- LowLevelAllocator ----- {{{1
343 // A simple low-level memory allocator for internal use.
344 class LowLevelAllocator {
345  public:
LowLevelAllocator(LinkerInitialized)346   explicit LowLevelAllocator(LinkerInitialized) {}
347   // 'size' must be a power of two.
348   // Requires an external lock.
349   void *Allocate(size_t size);
350  private:
351   char *allocated_end_;
352   char *allocated_current_;
353 };
354 
355 }  // namespace __asan
356 
357 #endif  // ASAN_INTERNAL_H
358