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:
parent
9bdd3e8497
commit
ddab7ee80a
@ -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;
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user