diff options
Diffstat (limited to 'lib/tsan/rtl/tsan_platform.h')
-rw-r--r-- | lib/tsan/rtl/tsan_platform.h | 80 |
1 files changed, 70 insertions, 10 deletions
diff --git a/lib/tsan/rtl/tsan_platform.h b/lib/tsan/rtl/tsan_platform.h index b557fa1caec5..c859c3e85b19 100644 --- a/lib/tsan/rtl/tsan_platform.h +++ b/lib/tsan/rtl/tsan_platform.h @@ -12,31 +12,85 @@ // Platform-specific code. //===----------------------------------------------------------------------===// +/* +C++ linux memory layout: +0000 0000 0000 - 03c0 0000 0000: protected +03c0 0000 0000 - 1000 0000 0000: shadow +1000 0000 0000 - 6000 0000 0000: protected +6000 0000 0000 - 6200 0000 0000: traces +6200 0000 0000 - 7d00 0000 0000: - +7d00 0000 0000 - 7e00 0000 0000: heap +7e00 0000 0000 - 7fff ffff ffff: modules and main thread stack + +C++ COMPAT linux memory layout: +0000 0000 0000 - 0400 0000 0000: protected +0400 0000 0000 - 1000 0000 0000: shadow +1000 0000 0000 - 2900 0000 0000: protected +2900 0000 0000 - 2c00 0000 0000: modules +2c00 0000 0000 - 6000 0000 0000: - +6000 0000 0000 - 6200 0000 0000: traces +6200 0000 0000 - 7d00 0000 0000: - +7d00 0000 0000 - 7e00 0000 0000: heap +7e00 0000 0000 - 7f00 0000 0000: - +7f00 0000 0000 - 7fff ffff ffff: main thread stack + +Go linux and darwin memory layout: +0000 0000 0000 - 0000 1000 0000: executable +0000 1000 0000 - 00f8 0000 0000: - +00f8 0000 0000 - 0118 0000 0000: heap +0118 0000 0000 - 1000 0000 0000: - +1000 0000 0000 - 1460 0000 0000: shadow +1460 0000 0000 - 6000 0000 0000: - +6000 0000 0000 - 6200 0000 0000: traces +6200 0000 0000 - 7fff ffff ffff: - + +Go windows memory layout: +0000 0000 0000 - 0000 1000 0000: executable +0000 1000 0000 - 00f8 0000 0000: - +00f8 0000 0000 - 0118 0000 0000: heap +0118 0000 0000 - 0100 0000 0000: - +0100 0000 0000 - 0560 0000 0000: shadow +0560 0000 0000 - 0760 0000 0000: traces +0760 0000 0000 - 07ff ffff ffff: - +*/ + #ifndef TSAN_PLATFORM_H #define TSAN_PLATFORM_H -#include "tsan_rtl.h" +#include "tsan_defs.h" +#include "tsan_trace.h" -#if __LP64__ +#if defined(__LP64__) || defined(_WIN64) namespace __tsan { #if defined(TSAN_GO) static const uptr kLinuxAppMemBeg = 0x000000000000ULL; static const uptr kLinuxAppMemEnd = 0x00fcffffffffULL; +# if defined(_WIN32) +static const uptr kLinuxShadowMsk = 0x010000000000ULL; +# else static const uptr kLinuxShadowMsk = 0x100000000000ULL; +# endif // TSAN_COMPAT_SHADOW is intended for COMPAT virtual memory layout, // when memory addresses are of the 0x2axxxxxxxxxx form. // The option is enabled with 'setarch x86_64 -L'. #elif defined(TSAN_COMPAT_SHADOW) && TSAN_COMPAT_SHADOW -static const uptr kLinuxAppMemBeg = 0x2a0000000000ULL; +static const uptr kLinuxAppMemBeg = 0x290000000000ULL; static const uptr kLinuxAppMemEnd = 0x7fffffffffffULL; #else -static const uptr kLinuxAppMemBeg = 0x7ef000000000ULL; +static const uptr kLinuxAppMemBeg = 0x7cf000000000ULL; static const uptr kLinuxAppMemEnd = 0x7fffffffffffULL; #endif static const uptr kLinuxAppMemMsk = 0x7c0000000000ULL; +#if defined(_WIN32) +const uptr kTraceMemBegin = 0x056000000000ULL; +#else +const uptr kTraceMemBegin = 0x600000000000ULL; +#endif +const uptr kTraceMemSize = 0x020000000000ULL; + // This has to be a macro to allow constant initialization of constants below. #ifndef TSAN_GO #define MemToShadow(addr) \ @@ -48,7 +102,7 @@ static const uptr kLinuxAppMemMsk = 0x7c0000000000ULL; static const uptr kLinuxShadowBeg = MemToShadow(kLinuxAppMemBeg); static const uptr kLinuxShadowEnd = - MemToShadow(kLinuxAppMemEnd) | (kPageSize - 1); + MemToShadow(kLinuxAppMemEnd) | 0xff; static inline bool IsAppMem(uptr mem) { return mem >= kLinuxAppMemBeg && mem <= kLinuxAppMemEnd; @@ -62,9 +116,6 @@ static inline uptr ShadowToMem(uptr shadow) { CHECK(IsShadowMem(shadow)); #ifdef TSAN_GO return (shadow & ~kLinuxShadowMsk) / kShadowCnt; -#elif defined(TSAN_COMPAT_SHADOW) && TSAN_COMPAT_SHADOW - // COMPAT mapping is not quite one-to-one. - return (shadow / kShadowCnt) | 0x280000000000ULL; #else return (shadow / kShadowCnt) | kLinuxAppMemMsk; #endif @@ -72,9 +123,10 @@ static inline uptr ShadowToMem(uptr shadow) { // For COMPAT mapping returns an alternative address // that mapped to the same shadow address. +// COMPAT mapping is not quite one-to-one. static inline uptr AlternativeAddress(uptr addr) { #if defined(TSAN_COMPAT_SHADOW) && TSAN_COMPAT_SHADOW - return addr | kLinuxAppMemMsk; + return (addr & ~kLinuxAppMemMsk) | 0x280000000000ULL; #else return 0; #endif @@ -85,16 +137,24 @@ void FlushShadowMemory(); const char *InitializePlatform(); void FinalizePlatform(); +uptr ALWAYS_INLINE INLINE GetThreadTrace(int tid) { + uptr p = kTraceMemBegin + (uptr)tid * kTraceSize * sizeof(Event); + DCHECK_LT(p, kTraceMemBegin + kTraceMemSize); + return p; +} void internal_start_thread(void(*func)(void*), void *arg); +// Says whether the addr relates to a global var. +// Guesses with high probability, may yield both false positives and negatives. +bool IsGlobalVar(uptr addr); uptr GetTlsSize(); void GetThreadStackAndTls(bool main, uptr *stk_addr, uptr *stk_size, uptr *tls_addr, uptr *tls_size); } // namespace __tsan -#else // __LP64__ +#else // defined(__LP64__) || defined(_WIN64) # error "Only 64-bit is supported" #endif |