asan_internal.h revision ef14ff6512d7b2e20aa3206dff820b5f90285420
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__) 18# error "This operating system is not supported by AddressSanitizer" 19#endif 20 21#include <stdint.h> // for __WORDSIZE 22#include <stdlib.h> // for size_t 23#include <unistd.h> // for _exit 24 25// If __WORDSIZE was undefined by the platform, define it in terms of the 26// compiler built-in __LP64__. 27#ifndef __WORDSIZE 28#if __LP64__ 29#define __WORDSIZE 64 30#else 31#define __WORDSIZE 32 32#endif 33#endif 34 35#ifdef ANDROID 36#include <sys/atomics.h> 37#endif 38 39#if defined(__has_feature) && __has_feature(address_sanitizer) 40# error "The AddressSanitizer run-time should not be" 41 " instrumented by AddressSanitizer" 42#endif 43 44// Build-time configuration options. 45 46// If set, sysinfo/sysinfo.h will be used to iterate over /proc/maps. 47#ifndef ASAN_USE_SYSINFO 48#ifdef __linux__ 49# define ASAN_USE_SYSINFO 0 50#else 51# define ASAN_USE_SYSINFO 1 52#endif 53#endif 54 55// If set, asan will install its own SEGV signal handler. 56#ifndef ASAN_NEEDS_SEGV 57# define ASAN_NEEDS_SEGV 1 58#endif 59 60// If set, asan will intercept C++ exception api call(s). 61#ifndef ASAN_HAS_EXCEPTIONS 62# define ASAN_HAS_EXCEPTIONS 1 63#endif 64 65// If set, asan uses the values of SHADOW_SCALE and SHADOW_OFFSET 66// provided by the instrumented objects. Otherwise constants are used. 67#ifndef ASAN_FLEXIBLE_MAPPING_AND_OFFSET 68# define ASAN_FLEXIBLE_MAPPING_AND_OFFSET 0 69#endif 70 71// All internal functions in asan reside inside the __asan namespace 72// to avoid namespace collisions with the user programs. 73// Seperate namespace also makes it simpler to distinguish the asan run-time 74// functions from the instrumented user code in a profile. 75namespace __asan { 76 77class AsanThread; 78struct AsanStackTrace; 79 80// asan_rtl.cc 81void CheckFailed(const char *cond, const char *file, int line); 82void ShowStatsAndAbort(); 83 84// asan_globals.cc 85bool DescribeAddrIfGlobal(uintptr_t addr); 86 87// asan_malloc_linux.cc / asan_malloc_mac.cc 88void ReplaceSystemMalloc(); 89 90void OutOfMemoryMessageAndDie(const char *mem_type, size_t size); 91 92// asan_linux.cc / asan_mac.cc 93void *AsanDoesNotSupportStaticLinkage(); 94int AsanOpenReadonly(const char* filename); 95 96void *AsanMmapFixedNoReserve(uintptr_t fixed_addr, size_t size); 97void *AsanMmapFixedReserve(uintptr_t fixed_addr, size_t size); 98void *AsanMprotect(uintptr_t fixed_addr, size_t size); 99void *AsanMmapSomewhereOrDie(size_t size, const char *where); 100void AsanUnmapOrDie(void *ptr, size_t size); 101 102void AsanDisableCoreDumper(); 103 104ssize_t AsanRead(int fd, void *buf, size_t count); 105ssize_t AsanWrite(int fd, const void *buf, size_t count); 106int AsanClose(int fd); 107 108// Opens the file 'file_name" and reads up to 'max_len' bytes. 109// The resulting buffer is mmaped and stored in '*buff'. 110// The size of the mmaped region is stored in '*buff_size', 111// Returns the number of read bytes or -1 if file can not be opened. 112ssize_t ReadFileToBuffer(const char *file_name, char **buff, 113 size_t *buff_size, size_t max_len); 114 115// asan_printf.cc 116void RawWrite(const char *buffer); 117int SNPrint(char *buffer, size_t length, const char *format, ...); 118void Printf(const char *format, ...); 119int SScanf(const char *str, const char *format, ...); 120void Report(const char *format, ...); 121 122// Don't use std::min and std::max, to minimize dependency on libstdc++. 123template<class T> T Min(T a, T b) { return a < b ? a : b; } 124template<class T> T Max(T a, T b) { return a > b ? a : b; } 125 126// asan_poisoning.cc 127// Poisons the shadow memory for "size" bytes starting from "addr". 128void PoisonShadow(uintptr_t addr, size_t size, uint8_t value); 129// Poisons the shadow memory for "redzone_size" bytes starting from 130// "addr + size". 131void PoisonShadowPartialRightRedzone(uintptr_t addr, 132 uintptr_t size, 133 uintptr_t redzone_size, 134 uint8_t value); 135 136extern size_t FLAG_quarantine_size; 137extern int FLAG_demangle; 138extern bool FLAG_symbolize; 139extern int FLAG_v; 140extern size_t FLAG_redzone; 141extern int FLAG_debug; 142extern bool FLAG_poison_shadow; 143extern int FLAG_report_globals; 144extern size_t FLAG_malloc_context_size; 145extern bool FLAG_replace_str; 146extern bool FLAG_replace_intrin; 147extern bool FLAG_replace_cfallocator; 148extern bool FLAG_fast_unwind; 149extern bool FLAG_use_fake_stack; 150extern size_t FLAG_max_malloc_fill_size; 151extern int FLAG_exitcode; 152extern bool FLAG_allow_user_poisoning; 153 154extern int asan_inited; 155// Used to avoid infinite recursion in __asan_init(). 156extern bool asan_init_is_running; 157 158enum LinkerInitialized { LINKER_INITIALIZED = 0 }; 159 160#ifndef ASAN_DIE 161#define ASAN_DIE _exit(FLAG_exitcode) 162#endif // ASAN_DIE 163 164#define CHECK(cond) do { if (!(cond)) { \ 165 CheckFailed(#cond, __FILE__, __LINE__); \ 166}}while(0) 167 168#define RAW_CHECK_MSG(expr, msg) do { \ 169 if (!(expr)) { \ 170 RawWrite(msg); \ 171 ASAN_DIE; \ 172 } \ 173} while (0) 174 175#define RAW_CHECK(expr) RAW_CHECK_MSG(expr, #expr) 176 177#define UNIMPLEMENTED() CHECK("unimplemented" && 0) 178 179#define ASAN_ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0])) 180 181const size_t kWordSize = __WORDSIZE / 8; 182const size_t kWordSizeInBits = 8 * kWordSize; 183const size_t kPageSizeBits = 12; 184const size_t kPageSize = 1UL << kPageSizeBits; 185 186#define GET_CALLER_PC() (uintptr_t)__builtin_return_address(0) 187#define GET_CURRENT_FRAME() (uintptr_t)__builtin_frame_address(0) 188 189#define GET_BP_PC_SP \ 190 uintptr_t bp = GET_CURRENT_FRAME(); \ 191 uintptr_t pc = GET_CALLER_PC(); \ 192 uintptr_t local_stack; \ 193 uintptr_t sp = (uintptr_t)&local_stack; 194 195// These magic values are written to shadow for better error reporting. 196const int kAsanHeapLeftRedzoneMagic = 0xfa; 197const int kAsanHeapRightRedzoneMagic = 0xfb; 198const int kAsanHeapFreeMagic = 0xfd; 199const int kAsanStackLeftRedzoneMagic = 0xf1; 200const int kAsanStackMidRedzoneMagic = 0xf2; 201const int kAsanStackRightRedzoneMagic = 0xf3; 202const int kAsanStackPartialRedzoneMagic = 0xf4; 203const int kAsanStackAfterReturnMagic = 0xf5; 204const int kAsanUserPoisonedMemoryMagic = 0xf7; 205const int kAsanGlobalRedzoneMagic = 0xf9; 206const int kAsanInternalHeapMagic = 0xfe; 207 208static const uintptr_t kCurrentStackFrameMagic = 0x41B58AB3; 209static const uintptr_t kRetiredStackFrameMagic = 0x45E0360E; 210 211// --------------------------- Bit twiddling ------- {{{1 212inline bool IsPowerOfTwo(size_t x) { 213 return (x & (x - 1)) == 0; 214} 215 216inline size_t RoundUpTo(size_t size, size_t boundary) { 217 CHECK(IsPowerOfTwo(boundary)); 218 return (size + boundary - 1) & ~(boundary - 1); 219} 220 221// -------------------------- LowLevelAllocator ----- {{{1 222// A simple low-level memory allocator for internal use. 223class LowLevelAllocator { 224 public: 225 explicit LowLevelAllocator(LinkerInitialized) {} 226 // 'size' must be a power of two. 227 // Requires an external lock. 228 void *Allocate(size_t size); 229 private: 230 char *allocated_end_; 231 char *allocated_current_; 232}; 233 234// -------------------------- Atomic ---------------- {{{1 235static inline int AtomicInc(int *a) { 236#ifdef ANDROID 237 return __atomic_inc(a) + 1; 238#else 239 return __sync_add_and_fetch(a, 1); 240#endif 241} 242 243static inline int AtomicDec(int *a) { 244#ifdef ANDROID 245 return __atomic_dec(a) - 1; 246#else 247 return __sync_add_and_fetch(a, -1); 248#endif 249} 250 251} // namespace __asan 252 253#endif // ASAN_INTERNAL_H 254