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++. 213 template<class T> T Min(T a, T b) { return a < b ? a : 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 333 inline bool IsPowerOfTwo(size_t x) { 334 return (x & (x - 1)) == 0; 335 } 336 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: 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