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