tsan_defs.h revision 5d71de26cedae3dafc17449fe0182045c0bd20e8
1//===-- tsan_defs.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 ThreadSanitizer (TSan), a race detector. 11// 12//===----------------------------------------------------------------------===// 13 14#ifndef TSAN_DEFS_H 15#define TSAN_DEFS_H 16 17#include "sanitizer_common/sanitizer_internal_defs.h" 18#include "sanitizer_common/sanitizer_libc.h" 19#include "tsan_stat.h" 20 21#ifndef TSAN_DEBUG 22#define TSAN_DEBUG 0 23#endif // TSAN_DEBUG 24 25namespace __tsan { 26 27#ifdef TSAN_GO 28const bool kGoMode = true; 29const bool kCppMode = false; 30const char *const kTsanOptionsEnv = "GORACE"; 31// Go linker does not support weak symbols. 32#define CPP_WEAK 33#else 34const bool kGoMode = false; 35const bool kCppMode = true; 36const char *const kTsanOptionsEnv = "TSAN_OPTIONS"; 37#define CPP_WEAK WEAK 38#endif 39 40const int kTidBits = 13; 41const unsigned kMaxTid = 1 << kTidBits; 42const unsigned kMaxTidInClock = kMaxTid * 2; // This includes msb 'freed' bit. 43const int kClkBits = 42; 44const unsigned kMaxTidReuse = (1 << (64 - kClkBits)) - 1; 45const uptr kShadowStackSize = 64 * 1024; 46const uptr kTraceStackSize = 256; 47 48#ifdef TSAN_SHADOW_COUNT 49# if TSAN_SHADOW_COUNT == 2 \ 50 || TSAN_SHADOW_COUNT == 4 || TSAN_SHADOW_COUNT == 8 51const uptr kShadowCnt = TSAN_SHADOW_COUNT; 52# else 53# error "TSAN_SHADOW_COUNT must be one of 2,4,8" 54# endif 55#else 56// Count of shadow values in a shadow cell. 57#define TSAN_SHADOW_COUNT 4 58const uptr kShadowCnt = 4; 59#endif 60 61// That many user bytes are mapped onto a single shadow cell. 62const uptr kShadowCell = 8; 63 64// Size of a single shadow value (u64). 65const uptr kShadowSize = 8; 66 67// Shadow memory is kShadowMultiplier times larger than user memory. 68const uptr kShadowMultiplier = kShadowSize * kShadowCnt / kShadowCell; 69 70// That many user bytes are mapped onto a single meta shadow cell. 71// Must be less or equal to minimal memory allocator alignment. 72const uptr kMetaShadowCell = 8; 73 74// Size of a single meta shadow value (u32). 75const uptr kMetaShadowSize = 4; 76 77#if defined(TSAN_NO_HISTORY) && TSAN_NO_HISTORY 78const bool kCollectHistory = false; 79#else 80const bool kCollectHistory = true; 81#endif 82 83#if defined(TSAN_COLLECT_STATS) && TSAN_COLLECT_STATS 84const bool kCollectStats = true; 85#else 86const bool kCollectStats = false; 87#endif 88 89// The following "build consistency" machinery ensures that all source files 90// are built in the same configuration. Inconsistent builds lead to 91// hard to debug crashes. 92#if TSAN_DEBUG 93void build_consistency_debug(); 94#else 95void build_consistency_release(); 96#endif 97 98#if TSAN_COLLECT_STATS 99void build_consistency_stats(); 100#else 101void build_consistency_nostats(); 102#endif 103 104#if TSAN_SHADOW_COUNT == 1 105void build_consistency_shadow1(); 106#elif TSAN_SHADOW_COUNT == 2 107void build_consistency_shadow2(); 108#elif TSAN_SHADOW_COUNT == 4 109void build_consistency_shadow4(); 110#else 111void build_consistency_shadow8(); 112#endif 113 114static inline void USED build_consistency() { 115#if TSAN_DEBUG 116 build_consistency_debug(); 117#else 118 build_consistency_release(); 119#endif 120#if TSAN_COLLECT_STATS 121 build_consistency_stats(); 122#else 123 build_consistency_nostats(); 124#endif 125#if TSAN_SHADOW_COUNT == 1 126 build_consistency_shadow1(); 127#elif TSAN_SHADOW_COUNT == 2 128 build_consistency_shadow2(); 129#elif TSAN_SHADOW_COUNT == 4 130 build_consistency_shadow4(); 131#else 132 build_consistency_shadow8(); 133#endif 134} 135 136template<typename T> 137T min(T a, T b) { 138 return a < b ? a : b; 139} 140 141template<typename T> 142T max(T a, T b) { 143 return a > b ? a : b; 144} 145 146template<typename T> 147T RoundUp(T p, u64 align) { 148 DCHECK_EQ(align & (align - 1), 0); 149 return (T)(((u64)p + align - 1) & ~(align - 1)); 150} 151 152template<typename T> 153T RoundDown(T p, u64 align) { 154 DCHECK_EQ(align & (align - 1), 0); 155 return (T)((u64)p & ~(align - 1)); 156} 157 158// Zeroizes high part, returns 'bits' lsb bits. 159template<typename T> 160T GetLsb(T v, int bits) { 161 return (T)((u64)v & ((1ull << bits) - 1)); 162} 163 164struct MD5Hash { 165 u64 hash[2]; 166 bool operator==(const MD5Hash &other) const; 167}; 168 169MD5Hash md5_hash(const void *data, uptr size); 170 171struct ThreadState; 172class ThreadContext; 173struct Context; 174struct ReportStack; 175class ReportDesc; 176class RegionAlloc; 177class StackTrace; 178 179// Descriptor of user's memory block. 180struct MBlock { 181 u64 siz; 182 u32 stk; 183 u16 tid; 184}; 185 186COMPILER_CHECK(sizeof(MBlock) == 16); 187 188} // namespace __tsan 189 190#endif // TSAN_DEFS_H 191