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_;
}