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 const unsigned kMaxTidReuse = (1 << (64 - kClkBits)) - 1; 45 const uptr kShadowStackSize = 64 * 1024; 46 const uptr kTraceStackSize = 256; 47 48 #ifdef TSAN_SHADOW_COUNT 49 # if TSAN_SHADOW_COUNT == 2 \ 50 || TSAN_SHADOW_COUNT == 4 || TSAN_SHADOW_COUNT == 8 51 const 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 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 // That many user bytes are mapped onto a single meta shadow cell. 71 // Must be less or equal to minimal memory allocator alignment. 72 const uptr kMetaShadowCell = 8; 73 74 // Size of a single meta shadow value (u32). 75 const uptr kMetaShadowSize = 4; 76 77 #if defined(TSAN_NO_HISTORY) && TSAN_NO_HISTORY 78 const bool kCollectHistory = false; 79 #else 80 const bool kCollectHistory = true; 81 #endif 82 83 #if defined(TSAN_COLLECT_STATS) && TSAN_COLLECT_STATS 84 const bool kCollectStats = true; 85 #else 86 const 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 93 void build_consistency_debug(); 94 #else 95 void build_consistency_release(); 96 #endif 97 98 #if TSAN_COLLECT_STATS 99 void build_consistency_stats(); 100 #else 101 void build_consistency_nostats(); 102 #endif 103 104 #if TSAN_SHADOW_COUNT == 1 105 void build_consistency_shadow1(); 106 #elif TSAN_SHADOW_COUNT == 2 107 void build_consistency_shadow2(); 108 #elif TSAN_SHADOW_COUNT == 4 109 void build_consistency_shadow4(); 110 #else 111 void build_consistency_shadow8(); 112 #endif 113 114 static 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 136 template<typename T> 137 T min(T a, T b) { 138 return a < b ? a : b; 139 } 140 141 template<typename T> 142 T max(T a, T b) { 143 return a > b ? a : b; 144 } 145 146 template<typename T> 147 T RoundUp(T p, u64 align) { 148 DCHECK_EQ(align & (align - 1), 0); 149 return (T)(((u64)p + align - 1) & ~(align - 1)); 150 } 151 152 template<typename T> 153 T 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. 159 template<typename T> 160 T GetLsb(T v, int bits) { 161 return (T)((u64)v & ((1ull << bits) - 1)); 162 } 163 164 struct MD5Hash { 165 u64 hash[2]; 166 bool operator==(const MD5Hash &other) const; 167 }; 168 169 MD5Hash md5_hash(const void *data, uptr size); 170 171 struct ThreadState; 172 class ThreadContext; 173 struct Context; 174 struct ReportStack; 175 class ReportDesc; 176 class RegionAlloc; 177 class StackTrace; 178 179 // Descriptor of user's memory block. 180 struct MBlock { 181 u64 siz; 182 u32 stk; 183 u16 tid; 184 }; 185 186 COMPILER_CHECK(sizeof(MBlock) == 16); 187 188 } // namespace __tsan 189 190 #endif // TSAN_DEFS_H 191