* Add missing ChangeLog entry.
[official-gcc.git] / libsanitizer / tsan / tsan_platform.h
blobb7a6376e8ed05d4e443a2359fdba6e002b75e14c
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 //===----------------------------------------------------------------------===//
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 - 3000 0000 0000: protected
18 3000 0000 0000 - 4000 0000 0000: metainfo (memory blocks and sync objects)
19 4000 0000 0000 - 6000 0000 0000: protected
20 6000 0000 0000 - 6200 0000 0000: traces
21 6200 0000 0000 - 7d00 0000 0000: -
22 7d00 0000 0000 - 7e00 0000 0000: heap
23 7e00 0000 0000 - 7fff ffff ffff: modules and main thread stack
25 Go linux and darwin memory layout:
26 0000 0000 0000 - 0000 1000 0000: executable
27 0000 1000 0000 - 00f8 0000 0000: -
28 00c0 0000 0000 - 00e0 0000 0000: heap
29 00e0 0000 0000 - 1000 0000 0000: -
30 1000 0000 0000 - 1380 0000 0000: shadow
31 1460 0000 0000 - 2000 0000 0000: -
32 3000 0000 0000 - 4000 0000 0000: metainfo (memory blocks and sync objects)
33 4000 0000 0000 - 6000 0000 0000: -
34 6000 0000 0000 - 6200 0000 0000: traces
35 6200 0000 0000 - 7fff ffff ffff: -
37 Go windows memory layout:
38 0000 0000 0000 - 0000 1000 0000: executable
39 0000 1000 0000 - 00f8 0000 0000: -
40 00c0 0000 0000 - 00e0 0000 0000: heap
41 00e0 0000 0000 - 0100 0000 0000: -
42 0100 0000 0000 - 0560 0000 0000: shadow
43 0560 0000 0000 - 0760 0000 0000: traces
44 0760 0000 0000 - 07d0 0000 0000: metainfo (memory blocks and sync objects)
45 07d0 0000 0000 - 07ff ffff ffff: -
48 #ifndef TSAN_PLATFORM_H
49 #define TSAN_PLATFORM_H
51 #include "tsan_defs.h"
52 #include "tsan_trace.h"
54 #if defined(__LP64__) || defined(_WIN64)
55 namespace __tsan {
57 #if defined(TSAN_GO)
58 static const uptr kLinuxAppMemBeg = 0x000000000000ULL;
59 static const uptr kLinuxAppMemEnd = 0x04dfffffffffULL;
60 # if SANITIZER_WINDOWS
61 static const uptr kLinuxShadowMsk = 0x010000000000ULL;
62 static const uptr kMetaShadow = 0x076000000000ULL;
63 static const uptr kMetaSize = 0x007000000000ULL;
64 # else // if SANITIZER_WINDOWS
65 static const uptr kLinuxShadowMsk = 0x200000000000ULL;
66 static const uptr kMetaShadow = 0x300000000000ULL;
67 static const uptr kMetaSize = 0x100000000000ULL;
68 # endif // if SANITIZER_WINDOWS
69 #else // defined(TSAN_GO)
70 static const uptr kMetaShadow = 0x300000000000ULL;
71 static const uptr kMetaSize = 0x100000000000ULL;
72 static const uptr kLinuxAppMemBeg = 0x7cf000000000ULL;
73 static const uptr kLinuxAppMemEnd = 0x7fffffffffffULL;
74 #endif
76 static const uptr kLinuxAppMemMsk = 0x7c0000000000ULL;
78 #if SANITIZER_WINDOWS
79 const uptr kTraceMemBegin = 0x056000000000ULL;
80 #else
81 const uptr kTraceMemBegin = 0x600000000000ULL;
82 #endif
83 const uptr kTraceMemSize = 0x020000000000ULL;
85 // This has to be a macro to allow constant initialization of constants below.
86 #ifndef TSAN_GO
87 #define MemToShadow(addr) \
88 ((((uptr)addr) & ~(kLinuxAppMemMsk | (kShadowCell - 1))) * kShadowCnt)
89 #define MemToMeta(addr) \
90 (u32*)(((((uptr)addr) & ~(kLinuxAppMemMsk | (kMetaShadowCell - 1))) \
91 / kMetaShadowCell * kMetaShadowSize) | kMetaShadow)
92 #else
93 #define MemToShadow(addr) \
94 (((((uptr)addr) & ~(kShadowCell - 1)) * kShadowCnt) | kLinuxShadowMsk)
95 #define MemToMeta(addr) \
96 (u32*)(((((uptr)addr) & ~(kMetaShadowCell - 1)) \
97 / kMetaShadowCell * kMetaShadowSize) | kMetaShadow)
98 #endif
100 static const uptr kLinuxShadowBeg = MemToShadow(kLinuxAppMemBeg);
101 static const uptr kLinuxShadowEnd =
102 MemToShadow(kLinuxAppMemEnd) | 0xff;
104 static inline bool IsAppMem(uptr mem) {
105 #if defined(TSAN_GO)
106 return mem <= kLinuxAppMemEnd;
107 #else
108 return mem >= kLinuxAppMemBeg && mem <= kLinuxAppMemEnd;
109 #endif
112 static inline bool IsShadowMem(uptr mem) {
113 return mem >= kLinuxShadowBeg && mem <= kLinuxShadowEnd;
116 static inline uptr ShadowToMem(uptr shadow) {
117 CHECK(IsShadowMem(shadow));
118 #ifdef TSAN_GO
119 return (shadow & ~kLinuxShadowMsk) / kShadowCnt;
120 #else
121 return (shadow / kShadowCnt) | kLinuxAppMemMsk;
122 #endif
125 void FlushShadowMemory();
126 void WriteMemoryProfile(char *buf, uptr buf_size, uptr nthread, uptr nlive);
127 uptr GetRSS();
129 void InitializePlatform();
130 void FinalizePlatform();
132 // The additional page is to catch shadow stack overflow as paging fault.
133 // Windows wants 64K alignment for mmaps.
134 const uptr kTotalTraceSize = (kTraceSize * sizeof(Event) + sizeof(Trace)
135 + (64 << 10) + (64 << 10) - 1) & ~((64 << 10) - 1);
137 uptr ALWAYS_INLINE GetThreadTrace(int tid) {
138 uptr p = kTraceMemBegin + (uptr)tid * kTotalTraceSize;
139 DCHECK_LT(p, kTraceMemBegin + kTraceMemSize);
140 return p;
143 uptr ALWAYS_INLINE GetThreadTraceHeader(int tid) {
144 uptr p = kTraceMemBegin + (uptr)tid * kTotalTraceSize
145 + kTraceSize * sizeof(Event);
146 DCHECK_LT(p, kTraceMemBegin + kTraceMemSize);
147 return p;
150 void *internal_start_thread(void(*func)(void*), void *arg);
151 void internal_join_thread(void *th);
153 // Says whether the addr relates to a global var.
154 // Guesses with high probability, may yield both false positives and negatives.
155 bool IsGlobalVar(uptr addr);
156 int ExtractResolvFDs(void *state, int *fds, int nfd);
157 int ExtractRecvmsgFDs(void *msg, int *fds, int nfd);
159 int call_pthread_cancel_with_cleanup(int(*fn)(void *c, void *m,
160 void *abstime), void *c, void *m, void *abstime,
161 void(*cleanup)(void *arg), void *arg);
163 } // namespace __tsan
165 #else // defined(__LP64__) || defined(_WIN64)
166 # error "Only 64-bit is supported"
167 #endif
169 #endif // TSAN_PLATFORM_H