summaryrefslogtreecommitdiff
path: root/libc
diff options
context:
space:
mode:
authorTreehugger Robot <treehugger-gerrit@google.com>2018-07-12 04:33:19 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2018-07-12 04:33:19 +0000
commit2e457f5128b230fe2d9f0a581ddb4771cf83bf24 (patch)
tree6b895f8914d5841c468f2a078d9d0690f368ac2d /libc
parent06f217d399b1bf6345e4c71b014cdaac3d1c183a (diff)
parentbcea0e2afd21ab72bcd7fef27af08dfe9bdcab29 (diff)
Merge "Call __emutls_unregister_key on dlclose"
Diffstat (limited to 'libc')
-rw-r--r--libc/arch-common/bionic/crtbegin_so.c20
1 files changed, 18 insertions, 2 deletions
diff --git a/libc/arch-common/bionic/crtbegin_so.c b/libc/arch-common/bionic/crtbegin_so.c
index 3754363ab..cf369cc82 100644
--- a/libc/arch-common/bionic/crtbegin_so.c
+++ b/libc/arch-common/bionic/crtbegin_so.c
@@ -29,11 +29,27 @@
extern void __cxa_finalize(void *);
extern void *__dso_handle;
-__attribute__((visibility("hidden"),destructor))
-void __on_dlclose() {
+__attribute__((destructor))
+static void __on_dlclose(void) {
__cxa_finalize(&__dso_handle);
}
+/* Define a weak stub function here that will be overridden if the solib uses
+ * emutls. The function needs to be a definition, not just a declaration,
+ * because gold has a bug where it outputs weak+hidden symbols into the .dynsym
+ * table. */
+__attribute__((weak,visibility("hidden")))
+void __emutls_unregister_key(void) {
+}
+
+/* Use a priority of 0 to run after any ordinary destructor function. The
+ * priority setting moves the function towards the front of the .fini_array
+ * section. */
+__attribute__((destructor(0)))
+static void __on_dlclose_late(void) {
+ __emutls_unregister_key();
+}
+
/* CRT_LEGACY_WORKAROUND should only be defined when building
* this file as part of the platform's C library.
*