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