1 //===-- tsan_platform.h -----------------------------------------*- C++ -*-===//
3 // This file is distributed under the University of Illinois Open Source
4 // License. See LICENSE.TXT for details.
6 //===----------------------------------------------------------------------===//
8 // This file is a part of ThreadSanitizer (TSan), a race detector.
10 // Platform-specific code.
11 //===----------------------------------------------------------------------===//
13 #ifndef TSAN_PLATFORM_H
14 #define TSAN_PLATFORM_H
16 #if !defined(__LP64__) && !defined(_WIN64)
17 # error "Only 64-bit is supported"
20 #include "tsan_defs.h"
21 #include "tsan_trace.h"
25 #if !defined(SANITIZER_GO)
27 #if defined(__x86_64__)
29 C/C++ on linux/x86_64 and freebsd/x86_64
30 0000 0000 1000 - 0100 0000 0000: main binary and/or MAP_32BIT mappings
31 0100 0000 0000 - 0200 0000 0000: -
32 0200 0000 0000 - 1000 0000 0000: shadow
33 1000 0000 0000 - 3000 0000 0000: -
34 3000 0000 0000 - 4000 0000 0000: metainfo (memory blocks and sync objects)
35 4000 0000 0000 - 6000 0000 0000: -
36 6000 0000 0000 - 6200 0000 0000: traces
37 6200 0000 0000 - 7d00 0000 0000: -
38 7d00 0000 0000 - 7e00 0000 0000: heap
39 7e00 0000 0000 - 7e80 0000 0000: -
40 7e80 0000 0000 - 8000 0000 0000: modules and main thread stack
42 const uptr kMetaShadowBeg
= 0x300000000000ull
;
43 const uptr kMetaShadowEnd
= 0x400000000000ull
;
44 const uptr kTraceMemBeg
= 0x600000000000ull
;
45 const uptr kTraceMemEnd
= 0x620000000000ull
;
46 const uptr kShadowBeg
= 0x020000000000ull
;
47 const uptr kShadowEnd
= 0x100000000000ull
;
48 const uptr kHeapMemBeg
= 0x7d0000000000ull
;
49 const uptr kHeapMemEnd
= 0x7e0000000000ull
;
50 const uptr kLoAppMemBeg
= 0x000000001000ull
;
51 const uptr kLoAppMemEnd
= 0x010000000000ull
;
52 const uptr kHiAppMemBeg
= 0x7e8000000000ull
;
53 const uptr kHiAppMemEnd
= 0x800000000000ull
;
54 const uptr kAppMemMsk
= 0x7c0000000000ull
;
55 const uptr kAppMemXor
= 0x020000000000ull
;
56 const uptr kVdsoBeg
= 0xf000000000000000ull
;
57 #elif defined(__mips64)
60 0100 0000 00 - 0200 0000 00: main binary
61 0200 0000 00 - 1400 0000 00: -
62 1400 0000 00 - 2400 0000 00: shadow
63 2400 0000 00 - 3000 0000 00: -
64 3000 0000 00 - 4000 0000 00: metainfo (memory blocks and sync objects)
65 4000 0000 00 - 6000 0000 00: -
66 6000 0000 00 - 6200 0000 00: traces
67 6200 0000 00 - fe00 0000 00: -
68 fe00 0000 00 - ff00 0000 00: heap
69 ff00 0000 00 - ff80 0000 00: -
70 ff80 0000 00 - ffff ffff ff: modules and main thread stack
72 const uptr kMetaShadowBeg
= 0x3000000000ull
;
73 const uptr kMetaShadowEnd
= 0x4000000000ull
;
74 const uptr kTraceMemBeg
= 0x6000000000ull
;
75 const uptr kTraceMemEnd
= 0x6200000000ull
;
76 const uptr kShadowBeg
= 0x1400000000ull
;
77 const uptr kShadowEnd
= 0x2400000000ull
;
78 const uptr kHeapMemBeg
= 0xfe00000000ull
;
79 const uptr kHeapMemEnd
= 0xff00000000ull
;
80 const uptr kLoAppMemBeg
= 0x0100000000ull
;
81 const uptr kLoAppMemEnd
= 0x0200000000ull
;
82 const uptr kHiAppMemBeg
= 0xff80000000ull
;
83 const uptr kHiAppMemEnd
= 0xffffffffffull
;
84 const uptr kAppMemMsk
= 0xfc00000000ull
;
85 const uptr kAppMemXor
= 0x0400000000ull
;
86 const uptr kVdsoBeg
= 0xfffff00000ull
;
87 #elif defined(__aarch64__)
88 # if SANITIZER_AARCH64_VMA == 39
90 C/C++ on linux/aarch64 (39-bit VMA)
91 0000 4000 00 - 0200 0000 00: main binary
92 2000 0000 00 - 4000 0000 00: shadow memory
93 4000 0000 00 - 5000 0000 00: metainfo
94 5000 0000 00 - 6000 0000 00: -
95 6000 0000 00 - 6200 0000 00: traces
96 6200 0000 00 - 7d00 0000 00: -
97 7d00 0000 00 - 7e00 0000 00: heap
98 7e00 0000 00 - 7fff ffff ff: modules and main thread stack
100 const uptr kLoAppMemBeg
= 0x0000400000ull
;
101 const uptr kLoAppMemEnd
= 0x0200000000ull
;
102 const uptr kShadowBeg
= 0x2000000000ull
;
103 const uptr kShadowEnd
= 0x4000000000ull
;
104 const uptr kMetaShadowBeg
= 0x4000000000ull
;
105 const uptr kMetaShadowEnd
= 0x5000000000ull
;
106 const uptr kTraceMemBeg
= 0x6000000000ull
;
107 const uptr kTraceMemEnd
= 0x6200000000ull
;
108 const uptr kHeapMemBeg
= 0x7d00000000ull
;
109 const uptr kHeapMemEnd
= 0x7e00000000ull
;
110 const uptr kHiAppMemBeg
= 0x7e00000000ull
;
111 const uptr kHiAppMemEnd
= 0x7fffffffffull
;
112 const uptr kAppMemMsk
= 0x7800000000ull
;
113 const uptr kAppMemXor
= 0x0800000000ull
;
114 const uptr kVdsoBeg
= 0x7f00000000ull
;
115 # elif SANITIZER_AARCH64_VMA == 42
117 C/C++ on linux/aarch64 (42-bit VMA)
118 00000 4000 00 - 01000 0000 00: main binary
119 01000 0000 00 - 10000 0000 00: -
120 10000 0000 00 - 20000 0000 00: shadow memory
121 20000 0000 00 - 26000 0000 00: -
122 26000 0000 00 - 28000 0000 00: metainfo
123 28000 0000 00 - 36200 0000 00: -
124 36200 0000 00 - 36240 0000 00: traces
125 36240 0000 00 - 3e000 0000 00: -
126 3e000 0000 00 - 3f000 0000 00: heap
127 3c000 0000 00 - 3ff00 0000 00: -
128 3ff00 0000 00 - 3ffff f000 00: modules and main thread stack
130 const uptr kLoAppMemBeg
= 0x00000400000ull
;
131 const uptr kLoAppMemEnd
= 0x01000000000ull
;
132 const uptr kShadowBeg
= 0x10000000000ull
;
133 const uptr kShadowEnd
= 0x20000000000ull
;
134 const uptr kMetaShadowBeg
= 0x26000000000ull
;
135 const uptr kMetaShadowEnd
= 0x28000000000ull
;
136 const uptr kTraceMemBeg
= 0x36200000000ull
;
137 const uptr kTraceMemEnd
= 0x36400000000ull
;
138 const uptr kHeapMemBeg
= 0x3e000000000ull
;
139 const uptr kHeapMemEnd
= 0x3f000000000ull
;
140 const uptr kHiAppMemBeg
= 0x3ff00000000ull
;
141 const uptr kHiAppMemEnd
= 0x3fffff00000ull
;
142 const uptr kAppMemMsk
= 0x3c000000000ull
;
143 const uptr kAppMemXor
= 0x04000000000ull
;
144 const uptr kVdsoBeg
= 0x37f00000000ull
;
149 bool IsAppMem(uptr mem
) {
150 return (mem
>= kHeapMemBeg
&& mem
< kHeapMemEnd
) ||
151 (mem
>= kLoAppMemBeg
&& mem
< kLoAppMemEnd
) ||
152 (mem
>= kHiAppMemBeg
&& mem
< kHiAppMemEnd
);
156 bool IsShadowMem(uptr mem
) {
157 return mem
>= kShadowBeg
&& mem
<= kShadowEnd
;
161 bool IsMetaMem(uptr mem
) {
162 return mem
>= kMetaShadowBeg
&& mem
<= kMetaShadowEnd
;
166 uptr
MemToShadow(uptr x
) {
168 return (((x
) & ~(kAppMemMsk
| (kShadowCell
- 1)))
169 ^ kAppMemXor
) * kShadowCnt
;
173 u32
*MemToMeta(uptr x
) {
175 return (u32
*)(((((x
) & ~(kAppMemMsk
| (kMetaShadowCell
- 1)))
176 ^ kAppMemXor
) / kMetaShadowCell
* kMetaShadowSize
) | kMetaShadowBeg
);
180 uptr
ShadowToMem(uptr s
) {
181 CHECK(IsShadowMem(s
));
182 if (s
>= MemToShadow(kLoAppMemBeg
) && s
<= MemToShadow(kLoAppMemEnd
- 1))
183 return (s
/ kShadowCnt
) ^ kAppMemXor
;
185 return ((s
/ kShadowCnt
) ^ kAppMemXor
) | kAppMemMsk
;
188 static USED uptr UserRegions
[] = {
189 kLoAppMemBeg
, kLoAppMemEnd
,
190 kHiAppMemBeg
, kHiAppMemEnd
,
191 kHeapMemBeg
, kHeapMemEnd
,
194 #elif defined(SANITIZER_GO) && !SANITIZER_WINDOWS
196 /* Go on linux, darwin and freebsd
197 0000 0000 1000 - 0000 1000 0000: executable
198 0000 1000 0000 - 00c0 0000 0000: -
199 00c0 0000 0000 - 00e0 0000 0000: heap
200 00e0 0000 0000 - 2000 0000 0000: -
201 2000 0000 0000 - 2380 0000 0000: shadow
202 2380 0000 0000 - 3000 0000 0000: -
203 3000 0000 0000 - 4000 0000 0000: metainfo (memory blocks and sync objects)
204 4000 0000 0000 - 6000 0000 0000: -
205 6000 0000 0000 - 6200 0000 0000: traces
206 6200 0000 0000 - 8000 0000 0000: -
209 const uptr kMetaShadowBeg
= 0x300000000000ull
;
210 const uptr kMetaShadowEnd
= 0x400000000000ull
;
211 const uptr kTraceMemBeg
= 0x600000000000ull
;
212 const uptr kTraceMemEnd
= 0x620000000000ull
;
213 const uptr kShadowBeg
= 0x200000000000ull
;
214 const uptr kShadowEnd
= 0x238000000000ull
;
215 const uptr kAppMemBeg
= 0x000000001000ull
;
216 const uptr kAppMemEnd
= 0x00e000000000ull
;
219 bool IsAppMem(uptr mem
) {
220 return mem
>= kAppMemBeg
&& mem
< kAppMemEnd
;
224 bool IsShadowMem(uptr mem
) {
225 return mem
>= kShadowBeg
&& mem
<= kShadowEnd
;
229 bool IsMetaMem(uptr mem
) {
230 return mem
>= kMetaShadowBeg
&& mem
<= kMetaShadowEnd
;
234 uptr
MemToShadow(uptr x
) {
236 return ((x
& ~(kShadowCell
- 1)) * kShadowCnt
) | kShadowBeg
;
240 u32
*MemToMeta(uptr x
) {
242 return (u32
*)(((x
& ~(kMetaShadowCell
- 1)) / \
243 kMetaShadowCell
* kMetaShadowSize
) | kMetaShadowBeg
);
247 uptr
ShadowToMem(uptr s
) {
248 CHECK(IsShadowMem(s
));
249 return (s
& ~kShadowBeg
) / kShadowCnt
;
252 static USED uptr UserRegions
[] = {
253 kAppMemBeg
, kAppMemEnd
,
256 #elif defined(SANITIZER_GO) && SANITIZER_WINDOWS
259 0000 0000 1000 - 0000 1000 0000: executable
260 0000 1000 0000 - 00f8 0000 0000: -
261 00c0 0000 0000 - 00e0 0000 0000: heap
262 00e0 0000 0000 - 0100 0000 0000: -
263 0100 0000 0000 - 0500 0000 0000: shadow
264 0500 0000 0000 - 0560 0000 0000: -
265 0560 0000 0000 - 0760 0000 0000: traces
266 0760 0000 0000 - 07d0 0000 0000: metainfo (memory blocks and sync objects)
267 07d0 0000 0000 - 8000 0000 0000: -
270 const uptr kMetaShadowBeg
= 0x076000000000ull
;
271 const uptr kMetaShadowEnd
= 0x07d000000000ull
;
272 const uptr kTraceMemBeg
= 0x056000000000ull
;
273 const uptr kTraceMemEnd
= 0x076000000000ull
;
274 const uptr kShadowBeg
= 0x010000000000ull
;
275 const uptr kShadowEnd
= 0x050000000000ull
;
276 const uptr kAppMemBeg
= 0x000000001000ull
;
277 const uptr kAppMemEnd
= 0x00e000000000ull
;
280 bool IsAppMem(uptr mem
) {
281 return mem
>= kAppMemBeg
&& mem
< kAppMemEnd
;
285 bool IsShadowMem(uptr mem
) {
286 return mem
>= kShadowBeg
&& mem
<= kShadowEnd
;
290 bool IsMetaMem(uptr mem
) {
291 return mem
>= kMetaShadowBeg
&& mem
<= kMetaShadowEnd
;
295 uptr
MemToShadow(uptr x
) {
297 return ((x
& ~(kShadowCell
- 1)) * kShadowCnt
) + kShadowBeg
;
301 u32
*MemToMeta(uptr x
) {
303 return (u32
*)(((x
& ~(kMetaShadowCell
- 1)) / \
304 kMetaShadowCell
* kMetaShadowSize
) | kMetaShadowBeg
);
308 uptr
ShadowToMem(uptr s
) {
309 CHECK(IsShadowMem(s
));
310 // FIXME(dvyukov): this is most likely wrong as the mapping is not bijection.
311 return (s
- kShadowBeg
) / kShadowCnt
;
314 static USED uptr UserRegions
[] = {
315 kAppMemBeg
, kAppMemEnd
,
319 # error "Unknown platform"
322 // The additional page is to catch shadow stack overflow as paging fault.
323 // Windows wants 64K alignment for mmaps.
324 const uptr kTotalTraceSize
= (kTraceSize
* sizeof(Event
) + sizeof(Trace
)
325 + (64 << 10) + (64 << 10) - 1) & ~((64 << 10) - 1);
327 uptr ALWAYS_INLINE
GetThreadTrace(int tid
) {
328 uptr p
= kTraceMemBeg
+ (uptr
)tid
* kTotalTraceSize
;
329 DCHECK_LT(p
, kTraceMemEnd
);
333 uptr ALWAYS_INLINE
GetThreadTraceHeader(int tid
) {
334 uptr p
= kTraceMemBeg
+ (uptr
)tid
* kTotalTraceSize
335 + kTraceSize
* sizeof(Event
);
336 DCHECK_LT(p
, kTraceMemEnd
);
340 void InitializePlatform();
341 void CheckAndProtect();
342 void InitializeShadowMemoryPlatform();
343 void FlushShadowMemory();
344 void WriteMemoryProfile(char *buf
, uptr buf_size
, uptr nthread
, uptr nlive
);
346 // Says whether the addr relates to a global var.
347 // Guesses with high probability, may yield both false positives and negatives.
348 bool IsGlobalVar(uptr addr
);
349 int ExtractResolvFDs(void *state
, int *fds
, int nfd
);
350 int ExtractRecvmsgFDs(void *msg
, int *fds
, int nfd
);
352 int call_pthread_cancel_with_cleanup(int(*fn
)(void *c
, void *m
,
353 void *abstime
), void *c
, void *m
, void *abstime
,
354 void(*cleanup
)(void *arg
), void *arg
);
356 void DestroyThreadState();
358 } // namespace __tsan
360 #endif // TSAN_PLATFORM_H