Home | History | Annotate | Line # | Download | only in tsan
tsan_rtl.h revision 1.2
      1  1.1  mrg //===-- tsan_rtl.h ----------------------------------------------*- C++ -*-===//
      2  1.1  mrg //
      3  1.1  mrg // This file is distributed under the University of Illinois Open Source
      4  1.1  mrg // License. See LICENSE.TXT for details.
      5  1.1  mrg //
      6  1.1  mrg //===----------------------------------------------------------------------===//
      7  1.1  mrg //
      8  1.1  mrg // This file is a part of ThreadSanitizer (TSan), a race detector.
      9  1.1  mrg //
     10  1.1  mrg // Main internal TSan header file.
     11  1.1  mrg //
     12  1.1  mrg // Ground rules:
     13  1.1  mrg //   - C++ run-time should not be used (static CTORs, RTTI, exceptions, static
     14  1.1  mrg //     function-scope locals)
     15  1.1  mrg //   - All functions/classes/etc reside in namespace __tsan, except for those
     16  1.1  mrg //     declared in tsan_interface.h.
     17  1.1  mrg //   - Platform-specific files should be used instead of ifdefs (*).
     18  1.1  mrg //   - No system headers included in header files (*).
     19  1.1  mrg //   - Platform specific headres included only into platform-specific files (*).
     20  1.1  mrg //
     21  1.1  mrg //  (*) Except when inlining is critical for performance.
     22  1.1  mrg //===----------------------------------------------------------------------===//
     23  1.1  mrg 
     24  1.1  mrg #ifndef TSAN_RTL_H
     25  1.1  mrg #define TSAN_RTL_H
     26  1.1  mrg 
     27  1.2  mrg #include "sanitizer_common/sanitizer_allocator.h"
     28  1.2  mrg #include "sanitizer_common/sanitizer_allocator_internal.h"
     29  1.2  mrg #include "sanitizer_common/sanitizer_asm.h"
     30  1.1  mrg #include "sanitizer_common/sanitizer_common.h"
     31  1.2  mrg #include "sanitizer_common/sanitizer_deadlock_detector_interface.h"
     32  1.2  mrg #include "sanitizer_common/sanitizer_libignore.h"
     33  1.2  mrg #include "sanitizer_common/sanitizer_suppressions.h"
     34  1.2  mrg #include "sanitizer_common/sanitizer_thread_registry.h"
     35  1.2  mrg #include "sanitizer_common/sanitizer_vector.h"
     36  1.1  mrg #include "tsan_clock.h"
     37  1.1  mrg #include "tsan_defs.h"
     38  1.1  mrg #include "tsan_flags.h"
     39  1.2  mrg #include "tsan_mman.h"
     40  1.1  mrg #include "tsan_sync.h"
     41  1.1  mrg #include "tsan_trace.h"
     42  1.1  mrg #include "tsan_report.h"
     43  1.1  mrg #include "tsan_platform.h"
     44  1.1  mrg #include "tsan_mutexset.h"
     45  1.2  mrg #include "tsan_ignoreset.h"
     46  1.2  mrg #include "tsan_stack_trace.h"
     47  1.1  mrg 
     48  1.1  mrg #if SANITIZER_WORDSIZE != 64
     49  1.1  mrg # error "ThreadSanitizer is supported only on 64-bit platforms"
     50  1.1  mrg #endif
     51  1.1  mrg 
     52  1.1  mrg namespace __tsan {
     53  1.1  mrg 
     54  1.2  mrg #if !SANITIZER_GO
     55  1.2  mrg struct MapUnmapCallback;
     56  1.2  mrg #if defined(__mips64) || defined(__aarch64__) || defined(__powerpc__)
     57  1.2  mrg static const uptr kAllocatorRegionSizeLog = 20;
     58  1.2  mrg static const uptr kAllocatorNumRegions =
     59  1.2  mrg     SANITIZER_MMAP_RANGE_SIZE >> kAllocatorRegionSizeLog;
     60  1.2  mrg typedef TwoLevelByteMap<(kAllocatorNumRegions >> 12), 1 << 12,
     61  1.2  mrg     MapUnmapCallback> ByteMap;
     62  1.2  mrg struct AP32 {
     63  1.2  mrg   static const uptr kSpaceBeg = 0;
     64  1.2  mrg   static const u64 kSpaceSize = SANITIZER_MMAP_RANGE_SIZE;
     65  1.2  mrg   static const uptr kMetadataSize = 0;
     66  1.2  mrg   typedef __sanitizer::CompactSizeClassMap SizeClassMap;
     67  1.2  mrg   static const uptr kRegionSizeLog = kAllocatorRegionSizeLog;
     68  1.2  mrg   typedef __tsan::ByteMap ByteMap;
     69  1.2  mrg   typedef __tsan::MapUnmapCallback MapUnmapCallback;
     70  1.2  mrg   static const uptr kFlags = 0;
     71  1.1  mrg };
     72  1.2  mrg typedef SizeClassAllocator32<AP32> PrimaryAllocator;
     73  1.1  mrg #else
     74  1.2  mrg struct AP64 {  // Allocator64 parameters. Deliberately using a short name.
     75  1.2  mrg   static const uptr kSpaceBeg = Mapping::kHeapMemBeg;
     76  1.2  mrg   static const uptr kSpaceSize = Mapping::kHeapMemEnd - Mapping::kHeapMemBeg;
     77  1.2  mrg   static const uptr kMetadataSize = 0;
     78  1.2  mrg   typedef DefaultSizeClassMap SizeClassMap;
     79  1.2  mrg   typedef __tsan::MapUnmapCallback MapUnmapCallback;
     80  1.2  mrg   static const uptr kFlags = 0;
     81  1.2  mrg };
     82  1.2  mrg typedef SizeClassAllocator64<AP64> PrimaryAllocator;
     83  1.1  mrg #endif
     84  1.1  mrg typedef SizeClassAllocatorLocalCache<PrimaryAllocator> AllocatorCache;
     85  1.2  mrg typedef LargeMmapAllocator<MapUnmapCallback> SecondaryAllocator;
     86  1.1  mrg typedef CombinedAllocator<PrimaryAllocator, AllocatorCache,
     87  1.1  mrg     SecondaryAllocator> Allocator;
     88  1.1  mrg Allocator *allocator();
     89  1.1  mrg #endif
     90  1.1  mrg 
     91  1.1  mrg void TsanCheckFailed(const char *file, int line, const char *cond,
     92  1.1  mrg                      u64 v1, u64 v2);
     93  1.1  mrg 
     94  1.2  mrg const u64 kShadowRodata = (u64)-1;  // .rodata shadow marker
     95  1.2  mrg 
     96  1.1  mrg // FastState (from most significant bit):
     97  1.1  mrg //   ignore          : 1
     98  1.1  mrg //   tid             : kTidBits
     99  1.1  mrg //   unused          : -
    100  1.1  mrg //   history_size    : 3
    101  1.2  mrg //   epoch           : kClkBits
    102  1.1  mrg class FastState {
    103  1.1  mrg  public:
    104  1.1  mrg   FastState(u64 tid, u64 epoch) {
    105  1.1  mrg     x_ = tid << kTidShift;
    106  1.2  mrg     x_ |= epoch;
    107  1.1  mrg     DCHECK_EQ(tid, this->tid());
    108  1.1  mrg     DCHECK_EQ(epoch, this->epoch());
    109  1.1  mrg     DCHECK_EQ(GetIgnoreBit(), false);
    110  1.1  mrg   }
    111  1.1  mrg 
    112  1.1  mrg   explicit FastState(u64 x)
    113  1.1  mrg       : x_(x) {
    114  1.1  mrg   }
    115  1.1  mrg 
    116  1.1  mrg   u64 raw() const {
    117  1.1  mrg     return x_;
    118  1.1  mrg   }
    119  1.1  mrg 
    120  1.1  mrg   u64 tid() const {
    121  1.1  mrg     u64 res = (x_ & ~kIgnoreBit) >> kTidShift;
    122  1.1  mrg     return res;
    123  1.1  mrg   }
    124  1.1  mrg 
    125  1.1  mrg   u64 TidWithIgnore() const {
    126  1.1  mrg     u64 res = x_ >> kTidShift;
    127  1.1  mrg     return res;
    128  1.1  mrg   }
    129  1.1  mrg 
    130  1.1  mrg   u64 epoch() const {
    131  1.2  mrg     u64 res = x_ & ((1ull << kClkBits) - 1);
    132  1.1  mrg     return res;
    133  1.1  mrg   }
    134  1.1  mrg 
    135  1.1  mrg   void IncrementEpoch() {
    136  1.1  mrg     u64 old_epoch = epoch();
    137  1.2  mrg     x_ += 1;
    138  1.1  mrg     DCHECK_EQ(old_epoch + 1, epoch());
    139  1.1  mrg     (void)old_epoch;
    140  1.1  mrg   }
    141  1.1  mrg 
    142  1.1  mrg   void SetIgnoreBit() { x_ |= kIgnoreBit; }
    143  1.1  mrg   void ClearIgnoreBit() { x_ &= ~kIgnoreBit; }
    144  1.1  mrg   bool GetIgnoreBit() const { return (s64)x_ < 0; }
    145  1.1  mrg 
    146  1.1  mrg   void SetHistorySize(int hs) {
    147  1.1  mrg     CHECK_GE(hs, 0);
    148  1.1  mrg     CHECK_LE(hs, 7);
    149  1.2  mrg     x_ = (x_ & ~(kHistoryMask << kHistoryShift)) | (u64(hs) << kHistoryShift);
    150  1.1  mrg   }
    151  1.1  mrg 
    152  1.2  mrg   ALWAYS_INLINE
    153  1.1  mrg   int GetHistorySize() const {
    154  1.2  mrg     return (int)((x_ >> kHistoryShift) & kHistoryMask);
    155  1.1  mrg   }
    156  1.1  mrg 
    157  1.1  mrg   void ClearHistorySize() {
    158  1.2  mrg     SetHistorySize(0);
    159  1.1  mrg   }
    160  1.1  mrg 
    161  1.2  mrg   ALWAYS_INLINE
    162  1.1  mrg   u64 GetTracePos() const {
    163  1.1  mrg     const int hs = GetHistorySize();
    164  1.1  mrg     // When hs == 0, the trace consists of 2 parts.
    165  1.1  mrg     const u64 mask = (1ull << (kTracePartSizeBits + hs + 1)) - 1;
    166  1.1  mrg     return epoch() & mask;
    167  1.1  mrg   }
    168  1.1  mrg 
    169  1.1  mrg  private:
    170  1.1  mrg   friend class Shadow;
    171  1.1  mrg   static const int kTidShift = 64 - kTidBits - 1;
    172  1.1  mrg   static const u64 kIgnoreBit = 1ull << 63;
    173  1.1  mrg   static const u64 kFreedBit = 1ull << 63;
    174  1.2  mrg   static const u64 kHistoryShift = kClkBits;
    175  1.2  mrg   static const u64 kHistoryMask = 7;
    176  1.1  mrg   u64 x_;
    177  1.1  mrg };
    178  1.1  mrg 
    179  1.1  mrg // Shadow (from most significant bit):
    180  1.1  mrg //   freed           : 1
    181  1.1  mrg //   tid             : kTidBits
    182  1.1  mrg //   is_atomic       : 1
    183  1.1  mrg //   is_read         : 1
    184  1.1  mrg //   size_log        : 2
    185  1.1  mrg //   addr0           : 3
    186  1.2  mrg //   epoch           : kClkBits
    187  1.1  mrg class Shadow : public FastState {
    188  1.1  mrg  public:
    189  1.1  mrg   explicit Shadow(u64 x)
    190  1.1  mrg       : FastState(x) {
    191  1.1  mrg   }
    192  1.1  mrg 
    193  1.1  mrg   explicit Shadow(const FastState &s)
    194  1.1  mrg       : FastState(s.x_) {
    195  1.1  mrg     ClearHistorySize();
    196  1.1  mrg   }
    197  1.1  mrg 
    198  1.1  mrg   void SetAddr0AndSizeLog(u64 addr0, unsigned kAccessSizeLog) {
    199  1.2  mrg     DCHECK_EQ((x_ >> kClkBits) & 31, 0);
    200  1.1  mrg     DCHECK_LE(addr0, 7);
    201  1.1  mrg     DCHECK_LE(kAccessSizeLog, 3);
    202  1.2  mrg     x_ |= ((kAccessSizeLog << 3) | addr0) << kClkBits;
    203  1.1  mrg     DCHECK_EQ(kAccessSizeLog, size_log());
    204  1.1  mrg     DCHECK_EQ(addr0, this->addr0());
    205  1.1  mrg   }
    206  1.1  mrg 
    207  1.1  mrg   void SetWrite(unsigned kAccessIsWrite) {
    208  1.1  mrg     DCHECK_EQ(x_ & kReadBit, 0);
    209  1.1  mrg     if (!kAccessIsWrite)
    210  1.1  mrg       x_ |= kReadBit;
    211  1.1  mrg     DCHECK_EQ(kAccessIsWrite, IsWrite());
    212  1.1  mrg   }
    213  1.1  mrg 
    214  1.1  mrg   void SetAtomic(bool kIsAtomic) {
    215  1.1  mrg     DCHECK(!IsAtomic());
    216  1.1  mrg     if (kIsAtomic)
    217  1.1  mrg       x_ |= kAtomicBit;
    218  1.1  mrg     DCHECK_EQ(IsAtomic(), kIsAtomic);
    219  1.1  mrg   }
    220  1.1  mrg 
    221  1.1  mrg   bool IsAtomic() const {
    222  1.1  mrg     return x_ & kAtomicBit;
    223  1.1  mrg   }
    224  1.1  mrg 
    225  1.1  mrg   bool IsZero() const {
    226  1.1  mrg     return x_ == 0;
    227  1.1  mrg   }
    228  1.1  mrg 
    229  1.1  mrg   static inline bool TidsAreEqual(const Shadow s1, const Shadow s2) {
    230  1.1  mrg     u64 shifted_xor = (s1.x_ ^ s2.x_) >> kTidShift;
    231  1.1  mrg     DCHECK_EQ(shifted_xor == 0, s1.TidWithIgnore() == s2.TidWithIgnore());
    232  1.1  mrg     return shifted_xor == 0;
    233  1.1  mrg   }
    234  1.1  mrg 
    235  1.2  mrg   static ALWAYS_INLINE
    236  1.2  mrg   bool Addr0AndSizeAreEqual(const Shadow s1, const Shadow s2) {
    237  1.2  mrg     u64 masked_xor = ((s1.x_ ^ s2.x_) >> kClkBits) & 31;
    238  1.1  mrg     return masked_xor == 0;
    239  1.1  mrg   }
    240  1.1  mrg 
    241  1.2  mrg   static ALWAYS_INLINE bool TwoRangesIntersect(Shadow s1, Shadow s2,
    242  1.1  mrg       unsigned kS2AccessSize) {
    243  1.1  mrg     bool res = false;
    244  1.1  mrg     u64 diff = s1.addr0() - s2.addr0();
    245  1.1  mrg     if ((s64)diff < 0) {  // s1.addr0 < s2.addr0  // NOLINT
    246  1.1  mrg       // if (s1.addr0() + size1) > s2.addr0()) return true;
    247  1.2  mrg       if (s1.size() > -diff)
    248  1.2  mrg         res = true;
    249  1.1  mrg     } else {
    250  1.1  mrg       // if (s2.addr0() + kS2AccessSize > s1.addr0()) return true;
    251  1.2  mrg       if (kS2AccessSize > diff)
    252  1.2  mrg         res = true;
    253  1.1  mrg     }
    254  1.2  mrg     DCHECK_EQ(res, TwoRangesIntersectSlow(s1, s2));
    255  1.2  mrg     DCHECK_EQ(res, TwoRangesIntersectSlow(s2, s1));
    256  1.1  mrg     return res;
    257  1.1  mrg   }
    258  1.1  mrg 
    259  1.2  mrg   u64 ALWAYS_INLINE addr0() const { return (x_ >> kClkBits) & 7; }
    260  1.2  mrg   u64 ALWAYS_INLINE size() const { return 1ull << size_log(); }
    261  1.2  mrg   bool ALWAYS_INLINE IsWrite() const { return !IsRead(); }
    262  1.2  mrg   bool ALWAYS_INLINE IsRead() const { return x_ & kReadBit; }
    263  1.1  mrg 
    264  1.1  mrg   // The idea behind the freed bit is as follows.
    265  1.1  mrg   // When the memory is freed (or otherwise unaccessible) we write to the shadow
    266  1.1  mrg   // values with tid/epoch related to the free and the freed bit set.
    267  1.1  mrg   // During memory accesses processing the freed bit is considered
    268  1.1  mrg   // as msb of tid. So any access races with shadow with freed bit set
    269  1.1  mrg   // (it is as if write from a thread with which we never synchronized before).
    270  1.1  mrg   // This allows us to detect accesses to freed memory w/o additional
    271  1.1  mrg   // overheads in memory access processing and at the same time restore
    272  1.1  mrg   // tid/epoch of free.
    273  1.1  mrg   void MarkAsFreed() {
    274  1.1  mrg      x_ |= kFreedBit;
    275  1.1  mrg   }
    276  1.1  mrg 
    277  1.1  mrg   bool IsFreed() const {
    278  1.1  mrg     return x_ & kFreedBit;
    279  1.1  mrg   }
    280  1.1  mrg 
    281  1.1  mrg   bool GetFreedAndReset() {
    282  1.1  mrg     bool res = x_ & kFreedBit;
    283  1.1  mrg     x_ &= ~kFreedBit;
    284  1.1  mrg     return res;
    285  1.1  mrg   }
    286  1.1  mrg 
    287  1.2  mrg   bool ALWAYS_INLINE IsBothReadsOrAtomic(bool kIsWrite, bool kIsAtomic) const {
    288  1.2  mrg     bool v = x_ & ((u64(kIsWrite ^ 1) << kReadShift)
    289  1.2  mrg         | (u64(kIsAtomic) << kAtomicShift));
    290  1.1  mrg     DCHECK_EQ(v, (!IsWrite() && !kIsWrite) || (IsAtomic() && kIsAtomic));
    291  1.1  mrg     return v;
    292  1.1  mrg   }
    293  1.1  mrg 
    294  1.2  mrg   bool ALWAYS_INLINE IsRWNotWeaker(bool kIsWrite, bool kIsAtomic) const {
    295  1.1  mrg     bool v = ((x_ >> kReadShift) & 3)
    296  1.1  mrg         <= u64((kIsWrite ^ 1) | (kIsAtomic << 1));
    297  1.1  mrg     DCHECK_EQ(v, (IsAtomic() < kIsAtomic) ||
    298  1.1  mrg         (IsAtomic() == kIsAtomic && !IsWrite() <= !kIsWrite));
    299  1.1  mrg     return v;
    300  1.1  mrg   }
    301  1.1  mrg 
    302  1.2  mrg   bool ALWAYS_INLINE IsRWWeakerOrEqual(bool kIsWrite, bool kIsAtomic) const {
    303  1.1  mrg     bool v = ((x_ >> kReadShift) & 3)
    304  1.1  mrg         >= u64((kIsWrite ^ 1) | (kIsAtomic << 1));
    305  1.1  mrg     DCHECK_EQ(v, (IsAtomic() > kIsAtomic) ||
    306  1.1  mrg         (IsAtomic() == kIsAtomic && !IsWrite() >= !kIsWrite));
    307  1.1  mrg     return v;
    308  1.1  mrg   }
    309  1.1  mrg 
    310  1.1  mrg  private:
    311  1.2  mrg   static const u64 kReadShift   = 5 + kClkBits;
    312  1.1  mrg   static const u64 kReadBit     = 1ull << kReadShift;
    313  1.2  mrg   static const u64 kAtomicShift = 6 + kClkBits;
    314  1.1  mrg   static const u64 kAtomicBit   = 1ull << kAtomicShift;
    315  1.1  mrg 
    316  1.2  mrg   u64 size_log() const { return (x_ >> (3 + kClkBits)) & 3; }
    317  1.1  mrg 
    318  1.2  mrg   static bool TwoRangesIntersectSlow(const Shadow s1, const Shadow s2) {
    319  1.1  mrg     if (s1.addr0() == s2.addr0()) return true;
    320  1.1  mrg     if (s1.addr0() < s2.addr0() && s1.addr0() + s1.size() > s2.addr0())
    321  1.1  mrg       return true;
    322  1.1  mrg     if (s2.addr0() < s1.addr0() && s2.addr0() + s2.size() > s1.addr0())
    323  1.1  mrg       return true;
    324  1.1  mrg     return false;
    325  1.1  mrg   }
    326  1.1  mrg };
    327  1.1  mrg 
    328  1.2  mrg struct ThreadSignalContext;
    329  1.2  mrg 
    330  1.2  mrg struct JmpBuf {
    331  1.2  mrg   uptr sp;
    332  1.2  mrg   uptr mangled_sp;
    333  1.2  mrg   int int_signal_send;
    334  1.2  mrg   bool in_blocking_func;
    335  1.2  mrg   uptr in_signal_handler;
    336  1.2  mrg   uptr *shadow_stack_pos;
    337  1.2  mrg };
    338  1.2  mrg 
    339  1.2  mrg // A Processor represents a physical thread, or a P for Go.
    340  1.2  mrg // It is used to store internal resources like allocate cache, and does not
    341  1.2  mrg // participate in race-detection logic (invisible to end user).
    342  1.2  mrg // In C++ it is tied to an OS thread just like ThreadState, however ideally
    343  1.2  mrg // it should be tied to a CPU (this way we will have fewer allocator caches).
    344  1.2  mrg // In Go it is tied to a P, so there are significantly fewer Processor's than
    345  1.2  mrg // ThreadState's (which are tied to Gs).
    346  1.2  mrg // A ThreadState must be wired with a Processor to handle events.
    347  1.2  mrg struct Processor {
    348  1.2  mrg   ThreadState *thr; // currently wired thread, or nullptr
    349  1.2  mrg #if !SANITIZER_GO
    350  1.2  mrg   AllocatorCache alloc_cache;
    351  1.2  mrg   InternalAllocatorCache internal_alloc_cache;
    352  1.2  mrg #endif
    353  1.2  mrg   DenseSlabAllocCache block_cache;
    354  1.2  mrg   DenseSlabAllocCache sync_cache;
    355  1.2  mrg   DenseSlabAllocCache clock_cache;
    356  1.2  mrg   DDPhysicalThread *dd_pt;
    357  1.2  mrg };
    358  1.2  mrg 
    359  1.2  mrg #if !SANITIZER_GO
    360  1.2  mrg // ScopedGlobalProcessor temporary setups a global processor for the current
    361  1.2  mrg // thread, if it does not have one. Intended for interceptors that can run
    362  1.2  mrg // at the very thread end, when we already destroyed the thread processor.
    363  1.2  mrg struct ScopedGlobalProcessor {
    364  1.2  mrg   ScopedGlobalProcessor();
    365  1.2  mrg   ~ScopedGlobalProcessor();
    366  1.2  mrg };
    367  1.2  mrg #endif
    368  1.1  mrg 
    369  1.1  mrg // This struct is stored in TLS.
    370  1.1  mrg struct ThreadState {
    371  1.1  mrg   FastState fast_state;
    372  1.1  mrg   // Synch epoch represents the threads's epoch before the last synchronization
    373  1.1  mrg   // action. It allows to reduce number of shadow state updates.
    374  1.1  mrg   // For example, fast_synch_epoch=100, last write to addr X was at epoch=150,
    375  1.1  mrg   // if we are processing write to X from the same thread at epoch=200,
    376  1.1  mrg   // we do nothing, because both writes happen in the same 'synch epoch'.
    377  1.1  mrg   // That is, if another memory access does not race with the former write,
    378  1.1  mrg   // it does not race with the latter as well.
    379  1.1  mrg   // QUESTION: can we can squeeze this into ThreadState::Fast?
    380  1.1  mrg   // E.g. ThreadState::Fast is a 44-bit, 32 are taken by synch_epoch and 12 are
    381  1.1  mrg   // taken by epoch between synchs.
    382  1.1  mrg   // This way we can save one load from tls.
    383  1.1  mrg   u64 fast_synch_epoch;
    384  1.1  mrg   // This is a slow path flag. On fast path, fast_state.GetIgnoreBit() is read.
    385  1.1  mrg   // We do not distinguish beteween ignoring reads and writes
    386  1.1  mrg   // for better performance.
    387  1.1  mrg   int ignore_reads_and_writes;
    388  1.2  mrg   int ignore_sync;
    389  1.2  mrg   int suppress_reports;
    390  1.2  mrg   // Go does not support ignores.
    391  1.2  mrg #if !SANITIZER_GO
    392  1.2  mrg   IgnoreSet mop_ignore_set;
    393  1.2  mrg   IgnoreSet sync_ignore_set;
    394  1.2  mrg #endif
    395  1.2  mrg   // C/C++ uses fixed size shadow stack embed into Trace.
    396  1.2  mrg   // Go uses malloc-allocated shadow stack with dynamic size.
    397  1.2  mrg   uptr *shadow_stack;
    398  1.2  mrg   uptr *shadow_stack_end;
    399  1.1  mrg   uptr *shadow_stack_pos;
    400  1.1  mrg   u64 *racy_shadow_addr;
    401  1.1  mrg   u64 racy_state[2];
    402  1.1  mrg   MutexSet mset;
    403  1.1  mrg   ThreadClock clock;
    404  1.2  mrg #if !SANITIZER_GO
    405  1.2  mrg   Vector<JmpBuf> jmp_bufs;
    406  1.2  mrg   int ignore_interceptors;
    407  1.1  mrg #endif
    408  1.2  mrg #if TSAN_COLLECT_STATS
    409  1.1  mrg   u64 stat[StatCnt];
    410  1.2  mrg #endif
    411  1.1  mrg   const int tid;
    412  1.1  mrg   const int unique_id;
    413  1.1  mrg   bool in_symbolizer;
    414  1.2  mrg   bool in_ignored_lib;
    415  1.2  mrg   bool is_inited;
    416  1.2  mrg   bool is_dead;
    417  1.1  mrg   bool is_freeing;
    418  1.2  mrg   bool is_vptr_access;
    419  1.1  mrg   const uptr stk_addr;
    420  1.1  mrg   const uptr stk_size;
    421  1.1  mrg   const uptr tls_addr;
    422  1.1  mrg   const uptr tls_size;
    423  1.2  mrg   ThreadContext *tctx;
    424  1.1  mrg 
    425  1.2  mrg #if SANITIZER_DEBUG && !SANITIZER_GO
    426  1.2  mrg   InternalDeadlockDetector internal_deadlock_detector;
    427  1.2  mrg #endif
    428  1.2  mrg   DDLogicalThread *dd_lt;
    429  1.2  mrg 
    430  1.2  mrg   // Current wired Processor, or nullptr. Required to handle any events.
    431  1.2  mrg   Processor *proc1;
    432  1.2  mrg #if !SANITIZER_GO
    433  1.2  mrg   Processor *proc() { return proc1; }
    434  1.2  mrg #else
    435  1.2  mrg   Processor *proc();
    436  1.2  mrg #endif
    437  1.1  mrg 
    438  1.2  mrg   atomic_uintptr_t in_signal_handler;
    439  1.2  mrg   ThreadSignalContext *signal_ctx;
    440  1.1  mrg 
    441  1.2  mrg #if !SANITIZER_GO
    442  1.1  mrg   u32 last_sleep_stack_id;
    443  1.1  mrg   ThreadClock last_sleep_clock;
    444  1.1  mrg #endif
    445  1.1  mrg 
    446  1.1  mrg   // Set in regions of runtime that must be signal-safe and fork-safe.
    447  1.1  mrg   // If set, malloc must not be called.
    448  1.1  mrg   int nomalloc;
    449  1.1  mrg 
    450  1.2  mrg   const ReportDesc *current_report;
    451  1.2  mrg 
    452  1.1  mrg   explicit ThreadState(Context *ctx, int tid, int unique_id, u64 epoch,
    453  1.2  mrg                        unsigned reuse_count,
    454  1.1  mrg                        uptr stk_addr, uptr stk_size,
    455  1.1  mrg                        uptr tls_addr, uptr tls_size);
    456  1.1  mrg };
    457  1.1  mrg 
    458  1.2  mrg #if !SANITIZER_GO
    459  1.2  mrg #if SANITIZER_MAC || SANITIZER_ANDROID
    460  1.2  mrg ThreadState *cur_thread();
    461  1.2  mrg void cur_thread_finalize();
    462  1.2  mrg #else
    463  1.2  mrg __attribute__((tls_model("initial-exec")))
    464  1.1  mrg extern THREADLOCAL char cur_thread_placeholder[];
    465  1.1  mrg INLINE ThreadState *cur_thread() {
    466  1.1  mrg   return reinterpret_cast<ThreadState *>(&cur_thread_placeholder);
    467  1.1  mrg }
    468  1.2  mrg INLINE void cur_thread_finalize() { }
    469  1.2  mrg #endif  // SANITIZER_MAC || SANITIZER_ANDROID
    470  1.2  mrg #endif  // SANITIZER_GO
    471  1.1  mrg 
    472  1.2  mrg class ThreadContext : public ThreadContextBase {
    473  1.2  mrg  public:
    474  1.2  mrg   explicit ThreadContext(int tid);
    475  1.2  mrg   ~ThreadContext();
    476  1.1  mrg   ThreadState *thr;
    477  1.2  mrg   u32 creation_stack_id;
    478  1.1  mrg   SyncClock sync;
    479  1.1  mrg   // Epoch at which the thread had started.
    480  1.1  mrg   // If we see an event from the thread stamped by an older epoch,
    481  1.1  mrg   // the event is from a dead thread that shared tid with this thread.
    482  1.1  mrg   u64 epoch0;
    483  1.1  mrg   u64 epoch1;
    484  1.1  mrg 
    485  1.2  mrg   // Override superclass callbacks.
    486  1.2  mrg   void OnDead() override;
    487  1.2  mrg   void OnJoined(void *arg) override;
    488  1.2  mrg   void OnFinished() override;
    489  1.2  mrg   void OnStarted(void *arg) override;
    490  1.2  mrg   void OnCreated(void *arg) override;
    491  1.2  mrg   void OnReset() override;
    492  1.2  mrg   void OnDetached(void *arg) override;
    493  1.1  mrg };
    494  1.1  mrg 
    495  1.1  mrg struct RacyStacks {
    496  1.1  mrg   MD5Hash hash[2];
    497  1.1  mrg   bool operator==(const RacyStacks &other) const {
    498  1.1  mrg     if (hash[0] == other.hash[0] && hash[1] == other.hash[1])
    499  1.1  mrg       return true;
    500  1.1  mrg     if (hash[0] == other.hash[1] && hash[1] == other.hash[0])
    501  1.1  mrg       return true;
    502  1.1  mrg     return false;
    503  1.1  mrg   }
    504  1.1  mrg };
    505  1.1  mrg 
    506  1.1  mrg struct RacyAddress {
    507  1.1  mrg   uptr addr_min;
    508  1.1  mrg   uptr addr_max;
    509  1.1  mrg };
    510  1.1  mrg 
    511  1.1  mrg struct FiredSuppression {
    512  1.1  mrg   ReportType type;
    513  1.2  mrg   uptr pc_or_addr;
    514  1.2  mrg   Suppression *supp;
    515  1.1  mrg };
    516  1.1  mrg 
    517  1.1  mrg struct Context {
    518  1.1  mrg   Context();
    519  1.1  mrg 
    520  1.1  mrg   bool initialized;
    521  1.2  mrg #if !SANITIZER_GO
    522  1.2  mrg   bool after_multithreaded_fork;
    523  1.2  mrg #endif
    524  1.1  mrg 
    525  1.2  mrg   MetaMap metamap;
    526  1.1  mrg 
    527  1.1  mrg   Mutex report_mtx;
    528  1.1  mrg   int nreported;
    529  1.1  mrg   int nmissed_expected;
    530  1.2  mrg   atomic_uint64_t last_symbolize_time_ns;
    531  1.1  mrg 
    532  1.2  mrg   void *background_thread;
    533  1.2  mrg   atomic_uint32_t stop_background_thread;
    534  1.1  mrg 
    535  1.2  mrg   ThreadRegistry *thread_registry;
    536  1.2  mrg 
    537  1.2  mrg   Mutex racy_mtx;
    538  1.1  mrg   Vector<RacyStacks> racy_stacks;
    539  1.1  mrg   Vector<RacyAddress> racy_addresses;
    540  1.2  mrg   // Number of fired suppressions may be large enough.
    541  1.2  mrg   Mutex fired_suppressions_mtx;
    542  1.2  mrg   InternalMmapVector<FiredSuppression> fired_suppressions;
    543  1.2  mrg   DDetector *dd;
    544  1.2  mrg 
    545  1.2  mrg   ClockAlloc clock_alloc;
    546  1.1  mrg 
    547  1.1  mrg   Flags flags;
    548  1.1  mrg 
    549  1.1  mrg   u64 stat[StatCnt];
    550  1.1  mrg   u64 int_alloc_cnt[MBlockTypeCount];
    551  1.1  mrg   u64 int_alloc_siz[MBlockTypeCount];
    552  1.1  mrg };
    553  1.1  mrg 
    554  1.2  mrg extern Context *ctx;  // The one and the only global runtime context.
    555  1.2  mrg 
    556  1.2  mrg ALWAYS_INLINE Flags *flags() {
    557  1.2  mrg   return &ctx->flags;
    558  1.2  mrg }
    559  1.2  mrg 
    560  1.2  mrg struct ScopedIgnoreInterceptors {
    561  1.2  mrg   ScopedIgnoreInterceptors() {
    562  1.2  mrg #if !SANITIZER_GO
    563  1.2  mrg     cur_thread()->ignore_interceptors++;
    564  1.2  mrg #endif
    565  1.2  mrg   }
    566  1.2  mrg 
    567  1.2  mrg   ~ScopedIgnoreInterceptors() {
    568  1.2  mrg #if !SANITIZER_GO
    569  1.2  mrg     cur_thread()->ignore_interceptors--;
    570  1.2  mrg #endif
    571  1.2  mrg   }
    572  1.1  mrg };
    573  1.1  mrg 
    574  1.2  mrg const char *GetObjectTypeFromTag(uptr tag);
    575  1.2  mrg const char *GetReportHeaderFromTag(uptr tag);
    576  1.2  mrg uptr TagFromShadowStackFrame(uptr pc);
    577  1.2  mrg 
    578  1.2  mrg class ScopedReportBase {
    579  1.1  mrg  public:
    580  1.2  mrg   void AddMemoryAccess(uptr addr, uptr external_tag, Shadow s, StackTrace stack,
    581  1.1  mrg                        const MutexSet *mset);
    582  1.2  mrg   void AddStack(StackTrace stack, bool suppressable = false);
    583  1.2  mrg   void AddThread(const ThreadContext *tctx, bool suppressable = false);
    584  1.2  mrg   void AddThread(int unique_tid, bool suppressable = false);
    585  1.2  mrg   void AddUniqueTid(int unique_tid);
    586  1.1  mrg   void AddMutex(const SyncVar *s);
    587  1.2  mrg   u64 AddMutex(u64 id);
    588  1.1  mrg   void AddLocation(uptr addr, uptr size);
    589  1.1  mrg   void AddSleep(u32 stack_id);
    590  1.2  mrg   void SetCount(int count);
    591  1.1  mrg 
    592  1.1  mrg   const ReportDesc *GetReport() const;
    593  1.1  mrg 
    594  1.2  mrg  protected:
    595  1.2  mrg   ScopedReportBase(ReportType typ, uptr tag);
    596  1.2  mrg   ~ScopedReportBase();
    597  1.2  mrg 
    598  1.1  mrg  private:
    599  1.1  mrg   ReportDesc *rep_;
    600  1.2  mrg   // Symbolizer makes lots of intercepted calls. If we try to process them,
    601  1.2  mrg   // at best it will cause deadlocks on internal mutexes.
    602  1.2  mrg   ScopedIgnoreInterceptors ignore_interceptors_;
    603  1.1  mrg 
    604  1.2  mrg   void AddDeadMutex(u64 id);
    605  1.1  mrg 
    606  1.2  mrg   ScopedReportBase(const ScopedReportBase &) = delete;
    607  1.2  mrg   void operator=(const ScopedReportBase &) = delete;
    608  1.1  mrg };
    609  1.1  mrg 
    610  1.2  mrg class ScopedReport : public ScopedReportBase {
    611  1.2  mrg  public:
    612  1.2  mrg   explicit ScopedReport(ReportType typ, uptr tag = kExternalTagNone);
    613  1.2  mrg   ~ScopedReport();
    614  1.2  mrg 
    615  1.2  mrg  private:
    616  1.2  mrg   ScopedErrorReportLock lock_;
    617  1.2  mrg };
    618  1.2  mrg 
    619  1.2  mrg ThreadContext *IsThreadStackOrTls(uptr addr, bool *is_stack);
    620  1.2  mrg void RestoreStack(int tid, const u64 epoch, VarSizeStackTrace *stk,
    621  1.2  mrg                   MutexSet *mset, uptr *tag = nullptr);
    622  1.2  mrg 
    623  1.2  mrg // The stack could look like:
    624  1.2  mrg //   <start> | <main> | <foo> | tag | <bar>
    625  1.2  mrg // This will extract the tag and keep:
    626  1.2  mrg //   <start> | <main> | <foo> | <bar>
    627  1.2  mrg template<typename StackTraceTy>
    628  1.2  mrg void ExtractTagFromStack(StackTraceTy *stack, uptr *tag = nullptr) {
    629  1.2  mrg   if (stack->size < 2) return;
    630  1.2  mrg   uptr possible_tag_pc = stack->trace[stack->size - 2];
    631  1.2  mrg   uptr possible_tag = TagFromShadowStackFrame(possible_tag_pc);
    632  1.2  mrg   if (possible_tag == kExternalTagNone) return;
    633  1.2  mrg   stack->trace_buffer[stack->size - 2] = stack->trace_buffer[stack->size - 1];
    634  1.2  mrg   stack->size -= 1;
    635  1.2  mrg   if (tag) *tag = possible_tag;
    636  1.2  mrg }
    637  1.2  mrg 
    638  1.2  mrg template<typename StackTraceTy>
    639  1.2  mrg void ObtainCurrentStack(ThreadState *thr, uptr toppc, StackTraceTy *stack,
    640  1.2  mrg                         uptr *tag = nullptr) {
    641  1.2  mrg   uptr size = thr->shadow_stack_pos - thr->shadow_stack;
    642  1.2  mrg   uptr start = 0;
    643  1.2  mrg   if (size + !!toppc > kStackTraceMax) {
    644  1.2  mrg     start = size + !!toppc - kStackTraceMax;
    645  1.2  mrg     size = kStackTraceMax - !!toppc;
    646  1.2  mrg   }
    647  1.2  mrg   stack->Init(&thr->shadow_stack[start], size, toppc);
    648  1.2  mrg   ExtractTagFromStack(stack, tag);
    649  1.2  mrg }
    650  1.2  mrg 
    651  1.2  mrg #define GET_STACK_TRACE_FATAL(thr, pc) \
    652  1.2  mrg   VarSizeStackTrace stack; \
    653  1.2  mrg   ObtainCurrentStack(thr, pc, &stack); \
    654  1.2  mrg   stack.ReverseOrder();
    655  1.1  mrg 
    656  1.2  mrg #if TSAN_COLLECT_STATS
    657  1.1  mrg void StatAggregate(u64 *dst, u64 *src);
    658  1.1  mrg void StatOutput(u64 *stat);
    659  1.2  mrg #endif
    660  1.2  mrg 
    661  1.2  mrg void ALWAYS_INLINE StatInc(ThreadState *thr, StatType typ, u64 n = 1) {
    662  1.2  mrg #if TSAN_COLLECT_STATS
    663  1.2  mrg   thr->stat[typ] += n;
    664  1.2  mrg #endif
    665  1.2  mrg }
    666  1.2  mrg void ALWAYS_INLINE StatSet(ThreadState *thr, StatType typ, u64 n) {
    667  1.2  mrg #if TSAN_COLLECT_STATS
    668  1.2  mrg   thr->stat[typ] = n;
    669  1.2  mrg #endif
    670  1.1  mrg }
    671  1.1  mrg 
    672  1.1  mrg void MapShadow(uptr addr, uptr size);
    673  1.2  mrg void MapThreadTrace(uptr addr, uptr size, const char *name);
    674  1.2  mrg void DontNeedShadowFor(uptr addr, uptr size);
    675  1.1  mrg void InitializeShadowMemory();
    676  1.1  mrg void InitializeInterceptors();
    677  1.2  mrg void InitializeLibIgnore();
    678  1.1  mrg void InitializeDynamicAnnotations();
    679  1.1  mrg 
    680  1.2  mrg void ForkBefore(ThreadState *thr, uptr pc);
    681  1.2  mrg void ForkParentAfter(ThreadState *thr, uptr pc);
    682  1.2  mrg void ForkChildAfter(ThreadState *thr, uptr pc);
    683  1.2  mrg 
    684  1.1  mrg void ReportRace(ThreadState *thr);
    685  1.2  mrg bool OutputReport(ThreadState *thr, const ScopedReport &srep);
    686  1.2  mrg bool IsFiredSuppression(Context *ctx, ReportType type, StackTrace trace);
    687  1.1  mrg bool IsExpectedReport(uptr addr, uptr size);
    688  1.2  mrg void PrintMatchedBenignRaces();
    689  1.1  mrg 
    690  1.1  mrg #if defined(TSAN_DEBUG_OUTPUT) && TSAN_DEBUG_OUTPUT >= 1
    691  1.1  mrg # define DPrintf Printf
    692  1.1  mrg #else
    693  1.1  mrg # define DPrintf(...)
    694  1.1  mrg #endif
    695  1.1  mrg 
    696  1.1  mrg #if defined(TSAN_DEBUG_OUTPUT) && TSAN_DEBUG_OUTPUT >= 2
    697  1.1  mrg # define DPrintf2 Printf
    698  1.1  mrg #else
    699  1.1  mrg # define DPrintf2(...)
    700  1.1  mrg #endif
    701  1.1  mrg 
    702  1.1  mrg u32 CurrentStackId(ThreadState *thr, uptr pc);
    703  1.2  mrg ReportStack *SymbolizeStackId(u32 stack_id);
    704  1.1  mrg void PrintCurrentStack(ThreadState *thr, uptr pc);
    705  1.2  mrg void PrintCurrentStackSlow(uptr pc);  // uses libunwind
    706  1.1  mrg 
    707  1.1  mrg void Initialize(ThreadState *thr);
    708  1.2  mrg void MaybeSpawnBackgroundThread();
    709  1.1  mrg int Finalize(ThreadState *thr);
    710  1.1  mrg 
    711  1.2  mrg void OnUserAlloc(ThreadState *thr, uptr pc, uptr p, uptr sz, bool write);
    712  1.2  mrg void OnUserFree(ThreadState *thr, uptr pc, uptr p, bool write);
    713  1.1  mrg 
    714  1.1  mrg void MemoryAccess(ThreadState *thr, uptr pc, uptr addr,
    715  1.1  mrg     int kAccessSizeLog, bool kAccessIsWrite, bool kIsAtomic);
    716  1.1  mrg void MemoryAccessImpl(ThreadState *thr, uptr addr,
    717  1.1  mrg     int kAccessSizeLog, bool kAccessIsWrite, bool kIsAtomic,
    718  1.1  mrg     u64 *shadow_mem, Shadow cur);
    719  1.1  mrg void MemoryAccessRange(ThreadState *thr, uptr pc, uptr addr,
    720  1.1  mrg     uptr size, bool is_write);
    721  1.1  mrg void MemoryAccessRangeStep(ThreadState *thr, uptr pc, uptr addr,
    722  1.1  mrg     uptr size, uptr step, bool is_write);
    723  1.2  mrg void UnalignedMemoryAccess(ThreadState *thr, uptr pc, uptr addr,
    724  1.2  mrg     int size, bool kAccessIsWrite, bool kIsAtomic);
    725  1.1  mrg 
    726  1.1  mrg const int kSizeLog1 = 0;
    727  1.1  mrg const int kSizeLog2 = 1;
    728  1.1  mrg const int kSizeLog4 = 2;
    729  1.1  mrg const int kSizeLog8 = 3;
    730  1.1  mrg 
    731  1.2  mrg void ALWAYS_INLINE MemoryRead(ThreadState *thr, uptr pc,
    732  1.1  mrg                                      uptr addr, int kAccessSizeLog) {
    733  1.1  mrg   MemoryAccess(thr, pc, addr, kAccessSizeLog, false, false);
    734  1.1  mrg }
    735  1.1  mrg 
    736  1.2  mrg void ALWAYS_INLINE MemoryWrite(ThreadState *thr, uptr pc,
    737  1.1  mrg                                       uptr addr, int kAccessSizeLog) {
    738  1.1  mrg   MemoryAccess(thr, pc, addr, kAccessSizeLog, true, false);
    739  1.1  mrg }
    740  1.1  mrg 
    741  1.2  mrg void ALWAYS_INLINE MemoryReadAtomic(ThreadState *thr, uptr pc,
    742  1.1  mrg                                            uptr addr, int kAccessSizeLog) {
    743  1.1  mrg   MemoryAccess(thr, pc, addr, kAccessSizeLog, false, true);
    744  1.1  mrg }
    745  1.1  mrg 
    746  1.2  mrg void ALWAYS_INLINE MemoryWriteAtomic(ThreadState *thr, uptr pc,
    747  1.1  mrg                                             uptr addr, int kAccessSizeLog) {
    748  1.1  mrg   MemoryAccess(thr, pc, addr, kAccessSizeLog, true, true);
    749  1.1  mrg }
    750  1.1  mrg 
    751  1.1  mrg void MemoryResetRange(ThreadState *thr, uptr pc, uptr addr, uptr size);
    752  1.1  mrg void MemoryRangeFreed(ThreadState *thr, uptr pc, uptr addr, uptr size);
    753  1.1  mrg void MemoryRangeImitateWrite(ThreadState *thr, uptr pc, uptr addr, uptr size);
    754  1.2  mrg 
    755  1.2  mrg void ThreadIgnoreBegin(ThreadState *thr, uptr pc, bool save_stack = true);
    756  1.2  mrg void ThreadIgnoreEnd(ThreadState *thr, uptr pc);
    757  1.2  mrg void ThreadIgnoreSyncBegin(ThreadState *thr, uptr pc, bool save_stack = true);
    758  1.2  mrg void ThreadIgnoreSyncEnd(ThreadState *thr, uptr pc);
    759  1.1  mrg 
    760  1.1  mrg void FuncEntry(ThreadState *thr, uptr pc);
    761  1.1  mrg void FuncExit(ThreadState *thr);
    762  1.1  mrg 
    763  1.1  mrg int ThreadCreate(ThreadState *thr, uptr pc, uptr uid, bool detached);
    764  1.2  mrg void ThreadStart(ThreadState *thr, int tid, tid_t os_id, bool workerthread);
    765  1.1  mrg void ThreadFinish(ThreadState *thr);
    766  1.1  mrg int ThreadTid(ThreadState *thr, uptr pc, uptr uid);
    767  1.1  mrg void ThreadJoin(ThreadState *thr, uptr pc, int tid);
    768  1.1  mrg void ThreadDetach(ThreadState *thr, uptr pc, int tid);
    769  1.1  mrg void ThreadFinalize(ThreadState *thr);
    770  1.1  mrg void ThreadSetName(ThreadState *thr, const char *name);
    771  1.1  mrg int ThreadCount(ThreadState *thr);
    772  1.1  mrg void ProcessPendingSignals(ThreadState *thr);
    773  1.1  mrg 
    774  1.2  mrg Processor *ProcCreate();
    775  1.2  mrg void ProcDestroy(Processor *proc);
    776  1.2  mrg void ProcWire(Processor *proc, ThreadState *thr);
    777  1.2  mrg void ProcUnwire(Processor *proc, ThreadState *thr);
    778  1.2  mrg 
    779  1.2  mrg // Note: the parameter is called flagz, because flags is already taken
    780  1.2  mrg // by the global function that returns flags.
    781  1.2  mrg void MutexCreate(ThreadState *thr, uptr pc, uptr addr, u32 flagz = 0);
    782  1.2  mrg void MutexDestroy(ThreadState *thr, uptr pc, uptr addr, u32 flagz = 0);
    783  1.2  mrg void MutexPreLock(ThreadState *thr, uptr pc, uptr addr, u32 flagz = 0);
    784  1.2  mrg void MutexPostLock(ThreadState *thr, uptr pc, uptr addr, u32 flagz = 0,
    785  1.2  mrg     int rec = 1);
    786  1.2  mrg int  MutexUnlock(ThreadState *thr, uptr pc, uptr addr, u32 flagz = 0);
    787  1.2  mrg void MutexPreReadLock(ThreadState *thr, uptr pc, uptr addr, u32 flagz = 0);
    788  1.2  mrg void MutexPostReadLock(ThreadState *thr, uptr pc, uptr addr, u32 flagz = 0);
    789  1.1  mrg void MutexReadUnlock(ThreadState *thr, uptr pc, uptr addr);
    790  1.1  mrg void MutexReadOrWriteUnlock(ThreadState *thr, uptr pc, uptr addr);
    791  1.2  mrg void MutexRepair(ThreadState *thr, uptr pc, uptr addr);  // call on EOWNERDEAD
    792  1.2  mrg void MutexInvalidAccess(ThreadState *thr, uptr pc, uptr addr);
    793  1.1  mrg 
    794  1.1  mrg void Acquire(ThreadState *thr, uptr pc, uptr addr);
    795  1.2  mrg // AcquireGlobal synchronizes the current thread with all other threads.
    796  1.2  mrg // In terms of happens-before relation, it draws a HB edge from all threads
    797  1.2  mrg // (where they happen to execute right now) to the current thread. We use it to
    798  1.2  mrg // handle Go finalizers. Namely, finalizer goroutine executes AcquireGlobal
    799  1.2  mrg // right before executing finalizers. This provides a coarse, but simple
    800  1.2  mrg // approximation of the actual required synchronization.
    801  1.1  mrg void AcquireGlobal(ThreadState *thr, uptr pc);
    802  1.1  mrg void Release(ThreadState *thr, uptr pc, uptr addr);
    803  1.1  mrg void ReleaseStore(ThreadState *thr, uptr pc, uptr addr);
    804  1.1  mrg void AfterSleep(ThreadState *thr, uptr pc);
    805  1.2  mrg void AcquireImpl(ThreadState *thr, uptr pc, SyncClock *c);
    806  1.2  mrg void ReleaseImpl(ThreadState *thr, uptr pc, SyncClock *c);
    807  1.2  mrg void ReleaseStoreImpl(ThreadState *thr, uptr pc, SyncClock *c);
    808  1.2  mrg void AcquireReleaseImpl(ThreadState *thr, uptr pc, SyncClock *c);
    809  1.1  mrg 
    810  1.1  mrg // The hacky call uses custom calling convention and an assembly thunk.
    811  1.1  mrg // It is considerably faster that a normal call for the caller
    812  1.1  mrg // if it is not executed (it is intended for slow paths from hot functions).
    813  1.1  mrg // The trick is that the call preserves all registers and the compiler
    814  1.1  mrg // does not treat it as a call.
    815  1.1  mrg // If it does not work for you, use normal call.
    816  1.2  mrg #if !SANITIZER_DEBUG && defined(__x86_64__) && !SANITIZER_MAC
    817  1.1  mrg // The caller may not create the stack frame for itself at all,
    818  1.1  mrg // so we create a reserve stack frame for it (1024b must be enough).
    819  1.1  mrg #define HACKY_CALL(f) \
    820  1.1  mrg   __asm__ __volatile__("sub $1024, %%rsp;" \
    821  1.2  mrg                        CFI_INL_ADJUST_CFA_OFFSET(1024) \
    822  1.1  mrg                        ".hidden " #f "_thunk;" \
    823  1.1  mrg                        "call " #f "_thunk;" \
    824  1.1  mrg                        "add $1024, %%rsp;" \
    825  1.2  mrg                        CFI_INL_ADJUST_CFA_OFFSET(-1024) \
    826  1.1  mrg                        ::: "memory", "cc");
    827  1.1  mrg #else
    828  1.1  mrg #define HACKY_CALL(f) f()
    829  1.1  mrg #endif
    830  1.1  mrg 
    831  1.1  mrg void TraceSwitch(ThreadState *thr);
    832  1.1  mrg uptr TraceTopPC(ThreadState *thr);
    833  1.1  mrg uptr TraceSize();
    834  1.1  mrg uptr TraceParts();
    835  1.2  mrg Trace *ThreadTrace(int tid);
    836  1.1  mrg 
    837  1.1  mrg extern "C" void __tsan_trace_switch();
    838  1.2  mrg void ALWAYS_INLINE TraceAddEvent(ThreadState *thr, FastState fs,
    839  1.1  mrg                                         EventType typ, u64 addr) {
    840  1.2  mrg   if (!kCollectHistory)
    841  1.2  mrg     return;
    842  1.1  mrg   DCHECK_GE((int)typ, 0);
    843  1.1  mrg   DCHECK_LE((int)typ, 7);
    844  1.2  mrg   DCHECK_EQ(GetLsb(addr, kEventPCBits), addr);
    845  1.1  mrg   StatInc(thr, StatEvents);
    846  1.1  mrg   u64 pos = fs.GetTracePos();
    847  1.1  mrg   if (UNLIKELY((pos % kTracePartSize) == 0)) {
    848  1.2  mrg #if !SANITIZER_GO
    849  1.1  mrg     HACKY_CALL(__tsan_trace_switch);
    850  1.1  mrg #else
    851  1.1  mrg     TraceSwitch(thr);
    852  1.1  mrg #endif
    853  1.1  mrg   }
    854  1.1  mrg   Event *trace = (Event*)GetThreadTrace(fs.tid());
    855  1.1  mrg   Event *evp = &trace[pos];
    856  1.2  mrg   Event ev = (u64)addr | ((u64)typ << kEventPCBits);
    857  1.1  mrg   *evp = ev;
    858  1.1  mrg }
    859  1.1  mrg 
    860  1.2  mrg #if !SANITIZER_GO
    861  1.2  mrg uptr ALWAYS_INLINE HeapEnd() {
    862  1.2  mrg   return HeapMemEnd() + PrimaryAllocator::AdditionalSize();
    863  1.2  mrg }
    864  1.2  mrg #endif
    865  1.2  mrg 
    866  1.1  mrg }  // namespace __tsan
    867  1.1  mrg 
    868  1.1  mrg #endif  // TSAN_RTL_H
    869