]>
Commit | Line | Data |
---|---|---|
cd0be65c WM |
1 | //===-- tsan_platform.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 | // Platform-specific code. | |
11 | //===----------------------------------------------------------------------===// | |
12 | ||
a0408454 KS |
13 | /* |
14 | C++ linux memory layout: | |
15 | 0000 0000 0000 - 03c0 0000 0000: protected | |
16 | 03c0 0000 0000 - 1000 0000 0000: shadow | |
17 | 1000 0000 0000 - 6000 0000 0000: protected | |
18 | 6000 0000 0000 - 6200 0000 0000: traces | |
19 | 6200 0000 0000 - 7d00 0000 0000: - | |
20 | 7d00 0000 0000 - 7e00 0000 0000: heap | |
21 | 7e00 0000 0000 - 7fff ffff ffff: modules and main thread stack | |
22 | ||
23 | C++ COMPAT linux memory layout: | |
24 | 0000 0000 0000 - 0400 0000 0000: protected | |
25 | 0400 0000 0000 - 1000 0000 0000: shadow | |
26 | 1000 0000 0000 - 2900 0000 0000: protected | |
27 | 2900 0000 0000 - 2c00 0000 0000: modules | |
28 | 2c00 0000 0000 - 6000 0000 0000: - | |
29 | 6000 0000 0000 - 6200 0000 0000: traces | |
30 | 6200 0000 0000 - 7d00 0000 0000: - | |
31 | 7d00 0000 0000 - 7e00 0000 0000: heap | |
32 | 7e00 0000 0000 - 7f00 0000 0000: - | |
33 | 7f00 0000 0000 - 7fff ffff ffff: main thread stack | |
34 | ||
35 | Go linux and darwin memory layout: | |
36 | 0000 0000 0000 - 0000 1000 0000: executable | |
37 | 0000 1000 0000 - 00f8 0000 0000: - | |
38 | 00f8 0000 0000 - 0118 0000 0000: heap | |
39 | 0118 0000 0000 - 1000 0000 0000: - | |
40 | 1000 0000 0000 - 1460 0000 0000: shadow | |
41 | 1460 0000 0000 - 6000 0000 0000: - | |
42 | 6000 0000 0000 - 6200 0000 0000: traces | |
43 | 6200 0000 0000 - 7fff ffff ffff: - | |
44 | ||
45 | Go windows memory layout: | |
46 | 0000 0000 0000 - 0000 1000 0000: executable | |
47 | 0000 1000 0000 - 00f8 0000 0000: - | |
48 | 00f8 0000 0000 - 0118 0000 0000: heap | |
49 | 0118 0000 0000 - 0100 0000 0000: - | |
50 | 0100 0000 0000 - 0560 0000 0000: shadow | |
51 | 0560 0000 0000 - 0760 0000 0000: traces | |
52 | 0760 0000 0000 - 07ff ffff ffff: - | |
53 | */ | |
54 | ||
cd0be65c WM |
55 | #ifndef TSAN_PLATFORM_H |
56 | #define TSAN_PLATFORM_H | |
57 | ||
a0408454 KS |
58 | #include "tsan_defs.h" |
59 | #include "tsan_trace.h" | |
cd0be65c | 60 | |
e297eb60 | 61 | #if defined(__LP64__) || defined(_WIN64) |
cd0be65c WM |
62 | namespace __tsan { |
63 | ||
64 | #if defined(TSAN_GO) | |
65 | static const uptr kLinuxAppMemBeg = 0x000000000000ULL; | |
66 | static const uptr kLinuxAppMemEnd = 0x00fcffffffffULL; | |
e297eb60 KS |
67 | # if defined(_WIN32) |
68 | static const uptr kLinuxShadowMsk = 0x010000000000ULL; | |
69 | # else | |
cd0be65c | 70 | static const uptr kLinuxShadowMsk = 0x100000000000ULL; |
e297eb60 | 71 | # endif |
cd0be65c WM |
72 | // TSAN_COMPAT_SHADOW is intended for COMPAT virtual memory layout, |
73 | // when memory addresses are of the 0x2axxxxxxxxxx form. | |
74 | // The option is enabled with 'setarch x86_64 -L'. | |
75 | #elif defined(TSAN_COMPAT_SHADOW) && TSAN_COMPAT_SHADOW | |
76 | static const uptr kLinuxAppMemBeg = 0x290000000000ULL; | |
77 | static const uptr kLinuxAppMemEnd = 0x7fffffffffffULL; | |
78 | #else | |
79 | static const uptr kLinuxAppMemBeg = 0x7cf000000000ULL; | |
80 | static const uptr kLinuxAppMemEnd = 0x7fffffffffffULL; | |
81 | #endif | |
82 | ||
83 | static const uptr kLinuxAppMemMsk = 0x7c0000000000ULL; | |
84 | ||
a0408454 KS |
85 | #if defined(_WIN32) |
86 | const uptr kTraceMemBegin = 0x056000000000ULL; | |
87 | #else | |
88 | const uptr kTraceMemBegin = 0x600000000000ULL; | |
89 | #endif | |
90 | const uptr kTraceMemSize = 0x020000000000ULL; | |
91 | ||
cd0be65c WM |
92 | // This has to be a macro to allow constant initialization of constants below. |
93 | #ifndef TSAN_GO | |
94 | #define MemToShadow(addr) \ | |
95 | (((addr) & ~(kLinuxAppMemMsk | (kShadowCell - 1))) * kShadowCnt) | |
96 | #else | |
97 | #define MemToShadow(addr) \ | |
98 | ((((addr) & ~(kShadowCell - 1)) * kShadowCnt) | kLinuxShadowMsk) | |
99 | #endif | |
100 | ||
101 | static const uptr kLinuxShadowBeg = MemToShadow(kLinuxAppMemBeg); | |
102 | static const uptr kLinuxShadowEnd = | |
4ba5ca46 | 103 | MemToShadow(kLinuxAppMemEnd) | 0xff; |
cd0be65c WM |
104 | |
105 | static inline bool IsAppMem(uptr mem) { | |
106 | return mem >= kLinuxAppMemBeg && mem <= kLinuxAppMemEnd; | |
107 | } | |
108 | ||
109 | static inline bool IsShadowMem(uptr mem) { | |
110 | return mem >= kLinuxShadowBeg && mem <= kLinuxShadowEnd; | |
111 | } | |
112 | ||
113 | static inline uptr ShadowToMem(uptr shadow) { | |
114 | CHECK(IsShadowMem(shadow)); | |
115 | #ifdef TSAN_GO | |
116 | return (shadow & ~kLinuxShadowMsk) / kShadowCnt; | |
117 | #else | |
118 | return (shadow / kShadowCnt) | kLinuxAppMemMsk; | |
119 | #endif | |
120 | } | |
121 | ||
122 | // For COMPAT mapping returns an alternative address | |
123 | // that mapped to the same shadow address. | |
124 | // COMPAT mapping is not quite one-to-one. | |
125 | static inline uptr AlternativeAddress(uptr addr) { | |
126 | #if defined(TSAN_COMPAT_SHADOW) && TSAN_COMPAT_SHADOW | |
127 | return (addr & ~kLinuxAppMemMsk) | 0x280000000000ULL; | |
128 | #else | |
129 | return 0; | |
130 | #endif | |
131 | } | |
132 | ||
133 | uptr GetShadowMemoryConsumption(); | |
134 | void FlushShadowMemory(); | |
135 | ||
136 | const char *InitializePlatform(); | |
137 | void FinalizePlatform(); | |
a0408454 KS |
138 | uptr ALWAYS_INLINE INLINE GetThreadTrace(int tid) { |
139 | uptr p = kTraceMemBegin + (uptr)tid * kTraceSize * sizeof(Event); | |
140 | DCHECK_LT(p, kTraceMemBegin + kTraceMemSize); | |
141 | return p; | |
142 | } | |
cd0be65c WM |
143 | |
144 | void internal_start_thread(void(*func)(void*), void *arg); | |
145 | ||
146 | // Says whether the addr relates to a global var. | |
147 | // Guesses with high probability, may yield both false positives and negatives. | |
148 | bool IsGlobalVar(uptr addr); | |
149 | uptr GetTlsSize(); | |
150 | void GetThreadStackAndTls(bool main, uptr *stk_addr, uptr *stk_size, | |
151 | uptr *tls_addr, uptr *tls_size); | |
152 | ||
153 | } // namespace __tsan | |
154 | ||
e297eb60 | 155 | #else // defined(__LP64__) || defined(_WIN64) |
cd0be65c WM |
156 | # error "Only 64-bit is supported" |
157 | #endif | |
158 | ||
159 | #endif // TSAN_PLATFORM_H |