Date: Mon, 20 Aug 2018 18:00:21 +0200 From: Michal Meloun <melounmichal@gmail.com> To: Brooks Davis <brooks@FreeBSD.org>, src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: Re: svn commit: r337978 - in head/libexec/rtld-elf: . aarch64 arm mips powerpc powerpc64 riscv Message-ID: <29d939de-108e-c7c4-b4b6-4a7772dca2eb@freebsd.org> In-Reply-To: <201808171619.w7HGJlZe015255@repo.freebsd.org> References: <201808171619.w7HGJlZe015255@repo.freebsd.org>
next in thread | previous in thread | raw e-mail | index | archive | help
On 17.08.2018 18:19, Brooks Davis wrote: > Author: brooks > Date: Fri Aug 17 16:19:47 2018 > New Revision: 337978 > URL: https://svnweb.freebsd.org/changeset/base/337978 > > Log: > Rework rtld's TLS Variant I implementation to match r326794 > > The above commit fixed handling overaligned TLS segments in libc's > TLS Variant I implementation, but rtld provides its own implementation > for dynamically-linked executables which lacks these fixes. Thus, > port these changes to rtld. > > Submitted by: James Clarke > Reviewed by: kbowling > Testing byL kbowling (powerpc64), br (riscv), kevans (armv7) > Obtained from: CheriBSD > Sponsored by: DARPA, AFRL > Differential Revision: https://reviews.freebsd.org/D16510 > > Modified: > head/libexec/rtld-elf/aarch64/rtld_machdep.h > head/libexec/rtld-elf/arm/rtld_machdep.h > head/libexec/rtld-elf/mips/rtld_machdep.h > head/libexec/rtld-elf/powerpc/rtld_machdep.h > head/libexec/rtld-elf/powerpc64/rtld_machdep.h > head/libexec/rtld-elf/riscv/rtld_machdep.h > head/libexec/rtld-elf/rtld.c > This commit breaks TLS handling for (at least) armv7. Can you please revert it until I will be able to identify where is problem? In my case, the libc _ThreadRuneLocale symbol is not zero on program start. Thanks, Michal > Modified: head/libexec/rtld-elf/aarch64/rtld_machdep.h > ============================================================================== > --- head/libexec/rtld-elf/aarch64/rtld_machdep.h Fri Aug 17 16:07:06 2018 (r337977) > +++ head/libexec/rtld-elf/aarch64/rtld_machdep.h Fri Aug 17 16:19:47 2018 (r337978) > @@ -69,6 +69,8 @@ Elf_Addr reloc_jmpslot(Elf_Addr *where, Elf_Addr targe > #define calculate_tls_offset(prev_offset, prev_size, size, align) \ > 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 > > #define TLS_TCB_SIZE 16 > typedef struct { > > Modified: head/libexec/rtld-elf/arm/rtld_machdep.h > ============================================================================== > --- head/libexec/rtld-elf/arm/rtld_machdep.h Fri Aug 17 16:07:06 2018 (r337977) > +++ head/libexec/rtld-elf/arm/rtld_machdep.h Fri Aug 17 16:19:47 2018 (r337978) > @@ -69,6 +69,8 @@ typedef struct { > #define calculate_tls_offset(prev_offset, prev_size, size, align) \ > 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 > > extern void *__tls_get_addr(tls_index *ti); > > > Modified: head/libexec/rtld-elf/mips/rtld_machdep.h > ============================================================================== > --- head/libexec/rtld-elf/mips/rtld_machdep.h Fri Aug 17 16:07:06 2018 (r337977) > +++ head/libexec/rtld-elf/mips/rtld_machdep.h Fri Aug 17 16:19:47 2018 (r337978) > @@ -64,10 +64,11 @@ typedef struct { > #define round(size, align) \ > (((size) + (align) - 1) & ~((align) - 1)) > #define calculate_first_tls_offset(size, align) \ > - round(TLS_TCB_SIZE, align) > + TLS_TCB_SIZE > #define calculate_tls_offset(prev_offset, prev_size, size, align) \ > 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); > > > Modified: head/libexec/rtld-elf/powerpc/rtld_machdep.h > ============================================================================== > --- head/libexec/rtld-elf/powerpc/rtld_machdep.h Fri Aug 17 16:07:06 2018 (r337977) > +++ head/libexec/rtld-elf/powerpc/rtld_machdep.h Fri Aug 17 16:19:47 2018 (r337978) > @@ -74,10 +74,11 @@ void _rtld_powerpc_pltcall(void); > #define round(size, align) \ > (((size) + (align) - 1) & ~((align) - 1)) > #define calculate_first_tls_offset(size, align) \ > - round(8, align) > + TLS_TCB_SIZE > #define calculate_tls_offset(prev_offset, prev_size, size, align) \ > round(prev_offset + prev_size, align) > #define calculate_tls_end(off, size) ((off) + (size)) > +#define calculate_tls_post_size(align) 0 > > typedef struct { > unsigned long ti_module; > > Modified: head/libexec/rtld-elf/powerpc64/rtld_machdep.h > ============================================================================== > --- head/libexec/rtld-elf/powerpc64/rtld_machdep.h Fri Aug 17 16:07:06 2018 (r337977) > +++ head/libexec/rtld-elf/powerpc64/rtld_machdep.h Fri Aug 17 16:19:47 2018 (r337978) > @@ -66,10 +66,11 @@ Elf_Addr reloc_jmpslot(Elf_Addr *where, Elf_Addr targe > #define round(size, align) \ > (((size) + (align) - 1) & ~((align) - 1)) > #define calculate_first_tls_offset(size, align) \ > - round(16, align) > + TLS_TCB_SIZE > #define calculate_tls_offset(prev_offset, prev_size, size, align) \ > round(prev_offset + prev_size, align) > #define calculate_tls_end(off, size) ((off) + (size)) > +#define calculate_tls_post_size(align) 0 > > typedef struct { > unsigned long ti_module; > > Modified: head/libexec/rtld-elf/riscv/rtld_machdep.h > ============================================================================== > --- head/libexec/rtld-elf/riscv/rtld_machdep.h Fri Aug 17 16:07:06 2018 (r337977) > +++ head/libexec/rtld-elf/riscv/rtld_machdep.h Fri Aug 17 16:19:47 2018 (r337978) > @@ -89,10 +89,11 @@ Elf_Addr reloc_jmpslot(Elf_Addr *where, Elf_Addr targe > #define round(size, align) \ > (((size) + (align) - 1) & ~((align) - 1)) > #define calculate_first_tls_offset(size, align) \ > - round(16, align) > + TLS_TCB_SIZE > #define calculate_tls_offset(prev_offset, prev_size, size, align) \ > round(prev_offset + prev_size, align) > #define calculate_tls_end(off, size) ((off) + (size)) > +#define calculate_tls_post_size(align) 0 > > typedef struct { > unsigned long ti_module; > > Modified: head/libexec/rtld-elf/rtld.c > ============================================================================== > --- head/libexec/rtld-elf/rtld.c Fri Aug 17 16:07:06 2018 (r337977) > +++ head/libexec/rtld-elf/rtld.c Fri Aug 17 16:19:47 2018 (r337978) > @@ -4693,47 +4693,87 @@ tls_get_addr_common(Elf_Addr **dtvp, int index, size_t > defined(__powerpc__) || defined(__riscv) > > /* > + * Return pointer to allocated TLS block > + */ > +static void * > +get_tls_block_ptr(void *tcb, size_t tcbsize) > +{ > + size_t extra_size, post_size, pre_size, tls_block_size; > + size_t tls_init_align; > + > + tls_init_align = MAX(obj_main->tlsalign, 1); > + > + /* Compute fragments sizes. */ > + extra_size = tcbsize - TLS_TCB_SIZE; > + post_size = calculate_tls_post_size(tls_init_align); > + tls_block_size = tcbsize + post_size; > + pre_size = roundup2(tls_block_size, tls_init_align) - tls_block_size; > + > + return ((char *)tcb - pre_size - extra_size); > +} > + > +/* > * Allocate Static TLS using the Variant I method. > + * > + * For details on the layout, see lib/libc/gen/tls.c. > + * > + * NB: rtld's tls_static_space variable includes TLS_TCB_SIZE and post_size as > + * it is based on tls_last_offset, and TLS offsets here are really TCB > + * offsets, whereas libc's tls_static_space is just the executable's static > + * TLS segment. > */ > void * > allocate_tls(Obj_Entry *objs, void *oldtcb, size_t tcbsize, size_t tcbalign) > { > Obj_Entry *obj; > - char *tcb; > - Elf_Addr **tls; > - Elf_Addr *dtv; > + char *tls_block; > + Elf_Addr *dtv, **tcb; > Elf_Addr addr; > int i; > + size_t extra_size, maxalign, post_size, pre_size, tls_block_size; > + size_t tls_init_align; > > if (oldtcb != NULL && tcbsize == TLS_TCB_SIZE) > return (oldtcb); > > assert(tcbsize >= TLS_TCB_SIZE); > - tcb = xcalloc(1, tls_static_space - TLS_TCB_SIZE + tcbsize); > - tls = (Elf_Addr **)(tcb + tcbsize - TLS_TCB_SIZE); > + maxalign = MAX(tcbalign, tls_static_max_align); > + tls_init_align = MAX(obj_main->tlsalign, 1); > > + /* Compute fragmets sizes. */ > + extra_size = tcbsize - TLS_TCB_SIZE; > + post_size = calculate_tls_post_size(tls_init_align); > + tls_block_size = tcbsize + post_size; > + pre_size = roundup2(tls_block_size, tls_init_align) - tls_block_size; > + tls_block_size += pre_size + tls_static_space - TLS_TCB_SIZE - post_size; > + > + /* Allocate whole TLS block */ > + tls_block = malloc_aligned(tls_block_size, maxalign); > + tcb = (Elf_Addr **)(tls_block + pre_size + extra_size); > + > if (oldtcb != NULL) { > - memcpy(tls, oldtcb, tls_static_space); > - free(oldtcb); > + memcpy(tls_block, get_tls_block_ptr(oldtcb, tcbsize), > + tls_static_space); > + free_aligned(get_tls_block_ptr(oldtcb, tcbsize)); > > /* Adjust the DTV. */ > - dtv = tls[0]; > + dtv = tcb[0]; > for (i = 0; i < dtv[1]; i++) { > if (dtv[i+2] >= (Elf_Addr)oldtcb && > dtv[i+2] < (Elf_Addr)oldtcb + tls_static_space) { > - dtv[i+2] = dtv[i+2] - (Elf_Addr)oldtcb + (Elf_Addr)tls; > + dtv[i+2] = dtv[i+2] - (Elf_Addr)oldtcb + (Elf_Addr)tcb; > } > } > } else { > dtv = xcalloc(tls_max_index + 2, sizeof(Elf_Addr)); > - tls[0] = dtv; > + tcb[0] = dtv; > dtv[0] = tls_dtv_generation; > dtv[1] = tls_max_index; > > for (obj = globallist_curr(objs); obj != NULL; > obj = globallist_next(obj)) { > if (obj->tlsoffset > 0) { > - addr = (Elf_Addr)tls + obj->tlsoffset; > + addr = (Elf_Addr)tcb + obj->tlsoffset; > if (obj->tlsinitsize > 0) > memcpy((void*) addr, obj->tlsinit, obj->tlsinitsize); > if (obj->tlssize > obj->tlsinitsize) > @@ -4752,14 +4792,19 @@ free_tls(void *tcb, size_t tcbsize, size_t tcbalign) > { > Elf_Addr *dtv; > Elf_Addr tlsstart, tlsend; > - int dtvsize, i; > + size_t post_size; > + size_t dtvsize, i, tls_init_align; > > assert(tcbsize >= TLS_TCB_SIZE); > + tls_init_align = MAX(obj_main->tlsalign, 1); > > - tlsstart = (Elf_Addr)tcb + tcbsize - TLS_TCB_SIZE; > - tlsend = tlsstart + tls_static_space; > + /* Compute fragments sizes. */ > + post_size = calculate_tls_post_size(tls_init_align); > > - dtv = *(Elf_Addr **)tlsstart; > + tlsstart = (Elf_Addr)tcb + TLS_TCB_SIZE + post_size; > + tlsend = (Elf_Addr)tcb + tls_static_space; > + > + dtv = *(Elf_Addr **)tcb; > dtvsize = dtv[1]; > for (i = 0; i < dtvsize; i++) { > if (dtv[i+2] && (dtv[i+2] < tlsstart || dtv[i+2] >= tlsend)) { > @@ -4767,7 +4812,7 @@ free_tls(void *tcb, size_t tcbsize, size_t tcbalign) > } > } > free(dtv); > - free(tcb); > + free_aligned(get_tls_block_ptr(tcb, tcbsize)); > } > > #endif >
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?29d939de-108e-c7c4-b4b6-4a7772dca2eb>