[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