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