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
This commit is contained in:
Doug Rabson 2005-02-27 12:55:40 +00:00
parent 9bdd3e8497
commit ddab7ee80a
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=142645
3 changed files with 24 additions and 0 deletions

View File

@ -305,6 +305,9 @@ obj_free(Obj_Entry *obj)
{
Objlist_Entry *elm;
if (obj->tls_done) {
free_tls_offset(obj);
}
free(obj->path);
while (obj->needed != NULL) {
Needed_Entry *needed = obj->needed;

View File

@ -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)
{

View File

@ -238,6 +238,7 @@ void *allocate_tls(Obj_Entry *, void *, size_t, size_t);
void free_tls(void *, size_t, size_t);
void *allocate_module_tls(int index);
bool allocate_tls_offset(Obj_Entry *obj);
void free_tls_offset(Obj_Entry *obj);
/*
* MD function declarations.