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)
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