tsan_defs.h 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. //===-- tsan_defs.h ---------------------------------------------*- C++ -*-===//
  2. //
  3. // This file is distributed under the University of Illinois Open Source
  4. // License. See LICENSE.TXT for details.
  5. //
  6. //===----------------------------------------------------------------------===//
  7. //
  8. // This file is a part of ThreadSanitizer (TSan), a race detector.
  9. //
  10. //===----------------------------------------------------------------------===//
  11. #ifndef TSAN_DEFS_H
  12. #define TSAN_DEFS_H
  13. #include "sanitizer_common/sanitizer_internal_defs.h"
  14. #include "sanitizer_common/sanitizer_libc.h"
  15. #include "tsan_stat.h"
  16. #ifndef TSAN_DEBUG
  17. #define TSAN_DEBUG 0
  18. #endif // TSAN_DEBUG
  19. namespace __tsan {
  20. #ifdef TSAN_GO
  21. const bool kGoMode = true;
  22. const bool kCppMode = false;
  23. const char *const kTsanOptionsEnv = "GORACE";
  24. // Go linker does not support weak symbols.
  25. #define CPP_WEAK
  26. #else
  27. const bool kGoMode = false;
  28. const bool kCppMode = true;
  29. const char *const kTsanOptionsEnv = "TSAN_OPTIONS";
  30. #define CPP_WEAK WEAK
  31. #endif
  32. const int kTidBits = 13;
  33. const unsigned kMaxTid = 1 << kTidBits;
  34. const unsigned kMaxTidInClock = kMaxTid * 2; // This includes msb 'freed' bit.
  35. const int kClkBits = 42;
  36. const unsigned kMaxTidReuse = (1 << (64 - kClkBits)) - 1;
  37. const uptr kShadowStackSize = 64 * 1024;
  38. #ifdef TSAN_SHADOW_COUNT
  39. # if TSAN_SHADOW_COUNT == 2 \
  40. || TSAN_SHADOW_COUNT == 4 || TSAN_SHADOW_COUNT == 8
  41. const uptr kShadowCnt = TSAN_SHADOW_COUNT;
  42. # else
  43. # error "TSAN_SHADOW_COUNT must be one of 2,4,8"
  44. # endif
  45. #else
  46. // Count of shadow values in a shadow cell.
  47. #define TSAN_SHADOW_COUNT 4
  48. const uptr kShadowCnt = 4;
  49. #endif
  50. // That many user bytes are mapped onto a single shadow cell.
  51. const uptr kShadowCell = 8;
  52. // Size of a single shadow value (u64).
  53. const uptr kShadowSize = 8;
  54. // Shadow memory is kShadowMultiplier times larger than user memory.
  55. const uptr kShadowMultiplier = kShadowSize * kShadowCnt / kShadowCell;
  56. // That many user bytes are mapped onto a single meta shadow cell.
  57. // Must be less or equal to minimal memory allocator alignment.
  58. const uptr kMetaShadowCell = 8;
  59. // Size of a single meta shadow value (u32).
  60. const uptr kMetaShadowSize = 4;
  61. #if defined(TSAN_NO_HISTORY) && TSAN_NO_HISTORY
  62. const bool kCollectHistory = false;
  63. #else
  64. const bool kCollectHistory = true;
  65. #endif
  66. #if defined(TSAN_COLLECT_STATS) && TSAN_COLLECT_STATS
  67. const bool kCollectStats = true;
  68. #else
  69. const bool kCollectStats = false;
  70. #endif
  71. // The following "build consistency" machinery ensures that all source files
  72. // are built in the same configuration. Inconsistent builds lead to
  73. // hard to debug crashes.
  74. #if TSAN_DEBUG
  75. void build_consistency_debug();
  76. #else
  77. void build_consistency_release();
  78. #endif
  79. #if TSAN_COLLECT_STATS
  80. void build_consistency_stats();
  81. #else
  82. void build_consistency_nostats();
  83. #endif
  84. #if TSAN_SHADOW_COUNT == 1
  85. void build_consistency_shadow1();
  86. #elif TSAN_SHADOW_COUNT == 2
  87. void build_consistency_shadow2();
  88. #elif TSAN_SHADOW_COUNT == 4
  89. void build_consistency_shadow4();
  90. #else
  91. void build_consistency_shadow8();
  92. #endif
  93. static inline void USED build_consistency() {
  94. #if TSAN_DEBUG
  95. build_consistency_debug();
  96. #else
  97. build_consistency_release();
  98. #endif
  99. #if TSAN_COLLECT_STATS
  100. build_consistency_stats();
  101. #else
  102. build_consistency_nostats();
  103. #endif
  104. #if TSAN_SHADOW_COUNT == 1
  105. build_consistency_shadow1();
  106. #elif TSAN_SHADOW_COUNT == 2
  107. build_consistency_shadow2();
  108. #elif TSAN_SHADOW_COUNT == 4
  109. build_consistency_shadow4();
  110. #else
  111. build_consistency_shadow8();
  112. #endif
  113. }
  114. template<typename T>
  115. T min(T a, T b) {
  116. return a < b ? a : b;
  117. }
  118. template<typename T>
  119. T max(T a, T b) {
  120. return a > b ? a : b;
  121. }
  122. template<typename T>
  123. T RoundUp(T p, u64 align) {
  124. DCHECK_EQ(align & (align - 1), 0);
  125. return (T)(((u64)p + align - 1) & ~(align - 1));
  126. }
  127. template<typename T>
  128. T RoundDown(T p, u64 align) {
  129. DCHECK_EQ(align & (align - 1), 0);
  130. return (T)((u64)p & ~(align - 1));
  131. }
  132. // Zeroizes high part, returns 'bits' lsb bits.
  133. template<typename T>
  134. T GetLsb(T v, int bits) {
  135. return (T)((u64)v & ((1ull << bits) - 1));
  136. }
  137. struct MD5Hash {
  138. u64 hash[2];
  139. bool operator==(const MD5Hash &other) const;
  140. };
  141. MD5Hash md5_hash(const void *data, uptr size);
  142. struct ThreadState;
  143. class ThreadContext;
  144. struct Context;
  145. struct ReportStack;
  146. class ReportDesc;
  147. class RegionAlloc;
  148. // Descriptor of user's memory block.
  149. struct MBlock {
  150. u64 siz;
  151. u32 stk;
  152. u16 tid;
  153. };
  154. COMPILER_CHECK(sizeof(MBlock) == 16);
  155. } // namespace __tsan
  156. #endif // TSAN_DEFS_H