• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===-- tsan_platform.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 // Platform-specific code.
13 //===----------------------------------------------------------------------===//
14 
15 #ifndef TSAN_PLATFORM_H
16 #define TSAN_PLATFORM_H
17 
18 #include "tsan_rtl.h"
19 
20 #if __LP64__
21 namespace __tsan {
22 
23 #if defined(TSAN_GO)
24 static const uptr kLinuxAppMemBeg = 0x000000000000ULL;
25 static const uptr kLinuxAppMemEnd = 0x00fcffffffffULL;
26 static const uptr kLinuxShadowMsk = 0x100000000000ULL;
27 // TSAN_COMPAT_SHADOW is intended for COMPAT virtual memory layout,
28 // when memory addresses are of the 0x2axxxxxxxxxx form.
29 // The option is enabled with 'setarch x86_64 -L'.
30 #elif defined(TSAN_COMPAT_SHADOW) && TSAN_COMPAT_SHADOW
31 static const uptr kLinuxAppMemBeg = 0x290000000000ULL;
32 static const uptr kLinuxAppMemEnd = 0x7fffffffffffULL;
33 #else
34 static const uptr kLinuxAppMemBeg = 0x7cf000000000ULL;
35 static const uptr kLinuxAppMemEnd = 0x7fffffffffffULL;
36 #endif
37 
38 static const uptr kLinuxAppMemMsk = 0x7c0000000000ULL;
39 
40 // This has to be a macro to allow constant initialization of constants below.
41 #ifndef TSAN_GO
42 #define MemToShadow(addr) \
43     (((addr) & ~(kLinuxAppMemMsk | (kShadowCell - 1))) * kShadowCnt)
44 #else
45 #define MemToShadow(addr) \
46     ((((addr) & ~(kShadowCell - 1)) * kShadowCnt) | kLinuxShadowMsk)
47 #endif
48 
49 static const uptr kLinuxShadowBeg = MemToShadow(kLinuxAppMemBeg);
50 static const uptr kLinuxShadowEnd =
51   MemToShadow(kLinuxAppMemEnd) | (kPageSize - 1);
52 
IsAppMem(uptr mem)53 static inline bool IsAppMem(uptr mem) {
54   return mem >= kLinuxAppMemBeg && mem <= kLinuxAppMemEnd;
55 }
56 
IsShadowMem(uptr mem)57 static inline bool IsShadowMem(uptr mem) {
58   return mem >= kLinuxShadowBeg && mem <= kLinuxShadowEnd;
59 }
60 
ShadowToMem(uptr shadow)61 static inline uptr ShadowToMem(uptr shadow) {
62   CHECK(IsShadowMem(shadow));
63 #ifdef TSAN_GO
64   return (shadow & ~kLinuxShadowMsk) / kShadowCnt;
65 #else
66   return (shadow / kShadowCnt) | kLinuxAppMemMsk;
67 #endif
68 }
69 
70 // For COMPAT mapping returns an alternative address
71 // that mapped to the same shadow address.
72 // COMPAT mapping is not quite one-to-one.
AlternativeAddress(uptr addr)73 static inline uptr AlternativeAddress(uptr addr) {
74 #if defined(TSAN_COMPAT_SHADOW) && TSAN_COMPAT_SHADOW
75   return (addr & ~kLinuxAppMemMsk) | 0x280000000000ULL;
76 #else
77   return 0;
78 #endif
79 }
80 
81 uptr GetShadowMemoryConsumption();
82 void FlushShadowMemory();
83 
84 const char *InitializePlatform();
85 void FinalizePlatform();
86 
87 void internal_start_thread(void(*func)(void*), void *arg);
88 
89 // Says whether the addr relates to a global var.
90 // Guesses with high probability, may yield both false positives and negatives.
91 bool IsGlobalVar(uptr addr);
92 uptr GetTlsSize();
93 void GetThreadStackAndTls(bool main, uptr *stk_addr, uptr *stk_size,
94                           uptr *tls_addr, uptr *tls_size);
95 
96 }  // namespace __tsan
97 
98 #else  // __LP64__
99 # error "Only 64-bit is supported"
100 #endif
101 
102 #endif  // TSAN_PLATFORM_H
103