tsan_platform.h revision 92b54796149a8b5995fa49c43f43b709b83c5644
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/*
16C++ linux memory layout:
170000 0000 0000 - 03c0 0000 0000: protected
1803c0 0000 0000 - 1000 0000 0000: shadow
191000 0000 0000 - 6000 0000 0000: protected
206000 0000 0000 - 6200 0000 0000: traces
216200 0000 0000 - 7d00 0000 0000: -
227d00 0000 0000 - 7e00 0000 0000: heap
237e00 0000 0000 - 7fff ffff ffff: modules and main thread stack
24
25C++ COMPAT linux memory layout:
260000 0000 0000 - 0400 0000 0000: protected
270400 0000 0000 - 1000 0000 0000: shadow
281000 0000 0000 - 2900 0000 0000: protected
292900 0000 0000 - 2c00 0000 0000: modules
302c00 0000 0000 - 6000 0000 0000: -
316000 0000 0000 - 6200 0000 0000: traces
326200 0000 0000 - 7d00 0000 0000: -
337d00 0000 0000 - 7e00 0000 0000: heap
347e00 0000 0000 - 7f00 0000 0000: -
357f00 0000 0000 - 7fff ffff ffff: main thread stack
36
37Go linux and darwin memory layout:
380000 0000 0000 - 0000 1000 0000: executable
390000 1000 0000 - 00f8 0000 0000: -
4000c0 0000 0000 - 00e0 0000 0000: heap
4100e0 0000 0000 - 1000 0000 0000: -
421000 0000 0000 - 1380 0000 0000: shadow
431460 0000 0000 - 6000 0000 0000: -
446000 0000 0000 - 6200 0000 0000: traces
456200 0000 0000 - 7fff ffff ffff: -
46
47Go windows memory layout:
480000 0000 0000 - 0000 1000 0000: executable
490000 1000 0000 - 00f8 0000 0000: -
5000c0 0000 0000 - 00e0 0000 0000: heap
5100e0 0000 0000 - 0100 0000 0000: -
520100 0000 0000 - 0560 0000 0000: shadow
530560 0000 0000 - 0760 0000 0000: traces
540760 0000 0000 - 07ff ffff ffff: -
55*/
56
57#ifndef TSAN_PLATFORM_H
58#define TSAN_PLATFORM_H
59
60#include "tsan_defs.h"
61#include "tsan_trace.h"
62
63#if defined(__LP64__) || defined(_WIN64)
64namespace __tsan {
65
66#if defined(TSAN_GO)
67static const uptr kLinuxAppMemBeg = 0x000000000000ULL;
68static const uptr kLinuxAppMemEnd = 0x04dfffffffffULL;
69# if SANITIZER_WINDOWS
70static const uptr kLinuxShadowMsk = 0x010000000000ULL;
71# else
72static const uptr kLinuxShadowMsk = 0x200000000000ULL;
73# endif
74// TSAN_COMPAT_SHADOW is intended for COMPAT virtual memory layout,
75// when memory addresses are of the 0x2axxxxxxxxxx form.
76// The option is enabled with 'setarch x86_64 -L'.
77#elif defined(TSAN_COMPAT_SHADOW) && TSAN_COMPAT_SHADOW
78static const uptr kLinuxAppMemBeg = 0x290000000000ULL;
79static const uptr kLinuxAppMemEnd = 0x7fffffffffffULL;
80#else
81static const uptr kLinuxAppMemBeg = 0x7cf000000000ULL;
82static const uptr kLinuxAppMemEnd = 0x7fffffffffffULL;
83#endif
84
85static const uptr kLinuxAppMemMsk = 0x7c0000000000ULL;
86
87#if SANITIZER_WINDOWS
88const uptr kTraceMemBegin = 0x056000000000ULL;
89#else
90const uptr kTraceMemBegin = 0x600000000000ULL;
91#endif
92const uptr kTraceMemSize = 0x020000000000ULL;
93
94// This has to be a macro to allow constant initialization of constants below.
95#ifndef TSAN_GO
96#define MemToShadow(addr) \
97    (((addr) & ~(kLinuxAppMemMsk | (kShadowCell - 1))) * kShadowCnt)
98#else
99#define MemToShadow(addr) \
100    ((((addr) & ~(kShadowCell - 1)) * kShadowCnt) | kLinuxShadowMsk)
101#endif
102
103static const uptr kLinuxShadowBeg = MemToShadow(kLinuxAppMemBeg);
104static const uptr kLinuxShadowEnd =
105    MemToShadow(kLinuxAppMemEnd) | 0xff;
106
107static inline bool IsAppMem(uptr mem) {
108  return mem >= kLinuxAppMemBeg && mem <= kLinuxAppMemEnd;
109}
110
111static inline bool IsShadowMem(uptr mem) {
112  return mem >= kLinuxShadowBeg && mem <= kLinuxShadowEnd;
113}
114
115static inline uptr ShadowToMem(uptr shadow) {
116  CHECK(IsShadowMem(shadow));
117#ifdef TSAN_GO
118  return (shadow & ~kLinuxShadowMsk) / kShadowCnt;
119#else
120  return (shadow / kShadowCnt) | kLinuxAppMemMsk;
121#endif
122}
123
124// For COMPAT mapping returns an alternative address
125// that mapped to the same shadow address.
126// COMPAT mapping is not quite one-to-one.
127static inline uptr AlternativeAddress(uptr addr) {
128#if defined(TSAN_COMPAT_SHADOW) && TSAN_COMPAT_SHADOW
129  return (addr & ~kLinuxAppMemMsk) | 0x280000000000ULL;
130#else
131  return 0;
132#endif
133}
134
135void FlushShadowMemory();
136void WriteMemoryProfile(char *buf, uptr buf_size);
137uptr GetRSS();
138
139const char *InitializePlatform();
140void FinalizePlatform();
141uptr ALWAYS_INLINE GetThreadTrace(int tid) {
142  uptr p = kTraceMemBegin + (uptr)(tid * 2) * kTraceSize * sizeof(Event);
143  DCHECK_LT(p, kTraceMemBegin + kTraceMemSize);
144  return p;
145}
146
147uptr ALWAYS_INLINE GetThreadTraceHeader(int tid) {
148  uptr p = kTraceMemBegin + (uptr)(tid * 2 + 1) * kTraceSize * sizeof(Event);
149  DCHECK_LT(p, kTraceMemBegin + kTraceMemSize);
150  return p;
151}
152
153void internal_start_thread(void(*func)(void*), void *arg);
154
155// Says whether the addr relates to a global var.
156// Guesses with high probability, may yield both false positives and negatives.
157bool IsGlobalVar(uptr addr);
158int ExtractResolvFDs(void *state, int *fds, int nfd);
159
160}  // namespace __tsan
161
162#else  // defined(__LP64__) || defined(_WIN64)
163# error "Only 64-bit is supported"
164#endif
165
166#endif  // TSAN_PLATFORM_H
167