[llvm-commits] [compiler-rt] r159754 - in /compiler-rt/trunk/lib: sanitizer_common/sanitizer_allocator.cc sanitizer_common/sanitizer_common.h sanitizer_common/sanitizer_interface_defs.h sanitizer_common/sanitizer_posix.cc tsan/go/ tsan/go/buildgo.sh tsan/go/tsan_go.cc tsan/rtl/tsan_defs.h tsan/rtl/tsan_flags.cc tsan/rtl/tsan_mutex.cc tsan/rtl/tsan_platform.h tsan/rtl/tsan_platform_linux.cc tsan/rtl/tsan_rtl.cc tsan/rtl/tsan_rtl.h tsan/rtl/tsan_rtl_thread.cc

Dmitry Vyukov dvyukov at google.com
Thu Jul 5 09:18:28 PDT 2012


Author: dvyukov
Date: Thu Jul  5 11:18:28 2012
New Revision: 159754

URL: http://llvm.org/viewvc/llvm-project?rev=159754&view=rev
Log:
tsan: Go language support

Added:
    compiler-rt/trunk/lib/tsan/go/
    compiler-rt/trunk/lib/tsan/go/buildgo.sh   (with props)
    compiler-rt/trunk/lib/tsan/go/tsan_go.cc   (with props)
