From cf79c601c4943c2285e54a5c2f8764103c78f77a Mon Sep 17 00:00:00 2001 From: gonzo Date: Fri, 10 Feb 2012 06:42:50 +0000 Subject: [PATCH 121/175] Switch MIPS TLS implementation to Variant I git-svn-id: http://svn.freebsd.org/base/head@231347 ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f (cherry picked from commit d7319277b7e014d1ee7d64cb7c38919f072a41a7) Signed-off-by: Xin Li --- libexec/rtld-elf/mips/reloc.c | 26 +++++++++++++++++++++++++- libexec/rtld-elf/mips/rtld_machdep.h | 23 +++++++++++++++++------ libexec/rtld-elf/rtld.c | 4 ++-- 3 files changed, 44 insertions(+), 9 deletions(-) diff --git a/libexec/rtld-elf/mips/reloc.c b/libexec/rtld-elf/mips/reloc.c index c160841..b954fa3 100644 --- a/libexec/rtld-elf/mips/reloc.c +++ b/libexec/rtld-elf/mips/reloc.c @@ -39,8 +39,11 @@ __FBSDID("$FreeBSD$"); #include #include +#include + #include "debug.h" #include "rtld.h" +#include "rtld_printf.h" #ifdef __mips_n64 #define GOT1_MASK 0x8000000000000000UL @@ -528,11 +531,32 @@ reloc_jmpslot(Elf_Addr *where, Elf_Addr target, const Obj_Entry *defobj, void allocate_initial_tls(Obj_Entry *objs) { + char *tls; + /* + * Fix the size of the static TLS block by using the maximum + * offset allocated so far and adding a bit for dynamic modules to + * use. + */ + 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); + + sysarch(MIPS_SET_TLS, tls); + rtld_printf("allocate_initial_tls -> %p(%p)\n", tls, tls - TLS_TP_OFFSET - TLS_TCB_SIZE); } void * __tls_get_addr(tls_index* ti) { - return (NULL); + Elf_Addr** tls; + char *p; + + 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); + + return (p + TLS_DTV_OFFSET); } diff --git a/libexec/rtld-elf/mips/rtld_machdep.h b/libexec/rtld-elf/mips/rtld_machdep.h index 8a1b786..14fdf44 100644 --- a/libexec/rtld-elf/mips/rtld_machdep.h +++ b/libexec/rtld-elf/mips/rtld_machdep.h @@ -47,21 +47,32 @@ Elf_Addr reloc_jmpslot(Elf_Addr *where, Elf_Addr target, #define call_initfini_pointer(obj, target) \ (((InitFunc)(target))()) - + +/* + * TLS + */ + +#define TLS_TP_OFFSET 0x7000 +#define TLS_DTV_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; } tls_index; #define round(size, align) \ - (((size) + (align) - 1) & ~((align) - 1)) + (((size) + (align) - 1) & ~((align) - 1)) #define calculate_first_tls_offset(size, align) \ - round(size, align) + round(TLS_TCB_SIZE, align) #define calculate_tls_offset(prev_offset, prev_size, size, align) \ - round(prev_offset + prev_size, align) + round(prev_offset + prev_size, align) #define calculate_tls_end(off, size) ((off) + (size)) - - + /* * Lazy binding entry point, called via PLT. */ diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c index 53e44d5..c0b2757 100644 --- a/libexec/rtld-elf/rtld.c +++ b/libexec/rtld-elf/rtld.c @@ -3543,7 +3543,7 @@ tls_get_addr_common(Elf_Addr** dtvp, int index, size_t offset) /* XXX not sure what variants to use for arm. */ -#if defined(__ia64__) || defined(__powerpc__) +#if defined(__ia64__) || defined(__powerpc__) || defined(__mips__) /* * Allocate Static TLS using the Variant I method. @@ -3625,7 +3625,7 @@ free_tls(void *tcb, size_t tcbsize, size_t tcbalign) #endif #if defined(__i386__) || defined(__amd64__) || defined(__sparc64__) || \ - defined(__arm__) || defined(__mips__) + defined(__arm__) /* * Allocate Static TLS using the Variant II method. -- 1.7.9.4