<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>