Index: libexec/ld.elf_so/tls.c =================================================================== RCS file: /cvsroot/src/libexec/ld.elf_so/tls.c,v retrieving revision 1.27 diff -u -p -r1.27 tls.c --- libexec/ld.elf_so/tls.c 6 Jan 2026 07:01:48 -0000 1.27 +++ libexec/ld.elf_so/tls.c 13 Jan 2026 05:34:38 -0000 @@ -59,7 +59,7 @@ static struct tls_tcb *_rtld_tls_allocat static void *_rtld_tls_module_allocate(struct tls_tcb *, size_t); /* A macro to test correct alignment of a pointer. */ -#define ALIGNED_P(ptr, algnmt) (((uintptr_t)(ptr) & ((algnmt) - 1)) == 0) +#define ALIGNED_P(ptr, algnmt) ((algnmt) == 0 || ((uintptr_t)(ptr) & ((algnmt) - 1)) == 0) /* * DTV offset @@ -74,8 +74,18 @@ static void *_rtld_tls_module_allocate(s #define TLS_DTV_OFFSET 0 #endif +#if defined(__HAVE_TLS_VARIANT_I) +#define _RTLD_TLS_INITIAL_OFFSET sizeof(struct tls_tcb) +#endif +#if defined(__HAVE_TLS_VARIANT_II) +#define _RTLD_TLS_INITIAL_OFFSET 0 +#endif + static size_t _rtld_tls_static_space; /* Static TLS space allocated */ -static size_t _rtld_tls_static_offset; /* Next offset for static TLS to use */ +static size_t _rtld_tls_static_offset = + _RTLD_TLS_INITIAL_OFFSET; /* Next offset for static TLS to use */ +static size_t _rtld_tls_static_max_align; + size_t _rtld_tls_dtv_generation = 1; /* Bumped on each load of obj w/ TLS */ size_t _rtld_tls_max_index = 1; /* Max index into up-to-date DTV */ @@ -247,7 +257,10 @@ _rtld_tls_allocate_locked(void) struct tls_tcb *tcb; uint8_t *p, *q; - p = xcalloc(_rtld_tls_static_space + sizeof(struct tls_tcb)); + p = xmalloc_aligned(_rtld_tls_static_space + sizeof(struct tls_tcb), + _rtld_tls_static_max_align, 0); + + memset(p, 0, _rtld_tls_static_space + sizeof(struct tls_tcb)); #ifdef __HAVE_TLS_VARIANT_I tcb = (struct tls_tcb *)p; p += sizeof(struct tls_tcb); @@ -384,7 +397,7 @@ _rtld_tls_module_allocate(struct tls_tcb return p; } - p = xmalloc(obj->tlssize); + p = xmalloc_aligned(obj->tlssize, obj->tlsalign, 0); memcpy(p, obj->tlsinit, obj->tlsinitsize); memset(p + obj->tlsinitsize, 0, obj->tlssize - obj->tlsinitsize); @@ -423,6 +436,7 @@ _rtld_tls_offset_allocate(Obj_Entry *obj #ifdef __HAVE_TLS_VARIANT_I offset = roundup2(_rtld_tls_static_offset, obj->tlsalign); next_offset = offset + obj->tlssize; + offset -= sizeof(struct tls_tcb); #else offset = roundup2(_rtld_tls_static_offset + obj->tlssize, obj->tlsalign); @@ -451,6 +465,9 @@ _rtld_tls_offset_allocate(Obj_Entry *obj return -1; } } + if (obj->tlsalign > _rtld_tls_static_max_align) { + _rtld_tls_static_max_align = obj->tlsalign; + } obj->tlsoffset = offset; dbg(("%s: static tls offset 0x%zx size %zu align %zu (%zx/%zx)", obj->path, obj->tlsoffset, obj->tlssize, obj->tlsalign,