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); 137 138const char *InitializePlatform(); 139void FinalizePlatform(); 140uptr ALWAYS_INLINE GetThreadTrace(int tid) { 141 uptr p = kTraceMemBegin + (uptr)(tid * 2) * kTraceSize * sizeof(Event); 142 DCHECK_LT(p, kTraceMemBegin + kTraceMemSize); 143 return p; 144} 145 146uptr ALWAYS_INLINE GetThreadTraceHeader(int tid) { 147 uptr p = kTraceMemBegin + (uptr)(tid * 2 + 1) * kTraceSize * sizeof(Event); 148 DCHECK_LT(p, kTraceMemBegin + kTraceMemSize); 149 return p; 150} 151 152void internal_start_thread(void(*func)(void*), void *arg); 153 154// Says whether the addr relates to a global var. 155// Guesses with high probability, may yield both false positives and negatives. 156bool IsGlobalVar(uptr addr); 157int ExtractResolvFDs(void *state, int *fds, int nfd); 158 159} // namespace __tsan 160 161#else // defined(__LP64__) || defined(_WIN64) 162# error "Only 64-bit is supported" 163#endif 164 165#endif // TSAN_PLATFORM_H 166