diff options
-rw-r--r-- | cmake/config-ix.cmake | 2 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_linux.cc | 85 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_linux.h | 3 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc | 6 | ||||
-rw-r--r-- | lib/tsan/rtl/tsan_interceptors.cc | 6 | ||||
-rw-r--r-- | lib/tsan/rtl/tsan_platform.h | 127 | ||||
-rw-r--r-- | lib/tsan/rtl/tsan_platform_linux.cc | 8 | ||||
-rw-r--r-- | lib/tsan/rtl/tsan_platform_posix.cc | 12 | ||||
-rw-r--r-- | lib/tsan/rtl/tsan_rtl.h | 2 | ||||
-rw-r--r-- | test/tsan/CMakeLists.txt | 2 | ||||
-rw-r--r-- | test/tsan/cond_cancel.c | 8 | ||||
-rw-r--r-- | test/tsan/java_race_pc.cc | 4 | ||||
-rw-r--r-- | test/tsan/map32bit.cc | 1 | ||||
-rw-r--r-- | test/tsan/mmap_large.cc | 2 | ||||
-rw-r--r-- | test/tsan/race_on_mutex.c | 3 | ||||
-rw-r--r-- | test/tsan/signal_errno.cc | 4 | ||||
-rw-r--r-- | test/tsan/signal_longjmp.cc | 4 | ||||
-rw-r--r-- | test/tsan/test.h | 2 |
18 files changed, 270 insertions, 11 deletions
diff --git a/cmake/config-ix.cmake b/cmake/config-ix.cmake index 50e59c79e..f953704c6 100644 --- a/cmake/config-ix.cmake +++ b/cmake/config-ix.cmake @@ -278,7 +278,7 @@ set(ALL_LSAN_SUPPORTED_ARCH ${X86_64} ${MIPS64} ${ARM64}) set(ALL_MSAN_SUPPORTED_ARCH ${X86_64} ${MIPS64} ${ARM64}) set(ALL_PROFILE_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${PPC64} ${MIPS32} ${MIPS64}) -set(ALL_TSAN_SUPPORTED_ARCH ${X86_64} ${MIPS64} ${ARM64}) +set(ALL_TSAN_SUPPORTED_ARCH ${X86_64} ${MIPS64} ${ARM64} ${PPC64}) set(ALL_UBSAN_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${MIPS32} ${MIPS64} ${PPC64}) set(ALL_SAFESTACK_SUPPORTED_ARCH ${X86} ${X86_64}) diff --git a/lib/sanitizer_common/sanitizer_linux.cc b/lib/sanitizer_common/sanitizer_linux.cc index 2e685acc4..9239d1e6b 100644 --- a/lib/sanitizer_common/sanitizer_linux.cc +++ b/lib/sanitizer_common/sanitizer_linux.cc @@ -89,7 +89,8 @@ const int FUTEX_WAKE = 1; // Are we using 32-bit or 64-bit Linux syscalls? // x32 (which defines __x86_64__) has SANITIZER_WORDSIZE == 32 // but it still needs to use 64-bit syscalls. -#if SANITIZER_LINUX && (defined(__x86_64__) || SANITIZER_WORDSIZE == 64) +#if SANITIZER_LINUX && (defined(__x86_64__) || defined(__powerpc64__) || \ + SANITIZER_WORDSIZE == 64) # define SANITIZER_LINUX_USES_64BIT_SYSCALLS 1 #else # define SANITIZER_LINUX_USES_64BIT_SYSCALLS 0 @@ -983,6 +984,88 @@ uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg, : "x30", "memory"); return res; } +#elif defined(__powerpc64__) +uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg, + int *parent_tidptr, void *newtls, int *child_tidptr) { + long long res; +/* Stack frame offsets. */ +#if _CALL_ELF != 2 +#define FRAME_MIN_SIZE 112 +#define FRAME_TOC_SAVE 40 +#else +#define FRAME_MIN_SIZE 32 +#define FRAME_TOC_SAVE 24 +#endif + if (!fn || !child_stack) + return -EINVAL; + CHECK_EQ(0, (uptr)child_stack % 16); + child_stack = (char *)child_stack - 2 * sizeof(unsigned long long); + ((unsigned long long *)child_stack)[0] = (uptr)fn; + ((unsigned long long *)child_stack)[1] = (uptr)arg; + + register int (*__fn)(void *) __asm__("r3") = fn; + register void *__cstack __asm__("r4") = child_stack; + register int __flags __asm__("r5") = flags; + register void * __arg __asm__("r6") = arg; + register int * __ptidptr __asm__("r7") = parent_tidptr; + register void * __newtls __asm__("r8") = newtls; + register int * __ctidptr __asm__("r9") = child_tidptr; + + __asm__ __volatile__( + /* fn, arg, child_stack are saved acrVoss the syscall */ + "mr 28, %5\n\t" + "mr 29, %6\n\t" + "mr 27, %8\n\t" + + /* syscall + r3 == flags + r4 == child_stack + r5 == parent_tidptr + r6 == newtls + r7 == child_tidptr */ + "mr 3, %7\n\t" + "mr 5, %9\n\t" + "mr 6, %10\n\t" + "mr 7, %11\n\t" + "li 0, %3\n\t" + "sc\n\t" + + /* Test if syscall was successful */ + "cmpdi cr1, 3, 0\n\t" + "crandc cr1*4+eq, cr1*4+eq, cr0*4+so\n\t" + "bne- cr1, 1f\n\t" + + /* Do the function call */ + "std 2, %13(1)\n\t" +#if _CALL_ELF != 2 + "ld 0, 0(28)\n\t" + "ld 2, 8(28)\n\t" + "mtctr 0\n\t" +#else + "mr 12, 28\n\t" + "mtctr 12\n\t" +#endif + "mr 3, 27\n\t" + "bctrl\n\t" + "ld 2, %13(1)\n\t" + + /* Call _exit(r3) */ + "li 0, %4\n\t" + "sc\n\t" + + /* Return to parent */ + "1:\n\t" + "mr %0, 3\n\t" + : "=r" (res) + : "0" (-1), "i" (EINVAL), + "i" (__NR_clone), "i" (__NR_exit), + "r" (__fn), "r" (__cstack), "r" (__flags), + "r" (__arg), "r" (__ptidptr), "r" (__newtls), + "r" (__ctidptr), "i" (FRAME_MIN_SIZE), "i" (FRAME_TOC_SAVE) + : "cr0", "cr1", "memory", "ctr", + "r0", "r29", "r27", "r28"); + return res; +} #endif // defined(__x86_64__) && SANITIZER_LINUX #if SANITIZER_ANDROID diff --git a/lib/sanitizer_common/sanitizer_linux.h b/lib/sanitizer_common/sanitizer_linux.h index d996f8c32..77bfbd156 100644 --- a/lib/sanitizer_common/sanitizer_linux.h +++ b/lib/sanitizer_common/sanitizer_linux.h @@ -44,7 +44,8 @@ uptr internal_prctl(int option, uptr arg2, uptr arg3, uptr arg4, uptr arg5); // internal_sigaction instead. int internal_sigaction_norestorer(int signum, const void *act, void *oldact); void internal_sigdelset(__sanitizer_sigset_t *set, int signum); -#if defined(__x86_64__) || defined(__mips__) || defined(__aarch64__) +#if defined(__x86_64__) || defined(__mips__) || defined(__aarch64__) \ + || defined(__powerpc64__) uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg, int *parent_tidptr, void *newtls, int *child_tidptr); #endif diff --git a/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc b/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc index 6fd63126f..2376ee56e 100644 --- a/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc +++ b/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc @@ -15,7 +15,7 @@ #include "sanitizer_platform.h" #if SANITIZER_LINUX && (defined(__x86_64__) || defined(__mips__) || \ - defined(__aarch64__)) + defined(__aarch64__) || defined(__powerpc64__)) #include "sanitizer_stoptheworld.h" @@ -511,5 +511,5 @@ uptr SuspendedThreadsList::RegisterCount() { } } // namespace __sanitizer -#endif // SANITIZER_LINUX && (defined(__x86_64__) || defined(__mips__) - // || defined(__aarch64__) +#endif // SANITIZER_LINUX && (defined(__x86_64__) || defined(__mips__) + // || defined(__aarch64__) || defined(__powerpc64__) diff --git a/lib/tsan/rtl/tsan_interceptors.cc b/lib/tsan/rtl/tsan_interceptors.cc index 57a676f8d..bc31075c7 100644 --- a/lib/tsan/rtl/tsan_interceptors.cc +++ b/lib/tsan/rtl/tsan_interceptors.cc @@ -79,9 +79,11 @@ struct ucontext_t { }; #endif -#if defined(__x86_64__) || defined(__mips__) +#if defined(__x86_64__) || defined(__mips__) \ + || (defined(__powerpc64__) && defined(__BIG_ENDIAN__)) #define PTHREAD_ABI_BASE "GLIBC_2.3.2" -#elif defined(__aarch64__) +#elif defined(__aarch64__) || (defined(__powerpc64__) \ + && defined(__LITTLE_ENDIAN__)) #define PTHREAD_ABI_BASE "GLIBC_2.17" #endif diff --git a/lib/tsan/rtl/tsan_platform.h b/lib/tsan/rtl/tsan_platform.h index 254ea7985..b6bd8b0f5 100644 --- a/lib/tsan/rtl/tsan_platform.h +++ b/lib/tsan/rtl/tsan_platform.h @@ -161,6 +161,79 @@ struct Mapping42 { // Indicates the runtime will define the memory regions at runtime. #define TSAN_RUNTIME_VMA 1 +#elif defined(__powerpc64__) +// PPC64 supports multiple VMA which leads to multiple address transformation +// functions. To support these multiple VMAS transformations and mappings TSAN +// runtime for PPC64 uses an external memory read (vmaSize) to select which +// mapping to use. Although slower, it make a same instrumented binary run on +// multiple kernels. + +/* +C/C++ on linux/powerpc64 (44-bit VMA) +0000 0000 0100 - 0001 0000 0000: main binary +0001 0000 0000 - 0001 0000 0000: - +0001 0000 0000 - 0b00 0000 0000: shadow +0b00 0000 0000 - 0b00 0000 0000: - +0b00 0000 0000 - 0d00 0000 0000: metainfo (memory blocks and sync objects) +0d00 0000 0000 - 0d00 0000 0000: - +0d00 0000 0000 - 0f00 0000 0000: traces +0f00 0000 0000 - 0f00 0000 0000: - +0f00 0000 0000 - 0f50 0000 0000: heap +0f50 0000 0000 - 0f60 0000 0000: - +0f60 0000 0000 - 1000 0000 0000: modules and main thread stack +*/ +struct Mapping44 { + static const uptr kMetaShadowBeg = 0x0b0000000000ull; + static const uptr kMetaShadowEnd = 0x0d0000000000ull; + static const uptr kTraceMemBeg = 0x0d0000000000ull; + static const uptr kTraceMemEnd = 0x0f0000000000ull; + static const uptr kShadowBeg = 0x000100000000ull; + static const uptr kShadowEnd = 0x0b0000000000ull; + static const uptr kLoAppMemBeg = 0x000000000100ull; + static const uptr kLoAppMemEnd = 0x000100000000ull; + static const uptr kHeapMemBeg = 0x0f0000000000ull; + static const uptr kHeapMemEnd = 0x0f5000000000ull; + static const uptr kHiAppMemBeg = 0x0f6000000000ull; + static const uptr kHiAppMemEnd = 0x100000000000ull; // 44 bits + static const uptr kAppMemMsk = 0x0f0000000000ull; + static const uptr kAppMemXor = 0x002100000000ull; + static const uptr kVdsoBeg = 0x3c0000000000000ull; +}; + +/* +C/C++ on linux/powerpc64 (46-bit VMA) +0000 0000 1000 - 0100 0000 0000: main binary +0100 0000 0000 - 0200 0000 0000: - +0100 0000 0000 - 1000 0000 0000: shadow +1000 0000 0000 - 1000 0000 0000: - +1000 0000 0000 - 2000 0000 0000: metainfo (memory blocks and sync objects) +2000 0000 0000 - 2000 0000 0000: - +2000 0000 0000 - 2200 0000 0000: traces +2200 0000 0000 - 3d00 0000 0000: - +3d00 0000 0000 - 3e00 0000 0000: heap +3e00 0000 0000 - 3e80 0000 0000: - +3e80 0000 0000 - 4000 0000 0000: modules and main thread stack +*/ +struct Mapping46 { + static const uptr kMetaShadowBeg = 0x100000000000ull; + static const uptr kMetaShadowEnd = 0x200000000000ull; + static const uptr kTraceMemBeg = 0x200000000000ull; + static const uptr kTraceMemEnd = 0x220000000000ull; + static const uptr kShadowBeg = 0x010000000000ull; + static const uptr kShadowEnd = 0x100000000000ull; + static const uptr kHeapMemBeg = 0x3d0000000000ull; + static const uptr kHeapMemEnd = 0x3e0000000000ull; + static const uptr kLoAppMemBeg = 0x000000001000ull; + static const uptr kLoAppMemEnd = 0x010000000000ull; + static const uptr kHiAppMemBeg = 0x3e8000000000ull; + static const uptr kHiAppMemEnd = 0x400000000000ull; // 46 bits + static const uptr kAppMemMsk = 0x3c0000000000ull; + static const uptr kAppMemXor = 0x020000000000ull; + static const uptr kVdsoBeg = 0x7800000000000000ull; +}; + +// Indicates the runtime will define the memory regions at runtime. +#define TSAN_RUNTIME_VMA 1 #endif #elif defined(SANITIZER_GO) && !SANITIZER_WINDOWS @@ -274,6 +347,12 @@ uptr MappingArchImpl(void) { else return MappingImpl<Mapping42, Type>(); DCHECK(0); +#elif defined(__powerpc64__) + if (vmaSize == 44) + return MappingImpl<Mapping44, Type>(); + else + return MappingImpl<Mapping46, Type>(); + DCHECK(0); #else return MappingImpl<Mapping, Type>(); #endif @@ -399,6 +478,12 @@ bool IsAppMem(uptr mem) { else return IsAppMemImpl<Mapping42>(mem); DCHECK(0); +#elif defined(__powerpc64__) + if (vmaSize == 44) + return IsAppMemImpl<Mapping44>(mem); + else + return IsAppMemImpl<Mapping46>(mem); + DCHECK(0); #else return IsAppMemImpl<Mapping>(mem); #endif @@ -418,6 +503,12 @@ bool IsShadowMem(uptr mem) { else return IsShadowMemImpl<Mapping42>(mem); DCHECK(0); +#elif defined(__powerpc64__) + if (vmaSize == 44) + return IsShadowMemImpl<Mapping44>(mem); + else + return IsShadowMemImpl<Mapping46>(mem); + DCHECK(0); #else return IsShadowMemImpl<Mapping>(mem); #endif @@ -437,6 +528,12 @@ bool IsMetaMem(uptr mem) { else return IsMetaMemImpl<Mapping42>(mem); DCHECK(0); +#elif defined(__powerpc64__) + if (vmaSize == 44) + return IsMetaMemImpl<Mapping44>(mem); + else + return IsMetaMemImpl<Mapping46>(mem); + DCHECK(0); #else return IsMetaMemImpl<Mapping>(mem); #endif @@ -462,6 +559,12 @@ uptr MemToShadow(uptr x) { else return MemToShadowImpl<Mapping42>(x); DCHECK(0); +#elif defined(__powerpc64__) + if (vmaSize == 44) + return MemToShadowImpl<Mapping44>(x); + else + return MemToShadowImpl<Mapping46>(x); + DCHECK(0); #else return MemToShadowImpl<Mapping>(x); #endif @@ -489,6 +592,12 @@ u32 *MemToMeta(uptr x) { else return MemToMetaImpl<Mapping42>(x); DCHECK(0); +#elif defined(__powerpc64__) + if (vmaSize == 44) + return MemToMetaImpl<Mapping44>(x); + else + return MemToMetaImpl<Mapping46>(x); + DCHECK(0); #else return MemToMetaImpl<Mapping>(x); #endif @@ -522,6 +631,12 @@ uptr ShadowToMem(uptr s) { else return ShadowToMemImpl<Mapping42>(s); DCHECK(0); +#elif defined(__powerpc64__) + if (vmaSize == 44) + return ShadowToMemImpl<Mapping44>(s); + else + return ShadowToMemImpl<Mapping46>(s); + DCHECK(0); #else return ShadowToMemImpl<Mapping>(s); #endif @@ -549,6 +664,12 @@ uptr GetThreadTrace(int tid) { else return GetThreadTraceImpl<Mapping42>(tid); DCHECK(0); +#elif defined(__powerpc64__) + if (vmaSize == 44) + return GetThreadTraceImpl<Mapping44>(tid); + else + return GetThreadTraceImpl<Mapping46>(tid); + DCHECK(0); #else return GetThreadTraceImpl<Mapping>(tid); #endif @@ -571,6 +692,12 @@ uptr GetThreadTraceHeader(int tid) { else return GetThreadTraceHeaderImpl<Mapping42>(tid); DCHECK(0); +#elif defined(__powerpc64__) + if (vmaSize == 44) + return GetThreadTraceHeaderImpl<Mapping44>(tid); + else + return GetThreadTraceHeaderImpl<Mapping46>(tid); + DCHECK(0); #else return GetThreadTraceHeaderImpl<Mapping>(tid); #endif diff --git a/lib/tsan/rtl/tsan_platform_linux.cc b/lib/tsan/rtl/tsan_platform_linux.cc index a635f4e74..ff7a4b975 100644 --- a/lib/tsan/rtl/tsan_platform_linux.cc +++ b/lib/tsan/rtl/tsan_platform_linux.cc @@ -244,11 +244,19 @@ void InitializePlatformEarly() { #ifdef TSAN_RUNTIME_VMA vmaSize = (MostSignificantSetBitIndex(GET_CURRENT_FRAME()) + 1); +#if defined(__aarch64__) if (vmaSize != 39 && vmaSize != 42) { Printf("FATAL: ThreadSanitizer: unsupported VMA range\n"); Printf("FATAL: Found %d - Supported 39 and 42\n", vmaSize); Die(); } +#elif defined(__powerpc64__) + if (vmaSize != 44 && vmaSize != 46) { + Printf("FATAL: ThreadSanitizer: unsupported VMA range\n"); + Printf("FATAL: Found %d - Supported 42 and 46\n", vmaSize); + Die(); + } +#endif #endif } diff --git a/lib/tsan/rtl/tsan_platform_posix.cc b/lib/tsan/rtl/tsan_platform_posix.cc index 968dd4093..7c9acf5b5 100644 --- a/lib/tsan/rtl/tsan_platform_posix.cc +++ b/lib/tsan/rtl/tsan_platform_posix.cc @@ -58,6 +58,18 @@ void InitializeShadowMemory() { } else { DCHECK(0); } +#elif defined(__powerpc64__) + uptr kMadviseRangeBeg = 0; + uptr kMadviseRangeSize = 0; + if (vmaSize == 44) { + kMadviseRangeBeg = 0x0f60000000ull; + kMadviseRangeSize = 0x0010000000ull; + } else if (vmaSize == 46) { + kMadviseRangeBeg = 0x3f0000000000ull; + kMadviseRangeSize = 0x010000000000ull; + } else { + DCHECK(0); + } #endif NoHugePagesInRegion(MemToShadow(kMadviseRangeBeg), kMadviseRangeSize * kShadowMultiplier); diff --git a/lib/tsan/rtl/tsan_rtl.h b/lib/tsan/rtl/tsan_rtl.h index a709b4f8f..04104b162 100644 --- a/lib/tsan/rtl/tsan_rtl.h +++ b/lib/tsan/rtl/tsan_rtl.h @@ -54,7 +54,7 @@ namespace __tsan { #ifndef SANITIZER_GO struct MapUnmapCallback; -#if defined(__mips64) || defined(__aarch64__) +#if defined(__mips64) || defined(__aarch64__) || defined(__powerpc__) static const uptr kAllocatorSpace = 0; static const uptr kAllocatorSize = SANITIZER_MMAP_RANGE_SIZE; static const uptr kAllocatorRegionSizeLog = 20; diff --git a/test/tsan/CMakeLists.txt b/test/tsan/CMakeLists.txt index d4fed1d16..01e80388b 100644 --- a/test/tsan/CMakeLists.txt +++ b/test/tsan/CMakeLists.txt @@ -1,5 +1,5 @@ set(TSAN_TEST_DEPS ${SANITIZER_COMMON_LIT_TEST_DEPS}) -if(NOT ${COMPILER_RT_DEFAULT_TARGET_ARCH} MATCHES "mips") +if(${COMPILER_RT_DEFAULT_TARGET_ARCH} MATCHES "x86_64") list(APPEND TSAN_TEST_DEPS GotsanRuntimeCheck) endif() if(NOT COMPILER_RT_STANDALONE_BUILD) diff --git a/test/tsan/cond_cancel.c b/test/tsan/cond_cancel.c index ddfb74517..ca56e8ee9 100644 --- a/test/tsan/cond_cancel.c +++ b/test/tsan/cond_cancel.c @@ -1,6 +1,14 @@ // RUN: %clang_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s // CHECK-NOT: WARNING // CHECK: OK +// This test is failing on powerpc64 (VMA=44). After calling pthread_cancel, +// the Thread-specific data destructors are not called, so the destructor +// "thread_finalize" (defined in tsan_interceptors.cc) can not set the status +// of the thread to "ThreadStatusFinished" failing a check in "SetJoined" +// (defined in sanitizer_thread_registry.cc). It might seem a bug on glibc, +// however the same version GLIBC-2.17 will not make fail the test on +// powerpc64 (VMA=46) +// XFAIL: powerpc64 #include "test.h" diff --git a/test/tsan/java_race_pc.cc b/test/tsan/java_race_pc.cc index 015a0b1f4..0745ade6c 100644 --- a/test/tsan/java_race_pc.cc +++ b/test/tsan/java_race_pc.cc @@ -1,4 +1,8 @@ // RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s +// This test fails on powerpc64 on both VMA (44 and 46). +// The Tsan report is returning wrong information about +// the location of the race. +// XFAIL: powerpc64 #include "java.h" void foobar() { diff --git a/test/tsan/map32bit.cc b/test/tsan/map32bit.cc index 9f933bc4e..0411f29a9 100644 --- a/test/tsan/map32bit.cc +++ b/test/tsan/map32bit.cc @@ -10,6 +10,7 @@ // MAP_32BIT flag for mmap is supported only for x86_64. // XFAIL: mips64 // XFAIL: aarch64 +// XFAIL: powerpc64 // MAP_32BIT doesn't exist on OS X. // UNSUPPORTED: darwin diff --git a/test/tsan/mmap_large.cc b/test/tsan/mmap_large.cc index de32d911f..764e954f2 100644 --- a/test/tsan/mmap_large.cc +++ b/test/tsan/mmap_large.cc @@ -16,6 +16,8 @@ int main() { const size_t kLog2Size = 39; #elif defined(__mips64) || defined(__aarch64__) const size_t kLog2Size = 32; +#elif defined(__powerpc64__) + const size_t kLog2Size = 39; #endif const uintptr_t kLocation = 0x40ULL << kLog2Size; void *p = mmap( diff --git a/test/tsan/race_on_mutex.c b/test/tsan/race_on_mutex.c index 7bd461bf3..ec705dee9 100644 --- a/test/tsan/race_on_mutex.c +++ b/test/tsan/race_on_mutex.c @@ -1,4 +1,7 @@ // RUN: %clang_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s +// This test fails on powerpc64 (VMA=46). +// The size of the write reported by Tsan for T1 is 8 instead of 1. +// XFAIL: powerpc64 #include "test.h" pthread_mutex_t Mtx; diff --git a/test/tsan/signal_errno.cc b/test/tsan/signal_errno.cc index 5354cdeeb..ce19950be 100644 --- a/test/tsan/signal_errno.cc +++ b/test/tsan/signal_errno.cc @@ -1,4 +1,8 @@ // RUN: %clang_tsan -O1 %s -o %t && %deflake %run %t | FileCheck %s +// This test fails on powerpc64 (VMA=44), it does not appear to be +// a functional problem, but the Tsan report is missing some info. +// XFAIL: powerpc64 + #include "test.h" #include <signal.h> #include <sys/types.h> diff --git a/test/tsan/signal_longjmp.cc b/test/tsan/signal_longjmp.cc index 556928ae9..fb4d2781d 100644 --- a/test/tsan/signal_longjmp.cc +++ b/test/tsan/signal_longjmp.cc @@ -5,6 +5,10 @@ // Longjmp assembly has not been implemented for mips64 yet // XFAIL: mips64 +// This test fails on powerpc64 (VMA=44), a segmentation fault +// error happens at the second assignment +// "((volatile int *volatile)mem)[1] = 1". +// XFAIL: powerpc64 #include <setjmp.h> #include <signal.h> diff --git a/test/tsan/test.h b/test/tsan/test.h index cec7c0d32..a681daa32 100644 --- a/test/tsan/test.h +++ b/test/tsan/test.h @@ -43,7 +43,7 @@ void print_address(const char *str, int n, ...) { va_start(ap, n); while (n--) { void *p = va_arg(ap, void *); -#if defined(__x86_64__) || defined(__aarch64__) +#if defined(__x86_64__) || defined(__aarch64__) || defined(__powerpc64__) // On FreeBSD, the %p conversion specifier works as 0x%x and thus does not // match to the format used in the diagnotic message. fprintf(stderr, "0x%012lx ", (unsigned long) p); |