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