Index: libexec/rtld-elf/aarch64/rtld_machdep.h =================================================================== --- libexec/rtld-elf/aarch64/rtld_machdep.h +++ libexec/rtld-elf/aarch64/rtld_machdep.h @@ -76,7 +76,6 @@ round(16, align) #define calculate_tls_offset(prev_offset, prev_size, size, align, offset) \ round(prev_offset + prev_size, align) -#define calculate_tls_end(off, size) ((off) + (size)) #define calculate_tls_post_size(align) \ round(TLS_TCB_SIZE, align) - TLS_TCB_SIZE Index: libexec/rtld-elf/amd64/reloc.c =================================================================== --- libexec/rtld-elf/amd64/reloc.c +++ libexec/rtld-elf/amd64/reloc.c @@ -563,9 +563,3 @@ { return calculate_tls_offset(0, 0, size, align, offset); } - -size_t -calculate_tls_end(size_t off, size_t size __unused) -{ - return (off); -} Index: libexec/rtld-elf/amd64/rtld_machdep.h =================================================================== --- libexec/rtld-elf/amd64/rtld_machdep.h +++ libexec/rtld-elf/amd64/rtld_machdep.h @@ -73,10 +73,10 @@ #define md_abi_variant_hook(x) +#define TLS_BELOW_TP #define TLS_DTV_OFFSET 0 size_t calculate_first_tls_offset(size_t size, size_t align, size_t offset); size_t calculate_tls_offset(size_t prev_offset, size_t prev_size, size_t size, size_t align, size_t offset); -size_t calculate_tls_end(size_t off, size_t size); #endif Index: libexec/rtld-elf/arm/rtld_machdep.h =================================================================== --- libexec/rtld-elf/arm/rtld_machdep.h +++ libexec/rtld-elf/arm/rtld_machdep.h @@ -68,7 +68,6 @@ round(8, align) #define calculate_tls_offset(prev_offset, prev_size, size, align, offset) \ round(prev_offset + prev_size, align) -#define calculate_tls_end(off, size) ((off) + (size)) #define calculate_tls_post_size(align) \ round(TLS_TCB_SIZE, align) - TLS_TCB_SIZE Index: libexec/rtld-elf/i386/reloc.c =================================================================== --- libexec/rtld-elf/i386/reloc.c +++ libexec/rtld-elf/i386/reloc.c @@ -554,9 +554,3 @@ { return calculate_tls_offset(0, 0, size, align, offset); } - -size_t -calculate_tls_end(size_t off, size_t size __unused) -{ - return (off); -} Index: libexec/rtld-elf/i386/rtld_machdep.h =================================================================== --- libexec/rtld-elf/i386/rtld_machdep.h +++ libexec/rtld-elf/i386/rtld_machdep.h @@ -74,10 +74,10 @@ #define md_abi_variant_hook(x) +#define TLS_BELOW_TP #define TLS_DTV_OFFSET 0 size_t calculate_first_tls_offset(size_t size, size_t align, size_t offset); size_t calculate_tls_offset(size_t prev_offset, size_t prev_size, size_t size, size_t align, size_t offset); -size_t calculate_tls_end(size_t off, size_t size); #endif Index: libexec/rtld-elf/mips/rtld_machdep.h =================================================================== --- libexec/rtld-elf/mips/rtld_machdep.h +++ libexec/rtld-elf/mips/rtld_machdep.h @@ -68,7 +68,6 @@ TLS_TCB_SIZE #define calculate_tls_offset(prev_offset, prev_size, size, align, offset) \ round(prev_offset + prev_size, align) -#define calculate_tls_end(off, size) ((off) + (size)) #define calculate_tls_post_size(align) 0 extern void *__tls_get_addr(tls_index *ti); Index: libexec/rtld-elf/powerpc/rtld_machdep.h =================================================================== --- libexec/rtld-elf/powerpc/rtld_machdep.h +++ libexec/rtld-elf/powerpc/rtld_machdep.h @@ -83,7 +83,6 @@ TLS_TCB_SIZE #define calculate_tls_offset(prev_offset, prev_size, size, align, offset) \ round(prev_offset + prev_size, align) -#define calculate_tls_end(off, size) ((off) + (size)) #define calculate_tls_post_size(align) 0 typedef struct { Index: libexec/rtld-elf/powerpc64/rtld_machdep.h =================================================================== --- libexec/rtld-elf/powerpc64/rtld_machdep.h +++ libexec/rtld-elf/powerpc64/rtld_machdep.h @@ -75,7 +75,6 @@ TLS_TCB_SIZE #define calculate_tls_offset(prev_offset, prev_size, size, align, offset) \ round(prev_offset + prev_size, align) -#define calculate_tls_end(off, size) ((off) + (size)) #define calculate_tls_post_size(align) 0 typedef struct { Index: libexec/rtld-elf/riscv/rtld_machdep.h =================================================================== --- libexec/rtld-elf/riscv/rtld_machdep.h +++ libexec/rtld-elf/riscv/rtld_machdep.h @@ -92,7 +92,6 @@ TLS_TCB_SIZE #define calculate_tls_offset(prev_offset, prev_size, size, align, offset) \ round(prev_offset + prev_size, align) -#define calculate_tls_end(off, size) ((off) + (size)) #define calculate_tls_post_size(align) 0 typedef struct { Index: libexec/rtld-elf/rtld.c =================================================================== --- libexec/rtld-elf/rtld.c +++ libexec/rtld-elf/rtld.c @@ -4939,8 +4939,7 @@ return (tls_get_addr_slow(dtvp, index, offset, false)); } -#if defined(__aarch64__) || defined(__arm__) || defined(__mips__) || \ - defined(__powerpc__) || defined(__riscv) +#ifndef TLS_BELOW_TP /* * Return pointer to allocated TLS block @@ -5071,9 +5070,7 @@ free_aligned(get_tls_block_ptr(tcb, tcbsize)); } -#endif - -#if defined(__i386__) || defined(__amd64__) +#else /* * Allocate Static TLS using the Variant II method. @@ -5227,6 +5224,11 @@ off = calculate_tls_offset(tls_last_offset, tls_last_size, obj->tlssize, obj->tlsalign, obj->tlspoffset); + obj->tlsoffset = off; +#ifndef TLS_BELOW_TP + off += obj->tlssize; +#endif + /* * If we have already fixed the size of the static TLS block, we * must stay within that size. When allocating the static TLS, we @@ -5234,13 +5236,13 @@ * loading modules which use static TLS. */ if (tls_static_space != 0) { - if (calculate_tls_end(off, obj->tlssize) > tls_static_space) + if (off > tls_static_space) return false; } else if (obj->tlsalign > tls_static_max_align) { tls_static_max_align = obj->tlsalign; } - tls_last_offset = obj->tlsoffset = off; + tls_last_offset = off; tls_last_size = obj->tlssize; obj->tls_done = true; @@ -5257,8 +5259,11 @@ * simplistic workaround to allow libGL.so.1 to be loaded and * unloaded multiple times. */ - if (calculate_tls_end(obj->tlsoffset, obj->tlssize) - == calculate_tls_end(tls_last_offset, tls_last_size)) { + size_t off = obj->tlsoffset; +#ifndef TLS_BELOW_TP + off += obj->tlssize; +#endif + if (off == tls_last_offset) { tls_last_offset -= obj->tlssize; tls_last_size = 0; }