summaryrefslogtreecommitdiffstats
path: root/libexec/rtld-elf/rtld.c
diff options
context:
space:
mode:
authordfr <dfr@FreeBSD.org>2005-02-27 12:55:40 +0000
committerdfr <dfr@FreeBSD.org>2005-02-27 12:55:40 +0000
commit0c34e7e727f487797ac2d25272d1d1a536d42a85 (patch)
treebc9d98ec067871de6297cc375f424591f69b4c1a /libexec/rtld-elf/rtld.c
parent5d9bc16368a571a4efed23a179ae62e3a0610008 (diff)
downloadFreeBSD-src-0c34e7e727f487797ac2d25272d1d1a536d42a85.zip
FreeBSD-src-0c34e7e727f487797ac2d25272d1d1a536d42a85.tar.gz
Attempt to free any static TLS space used by a shared library when it
is unloaded. This allows applications which load and unload libraries like libGL.so.1 several times to work properly. MFC after: 2 days
Diffstat (limited to 'libexec/rtld-elf/rtld.c')
-rw-r--r--libexec/rtld-elf/rtld.c20
1 files changed, 20 insertions, 0 deletions
diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c
index 6fc64dd..aec6e3d 100644
--- a/libexec/rtld-elf/rtld.c
+++ b/libexec/rtld-elf/rtld.c
@@ -2773,6 +2773,26 @@ allocate_tls_offset(Obj_Entry *obj)
return true;
}
+void
+free_tls_offset(Obj_Entry *obj)
+{
+#if defined(__i386__) || defined(__amd64__) || defined(__sparc64__) || \
+ defined(__arm__)
+ /*
+ * If we were the last thing to allocate out of the static TLS
+ * block, we give our space back to the 'allocator'. This is a
+ * simplistic workaround to allow libGL.so.1 to be loaded and
+ * unloaded multiple times. We only handle the Variant II
+ * mechanism for now - this really needs a proper allocator.
+ */
+ if (calculate_tls_end(obj->tlsoffset, obj->tlssize)
+ == calculate_tls_end(tls_last_offset, tls_last_size)) {
+ tls_last_offset -= obj->tlssize;
+ tls_last_size = 0;
+ }
+#endif
+}
+
void *
_rtld_allocate_tls(void *oldtls, size_t tcbsize, size_t tcbalign)
{
OpenPOWER on IntegriCloud