diff options
author | dfr <dfr@FreeBSD.org> | 2005-02-27 12:55:40 +0000 |
---|---|---|
committer | dfr <dfr@FreeBSD.org> | 2005-02-27 12:55:40 +0000 |
commit | 0c34e7e727f487797ac2d25272d1d1a536d42a85 (patch) | |
tree | bc9d98ec067871de6297cc375f424591f69b4c1a /libexec/rtld-elf/rtld.c | |
parent | 5d9bc16368a571a4efed23a179ae62e3a0610008 (diff) | |
download | FreeBSD-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.c | 20 |
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) { |