From 5ffd88a18e7677876e4d2a9235c958d3b97f9abb Mon Sep 17 00:00:00 2001 From: marcel Date: Thu, 31 Aug 2006 19:16:47 +0000 Subject: 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. --- lib/libthr/arch/powerpc/include/pthread_md.h | 8 ++++++-- lib/libthr/arch/powerpc/powerpc/pthread_md.c | 4 ++-- 2 files changed, 8 insertions(+), 4 deletions(-) (limited to 'lib/libthr/arch') 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 #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); } -- cgit v1.1