Index: sys/mips/mips/vm_machdep.c =================================================================== --- sys/mips/mips/vm_machdep.c (revision 232436) +++ sys/mips/mips/vm_machdep.c (working copy) @@ -601,18 +601,8 @@ cpu_set_user_tls(struct thread *td, void *tls_base) { - /* - * tls_base passed to this function - * from thr_new call and points to actual TCB struct, - * so we should add TP_OFFSET + sizeof(struct tcb) - * to make it the same way TLS base is passed to - * MIPS_SET_TLS/MIPS_GET_TLS API - */ -#ifdef __mips_n64 - td->td_md.md_tls = (char*)tls_base + 0x7010; -#else - td->td_md.md_tls = (char*)tls_base + 0x7008; -#endif + td->td_md.md_tls = (char*)tls_base; + return (0); } Index: sys/mips/mips/trap.c =================================================================== --- sys/mips/mips/trap.c (revision 232436) +++ sys/mips/mips/trap.c (working copy) @@ -82,6 +82,7 @@ #include #include #include +#include #include #ifdef DDB @@ -774,6 +775,7 @@ if (inst.RType.rd == 29) { frame_regs = &(trapframe->zero); frame_regs[inst.RType.rt] = (register_t)(intptr_t)td->td_md.md_tls; + frame_regs[inst.RType.rt] += TLS_TP_OFFSET + TLS_TCB_SIZE; trapframe->pc += sizeof(int); goto out; } Index: sys/mips/include/tls.h =================================================================== --- sys/mips/include/tls.h (revision 0) +++ sys/mips/include/tls.h (working copy) @@ -0,0 +1,47 @@ +/*- + * Copyright (c) 2012 Oleksandr Tymoshenko + * 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, + * without modification, immediately at the beginning of the file. + * 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. + * + * + */ + +#ifndef __MIPS_TLS_H__ +#define __MIPS_TLS_H__ + +/* + * TLS parameters + */ + +#define TLS_TP_OFFSET 0x7000 +#define TLS_DTP_OFFSET 0x8000 + +#ifdef __mips_n64 +#define TLS_TCB_SIZE 16 +#else +#define TLS_TCB_SIZE 8 +#endif + +#endif /* __MIPS_TLS_H__ */ Index: lib/libthr/arch/mips/include/pthread_md.h =================================================================== --- lib/libthr/arch/mips/include/pthread_md.h (revision 232436) +++ lib/libthr/arch/mips/include/pthread_md.h (working copy) @@ -35,15 +35,11 @@ #include #include +#include #include #define CPU_SPINWAIT #define DTV_OFFSET offsetof(struct tcb, tcb_dtv) -#ifdef __mips_n64 -#define TP_OFFSET 0x7010 -#else -#define TP_OFFSET 0x7008 -#endif /* * Variant I tcb. The structure layout is fixed, don't blindly @@ -65,7 +61,7 @@ _tcb_set(struct tcb *tcb) { - sysarch(MIPS_SET_TLS, ((uint8_t*)tcb + TP_OFFSET)); + sysarch(MIPS_SET_TLS, tcb); } /* @@ -74,10 +70,10 @@ static __inline struct tcb * _tcb_get(void) { - uint8_t *tcb; + struct tcb *tcb; sysarch(MIPS_GET_TLS, &tcb); - return ((struct tcb *)(tcb - TP_OFFSET)); + return tcb; } extern struct pthread *_thr_initial; Index: lib/csu/mips/crt1.c =================================================================== --- lib/csu/mips/crt1.c (revision 232436) +++ lib/csu/mips/crt1.c (working copy) @@ -47,10 +47,8 @@ struct Struct_Obj_Entry; struct ps_strings; -#ifndef NOSHARED extern int _DYNAMIC; #pragma weak _DYNAMIC -#endif extern void _init(void); extern void _fini(void); @@ -91,10 +89,11 @@ __progname = s + 1; } -#ifndef NOSHARED if (&_DYNAMIC != NULL) atexit(cleanup); -#endif + else + _init_tls(); + #ifdef GCRT atexit(_mcleanup); #endif Index: lib/libc/gen/tls.c =================================================================== --- lib/libc/gen/tls.c (revision 232436) +++ lib/libc/gen/tls.c (working copy) @@ -66,11 +66,10 @@ #error TLS_TCB_ALIGN undefined for target architecture #endif -#if defined(__ia64__) || defined(__powerpc__) +#if defined(__arm__) || defined(__ia64__) || defined(__mips__) || defined(__powerpc__) #define TLS_VARIANT_I #endif -#if defined(__i386__) || defined(__amd64__) || defined(__sparc64__) || \ - defined(__arm__) || defined(__mips__) +#if defined(__i386__) || defined(__amd64__) || defined(__sparc64__) #define TLS_VARIANT_II #endif @@ -308,6 +307,13 @@ } } +#ifdef TLS_VARIANT_I + /* + * tls_static_space should include space for TLS structure + */ + tls_static_space += TLS_TCB_SIZE; +#endif + tls = _rtld_allocate_tls(NULL, TLS_TCB_SIZE, TLS_TCB_ALIGN); _set_tp(tls); Index: lib/libc/mips/gen/_set_tp.c =================================================================== --- lib/libc/mips/gen/_set_tp.c (revision 232436) +++ lib/libc/mips/gen/_set_tp.c (working copy) @@ -29,7 +29,11 @@ #include #include +#include + void _set_tp(void *tp) { + + sysarch(MIPS_SET_TLS, tp); } Index: libexec/rtld-elf/mips/reloc.c =================================================================== --- libexec/rtld-elf/mips/reloc.c (revision 232436) +++ libexec/rtld-elf/mips/reloc.c (working copy) @@ -40,6 +40,7 @@ #include #include +#include #include "debug.h" #include "rtld.h" @@ -622,8 +623,7 @@ */ tls_static_space = tls_last_offset + tls_last_size + RTLD_STATIC_TLS_EXTRA; - tls = ((char *) allocate_tls(objs, NULL, TLS_TCB_SIZE, 8) - + TLS_TP_OFFSET + TLS_TCB_SIZE); + tls = (char *) allocate_tls(objs, NULL, TLS_TCB_SIZE, 8); sysarch(MIPS_SET_TLS, tls); } @@ -636,8 +636,7 @@ sysarch(MIPS_GET_TLS, &tls); - p = tls_get_addr_common((Elf_Addr**)((Elf_Addr)tls - TLS_TP_OFFSET - - TLS_TCB_SIZE), ti->ti_module, ti->ti_offset + TLS_DTP_OFFSET); + p = tls_get_addr_common(tls, ti->ti_module, ti->ti_offset + TLS_DTP_OFFSET); return (p); } Index: libexec/rtld-elf/mips/rtld_machdep.h =================================================================== --- libexec/rtld-elf/mips/rtld_machdep.h (revision 232436) +++ libexec/rtld-elf/mips/rtld_machdep.h (working copy) @@ -31,6 +31,7 @@ #include #include +#include struct Struct_Obj_Entry; @@ -48,19 +49,6 @@ #define call_initfini_pointer(obj, target) \ (((InitFunc)(target))()) -/* - * TLS - */ - -#define TLS_TP_OFFSET 0x7000 -#define TLS_DTP_OFFSET 0x8000 - -#ifdef __mips_n64 -#define TLS_TCB_SIZE 16 -#else -#define TLS_TCB_SIZE 8 -#endif - typedef struct { unsigned long ti_module; unsigned long ti_offset;