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