[compiler-rt] r229972 - [TSan][MIPS] Adding support for MIPS64

Mohit K. Bhakkad mohit.bhakkad at imgtec.com
Thu Feb 19 22:42:42 PST 2015


Author: mohit.bhakkad
Date: Fri Feb 20 00:42:41 2015
New Revision: 229972

URL: http://llvm.org/viewvc/llvm-project?rev=229972&view=rev
Log:
[TSan][MIPS] Adding support for MIPS64
Patch by Sagar Thakur

Reviewers: dvyukov, samsonov, petarj, kcc, dsanders.

Subscribers:  mohit.bhakkad, Anand.Takale, llvm-commits.

Differential Revision: http://reviews.llvm.org/D6291

Modified:
    compiler-rt/trunk/cmake/config-ix.cmake
    compiler-rt/trunk/lib/tsan/CMakeLists.txt
    compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc
    compiler-rt/trunk/lib/tsan/rtl/tsan_interface_atomic.cc
    compiler-rt/trunk/lib/tsan/rtl/tsan_platform.h
    compiler-rt/trunk/lib/tsan/rtl/tsan_platform_linux.cc
    compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.cc
    compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.h
    compiler-rt/trunk/lib/tsan/tests/CMakeLists.txt

Modified: compiler-rt/trunk/cmake/config-ix.cmake
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/cmake/config-ix.cmake?rev=229972&r1=229971&r2=229972&view=diff
==============================================================================
--- compiler-rt/trunk/cmake/config-ix.cmake (original)
+++ compiler-rt/trunk/cmake/config-ix.cmake Fri Feb 20 00:42:41 2015
@@ -207,7 +207,7 @@ filter_available_targets(LSAN_COMMON_SUP
 filter_available_targets(MSAN_SUPPORTED_ARCH x86_64 mips64 mips64el)
 filter_available_targets(PROFILE_SUPPORTED_ARCH x86_64 i386 i686 arm mips mips64
   mipsel mips64el aarch64 powerpc64 powerpc64le)
-filter_available_targets(TSAN_SUPPORTED_ARCH x86_64)
+filter_available_targets(TSAN_SUPPORTED_ARCH x86_64 mips64 mips64el)
 filter_available_targets(UBSAN_SUPPORTED_ARCH x86_64 i386 i686 arm aarch64 mips mipsel mips64 mips64el)
 
 if(ANDROID)

Modified: compiler-rt/trunk/lib/tsan/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/CMakeLists.txt?rev=229972&r1=229971&r2=229972&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/CMakeLists.txt (original)
+++ compiler-rt/trunk/lib/tsan/CMakeLists.txt Fri Feb 20 00:42:41 2015
@@ -79,35 +79,40 @@ set(TSAN_HEADERS
 set(TSAN_RUNTIME_LIBRARIES)
 add_custom_target(tsan)
 # TSan is currently supported on 64-bit Linux only.
-if(CAN_TARGET_x86_64 AND UNIX AND NOT APPLE)
-  set(TSAN_ASM_SOURCES rtl/tsan_rtl_amd64.S)
-  # Pass ASM file directly to the C++ compiler.
-  set_source_files_properties(${TSAN_ASM_SOURCES} PROPERTIES
-    LANGUAGE C)
-  set(arch "x86_64")
-  add_compiler_rt_runtime(clang_rt.tsan-${arch} ${arch} STATIC
-    SOURCES ${TSAN_SOURCES} ${TSAN_ASM_SOURCES}
-            $<TARGET_OBJECTS:RTInterception.${arch}>
-            $<TARGET_OBJECTS:RTSanitizerCommon.${arch}>
-            $<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}>
-    CFLAGS ${TSAN_RTL_CFLAGS}
-    DEFS ${TSAN_COMMON_DEFINITIONS})
-  list(APPEND TSAN_RUNTIME_LIBRARIES clang_rt.tsan-${arch})
-  add_sanitizer_rt_symbols(clang_rt.tsan-${arch} rtl/tsan.syms.extra)
-  add_dependencies(tsan clang_rt.tsan-${arch}
-    clang_rt.tsan-${arch}-symbols)
+if(UNIX AND NOT APPLE)
+  foreach(arch ${TSAN_SUPPORTED_ARCH})
+    if(arch STREQUAL "x86_64")
+      set(TSAN_ASM_SOURCES rtl/tsan_rtl_amd64.S)
+      # Pass ASM file directly to the C++ compiler.
+      set_source_files_properties(${TSAN_ASM_SOURCES} PROPERTIES
+        LANGUAGE C)
+      # Sanity check for Go runtime.
+      set(BUILDGO_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/go/buildgo.sh)
+      add_custom_target(GotsanRuntimeCheck
+        COMMAND CC=${CMAKE_C_COMPILER} 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)
+    else()
+      set(TSAN_ASM_SOURCES)
+    endif()
+    add_compiler_rt_runtime(clang_rt.tsan-${arch} ${arch} STATIC
+      SOURCES ${TSAN_SOURCES} ${TSAN_ASM_SOURCES}
+              $<TARGET_OBJECTS:RTInterception.${arch}>
+              $<TARGET_OBJECTS:RTSanitizerCommon.${arch}>
+              $<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}>
+      CFLAGS ${TSAN_RTL_CFLAGS}
+      DEFS ${TSAN_COMMON_DEFINITIONS})
+    list(APPEND TSAN_RUNTIME_LIBRARIES clang_rt.tsan-${arch})
+    add_sanitizer_rt_symbols(clang_rt.tsan-${arch} rtl/tsan.syms.extra)
+    add_dependencies(tsan clang_rt.tsan-${arch}
+      clang_rt.tsan-${arch}-symbols)
+  endforeach()
 endif()
 
 add_dependencies(compiler-rt tsan)
 
