<div dir="ltr">Nice! <div>Please also update the docs (where relevant). </div><div>Do we need to remove -PIE from the driver now? </div></div><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Oct 24, 2014 at 10:07 AM, Dmitry Vyukov <span dir="ltr"><<a href="mailto:dvyukov@google.com" target="_blank">dvyukov@google.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: dvyukov<br>
Date: Fri Oct 24 12:07:29 2014<br>
New Revision: 220571<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=220571&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=220571&view=rev</a><br>
Log:<br>
tsan: support mmap(MAP_32BIT)<br>
Allow user memory in the first TB of address space.<br>
This also enabled non-pie binaries and freebsd.<br>
Fixes issue:<br>
<a href="https://code.google.com/p/thread-sanitizer/issues/detail?id=5" target="_blank">https://code.google.com/p/thread-sanitizer/issues/detail?id=5</a><br>
<br>
<br>
Added:<br>
compiler-rt/trunk/test/tsan/map32bit.cc<br>
Modified:<br>
compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator.h<br>
compiler-rt/trunk/lib/tsan/rtl/tsan_platform.h<br>
compiler-rt/trunk/lib/tsan/rtl/tsan_platform_linux.cc<br>
compiler-rt/trunk/lib/tsan/rtl/tsan_platform_mac.cc<br>
compiler-rt/trunk/lib/tsan/rtl/tsan_platform_windows.cc<br>
compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.cc<br>
compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.h<br>
compiler-rt/trunk/lib/tsan/tests/unit/tsan_mman_test.cc<br>
<br>
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator.h?rev=220571&r1=220570&r2=220571&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator.h?rev=220571&r1=220570&r2=220571&view=diff</a><br>
==============================================================================<br>
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator.h (original)<br>
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator.h Fri Oct 24 12:07:29 2014<br>
@@ -461,6 +461,11 @@ class SizeClassAllocator64 {<br>
}<br>
}<br>
<br>
+ static uptr AdditionalSize() {<br>
+ return RoundUpTo(sizeof(RegionInfo) * kNumClassesRounded,<br>
+ GetPageSizeCached());<br>
+ }<br>
+<br>
typedef SizeClassMap SizeClassMapT;<br>
static const uptr kNumClasses = SizeClassMap::kNumClasses;<br>
static const uptr kNumClassesRounded = SizeClassMap::kNumClassesRounded;<br>
@@ -490,11 +495,6 @@ class SizeClassAllocator64 {<br>
};<br>
COMPILER_CHECK(sizeof(RegionInfo) >= kCacheLineSize);<br>
<br>
- static uptr AdditionalSize() {<br>
- return RoundUpTo(sizeof(RegionInfo) * kNumClassesRounded,<br>
- GetPageSizeCached());<br>
- }<br>
-<br>
RegionInfo *GetRegionInfo(uptr class_id) {<br>
CHECK_LT(class_id, kNumClasses);<br>
RegionInfo *regions = reinterpret_cast<RegionInfo*>(kSpaceBeg + kSpaceSize);<br>
<br>
Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_platform.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_platform.h?rev=220571&r1=220570&r2=220571&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_platform.h?rev=220571&r1=220570&r2=220571&view=diff</a><br>
==============================================================================<br>
--- compiler-rt/trunk/lib/tsan/rtl/tsan_platform.h (original)<br>
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_platform.h Fri Oct 24 12:07:29 2014<br>
@@ -12,124 +12,223 @@<br>
// Platform-specific code.<br>
//===----------------------------------------------------------------------===//<br>
<br>
+#ifndef TSAN_PLATFORM_H<br>
+#define TSAN_PLATFORM_H<br>
+<br>
+#if !defined(__LP64__) && !defined(_WIN64)<br>
+# error "Only 64-bit is supported"<br>
+#endif<br>
+<br>
+#include "tsan_defs.h"<br>
+#include "tsan_trace.h"<br>
+<br>
+namespace __tsan {<br>
+<br>
+#if !defined(TSAN_GO)<br>
+<br>
/*<br>
-C++ linux memory layout:<br>
-0000 0000 0000 - 03c0 0000 0000: protected<br>
-03c0 0000 0000 - 1000 0000 0000: shadow<br>
-1000 0000 0000 - 3000 0000 0000: protected<br>
+C/C++ on linux and freebsd<br>
+0000 0000 1000 - 0100 0000 0000: main binary and/or MAP_32BIT mappings<br>
+0100 0000 0000 - 0200 0000 0000: -<br>
+0200 0000 0000 - 1000 0000 0000: shadow<br>
+1000 0000 0000 - 3000 0000 0000: -<br>
3000 0000 0000 - 4000 0000 0000: metainfo (memory blocks and sync objects)<br>
-4000 0000 0000 - 6000 0000 0000: protected<br>
+4000 0000 0000 - 6000 0000 0000: -<br>
6000 0000 0000 - 6200 0000 0000: traces<br>
6200 0000 0000 - 7d00 0000 0000: -<br>
7d00 0000 0000 - 7e00 0000 0000: heap<br>
-7e00 0000 0000 - 7fff ffff ffff: modules and main thread stack<br>
+7e00 0000 0000 - 7e80 0000 0000: -<br>
+7e80 0000 0000 - 8000 0000 0000: modules and main thread stack<br>
+*/<br>
<br>
-Go linux and darwin memory layout:<br>
-0000 0000 0000 - 0000 1000 0000: executable<br>
-0000 1000 0000 - 00f8 0000 0000: -<br>
+const uptr kMetaShadowBeg = 0x300000000000ull;<br>
+const uptr kMetaShadowEnd = 0x400000000000ull;<br>
+const uptr kTraceMemBeg = 0x600000000000ull;<br>
+const uptr kTraceMemEnd = 0x620000000000ull;<br>
+const uptr kShadowBeg = 0x020000000000ull;<br>
+const uptr kShadowEnd = 0x100000000000ull;<br>
+const uptr kHeapMemBeg = 0x7d0000000000ull;<br>
+const uptr kHeapMemEnd = 0x7e0000000000ull;<br>
+const uptr kLoAppMemBeg = 0x000000001000ull;<br>
+const uptr kLoAppMemEnd = 0x010000000000ull;<br>
+const uptr kHiAppMemBeg = 0x7e8000000000ull;<br>
+const uptr kHiAppMemEnd = 0x800000000000ull;<br>
+const uptr kAppMemMsk = 0x7c0000000000ull;<br>
+const uptr kAppMemXor = 0x020000000000ull;<br>
+<br>
+ALWAYS_INLINE<br>
+bool IsAppMem(uptr mem) {<br>
+ return (mem >= kHeapMemBeg && mem < kHeapMemEnd) ||<br>
+ (mem >= kLoAppMemBeg && mem < kLoAppMemEnd) ||<br>
+ (mem >= kHiAppMemBeg && mem < kHiAppMemEnd);<br>
+}<br>
+<br>
+ALWAYS_INLINE<br>
+bool IsShadowMem(uptr mem) {<br>
+ return mem >= kShadowBeg && mem <= kShadowEnd;<br>
+}<br>
+<br>
+ALWAYS_INLINE<br>
+bool IsMetaMem(uptr mem) {<br>
+ return mem >= kMetaShadowBeg && mem <= kMetaShadowEnd;<br>
+}<br>
+<br>
+ALWAYS_INLINE<br>
+uptr MemToShadow(uptr x) {<br>
+ DCHECK(IsAppMem(x));<br>
+ return (((x) & ~(kAppMemMsk | (kShadowCell - 1)))<br>
+ ^ kAppMemXor) * kShadowCnt;<br>
+}<br>
+<br>
+ALWAYS_INLINE<br>
+u32 *MemToMeta(uptr x) {<br>
+ DCHECK(IsAppMem(x));<br>
+ return (u32*)(((((x) & ~(kAppMemMsk | (kMetaShadowCell - 1)))<br>
+ ^ kAppMemXor) / kMetaShadowCell * kMetaShadowSize) | kMetaShadowBeg);<br>
+}<br>
+<br>
+ALWAYS_INLINE<br>
+uptr ShadowToMem(uptr s) {<br>
+ CHECK(IsShadowMem(s));<br>
+ if (s >= MemToShadow(kLoAppMemBeg) && s <= MemToShadow(kLoAppMemEnd - 1))<br>
+ return (s / kShadowCnt) ^ kAppMemXor;<br>
+ else<br>
+ return ((s / kShadowCnt) ^ kAppMemXor) | kAppMemMsk;<br>
+}<br>
+<br>
+static USED uptr UserRegions[] = {<br>
+ kLoAppMemBeg, kLoAppMemEnd,<br>
+ kHiAppMemBeg, kHiAppMemEnd,<br>
+ kHeapMemBeg, kHeapMemEnd,<br>
+};<br>
+<br>
+#elif defined(TSAN_GO) && !SANITIZER_WINDOWS<br>
+<br>
+/* Go on linux, darwin and freebsd<br>
+0000 0000 1000 - 0000 1000 0000: executable<br>
+0000 1000 0000 - 00c0 0000 0000: -<br>
00c0 0000 0000 - 00e0 0000 0000: heap<br>
-00e0 0000 0000 - 1000 0000 0000: -<br>
-1000 0000 0000 - 1380 0000 0000: shadow<br>
-1460 0000 0000 - 2000 0000 0000: -<br>
+00e0 0000 0000 - 2000 0000 0000: -<br>
+2000 0000 0000 - 2380 0000 0000: shadow<br>
+2380 0000 0000 - 3000 0000 0000: -<br>
3000 0000 0000 - 4000 0000 0000: metainfo (memory blocks and sync objects)<br>
4000 0000 0000 - 6000 0000 0000: -<br>
6000 0000 0000 - 6200 0000 0000: traces<br>
-6200 0000 0000 - 7fff ffff ffff: -<br>
+6200 0000 0000 - 8000 0000 0000: -<br>
+*/<br>
+<br>
+const uptr kMetaShadowBeg = 0x300000000000ull;<br>
+const uptr kMetaShadowEnd = 0x400000000000ull;<br>
+const uptr kTraceMemBeg = 0x600000000000ull;<br>
+const uptr kTraceMemEnd = 0x620000000000ull;<br>
+const uptr kShadowBeg = 0x200000000000ull;<br>
+const uptr kShadowEnd = 0x238000000000ull;<br>
+const uptr kAppMemBeg = 0x000000001000ull;<br>
+const uptr kAppMemEnd = 0x00e000000000ull;<br>
+<br>
+ALWAYS_INLINE<br>
+bool IsAppMem(uptr mem) {<br>
+ return mem >= kAppMemBeg && mem < kAppMemEnd;<br>
+}<br>
<br>
-Go windows memory layout:<br>
-0000 0000 0000 - 0000 1000 0000: executable<br>
+ALWAYS_INLINE<br>
+bool IsShadowMem(uptr mem) {<br>
+ return mem >= kShadowBeg && mem <= kShadowEnd;<br>
+}<br>
+<br>
+ALWAYS_INLINE<br>
+bool IsMetaMem(uptr mem) {<br>
+ return mem >= kMetaShadowBeg && mem <= kMetaShadowEnd;<br>
+}<br>
+<br>
+ALWAYS_INLINE<br>
+uptr MemToShadow(uptr x) {<br>
+ DCHECK(IsAppMem(x));<br>
+ return ((x & ~(kShadowCell - 1)) * kShadowCnt) | kShadowBeg;<br>
+}<br>
+<br>
+ALWAYS_INLINE<br>
+u32 *MemToMeta(uptr x) {<br>
+ DCHECK(IsAppMem(x));<br>
+ return (u32*)(((x & ~(kMetaShadowCell - 1)) / \<br>
+ kMetaShadowCell * kMetaShadowSize) | kMetaShadowBeg);<br>
+}<br>
+<br>
+ALWAYS_INLINE<br>
+uptr ShadowToMem(uptr s) {<br>
+ CHECK(IsShadowMem(s));<br>
+ return (s & ~kShadowBeg) / kShadowCnt;<br>
+}<br>
+<br>
+static USED uptr UserRegions[] = {<br>
+ kAppMemBeg, kAppMemEnd,<br>
+};<br>
+<br>
+#elif defined(TSAN_GO) && SANITIZER_WINDOWS<br>
+<br>
+/* Go on windows<br>
+0000 0000 1000 - 0000 1000 0000: executable<br>
0000 1000 0000 - 00f8 0000 0000: -<br>
00c0 0000 0000 - 00e0 0000 0000: heap<br>
00e0 0000 0000 - 0100 0000 0000: -<br>
-0100 0000 0000 - 0560 0000 0000: shadow<br>
+0100 0000 0000 - 0380 0000 0000: shadow<br>
+0380 0000 0000 - 0560 0000 0000: -<br>
0560 0000 0000 - 0760 0000 0000: traces<br>
0760 0000 0000 - 07d0 0000 0000: metainfo (memory blocks and sync objects)<br>
-07d0 0000 0000 - 07ff ffff ffff: -<br>
+07d0 0000 0000 - 8000 0000 0000: -<br>
*/<br>
<br>
-#ifndef TSAN_PLATFORM_H<br>
-#define TSAN_PLATFORM_H<br>
-<br>
-#include "tsan_defs.h"<br>
-#include "tsan_trace.h"<br>
-<br>
-#if defined(__LP64__) || defined(_WIN64)<br>
-namespace __tsan {<br>
-<br>
-#if defined(TSAN_GO)<br>
-static const uptr kLinuxAppMemBeg = 0x000000000000ULL;<br>
-static const uptr kLinuxAppMemEnd = 0x04dfffffffffULL;<br>
-# if SANITIZER_WINDOWS<br>
-static const uptr kLinuxShadowMsk = 0x010000000000ULL;<br>
-static const uptr kMetaShadow = 0x076000000000ULL;<br>
-static const uptr kMetaSize = 0x007000000000ULL;<br>
-# else // if SANITIZER_WINDOWS<br>
-static const uptr kLinuxShadowMsk = 0x200000000000ULL;<br>
-static const uptr kMetaShadow = 0x300000000000ULL;<br>
-static const uptr kMetaSize = 0x100000000000ULL;<br>
-# endif // if SANITIZER_WINDOWS<br>
-#else // defined(TSAN_GO)<br>
-static const uptr kMetaShadow = 0x300000000000ULL;<br>
-static const uptr kMetaSize = 0x100000000000ULL;<br>
-static const uptr kLinuxAppMemBeg = 0x7cf000000000ULL;<br>
-static const uptr kLinuxAppMemEnd = 0x7fffffffffffULL;<br>
-#endif<br>
-<br>
-static const uptr kLinuxAppMemMsk = 0x7c0000000000ULL;<br>
+const uptr kMetaShadowBeg = 0x076000000000ull;<br>
+const uptr kMetaShadowEnd = 0x07d000000000ull;<br>
+const uptr kTraceMemBeg = 0x056000000000ull;<br>
+const uptr kTraceMemEnd = 0x076000000000ull;<br>
+const uptr kShadowBeg = 0x010000000000ull;<br>
+const uptr kShadowEnd = 0x038000000000ull;<br>
+const uptr kAppMemBeg = 0x000000001000ull;<br>
+const uptr kAppMemEnd = 0x00e000000000ull;<br>
+<br>
+ALWAYS_INLINE<br>
+bool IsAppMem(uptr mem) {<br>
+ return mem >= kAppMemBeg && mem < kAppMemEnd;<br>
+}<br>
<br>
-#if SANITIZER_WINDOWS<br>
-const uptr kTraceMemBegin = 0x056000000000ULL;<br>
-#else<br>
-const uptr kTraceMemBegin = 0x600000000000ULL;<br>
-#endif<br>
-const uptr kTraceMemSize = 0x020000000000ULL;<br>
+ALWAYS_INLINE<br>
+bool IsShadowMem(uptr mem) {<br>
+ return mem >= kShadowBeg && mem <= kShadowEnd;<br>
+}<br>
<br>
-// This has to be a macro to allow constant initialization of constants below.<br>
-#ifndef TSAN_GO<br>
-#define MemToShadow(addr) \<br>
- ((((uptr)addr) & ~(kLinuxAppMemMsk | (kShadowCell - 1))) * kShadowCnt)<br>
-#define MemToMeta(addr) \<br>
- (u32*)(((((uptr)addr) & ~(kLinuxAppMemMsk | (kMetaShadowCell - 1))) \<br>
- / kMetaShadowCell * kMetaShadowSize) | kMetaShadow)<br>
-#else<br>
-#define MemToShadow(addr) \<br>
- (((((uptr)addr) & ~(kShadowCell - 1)) * kShadowCnt) | kLinuxShadowMsk)<br>
-#define MemToMeta(addr) \<br>
- (u32*)(((((uptr)addr) & ~(kMetaShadowCell - 1)) \<br>
- / kMetaShadowCell * kMetaShadowSize) | kMetaShadow)<br>
-#endif<br>
+ALWAYS_INLINE<br>
+bool IsMetaMem(uptr mem) {<br>
+ return mem >= kMetaShadowBeg && mem <= kMetaShadowEnd;<br>
+}<br>
<br>
-static const uptr kLinuxShadowBeg = MemToShadow(kLinuxAppMemBeg);<br>
-static const uptr kLinuxShadowEnd =<br>
- MemToShadow(kLinuxAppMemEnd) | 0xff;<br>
-<br>
-static inline bool IsAppMem(uptr mem) {<br>
-#if defined(TSAN_GO)<br>
- return mem <= kLinuxAppMemEnd;<br>
-#else<br>
- return mem >= kLinuxAppMemBeg && mem <= kLinuxAppMemEnd;<br>
-#endif<br>
+ALWAYS_INLINE<br>
+uptr MemToShadow(uptr x) {<br>
+ DCHECK(IsAppMem(x));<br>
+ return ((x & ~(kShadowCell - 1)) * kShadowCnt) | kShadowBeg;<br>
}<br>
<br>
-static inline bool IsShadowMem(uptr mem) {<br>
- return mem >= kLinuxShadowBeg && mem <= kLinuxShadowEnd;<br>
+ALWAYS_INLINE<br>
+u32 *MemToMeta(uptr x) {<br>
+ DCHECK(IsAppMem(x));<br>
+ return (u32*)(((x & ~(kMetaShadowCell - 1)) / \<br>
+ kMetaShadowCell * kMetaShadowSize) | kMetaShadowEnd);<br>
}<br>
<br>
-static inline uptr ShadowToMem(uptr shadow) {<br>
- CHECK(IsShadowMem(shadow));<br>
-#ifdef TSAN_GO<br>
- return (shadow & ~kLinuxShadowMsk) / kShadowCnt;<br>
-#else<br>
- return (shadow / kShadowCnt) | kLinuxAppMemMsk;<br>
-#endif<br>
+ALWAYS_INLINE<br>
+uptr ShadowToMem(uptr s) {<br>
+ CHECK(IsShadowMem(s));<br>
+ // FIXME(dvyukov): this is most likely wrong as the mapping is not bijection.<br>
+ return (x & ~kShadowBeg) / kShadowCnt;<br>
}<br>
<br>
-void FlushShadowMemory();<br>
-void WriteMemoryProfile(char *buf, uptr buf_size, uptr nthread, uptr nlive);<br>
-uptr GetRSS();<br>
+static USED uptr UserRegions[] = {<br>
+ kAppMemBeg, kAppMemEnd,<br>
+};<br>
<br>
-void InitializePlatform();<br>
-void FinalizePlatform();<br>
+#else<br>
+# error "Unknown platform"<br>
+#endif<br>
<br>
// The additional page is to catch shadow stack overflow as paging fault.<br>
// Windows wants 64K alignment for mmaps.<br>
@@ -137,18 +236,23 @@ const uptr kTotalTraceSize = (kTraceSize<br>
+ (64 << 10) + (64 << 10) - 1) & ~((64 << 10) - 1);<br>
<br>
uptr ALWAYS_INLINE GetThreadTrace(int tid) {<br>
- uptr p = kTraceMemBegin + (uptr)tid * kTotalTraceSize;<br>
- DCHECK_LT(p, kTraceMemBegin + kTraceMemSize);<br>
+ uptr p = kTraceMemBeg + (uptr)tid * kTotalTraceSize;<br>
+ DCHECK_LT(p, kTraceMemEnd);<br>
return p;<br>
}<br>
<br>
uptr ALWAYS_INLINE GetThreadTraceHeader(int tid) {<br>
- uptr p = kTraceMemBegin + (uptr)tid * kTotalTraceSize<br>
+ uptr p = kTraceMemBeg + (uptr)tid * kTotalTraceSize<br>
+ kTraceSize * sizeof(Event);<br>
- DCHECK_LT(p, kTraceMemBegin + kTraceMemSize);<br>
+ DCHECK_LT(p, kTraceMemEnd);<br>
return p;<br>
}<br>
<br>
+void InitializePlatform();<br>
+void FlushShadowMemory();<br>
+void WriteMemoryProfile(char *buf, uptr buf_size, uptr nthread, uptr nlive);<br>
+uptr GetRSS();<br>
+<br>
void *internal_start_thread(void(*func)(void*), void *arg);<br>
void internal_join_thread(void *th);<br>
<br>
@@ -164,8 +268,4 @@ int call_pthread_cancel_with_cleanup(int<br>
<br>
} // namespace __tsan<br>
<br>
-#else // defined(__LP64__) || defined(_WIN64)<br>
-# error "Only 64-bit is supported"<br>
-#endif<br>
-<br>
#endif // TSAN_PLATFORM_H<br>
<br>
Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_platform_linux.cc<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_platform_linux.cc?rev=220571&r1=220570&r2=220571&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_platform_linux.cc?rev=220571&r1=220570&r2=220571&view=diff</a><br>
==============================================================================<br>
--- compiler-rt/trunk/lib/tsan/rtl/tsan_platform_linux.cc (original)<br>
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_platform_linux.cc Fri Oct 24 12:07:29 2014<br>
@@ -63,6 +63,9 @@ void *__libc_stack_end = 0;<br>
<br>
namespace __tsan {<br>
<br>
+static uptr g_data_start;<br>
+static uptr g_data_end;<br>
+<br>
const uptr kPageSize = 4096;<br>
<br>
enum {<br>
@@ -77,22 +80,26 @@ enum {<br>
MemCount = 8,<br>
};<br>
<br>
-void FillProfileCallback(uptr start, uptr rss, bool file,<br>
+void FillProfileCallback(uptr p, uptr rss, bool file,<br>
uptr *mem, uptr stats_size) {<br>
mem[MemTotal] += rss;<br>
- start >>= 40;<br>
- if (start < 0x10)<br>
+ if (p >= kShadowBeg && p < kShadowEnd)<br>
mem[MemShadow] += rss;<br>
- else if (start >= 0x20 && start < 0x30)<br>
- mem[file ? MemFile : MemMmap] += rss;<br>
- else if (start >= 0x30 && start < 0x40)<br>
+ else if (p >= kMetaShadowBeg && p < kMetaShadowEnd)<br>
mem[MemMeta] += rss;<br>
- else if (start >= 0x7e)<br>
+#ifndef TSAN_GO<br>
+ else if (p >= kHeapMemBeg && p < kHeapMemEnd)<br>
+ mem[MemHeap] += rss;<br>
+ else if (p >= kLoAppMemBeg && p < kLoAppMemEnd)<br>
+ mem[file ? MemFile : MemMmap] += rss;<br>
+ else if (p >= kHiAppMemBeg && p < kHiAppMemEnd)<br>
+ mem[file ? MemFile : MemMmap] += rss;<br>
+#else<br>
+ else if (p >= kAppMemBeg && p < kAppMemEnd)<br>
mem[file ? MemFile : MemMmap] += rss;<br>
- else if (start >= 0x60 && start < 0x62)<br>
+#endif<br>
+ else if (p >= kTraceMemBeg && p < kTraceMemEnd)<br>
mem[MemTrace] += rss;<br>
- else if (start >= 0x7d && start < 0x7e)<br>
- mem[MemHeap] += rss;<br>
else<br>
mem[MemOther] += rss;<br>
}<br>
@@ -142,7 +149,7 @@ uptr GetRSS() {<br>
void FlushShadowMemoryCallback(<br>
const SuspendedThreadsList &suspended_threads_list,<br>
void *argument) {<br>
- FlushUnneededShadowMemory(kLinuxShadowBeg, kLinuxShadowEnd - kLinuxShadowBeg);<br>
+ FlushUnneededShadowMemory(kShadowBeg, kShadowEnd - kShadowBeg);<br>
}<br>
#endif<br>
<br>
@@ -223,12 +230,12 @@ static void MapRodata() {<br>
<br>
void InitializeShadowMemory() {<br>
// Map memory shadow.<br>
- uptr shadow = (uptr)MmapFixedNoReserve(kLinuxShadowBeg,<br>
- kLinuxShadowEnd - kLinuxShadowBeg);<br>
- if (shadow != kLinuxShadowBeg) {<br>
+ uptr shadow = (uptr)MmapFixedNoReserve(kShadowBeg,<br>
+ kShadowEnd - kShadowBeg);<br>
+ if (shadow != kShadowBeg) {<br>
Printf("FATAL: ThreadSanitizer can not mmap the shadow memory\n");<br>
Printf("FATAL: Make sure to compile with -fPIE and "<br>
- "to link with -pie (%p, %p).\n", shadow, kLinuxShadowBeg);<br>
+ "to link with -pie (%p, %p).\n", shadow, kShadowBeg);<br>
Die();<br>
}<br>
// This memory range is used for thread stacks and large user mmaps.<br>
@@ -240,73 +247,23 @@ void InitializeShadowMemory() {<br>
0x10000000000ULL * kShadowMultiplier, MADV_NOHUGEPAGE);<br>
#endif<br>
DPrintf("memory shadow: %zx-%zx (%zuGB)\n",<br>
- kLinuxShadowBeg, kLinuxShadowEnd,<br>
- (kLinuxShadowEnd - kLinuxShadowBeg) >> 30);<br>
+ kShadowBeg, kShadowEnd,<br>
+ (kShadowEnd - kShadowBeg) >> 30);<br>
<br>
// Map meta shadow.<br>
- if (MemToMeta(kLinuxAppMemBeg) < (u32*)kMetaShadow) {<br>
- Printf("ThreadSanitizer: bad meta shadow (%p -> %p < %p)\n",<br>
- kLinuxAppMemBeg, MemToMeta(kLinuxAppMemBeg), kMetaShadow);<br>
- Die();<br>
- }<br>
- if (MemToMeta(kLinuxAppMemEnd) >= (u32*)(kMetaShadow + kMetaSize)) {<br>
- Printf("ThreadSanitizer: bad meta shadow (%p -> %p >= %p)\n",<br>
- kLinuxAppMemEnd, MemToMeta(kLinuxAppMemEnd), kMetaShadow + kMetaSize);<br>
- Die();<br>
- }<br>
- uptr meta = (uptr)MmapFixedNoReserve(kMetaShadow, kMetaSize);<br>
- if (meta != kMetaShadow) {<br>
+ uptr meta = (uptr)MmapFixedNoReserve(kMetaShadowBeg,<br>
+ kMetaShadowEnd - kMetaShadowBeg);<br>
+ if (meta != kMetaShadowBeg) {<br>
Printf("FATAL: ThreadSanitizer can not mmap the shadow memory\n");<br>
Printf("FATAL: Make sure to compile with -fPIE and "<br>
- "to link with -pie (%p, %p).\n", meta, kMetaShadow);<br>
+ "to link with -pie (%p, %p).\n", meta, kMetaShadowBeg);<br>
Die();<br>
}<br>
DPrintf("meta shadow: %zx-%zx (%zuGB)\n",<br>
kMetaShadow, kMetaShadow + kMetaSize, kMetaSize >> 30);<br>
<br>
- // Protect gaps.<br>
- const uptr kClosedLowBeg = 0x200000;<br>
- const uptr kClosedLowEnd = kLinuxShadowBeg - 1;<br>
- const uptr kClosedMidBeg = kLinuxShadowEnd + 1;<br>
- const uptr kClosedMidEnd = min(min(kLinuxAppMemBeg, kTraceMemBegin),<br>
- kMetaShadow);<br>
-<br>
- ProtectRange(kClosedLowBeg, kClosedLowEnd);<br>
- ProtectRange(kClosedMidBeg, kClosedMidEnd);<br>
- VPrintf(2, "kClosedLow %zx-%zx (%zuGB)\n",<br>
- kClosedLowBeg, kClosedLowEnd, (kClosedLowEnd - kClosedLowBeg) >> 30);<br>
- VPrintf(2, "kClosedMid %zx-%zx (%zuGB)\n",<br>
- kClosedMidBeg, kClosedMidEnd, (kClosedMidEnd - kClosedMidBeg) >> 30);<br>
- VPrintf(2, "app mem: %zx-%zx (%zuGB)\n",<br>
- kLinuxAppMemBeg, kLinuxAppMemEnd,<br>
- (kLinuxAppMemEnd - kLinuxAppMemBeg) >> 30);<br>
- VPrintf(2, "stack: %zx\n", (uptr)&shadow);<br>
-<br>
MapRodata();<br>
}<br>
-#endif<br>
-<br>
-static uptr g_data_start;<br>
-static uptr g_data_end;<br>
-<br>
-#ifndef TSAN_GO<br>
-static void CheckPIE() {<br>
- // Ensure that the binary is indeed compiled with -pie.<br>
- MemoryMappingLayout proc_maps(true);<br>
- uptr start, end;<br>
- if (proc_maps.Next(&start, &end,<br>
- /*offset*/0, /*filename*/0, /*filename_size*/0,<br>
- /*protection*/0)) {<br>
- if ((u64)start < kLinuxAppMemBeg) {<br>
- Printf("FATAL: ThreadSanitizer can not mmap the shadow memory ("<br>
- "something is mapped at 0x%zx < 0x%zx)\n",<br>
- start, kLinuxAppMemBeg);<br>
- Printf("FATAL: Make sure to compile with -fPIE"<br>
- " and to link with -pie.\n");<br>
- Die();<br>
- }<br>
- }<br>
-}<br>
<br>
static void InitDataSeg() {<br>
MemoryMappingLayout proc_maps(true);<br>
@@ -333,6 +290,28 @@ static void InitDataSeg() {<br>
CHECK_LT((uptr)&g_data_start, g_data_end);<br>
}<br>
<br>
+static void CheckAndProtect() {<br>
+ // Ensure that the binary is indeed compiled with -pie.<br>
+ MemoryMappingLayout proc_maps(true);<br>
+ uptr p, end;<br>
+ while (proc_maps.Next(&p, &end, 0, 0, 0, 0)) {<br>
+ if (IsAppMem(p))<br>
+ continue;<br>
+ if (p >= kHeapMemEnd &&<br>
+ p < kHeapMemEnd + PrimaryAllocator::AdditionalSize())<br>
+ continue;<br>
+ if (p >= 0xf000000000000000ull) // vdso<br>
+ break;<br>
+ Printf("FATAL: ThreadSanitizer: unexpected memory mapping %p-%p\n", p, end);<br>
+ Die();<br>
+ }<br>
+<br>
+ ProtectRange(kLoAppMemEnd, kShadowBeg);<br>
+ ProtectRange(kShadowEnd, kMetaShadowBeg);<br>
+ ProtectRange(kMetaShadowEnd, kTraceMemBeg);<br>
+ ProtectRange(kTraceMemEnd, kHeapMemBeg);<br>
+ ProtectRange(kHeapMemEnd + PrimaryAllocator::AdditionalSize(), kHiAppMemBeg);<br>
+}<br>
#endif // #ifndef TSAN_GO<br>
<br>
void InitializePlatform() {<br>
@@ -368,7 +347,7 @@ void InitializePlatform() {<br>
}<br>
<br>
#ifndef TSAN_GO<br>
- CheckPIE();<br>
+ CheckAndProtect();<br>
InitTlsSize();<br>
InitDataSeg();<br>
#endif<br>
<br>
Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_platform_mac.cc<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_platform_mac.cc?rev=220571&r1=220570&r2=220571&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_platform_mac.cc?rev=220571&r1=220570&r2=220571&view=diff</a><br>
==============================================================================<br>
--- compiler-rt/trunk/lib/tsan/rtl/tsan_platform_mac.cc (original)<br>
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_platform_mac.cc Fri Oct 24 12:07:29 2014<br>
@@ -56,20 +56,20 @@ uptr GetRSS() {<br>
<br>
#ifndef TSAN_GO<br>
void InitializeShadowMemory() {<br>
- uptr shadow = (uptr)MmapFixedNoReserve(kLinuxShadowBeg,<br>
- kLinuxShadowEnd - kLinuxShadowBeg);<br>
- if (shadow != kLinuxShadowBeg) {<br>
+ uptr shadow = (uptr)MmapFixedNoReserve(kShadowBeg,<br>
+ kShadowEnd - kShadowBeg);<br>
+ if (shadow != kShadowBeg) {<br>
Printf("FATAL: ThreadSanitizer can not mmap the shadow memory\n");<br>
Printf("FATAL: Make sure to compile with -fPIE and "<br>
"to link with -pie.\n");<br>
Die();<br>
}<br>
- DPrintf("kLinuxShadow %zx-%zx (%zuGB)\n",<br>
- kLinuxShadowBeg, kLinuxShadowEnd,<br>
- (kLinuxShadowEnd - kLinuxShadowBeg) >> 30);<br>
- DPrintf("kLinuxAppMem %zx-%zx (%zuGB)\n",<br>
- kLinuxAppMemBeg, kLinuxAppMemEnd,<br>
- (kLinuxAppMemEnd - kLinuxAppMemBeg) >> 30);<br>
+ DPrintf("kShadow %zx-%zx (%zuGB)\n",<br>
+ kShadowBeg, kShadowEnd,<br>
+ (kShadowEnd - kShadowBeg) >> 30);<br>
+ DPrintf("kAppMem %zx-%zx (%zuGB)\n",<br>
+ kAppMemBeg, kAppMemEnd,<br>
+ (kAppMemEnd - kAppMemBeg) >> 30);<br>
}<br>
#endif<br>
<br>
@@ -77,10 +77,6 @@ void InitializePlatform() {<br>
DisableCoreDumperIfNecessary();<br>
}<br>
<br>
-void FinalizePlatform() {<br>
- fflush(0);<br>
-}<br>
-<br>
#ifndef TSAN_GO<br>
int call_pthread_cancel_with_cleanup(int(*fn)(void *c, void *m,<br>
void *abstime), void *c, void *m, void *abstime,<br>
<br>
Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_platform_windows.cc<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_platform_windows.cc?rev=220571&r1=220570&r2=220571&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_platform_windows.cc?rev=220571&r1=220570&r2=220571&view=diff</a><br>
==============================================================================<br>
--- compiler-rt/trunk/lib/tsan/rtl/tsan_platform_windows.cc (original)<br>
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_platform_windows.cc Fri Oct 24 12:07:29 2014<br>
@@ -38,10 +38,6 @@ uptr GetRSS() {<br>
void InitializePlatform() {<br>
}<br>
<br>
-void FinalizePlatform() {<br>
- fflush(0);<br>
-}<br>
-<br>
} // namespace __tsan<br>
<br>
#endif // SANITIZER_WINDOWS<br>
<br>
Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.cc<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.cc?rev=220571&r1=220570&r2=220571&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.cc?rev=220571&r1=220570&r2=220571&view=diff</a><br>
==============================================================================<br>
--- compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.cc (original)<br>
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.cc Fri Oct 24 12:07:29 2014<br>
@@ -261,8 +261,8 @@ void MapShadow(uptr addr, uptr size) {<br>
<br>
void MapThreadTrace(uptr addr, uptr size) {<br>
DPrintf("#0: Mapping trace at %p-%p(0x%zx)\n", addr, addr + size, size);<br>
- CHECK_GE(addr, kTraceMemBegin);<br>
- CHECK_LE(addr + size, kTraceMemBegin + kTraceMemSize);<br>
+ CHECK_GE(addr, kTraceMemBeg);<br>
+ CHECK_LE(addr + size, kTraceMemEnd);<br>
CHECK_EQ(addr, addr & ~((64 << 10) - 1)); // windows wants 64K alignment<br>
uptr addr1 = (uptr)MmapFixedNoReserve(addr, size);<br>
if (addr1 != addr) {<br>
@@ -272,6 +272,28 @@ void MapThreadTrace(uptr addr, uptr size<br>
}<br>
}<br>
<br>
+static void CheckShadowMapping() {<br>
+ for (uptr i = 0; i < ARRAY_SIZE(UserRegions); i += 2) {<br>
+ const uptr beg = UserRegions[i];<br>
+ const uptr end = UserRegions[i + 1];<br>
+ VPrintf(3, "checking shadow region %p-%p\n", beg, end);<br>
+ for (uptr p0 = beg; p0 <= end; p0 += (end - beg) / 4) {<br>
+ for (int x = -1; x <= 1; x++) {<br>
+ const uptr p = p0 + x;<br>
+ if (p < beg || p >= end)<br>
+ continue;<br>
+ const uptr s = MemToShadow(p);<br>
+ VPrintf(3, " checking pointer %p -> %p\n", p, s);<br>
+ CHECK(IsAppMem(p));<br>
+ CHECK(IsShadowMem(s));<br>
+ CHECK_EQ(p & ~(kShadowCell - 1), ShadowToMem(s));<br>
+ const uptr m = (uptr)MemToMeta(p);<br>
+ CHECK(IsMetaMem(m));<br>
+ }<br>
+ }<br>
+ }<br>
+}<br>
+<br>
void Initialize(ThreadState *thr) {<br>
// Thread safe because done before all threads exist.<br>
static bool is_initialized = false;<br>
@@ -291,6 +313,7 @@ void Initialize(ThreadState *thr) {<br>
InitializeAllocator();<br>
#endif<br>
InitializeInterceptors();<br>
+ CheckShadowMapping();<br>
InitializePlatform();<br>
InitializeMutex();<br>
InitializeDynamicAnnotations();<br>
@@ -692,6 +715,8 @@ ALWAYS_INLINE<br>
bool ContainsSameAccess(u64 *s, u64 a, u64 sync_epoch, bool is_write) {<br>
#if defined(__SSE3__) && TSAN_SHADOW_COUNT == 4<br>
bool res = ContainsSameAccessFast(s, a, sync_epoch, is_write);<br>
+ // NOTE: this check can fail if the shadow is concurrently mutated<br>
+ // by other threads.<br>
DCHECK_EQ(res, ContainsSameAccessSlow(s, a, sync_epoch, is_write));<br>
return res;<br>
#else<br>
<br>
Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.h?rev=220571&r1=220570&r2=220571&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.h?rev=220571&r1=220570&r2=220571&view=diff</a><br>
==============================================================================<br>
--- compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.h (original)<br>
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.h Fri Oct 24 12:07:29 2014<br>
@@ -53,11 +53,8 @@<br>
namespace __tsan {<br>
<br>
#ifndef TSAN_GO<br>
-const uptr kAllocatorSpace = 0x7d0000000000ULL;<br>
-const uptr kAllocatorSize = 0x10000000000ULL; // 1T.<br>
-<br>
struct MapUnmapCallback;<br>
-typedef SizeClassAllocator64<kAllocatorSpace, kAllocatorSize, 0,<br>
+typedef SizeClassAllocator64<kHeapMemBeg, kHeapMemEnd - kHeapMemBeg, 0,<br>
DefaultSizeClassMap, MapUnmapCallback> PrimaryAllocator;<br>
typedef SizeClassAllocatorLocalCache<PrimaryAllocator> AllocatorCache;<br>
typedef LargeMmapAllocator<MapUnmapCallback> SecondaryAllocator;<br>
<br>
Modified: compiler-rt/trunk/lib/tsan/tests/unit/tsan_mman_test.cc<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/tests/unit/tsan_mman_test.cc?rev=220571&r1=220570&r2=220571&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/tests/unit/tsan_mman_test.cc?rev=220571&r1=220570&r2=220571&view=diff</a><br>
==============================================================================<br>
--- compiler-rt/trunk/lib/tsan/tests/unit/tsan_mman_test.cc (original)<br>
+++ compiler-rt/trunk/lib/tsan/tests/unit/tsan_mman_test.cc Fri Oct 24 12:07:29 2014<br>
@@ -103,7 +103,7 @@ TEST(Mman, UsableSize) {<br>
EXPECT_EQ(20U, user_alloc_usable_size(p2));<br>
user_free(thr, pc, p);<br>
user_free(thr, pc, p2);<br>
- EXPECT_EQ(0U, user_alloc_usable_size((void*)0x123));<br>
+ EXPECT_EQ(0U, user_alloc_usable_size((void*)0x4123));<br>
}<br>
<br>
TEST(Mman, Stats) {<br>
<br>
Added: compiler-rt/trunk/test/tsan/map32bit.cc<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/tsan/map32bit.cc?rev=220571&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/tsan/map32bit.cc?rev=220571&view=auto</a><br>
==============================================================================<br>
--- compiler-rt/trunk/test/tsan/map32bit.cc (added)<br>
+++ compiler-rt/trunk/test/tsan/map32bit.cc Fri Oct 24 12:07:29 2014<br>
@@ -0,0 +1,41 @@<br>
+// RUN: %clangxx_tsan -O1 %s -o %t && %deflake %run %t 2>&1 | FileCheck %s<br>
+#include <pthread.h><br>
+#include <stdio.h><br>
+#include <stddef.h><br>
+#include <stdint.h><br>
+#include <unistd.h><br>
+#include <errno.h><br>
+#include <sys/mman.h><br>
+<br>
+// Test for issue:<br>
+// <a href="https://code.google.com/p/thread-sanitizer/issues/detail?id=5" target="_blank">https://code.google.com/p/thread-sanitizer/issues/detail?id=5</a><br>
+<br>
+void *Thread(void *ptr) {<br>
+ *(int*)ptr = 42;<br>
+ return 0;<br>
+}<br>
+<br>
+int main() {<br>
+ void *ptr = mmap(0, 128 << 10, PROT_READ|PROT_WRITE,<br>
+ MAP_32BIT|MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);<br>
+ fprintf(stderr, "ptr=%p\n", ptr);<br>
+ if (ptr == MAP_FAILED) {<br>
+ fprintf(stderr, "mmap failed: %d\n", errno);<br>
+ return 1;<br>
+ }<br>
+ if ((uintptr_t)ptr >= (1ull << 32)) {<br>
+ fprintf(stderr, "ptr is too high\n");<br>
+ return 1;<br>
+ }<br>
+ pthread_t t;<br>
+ pthread_create(&t, 0, Thread, ptr);<br>
+ sleep(1);<br>
+ *(int*)ptr = 42;<br>
+ pthread_join(t, 0);<br>
+ munmap(ptr, 128 << 10);<br>
+ fprintf(stderr, "DONE\n");<br>
+}<br>
+<br>
+// CHECK: WARNING: ThreadSanitizer: data race<br>
+// CHECK: DONE<br>
+<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div>