diff --git a/src/internal/pthread_impl.h b/src/internal/pthread_impl.h index 56b92b22..f7facba3 100644 --- a/src/internal/pthread_impl.h +++ b/src/internal/pthread_impl.h @@ -22,7 +22,7 @@ struct pthread { struct pthread *self; - void *dtv, *unused1, *unused2; + void **dtv, *unused1, *unused2; uintptr_t sysinfo; uintptr_t canary; pid_t tid, pid; diff --git a/src/ldso/dynlink.c b/src/ldso/dynlink.c index 4e0b9f4e..774ab849 100644 --- a/src/ldso/dynlink.c +++ b/src/ldso/dynlink.c @@ -654,6 +654,16 @@ void *__copy_tls(unsigned char *mem, size_t cnt) return mem; } +void *__tls_get_addr(size_t *p) +{ + pthread_t self = __pthread_self(); + if ((size_t)self->dtv[0] < p[0]) { + // FIXME: obtain new DTV and TLS from the DSO + a_crash(); + } + return (char *)self->dtv[p[0]] + p[1]; +} + void *__dynlink(int argc, char **argv) { size_t aux[AUX_CNT] = {0}; diff --git a/src/thread/i386/tls.s b/src/thread/i386/tls.s new file mode 100644 index 00000000..e1f22629 --- /dev/null +++ b/src/thread/i386/tls.s @@ -0,0 +1,8 @@ +.text +.global ___tls_get_addr +.type ___tls_get_addr,@function +___tls_get_addr: + push %eax + call __tls_get_addr + pop %edx + ret diff --git a/src/thread/tls.c b/src/thread/tls.c new file mode 100644 index 00000000..e69de29b