-# Sanity check for Go runtime.
-set(BUILDGO_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/go/buildgo.sh)
-add_custom_target(GotsanRuntimeCheck
-  COMMAND CC=${CMAKE_C_COMPILER} 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)
 
 # Build libcxx instrumented with TSan.
 if(TSAN_SUPPORTED_ARCH AND

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc?rev=229972&r1=229971&r2=229972&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc Fri Feb 20 00:42:41 2015
@@ -39,17 +39,27 @@ using namespace __tsan;  // NOLINT
 #define stderr __stderrp
 #endif
 
+#ifdef __mips__
+const int kSigCount = 129;
+#else
 const int kSigCount = 65;
+#endif
 
 struct my_siginfo_t {
   // The size is determined by looking at sizeof of real siginfo_t on linux.
   u64 opaque[128 / sizeof(u64)];
 };
 
+#ifdef __mips__
+struct ucontext_t {
+  u64 opaque[768 / sizeof(u64) + 1];
+};
+#else
 struct ucontext_t {
   // The size is determined by looking at sizeof of real ucontext_t on linux.
   u64 opaque[936 / sizeof(u64) + 1];
 };
+#endif
 
 extern "C" int pthread_attr_init(void *attr);
 extern "C" int pthread_attr_destroy(void *attr);
@@ -89,8 +99,13 @@ const int SIGFPE = 8;
 const int SIGSEGV = 11;
 const int SIGPIPE = 13;
 const int SIGTERM = 15;
+#ifdef __mips__
+const int SIGBUS = 10;
+const int SIGSYS = 12;
+#else
 const int SIGBUS = 7;
 const int SIGSYS = 31;
+#endif
 void *const MAP_FAILED = (void*)-1;
 const int PTHREAD_BARRIER_SERIAL_THREAD = -1;
 const int MAP_FIXED = 0x10;
@@ -108,6 +123,9 @@ typedef void (*sighandler_t)(int sig);
 typedef void (*sigactionhandler_t)(int sig, my_siginfo_t *siginfo, void *uctx);
 
 struct sigaction_t {
+#ifdef __mips__
+  u32 sa_flags;
+#endif
   union {
     sighandler_t sa_handler;
     sigactionhandler_t sa_sigaction;
@@ -117,7 +135,9 @@ struct sigaction_t {
   __sanitizer_sigset_t sa_mask;
 #else
   __sanitizer_sigset_t sa_mask;
+#ifndef __mips__
   int sa_flags;
+#endif
   void (*sa_restorer)();
 #endif
 };
@@ -125,8 +145,13 @@ struct sigaction_t {
 const sighandler_t SIG_DFL = (sighandler_t)0;
 const sighandler_t SIG_IGN = (sighandler_t)1;
 const sighandler_t SIG_ERR = (sighandler_t)-1;
+#ifdef __mips__
+const int SA_SIGINFO = 8;
+const int SIG_SETMASK = 3;
+#else
 const int SA_SIGINFO = 4;
 const int SIG_SETMASK = 2;
+#endif
 
 namespace std {
 struct nothrow_t {};

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_interface_atomic.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_interface_atomic.cc?rev=229972&r1=229971&r2=229972&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_interface_atomic.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_interface_atomic.cc Fri Feb 20 00:42:41 2015
@@ -33,14 +33,14 @@ typedef unsigned short     a16;  // NOLI
 typedef unsigned int       a32;
 typedef unsigned long long a64;  // NOLINT
 #if !defined(SANITIZER_GO) && (defined(__SIZEOF_INT128__) \
-    || (__clang_major__ * 100 + __clang_minor__ >= 302))
+    || (__clang_major__ * 100 + __clang_minor__ >= 302)) && !defined(__mips64)
 __extension__ typedef __int128 a128;
 # define __TSAN_HAS_INT128 1
 #else
 # define __TSAN_HAS_INT128 0
 #endif
 
-#ifndef SANITIZER_GO
+#if !defined(SANITIZER_GO) && __TSAN_HAS_INT128
 // Protects emulation of 128-bit atomic operations.
 static StaticSpinMutex mutex128;
 #endif
@@ -125,7 +125,8 @@ template<typename T> T func_cas(volatile
 // Atomic ops are executed under tsan internal mutex,
 // here we assume that the atomic variables are not accessed
 // from non-instrumented code.
-#if !defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16) && !defined(SANITIZER_GO)
+#if !defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16) && !defined(SANITIZER_GO) \
+    && __TSAN_HAS_INT128
 a128 func_xchg(volatile a128 *v, a128 op) {
   SpinMutexLock lock(&mutex128);
   a128 cmp = *v;

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_platform.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_platform.h?rev=229972&r1=229971&r2=229972&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_platform.h (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_platform.h Fri Feb 20 00:42:41 2015
@@ -26,8 +26,9 @@ namespace __tsan {
 
 #if !defined(SANITIZER_GO)
 
+#if defined(__x86_64__)
 /*
-C/C++ on linux and freebsd
+C/C++ on linux/x86_64 and freebsd/x86_64
 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
@@ -40,7 +41,6 @@ C/C++ on linux and freebsd
 7e00 0000 0000 - 7e80 0000 0000: -
 7e80 0000 0000 - 8000 0000 0000: modules and main thread stack
 */
-
 const uptr kMetaShadowBeg = 0x300000000000ull;
 const uptr kMetaShadowEnd = 0x400000000000ull;
 const uptr kTraceMemBeg   = 0x600000000000ull;
@@ -55,6 +55,38 @@ const uptr kHiAppMemBeg   = 0x7e80000000
 const uptr kHiAppMemEnd   = 0x800000000000ull;
 const uptr kAppMemMsk     = 0x7c0000000000ull;
 const uptr kAppMemXor     = 0x020000000000ull;
+const uptr kVdsoBeg       = 0xf000000000000000ull;
+#elif defined(__mips64)
+/*
+C/C++ on linux/mips64
+0100 0000 00 - 0200 0000 00: main binary
+0200 0000 00 - 1400 0000 00: -
+1400 0000 00 - 2400 0000 00: shadow
+2400 0000 00 - 3000 0000 00: -
+3000 0000 00 - 4000 0000 00: metainfo (memory blocks and sync objects)
+4000 0000 00 - 6000 0000 00: -
+6000 0000 00 - 6200 0000 00: traces
+6200 0000 00 - fe00 0000 00: -
+fe00 0000 00 - ff00 0000 00: heap
+ff00 0000 00 - ff80 0000 00: -
+ff80 0000 00 - ffff ffff ff: modules and main thread stack
+*/
+const uptr kMetaShadowBeg = 0x3000000000ull;
+const uptr kMetaShadowEnd = 0x4000000000ull;
+const uptr kTraceMemBeg   = 0x6000000000ull;
+const uptr kTraceMemEnd   = 0x6200000000ull;
+const uptr kShadowBeg     = 0x1400000000ull;
+const uptr kShadowEnd     = 0x2400000000ull;
+const uptr kHeapMemBeg    = 0xfe00000000ull;
+const uptr kHeapMemEnd    = 0xff00000000ull;
+const uptr kLoAppMemBeg   = 0x0100000000ull;
+const uptr kLoAppMemEnd   = 0x0200000000ull;
+const uptr kHiAppMemBeg   = 0xff80000000ull;
+const uptr kHiAppMemEnd   = 0xffffffffffull;
+const uptr kAppMemMsk     = 0xfc00000000ull;
+const uptr kAppMemXor     = 0x0400000000ull;
+const uptr kVdsoBeg       = 0xfffff00000ull;
+#endif
 
 ALWAYS_INLINE
 bool IsAppMem(uptr mem) {

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_platform_linux.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_platform_linux.cc?rev=229972&r1=229971&r2=229972&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_platform_linux.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_platform_linux.cc Fri Feb 20 00:42:41 2015
@@ -66,8 +66,6 @@ namespace __tsan {
 static uptr g_data_start;
 static uptr g_data_end;
 
-const uptr kPageSize = 4096;
-
 enum {
   MemTotal  = 0,
   MemShadow = 1,
@@ -173,7 +171,7 @@ static void MapRodata() {
     *p = kShadowRodata;
   internal_write(fd, marker.data(), marker.size());
   // Map the file into memory.
-  uptr page = internal_mmap(0, kPageSize, PROT_READ | PROT_WRITE,
+  uptr page = internal_mmap(0, GetPageSizeCached(), PROT_READ | PROT_WRITE,
                             MAP_PRIVATE | MAP_ANONYMOUS, fd, 0);
   if (internal_iserror(page)) {
     internal_close(fd);
@@ -216,8 +214,15 @@ void InitializeShadowMemory() {
   // a program uses a small part of large mmap. On some programs
   // we see 20% memory usage reduction without huge pages for this range.
   // FIXME: don't use constants here.
-  NoHugePagesInRegion(MemToShadow(0x7f0000000000ULL),
-                      0x10000000000ULL * kShadowMultiplier);
+#if defined(__x86_64__)
+  const uptr kMadviseRangeBeg  = 0x7f0000000000ull;
+  const uptr kMadviseRangeSize = 0x010000000000ull;
+#elif defined(__mips64)
+  const uptr kMadviseRangeBeg  = 0xff00000000ull;
+  const uptr kMadviseRangeSize = 0x0100000000ull;
+#endif
+  NoHugePagesInRegion(MemToShadow(kMadviseRangeBeg),
+                      kMadviseRangeSize * kShadowMultiplier);
   if (common_flags()->use_madv_dontdump)
     DontDumpShadowMemory(kShadowBeg, kShadowEnd - kShadowBeg);
   DPrintf("memory shadow: %zx-%zx (%zuGB)\n",
@@ -289,9 +294,9 @@ static void CheckAndProtect() {
     if (IsAppMem(p))
       continue;
     if (p >= kHeapMemEnd &&
-        p < kHeapMemEnd + PrimaryAllocator::AdditionalSize())
+        p < HeapEnd())
       continue;
-    if (p >= 0xf000000000000000ull)  // vdso
+    if (p >= kVdsoBeg)  // vdso
       break;
     Printf("FATAL: ThreadSanitizer: unexpected memory mapping %p-%p\n", p, end);
     Die();
@@ -304,7 +309,7 @@ static void CheckAndProtect() {
   // Protect the whole range for now, so that user does not map something here.
   ProtectRange(kTraceMemBeg, kTraceMemEnd);
   ProtectRange(kTraceMemEnd, kHeapMemBeg);
-  ProtectRange(kHeapMemEnd + PrimaryAllocator::AdditionalSize(), kHiAppMemBeg);
+  ProtectRange(HeapEnd(), kHiAppMemBeg);
 }
 #endif  // #ifndef SANITIZER_GO
 

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.cc?rev=229972&r1=229971&r2=229972&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.cc Fri Feb 20 00:42:41 2015
@@ -217,12 +217,14 @@ static void StartBackgroundThread() {
   ctx->background_thread = internal_start_thread(&BackgroundThread, 0);
 }
 
+#ifndef __mips__
 static void StopBackgroundThread() {
   atomic_store(&ctx->stop_background_thread, 1, memory_order_relaxed);
   internal_join_thread(ctx->background_thread);
   ctx->background_thread = 0;
 }
 #endif
+#endif
 
 void DontNeedShadowFor(uptr addr, uptr size) {
   uptr shadow_beg = MemToShadow(addr);
@@ -330,9 +332,14 @@ void Initialize(ThreadState *thr) {
 #ifndef SANITIZER_GO
   InitializeLibIgnore();
   Symbolizer::GetOrInit()->AddHooks(EnterSymbolizer, ExitSymbolizer);
+  // On MIPS, TSan initialization is run before
+  // __pthread_initialize_minimal_internal() is finished, so we can not spawn
+  // new threads.
+#ifndef __mips__
   StartBackgroundThread();
   SetSandboxingCallback(StopBackgroundThread);
 #endif
+#endif
   if (common_flags()->detect_deadlocks)
     ctx->dd = DDetector::Create(flags());
 
@@ -832,7 +839,7 @@ static void MemoryRangeSet(ThreadState *
     }
   } else {
     // The region is big, reset only beginning and end.
-    const uptr kPageSize = 4096;
+    const uptr kPageSize = GetPageSizeCached();
     u64 *begin = (u64*)MemToShadow(addr);
     u64 *end = begin + size / kShadowCell * kShadowCnt;
     u64 *p = begin;

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.h?rev=229972&r1=229971&r2=229972&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.h (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.h Fri Feb 20 00:42:41 2015
@@ -54,8 +54,21 @@ namespace __tsan {
 
 #ifndef SANITIZER_GO
 struct MapUnmapCallback;
+#ifdef __mips64
+static const uptr kAllocatorSpace = 0;
+static const uptr kAllocatorSize = SANITIZER_MMAP_RANGE_SIZE;
+static const uptr kAllocatorRegionSizeLog = 20;
+static const uptr kAllocatorNumRegions =
+    kAllocatorSize >> kAllocatorRegionSizeLog;
+typedef TwoLevelByteMap<(kAllocatorNumRegions >> 12), 1 << 12,
+    MapUnmapCallback> ByteMap;
+typedef SizeClassAllocator32<kAllocatorSpace, kAllocatorSize, 0,
+    CompactSizeClassMap, kAllocatorRegionSizeLog, ByteMap,
+    MapUnmapCallback> PrimaryAllocator;
+#else
 typedef SizeClassAllocator64<kHeapMemBeg, kHeapMemEnd - kHeapMemBeg, 0,
     DefaultSizeClassMap, MapUnmapCallback> PrimaryAllocator;
+#endif
 typedef SizeClassAllocatorLocalCache<PrimaryAllocator> AllocatorCache;
 typedef LargeMmapAllocator<MapUnmapCallback> SecondaryAllocator;
 typedef CombinedAllocator<PrimaryAllocator, AllocatorCache,
@@ -738,6 +751,16 @@ void ALWAYS_INLINE TraceAddEvent(ThreadS
   *evp = ev;
 }
 
+#ifndef SANITIZER_GO
+uptr ALWAYS_INLINE HeapEnd() {
+#if SANITIZER_CAN_USE_ALLOCATOR64
+  return kHeapMemEnd + PrimaryAllocator::AdditionalSize();
+#else
+  return kHeapMemEnd;
+#endif
+}
+#endif
+
 }  // namespace __tsan
 
 #endif  // TSAN_RTL_H

Modified: compiler-rt/trunk/lib/tsan/tests/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/tests/CMakeLists.txt?rev=229972&r1=229971&r2=229972&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/tests/CMakeLists.txt (original)
+++ compiler-rt/trunk/lib/tsan/tests/CMakeLists.txt Fri Feb 20 00:42:41 2015
@@ -34,26 +34,28 @@ endmacro()
 
 macro(add_tsan_unittest testname)
   # Build unit tests only for 64-bit Linux.
-  if(UNIX AND NOT APPLE AND CAN_TARGET_x86_64)
-    parse_arguments(TEST "SOURCES;HEADERS" "" ${ARGN})
-    set(TEST_OBJECTS)
-    foreach(SOURCE ${TEST_SOURCES} ${COMPILER_RT_GTEST_SOURCE})
-      tsan_compile(TEST_OBJECTS ${SOURCE} x86_64 ${TEST_HEADERS})
+  if(UNIX AND NOT APPLE)
+    foreach(arch ${TSAN_SUPPORTED_ARCH})
+      parse_arguments(TEST "SOURCES;HEADERS" "" ${ARGN})
+      set(TEST_OBJECTS)
+      foreach(SOURCE ${TEST_SOURCES} ${COMPILER_RT_GTEST_SOURCE})
+        tsan_compile(TEST_OBJECTS ${SOURCE} ${arch} ${TEST_HEADERS})
+      endforeach()
+      get_target_flags_for_arch(${arch} TARGET_LINK_FLAGS)
+      set(TEST_DEPS ${TEST_OBJECTS})
+      if(NOT COMPILER_RT_STANDALONE_BUILD)
+        list(APPEND TEST_DEPS tsan)
+      endif()
+      # FIXME: Looks like we should link TSan with just-built runtime,
+      # and not rely on -fsanitize=thread, as these tests are essentially
+      # unit tests.
+      add_compiler_rt_test(TsanUnitTests ${testname}
+              OBJECTS ${TEST_OBJECTS}
+              DEPS ${TEST_DEPS}
+              LINK_FLAGS ${TARGET_LINK_FLAGS}
+                         -fsanitize=thread
+                         -lstdc++ -lm)
     endforeach()
-    get_target_flags_for_arch(${arch} TARGET_LINK_FLAGS)
-    set(TEST_DEPS ${TEST_OBJECTS})
-    if(NOT COMPILER_RT_STANDALONE_BUILD)
-      list(APPEND TEST_DEPS tsan)
-    endif()
-    # FIXME: Looks like we should link TSan with just-built runtime,
-    # and not rely on -fsanitize=thread, as these tests are essentially
-    # unit tests.
-    add_compiler_rt_test(TsanUnitTests ${testname}
-            OBJECTS ${TEST_OBJECTS}
-            DEPS ${TEST_DEPS}
-            LINK_FLAGS ${TARGET_LINK_FLAGS}
-                       -fsanitize=thread
-                       -lstdc++ -lm)
   endif()
 endmacro()
 





More information about the llvm-commits mailing list