diff options
author | marcel <marcel@FreeBSD.org> | 2010-02-16 02:48:11 +0000 |
---|---|---|
committer | marcel <marcel@FreeBSD.org> | 2010-02-16 02:48:11 +0000 |
commit | b72bfb8c312d5db35f2c91540a4c9f0cd7555c24 (patch) | |
tree | 9a38df765f774a3f3d54daa2e5359a10cf0578e8 /libexec | |
parent | 56cf56f59df60dc691d2efd078049223c846a9e6 (diff) | |
download | FreeBSD-src-b72bfb8c312d5db35f2c91540a4c9f0cd7555c24.zip FreeBSD-src-b72bfb8c312d5db35f2c91540a4c9f0cd7555c24.tar.gz |
Improve TLS variant I:
o Use obj->tlsinitsize to determine whether there's initialized data.
o If obj->tlssize > obj->tlsinitsize, then bzero uninitialized data.
o Don't exclude variant I from the work-around in free_tls_offset().
Diffstat (limited to 'libexec')
-rw-r--r-- | libexec/rtld-elf/rtld.c | 19 |
1 files changed, 8 insertions, 11 deletions
diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c index cab8c87d..d91dcee 100644 --- a/libexec/rtld-elf/rtld.c +++ b/libexec/rtld-elf/rtld.c @@ -3151,13 +3151,13 @@ allocate_tls(Obj_Entry *objs, void *oldtcb, size_t tcbsize, size_t tcbalign) dtv[1] = tls_max_index; for (obj = objs; obj; obj = obj->next) { - if (obj->tlsoffset) { + if (obj->tlsoffset > 0) { addr = (Elf_Addr)tls + obj->tlsoffset; - memset((void*) (addr + obj->tlsinitsize), - 0, obj->tlssize - obj->tlsinitsize); - if (obj->tlsinit) - memcpy((void*) addr, obj->tlsinit, - obj->tlsinitsize); + if (obj->tlsinitsize > 0) + memcpy((void*) addr, obj->tlsinit, obj->tlsinitsize); + if (obj->tlssize > obj->tlsinitsize) + memset((void*) (addr + obj->tlsinitsize), 0, + obj->tlssize - obj->tlsinitsize); dtv[obj->tlsindex + 1] = addr; } } @@ -3357,21 +3357,18 @@ allocate_tls_offset(Obj_Entry *obj) void free_tls_offset(Obj_Entry *obj) { -#if defined(__i386__) || defined(__amd64__) || defined(__sparc64__) || \ - defined(__arm__) || defined(__mips__) + /* * 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. + * unloaded multiple times. */ 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 * |