mirror of git://git.musl-libc.org/musl
fix over-alignment of TLS, insufficient builtin TLS on 64-bit archs
a conservative estimate of 4*sizeof(size_t) was used as the minimum alignment for thread-local storage, despite the only requirements being alignment suitable for struct pthread and void* (which struct pthread already contains). additional alignment required by the application or libraries is encoded in their headers and is already applied. over-alignment prevented the builtin_tls array from ever being used in dynamic-linked programs on 64-bit archs, thereby requiring allocation at startup even in programs with no TLS of their own.
This commit is contained in:
parent
2b42c8cb37
commit
bd67959f3a
|
@ -2,6 +2,7 @@
|
|||
#include <limits.h>
|
||||
#include <sys/mman.h>
|
||||
#include <string.h>
|
||||
#include <stddef.h>
|
||||
#include "pthread_impl.h"
|
||||
#include "libc.h"
|
||||
#include "atomic.h"
|
||||
|
@ -22,7 +23,12 @@ int __init_tp(void *p)
|
|||
|
||||
#ifndef SHARED
|
||||
|
||||
static long long builtin_tls[(sizeof(struct pthread) + 64)/sizeof(long long)];
|
||||
static struct builtin_tls {
|
||||
char c;
|
||||
struct pthread pt;
|
||||
void *space[16];
|
||||
} builtin_tls[1];
|
||||
#define MIN_TLS_ALIGN offsetof(struct builtin_tls, pt)
|
||||
|
||||
struct tls_image {
|
||||
void *image;
|
||||
|
@ -86,7 +92,7 @@ void __init_tls(size_t *aux)
|
|||
}
|
||||
|
||||
T.size += (-T.size - (uintptr_t)T.image) & (T.align-1);
|
||||
if (T.align < 4*sizeof(size_t)) T.align = 4*sizeof(size_t);
|
||||
if (T.align < MIN_TLS_ALIGN) T.align = MIN_TLS_ALIGN;
|
||||
|
||||
libc.tls_size = 2*sizeof(void *)+T.size+T.align+sizeof(struct pthread);
|
||||
|
||||
|
|
|
@ -122,6 +122,13 @@ void __init_libc(char **, char *);
|
|||
|
||||
const char *__libc_get_version(void);
|
||||
|
||||
static struct builtin_tls {
|
||||
char c;
|
||||
struct pthread pt;
|
||||
void *space[16];
|
||||
} builtin_tls[1];
|
||||
#define MIN_TLS_ALIGN offsetof(struct builtin_tls, pt)
|
||||
|
||||
static struct dso *head, *tail, *ldso, *fini_head;
|
||||
static char *env_path, *sys_path;
|
||||
static unsigned long long gencnt;
|
||||
|
@ -132,10 +139,9 @@ static int noload;
|
|||
static jmp_buf *rtld_fail;
|
||||
static pthread_rwlock_t lock;
|
||||
static struct debug debug;
|
||||
static size_t tls_cnt, tls_offset, tls_align = 4*sizeof(size_t);
|
||||
static size_t tls_cnt, tls_offset, tls_align = MIN_TLS_ALIGN;
|
||||
static size_t static_tls_cnt;
|
||||
static pthread_mutex_t init_fini_lock = { ._m_type = PTHREAD_MUTEX_RECURSIVE };
|
||||
static long long builtin_tls[(sizeof(struct pthread) + 64)/sizeof(long long)];
|
||||
|
||||
struct debug *_dl_debug_addr = &debug;
|
||||
|
||||
|
|
Loading…
Reference in New Issue