blob: d869d95e08785b8184ad126fcf90fcf6e06ce346 [file] [log] [blame]
Kostya Serebryany7ac41482012-05-10 13:48:04 +00001//===-- 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
Alexey Samsonov94b50362012-06-05 14:25:27 +000017#include "sanitizer_common/sanitizer_internal_defs.h"
Alexey Samsonovf7667cc2012-06-07 11:54:08 +000018#include "sanitizer_common/sanitizer_libc.h"
Kostya Serebryany7ac41482012-05-10 13:48:04 +000019#include "tsan_stat.h"
Pirama Arumuga Nainarcdce50b2015-07-01 12:26:56 -070020#include "ubsan/ubsan_platform.h"
Kostya Serebryany7ac41482012-05-10 13:48:04 +000021
Stephen Hines86277eb2015-03-23 12:06:32 -070022// Setup defaults for compile definitions.
23#ifndef TSAN_NO_HISTORY
24# define TSAN_NO_HISTORY 0
25#endif
26
27#ifndef TSAN_COLLECT_STATS
28# define TSAN_COLLECT_STATS 0
29#endif
Kostya Serebryany7ac41482012-05-10 13:48:04 +000030
Pirama Arumuga Nainarcdce50b2015-07-01 12:26:56 -070031#ifndef TSAN_CONTAINS_UBSAN
32# define TSAN_CONTAINS_UBSAN (CAN_SANITIZE_UB && !defined(SANITIZER_GO))
33#endif
34
Alexey Samsonov0a4c9062012-06-05 13:50:57 +000035namespace __tsan {
Kostya Serebryany7ac41482012-05-10 13:48:04 +000036
Stephen Hines86277eb2015-03-23 12:06:32 -070037#ifdef SANITIZER_GO
Dmitry Vyukov3fb70e32012-11-28 13:01:32 +000038const bool kGoMode = true;
39const bool kCppMode = false;
Dmitry Vyukov79c98362012-11-08 11:32:40 +000040const char *const kTsanOptionsEnv = "GORACE";
Dmitry Vyukova55fbd52013-01-30 14:38:44 +000041// Go linker does not support weak symbols.
42#define CPP_WEAK
Dmitry Vyukov79c98362012-11-08 11:32:40 +000043#else
Dmitry Vyukov3fb70e32012-11-28 13:01:32 +000044const bool kGoMode = false;
45const bool kCppMode = true;
Dmitry Vyukov79c98362012-11-08 11:32:40 +000046const char *const kTsanOptionsEnv = "TSAN_OPTIONS";
Dmitry Vyukova55fbd52013-01-30 14:38:44 +000047#define CPP_WEAK WEAK
Dmitry Vyukov79c98362012-11-08 11:32:40 +000048#endif
49
Dmitry Vyukov9d2ffc22012-05-22 14:34:43 +000050const int kTidBits = 13;
Kostya Serebryany3d6ae152012-05-11 14:42:24 +000051const unsigned kMaxTid = 1 << kTidBits;
Stephen Hines86277eb2015-03-23 12:06:32 -070052#ifndef SANITIZER_GO
Dmitry Vyukov069ce822012-05-17 14:17:51 +000053const unsigned kMaxTidInClock = kMaxTid * 2; // This includes msb 'freed' bit.
Stephen Hines86277eb2015-03-23 12:06:32 -070054#else
55const unsigned kMaxTidInClock = kMaxTid; // Go does not track freed memory.
56#endif
Dmitry Vyukov334553e2013-02-01 09:42:06 +000057const int kClkBits = 42;
Stephen Hines2d1fdb22014-05-28 23:58:16 -070058const unsigned kMaxTidReuse = (1 << (64 - kClkBits)) - 1;
Dmitry Vyukov01a7ce82013-10-16 15:35:12 +000059const uptr kShadowStackSize = 64 * 1024;
Kostya Serebryany7ac41482012-05-10 13:48:04 +000060
Kostya Serebryany7ac41482012-05-10 13:48:04 +000061// Count of shadow values in a shadow cell.
Dmitry Vyukov993e2e02012-11-15 18:44:22 +000062const uptr kShadowCnt = 4;
Kostya Serebryany7ac41482012-05-10 13:48:04 +000063
64// That many user bytes are mapped onto a single shadow cell.
Dmitry Vyukov6c51d6e2012-11-06 13:21:06 +000065const uptr kShadowCell = 8;
Kostya Serebryany7ac41482012-05-10 13:48:04 +000066
67// Size of a single shadow value (u64).
Dmitry Vyukov6c51d6e2012-11-06 13:21:06 +000068const uptr kShadowSize = 8;
Kostya Serebryany7ac41482012-05-10 13:48:04 +000069
Dmitry Vyukova05fcc12012-11-06 16:00:16 +000070// Shadow memory is kShadowMultiplier times larger than user memory.
71const uptr kShadowMultiplier = kShadowSize * kShadowCnt / kShadowCell;
72
Stephen Hines6a211c52014-07-21 00:49:56 -070073// That many user bytes are mapped onto a single meta shadow cell.
74// Must be less or equal to minimal memory allocator alignment.
75const uptr kMetaShadowCell = 8;
76
77// Size of a single meta shadow value (u32).
78const uptr kMetaShadowSize = 4;
79
Stephen Hines86277eb2015-03-23 12:06:32 -070080#if TSAN_NO_HISTORY
Stephen Hines2d1fdb22014-05-28 23:58:16 -070081const bool kCollectHistory = false;
82#else
83const bool kCollectHistory = true;
84#endif
85
Kostya Serebryany7ac41482012-05-10 13:48:04 +000086// 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.
Stephen Hines86277eb2015-03-23 12:06:32 -070089#if SANITIZER_DEBUG
Kostya Serebryany7ac41482012-05-10 13:48:04 +000090void build_consistency_debug();
91#else
92void build_consistency_release();
93#endif
94
95#if TSAN_COLLECT_STATS
96void build_consistency_stats();
97#else
98void build_consistency_nostats();
99#endif
100
Kostya Serebryany7ac41482012-05-10 13:48:04 +0000101static inline void USED build_consistency() {
Stephen Hines86277eb2015-03-23 12:06:32 -0700102#if SANITIZER_DEBUG
Dmitry Vyukov5aa3f222012-05-24 14:50:33 +0000103 build_consistency_debug();
Kostya Serebryany7ac41482012-05-10 13:48:04 +0000104#else
Dmitry Vyukov5aa3f222012-05-24 14:50:33 +0000105 build_consistency_release();
Kostya Serebryany7ac41482012-05-10 13:48:04 +0000106#endif
107#if TSAN_COLLECT_STATS
Dmitry Vyukov5aa3f222012-05-24 14:50:33 +0000108 build_consistency_stats();
Kostya Serebryany7ac41482012-05-10 13:48:04 +0000109#else
Dmitry Vyukov5aa3f222012-05-24 14:50:33 +0000110 build_consistency_nostats();
Kostya Serebryany7ac41482012-05-10 13:48:04 +0000111#endif
Kostya Serebryany7ac41482012-05-10 13:48:04 +0000112}
113
114template<typename T>
115T min(T a, T b) {
116 return a < b ? a : b;
117}
118
119template<typename T>
120T max(T a, T b) {
121 return a > b ? a : b;
122}
123
124template<typename T>
Dmitry Vyukov0415ac02012-12-04 12:19:53 +0000125T RoundUp(T p, u64 align) {
Kostya Serebryany7ac41482012-05-10 13:48:04 +0000126 DCHECK_EQ(align & (align - 1), 0);
127 return (T)(((u64)p + align - 1) & ~(align - 1));
128}
129
Dmitry Vyukov0415ac02012-12-04 12:19:53 +0000130template<typename T>
131T RoundDown(T p, u64 align) {
132 DCHECK_EQ(align & (align - 1), 0);
133 return (T)((u64)p & ~(align - 1));
134}
135
Dmitry Vyukovad9da372012-12-06 12:16:15 +0000136// Zeroizes high part, returns 'bits' lsb bits.
137template<typename T>
138T GetLsb(T v, int bits) {
139 return (T)((u64)v & ((1ull << bits) - 1));
140}
141
Kostya Serebryany7ac41482012-05-10 13:48:04 +0000142struct MD5Hash {
143 u64 hash[2];
Dmitry Vyukovb78caa62012-07-05 16:18:28 +0000144 bool operator==(const MD5Hash &other) const;
Kostya Serebryany7ac41482012-05-10 13:48:04 +0000145};
146
147MD5Hash md5_hash(const void *data, uptr size);
148
149struct ThreadState;
Stephen Hines2d1fdb22014-05-28 23:58:16 -0700150class ThreadContext;
Kostya Serebryany7ac41482012-05-10 13:48:04 +0000151struct Context;
152struct ReportStack;
153class ReportDesc;
154class RegionAlloc;
Stephen Hines6a211c52014-07-21 00:49:56 -0700155
156// Descriptor of user's memory block.
157struct MBlock {
158 u64 siz;
159 u32 stk;
160 u16 tid;
161};
162
163COMPILER_CHECK(sizeof(MBlock) == 16);
Kostya Serebryany7ac41482012-05-10 13:48:04 +0000164
165} // namespace __tsan
166
Kostya Serebryany7ac41482012-05-10 13:48:04 +0000167#endif // TSAN_DEFS_H