Index: lib/libthr/arch/mips/include/pthread_md.h =================================================================== --- lib/libthr/arch/mips/include/pthread_md.h (revision 303126) +++ lib/libthr/arch/mips/include/pthread_md.h (working copy) @@ -61,6 +61,7 @@ _tcb_set(struct tcb *tcb) /* * Get the current tcb. */ +#ifdef TLS_USE_SYSARCH static __inline struct tcb * _tcb_get(void) { @@ -70,6 +71,55 @@ _tcb_get(void) return tcb; } +#else /* ! TLS_USE_SYSARCH */ + +# if defined(__mips_n64) +static __inline struct tcb * +_tcb_get(void) +{ + uint64_t _rv; + + __asm__ __volatile__ ( + ".set\tpush\n\t" + ".set\tmips64r2\n\t" + "rdhwr\t%0, $29\n\t" + ".set\tpop" + : "=v" (_rv)); + + /* + * XXXSS See 'git show c6be4f4d2d1b71c04de5d3bbb6933ce2dbcdb317' + * + * Remove the offset since this really a request to get the TLS + * pointer via sysarch() (in theory). Of course, this may go away + * once the TLS code is rewritten. + */ + return (struct tcb *)(_rv - TLS_TP_OFFSET - TLS_TCB_SIZE); +} +# else /* mips 32 */ +static __inline struct tcb * +_tcb_get(void) +{ + uint32_t _rv; + + __asm__ __volatile__ ( + ".set\tpush\n\t" + ".set\tmips32r2\n\t" + "rdhwr\t%0, $29\n\t" + ".set\tpop" + : "=v" (_rv)); + + /* + * XXXSS See 'git show c6be4f4d2d1b71c04de5d3bbb6933ce2dbcdb317' + * + * Remove the offset since this really a request to get the TLS + * pointer via sysarch() (in theory). Of course, this may go away + * once the TLS code is rewritten. + */ + return (struct tcb *)(_rv - TLS_TP_OFFSET - TLS_TCB_SIZE); +} +# endif /* ! __mips_n64 */ +#endif /* ! TLS_USE_SYSARCH */ + extern struct pthread *_thr_initial; static __inline struct pthread * Index: libexec/rtld-elf/mips/reloc.c =================================================================== --- libexec/rtld-elf/mips/reloc.c (revision 303126) +++ libexec/rtld-elf/mips/reloc.c (working copy) @@ -634,13 +634,67 @@ allocate_initial_tls(Obj_Entry *objs) sysarch(MIPS_SET_TLS, tls); } +#ifdef __mips_n64 void * +_mips_get_tls(void) +{ + uint64_t _rv; + + __asm__ __volatile__ ( + ".set\tpush\n\t" + ".set\tmips64r2\n\t" + "rdhwr\t%0, $29\n\t" + ".set\tpop" + : "=v" (_rv)); + /* + * XXXSS See 'git show c6be4f4d2d1b71c04de5d3bbb6933ce2dbcdb317' + * + * Remove the offset since this really a request to get the TLS + * pointer via sysarch() (in theory). Of course, this may go away + * once the TLS code is rewritten. + */ + _rv = _rv - TLS_TP_OFFSET - TLS_TCB_SIZE; + + return (void *)_rv; +} + +#else /* mips 32 */ + +void * +_mips_get_tls(void) +{ + uint32_t _rv; + + __asm__ __volatile__ ( + ".set\tpush\n\t" + ".set\tmips32r2\n\t" + "rdhwr\t%0, $29\n\t" + ".set\tpop" + : "=v" (_rv)); + /* + * XXXSS See 'git show c6be4f4d2d1b71c04de5d3bbb6933ce2dbcdb317' + * + * Remove the offset since this really a request to get the TLS + * pointer via sysarch() (in theory). Of course, this may go away + * once the TLS code is rewritten. + */ + _rv = _rv - TLS_TP_OFFSET - TLS_TCB_SIZE; + + return (void *)_rv; +} +#endif /* ! __mips_n64 */ + +void * __tls_get_addr(tls_index* ti) { Elf_Addr** tls; char *p; +#ifdef TLS_USE_SYSARCH sysarch(MIPS_GET_TLS, &tls); +#else + tls = _mips_get_tls(); +#endif p = tls_get_addr_common(tls, ti->ti_module, ti->ti_offset + TLS_DTP_OFFSET);