NetBSD-Bugs archive

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

Re: port-sparc/54093 (Recent test regressions on sparc)



The following reply was made to PR port-sparc/54093; it has been noted by GNATS.

From: Takeshi Nakayama <nakayama%NetBSD.org@localhost>
To: gnats-bugs%netbsd.org@localhost, martin%NetBSD.org@localhost
Cc: port-sparc-maintainer%netbsd.org@localhost, netbsd-bugs%netbsd.org@localhost,
        gnats-admin%netbsd.org@localhost, gson%gson.org@localhost
Subject: Re: port-sparc/54093 (Recent test regressions on sparc)
Date: Sun, 03 Nov 2019 04:01:30 +0900 (JST)

 Hello,
 
 I found that the cause of this probrem is that TLS data area is not
 properly aligned.  jemalloc uses TLS, so the problem has become
 apparent.
 
 netbsd-8% readelf -l /lib/libc.so | egrep 'TLS|Align'
   Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
   TLS            0x140000 0x00140000 0x00140000 0x00000 0x00004 R   0x4
 
 netbsd-9% readelf -l /lib/libc.so | egrep 'TLS|Align'
   Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
   TLS            0x1d2000 0x001e2000 0x001e2000 0x00b10 0x00b14 R   0x8
 
 When I upgraded to netbsd-9, statically linked binaries and some
 pkg binaries compiled with netbsd-8 now cause bus errors.  So I
 take a look in details and found the cause by referring to the
 following document.
 
   https://docs.oracle.com/cd/E19683-01/817-3677/6mj8mbtcb/index.html
 
 The attached patch fixes the problem (and also fixes PR/54074).
 lib/libc/tls/tls.c is a fix for statically linked binaries and
 libexec/ld.elf_so/tls.c is a fix for dynamically linked binaries.
 
 I think there is a similar problem in the case of __HAVE_TLS_VARIANT_I,
 but I couldn't confirm it because I don't have such a machine.
 
 -- Takeshi Nakayama
 
 
 Index: lib/libc/tls/tls.c
 ===================================================================
 RCS file: /cvsroot/src/lib/libc/tls/tls.c,v
 retrieving revision 1.9
 diff -u -d -r1.9 tls.c
 --- lib/libc/tls/tls.c	13 Jul 2018 19:50:21 -0000	1.9
 +++ lib/libc/tls/tls.c	1 Nov 2019 13:01:25 -0000
 @@ -57,6 +57,9 @@
  static const void *tls_initaddr;
  static size_t tls_initsize;
  static size_t tls_size;
 +#ifdef __HAVE_TLS_VARIANT_II
 +static size_t tls_align;
 +#endif
  static size_t tls_allocation;
  static void *initial_thread_tcb;
  
 @@ -85,7 +88,7 @@
  
  	if (initial_thread_tcb == NULL) {
  #ifdef __HAVE_TLS_VARIANT_II
 -		tls_size = roundup2(tls_size, sizeof(void *));
 +		tls_size = roundup2(tls_size, tls_align);
  #endif
  		tls_allocation = tls_size + sizeof(*tcb);
  
 @@ -149,6 +152,9 @@
  		tls_initaddr = (void *)(phdr->p_vaddr + data->dlpi_addr);
  		tls_initsize = phdr->p_filesz;
  		tls_size = phdr->p_memsz;
 +#ifdef __HAVE_TLS_VARIANT_II
 +		tls_align = phdr->p_align;
 +#endif
  	}
  	return 0;
  }
 Index: libexec/ld.elf_so/tls.c
 ===================================================================
 RCS file: /cvsroot/src/libexec/ld.elf_so/tls.c,v
 retrieving revision 1.12
 diff -u -d -r1.12 tls.c
 --- libexec/ld.elf_so/tls.c	13 Apr 2019 00:23:32 -0000	1.12
 +++ libexec/ld.elf_so/tls.c	1 Nov 2019 13:01:25 -0000
 @@ -48,6 +48,9 @@
  
  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 */
 +#ifndef __HAVE_TLS_VARIANT_I
 +static size_t _rtld_tls_static_align;	/* Static TLS space alignment */
 +#endif
  size_t _rtld_tls_dtv_generation = 1;
  size_t _rtld_tls_max_index = 1;
  
 @@ -99,7 +102,7 @@
  
  #ifndef __HAVE_TLS_VARIANT_I
  	_rtld_tls_static_space = roundup2(_rtld_tls_static_space,
 -	    sizeof(void *));
 +	    _rtld_tls_static_align);
  #endif
  	dbg(("_rtld_tls_static_space %zu", _rtld_tls_static_space));
  
 @@ -118,11 +121,13 @@
  	struct tls_tcb *tcb;
  	uint8_t *p, *q;
  
 -	p = xcalloc(_rtld_tls_static_space + sizeof(struct tls_tcb));
  #ifdef __HAVE_TLS_VARIANT_I
 +	p = xcalloc(_rtld_tls_static_space + sizeof(struct tls_tcb));
  	tcb = (struct tls_tcb *)p;
  	p += sizeof(struct tls_tcb);
  #else
 +	p = xcalloc(roundup2(_rtld_tls_static_space + sizeof(struct tls_tcb),
 +	    _rtld_tls_static_align));
  	p += _rtld_tls_static_space;
  	tcb = (struct tls_tcb *)p;
  	tcb->tcb_self = tcb;
 @@ -207,7 +212,11 @@
  		_rtld_die();
  	}
  
 +#ifdef __HAVE_TLS_VARIANT_I
  	p = xmalloc(obj->tlssize);
 +#else
 +	p = xmalloc(roundup2(obj->tlssize, obj->tlsalign));
 +#endif
  	memcpy(p, obj->tlsinit, obj->tlsinitsize);
  	memset(p + obj->tlsinitsize, 0, obj->tlssize - obj->tlsinitsize);
  
 @@ -260,6 +269,10 @@
  	}
  	obj->tlsoffset = offset;
  	_rtld_tls_static_offset = next_offset;
 +#ifndef __HAVE_TLS_VARIANT_I
 +	if (_rtld_tls_static_align < obj->tlsalign)
 +		_rtld_tls_static_align = obj->tlsalign;
 +#endif
  	obj->tls_done = 1;
  
  	return 0;
 


Home | Main Index | Thread Index | Old Index