Modified:
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_interface_defs.h
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_posix.cc
    compiler-rt/trunk/lib/tsan/rtl/tsan_defs.h
    compiler-rt/trunk/lib/tsan/rtl/tsan_flags.cc
    compiler-rt/trunk/lib/tsan/rtl/tsan_mutex.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/rtl/tsan_rtl_thread.cc

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator.cc?rev=159754&r1=159753&r2=159754&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator.cc Thu Jul  5 11:18:28 2012
@@ -31,13 +31,18 @@
 const u64 kBlockMagic = 0x6A6CB03ABCEBC041ull;
 
 void *InternalAlloc(uptr size) {
+  if (size + sizeof(u64) < size)
+    return 0;
   void *p = LIBC_MALLOC(size + sizeof(u64));
+  if (p == 0)
+    return 0;
   ((u64*)p)[0] = kBlockMagic;
   return (char*)p + sizeof(u64);
 }
 
 void InternalFree(void *addr) {
-  if (!addr) return;
+  if (addr == 0)
+    return;
   addr = (char*)addr - sizeof(u64);
   CHECK_EQ(((u64*)addr)[0], kBlockMagic);
   ((u64*)addr)[0] = 0;

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h?rev=159754&r1=159753&r2=159754&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h Thu Jul  5 11:18:28 2012
@@ -83,10 +83,10 @@
 void SortArray(uptr *array, uptr size);
 
 // Math
-inline bool IsPowerOfTwo(uptr x) {
+INLINE bool IsPowerOfTwo(uptr x) {
   return (x & (x - 1)) == 0;
 }
-inline uptr RoundUpTo(uptr size, uptr boundary) {
+INLINE uptr RoundUpTo(uptr size, uptr boundary) {
   CHECK(IsPowerOfTwo(boundary));
   return (size + boundary - 1) & ~(boundary - 1);
 }
@@ -95,14 +95,14 @@
 template<class T> T Max(T a, T b) { return a > b ? a : b; }
 
 // Char handling
-inline bool IsSpace(int c) {
+INLINE bool IsSpace(int c) {
   return (c == ' ') || (c == '\n') || (c == '\t') ||
          (c == '\f') || (c == '\r') || (c == '\v');
 }
-inline bool IsDigit(int c) {
+INLINE bool IsDigit(int c) {
   return (c >= '0') && (c <= '9');
 }
-inline int ToLower(int c) {
+INLINE int ToLower(int c) {
   return (c >= 'A' && c <= 'Z') ? (c + 'a' - 'A') : c;
 }
 

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_interface_defs.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_interface_defs.h?rev=159754&r1=159753&r2=159754&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_interface_defs.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_interface_defs.h Thu Jul  5 11:18:28 2012
@@ -22,10 +22,13 @@
 // FIXME find out what we need on Windows. __declspec(dllexport) ?
 # define SANITIZER_INTERFACE_ATTRIBUTE
 # define SANITIZER_WEAK_ATTRIBUTE
-#else  // _WIN32
+#elif defined(SANITIZER_GO)
+# define SANITIZER_INTERFACE_ATTRIBUTE
+# define SANITIZER_WEAK_ATTRIBUTE
+#else
 # define SANITIZER_INTERFACE_ATTRIBUTE __attribute__((visibility("default")))
 # define SANITIZER_WEAK_ATTRIBUTE  __attribute__((weak))
-#endif  // _WIN32
+#endif
 
 // __has_feature
 #if !defined(__has_feature)

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_posix.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_posix.cc?rev=159754&r1=159753&r2=159754&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_posix.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_posix.cc Thu Jul  5 11:18:28 2012
@@ -152,7 +152,11 @@
 }
 
 int Atexit(void (*function)(void)) {
+#ifndef SANITIZER_GO
   return atexit(function);
+#else
+  return 0;
+#endif
 }
 
 }  // namespace __sanitizer

Added: compiler-rt/trunk/lib/tsan/go/buildgo.sh
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/go/buildgo.sh?rev=159754&view=auto
==============================================================================
--- compiler-rt/trunk/lib/tsan/go/buildgo.sh (added)
+++ compiler-rt/trunk/lib/tsan/go/buildgo.sh Thu Jul  5 11:18:28 2012
@@ -0,0 +1,49 @@
+#!/bin/bash
+set -e
+
+SRCS="
+	tsan_go.cc
+	../rtl/tsan_clock.cc
+	../rtl/tsan_flags.cc
+	../rtl/tsan_md5.cc
+	../rtl/tsan_mutex.cc
+	../rtl/tsan_platform_linux.cc
+	../rtl/tsan_printf.cc
+	../rtl/tsan_report.cc
+	../rtl/tsan_rtl.cc
+	../rtl/tsan_rtl_mutex.cc
+	../rtl/tsan_rtl_report.cc
+	../rtl/tsan_rtl_thread.cc
+	../rtl/tsan_stat.cc
+	../rtl/tsan_suppressions.cc
+	../rtl/tsan_symbolize.cc
+	../rtl/tsan_sync.cc
+	../../sanitizer_common/sanitizer_allocator.cc
+	../../sanitizer_common/sanitizer_common.cc
+	../../sanitizer_common/sanitizer_libc.cc
+	../../sanitizer_common/sanitizer_linux.cc
+	../../sanitizer_common/sanitizer_posix.cc
+	../../sanitizer_common/sanitizer_printf.cc
+	../../sanitizer_common/sanitizer_symbolizer.cc
+"
+
+#ASMS="../rtl/tsan_rtl_amd64.S"
+
+rm -f gotsan.cc
+for F in $SRCS; do
+	cat $F >> gotsan.cc
+done
+
+CFLAGS=" -I../rtl -I../.. -I../../sanitizer_common -fPIC -g -Wall -Werror -ffreestanding -fno-exceptions -DTSAN_GO -DSANITIZER_GO"
+if [ "$DEBUG" == "" ]; then
+	CFLAGS+=" -DTSAN_DEBUG=0 -O3 -fno-omit-frame-pointer"
+else
+	CFLAGS+=" -DTSAN_DEBUG=1 -g"
+fi
+
+echo gcc gotsan.cc -S -o tmp.s $CFLAGS
+gcc gotsan.cc -S -o tmp.s $CFLAGS
+cat tmp.s $ASMS > gotsan.s
+echo as gotsan.s -o gotsan.syso
+as gotsan.s -o gotsan.syso
+

Propchange: compiler-rt/trunk/lib/tsan/go/buildgo.sh
------------------------------------------------------------------------------
    svn:eol-style = LF

Propchange: compiler-rt/trunk/lib/tsan/go/buildgo.sh
------------------------------------------------------------------------------
    svn:executable = *

Added: compiler-rt/trunk/lib/tsan/go/tsan_go.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/go/tsan_go.cc?rev=159754&view=auto
==============================================================================
--- compiler-rt/trunk/lib/tsan/go/tsan_go.cc (added)
+++ compiler-rt/trunk/lib/tsan/go/tsan_go.cc Thu Jul  5 11:18:28 2012
@@ -0,0 +1,193 @@
+//===-- tsan_go.cc --------------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// ThreadSanitizer runtime for Go language.
+//
+//===----------------------------------------------------------------------===//
+
+#include "tsan_rtl.h"
+#include "tsan_symbolize.h"
+#include "sanitizer_common/sanitizer_common.h"
+#include <stdlib.h>
+
+namespace __tsan {
+
+struct ThreadStatePlaceholder {
+  uptr opaque[sizeof(ThreadState) / sizeof(uptr) + kCacheLineSize];
+};
+
+static ThreadStatePlaceholder *threads;
+
+void InitializeInterceptors() {
+}
+
+void InitializeDynamicAnnotations() {
+}
+
+bool IsExpectedReport(uptr addr, uptr size) {
+  return false;
+}
+
+void internal_start_thread(void(*func)(void*), void *arg) {
+}
+
+ReportStack *SymbolizeCodeAddr2Line(uptr addr) {
+  return NewReportStackEntry(addr);
+}
+
+ReportStack *SymbolizeDataAddr2Line(uptr addr) {
+  return 0;
+}
+
+void *internal_alloc(MBlockType typ, uptr sz) {
+  return InternalAlloc(sz);
+}
+
+void internal_free(void *p) {
+  InternalFree(p);
+}
+
+extern "C" {
+
+enum Tsan1EventType {
+	NOOP,               // Should not appear.
+	READ,               // {tid, pc, addr, size}
+	WRITE,              // {tid, pc, addr, size}
+	READER_LOCK,        // {tid, pc, lock, 0}
+	WRITER_LOCK,        // {tid, pc, lock, 0}
+	UNLOCK,             // {tid, pc, lock, 0}
+	UNLOCK_OR_INIT,     // {tid, pc, lock, 0}
+	LOCK_CREATE,        // {tid, pc, lock, 0}
+	LOCK_DESTROY,       // {tid, pc, lock, 0}
+	THR_CREATE_BEFORE,  // Parent thread's event. {tid, pc, 0, 0}
+	THR_CREATE_AFTER,   // Parent thread's event. {tid, 0, 0, child_tid}/* 10 */
+	THR_START,          // Child thread's event {tid, CallStack, 0, parent_tid}
+	THR_FIRST_INSN,     // Used only by valgrind.
+	THR_END,            // {tid, 0, 0, 0}
+	THR_JOIN_AFTER,     // {tid, pc, joined_tid}
+	THR_STACK_TOP,      // {tid, pc, stack_top, stack_size_if_known}
+	RTN_EXIT,           // {tid, 0, 0, 0}
+	RTN_CALL,           // {tid, pc, 0, 0}
+	SBLOCK_ENTER,       // {tid, pc, 0, 0}
+	SIGNAL,             // {tid, pc, obj, 0}
+	WAIT,               // {tid, pc, obj, 0} /* 20 */
+	CYCLIC_BARRIER_INIT,         // {tid, pc, obj, n}
+	CYCLIC_BARRIER_WAIT_BEFORE,  // {tid, pc, obj, 0}
+	CYCLIC_BARRIER_WAIT_AFTER,   // {tid, pc, obj, 0}
+	PCQ_CREATE,         // {tid, pc, pcq_addr, 0}
+	PCQ_DESTROY,        // {tid, pc, pcq_addr, 0}
+	PCQ_PUT,            // {tid, pc, pcq_addr, 0}
+	PCQ_GET,            // {tid, pc, pcq_addr, 0}
+	STACK_MEM_DIE,      // deprecated.
+	MALLOC,             // {tid, pc, addr, size}
+	FREE,               // {tid, pc, addr, 0} /* 30 */
+	MMAP,               // {tid, pc, addr, size}
+	MUNMAP,             // {tid, pc, addr, size}
+	PUBLISH_RANGE,      // may be deprecated later.
+	UNPUBLISH_RANGE,    // deprecated. TODO(kcc): get rid of this.
+	HB_LOCK,            // {tid, pc, addr, 0}
+	NON_HB_LOCK,        // {tid, pc, addr, 0}
+	IGNORE_READS_BEG,   // {tid, pc, 0, 0}
+	IGNORE_READS_END,   // {tid, pc, 0, 0}
+	IGNORE_WRITES_BEG,  // {tid, pc, 0, 0}
+	IGNORE_WRITES_END,  // {tid, pc, 0, 0}
+	SET_THREAD_NAME,    // {tid, pc, name_str, 0}
+	SET_LOCK_NAME,      // {tid, pc, lock, lock_name_str}
+	TRACE_MEM,          // {tid, pc, addr, 0}
+	EXPECT_RACE,        // {tid, descr_str, ptr, size}
+	BENIGN_RACE,        // {tid, descr_str, ptr, size}
+	EXPECT_RACE_BEGIN,  // {tid, pc, 0, 0}
+	EXPECT_RACE_END,    // {tid, pc, 0, 0}
+	VERBOSITY,          // Used for debugging.
+	STACK_TRACE,        // {tid, pc, 0, 0}, for debugging.
+	FLUSH_STATE,        // {tid, pc, 0, 0}
+	PC_DESCRIPTION,     // {0, pc, descr_str, 0}, for ts_offline.
+	PRINT_MESSAGE,      // {tid, pc, message_str, 0}, for ts_offline.
+	FLUSH_EXPECTED_RACES,  // {0, 0, 0, 0}
+	LAST_EVENT          // Should not appear.
+};
+
+void __tsan_init() {
+  threads = (ThreadStatePlaceholder*)internal_alloc(MBlockThreadContex,
+      kMaxTid * sizeof(ThreadStatePlaceholder));
+  //!!! internal_memset(threads, 0, kMaxTid * sizeof(ThreadStatePlaceholder));
+  ThreadState *thr = (ThreadState*)&threads[0];
+  thr->in_rtl++;
+  Initialize(thr);
+  thr->in_rtl--;
+}
+
+void __tsan_fini() {
+  // FIXME: Not necessary thread 0.
+  ThreadState *thr = (ThreadState*)&threads[0];
+  thr->in_rtl++;
+  int res = Finalize(thr);
+  thr->in_rtl--;
+  exit(res);  
+}
+
+void __tsan_event(int typ, int tid, void *pc, void *addr, int info) {
+  //if (typ != READ && typ != WRITE && typ != SBLOCK_ENTER)
+  //  Printf("typ=%d tid=%d pc=%p addr=%p info=%d\n", typ, tid, pc, addr, info);
+  ThreadState *thr = (ThreadState*)&threads[tid];
+  switch (typ) {
+  case READ:
+    MemoryAccess(thr, (uptr)pc, (uptr)addr, 0, false);
+    break;
+  case WRITE:
+    MemoryAccess(thr, (uptr)pc, (uptr)addr, 0, true);
+    break;
+  case RTN_EXIT:
+    FuncExit(thr);
+    break;
+  case RTN_CALL:
+    FuncEntry(thr, (uptr)pc);
+    break;
+  case SBLOCK_ENTER:
+    break;
+  case SIGNAL:
+    thr->in_rtl++;
+    Release(thr, (uptr)pc, (uptr)addr);
+    thr->in_rtl--;
+    break;
+  case WAIT:
+    thr->in_rtl++;
+    Acquire(thr, (uptr)pc, (uptr)addr);
+    thr->in_rtl--;
+    break;
+  case MALLOC:
+    thr->in_rtl++;
+    MemoryResetRange(thr, (uptr)pc, (uptr)addr, (uptr)info);
+    thr->in_rtl--;
+    break;
+  case FREE:
+    break;
+  case THR_START: {
+    //Printf("typ=%d tid=%d pc=%p addr=%p info=%d\n", typ, tid, pc, addr, info);
+    if (tid == 0)
+      return;
+    ThreadState *parent = (ThreadState*)&threads[info];
+    thr->in_rtl++;
+    parent->in_rtl++;
+    int tid2 = ThreadCreate(parent, (uptr)pc, 0, true);
+    CHECK_EQ(tid2, tid);
+    ThreadStart(thr, tid2);
+    parent->in_rtl--;
+    thr->in_rtl--;
+    break;
+  }
+  default:
+    thr->in_rtl++;
+    Printf("Event: typ=%d thr=%d\n", typ, tid);
+    thr->in_rtl--;
+  }
+}
+
+}  // extern "C"
+}  // namespace __tsan

Propchange: compiler-rt/trunk/lib/tsan/go/tsan_go.cc
------------------------------------------------------------------------------
    svn:eol-style = LF

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_defs.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_defs.h?rev=159754&r1=159753&r2=159754&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_defs.h (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_defs.h Thu Jul  5 11:18:28 2012
@@ -28,7 +28,11 @@
 const unsigned kMaxTid = 1 << kTidBits;
 const unsigned kMaxTidInClock = kMaxTid * 2;  // This includes msb 'freed' bit.
 const int kClkBits = 43;
+#ifdef TSAN_GO
+const int kShadowStackSize = 8 * 1024;
+#else
 const int kShadowStackSize = 1024;
+#endif
 
 #ifdef TSAN_SHADOW_COUNT
 # if TSAN_SHADOW_COUNT == 2 \
@@ -119,9 +123,7 @@
 
 struct MD5Hash {
   u64 hash[2];
-  bool operator==(const MD5Hash &other) const {
-    return hash[0] == other.hash[0] && hash[1] == other.hash[1];
-  }
+  bool operator==(const MD5Hash &other) const;
 };
 
 MD5Hash md5_hash(const void *data, uptr size);

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_flags.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_flags.cc?rev=159754&r1=159753&r2=159754&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_flags.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_flags.cc Thu Jul  5 11:18:28 2012
@@ -53,7 +53,6 @@
   f->running_on_valgrind = false;
   f->use_internal_symbolizer = false;
 
-
   // Let a frontend override.
   OverrideFlags(f);
 

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_mutex.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_mutex.cc?rev=159754&r1=159753&r2=159754&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_mutex.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_mutex.cc Thu Jul  5 11:18:28 2012
@@ -198,7 +198,7 @@
 }
 
 void Mutex::Lock() {
-#if TSAN_DEBUG
+#if TSAN_DEBUG && !TSAN_GO
   cur_thread()->deadlock_detector.Lock(type_);
 #endif
   uptr cmp = kUnlocked;
@@ -223,13 +223,13 @@
   uptr prev = atomic_fetch_sub(&state_, kWriteLock, memory_order_release);
   (void)prev;
   DCHECK_NE(prev & kWriteLock, 0);
-#if TSAN_DEBUG
+#if TSAN_DEBUG && !TSAN_GO
   cur_thread()->deadlock_detector.Unlock(type_);
 #endif
 }
 
 void Mutex::ReadLock() {
-#if TSAN_DEBUG
+#if TSAN_DEBUG && !TSAN_GO
   cur_thread()->deadlock_detector.Lock(type_);
 #endif
   uptr prev = atomic_fetch_add(&state_, kReadLock, memory_order_acquire);
@@ -251,7 +251,7 @@
   (void)prev;
   DCHECK_EQ(prev & kWriteLock, 0);
   DCHECK_GT(prev & ~kWriteLock, 0);
-#if TSAN_DEBUG
+#if TSAN_DEBUG && !TSAN_GO
   cur_thread()->deadlock_detector.Unlock(type_);
 #endif
 }

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=159754&r1=159753&r2=159754&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_platform.h (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_platform.h Thu Jul  5 11:18:28 2012
@@ -21,26 +21,30 @@
 #if __LP64__
 namespace __tsan {
 
+#if defined(TSAN_GO)
+static const uptr kLinuxAppMemBeg = 0x000000000000ULL;
+static const uptr kLinuxAppMemEnd = 0x00fcffffffffULL;
+static const uptr kLinuxShadowMsk = 0x100000000000ULL;
 // 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'.
-#if defined(TSAN_COMPAT_SHADOW) && TSAN_COMPAT_SHADOW
-
+#elif defined(TSAN_COMPAT_SHADOW) && TSAN_COMPAT_SHADOW
 static const uptr kLinuxAppMemBeg = 0x2a0000000000ULL;
 static const uptr kLinuxAppMemEnd = 0x7fffffffffffULL;
-
 #else
-
 static const uptr kLinuxAppMemBeg = 0x7ef000000000ULL;
 static const uptr kLinuxAppMemEnd = 0x7fffffffffffULL;
-
 #endif
 
 static const uptr kLinuxAppMemMsk = 0x7c0000000000ULL;
 
 // This has to be a macro to allow constant initialization of constants below.
+#ifndef TSAN_GO
 #define MemToShadow(addr) \
     (((addr) & ~(kLinuxAppMemMsk | (kShadowCell - 1))) * kShadowCnt)
+#else
+#define MemToShadow(addr) (((addr) * kShadowCnt) | kLinuxShadowMsk)
+#endif
 
 static const uptr kLinuxShadowBeg = MemToShadow(kLinuxAppMemBeg);
 static const uptr kLinuxShadowEnd =
@@ -56,7 +60,9 @@
 
 static inline uptr ShadowToMem(uptr shadow) {
   CHECK(IsShadowMem(shadow));
-#if defined(TSAN_COMPAT_SHADOW) && TSAN_COMPAT_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

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=159754&r1=159753&r2=159754&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_platform_linux.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_platform_linux.cc Thu Jul  5 11:18:28 2012
@@ -51,8 +51,7 @@
 
 namespace __tsan {
 
-static uptr g_tls_size;
-
+#ifndef TSAN_GO
 ScopedInRtl::ScopedInRtl()
     : thr_(cur_thread()) {
   in_rtl_ = thr_->in_rtl;
@@ -65,6 +64,13 @@
   errno = errno_;
   CHECK_EQ(in_rtl_, thr_->in_rtl);
 }
+#else
+ScopedInRtl::ScopedInRtl() {
+}
+
+ScopedInRtl::~ScopedInRtl() {
+}
+#endif
 
 uptr GetShadowMemoryConsumption() {
   return 0;
@@ -76,6 +82,7 @@
           MADV_DONTNEED);
 }
 
+#ifndef TSAN_GO
 static void ProtectRange(uptr beg, uptr end) {
   ScopedInRtl in_rtl;
   CHECK_LE(beg, end);
@@ -87,12 +94,9 @@
     Die();
   }
 }
+#endif
 
 void InitializeShadowMemory() {
-  const uptr kClosedLowBeg  = 0x200000;
-  const uptr kClosedLowEnd  = kLinuxShadowBeg - 1;
-  const uptr kClosedMidBeg = kLinuxShadowEnd + 1;
-  const uptr kClosedMidEnd = kLinuxAppMemBeg - 1;
   uptr shadow = (uptr)MmapFixedNoReserve(kLinuxShadowBeg,
     kLinuxShadowEnd - kLinuxShadowBeg);
   if (shadow != kLinuxShadowBeg) {
@@ -101,21 +105,32 @@
                "to link with -pie.\n");
     Die();
   }
+#ifndef TSAN_GO
+  const uptr kClosedLowBeg  = 0x200000;
+  const uptr kClosedLowEnd  = kLinuxShadowBeg - 1;
+  const uptr kClosedMidBeg = kLinuxShadowEnd + 1;
+  const uptr kClosedMidEnd = kLinuxAppMemBeg - 1;
   ProtectRange(kClosedLowBeg, kClosedLowEnd);
   ProtectRange(kClosedMidBeg, kClosedMidEnd);
+#endif
+#ifndef TSAN_GO
   DPrintf("kClosedLow   %zx-%zx (%zuGB)\n",
       kClosedLowBeg, kClosedLowEnd, (kClosedLowEnd - kClosedLowBeg) >> 30);
+#endif
   DPrintf("kLinuxShadow %zx-%zx (%zuGB)\n",
       kLinuxShadowBeg, kLinuxShadowEnd,
       (kLinuxShadowEnd - kLinuxShadowBeg) >> 30);
+#ifndef TSAN_GO
   DPrintf("kClosedMid   %zx-%zx (%zuGB)\n",
       kClosedMidBeg, kClosedMidEnd, (kClosedMidEnd - kClosedMidBeg) >> 30);
+#endif
   DPrintf("kLinuxAppMem %zx-%zx (%zuGB)\n",
       kLinuxAppMemBeg, kLinuxAppMemEnd,
       (kLinuxAppMemEnd - kLinuxAppMemBeg) >> 30);
   DPrintf("stack        %zx\n", (uptr)&shadow);
 }
 
+#ifndef TSAN_GO
 static void CheckPIE() {
   // Ensure that the binary is indeed compiled with -pie.
   ProcessMaps proc_maps;
@@ -133,6 +148,8 @@
   }
 }
 
+static uptr g_tls_size;
+
 #ifdef __i386__
 # define INTERNAL_FUNCTION __attribute__((regparm(3), stdcall))
 #else
@@ -152,6 +169,7 @@
   get_tls(&tls_size, &tls_align);
   return tls_size;
 }
+#endif  // #ifndef TSAN_GO
 
 const char *InitializePlatform() {
   void *p = 0;
@@ -164,8 +182,10 @@
     setrlimit(RLIMIT_CORE, (rlimit*)&lim);
   }
 
+#ifndef TSAN_GO
   CheckPIE();
   g_tls_size = (uptr)InitTlsSize();
+#endif
   return getenv("TSAN_OPTIONS");
 }
 
@@ -174,11 +194,16 @@
 }
 
 uptr GetTlsSize() {
+#ifndef TSAN_GO
   return g_tls_size;
+#else
+  return 0;
+#endif
 }
 
 void GetThreadStackAndTls(bool main, uptr *stk_addr, uptr *stk_size,
                           uptr *tls_addr, uptr *tls_size) {
+#ifndef TSAN_GO
   arch_prctl(ARCH_GET_FS, tls_addr);
   *tls_addr -= g_tls_size;
   *tls_size = g_tls_size;
@@ -197,6 +222,13 @@
       *tls_addr = *stk_addr + *stk_size;
     }
   }
