[asan] Make ASan report the correct thread address ranges to LSan.

This CL enables thread support in LSan when used on top of ASan.

git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@182854 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/asan/asan_thread.cc b/lib/asan/asan_thread.cc
index da28381..0787e93 100644
--- a/lib/asan/asan_thread.cc
+++ b/lib/asan/asan_thread.cc
@@ -100,17 +100,17 @@
   // We also clear the shadow on thread destruction because
   // some code may still be executing in later TSD destructors
   // and we don't want it to have any poisoned stack.
-  ClearShadowForThreadStack();
+  ClearShadowForThreadStackAndTLS();
   fake_stack().Cleanup();
   uptr size = RoundUpTo(sizeof(AsanThread), GetPageSizeCached());
   UnmapOrDie(this, size);
 }
 
 void AsanThread::Init() {
-  SetThreadStackTopAndBottom();
+  SetThreadStackAndTls();
   CHECK(AddrIsInMem(stack_bottom_));
   CHECK(AddrIsInMem(stack_top_ - 1));
-  ClearShadowForThreadStack();
+  ClearShadowForThreadStackAndTLS();
   if (flags()->verbosity >= 1) {
     int local = 0;
     Report("T%d: stack [%p,%p) size 0x%zx; local=%p\n",
@@ -143,14 +143,21 @@
   return res;
 }
 
-void AsanThread::SetThreadStackTopAndBottom() {
-  GetThreadStackTopAndBottom(tid() == 0, &stack_top_, &stack_bottom_);
+void AsanThread::SetThreadStackAndTls() {
+  uptr stack_size = 0, tls_size = 0;
+  GetThreadStackAndTls(tid() == 0, &stack_bottom_, &stack_size, &tls_begin_,
+                       &tls_size);
+  stack_top_ = stack_bottom_ + stack_size;
+  tls_end_ = tls_begin_ + tls_size;
+
   int local;
   CHECK(AddrIsInStack((uptr)&local));
 }
 
-void AsanThread::ClearShadowForThreadStack() {
+void AsanThread::ClearShadowForThreadStackAndTLS() {
   PoisonShadow(stack_bottom_, stack_top_ - stack_bottom_, 0);
+  if (tls_begin_ != tls_end_)
+    PoisonShadow(tls_begin_, tls_end_ - tls_begin_, 0);
 }
 
 const char *AsanThread::GetFrameNameByAddr(uptr addr, uptr *offset,
@@ -251,8 +258,19 @@
 bool GetThreadRangesLocked(uptr os_id, uptr *stack_begin, uptr *stack_end,
                            uptr *tls_begin, uptr *tls_end,
                            uptr *cache_begin, uptr *cache_end) {
-  // FIXME: Stub.
-  return false;
+  __asan::AsanThreadContext *context = static_cast<__asan::AsanThreadContext *>(
+      __asan::asanThreadRegistry().FindThreadContextByOsIDLocked(os_id));
+  if (!context) return false;
+  __asan::AsanThread *t = context->thread;
+  if (!t) return false;
+  *stack_begin = t->stack_bottom();
+  *stack_end = t->stack_top();
+  *tls_begin = t->tls_begin();
+  *tls_end = t->tls_end();
+  // ASan doesn't keep allocator caches in TLS, so these are unused.
+  *cache_begin = 0;
+  *cache_end = 0;
+  return true;
 }
 
 void LockThreadRegistry() {