asan_internal.h revision 4d5f98df886051afeece1698d4bc8f154391c22d
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. 25typedef unsigned __int8 uint8_t; 26typedef unsigned __int16 uint16_t; 27typedef unsigned __int32 uint32_t; 28typedef unsigned __int64 uint64_t; 29typedef __int8 int8_t; 30typedef __int16 int16_t; 31typedef __int32 int32_t; 32typedef __int64 int64_t; 33typedef unsigned long DWORD; // NOLINT 34 35extern "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 defined(__has_feature) && __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. 146namespace __asan { 147 148class AsanThread; 149struct AsanStackTrace; 150 151// asan_rtl.cc 152void NORETURN CheckFailed(const char *cond, const char *file, int line); 153void NORETURN ShowStatsAndAbort(); 154 155// asan_globals.cc 156bool DescribeAddrIfGlobal(uintptr_t addr); 157 158void ReplaceOperatorsNewAndDelete(); 159// asan_malloc_linux.cc / asan_malloc_mac.cc 160void ReplaceSystemMalloc(); 161 162void OutOfMemoryMessageAndDie(const char *mem_type, size_t size); 163 164// asan_linux.cc / asan_mac.cc / asan_win.cc 165void *AsanDoesNotSupportStaticLinkage(); 166bool AsanShadowRangeIsAvailable(); 167int AsanOpenReadonly(const char* filename); 168const char *AsanGetEnv(const char *name); 169void AsanDumpProcessMap(); 170 171void *AsanMmapFixedNoReserve(uintptr_t fixed_addr, size_t size); 172void *AsanMmapFixedReserve(uintptr_t fixed_addr, size_t size); 173void *AsanMprotect(uintptr_t fixed_addr, size_t size); 174void *AsanMmapSomewhereOrDie(size_t size, const char *where); 175void AsanUnmapOrDie(void *ptr, size_t size); 176 177void AsanDisableCoreDumper(); 178void GetPcSpBp(void *context, uintptr_t *pc, uintptr_t *sp, uintptr_t *bp); 179 180size_t AsanRead(int fd, void *buf, size_t count); 181size_t AsanWrite(int fd, const void *buf, size_t count); 182int AsanClose(int fd); 183 184bool AsanInterceptsSignal(int signum); 185void SetAlternateSignalStack(); 186void UnsetAlternateSignalStack(); 187void InstallSignalHandlers(); 188int GetPid(); 189uintptr_t GetThreadSelf(); 190int AtomicInc(int *a); 191uint16_t AtomicExchange(uint16_t *a, uint16_t new_val); 192 193// Wrapper for TLS/TSD. 194void AsanTSDInit(void (*destructor)(void *tsd)); 195void *AsanTSDGet(); 196void 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. 202size_t ReadFileToBuffer(const char *file_name, char **buff, 203 size_t *buff_size, size_t max_len); 204 205// asan_printf.cc 206void RawWrite(const char *buffer); 207int SNPrintf(char *buffer, size_t length, const char *format, ...); 208void Printf(const char *format, ...); 209int SScanf(const char *str, const char *format, ...); 210void Report(const char *format, ...); 211 212// Don't use std::min and std::max, to minimize dependency on libstdc++. 213template<class T> T Min(T a, T b) { return a < b ? a : b; } 214template<class T> T Max(T a, T b) { return a > b ? a : b; } 215 216void SortArray(uintptr_t *array, size_t size); 217 218// asan_poisoning.cc 219// Poisons the shadow memory for "size" bytes starting from "addr". 220void PoisonShadow(uintptr_t addr, size_t size, uint8_t value); 221// Poisons the shadow memory for "redzone_size" bytes starting from 222// "addr + size". 223void 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__ 230bool 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 237extern size_t FLAG_quarantine_size; 238extern int FLAG_demangle; 239extern bool FLAG_symbolize; 240extern int FLAG_v; 241extern size_t FLAG_redzone; 242extern int FLAG_debug; 243extern bool FLAG_poison_shadow; 244extern int FLAG_report_globals; 245extern size_t FLAG_malloc_context_size; 246extern bool FLAG_replace_str; 247extern bool FLAG_replace_intrin; 248extern bool FLAG_replace_cfallocator; 249extern bool FLAG_fast_unwind; 250extern bool FLAG_use_fake_stack; 251extern size_t FLAG_max_malloc_fill_size; 252extern int FLAG_exitcode; 253extern bool FLAG_allow_user_poisoning; 254extern int FLAG_sleep_before_dying; 255extern bool FLAG_handle_segv; 256extern bool FLAG_use_sigaltstack; 257 258extern int asan_inited; 259// Used to avoid infinite recursion in __asan_init(). 260extern bool asan_init_is_running; 261 262enum LinkerInitialized { LINKER_INITIALIZED = 0 }; 263 264void NORETURN AsanDie(); 265void SleepForSeconds(int seconds); 266void NORETURN Exit(int exitcode); 267void NORETURN Abort(); 268int 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 287const size_t kWordSize = __WORDSIZE / 8; 288const size_t kWordSizeInBits = 8 * kWordSize; 289const size_t kPageSizeBits = 12; 290const size_t kPageSize = 1UL << kPageSizeBits; 291 292#ifndef _WIN32 293const 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 297typedef void* thread_return_t; 298#else 299const 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 306typedef DWORD thread_return_t; 307 308# ifndef ASAN_USE_EXTERNAL_SYMBOLIZER 309# define ASAN_USE_EXTERNAL_SYMBOLIZER __asan::WinSymbolize 310bool WinSymbolize(const void *addr, char *out_buffer, int buffer_size); 311# endif 312#endif 313 314typedef thread_return_t (THREAD_CALLING_CONV *thread_callback_t)(void* arg); 315 316// These magic values are written to shadow for better error reporting. 317const int kAsanHeapLeftRedzoneMagic = 0xfa; 318const int kAsanHeapRightRedzoneMagic = 0xfb; 319const int kAsanHeapFreeMagic = 0xfd; 320const int kAsanStackLeftRedzoneMagic = 0xf1; 321const int kAsanStackMidRedzoneMagic = 0xf2; 322const int kAsanStackRightRedzoneMagic = 0xf3; 323const int kAsanStackPartialRedzoneMagic = 0xf4; 324const int kAsanStackAfterReturnMagic = 0xf5; 325const int kAsanUserPoisonedMemoryMagic = 0xf7; 326const int kAsanGlobalRedzoneMagic = 0xf9; 327const int kAsanInternalHeapMagic = 0xfe; 328 329static const uintptr_t kCurrentStackFrameMagic = 0x41B58AB3; 330static const uintptr_t kRetiredStackFrameMagic = 0x45E0360E; 331 332// --------------------------- Bit twiddling ------- {{{1 333inline bool IsPowerOfTwo(size_t x) { 334 return (x & (x - 1)) == 0; 335} 336 337inline 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. 344class LowLevelAllocator { 345 public: 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