+ if (main_tls.align < MIN_TLS_ALIGN) main_tls.align = MIN_TLS_ALIGN;
+
+ libc.tls_align = main_tls.align;
+ libc.tls_size = 2*sizeof(void *) + sizeof(struct pthread)
+#ifdef TLS_ABOVE_TP
+ + main_tls.offset
+#endif
+ + main_tls.size + main_tls.align
+ + MIN_TLS_ALIGN-1 & -MIN_TLS_ALIGN;
+
+ if (libc.tls_size > sizeof builtin_tls) {
+#ifndef SYS_mmap2
+#define SYS_mmap2 SYS_mmap
+#endif
+ mem = (void *)__syscall(
+ SYS_mmap2,
+ 0, libc.tls_size, PROT_READ|PROT_WRITE,
+ MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
+ /* -4095...-1 cast to void * will crash on dereference anyway,
+ * so don't bloat the init code checking for error codes and
+ * explicitly calling a_crash(). */
+ } else {
+ mem = builtin_tls;
+ }
+
+ /* Failure to initialize thread pointer is always fatal. */
+ if (__init_tp(__copy_tls(mem)) < 0)
+ a_crash();
+}
+
+weak_alias(static_init_tls, __init_tls);