blob: 7c33bc7f80dea01e6cbf2db8e7d67c1566c0dd38 [file] [log] [blame]
Kostya Serebryany4ad375f2012-05-10 13:48:04 +00001//===-- 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_LINUX_H
16#define TSAN_LINUX_H
17#ifdef __linux__
18
19#include "tsan_rtl.h"
20
21#if __LP64__
22namespace __tsan {
23
24// TSAN_COMPAT_SHADOW is intended for COMPAT virtual memory layout,
25// when memory addresses are of the 0x2axxxxxxxxxx form.
26// The option is enabled with 'setarch x86_64 -L'.
27#if defined(TSAN_COMPAT_SHADOW) && TSAN_COMPAT_SHADOW
28
29static const uptr kLinuxAppMemBeg = 0x2a0000000000ULL;
30static const uptr kLinuxAppMemEnd = 0x7fffffffffffULL;
31
32#else
33
34static const uptr kLinuxAppMemBeg = 0x7ef000000000ULL;
35static const uptr kLinuxAppMemEnd = 0x7fffffffffffULL;
36
37#endif
38
39static const uptr kLinuxAppMemMsk = 0x7c0000000000ULL;
40
41// This has to be a macro to allow constant initialization of constants below.
42#define MemToShadow(addr) \
43 (((addr) & ~(kLinuxAppMemMsk | (kShadowCell - 1))) * kShadowCnt)
44
45static const uptr kLinuxShadowBeg = MemToShadow(kLinuxAppMemBeg);
46static const uptr kLinuxShadowEnd =
47 MemToShadow(kLinuxAppMemEnd) | (kPageSize - 1);
48
49static inline bool IsAppMem(uptr mem) {
50 return mem >= kLinuxAppMemBeg && mem <= kLinuxAppMemEnd;
51}
52
53static inline bool IsShadowMem(uptr mem) {
54 return mem >= kLinuxShadowBeg && mem <= kLinuxShadowEnd;
55}
56
57static inline uptr ShadowToMem(uptr shadow) {
58 CHECK(IsShadowMem(shadow));
59#if defined(TSAN_COMPAT_SHADOW) && TSAN_COMPAT_SHADOW
60 // COMPAT mapping is not quite one-to-one.
61 return (shadow / kShadowCnt) | 0x280000000000ULL;
62#else
63 return (shadow / kShadowCnt) | kLinuxAppMemMsk;
64#endif
65}
66
Dmitry Vyukovea03fc22012-06-14 21:40:35 +000067// For COMPAT mapping returns an alternative address
68// that mapped to the same shadow address.
69static inline uptr AlternativeAddress(uptr addr) {
70#if defined(TSAN_COMPAT_SHADOW) && TSAN_COMPAT_SHADOW
71 return addr | kLinuxAppMemMsk;
72#else
73 return 0;
74#endif
75}
76
Dmitry Vyukov15710c92012-05-22 11:33:03 +000077uptr GetShadowMemoryConsumption();
Dmitry Vyukov302cebb2012-05-22 18:07:45 +000078void FlushShadowMemory();
Dmitry Vyukov15710c92012-05-22 11:33:03 +000079
Kostya Serebryany4ad375f2012-05-10 13:48:04 +000080const char *InitializePlatform();
81void FinalizePlatform();
Kostya Serebryany4ad375f2012-05-10 13:48:04 +000082
Dmitry Vyukov15710c92012-05-22 11:33:03 +000083void internal_yield();
84void internal_sleep_ms(u32 ms);
85
86void internal_start_thread(void(*func)(void*), void *arg);
Kostya Serebryany4ad375f2012-05-10 13:48:04 +000087
Kostya Serebryany4ad375f2012-05-10 13:48:04 +000088const char *internal_getpwd();
89
90uptr GetTlsSize();
Dmitry Vyukov7339eb12012-05-25 11:15:04 +000091void GetThreadStackAndTls(bool main, uptr *stk_addr, uptr *stk_size,
Kostya Serebryany4ad375f2012-05-10 13:48:04 +000092 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 // __linux__
101#endif // TSAN_LINUX_H