Fix dlclose for libraries with thread_local dtors

Introduce new flag to mark soinfo as TLS_NODELETE when
there are thread_local dtors associated with dso_handle
belonging to it.

Test: bionic-unit-tests --gtest_filter=dl*
Test: bionic-unit-tests-glibc --gtest_filter=dl*
Bug: https://github.com/android-ndk/ndk/issues/360
Change-Id: I724ef89fc899788f95c47e6372c38b3313f18fed
diff --git a/linker/linker_soinfo.cpp b/linker/linker_soinfo.cpp
index dd91752..54bfcf0 100644
--- a/linker/linker_soinfo.cpp
+++ b/linker/linker_soinfo.cpp
@@ -537,6 +537,14 @@
   rtld_flags_ |= RTLD_NODELETE;
 }
 
+void soinfo::set_tls_nodelete() {
+  flags_ |= FLAG_TLS_NODELETE;
+}
+
+void soinfo::unset_tls_nodelete() {
+  flags_ &= ~FLAG_TLS_NODELETE;
+}
+
 const char* soinfo::get_realpath() const {
 #if defined(__work_around_b_24465209__)
   if (has_min_version(2)) {
@@ -650,7 +658,11 @@
 }
 
 bool soinfo::can_unload() const {
-  return !is_linked() || ((get_rtld_flags() & (RTLD_NODELETE | RTLD_GLOBAL)) == 0);
+  return !is_linked() ||
+         (
+             (get_rtld_flags() & (RTLD_NODELETE | RTLD_GLOBAL)) == 0 &&
+             (flags_ & FLAG_TLS_NODELETE) == 0
+         );
 }
 
 bool soinfo::is_linked() const {
@@ -693,6 +705,10 @@
   return --local_group_root_->ref_count_;
 }
 
+size_t soinfo::get_ref_count() const {
+  return local_group_root_->ref_count_;
+}
+
 soinfo* soinfo::get_local_group_root() const {
   return local_group_root_;
 }