Add TLS support for i386 and amd64.
This commit is contained in:
parent
fb318ab4c6
commit
e082c758ec
@ -28,29 +28,37 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <strings.h>
|
||||
#include "rtld_tls.h"
|
||||
#include "pthread_md.h"
|
||||
|
||||
/*
|
||||
* The constructors.
|
||||
*/
|
||||
struct tcb *
|
||||
_tcb_ctor(struct pthread *thread)
|
||||
_tcb_ctor(struct pthread *thread, int initial)
|
||||
{
|
||||
struct tcb *tcb;
|
||||
void *oldtls;
|
||||
|
||||
if ((tcb = malloc(sizeof(struct tcb))) != NULL) {
|
||||
bzero(tcb, sizeof(struct tcb));
|
||||
tcb->tcb_thread = thread;
|
||||
/* Allocate TDV */
|
||||
if (initial) {
|
||||
__asm __volatile("movq %%fs:0, %0" : "=r" (oldtls));
|
||||
} else {
|
||||
oldtls = NULL;
|
||||
}
|
||||
|
||||
tcb = _rtld_allocate_tls(oldtls, sizeof(struct tcb), 16);
|
||||
if (tcb) {
|
||||
tcb->tcb_thread = thread;
|
||||
bzero(&tcb->tcb_tmbx, sizeof(tcb->tcb_tmbx));
|
||||
}
|
||||
|
||||
return (tcb);
|
||||
}
|
||||
|
||||
void
|
||||
_tcb_dtor(struct tcb *tcb)
|
||||
{
|
||||
/* Free TDV */
|
||||
free(tcb);
|
||||
_rtld_free_tls(tcb, sizeof(struct tcb), 16);
|
||||
}
|
||||
|
||||
struct kcb *
|
||||
|
@ -62,8 +62,10 @@ struct kcb {
|
||||
};
|
||||
|
||||
struct tcb {
|
||||
struct tdv *tcb_tdv;
|
||||
struct tcb *tcb_self; /* required by rtld */
|
||||
void *tcb_dtv; /* required by rtld */
|
||||
struct pthread *tcb_thread;
|
||||
void *tcb_spare[1]; /* align tcb_tmbx to 16 bytes */
|
||||
struct kse_thr_mailbox tcb_tmbx;
|
||||
};
|
||||
|
||||
@ -138,7 +140,7 @@ __kcb_readandclear64(volatile u_long *addr)
|
||||
/*
|
||||
* The constructors.
|
||||
*/
|
||||
struct tcb *_tcb_ctor(struct pthread *);
|
||||
struct tcb *_tcb_ctor(struct pthread *, int);
|
||||
void _tcb_dtor(struct tcb *tcb);
|
||||
struct kcb *_kcb_ctor(struct kse *);
|
||||
void _kcb_dtor(struct kcb *);
|
||||
|
@ -39,35 +39,35 @@ __FBSDID("$FreeBSD$");
|
||||
#include <string.h>
|
||||
#include <ucontext.h>
|
||||
|
||||
#include "rtld_tls.h"
|
||||
#include "pthread_md.h"
|
||||
|
||||
struct tcb *
|
||||
_tcb_ctor(struct pthread *thread)
|
||||
_tcb_ctor(struct pthread *thread, int initial)
|
||||
{
|
||||
struct tcb *tcb;
|
||||
void *addr;
|
||||
void *oldtls;
|
||||
|
||||
addr = malloc(sizeof(struct tcb) + 15);
|
||||
if (addr == NULL)
|
||||
tcb = NULL;
|
||||
else {
|
||||
tcb = (struct tcb *)(((uintptr_t)(addr) + 15) & ~15);
|
||||
bzero(tcb, sizeof(struct tcb));
|
||||
tcb->tcb_addr = addr;
|
||||
tcb->tcb_thread = thread;
|
||||
/* XXX - Allocate tdv/tls */
|
||||
if (initial) {
|
||||
__asm __volatile("movl %%gs:0, %0" : "=r" (oldtls));
|
||||
} else {
|
||||
oldtls = NULL;
|
||||
}
|
||||
|
||||
tcb = _rtld_allocate_tls(oldtls, sizeof(struct tcb), 16);
|
||||
if (tcb) {
|
||||
tcb->tcb_thread = thread;
|
||||
tcb->tcb_spare = 0;
|
||||
bzero(&tcb->tcb_tmbx, sizeof(tcb->tcb_tmbx));
|
||||
}
|
||||
|
||||
return (tcb);
|
||||
}
|
||||
|
||||
void
|
||||
_tcb_dtor(struct tcb *tcb)
|
||||
{
|
||||
void *addr;
|
||||
|
||||
addr = tcb->tcb_addr;
|
||||
tcb->tcb_addr = NULL;
|
||||
free(addr);
|
||||
_rtld_free_tls(tcb, sizeof(struct tcb), 16);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -47,7 +47,6 @@ extern int _thr_getcontext(mcontext_t *);
|
||||
|
||||
struct kse;
|
||||
struct pthread;
|
||||
struct tdv;
|
||||
|
||||
/*
|
||||
* %gs points to a struct kcb.
|
||||
@ -61,9 +60,9 @@ struct kcb {
|
||||
};
|
||||
|
||||
struct tcb {
|
||||
struct tdv *tcb_tdv;
|
||||
struct tcb *tcb_self; /* required by rtld */
|
||||
void *tcb_dtv; /* required by rtld */
|
||||
struct pthread *tcb_thread;
|
||||
void *tcb_addr; /* allocated tcb address */
|
||||
void *tcb_spare; /* align tcb_tmbx to 16 bytes */
|
||||
struct kse_thr_mailbox tcb_tmbx;
|
||||
};
|
||||
@ -140,7 +139,7 @@ __kcb_readandclear32(volatile u_long *addr)
|
||||
/*
|
||||
* The constructors.
|
||||
*/
|
||||
struct tcb *_tcb_ctor(struct pthread *);
|
||||
struct tcb *_tcb_ctor(struct pthread *, int);
|
||||
void _tcb_dtor(struct tcb *tcb);
|
||||
struct kcb *_kcb_ctor(struct kse *);
|
||||
void _kcb_dtor(struct kcb *);
|
||||
|
@ -34,7 +34,7 @@
|
||||
* The constructors.
|
||||
*/
|
||||
struct tcb *
|
||||
_tcb_ctor(struct pthread *thread)
|
||||
_tcb_ctor(struct pthread *thread, int initial)
|
||||
{
|
||||
struct tcb *tcb;
|
||||
|
||||
|
@ -81,7 +81,7 @@ register struct ia64_tp *_tp __asm("%r13");
|
||||
/*
|
||||
* The kcb and tcb constructors.
|
||||
*/
|
||||
struct tcb *_tcb_ctor(struct pthread *);
|
||||
struct tcb *_tcb_ctor(struct pthread *, int);
|
||||
void _tcb_dtor(struct tcb *);
|
||||
struct kcb *_kcb_ctor(struct kse *kse);
|
||||
void _kcb_dtor(struct kcb *);
|
||||
|
@ -91,7 +91,7 @@ register struct sparc64_tp *_tp __asm("%g6");
|
||||
/*
|
||||
* The kcb and tcb constructors.
|
||||
*/
|
||||
struct tcb *_tcb_ctor(struct pthread *);
|
||||
struct tcb *_tcb_ctor(struct pthread *, int);
|
||||
void _tcb_dtor(struct tcb *);
|
||||
struct kcb *_kcb_ctor(struct kse *kse);
|
||||
void _kcb_dtor(struct kcb *);
|
||||
|
@ -40,7 +40,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include "pthread_md.h"
|
||||
|
||||
struct tcb *
|
||||
_tcb_ctor(struct pthread *thread)
|
||||
_tcb_ctor(struct pthread *thread, int initial)
|
||||
{
|
||||
struct tcb *tcb;
|
||||
void *addr;
|
||||
|
@ -2382,7 +2382,7 @@ _thr_alloc(struct pthread *curthread)
|
||||
if ((thread == NULL) &&
|
||||
((thread = malloc(sizeof(struct pthread))) != NULL)) {
|
||||
bzero(thread, sizeof(struct pthread));
|
||||
if ((thread->tcb = _tcb_ctor(thread)) == NULL) {
|
||||
if ((thread->tcb = _tcb_ctor(thread, curthread == NULL)) == NULL) {
|
||||
free(thread);
|
||||
thread = NULL;
|
||||
} else {
|
||||
|
@ -35,7 +35,7 @@ __FBSDID("$FreeBSD$");
|
||||
* The constructors.
|
||||
*/
|
||||
struct tcb *
|
||||
_tcb_ctor(struct pthread *thread)
|
||||
_tcb_ctor(struct pthread *thread, int initial)
|
||||
{
|
||||
struct tcb *tcb;
|
||||
|
||||
|
@ -80,7 +80,7 @@ struct kcb {
|
||||
/*
|
||||
* The kcb and tcb constructors.
|
||||
*/
|
||||
struct tcb *_tcb_ctor(struct pthread *);
|
||||
struct tcb *_tcb_ctor(struct pthread *, int);
|
||||
void _tcb_dtor(struct tcb *);
|
||||
struct kcb *_kcb_ctor(struct kse *kse);
|
||||
void _kcb_dtor(struct kcb *);
|
||||
|
@ -28,29 +28,37 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <strings.h>
|
||||
#include "rtld_tls.h"
|
||||
#include "pthread_md.h"
|
||||
|
||||
/*
|
||||
* The constructors.
|
||||
*/
|
||||
struct tcb *
|
||||
_tcb_ctor(struct pthread *thread)
|
||||
_tcb_ctor(struct pthread *thread, int initial)
|
||||
{
|
||||
struct tcb *tcb;
|
||||
void *oldtls;
|
||||
|
||||
if ((tcb = malloc(sizeof(struct tcb))) != NULL) {
|
||||
bzero(tcb, sizeof(struct tcb));
|
||||
tcb->tcb_thread = thread;
|
||||
/* Allocate TDV */
|
||||
if (initial) {
|
||||
__asm __volatile("movq %%fs:0, %0" : "=r" (oldtls));
|
||||
} else {
|
||||
oldtls = NULL;
|
||||
}
|
||||
|
||||
tcb = _rtld_allocate_tls(oldtls, sizeof(struct tcb), 16);
|
||||
if (tcb) {
|
||||
tcb->tcb_thread = thread;
|
||||
bzero(&tcb->tcb_tmbx, sizeof(tcb->tcb_tmbx));
|
||||
}
|
||||
|
||||
return (tcb);
|
||||
}
|
||||
|
||||
void
|
||||
_tcb_dtor(struct tcb *tcb)
|
||||
{
|
||||
/* Free TDV */
|
||||
free(tcb);
|
||||
_rtld_free_tls(tcb, sizeof(struct tcb), 16);
|
||||
}
|
||||
|
||||
struct kcb *
|
||||
|
@ -62,8 +62,10 @@ struct kcb {
|
||||
};
|
||||
|
||||
struct tcb {
|
||||
struct tdv *tcb_tdv;
|
||||
struct tcb *tcb_self; /* required by rtld */
|
||||
void *tcb_dtv; /* required by rtld */
|
||||
struct pthread *tcb_thread;
|
||||
void *tcb_spare[1]; /* align tcb_tmbx to 16 bytes */
|
||||
struct kse_thr_mailbox tcb_tmbx;
|
||||
};
|
||||
|
||||
@ -138,7 +140,7 @@ __kcb_readandclear64(volatile u_long *addr)
|
||||
/*
|
||||
* The constructors.
|
||||
*/
|
||||
struct tcb *_tcb_ctor(struct pthread *);
|
||||
struct tcb *_tcb_ctor(struct pthread *, int);
|
||||
void _tcb_dtor(struct tcb *tcb);
|
||||
struct kcb *_kcb_ctor(struct kse *);
|
||||
void _kcb_dtor(struct kcb *);
|
||||
|
@ -39,35 +39,35 @@ __FBSDID("$FreeBSD$");
|
||||
#include <string.h>
|
||||
#include <ucontext.h>
|
||||
|
||||
#include "rtld_tls.h"
|
||||
#include "pthread_md.h"
|
||||
|
||||
struct tcb *
|
||||
_tcb_ctor(struct pthread *thread)
|
||||
_tcb_ctor(struct pthread *thread, int initial)
|
||||
{
|
||||
struct tcb *tcb;
|
||||
void *addr;
|
||||
void *oldtls;
|
||||
|
||||
addr = malloc(sizeof(struct tcb) + 15);
|
||||
if (addr == NULL)
|
||||
tcb = NULL;
|
||||
else {
|
||||
tcb = (struct tcb *)(((uintptr_t)(addr) + 15) & ~15);
|
||||
bzero(tcb, sizeof(struct tcb));
|
||||
tcb->tcb_addr = addr;
|
||||
tcb->tcb_thread = thread;
|
||||
/* XXX - Allocate tdv/tls */
|
||||
if (initial) {
|
||||
__asm __volatile("movl %%gs:0, %0" : "=r" (oldtls));
|
||||
} else {
|
||||
oldtls = NULL;
|
||||
}
|
||||
|
||||
tcb = _rtld_allocate_tls(oldtls, sizeof(struct tcb), 16);
|
||||
if (tcb) {
|
||||
tcb->tcb_thread = thread;
|
||||
tcb->tcb_spare = 0;
|
||||
bzero(&tcb->tcb_tmbx, sizeof(tcb->tcb_tmbx));
|
||||
}
|
||||
|
||||
return (tcb);
|
||||
}
|
||||
|
||||
void
|
||||
_tcb_dtor(struct tcb *tcb)
|
||||
{
|
||||
void *addr;
|
||||
|
||||
addr = tcb->tcb_addr;
|
||||
tcb->tcb_addr = NULL;
|
||||
free(addr);
|
||||
_rtld_free_tls(tcb, sizeof(struct tcb), 16);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -47,7 +47,6 @@ extern int _thr_getcontext(mcontext_t *);
|
||||
|
||||
struct kse;
|
||||
struct pthread;
|
||||
struct tdv;
|
||||
|
||||
/*
|
||||
* %gs points to a struct kcb.
|
||||
@ -61,9 +60,9 @@ struct kcb {
|
||||
};
|
||||
|
||||
struct tcb {
|
||||
struct tdv *tcb_tdv;
|
||||
struct tcb *tcb_self; /* required by rtld */
|
||||
void *tcb_dtv; /* required by rtld */
|
||||
struct pthread *tcb_thread;
|
||||
void *tcb_addr; /* allocated tcb address */
|
||||
void *tcb_spare; /* align tcb_tmbx to 16 bytes */
|
||||
struct kse_thr_mailbox tcb_tmbx;
|
||||
};
|
||||
@ -140,7 +139,7 @@ __kcb_readandclear32(volatile u_long *addr)
|
||||
/*
|
||||
* The constructors.
|
||||
*/
|
||||
struct tcb *_tcb_ctor(struct pthread *);
|
||||
struct tcb *_tcb_ctor(struct pthread *, int);
|
||||
void _tcb_dtor(struct tcb *tcb);
|
||||
struct kcb *_kcb_ctor(struct kse *);
|
||||
void _kcb_dtor(struct kcb *);
|
||||
|
@ -34,7 +34,7 @@
|
||||
* The constructors.
|
||||
*/
|
||||
struct tcb *
|
||||
_tcb_ctor(struct pthread *thread)
|
||||
_tcb_ctor(struct pthread *thread, int initial)
|
||||
{
|
||||
struct tcb *tcb;
|
||||
|
||||
|
@ -81,7 +81,7 @@ register struct ia64_tp *_tp __asm("%r13");
|
||||
/*
|
||||
* The kcb and tcb constructors.
|
||||
*/
|
||||
struct tcb *_tcb_ctor(struct pthread *);
|
||||
struct tcb *_tcb_ctor(struct pthread *, int);
|
||||
void _tcb_dtor(struct tcb *);
|
||||
struct kcb *_kcb_ctor(struct kse *kse);
|
||||
void _kcb_dtor(struct kcb *);
|
||||
|
@ -91,7 +91,7 @@ register struct sparc64_tp *_tp __asm("%g6");
|
||||
/*
|
||||
* The kcb and tcb constructors.
|
||||
*/
|
||||
struct tcb *_tcb_ctor(struct pthread *);
|
||||
struct tcb *_tcb_ctor(struct pthread *, int);
|
||||
void _tcb_dtor(struct tcb *);
|
||||
struct kcb *_kcb_ctor(struct kse *kse);
|
||||
void _kcb_dtor(struct kcb *);
|
||||
|
@ -40,7 +40,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include "pthread_md.h"
|
||||
|
||||
struct tcb *
|
||||
_tcb_ctor(struct pthread *thread)
|
||||
_tcb_ctor(struct pthread *thread, int initial)
|
||||
{
|
||||
struct tcb *tcb;
|
||||
void *addr;
|
||||
|
@ -2382,7 +2382,7 @@ _thr_alloc(struct pthread *curthread)
|
||||
if ((thread == NULL) &&
|
||||
((thread = malloc(sizeof(struct pthread))) != NULL)) {
|
||||
bzero(thread, sizeof(struct pthread));
|
||||
if ((thread->tcb = _tcb_ctor(thread)) == NULL) {
|
||||
if ((thread->tcb = _tcb_ctor(thread, curthread == NULL)) == NULL) {
|
||||
free(thread);
|
||||
thread = NULL;
|
||||
} else {
|
||||
|
Loading…
Reference in New Issue
Block a user