+#else
+  *stk_addr = 0;
+  *stk_size = 0;
+  *tls_addr = 0;
+  *tls_size = 0;
+#endif
 }
 
+
 }  // namespace __tsan

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=159754&r1=159753&r2=159754&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.cc Thu Jul  5 11:18:28 2012
@@ -31,7 +31,9 @@
 
 namespace __tsan {
 
+#ifndef TSAN_GO
 THREADLOCAL char cur_thread_placeholder[sizeof(ThreadState)] ALIGNED(64);
+#endif
 static char ctx_placeholder[sizeof(Context)] ALIGNED(64);
 
 static Context *ctx;
@@ -218,7 +220,7 @@
   return failed ? flags()->exitcode : 0;
 }
 
-static void TraceSwitch(ThreadState *thr) {
+void TraceSwitch(ThreadState *thr) {
   thr->nomalloc++;
   ScopedInRtl in_rtl;
   Lock l(&thr->trace.mtx);
@@ -229,6 +231,7 @@
   thr->nomalloc--;
 }
 
+#ifndef TSAN_GO
 extern "C" void __tsan_trace_switch() {
   TraceSwitch(cur_thread());
 }
@@ -236,6 +239,7 @@
 extern "C" void __tsan_report_race() {
   ReportRace(cur_thread());
 }
+#endif
 
 ALWAYS_INLINE
 static Shadow LoadShadow(u64 *p) {
@@ -259,7 +263,11 @@
   thr->racy_state[0] = cur.raw();
   thr->racy_state[1] = old.raw();
   thr->racy_shadow_addr = shadow_mem;
+#ifndef TSAN_GO
   HACKY_CALL(__tsan_report_race);
+#else
+  ReportRace(thr);
+#endif
 }
 
 static inline bool BothReads(Shadow s, int kAccessIsWrite) {
@@ -477,6 +485,10 @@
     thr->fast_state.ClearIgnoreBit();
 }
 
+bool MD5Hash::operator==(const MD5Hash &other) const {
+  return hash[0] == other.hash[0] && hash[1] == other.hash[1];
+}
+
 #if TSAN_DEBUG
 void build_consistency_debug() {}
 #else
@@ -501,5 +513,7 @@
 
 }  // namespace __tsan
 
