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