blob: b80b268de435f3db675eabddf48e7bcbaaf5a4a0 [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
Dmitry Vyukovc40c0072012-07-16 13:02:40 +000015#ifndef TSAN_PLATFORM_H
16#define TSAN_PLATFORM_H
Kostya Serebryany4ad375f2012-05-10 13:48:04 +000017
18#include "tsan_rtl.h"
19
20#if __LP64__
21namespace __tsan {
22
Dmitry Vyukov03d32ec2012-07-05 16:18:28 +000023#if defined(TSAN_GO)
24static const uptr kLinuxAppMemBeg = 0x000000000000ULL;
25static const uptr kLinuxAppMemEnd = 0x00fcffffffffULL;
26static const uptr kLinuxShadowMsk = 0x100000000000ULL;
Kostya Serebryany4ad375f2012-05-10 13:48:04 +000027// 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'.
Dmitry Vyukov03d32ec2012-07-05 16:18:28 +000030#elif defined(TSAN_COMPAT_SHADOW) && TSAN_COMPAT_SHADOW
Dmitry Vyukovf77c6ea2012-08-16 13:27:25 +000031static const uptr kLinuxAppMemBeg = 0x290000000000ULL;
Kostya Serebryany4ad375f2012-05-10 13:48:04 +000032static const uptr kLinuxAppMemEnd = 0x7fffffffffffULL;
Kostya Serebryany4ad375f2012-05-10 13:48:04 +000033#else
Dmitry Vyukov954fc8c2012-08-15 15:35:15 +000034static const uptr kLinuxAppMemBeg = 0x7cf000000000ULL;
Kostya Serebryany4ad375f2012-05-10 13:48:04 +000035static const uptr kLinuxAppMemEnd = 0x7fffffffffffULL;
Kostya Serebryany4ad375f2012-05-10 13:48:04 +000036#endif
37
38static const uptr kLinuxAppMemMsk = 0x7c0000000000ULL;
39
40// This has to be a macro to allow constant initialization of constants below.
Dmitry Vyukov03d32ec2012-07-05 16:18:28 +000041#ifndef TSAN_GO
Kostya Serebryany4ad375f2012-05-10 13:48:04 +000042#define MemToShadow(addr) \
43 (((addr) & ~(kLinuxAppMemMsk | (kShadowCell - 1))) * kShadowCnt)
Dmitry Vyukov03d32ec2012-07-05 16:18:28 +000044#else
Dmitry Vyukov239ae712012-07-06 20:23:59 +000045#define MemToShadow(addr) \
46 ((((addr) & ~(kShadowCell - 1)) * kShadowCnt) | kLinuxShadowMsk)
Dmitry Vyukov03d32ec2012-07-05 16:18:28 +000047#endif
Kostya Serebryany4ad375f2012-05-10 13:48:04 +000048
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));
Dmitry Vyukov03d32ec2012-07-05 16:18:28 +000063#ifdef TSAN_GO
64 return (shadow & ~kLinuxShadowMsk) / kShadowCnt;
Kostya Serebryany4ad375f2012-05-10 13:48:04 +000065#else
66 return (shadow / kShadowCnt) | kLinuxAppMemMsk;
67#endif
68}
69
Dmitry Vyukovea03fc22012-06-14 21:40:35 +000070// For COMPAT mapping returns an alternative address
71// that mapped to the same shadow address.
Dmitry Vyukovf77c6ea2012-08-16 13:27:25 +000072// COMPAT mapping is not quite one-to-one.
Dmitry Vyukovea03fc22012-06-14 21:40:35 +000073static inline uptr AlternativeAddress(uptr addr) {
74#if defined(TSAN_COMPAT_SHADOW) && TSAN_COMPAT_SHADOW
Dmitry Vyukov5c45dab2012-08-16 14:20:45 +000075 return (addr & ~kLinuxAppMemMsk) | 0x280000000000ULL;
Dmitry Vyukovea03fc22012-06-14 21:40:35 +000076#else
77 return 0;
78#endif
79}
80
Dmitry Vyukov15710c92012-05-22 11:33:03 +000081uptr GetShadowMemoryConsumption();
Dmitry Vyukov302cebb2012-05-22 18:07:45 +000082void FlushShadowMemory();
Dmitry Vyukov15710c92012-05-22 11:33:03 +000083
Kostya Serebryany4ad375f2012-05-10 13:48:04 +000084const char *InitializePlatform();
85void FinalizePlatform();
Kostya Serebryany4ad375f2012-05-10 13:48:04 +000086
Dmitry Vyukov15710c92012-05-22 11:33:03 +000087void internal_start_thread(void(*func)(void*), void *arg);
Kostya Serebryany4ad375f2012-05-10 13:48:04 +000088
Dmitry Vyukov7ea4c2cc2012-09-07 18:08:02 +000089// Says whether the addr relates to a global var.
90// Guesses with high probability, may yield both false positives and negatives.
91bool IsGlobalVar(uptr addr);
Kostya Serebryany4ad375f2012-05-10 13:48:04 +000092uptr GetTlsSize();
Dmitry Vyukov7339eb12012-05-25 11:15:04 +000093void GetThreadStackAndTls(bool main, uptr *stk_addr, uptr *stk_size,
Kostya Serebryany4ad375f2012-05-10 13:48:04 +000094 uptr *tls_addr, uptr *tls_size);
95
96} // namespace __tsan
97
98#else // __LP64__
99# error "Only 64-bit is supported"
100#endif
101
Dmitry Vyukovc40c0072012-07-16 13:02:40 +0000102#endif // TSAN_PLATFORM_H