Index: lib/tsan/CMakeLists.txt =================================================================== --- lib/tsan/CMakeLists.txt +++ lib/tsan/CMakeLists.txt @@ -152,6 +152,15 @@ add_asm_sources(TSAN_ASM_SOURCES rtl/tsan_rtl_aarch64.S) elseif(arch MATCHES "powerpc64|powerpc64le") add_asm_sources(TSAN_ASM_SOURCES rtl/tsan_rtl_ppc64.S) + # Sanity check for Go runtime. + set(BUILDGO_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/go/buildgo.sh) + add_custom_target(GotsanRuntimeCheck + COMMAND env "CC=${CMAKE_C_COMPILER} ${CMAKE_C_COMPILER_ARG1}" + IN_TMPDIR=1 SILENT=1 ${BUILDGO_SCRIPT} + DEPENDS clang_rt.tsan-${arch} ${BUILDGO_SCRIPT} + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/go + COMMENT "Checking TSan Go runtime..." + VERBATIM) elseif(arch MATCHES "mips64|mips64le") add_asm_sources(TSAN_ASM_SOURCES rtl/tsan_rtl_mips64.S) else() Index: lib/tsan/go/buildgo.sh =================================================================== --- lib/tsan/go/buildgo.sh +++ lib/tsan/go/buildgo.sh @@ -39,8 +39,7 @@ " if [ "`uname -a | grep Linux`" != "" ]; then - SUFFIX="linux_amd64" - OSCFLAGS="-fPIC -ffreestanding -Wno-maybe-uninitialized -Wno-unused-const-variable -Werror -Wno-unknown-warning-option" + OSCFLAGS="-fPIC -Wno-maybe-uninitialized" OSLDFLAGS="-lpthread -fPIC -fpie" SRCS=" $SRCS @@ -52,7 +51,13 @@ ../../sanitizer_common/sanitizer_linux.cc ../../sanitizer_common/sanitizer_linux_libcdep.cc ../../sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc - " + " + if [ "`uname -a | grep ppc64le`" != "" ]; then + SUFFIX="linux_ppc64le" + elif [ "`uname -a | grep x86_64`" != "" ]; then + SUFFIX="linux_amd64" + OSCFLAGS="$OSCFLAGS -ffreestanding -Wno-unused-const-variable -Werror -Wno-unknown-warning-option" + fi elif [ "`uname -a | grep FreeBSD`" != "" ]; then SUFFIX="freebsd_amd64" OSCFLAGS="-fno-strict-aliasing -fPIC -Werror" @@ -132,7 +137,12 @@ FLAGS=" -I../rtl -I../.. -I../../sanitizer_common -I../../../include -std=c++11 -m64 -Wall -fno-exceptions -fno-rtti -DSANITIZER_GO=1 -DSANITIZER_DEADLOCK_DETECTOR_VERSION=2 $OSCFLAGS" if [ "$DEBUG" = "" ]; then - FLAGS="$FLAGS -DSANITIZER_DEBUG=0 -O3 -msse3 -fomit-frame-pointer" + FLAGS="$FLAGS -DSANITIZER_DEBUG=0 -O3 -fomit-frame-pointer" + if [ "$SUFFIX" = "linux_ppc64le" ]; then + FLAGS="$FLAGS -mcpu=power8 -fno-function-sections" + elif [ "$SUFFIX" = "linux_amd64" ]; then + FLAGS="$FLAGS -msse3" + fi else FLAGS="$FLAGS -DSANITIZER_DEBUG=1 -g" fi Index: lib/tsan/rtl/tsan_platform.h =================================================================== --- lib/tsan/rtl/tsan_platform.h +++ lib/tsan/rtl/tsan_platform.h @@ -355,9 +355,9 @@ #define TSAN_RUNTIME_VMA 1 #endif -#elif SANITIZER_GO && !SANITIZER_WINDOWS +#elif SANITIZER_GO && !SANITIZER_WINDOWS && defined(__x86_64__) -/* Go on linux, darwin and freebsd +/* Go on linux, darwin and freebsd on x86_64 0000 0000 1000 - 0000 1000 0000: executable 0000 1000 0000 - 00c0 0000 0000: - 00c0 0000 0000 - 00e0 0000 0000: heap @@ -406,6 +406,61 @@ static const uptr kAppMemEnd = 0x00e000000000ull; }; +#elif SANITIZER_GO && defined(__powerpc64__) + +/* Only Mapping46 and Mapping47 are currently supported for powercp64 on Go. */ + +/* Go on linux/powerpc64 (46-bit VMA) +0000 0000 1000 - 0000 1000 0000: executable +0000 1000 0000 - 00c0 0000 0000: - +00c0 0000 0000 - 00e0 0000 0000: heap +00e0 0000 0000 - 2000 0000 0000: - +2000 0000 0000 - 2380 0000 0000: shadow +2380 0000 0000 - 2400 0000 0000: - +2400 0000 0000 - 3400 0000 0000: metainfo (memory blocks and sync objects) +3400 0000 0000 - 3600 0000 0000: - +3600 0000 0000 - 3800 0000 0000: traces +3800 0000 0000 - 4000 0000 0000: - +*/ + +struct Mapping46 { + static const uptr kMetaShadowBeg = 0x240000000000ull; + static const uptr kMetaShadowEnd = 0x340000000000ull; + static const uptr kTraceMemBeg = 0x360000000000ull; + static const uptr kTraceMemEnd = 0x380000000000ull; + static const uptr kShadowBeg = 0x200000000000ull; + static const uptr kShadowEnd = 0x238000000000ull; + static const uptr kAppMemBeg = 0x000000001000ull; + static const uptr kAppMemEnd = 0x00e000000000ull; +}; + +/* Go on linux/powerpc64 (47-bit VMA) +0000 0000 1000 - 0000 1000 0000: executable +0000 1000 0000 - 00c0 0000 0000: - +00c0 0000 0000 - 00e0 0000 0000: heap +00e0 0000 0000 - 2000 0000 0000: - +2000 0000 0000 - 3000 0000 0000: shadow +3000 0000 0000 - 3000 0000 0000: - +3000 0000 0000 - 4000 0000 0000: metainfo (memory blocks and sync objects) +4000 0000 0000 - 6000 0000 0000: - +6000 0000 0000 - 6200 0000 0000: traces +6200 0000 0000 - 8000 0000 0000: - +*/ + +struct Mapping47 { + static const uptr kMetaShadowBeg = 0x300000000000ull; + static const uptr kMetaShadowEnd = 0x400000000000ull; + static const uptr kTraceMemBeg = 0x600000000000ull; + static const uptr kTraceMemEnd = 0x620000000000ull; + static const uptr kShadowBeg = 0x200000000000ull; + static const uptr kShadowEnd = 0x300000000000ull; + static const uptr kAppMemBeg = 0x000000001000ull; + static const uptr kAppMemEnd = 0x00e000000000ull; +}; + +// Indicates the runtime will define the memory regions at runtime. +#define TSAN_RUNTIME_VMA 1 + #else # error "Unknown platform" #endif @@ -478,7 +533,9 @@ return 0; #elif defined(__powerpc64__) switch (vmaSize) { +#if !SANITIZER_GO case 44: return MappingImpl(); +#endif case 46: return MappingImpl(); case 47: return MappingImpl(); } @@ -633,7 +690,9 @@ return false; #elif defined(__powerpc64__) switch (vmaSize) { +#if !SANITIZER_GO case 44: return IsAppMemImpl(mem); +#endif case 46: return IsAppMemImpl(mem); case 47: return IsAppMemImpl(mem); } @@ -662,7 +721,9 @@ return false; #elif defined(__powerpc64__) switch (vmaSize) { +#if !SANITIZER_GO case 44: return IsShadowMemImpl(mem); +#endif case 46: return IsShadowMemImpl(mem); case 47: return IsShadowMemImpl(mem); } @@ -691,7 +752,9 @@ return false; #elif defined(__powerpc64__) switch (vmaSize) { +#if !SANITIZER_GO case 44: return IsMetaMemImpl(mem); +#endif case 46: return IsMetaMemImpl(mem); case 47: return IsMetaMemImpl(mem); } @@ -730,7 +793,9 @@ return 0; #elif defined(__powerpc64__) switch (vmaSize) { +#if !SANITIZER_GO case 44: return MemToShadowImpl(x); +#endif case 46: return MemToShadowImpl(x); case 47: return MemToShadowImpl(x); } @@ -771,7 +836,9 @@ return 0; #elif defined(__powerpc64__) switch (vmaSize) { +#if !SANITIZER_GO case 44: return MemToMetaImpl(x); +#endif case 46: return MemToMetaImpl(x); case 47: return MemToMetaImpl(x); } @@ -825,7 +892,9 @@ return 0; #elif defined(__powerpc64__) switch (vmaSize) { +#if !SANITIZER_GO case 44: return ShadowToMemImpl(s); +#endif case 46: return ShadowToMemImpl(s); case 47: return ShadowToMemImpl(s); } @@ -862,7 +931,9 @@ return 0; #elif defined(__powerpc64__) switch (vmaSize) { +#if !SANITIZER_GO case 44: return GetThreadTraceImpl(tid); +#endif case 46: return GetThreadTraceImpl(tid); case 47: return GetThreadTraceImpl(tid); } @@ -894,7 +965,9 @@ return 0; #elif defined(__powerpc64__) switch (vmaSize) { +#if !SANITIZER_GO case 44: return GetThreadTraceHeaderImpl(tid); +#endif case 46: return GetThreadTraceHeaderImpl(tid); case 47: return GetThreadTraceHeaderImpl(tid); } Index: lib/tsan/rtl/tsan_platform_linux.cc =================================================================== --- lib/tsan/rtl/tsan_platform_linux.cc +++ lib/tsan/rtl/tsan_platform_linux.cc @@ -217,11 +217,19 @@ Die(); } #elif defined(__powerpc64__) +# if !SANITIZER_GO if (vmaSize != 44 && vmaSize != 46 && vmaSize != 47) { Printf("FATAL: ThreadSanitizer: unsupported VMA range\n"); Printf("FATAL: Found %d - Supported 44, 46, and 47\n", vmaSize); Die(); } +# else + if (vmaSize != 46 && vmaSize != 47) { + Printf("FATAL: ThreadSanitizer: unsupported VMA range\n"); + Printf("FATAL: Found %d - Supported 46, and 47\n", vmaSize); + Die(); + } +# endif #endif #endif }