+#ifndef TSAN_GO
 // Must be included in this file to make sure everything is inlined.
 #include "tsan_interface_inl.h"
+#endif

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=159754&r1=159753&r2=159754&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.h (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.h Thu Jul  5 11:18:28 2012
@@ -254,11 +254,13 @@
 };
 
 Context *CTX();
-extern THREADLOCAL char cur_thread_placeholder[];
 
+#ifndef TSAN_GO
+extern THREADLOCAL char cur_thread_placeholder[];
 INLINE ThreadState *cur_thread() {
   return reinterpret_cast<ThreadState *>(&cur_thread_placeholder);
 }
+#endif
 
 enum ThreadStatus {
   ThreadStatusInvalid,   // Non-existent thread, data is invalid.
@@ -457,12 +459,19 @@
 #define HACKY_CALL(f) f()
 #endif
 
+void TraceSwitch(ThreadState *thr);
+
 extern "C" void __tsan_trace_switch();
 void ALWAYS_INLINE INLINE TraceAddEvent(ThreadState *thr, u64 epoch,
                                         EventType typ, uptr addr) {
   StatInc(thr, StatEvents);
-  if (UNLIKELY((epoch % kTracePartSize) == 0))
+  if (UNLIKELY((epoch % kTracePartSize) == 0)) {
+#ifndef TSAN_GO
     HACKY_CALL(__tsan_trace_switch);
+#else
+    TraceSwitch(thr);
+#endif
+  }
   Event *evp = &thr->trace.events[epoch % kTraceSize];
   Event ev = (u64)addr | ((u64)typ << 61);
   *evp = ev;

Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_thread.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_thread.cc?rev=159754&r1=159753&r2=159754&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_thread.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_thread.cc Thu Jul  5 11:18:28 2012
@@ -142,18 +142,22 @@
   GetThreadStackAndTls(tid == 0, &stk_addr, &stk_size, &tls_addr, &tls_size);
 
   if (tid) {
-    MemoryResetRange(thr, /*pc=*/ 1, stk_addr, stk_size);
+    if (stk_addr && stk_size) {
+      MemoryResetRange(thr, /*pc=*/ 1, stk_addr, stk_size);
+    }
 
-    // Check that the thr object is in tls;
-    const uptr thr_beg = (uptr)thr;
-    const uptr thr_end = (uptr)thr + sizeof(*thr);
-    CHECK_GE(thr_beg, tls_addr);
-    CHECK_LE(thr_beg, tls_addr + tls_size);
-    CHECK_GE(thr_end, tls_addr);
-    CHECK_LE(thr_end, tls_addr + tls_size);
-    // Since the thr object is huge, skip it.
-    MemoryResetRange(thr, /*pc=*/ 2, tls_addr, thr_beg - tls_addr);
-    MemoryResetRange(thr, /*pc=*/ 2, thr_end, tls_addr + tls_size - thr_end);
+    if (tls_addr && tls_size) {
+      // Check that the thr object is in tls;
+      const uptr thr_beg = (uptr)thr;
+      const uptr thr_end = (uptr)thr + sizeof(*thr);
+      CHECK_GE(thr_beg, tls_addr);
+      CHECK_LE(thr_beg, tls_addr + tls_size);
+      CHECK_GE(thr_end, tls_addr);
+      CHECK_LE(thr_end, tls_addr + tls_size);
+      // Since the thr object is huge, skip it.
+      MemoryResetRange(thr, /*pc=*/ 2, tls_addr, thr_beg - tls_addr);
+      MemoryResetRange(thr, /*pc=*/ 2, thr_end, tls_addr + tls_size - thr_end);
+    }
   }
 
   Lock l(&CTX()->thread_mtx);





More information about the llvm-commits mailing list