diff options
-rw-r--r-- | lib/csu/alpha/crt1.c | 2 | ||||
-rw-r--r-- | lib/csu/amd64/crt1.c | 2 | ||||
-rw-r--r-- | lib/csu/arm/crt1.c | 2 | ||||
-rw-r--r-- | lib/csu/i386-elf/crt1.c | 2 | ||||
-rw-r--r-- | lib/csu/ia64/crt1.S | 5 | ||||
-rw-r--r-- | lib/csu/powerpc/crt1.c | 2 | ||||
-rw-r--r-- | lib/csu/sparc64/crt1.c | 2 | ||||
-rw-r--r-- | lib/libc/alpha/gen/Makefile.inc | 2 | ||||
-rw-r--r-- | lib/libc/alpha/gen/_set_tp.c | 37 | ||||
-rw-r--r-- | lib/libc/amd64/gen/Makefile.inc | 2 | ||||
-rw-r--r-- | lib/libc/amd64/gen/_set_tp.c | 38 | ||||
-rw-r--r-- | lib/libc/gen/tls.c | 227 | ||||
-rw-r--r-- | lib/libc/i386/gen/Makefile.inc | 2 | ||||
-rw-r--r-- | lib/libc/i386/gen/_set_tp.c | 52 | ||||
-rw-r--r-- | lib/libc/ia64/gen/Makefile.inc | 2 | ||||
-rw-r--r-- | lib/libc/ia64/gen/_set_tp.c | 35 | ||||
-rw-r--r-- | lib/libc/include/libc_private.h | 9 | ||||
-rw-r--r-- | lib/libc/powerpc/gen/Makefile.inc | 3 | ||||
-rw-r--r-- | lib/libc/powerpc/gen/_set_tp.c | 35 | ||||
-rw-r--r-- | lib/libc/sparc64/gen/Makefile.inc | 2 | ||||
-rw-r--r-- | lib/libc/sparc64/gen/_set_tp.c | 35 |
21 files changed, 490 insertions, 8 deletions
diff --git a/lib/csu/alpha/crt1.c b/lib/csu/alpha/crt1.c index b8ad3ea..7a936e9 100644 --- a/lib/csu/alpha/crt1.c +++ b/lib/csu/alpha/crt1.c @@ -93,6 +93,8 @@ _start(char **ap, void (*cleanup)(void), struct Struct_Obj_Entry *obj __unused, if (&_DYNAMIC != NULL) atexit(cleanup); + else + _init_tls(); #ifdef GCRT atexit(_mcleanup); diff --git a/lib/csu/amd64/crt1.c b/lib/csu/amd64/crt1.c index 15aec44..f1f0f7b 100644 --- a/lib/csu/amd64/crt1.c +++ b/lib/csu/amd64/crt1.c @@ -77,6 +77,8 @@ _start(char **ap, void (*cleanup)(void)) if (&_DYNAMIC != NULL) atexit(cleanup); + else + _init_tls(); #ifdef GCRT atexit(_mcleanup); diff --git a/lib/csu/arm/crt1.c b/lib/csu/arm/crt1.c index 706aaee..bcee2ca 100644 --- a/lib/csu/arm/crt1.c +++ b/lib/csu/arm/crt1.c @@ -116,6 +116,8 @@ __start(int argc, char **argv, char **env, if (&_DYNAMIC != NULL) atexit(cleanup); + else + _init_tls(); #ifdef GCRT atexit(_mcleanup); diff --git a/lib/csu/i386-elf/crt1.c b/lib/csu/i386-elf/crt1.c index 15a544c..9e8acaa 100644 --- a/lib/csu/i386-elf/crt1.c +++ b/lib/csu/i386-elf/crt1.c @@ -92,6 +92,8 @@ _start(char *ap, ...) if (&_DYNAMIC != NULL) atexit(cleanup); + else + _init_tls(); #ifdef GCRT atexit(_mcleanup); diff --git a/lib/csu/ia64/crt1.S b/lib/csu/ia64/crt1.S index 9d6fb53..8740299 100644 --- a/lib/csu/ia64/crt1.S +++ b/lib/csu/ia64/crt1.S @@ -107,6 +107,11 @@ _start: (p7) br.call.sptk b0=atexit ;; } +{ .mfb + nop 0 + nop 0 + br.call.sptk b0=_init_tls +} #ifdef GCRT { .mmi mov gp=GP diff --git a/lib/csu/powerpc/crt1.c b/lib/csu/powerpc/crt1.c index 4c98271..080691c 100644 --- a/lib/csu/powerpc/crt1.c +++ b/lib/csu/powerpc/crt1.c @@ -100,6 +100,8 @@ _start(int argc, char **argv, char **env, if (&_DYNAMIC != NULL) atexit(cleanup); + else + _init_tls(); #ifdef GCRT atexit(_mcleanup); diff --git a/lib/csu/sparc64/crt1.c b/lib/csu/sparc64/crt1.c index 9930830..19c0fad 100644 --- a/lib/csu/sparc64/crt1.c +++ b/lib/csu/sparc64/crt1.c @@ -102,6 +102,8 @@ _start(char **ap, void (*cleanup)(void), struct Struct_Obj_Entry *obj __unused, if (&_DYNAMIC != NULL) atexit(cleanup); + else + _init_tls(); #ifdef GCRT atexit(_mcleanup); diff --git a/lib/libc/alpha/gen/Makefile.inc b/lib/libc/alpha/gen/Makefile.inc index 8f69274..96a92ce 100644 --- a/lib/libc/alpha/gen/Makefile.inc +++ b/lib/libc/alpha/gen/Makefile.inc @@ -1,6 +1,6 @@ # $FreeBSD$ -SRCS+= _setjmp.S fabs.S infinity.c ldexp.c modf.c setjmp.S +SRCS+= _setjmp.S _set_tp.c fabs.S infinity.c ldexp.c modf.c setjmp.S SRCS+= flt_rounds.c fpgetmask.c fpgetround.c fpgetsticky.c fpsetmask.c \ fpsetround.c fpsetsticky.c diff --git a/lib/libc/alpha/gen/_set_tp.c b/lib/libc/alpha/gen/_set_tp.c new file mode 100644 index 0000000..e100d7b --- /dev/null +++ b/lib/libc/alpha/gen/_set_tp.c @@ -0,0 +1,37 @@ +/*- + * Copyright (c) 2004 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include <stdint.h> +#include <machine/alpha_cpu.h> + +void +_set_tp(void *tp) +{ + + alpha_pal_wrunique((uintptr_t) tp); +} diff --git a/lib/libc/amd64/gen/Makefile.inc b/lib/libc/amd64/gen/Makefile.inc index 9cae7fa..3d28e66 100644 --- a/lib/libc/amd64/gen/Makefile.inc +++ b/lib/libc/amd64/gen/Makefile.inc @@ -1,7 +1,7 @@ # @(#)Makefile.inc 8.1 (Berkeley) 6/4/93 # $FreeBSD$ -SRCS+= _setjmp.S rfork_thread.S setjmp.S sigsetjmp.S \ +SRCS+= _setjmp.S _set_tp.c rfork_thread.S setjmp.S sigsetjmp.S \ fabs.S modf.S \ infinity.c ldexp.c makecontext.c signalcontext.c \ flt_rounds.c fpgetmask.c fpsetmask.c fpgetprec.c fpsetprec.c \ diff --git a/lib/libc/amd64/gen/_set_tp.c b/lib/libc/amd64/gen/_set_tp.c new file mode 100644 index 0000000..02e5e14 --- /dev/null +++ b/lib/libc/amd64/gen/_set_tp.c @@ -0,0 +1,38 @@ +/*- + * Copyright (c) 2004 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include <string.h> +#include <stdint.h> +#include <machine/sysarch.h> + +void +_set_tp(void *tp) +{ + + amd64_set_fsbase(tp); +} diff --git a/lib/libc/gen/tls.c b/lib/libc/gen/tls.c index 1c4f8ce..59e44b7 100644 --- a/lib/libc/gen/tls.c +++ b/lib/libc/gen/tls.c @@ -32,7 +32,35 @@ * runtime from ld-elf.so.1. */ -#include <stddef.h> +#include <stdlib.h> +#include <string.h> +#include <elf.h> +#include <assert.h> +#include "libc_private.h" + +/* XXX not sure what variants to use for arm. */ + +#if defined(__ia64__) || defined(__alpha__) || defined(__powerpc__) +#define TLS_VARIANT_I +#endif +#if defined(__i386__) || defined(__amd64__) || defined(__sparc64__) +#define TLS_VARIANT_II +#endif + +#ifndef PIC + +#define round(size, align) \ + (((size) + (align) - 1) & ~((align) - 1)) + +static size_t tls_static_space; +static size_t tls_init_size; +#ifdef TLS_VARIANT_I +static size_t tls_init_offset; +#endif +static void *tls_init; + +void _rtld_free_tls(void *tcb, size_t tcbsize, size_t tcbalign); +#endif #ifdef __i386__ @@ -55,15 +83,210 @@ __tls_get_addr() return (0); } -#pragma weak _rtld_allocate_tls +#ifdef TLS_VARIANT_I + +void +_rtld_free_tls(void *tls, size_t tcbsize, size_t tcbalign) +{ +#ifndef PIC + Elf_Addr* dtv; + + dtv = ((Elf_Addr**)tls)[0]; + free(tls); + free(dtv); +#endif +} + +/* + * Allocate Static TLS using the Variant I method. + */ void * _rtld_allocate_tls(void *oldtls, size_t tcbsize, size_t tcbalign) { +#ifndef PIC + size_t size; + char *tls; + Elf_Addr *dtv; + + size = tls_static_space; + + tls = malloc(size); + dtv = malloc(3 * sizeof(Elf_Addr)); + + *(Elf_Addr**) tls = dtv; + + dtv[0] = 1; + dtv[1] = 1; + dtv[2] = (Elf_Addr)(tls + tls_init_offset); + if (oldtls) { + /* + * Copy the static TLS block over whole. + */ + memcpy(tls + tls_init_offset, + (char*) oldtls + tls_init_offset, + tls_static_space - tls_init_offset); + + /* + * We assume that this block was the one we created with + * allocate_initial_tls(). + */ + _rtld_free_tls(oldtls, 2*sizeof(Elf_Addr), sizeof(Elf_Addr)); + } else { + memcpy(tls + tls_init_offset, tls_init, tls_init_size); + memset(tls + tls_init_offset + tls_init_size, + 0, tls_static_space - tls_init_size); + } + + return tls; +#else return (0); +#endif } +#endif + +#ifdef TLS_VARIANT_II + +/* + * Free Static TLS using the Variant II method. + */ #pragma weak _rtld_free_tls void _rtld_free_tls(void *tcb, size_t tcbsize, size_t tcbalign) { +#ifndef PIC + size_t size; + Elf_Addr* dtv; + Elf_Addr tlsstart, tlsend; + + /* + * Figure out the size of the initial TLS block so that we can + * find stuff which ___tls_get_addr() allocated dynamically. + */ + size = round(tls_static_space, tcbalign); + + dtv = ((Elf_Addr**)tcb)[1]; + tlsend = (Elf_Addr) tcb; + tlsstart = tlsend - size; + free((void*) tlsstart); + free(dtv); +#endif +} + +#pragma weak _rtld_allocate_tls +/* + * Allocate Static TLS using the Variant II method. + */ +void * +_rtld_allocate_tls(void *oldtls, size_t tcbsize, size_t tcbalign) +{ +#ifndef PIC + size_t size; + char *tls; + Elf_Addr *dtv; + Elf_Addr segbase, oldsegbase; + + size = round(tls_static_space, tcbalign); + + assert(tcbsize >= 2*sizeof(Elf_Addr)); + tls = malloc(size + tcbsize); + dtv = malloc(3 * sizeof(Elf_Addr)); + + segbase = (Elf_Addr)(tls + size); + ((Elf_Addr*)segbase)[0] = segbase; + ((Elf_Addr*)segbase)[1] = (Elf_Addr) dtv; + + dtv[0] = 1; + dtv[1] = 1; + dtv[2] = segbase - tls_static_space; + + if (oldtls) { + /* + * Copy the static TLS block over whole. + */ + oldsegbase = (Elf_Addr) oldtls; + memcpy((void *)(segbase - tls_static_space), + (const void *)(oldsegbase - tls_static_space), + tls_static_space); + + /* + * We assume that this block was the one we created with + * allocate_initial_tls(). + */ + _rtld_free_tls(oldtls, 2*sizeof(Elf_Addr), sizeof(Elf_Addr)); + } else { + memcpy((void *)(segbase - tls_static_space), + tls_init, tls_init_size); + memset((void *)(segbase - tls_static_space + tls_init_size), + 0, tls_static_space - tls_init_size); + } + + return (void*) segbase; +#else + return (0); +#endif +} + +#endif + +void +_init_tls() +{ +#ifndef PIC + extern char **environ; + Elf_Addr *sp; + Elf_Auxinfo *aux, *auxp; + Elf_Phdr *phdr; + size_t phent, phnum; + int i; + + sp = (Elf_Addr *) environ; + while (*sp++ != 0) + ; + aux = (Elf_Auxinfo *) sp; + phdr = 0; + phent = phnum = 0; + for (auxp = aux; auxp->a_type != AT_NULL; auxp++) { + switch (auxp->a_type) { + case AT_PHDR: + phdr = auxp->a_un.a_ptr; + break; + + case AT_PHENT: + phent = auxp->a_un.a_val; + break; + + case AT_PHNUM: + phnum = auxp->a_un.a_val; + break; + } + } + if (phdr == 0 || phent != sizeof(Elf_Phdr) || phnum == 0) + return; + + for (i = 0; i < phnum; i++) { + if (phdr[i].p_type == PT_TLS) { +#ifdef TLS_VARIANT_I + tls_static_space = round(2*sizeof(Elf_Addr), + phdr[i].p_align) + phdr[i].p_memsz; + tls_init_offset = round(2*sizeof(Elf_Addr), + phdr[i].p_align); +#else + tls_static_space = round(phdr[i].p_memsz, + phdr[i].p_align); +#endif + tls_init_size = phdr[i].p_filesz; + tls_init = (void*) phdr[i].p_vaddr; + } + } + + if (tls_static_space > 0) { + void* tls; + + tls = _rtld_allocate_tls(NULL, 2*sizeof(Elf_Addr), + sizeof(Elf_Addr)); + + _set_tp(tls); + } +#endif } diff --git a/lib/libc/i386/gen/Makefile.inc b/lib/libc/i386/gen/Makefile.inc index 7776387..709cf5d 100644 --- a/lib/libc/i386/gen/Makefile.inc +++ b/lib/libc/i386/gen/Makefile.inc @@ -1,6 +1,6 @@ # @(#)Makefile.inc 8.1 (Berkeley) 6/4/93 # $FreeBSD$ -SRCS+= _ctx_start.S _setjmp.S alloca.S fabs.S \ +SRCS+= _ctx_start.S _setjmp.S _set_tp.c alloca.S fabs.S \ flt_rounds.c infinity.c ldexp.c makecontext.c modf.S \ rfork_thread.S setjmp.S signalcontext.c sigsetjmp.S diff --git a/lib/libc/i386/gen/_set_tp.c b/lib/libc/i386/gen/_set_tp.c new file mode 100644 index 0000000..d975b79 --- /dev/null +++ b/lib/libc/i386/gen/_set_tp.c @@ -0,0 +1,52 @@ +/*- + * Copyright (c) 2004 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include <string.h> +#include <stdint.h> +#include <machine/segments.h> +#include <machine/sysarch.h> + +void +_set_tp(void *tp) +{ + union descriptor ldt; + int sel; + + memset(&ldt, 0, sizeof(ldt)); + ldt.sd.sd_lolimit = 0xffff; /* 4G limit */ + ldt.sd.sd_lobase = ((uintptr_t)tp) & 0xffffff; + ldt.sd.sd_type = SDT_MEMRWA; + ldt.sd.sd_dpl = SEL_UPL; + ldt.sd.sd_p = 1; /* present */ + ldt.sd.sd_hilimit = 0xf; /* 4G limit */ + ldt.sd.sd_def32 = 1; /* 32 bit */ + ldt.sd.sd_gran = 1; /* limit in pages */ + ldt.sd.sd_hibase = (((uintptr_t)tp) >> 24) & 0xff; + sel = i386_set_ldt(LDT_AUTO_ALLOC, &ldt, 1); + __asm __volatile("movl %0,%%gs" : : "rm" ((sel << 3) | 7)); +} diff --git a/lib/libc/ia64/gen/Makefile.inc b/lib/libc/ia64/gen/Makefile.inc index f7dcd6a..1eb7264 100644 --- a/lib/libc/ia64/gen/Makefile.inc +++ b/lib/libc/ia64/gen/Makefile.inc @@ -2,7 +2,7 @@ SRCS+= __divdf3.S __divdi3.S __divsf3.S __divsi3.S __moddi3.S __modsi3.S \ __udivdi3.S __udivsi3.S __umoddi3.S __umodsi3.S _setjmp.S fabs.S \ - flt_rounds.c fpgetmask.c fpgetround.c fpsetmask.c \ + _set_tp.c flt_rounds.c fpgetmask.c fpgetround.c fpsetmask.c \ fpsetround.c infinity.c \ ldexp.c makecontext.c modf.c setjmp.S signalcontext.c sigsetjmp.S diff --git a/lib/libc/ia64/gen/_set_tp.c b/lib/libc/ia64/gen/_set_tp.c new file mode 100644 index 0000000..2419e10 --- /dev/null +++ b/lib/libc/ia64/gen/_set_tp.c @@ -0,0 +1,35 @@ +/*- + * Copyright (c) 2004 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +void +_set_tp(void *tpval) +{ + register void* tp __asm__("r13"); + + tp = tpval; +} diff --git a/lib/libc/include/libc_private.h b/lib/libc/include/libc_private.h index f18dde5..0f170db 100644 --- a/lib/libc/include/libc_private.h +++ b/lib/libc/include/libc_private.h @@ -113,6 +113,15 @@ extern pthread_func_entry_t __thr_jtable[]; int _yp_check(char **); #endif +/* + * Initialise TLS for static programs + */ +void _init_tls(void); + +/* + * Set the TLS thread pointer + */ +void _set_tp(void *tp); /* * This is a pointer in the C run-time startup code. It is used diff --git a/lib/libc/powerpc/gen/Makefile.inc b/lib/libc/powerpc/gen/Makefile.inc index 7e23dfb..4f8f0ea 100644 --- a/lib/libc/powerpc/gen/Makefile.inc +++ b/lib/libc/powerpc/gen/Makefile.inc @@ -3,6 +3,7 @@ SRCS += _ctx_start.S fabs.S flt_rounds.c fpgetmask.c fpgetround.c \ fpgetsticky.c fpsetmask.c fpsetround.c fpsetsticky.c \ infinity.c ldexp.c makecontext.c modf.c _setjmp.S \ - setjmp.S sigsetjmp.S signalcontext.c syncicache.c + setjmp.S sigsetjmp.S signalcontext.c syncicache.c \ + _set_tp.c diff --git a/lib/libc/powerpc/gen/_set_tp.c b/lib/libc/powerpc/gen/_set_tp.c new file mode 100644 index 0000000..045416d --- /dev/null +++ b/lib/libc/powerpc/gen/_set_tp.c @@ -0,0 +1,35 @@ +/*- + * Copyright (c) 2004 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +void +_set_tp(void *tpval) +{ + register void* tp __asm__("r2"); + + tp = (char*) tpval + 0x7008; +} diff --git a/lib/libc/sparc64/gen/Makefile.inc b/lib/libc/sparc64/gen/Makefile.inc index 022a4a3e..c228fc0 100644 --- a/lib/libc/sparc64/gen/Makefile.inc +++ b/lib/libc/sparc64/gen/Makefile.inc @@ -3,4 +3,4 @@ SRCS+= _ctx_start.S _setjmp.S fabs.S fixunsdfsi.S flt_rounds.c fpgetmask.c \ fpgetround.c fpgetsticky.c fpsetmask.c fpsetround.c fpsetsticky.c \ infinity.c ldexp.c makecontext.c modf.S \ - signalcontext.c setjmp.S sigsetjmp.S + signalcontext.c setjmp.S sigsetjmp.S _set_tp.c diff --git a/lib/libc/sparc64/gen/_set_tp.c b/lib/libc/sparc64/gen/_set_tp.c new file mode 100644 index 0000000..6255fd3 --- /dev/null +++ b/lib/libc/sparc64/gen/_set_tp.c @@ -0,0 +1,35 @@ +/*- + * Copyright (c) 2004 Doug Rabson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +void +_set_tp(void *tpval) +{ + register void* tp __asm__("%g7"); + + tp = tpval; +} |