summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authormarcel <marcel@FreeBSD.org>2006-08-31 19:16:47 +0000
committermarcel <marcel@FreeBSD.org>2006-08-31 19:16:47 +0000
commit5ffd88a18e7677876e4d2a9235c958d3b97f9abb (patch)
tree9d46ea1126d4b7d307b2bb586afed6f1de8e0fca /lib
parentc088f26c25233f120328b8c5e839f56324626b96 (diff)
downloadFreeBSD-src-5ffd88a18e7677876e4d2a9235c958d3b97f9abb.zip
FreeBSD-src-5ffd88a18e7677876e4d2a9235c958d3b97f9abb.tar.gz
TLS fixes:
o The TLS pointer (r2) points 0x7000 after the *end* of the TCB. o _rtld_allocate_tls() gets a pointer to the current TCB, not the current TLS pointer. o _rtld_free_tls() gets the size of the TCB structure.
Diffstat (limited to 'lib')
-rw-r--r--lib/libthr/arch/powerpc/include/pthread_md.h8
-rw-r--r--lib/libthr/arch/powerpc/powerpc/pthread_md.c4
2 files changed, 8 insertions, 4 deletions
diff --git a/lib/libthr/arch/powerpc/include/pthread_md.h b/lib/libthr/arch/powerpc/include/pthread_md.h
index 008c4cd..1557fee 100644
--- a/lib/libthr/arch/powerpc/include/pthread_md.h
+++ b/lib/libthr/arch/powerpc/include/pthread_md.h
@@ -37,6 +37,7 @@
#include <sys/types.h>
#define DTV_OFFSET offsetof(struct tcb, tcb_dtv)
+#define TLS_TP_OFFSET 0x7000
/*
* Variant I tcb. The structure layout is fixed, don't blindly
@@ -50,7 +51,7 @@ struct tcb {
register uint8_t *_tp __asm("%r2");
-#define _tcb ((struct tcb *)(_tp - sizeof(struct tcb)))
+#define _tcb ((struct tcb *)(_tp - TLS_TP_OFFSET - sizeof(struct tcb)))
struct tcb *_tcb_ctor(struct pthread *, int);
void _tcb_dtor(struct tcb *);
@@ -58,7 +59,10 @@ void _tcb_dtor(struct tcb *);
static __inline void
_tcb_set(struct tcb *tcb)
{
- _tp = (uint8_t *)tcb + sizeof(struct tcb);
+ uint8_t *tp;
+
+ tp = (uint8_t *)tcb + TLS_TP_OFFSET + sizeof(struct tcb);
+ __asm __volatile("mr %0,%1" : "=r"(_tp) : "r"(tp));
}
static __inline struct tcb *
diff --git a/lib/libthr/arch/powerpc/powerpc/pthread_md.c b/lib/libthr/arch/powerpc/powerpc/pthread_md.c
index aa02a8d..c8f88d8 100644
--- a/lib/libthr/arch/powerpc/powerpc/pthread_md.c
+++ b/lib/libthr/arch/powerpc/powerpc/pthread_md.c
@@ -41,7 +41,7 @@ _tcb_ctor(struct pthread *thread, int initial)
void *oldtls;
if (initial)
- oldtls = _tp;
+ oldtls = _tcb_get();
else
oldtls = NULL;
tcb = _rtld_allocate_tls(oldtls, sizeof(struct tcb), 16);
@@ -54,5 +54,5 @@ _tcb_ctor(struct pthread *thread, int initial)
void
_tcb_dtor(struct tcb *tcb)
{
- _rtld_free_tls(tcb, sizeof(tcb), 16);
+ _rtld_free_tls(tcb, sizeof(struct tcb), 16);
}
OpenPOWER on IntegriCloud