beginnings of full TLS support in shared libraries
authorRich Felker <dalias@aerifal.cx>
Fri, 5 Oct 2012 01:01:56 +0000 (21:01 -0400)
committerRich Felker <dalias@aerifal.cx>
Fri, 5 Oct 2012 01:01:56 +0000 (21:01 -0400)
this code will not work yet because the necessary relocations are not
supported, and cannot be supported without some internal changes to
how relocation processing works (coming soon).

src/internal/pthread_impl.h
src/ldso/dynlink.c
src/thread/i386/tls.s [new file with mode: 0644]
src/thread/tls.c [new file with mode: 0644]

index 56b92b22cca20d9fd1b4b91ad818d34e8d9ef8d5..f7facba35c0c4a8209d41ba9c21e95d398212db4 100644 (file)
@@ -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;
index 4e0b9f4e0d6d50cabbcea804118562770aa08e80..774ab84922283a6feb5838d9a6720ee2dde7ad6f 100644 (file)
@@ -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 (file)
index 0000000..e1f2262
--- /dev/null
@@ -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 (file)
index 0000000..e69de29