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__ 21 namespace __tsan { 22 23 #if defined(TSAN_GO) 24 static const uptr kLinuxAppMemBeg = 0x000000000000ULL; 25 static const uptr kLinuxAppMemEnd = 0x00fcffffffffULL; 26 static 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 31 static const uptr kLinuxAppMemBeg = 0x290000000000ULL; 32 static const uptr kLinuxAppMemEnd = 0x7fffffffffffULL; 33 #else 34 static const uptr kLinuxAppMemBeg = 0x7cf000000000ULL; 35 static const uptr kLinuxAppMemEnd = 0x7fffffffffffULL; 36 #endif 37 38 static 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 49 static const uptr kLinuxShadowBeg = MemToShadow(kLinuxAppMemBeg); 50 static const uptr kLinuxShadowEnd = 51 MemToShadow(kLinuxAppMemEnd) | (kPageSize - 1); 52 53 static inline bool IsAppMem(uptr mem) { 54 return mem >= kLinuxAppMemBeg && mem <= kLinuxAppMemEnd; 55 } 56 57 static inline bool IsShadowMem(uptr mem) { 58 return mem >= kLinuxShadowBeg && mem <= kLinuxShadowEnd; 59 } 60 61 static 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. 73 static 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 81 uptr GetShadowMemoryConsumption(); 82 void FlushShadowMemory(); 83 84 const char *InitializePlatform(); 85 void FinalizePlatform(); 86 87 void internal_start_thread(void(*func)(void*), void *arg); 88 89 // Says whether the addr relates to a global var. 90 // Guesses with high probability, may yield both false positives and negatives. 91 bool IsGlobalVar(uptr addr); 92 uptr GetTlsSize(); 93 void GetThreadStackAndTls(bool main, uptr *stk_addr, uptr *stk_size, 94 uptr *tls_addr, uptr *tls_size); 95 96 } // namespace __tsan 97 98 #else // __LP64__ 99 # error "Only 64-bit is supported" 100 #endif 101 102 #endif // TSAN_PLATFORM_H 103