blob: 9c7b329dcf000d7baff16e93d2f863fae59241b5 [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";
41#else
Dmitry Vyukov3fb70e32012-11-28 13:01:32 +000042const bool kGoMode = false;
43const bool kCppMode = true;
Dmitry Vyukov79c98362012-11-08 11:32:40 +000044const char *const kTsanOptionsEnv = "TSAN_OPTIONS";
45#endif
46
Dmitry Vyukov9d2ffc22012-05-22 14:34:43 +000047const int kTidBits = 13;
Kostya Serebryany3d6ae152012-05-11 14:42:24 +000048const unsigned kMaxTid = 1 << kTidBits;
Stephen Hines86277eb2015-03-23 12:06:32 -070049#ifndef SANITIZER_GO
Dmitry Vyukov069ce822012-05-17 14:17:51 +000050const unsigned kMaxTidInClock = kMaxTid * 2; // This includes msb 'freed' bit.
Stephen Hines86277eb2015-03-23 12:06:32 -070051#else
52const unsigned kMaxTidInClock = kMaxTid; // Go does not track freed memory.
53#endif
Dmitry Vyukov334553e2013-02-01 09:42:06 +000054const int kClkBits = 42;
Stephen Hines2d1fdb22014-05-28 23:58:16 -070055const unsigned kMaxTidReuse = (1 << (64 - kClkBits)) - 1;
Dmitry Vyukov01a7ce82013-10-16 15:35:12 +000056const uptr kShadowStackSize = 64 * 1024;
Kostya Serebryany7ac41482012-05-10 13:48:04 +000057
Kostya Serebryany7ac41482012-05-10 13:48:04 +000058// Count of shadow values in a shadow cell.
Dmitry Vyukov993e2e02012-11-15 18:44:22 +000059const uptr kShadowCnt = 4;
Kostya Serebryany7ac41482012-05-10 13:48:04 +000060
61// That many user bytes are mapped onto a single shadow cell.
Dmitry Vyukov6c51d6e2012-11-06 13:21:06 +000062const uptr kShadowCell = 8;
Kostya Serebryany7ac41482012-05-10 13:48:04 +000063
64// Size of a single shadow value (u64).
Dmitry Vyukov6c51d6e2012-11-06 13:21:06 +000065const uptr kShadowSize = 8;
Kostya Serebryany7ac41482012-05-10 13:48:04 +000066
Dmitry Vyukova05fcc12012-11-06 16:00:16 +000067// Shadow memory is kShadowMultiplier times larger than user memory.
68const uptr kShadowMultiplier = kShadowSize * kShadowCnt / kShadowCell;
69
Stephen Hines6a211c52014-07-21 00:49:56 -070070// That many user bytes are mapped onto a single meta shadow cell.
71// Must be less or equal to minimal memory allocator alignment.
72const uptr kMetaShadowCell = 8;
73
74// Size of a single meta shadow value (u32).
75const uptr kMetaShadowSize = 4;
76
Stephen Hines86277eb2015-03-23 12:06:32 -070077#if TSAN_NO_HISTORY
Stephen Hines2d1fdb22014-05-28 23:58:16 -070078const bool kCollectHistory = false;
79#else
80const bool kCollectHistory = true;
81#endif
82
Pirama Arumuga Nainar799172d2016-03-03 15:50:30 -080083const unsigned kInvalidTid = (unsigned)-1;
84
Kostya Serebryany7ac41482012-05-10 13:48:04 +000085// The following "build consistency" machinery ensures that all source files
86// are built in the same configuration. Inconsistent builds lead to
87// hard to debug crashes.
Stephen Hines86277eb2015-03-23 12:06:32 -070088#if SANITIZER_DEBUG
Kostya Serebryany7ac41482012-05-10 13:48:04 +000089void build_consistency_debug();
90#else
91void build_consistency_release();
92#endif
93
94#if TSAN_COLLECT_STATS
95void build_consistency_stats();
96#else
97void build_consistency_nostats();
98#endif
99
Kostya Serebryany7ac41482012-05-10 13:48:04 +0000100static inline void USED build_consistency() {
Stephen Hines86277eb2015-03-23 12:06:32 -0700101#if SANITIZER_DEBUG
Dmitry Vyukov5aa3f222012-05-24 14:50:33 +0000102 build_consistency_debug();
Kostya Serebryany7ac41482012-05-10 13:48:04 +0000103#else
Dmitry Vyukov5aa3f222012-05-24 14:50:33 +0000104 build_consistency_release();
Kostya Serebryany7ac41482012-05-10 13:48:04 +0000105#endif
106#if TSAN_COLLECT_STATS
Dmitry Vyukov5aa3f222012-05-24 14:50:33 +0000107 build_consistency_stats();
Kostya Serebryany7ac41482012-05-10 13:48:04 +0000108#else
Dmitry Vyukov5aa3f222012-05-24 14:50:33 +0000109 build_consistency_nostats();
Kostya Serebryany7ac41482012-05-10 13:48:04 +0000110#endif
Kostya Serebryany7ac41482012-05-10 13:48:04 +0000111}
112
113template<typename T>
114T min(T a, T b) {
115 return a < b ? a : b;
116}
117
118template<typename T>
119T max(T a, T b) {
120 return a > b ? a : b;
121}
122
123template<typename T>
Dmitry Vyukov0415ac02012-12-04 12:19:53 +0000124T RoundUp(T p, u64 align) {
Kostya Serebryany7ac41482012-05-10 13:48:04 +0000125 DCHECK_EQ(align & (align - 1), 0);
126 return (T)(((u64)p + align - 1) & ~(align - 1));
127}
128
Dmitry Vyukov0415ac02012-12-04 12:19:53 +0000129template<typename T>
130T RoundDown(T p, u64 align) {
131 DCHECK_EQ(align & (align - 1), 0);
132 return (T)((u64)p & ~(align - 1));
133}
134
Dmitry Vyukovad9da372012-12-06 12:16:15 +0000135// Zeroizes high part, returns 'bits' lsb bits.
136template<typename T>
137T GetLsb(T v, int bits) {
138 return (T)((u64)v & ((1ull << bits) - 1));
139}
140
Kostya Serebryany7ac41482012-05-10 13:48:04 +0000141struct MD5Hash {
142 u64 hash[2];
Dmitry Vyukovb78caa62012-07-05 16:18:28 +0000143 bool operator==(const MD5Hash &other) const;
Kostya Serebryany7ac41482012-05-10 13:48:04 +0000144};
145
146MD5Hash md5_hash(const void *data, uptr size);
147
148struct ThreadState;
Stephen Hines2d1fdb22014-05-28 23:58:16 -0700149class ThreadContext;
Kostya Serebryany7ac41482012-05-10 13:48:04 +0000150struct Context;
151struct ReportStack;
152class ReportDesc;
153class RegionAlloc;
Stephen Hines6a211c52014-07-21 00:49:56 -0700154
155// Descriptor of user's memory block.
156struct MBlock {
157 u64 siz;
158 u32 stk;
159 u16 tid;
160};
161
162COMPILER_CHECK(sizeof(MBlock) == 16);
Kostya Serebryany7ac41482012-05-10 13:48:04 +0000163
164} // namespace __tsan
165
Kostya Serebryany7ac41482012-05-10 13:48:04 +0000166#endif // TSAN_DEFS_H