Source-Changes-D archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: CVS commit: src/libexec/ld.elf_so



Hi,

This commit fixes my problems.
And I found one more problem.

xsltproc command from pkgsrc/textproc/libxslt gets segfault as follows:
This blocks a build of pkgsrc/databases/tdb.

$ xsltproc --nonet /usr/pkg/share/xsl/docbook/manpages/docbook.xsl              zsh: segmentation fault (core dumped)  xsltproc --nonet /usr/pkg/share/xsl/docbook/manpages/docbook.xsl
$ gdb /usr/pkg/bin/xsltproc ./xsltproc.core                                     GNU gdb (GDB) 17.1
Copyright (C) 2025 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64--netbsd".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from /usr/pkg/bin/xsltproc...
(No debugging symbols found in /usr/pkg/bin/xsltproc)
[New process 15295]
Core was generated by `xsltproc'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0  _rtld_load_library (
    name=name@entry=0x7f7fff0cc400 "/usr/pkg/lib/libxslt-plugins/freshmeat_net_projects_freshmeat_submit.so", refobj=refobj@entry=0x7ece9b002000,
--Type <RET> for more, q to quit, c to continue without paging--
    flags=flags@entry=8, mask=mask@entry=0x7f7fff0cc3a0)
    at /usr/src/libexec/ld.elf_so/search.c:197
197             assert(obj->refcount > 0);
(gdb) bt
#0  _rtld_load_library (
    name=name@entry=0x7f7fff0cc400 "/usr/pkg/lib/libxslt-plugins/freshmeat_net_projects_freshmeat_submit.so", refobj=refobj@entry=0x7ece9b002000,
    flags=flags@entry=8, mask=mask@entry=0x7f7fff0cc3a0)
    at /usr/src/libexec/ld.elf_so/search.c:197
#1  0x00007f7ff7a1fc4e in dlopen (
    name=0x7f7fff0cc400 "/usr/pkg/lib/libxslt-plugins/freshmeat_net_projects_freshmeat_submit.so", mode=514) at /usr/src/libexec/ld.elf_so/rtld.c:1697
#2  0x00007ece9afc86ec in xsltExtModuleRegisterDynamic ()
   from /usr/pkg/lib/libxslt.so.1
#3  0x00007ece9afc9f3c in xsltExtModuleTopLevelLookup ()
   from /usr/pkg/lib/libxslt.so.1
#4  0x00007ece9afb812a in xsltParseStylesheetProcess ()
   from /usr/pkg/lib/libxslt.so.1
#5  0x00007ece9afcd0db in xsltParseStylesheetInclude ()
   from /usr/pkg/lib/libxslt.so.1
#6  0x00007ece9afb80eb in xsltParseStylesheetProcess ()
   from /usr/pkg/lib/libxslt.so.1
#7  0x00007ece9afb9156 in xsltParseStylesheetUser ()
   from /usr/pkg/lib/libxslt.so.1
#8  0x00007ece9afb9248 in xsltParseStylesheetImportedDoc ()
   from /usr/pkg/lib/libxslt.so.1
#9  0x00007ece9afccf08 in xsltParseStylesheetImport ()
--Type <RET> for more, q to quit, c to continue without paging--qq
❌️ Quit
(gdb) q

search.c line 197 is a assert() of the following snippet.

   192  found:
   193          obj = _rtld_load_object(pathname, flags, mask);
   194          if (obj == OBJ_ERR)
   195                  return NULL;
   196
   197          assert(obj->refcount > 0);
   198          return obj;
   199  }

xsltproc apparently try to open non existent file,
/usr/pkg/lib/libxslt-plugins/freshmeat_net_projects_freshmeat_submit.so .
However it is detected as "found".

Thank you.

"Taylor R Campbell" <riastradh%netbsd.org@localhost> writes:

> Module Name:	src
> Committed By:	riastradh
> Date:		Mon Jul 20 18:46:37 UTC 2026
>
> Modified Files:
> 	src/libexec/ld.elf_so: tls.c xmalloc.c
>
> Log Message:
> ld.elf_so: Fix static TLS alignment on variant II platforms.
>
> Only affects obscure architectures like x86, though.
>
> Sprinkle assertions to make sure this breaks in other ways on other
> architectures too, like variant I, or variant II with _lwp_gettcb().
> Fair's fair, right?
>
> XXX We should consider verifying that every Elf_Phdr::p_align is
> reasonable (i.e., is a power of two, or is zero but only if p_memsz
> is also zero), and that p_filesz <= p_memsz, in headers.c for the
> main object and in map_object.c for other objects.
>
> PR bin/60469: bin/60469: assertion "ALIGNED_P(q, obj->tlsalign)"
> failed: file "/usr/src/libexec/ld.elf_so/tls.c", line 333
>
>
> To generate a diff of this commit:
> cvs rdiff -u -r1.29 -r1.30 src/libexec/ld.elf_so/tls.c
> cvs rdiff -u -r1.27 -r1.28 src/libexec/ld.elf_so/xmalloc.c
>
> Please note that diffs are not public domain; they are subject to the
> copyright notices on the relevant files.
>
> Modified files:
>
> Index: src/libexec/ld.elf_so/tls.c
> diff -u src/libexec/ld.elf_so/tls.c:1.29 src/libexec/ld.elf_so/tls.c:1.30
> --- src/libexec/ld.elf_so/tls.c:1.29	Sun Mar 15 13:56:17 2026
> +++ src/libexec/ld.elf_so/tls.c	Mon Jul 20 18:46:37 2026
> @@ -1,4 +1,4 @@
> -/*	$NetBSD: tls.c,v 1.29 2026/03/15 13:56:17 skrll Exp $	*/
> +/*	$NetBSD: tls.c,v 1.30 2026/07/20 18:46:37 riastradh Exp $	*/
>  /*-
>   * Copyright (c) 2011 The NetBSD Foundation, Inc.
>   * All rights reserved.
> @@ -29,7 +29,7 @@
>   */
>  
>  #include <sys/cdefs.h>
> -__RCSID("$NetBSD: tls.c,v 1.29 2026/03/15 13:56:17 skrll Exp $");
> +__RCSID("$NetBSD: tls.c,v 1.30 2026/07/20 18:46:37 riastradh Exp $");
>  
>  /*
>   * Thread-local storage
> @@ -109,7 +109,8 @@ static void *_rtld_tls_module_allocate(s
>  static size_t _rtld_tls_static_space;	/* Static TLS space allocated */
>  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;
> +static size_t _rtld_tls_static_max_align =
> +    MAX(alignof(max_align_t), alignof(struct tls_tcb));
>  
>  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 */
> @@ -249,15 +250,20 @@ _rtld_tls_initial_allocation(void)
>  
>  #ifndef __HAVE_TLS_VARIANT_I
>  	_rtld_tls_static_space = roundup2(_rtld_tls_static_space,
> -	    alignof(max_align_t));
> +	    _rtld_tls_static_max_align);
>  
>  #ifdef __HAVE___LWP_SETTCB
>  	if (_rtld_tls_static_max_align > sizeof(struct tls_tcb))
>  		_rtld_tls_static_space +=
>  		     _rtld_tls_static_max_align - sizeof(struct tls_tcb);
> +	assert(_rtld_tls_static_space % _rtld_tls_static_max_align ==
> +	    sizeof(struct tls_tcb) % _rtld_tls_static_max_align);
> +#else
> +	assert(ALIGNED_P(_rtld_tls_static_space, _rtld_tls_static_max_align));
>  #endif
>  
>  #endif
> +
>  	dbg(("_rtld_tls_static_space %zu", _rtld_tls_static_space));
>  
>  	tcb = _rtld_tls_allocate_locked();
> @@ -288,9 +294,20 @@ _rtld_tls_allocate_locked(void)
>  	Obj_Entry *obj;
>  	struct tls_tcb *tcb;
>  	uint8_t *p, *q;
> +	uint8_t *lo __diagused, *hi __diagused; /* bounds of TLS space */
> +
> +#ifdef __HAVE_TLS_VARIANT_II
> +#ifdef __HAVE___LWP_SETTCB
> +	assert(_rtld_tls_static_space % _rtld_tls_static_max_align ==
> +	    sizeof(struct tls_tcb) % _rtld_tls_static_max_align);
> +#else
> +	assert(ALIGNED_P(_rtld_tls_static_space, _rtld_tls_static_max_align));
> +#endif
> +#endif
>  
>  	p = xmalloc_aligned(_rtld_tls_static_space + sizeof(struct tls_tcb),
>  	    _rtld_tls_static_max_align, 0);
> +	assert(ALIGNED_P(p, _rtld_tls_static_max_align));
>  
>  	memset(p, 0, _rtld_tls_static_space + sizeof(struct tls_tcb));
>  #ifdef __HAVE_TLS_VARIANT_I
> @@ -298,14 +315,22 @@ _rtld_tls_allocate_locked(void)
>  	if (_rtld_tls_static_max_align > sizeof(struct tls_tcb))
>  		p += _rtld_tls_static_max_align - sizeof(struct tls_tcb);
>  #endif
> +	assert(ALIGNED_P(p, alignof(struct tls_tcb)));
>  	tcb = (struct tls_tcb *)p;
>  	p += sizeof(struct tls_tcb);
> +	assert(ALIGNED_P(p, _rtld_tls_static_max_align));
> +	lo = p;
>  #else
> +	lo = p;
>  	p += _rtld_tls_static_space;
> +	assert(ALIGNED_P(p, _rtld_tls_static_max_align));
> +	assert(ALIGNED_P(p, alignof(struct tls_tcb)));
>  	tcb = (struct tls_tcb *)p;
>  	tcb->tcb_self = tcb;
>  #endif
> -	dbg(("lwp %d tls tcb %p", _lwp_self(), tcb));
> +	hi = lo + _rtld_tls_static_space;
> +	dbg(("lwp %d tls tcb %p p %p", _lwp_self(), tcb, p));
> +	dbg(("tls range [%p,%p)", lo, hi));
>  	/*
>  	 * "2 +" because the first element is the generation and the second
>  	 * one is the maximum index.
> @@ -317,20 +342,37 @@ _rtld_tls_allocate_locked(void)
>  
>  	for (obj = _rtld_objlist; obj != NULL; obj = obj->next) {
>  		if (obj->tls_static) {
> +			dbg(("%s: [lwp %d] tls offset=0x%zx size=0x%zx"
> +				" initsize=0x%zx align=0x%zx",
> +				obj->path, _lwp_self(),
> +				obj->tlsoffset, obj->tlssize,
> +				obj->tlsinitsize, obj->tlsalign));
> +			assert(obj->tlsinitsize <= obj->tlssize);
> +			assert(obj->tlsoffset <= _rtld_tls_static_space);
> +			assert(obj->tlssize <= _rtld_tls_static_space);
>  #ifdef __HAVE_TLS_VARIANT_I
> +			assert(obj->tlsoffset <= _rtld_tls_static_space -
> +			    obj->tlssize);
>  			q = p + obj->tlsoffset;
>  #else
> +			assert(obj->tlssize <= obj->tlsoffset);
>  			q = p - obj->tlsoffset;
>  #endif
>  			dbg(("%s: [lwp %d] tls dtv %p-%p index %zu "
> -			    "offset %zx alignment %zx tlsinit %p%s",
> +			    "offset 0x%zx alignment 0x%zx tlsinit %p%s",
>  			    obj->path, _lwp_self(),
>  			    q, q + obj->tlsinitsize, obj->tlsindex,
>  			    obj->tlsoffset, obj->tlsalign, obj->tlsinit,
> -			    ALIGNED_P(q, obj->tlsalign) ? "" :
> -				 " BAD ALIGNMENT"));
> +			    (obj->tlssize == 0 || ALIGNED_P(q, obj->tlsalign))
> +				? "" : " BAD ALIGNMENT"));
>  
> -			assert(ALIGNED_P(q, obj->tlsalign));
> +			assert(lo <= q);
> +			assert(q + obj->tlssize <= hi);
> +			assert(obj->tlssize == 0 || obj->tlsalign != 0);
> +			assert(obj->tlssize == 0 ||
> +			    (obj->tlsalign & (obj->tlsalign - 1)) == 0);
> +			assert(obj->tlssize == 0 ||
> +			    ALIGNED_P(q, obj->tlsalign));
>  
>  			if (obj->tlsinitsize)
>  				memcpy(q, obj->tlsinit, obj->tlsinitsize);
> @@ -436,6 +478,11 @@ _rtld_tls_module_allocate(struct tls_tcb
>  		return p;
>  	}
>  
> +	assert(obj->tlsinitsize <= obj->tlssize);
> +	assert(obj->tlssize == 0 || obj->tlsalign != 0);
> +	assert(obj->tlssize == 0 ||
> +	    (obj->tlsalign & (obj->tlsalign - 1)) == 0);
> +
>  	p = xmalloc_aligned(obj->tlssize, obj->tlsalign, 0);
>  	memcpy(p, obj->tlsinit, obj->tlsinitsize);
>  	memset(p + obj->tlsinitsize, 0, obj->tlssize - obj->tlsinitsize);
> @@ -460,12 +507,28 @@ _rtld_tls_offset_allocate(Obj_Entry *obj
>  {
>  	size_t offset, next_offset;
>  
> +	/*
> +	 * If this object uses dynamic TLS only, the caller shouldn't
> +	 * be trying to allocate a static TLS offset.
> +	 */
>  	if (obj->tls_dynamic)
>  		return -1;
>  
> +	/*
> +	 * If we have already allocated a static TLS offset, nothing
> +	 * more to do.
> +	 */
>  	if (obj->tls_static)
>  		return 0;
>  
> +	/*
> +	 * If the TLS size is zero, not much to do here -- choose zero
> +	 * offset (always valid) and mark the object as having
> +	 * allocated a static TLS offset.
> +	 *
> +	 * XXX Is it a problem for multiple objects to have the same
> +	 * TLS offset?
> +	 */
>  	if (obj->tlssize == 0) {
>  		obj->tlsoffset = 0;
>  		obj->tls_static = 1;
> @@ -483,6 +546,7 @@ _rtld_tls_offset_allocate(Obj_Entry *obj
>  	    obj->tlsalign);
>  	next_offset = offset;
>  #endif
> +	assert(ALIGNED_P(offset, obj->tlsalign));
>  
>  	/*
>  	 * Check if the static allocation was already done.
> @@ -509,6 +573,13 @@ _rtld_tls_offset_allocate(Obj_Entry *obj
>  	if (obj->tlsalign > _rtld_tls_static_max_align) {
>  		_rtld_tls_static_max_align = obj->tlsalign;
>  	}
> +	assert(_rtld_tls_static_max_align != 0);
> +	assert((_rtld_tls_static_max_align & (_rtld_tls_static_max_align - 1))
> +	    == 0);
> +	assert(ALIGNED_P(_rtld_tls_static_max_align, obj->tlsalign));
> +	assert(ALIGNED_P(_rtld_tls_static_max_align, alignof(max_align_t)));
> +	assert(ALIGNED_P(_rtld_tls_static_max_align, alignof(struct tls_tcb)));
> +
>  	obj->tlsoffset = offset;
>  	dbg(("%s: static tls offset 0x%zx size %zu align %zu (%zx/%zx)",
>  	    obj->path, obj->tlsoffset, obj->tlssize, obj->tlsalign,
>
> Index: src/libexec/ld.elf_so/xmalloc.c
> diff -u src/libexec/ld.elf_so/xmalloc.c:1.27 src/libexec/ld.elf_so/xmalloc.c:1.28
> --- src/libexec/ld.elf_so/xmalloc.c:1.27	Sun Jul 19 19:55:24 2026
> +++ src/libexec/ld.elf_so/xmalloc.c	Mon Jul 20 18:46:37 2026
> @@ -1,4 +1,4 @@
> -/*	$NetBSD: xmalloc.c,v 1.27 2026/07/19 19:55:24 riastradh Exp $	*/
> +/*	$NetBSD: xmalloc.c,v 1.28 2026/07/20 18:46:37 riastradh Exp $	*/
>  
>  /*
>   * Copyright 1996 John D. Polstra.
> @@ -77,7 +77,7 @@
>  
>  #include <sys/cdefs.h>
>  #ifndef lint
> -__RCSID("$NetBSD: xmalloc.c,v 1.27 2026/07/19 19:55:24 riastradh Exp $");
> +__RCSID("$NetBSD: xmalloc.c,v 1.28 2026/07/20 18:46:37 riastradh Exp $");
>  #endif /* not lint */
>  
>  #include <stdlib.h>
> @@ -230,6 +230,8 @@ xmalloc_aligned(size_t size, size_t alig
>  	union overhead *ov;
>  	uintptr_t x;
>  
> +	ASSERT((align & (align - 1)) == 0);
> +
>  	if (align < FIRST_BUCKET_SIZE)
>  		align = FIRST_BUCKET_SIZE;
>  	offset &= align - 1;
>

-- 
Ryo ONODERA // ryo%tetera.org@localhost
PGP fingerprint = 82A2 DC91 76E0 A10A 8ABB  FD1B F404 27FA C7D1 15F3


Home | Main Index | Thread Index | Old Index