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