]>
Commit | Line | Data |
---|---|---|
cd0be65c WM |
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" | |
696d846a | 18 | #include "ubsan/ubsan_platform.h" |
cd0be65c | 19 | |
696d846a MO |
20 | // Setup defaults for compile definitions. |
21 | #ifndef TSAN_NO_HISTORY | |
22 | # define TSAN_NO_HISTORY 0 | |
23 | #endif | |
24 | ||
25 | #ifndef TSAN_COLLECT_STATS | |
26 | # define TSAN_COLLECT_STATS 0 | |
27 | #endif | |
28 | ||
29 | #ifndef TSAN_CONTAINS_UBSAN | |
30 | # define TSAN_CONTAINS_UBSAN (CAN_SANITIZE_UB && !defined(SANITIZER_GO)) | |
31 | #endif | |
cd0be65c WM |
32 | |
33 | namespace __tsan { | |
34 | ||
696d846a | 35 | #ifdef SANITIZER_GO |
a0408454 KS |
36 | const bool kGoMode = true; |
37 | const bool kCppMode = false; | |
e297eb60 | 38 | const char *const kTsanOptionsEnv = "GORACE"; |
b4ab7d34 KS |
39 | // Go linker does not support weak symbols. |
40 | #define CPP_WEAK | |
e297eb60 | 41 | #else |
a0408454 KS |
42 | const bool kGoMode = false; |
43 | const bool kCppMode = true; | |
e297eb60 | 44 | const char *const kTsanOptionsEnv = "TSAN_OPTIONS"; |
b4ab7d34 | 45 | #define CPP_WEAK WEAK |
e297eb60 KS |
46 | #endif |
47 | ||
cd0be65c WM |
48 | const int kTidBits = 13; |
49 | const unsigned kMaxTid = 1 << kTidBits; | |
696d846a | 50 | #ifndef SANITIZER_GO |
cd0be65c | 51 | const unsigned kMaxTidInClock = kMaxTid * 2; // This includes msb 'freed' bit. |
696d846a MO |
52 | #else |
53 | const unsigned kMaxTidInClock = kMaxTid; // Go does not track freed memory. | |
54 | #endif | |
b4ab7d34 | 55 | const int kClkBits = 42; |
dee5ea7a | 56 | const unsigned kMaxTidReuse = (1 << (64 - kClkBits)) - 1; |
df77f0e4 | 57 | const uptr kShadowStackSize = 64 * 1024; |
cd0be65c | 58 | |
cd0be65c | 59 | // Count of shadow values in a shadow cell. |
e297eb60 | 60 | const uptr kShadowCnt = 4; |
cd0be65c WM |
61 | |
62 | // That many user bytes are mapped onto a single shadow cell. | |
e297eb60 | 63 | const uptr kShadowCell = 8; |
cd0be65c WM |
64 | |
65 | // Size of a single shadow value (u64). | |
e297eb60 KS |
66 | const uptr kShadowSize = 8; |
67 | ||
68 | // Shadow memory is kShadowMultiplier times larger than user memory. | |
69 | const uptr kShadowMultiplier = kShadowSize * kShadowCnt / kShadowCell; | |
cd0be65c | 70 | |
866e32ad KS |
71 | // That many user bytes are mapped onto a single meta shadow cell. |
72 | // Must be less or equal to minimal memory allocator alignment. | |
73 | const uptr kMetaShadowCell = 8; | |
74 | ||
75 | // Size of a single meta shadow value (u32). | |
76 | const uptr kMetaShadowSize = 4; | |
77 | ||
696d846a | 78 | #if TSAN_NO_HISTORY |
dee5ea7a KS |
79 | const bool kCollectHistory = false; |
80 | #else | |
81 | const bool kCollectHistory = true; | |
82 | #endif | |
83 | ||
55aea9f5 MO |
84 | const unsigned kInvalidTid = (unsigned)-1; |
85 | ||
cd0be65c WM |
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. | |
696d846a | 89 | #if SANITIZER_DEBUG |
cd0be65c WM |
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 | ||
cd0be65c | 101 | static inline void USED build_consistency() { |
696d846a | 102 | #if SANITIZER_DEBUG |
cd0be65c WM |
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 | |
cd0be65c WM |
112 | } |
113 | ||
114 | template<typename T> | |
115 | T min(T a, T b) { | |
116 | return a < b ? a : b; | |
117 | } | |
118 | ||
119 | template<typename T> | |
120 | T max(T a, T b) { | |
121 | return a > b ? a : b; | |
122 | } | |
123 | ||
124 | template<typename T> | |
a0408454 | 125 | T RoundUp(T p, u64 align) { |
cd0be65c WM |
126 | DCHECK_EQ(align & (align - 1), 0); |
127 | return (T)(((u64)p + align - 1) & ~(align - 1)); | |
128 | } | |
129 | ||
a0408454 KS |
130 | template<typename T> |
131 | T RoundDown(T p, u64 align) { | |
132 | DCHECK_EQ(align & (align - 1), 0); | |
133 | return (T)((u64)p & ~(align - 1)); | |
134 | } | |
135 | ||
e9772e16 KS |
136 | // Zeroizes high part, returns 'bits' lsb bits. |
137 | template<typename T> | |
138 | T GetLsb(T v, int bits) { | |
139 | return (T)((u64)v & ((1ull << bits) - 1)); | |
140 | } | |
141 | ||
cd0be65c WM |
142 | struct MD5Hash { |
143 | u64 hash[2]; | |
144 | bool operator==(const MD5Hash &other) const; | |
145 | }; | |
146 | ||
147 | MD5Hash md5_hash(const void *data, uptr size); | |
148 | ||
149 | struct ThreadState; | |
df77f0e4 | 150 | class ThreadContext; |
cd0be65c WM |
151 | struct Context; |
152 | struct ReportStack; | |
153 | class ReportDesc; | |
154 | class RegionAlloc; | |
866e32ad KS |
155 | |
156 | // Descriptor of user's memory block. | |
157 | struct MBlock { | |
158 | u64 siz; | |
159 | u32 stk; | |
160 | u16 tid; | |
161 | }; | |
162 | ||
163 | COMPILER_CHECK(sizeof(MBlock) == 16); | |
cd0be65c WM |
164 | |
165 | } // namespace __tsan | |
166 | ||
167 | #endif // TSAN_DEFS_H |