tsan_defs.h revision 2d1fdb26e458c4ddc04155c1d421bced3ba90cd0
15a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt//===-- tsan_defs.h ---------------------------------------------*- C++ -*-===//
25a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt//
35a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt//                     The LLVM Compiler Infrastructure
45a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt//
55a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt// This file is distributed under the University of Illinois Open Source
65a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt// License. See LICENSE.TXT for details.
75a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt//
85a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt//===----------------------------------------------------------------------===//
95a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt//
105a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt// This file is a part of ThreadSanitizer (TSan), a race detector.
115a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt//
125a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt//===----------------------------------------------------------------------===//
135a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
145a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#ifndef TSAN_DEFS_H
155a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#define TSAN_DEFS_H
165a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
175a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#include "sanitizer_common/sanitizer_internal_defs.h"
185a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#include "sanitizer_common/sanitizer_libc.h"
195a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#include "tsan_stat.h"
205a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
215a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#ifndef TSAN_DEBUG
225a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#define TSAN_DEBUG 0
235a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#endif  // TSAN_DEBUG
245a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
255a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtnamespace __tsan {
265a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
275a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#ifdef TSAN_GO
285a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtconst bool kGoMode = true;
295a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtconst bool kCppMode = false;
305a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtconst char *const kTsanOptionsEnv = "GORACE";
315a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt// Go linker does not support weak symbols.
325a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#define CPP_WEAK
335a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#else
345a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtconst bool kGoMode = false;
355a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtconst bool kCppMode = true;
365a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtconst char *const kTsanOptionsEnv = "TSAN_OPTIONS";
375a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#define CPP_WEAK WEAK
385a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#endif
395a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
405a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtconst int kTidBits = 13;
415a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtconst unsigned kMaxTid = 1 << kTidBits;
425a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtconst unsigned kMaxTidInClock = kMaxTid * 2;  // This includes msb 'freed' bit.
435a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtconst int kClkBits = 42;
445a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtconst unsigned kMaxTidReuse = (1 << (64 - kClkBits)) - 1;
455a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtconst uptr kShadowStackSize = 64 * 1024;
465a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtconst uptr kTraceStackSize = 256;
475a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
485a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#ifdef TSAN_SHADOW_COUNT
495a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt# if TSAN_SHADOW_COUNT == 2 \
505a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt  || TSAN_SHADOW_COUNT == 4 || TSAN_SHADOW_COUNT == 8
515a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtconst uptr kShadowCnt = TSAN_SHADOW_COUNT;
525a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt# else
535a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#   error "TSAN_SHADOW_COUNT must be one of 2,4,8"
545a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt# endif
555a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#else
565a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt// Count of shadow values in a shadow cell.
575a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtconst uptr kShadowCnt = 4;
585a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#endif
595a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
605a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt// That many user bytes are mapped onto a single shadow cell.
615a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtconst uptr kShadowCell = 8;
625a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
635a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt// Size of a single shadow value (u64).
645a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtconst uptr kShadowSize = 8;
655a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
665a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt// Shadow memory is kShadowMultiplier times larger than user memory.
675a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtconst uptr kShadowMultiplier = kShadowSize * kShadowCnt / kShadowCell;
685a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
695a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#if defined(TSAN_NO_HISTORY) && TSAN_NO_HISTORY
705a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtconst bool kCollectHistory = false;
715a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#else
725a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtconst bool kCollectHistory = true;
735a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#endif
745a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
755a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#if defined(TSAN_COLLECT_STATS) && TSAN_COLLECT_STATS
765a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtconst bool kCollectStats = true;
775a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#else
785a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtconst bool kCollectStats = false;
795a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#endif
805a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
815a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt// The following "build consistency" machinery ensures that all source files
825a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt// are built in the same configuration. Inconsistent builds lead to
835a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt// hard to debug crashes.
845a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#if TSAN_DEBUG
855a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtvoid build_consistency_debug();
865a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#else
875a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtvoid build_consistency_release();
885a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#endif
895a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
905a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#if TSAN_COLLECT_STATS
915a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtvoid build_consistency_stats();
925a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#else
935a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtvoid build_consistency_nostats();
945a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#endif
955a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
965a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#if TSAN_SHADOW_COUNT == 1
975a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtvoid build_consistency_shadow1();
985a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#elif TSAN_SHADOW_COUNT == 2
995a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtvoid build_consistency_shadow2();
1005a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#elif TSAN_SHADOW_COUNT == 4
1015a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtvoid build_consistency_shadow4();
1025a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#else
1035a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtvoid build_consistency_shadow8();
1045a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#endif
1055a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
1065a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstatic inline void USED build_consistency() {
1075a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#if TSAN_DEBUG
1085a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt  build_consistency_debug();
1095a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#else
1105a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt  build_consistency_release();
1115a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#endif
1125a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#if TSAN_COLLECT_STATS
1135a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt  build_consistency_stats();
1145a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#else
1155a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt  build_consistency_nostats();
1165a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#endif
1175a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#if TSAN_SHADOW_COUNT == 1
1185a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt  build_consistency_shadow1();
1195a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#elif TSAN_SHADOW_COUNT == 2
1205a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt  build_consistency_shadow2();
1215a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#elif TSAN_SHADOW_COUNT == 4
1225a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt  build_consistency_shadow4();
1235a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#else
1245a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt  build_consistency_shadow8();
1255a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#endif
1265a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt}
1275a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
1285a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidttemplate<typename T>
1295a1480c7c46c4236d93bfd303dde32062bee04acDmitry ShmidtT min(T a, T b) {
1305a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt  return a < b ? a : b;
1315a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt}
1325a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
1335a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidttemplate<typename T>
1345a1480c7c46c4236d93bfd303dde32062bee04acDmitry ShmidtT max(T a, T b) {
1355a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt  return a > b ? a : b;
1365a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt}
1375a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
1385a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidttemplate<typename T>
1395a1480c7c46c4236d93bfd303dde32062bee04acDmitry ShmidtT RoundUp(T p, u64 align) {
1405a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt  DCHECK_EQ(align & (align - 1), 0);
1415a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt  return (T)(((u64)p + align - 1) & ~(align - 1));
1425a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt}
1435a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
1445a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidttemplate<typename T>
1455a1480c7c46c4236d93bfd303dde32062bee04acDmitry ShmidtT RoundDown(T p, u64 align) {
1465a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt  DCHECK_EQ(align & (align - 1), 0);
1475a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt  return (T)((u64)p & ~(align - 1));
1485a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt}
1495a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
1505a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt// Zeroizes high part, returns 'bits' lsb bits.
1515a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidttemplate<typename T>
1525a1480c7c46c4236d93bfd303dde32062bee04acDmitry ShmidtT GetLsb(T v, int bits) {
1535a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt  return (T)((u64)v & ((1ull << bits) - 1));
1545a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt}
1555a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
1565a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstruct MD5Hash {
1575a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt  u64 hash[2];
1585a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt  bool operator==(const MD5Hash &other) const;
1595a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt};
1605a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
1615a1480c7c46c4236d93bfd303dde32062bee04acDmitry ShmidtMD5Hash md5_hash(const void *data, uptr size);
1625a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
1635a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstruct ThreadState;
1645a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtclass ThreadContext;
1655a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstruct Context;
1665a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstruct ReportStack;
1675a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtclass ReportDesc;
1685a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtclass RegionAlloc;
1695a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtclass StackTrace;
1705a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidtstruct MBlock;
1715a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
1725a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt}  // namespace __tsan
1735a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt
1745a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt#endif  // TSAN_DEFS_H
1755a1480c7c46c4236d93bfd303dde32062bee04acDmitry Shmidt