summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/internal/pthread_impl.h2
-rw-r--r--src/ldso/dynlink.c10
-rw-r--r--src/thread/i386/tls.s8
-rw-r--r--src/thread/tls.c0
4 files changed, 19 insertions, 1 deletions
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
--- /dev/null
+++ b/src/thread/tls.c