1 //===-- tsan_defs.h ---------------------------------------------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This file is a part of ThreadSanitizer (TSan), a race detector.
11 //===----------------------------------------------------------------------===//
16 #include "sanitizer_common/sanitizer_internal_defs.h"
17 #include "sanitizer_common/sanitizer_libc.h"
18 #include "sanitizer_common/sanitizer_mutex.h"
19 #include "ubsan/ubsan_platform.h"
21 #ifndef TSAN_VECTORIZE
22 # define TSAN_VECTORIZE __SSE4_2__
26 // <emmintrin.h> transitively includes <stdlib.h>,
27 // and it's prohibited to include std headers into tsan runtime.
28 // So we do this dirty trick.
29 # define _MM_MALLOC_H_INCLUDED
30 # define __MM_MALLOC_H
31 # include <emmintrin.h>
32 # include <smmintrin.h>
33 # define VECTOR_ALIGNED ALIGNED(16)
36 # define VECTOR_ALIGNED
39 // Setup defaults for compile definitions.
40 #ifndef TSAN_NO_HISTORY
41 # define TSAN_NO_HISTORY 0
44 #ifndef TSAN_CONTAINS_UBSAN
45 # if CAN_SANITIZE_UB && !SANITIZER_GO
46 # define TSAN_CONTAINS_UBSAN 1
48 # define TSAN_CONTAINS_UBSAN 0
54 constexpr uptr kByteBits
= 8;
57 enum class Sid
: u8
{};
58 constexpr uptr kThreadSlotCount
= 256;
59 constexpr Sid kFreeSid
= static_cast<Sid
>(255);
61 // Abstract time unit, vector clock element.
62 enum class Epoch
: u16
{};
63 constexpr uptr kEpochBits
= 14;
64 constexpr Epoch kEpochZero
= static_cast<Epoch
>(0);
65 constexpr Epoch kEpochOver
= static_cast<Epoch
>(1 << kEpochBits
);
67 const int kClkBits
= 42;
68 const unsigned kMaxTidReuse
= (1 << (64 - kClkBits
)) - 1;
72 u64 reused
: 64 - kClkBits
; // tid reuse count
76 static const uptr kSize
= 512;
77 static const uptr kTableSize
= kSize
/ sizeof(u32
);
78 static const uptr kClockCount
= kSize
/ sizeof(ClockElem
);
79 static const uptr kRefIdx
= kTableSize
- 1;
80 static const uptr kBlockIdx
= kTableSize
- 2;
83 u32 table
[kTableSize
];
84 ClockElem clock
[kClockCount
];
91 const int kTidBits
= 13;
92 // Reduce kMaxTid by kClockCount because one slot in ClockBlock table is
93 // occupied by reference counter, so total number of elements we can store
94 // in SyncClock is kClockCount * (kTableSize - 1).
95 const unsigned kMaxTid
= (1 << kTidBits
) - ClockBlock::kClockCount
;
97 const unsigned kMaxTidInClock
= kMaxTid
* 2; // This includes msb 'freed' bit.
99 const unsigned kMaxTidInClock
= kMaxTid
; // Go does not track freed memory.
101 const uptr kShadowStackSize
= 64 * 1024;
103 // Count of shadow values in a shadow cell.
104 const uptr kShadowCnt
= 4;
106 // That many user bytes are mapped onto a single shadow cell.
107 const uptr kShadowCell
= 8;
109 // Single shadow value.
110 typedef u64 RawShadow
;
111 const uptr kShadowSize
= sizeof(RawShadow
);
113 // Shadow memory is kShadowMultiplier times larger than user memory.
114 const uptr kShadowMultiplier
= kShadowSize
* kShadowCnt
/ kShadowCell
;
116 // That many user bytes are mapped onto a single meta shadow cell.
117 // Must be less or equal to minimal memory allocator alignment.
118 const uptr kMetaShadowCell
= 8;
120 // Size of a single meta shadow value (u32).
121 const uptr kMetaShadowSize
= 4;
123 // All addresses and PCs are assumed to be compressable to that many bits.
124 const uptr kCompressedAddrBits
= 44;
127 const bool kCollectHistory
= false;
129 const bool kCollectHistory
= true;
132 // The following "build consistency" machinery ensures that all source files
133 // are built in the same configuration. Inconsistent builds lead to
134 // hard to debug crashes.
136 void build_consistency_debug();
138 void build_consistency_release();
141 static inline void USED
build_consistency() {
143 build_consistency_debug();
145 build_consistency_release();
151 return a
< b
? a
: b
;
156 return a
> b
? a
: b
;
160 T
RoundUp(T p
, u64 align
) {
161 DCHECK_EQ(align
& (align
- 1), 0);
162 return (T
)(((u64
)p
+ align
- 1) & ~(align
- 1));
166 T
RoundDown(T p
, u64 align
) {
167 DCHECK_EQ(align
& (align
- 1), 0);
168 return (T
)((u64
)p
& ~(align
- 1));
171 // Zeroizes high part, returns 'bits' lsb bits.
173 T
GetLsb(T v
, int bits
) {
174 return (T
)((u64
)v
& ((1ull << bits
) - 1));
179 bool operator==(const MD5Hash
&other
) const;
182 MD5Hash
md5_hash(const void *data
, uptr size
);
192 typedef uptr AccessType
;
196 kAccessRead
= 1 << 0,
197 kAccessAtomic
= 1 << 1,
198 kAccessVptr
= 1 << 2, // read or write of an object virtual table pointer
199 kAccessFree
= 1 << 3, // synthetic memory access during memory freeing
200 kAccessExternalPC
= 1 << 4, // access PC can have kExternalPCBit set
203 // Descriptor of user's memory block.
211 COMPILER_CHECK(sizeof(MBlock
) == 16);
213 enum ExternalTag
: uptr
{
214 kExternalTagNone
= 0,
215 kExternalTagSwiftModifyingAccess
= 1,
216 kExternalTagFirstUserAvailable
= 2,
217 kExternalTagMax
= 1024,
218 // Don't set kExternalTagMax over 65,536, since MBlock only stores tags
219 // as 16-bit values, see tsan_defs.h.
223 MutexTypeTrace
= MutexLastCommon
,
226 MutexTypeAnnotations
,
233 } // namespace __tsan
235 #endif // TSAN_DEFS_H