Index: cmake/config-ix.cmake =================================================================== --- cmake/config-ix.cmake +++ cmake/config-ix.cmake @@ -143,6 +143,8 @@ check_symbol_exists(__i386__ "" __I386) check_symbol_exists(__mips__ "" __MIPS) check_symbol_exists(__mips64__ "" __MIPS64) + check_symbol_exists(__powerpc64__ "" __POWERPC64) + check_symbol_exists(__powerpc64le__ "" __POWERPC64LE) if(__ARM) add_default_target_arch(arm) elseif(__AARCH64) @@ -157,6 +159,10 @@ add_default_target_arch(mips64) elseif(__MIPS) add_default_target_arch(mips) + elseif(__POWERPC64) + add_default_target_arch(powerpc64) + elseif(__POWERPC64LE) + add_default_target_arch(powerpc64le) endif() endmacro() @@ -248,6 +254,7 @@ set(ARM64 aarch64) set(ARM32 arm) set(X86_64 x86_64) +set(PPC64 powerpc64 powerpc64le) if(APPLE) set(ARM64 arm64) set(ARM32 armv7 armv7s) @@ -255,18 +262,18 @@ endif() set(ALL_BUILTIN_SUPPORTED_ARCH i386 i686 ${X86_64} ${ARM32} ${ARM64}) -set(ALL_SANITIZER_COMMON_SUPPORTED_ARCH ${X86_64} i386 i686 powerpc64 - powerpc64le ${ARM32} ${ARM64} mips mips64 mipsel mips64el) -set(ALL_ASAN_SUPPORTED_ARCH ${X86_64} i386 i686 powerpc64 powerpc64le ${ARM32} +set(ALL_SANITIZER_COMMON_SUPPORTED_ARCH ${X86_64} i386 i686 ${PPC64} + ${ARM32} ${ARM64} mips mips64 mipsel mips64el) +set(ALL_ASAN_SUPPORTED_ARCH ${X86_64} i386 i686 ${PPC64} ${ARM32} ${ARM64} mips mipsel mips64 mips64el) set(ALL_DFSAN_SUPPORTED_ARCH ${X86_64} mips64 mips64el ${ARM64}) set(ALL_LSAN_SUPPORTED_ARCH ${X86_64} mips64 mips64el) set(ALL_MSAN_SUPPORTED_ARCH ${X86_64} mips64 mips64el) set(ALL_PROFILE_SUPPORTED_ARCH ${X86_64} i386 i686 ${ARM32} mips mips64 - mipsel mips64el ${ARM64} powerpc64 powerpc64le) -set(ALL_TSAN_SUPPORTED_ARCH ${X86_64} mips64 mips64el ${ARM64}) + mipsel mips64el ${ARM64} ${PPC64}) +set(ALL_TSAN_SUPPORTED_ARCH ${X86_64} mips64 mips64el ${ARM64} ${PPC64}) set(ALL_UBSAN_SUPPORTED_ARCH ${X86_64} i386 i686 ${ARM32} ${ARM64} mips - mipsel mips64 mips64el powerpc64 powerpc64le) + mipsel mips64 mips64el ${PPC64}) set(ALL_SAFESTACK_SUPPORTED_ARCH ${X86_64} i386 i686) if(APPLE) Index: lib/sanitizer_common/sanitizer_linux.h =================================================================== --- lib/sanitizer_common/sanitizer_linux.h +++ lib/sanitizer_common/sanitizer_linux.h @@ -44,7 +44,8 @@ // 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__) || defined(__powerpc64le__) uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg, int *parent_tidptr, void *newtls, int *child_tidptr); #endif Index: lib/sanitizer_common/sanitizer_linux.cc =================================================================== --- lib/sanitizer_common/sanitizer_linux.cc +++ lib/sanitizer_common/sanitizer_linux.cc @@ -88,7 +88,8 @@ // 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__) \ +|| defined(__powerpc64le__) || SANITIZER_WORDSIZE == 64) # define SANITIZER_LINUX_USES_64BIT_SYSCALLS 1 #else # define SANITIZER_LINUX_USES_64BIT_SYSCALLS 0 @@ -979,6 +980,16 @@ : "x30", "memory"); return res; } +#elif defined(__powerpc64__) || defined(__powerpc64le__) +// TSAN_PPC64 - not completed +uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg, + int *parent_tidptr, void *newtls, int *child_tidptr) { + long long res; + + res = clone(fn, child_stack, flags, arg, parent_tidptr, newtls, child_tidptr); + + return res; +} #endif // defined(__x86_64__) && SANITIZER_LINUX #if SANITIZER_ANDROID @@ -1108,7 +1119,8 @@ *bp = ucontext->uc_mcontext.gregs[REG_EBP]; *sp = ucontext->uc_mcontext.gregs[REG_ESP]; # endif -#elif defined(__powerpc__) || defined(__powerpc64__) +#elif defined(__powerpc__) || defined(__powerpc64__) \ + || defined(__powerpc64le__) ucontext_t *ucontext = (ucontext_t*)context; *pc = ucontext->uc_mcontext.regs->nip; *sp = ucontext->uc_mcontext.regs->gpr[PT_R1]; Index: lib/sanitizer_common/sanitizer_linux_libcdep.cc =================================================================== --- lib/sanitizer_common/sanitizer_linux_libcdep.cc +++ lib/sanitizer_common/sanitizer_linux_libcdep.cc @@ -178,7 +178,7 @@ # define DL_INTERNAL_FUNCTION #endif -#if defined(__mips__) +#if defined(__mips__) || defined(__powerpc64__) || defined(__powerpc64le__) // TlsPreTcbSize includes size of struct pthread_descr and size of tcb // head structure. It lies before the static tls blocks. static uptr TlsPreTcbSize() { @@ -213,8 +213,8 @@ } #if (defined(__x86_64__) || defined(__i386__) || defined(__mips__) \ - || defined(__aarch64__)) \ - && SANITIZER_LINUX && !SANITIZER_ANDROID + || defined(__aarch64__) || defined(__powerpc64__) \ + || defined(__powerpc64le__)) && SANITIZER_LINUX && !SANITIZER_ANDROID // sizeof(struct thread) from glibc. static atomic_uintptr_t kThreadDescriptorSize; @@ -266,6 +266,11 @@ val = 1776; atomic_store(&kThreadDescriptorSize, val, memory_order_relaxed); return val; +#elif defined(__powerpc64__) || defined(__powerpc64le__) + val = FIRST_32_SECOND_64(1872, 1872); + if (val) + atomic_store(&kThreadDescriptorSize, val, memory_order_relaxed); + return val; #endif return 0; } @@ -297,6 +302,11 @@ descr_addr = thread_pointer - kTlsTcbOffset - TlsPreTcbSize(); # elif defined(__aarch64__) descr_addr = reinterpret_cast(__builtin_thread_pointer()); +# elif defined(__powerpc64__) || defined(__powerpc64le__) + const uptr kTlsTcbOffset = 0x7000; + uptr thread_pointer; + asm("addi %0,%%r13,0" : "=r" (thread_pointer)); + descr_addr = thread_pointer - kTlsTcbOffset - TlsPreTcbSize(); # else # error "unsupported CPU arch" # endif @@ -332,7 +342,8 @@ *size = GetTlsSize(); *addr -= *size; *addr += ThreadDescriptorSize(); -# elif defined(__mips__) || defined(__aarch64__) +# elif defined(__mips__) || defined(__aarch64__) \ + || defined(__powerpc64__) || defined(__powerpc64le__) *addr = ThreadSelf(); *size = GetTlsSize(); # else Index: lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc =================================================================== --- lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc +++ lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc @@ -15,7 +15,8 @@ #include "sanitizer_platform.h" #if SANITIZER_LINUX && (defined(__x86_64__) || defined(__mips__) || \ - defined(__aarch64__)) + defined(__aarch64__) || defined(__powerpc64__) || \ + defined(__powerpc64le__)) #include "sanitizer_stoptheworld.h" Index: lib/tsan/rtl/tsan_interceptors.cc =================================================================== --- lib/tsan/rtl/tsan_interceptors.cc +++ lib/tsan/rtl/tsan_interceptors.cc @@ -2461,12 +2461,22 @@ TSAN_INTERCEPT(pthread_join); TSAN_INTERCEPT(pthread_detach); +#if defined(__powerpc__) || defined(__powerpc64__) \ + || defined(__powerpc64le__) + TSAN_INTERCEPT(pthread_cond_init); + TSAN_INTERCEPT(pthread_cond_signal); + TSAN_INTERCEPT(pthread_cond_broadcast); + TSAN_INTERCEPT(pthread_cond_wait); + TSAN_INTERCEPT(pthread_cond_timedwait); + TSAN_INTERCEPT(pthread_cond_destroy); +#else TSAN_INTERCEPT_VER(pthread_cond_init, PTHREAD_ABI_BASE); TSAN_INTERCEPT_VER(pthread_cond_signal, PTHREAD_ABI_BASE); TSAN_INTERCEPT_VER(pthread_cond_broadcast, PTHREAD_ABI_BASE); TSAN_INTERCEPT_VER(pthread_cond_wait, PTHREAD_ABI_BASE); TSAN_INTERCEPT_VER(pthread_cond_timedwait, PTHREAD_ABI_BASE); TSAN_INTERCEPT_VER(pthread_cond_destroy, PTHREAD_ABI_BASE); +#endif TSAN_INTERCEPT(pthread_mutex_init); TSAN_INTERCEPT(pthread_mutex_destroy); Index: lib/tsan/rtl/tsan_platform.h =================================================================== --- lib/tsan/rtl/tsan_platform.h +++ lib/tsan/rtl/tsan_platform.h @@ -145,6 +145,36 @@ const uptr kAppMemXor = 0x04000000000ull; const uptr kVdsoBeg = 0x37f00000000ull; # endif +#elif defined(__powerpc64__) || defined(__powerpc64le__) +/* +C/C++ on linux/powerpc64 +0000 0000 1000 - 0100 0000 0000: main binary and/or MAP_32BIT mappings +0100 0000 0000 - 0200 0000 0000: - +0200 0000 0000 - 1000 0000 0000: shadow +1000 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 - 7d00 0000 0000: - +7d00 0000 0000 - 7e00 0000 0000: heap +7e00 0000 0000 - 7e80 0000 0000: - +7e80 0000 0000 - 8000 0000 0000: modules and main thread stack +*/ +const uptr kMetaShadowBeg = 0x100000000000ull; +const uptr kMetaShadowEnd = 0x200000000000ull; +const uptr kTraceMemBeg = 0x200000000000ull; +const uptr kTraceMemEnd = 0x220000000000ull; +const uptr kShadowBeg = 0x020000000000ull; +const uptr kShadowEnd = 0x100000000000ull; +const uptr kHeapMemBeg = 0x3d0000000000ull; +const uptr kHeapMemEnd = 0x3e0000000000ull; +const uptr kLoAppMemBeg = 0x000000001000ull; +const uptr kLoAppMemEnd = 0x010000000000ull; +const uptr kHiAppMemBeg = 0x3e8000000000ull; +const uptr kHiAppMemEnd = 0x400000000000ull; +const uptr kAppMemMsk = 0x3c0000000000ull; +const uptr kAppMemXor = 0x020000000000ull; +const uptr kVdsoBeg = 0xf000000000000000ull; #endif ALWAYS_INLINE Index: lib/tsan/rtl/tsan_platform_linux.cc =================================================================== --- lib/tsan/rtl/tsan_platform_linux.cc +++ lib/tsan/rtl/tsan_platform_linux.cc @@ -224,6 +224,10 @@ #elif defined(__aarch64__) const uptr kMadviseRangeBeg = 0x7e00000000ull; const uptr kMadviseRangeSize = 0x0100000000ull; +#elif defined(__powerpc__) || defined(__powerpc64__) || \ + defined(__powerpc64le__) + const uptr kMadviseRangeBeg = 0x3f0000000000ull; + const uptr kMadviseRangeSize = 0x010000000000ull; #endif NoHugePagesInRegion(MemToShadow(kMadviseRangeBeg), kMadviseRangeSize * kShadowMultiplier); Index: test/tsan/CMakeLists.txt =================================================================== --- test/tsan/CMakeLists.txt +++ 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(NOT ${COMPILER_RT_DEFAULT_TARGET_ARCH} MATCHES "mips|powerpc64|powerpc64le") list(APPEND TSAN_TEST_DEPS GotsanRuntimeCheck) endif() if(NOT COMPILER_RT_STANDALONE_BUILD) Index: test/tsan/map32bit.cc =================================================================== --- test/tsan/map32bit.cc +++ test/tsan/map32bit.cc @@ -10,6 +10,8 @@ // MAP_32BIT flag for mmap is supported only for x86_64. // XFAIL: mips64 // XFAIL: aarch64 +// XFAIL: powerpc64 +// XFAIL: powerpc64le void *Thread(void *ptr) { *(int*)ptr = 42; Index: test/tsan/mmap_large.cc =================================================================== --- test/tsan/mmap_large.cc +++ test/tsan/mmap_large.cc @@ -16,6 +16,10 @@ const size_t kLog2Size = 39; #elif defined(__mips64) || defined(__aarch64__) const size_t kLog2Size = 32; +#elif defined(__powerpc) + const size_t kLog2Size = 39; +#elif defined(__powerpc64__) + const size_t kLog2Size = 39; #endif const uintptr_t kLocation = 0x40ULL << kLog2Size; void *p = mmap( Index: test/tsan/test.h =================================================================== --- test/tsan/test.h +++ test/tsan/test.h @@ -58,5 +58,7 @@ } fprintf(stderr, format, (unsigned long) address); +#elif defined(__powerpc64__) + fprintf(stderr, "0x%012lx", (unsigned long) address); #endif }