diff options
| author | matt <matt@NetBSD.org> | 2011-03-12 07:43:53 +0000 |
|---|---|---|
| committer | matt <matt@NetBSD.org> | 2011-03-12 07:43:53 +0000 |
| commit | 7d1d54b5992b2ca31b4929b926df522b82304a74 (patch) | |
| tree | 0d4c68c7fe17bc8f5db15a945d02b381b2dc5223 /libexec | |
| parent | 53931d6dfd1108d6b067852e509e387337e1a136 (diff) | |
Add TLS support for PowerPC.
If the port has __lwp_gettcb_fast or __lwp_settcb use them instead of
__lwp_getprivate_fast or lwp_setprivate.
Diffstat (limited to 'libexec')
| -rw-r--r-- | libexec/ld.elf_so/arch/powerpc/ppc_reloc.c | 45 | ||||
| -rw-r--r-- | libexec/ld.elf_so/tls.c | 20 |
2 files changed, 59 insertions, 6 deletions
diff --git a/libexec/ld.elf_so/arch/powerpc/ppc_reloc.c b/libexec/ld.elf_so/arch/powerpc/ppc_reloc.c index a29ca03b3ce..3c30b2685b4 100644 --- a/libexec/ld.elf_so/arch/powerpc/ppc_reloc.c +++ b/libexec/ld.elf_so/arch/powerpc/ppc_reloc.c @@ -1,4 +1,4 @@ -/* $NetBSD: ppc_reloc.c,v 1.47 2011/02/10 02:28:20 matt Exp $ */ +/* $NetBSD: ppc_reloc.c,v 1.48 2011/03/12 07:43:53 matt Exp $ */ /*- * Copyright (C) 1998 Tsubai Masanari @@ -30,7 +30,7 @@ #include <sys/cdefs.h> #ifndef lint -__RCSID("$NetBSD: ppc_reloc.c,v 1.47 2011/02/10 02:28:20 matt Exp $"); +__RCSID("$NetBSD: ppc_reloc.c,v 1.48 2011/03/12 07:43:53 matt Exp $"); #endif /* not lint */ #include <stdarg.h> @@ -204,6 +204,47 @@ _rtld_relocate_nonplt_objects(Obj_Entry *obj) rdbg(("COPY (avoid in main)")); break; + case R_TYPE(DTPMOD32): + def = _rtld_find_symdef(symnum, obj, &defobj, false); + if (def == NULL) + return -1; + + *where = (Elf_Addr)defobj->tlsindex; + rdbg(("DTPMOD32 %s in %s --> %p in %s", + obj->strtab + obj->symtab[symnum].st_name, + obj->path, (void *)*where, defobj->path)); + break; + + case R_TYPE(DTPREL32): + def = _rtld_find_symdef(symnum, obj, &defobj, false); + if (def == NULL) + return -1; + + if (!defobj->tls_done && _rtld_tls_offset_allocate(obj)) + return -1; + + *where = (Elf_Addr)(def->st_value + rela->r_addend + - TLS_DTV_OFFSET); + rdbg(("DTPREL32 %s in %s --> %p in %s", + obj->strtab + obj->symtab[symnum].st_name, + obj->path, (void *)*where, defobj->path)); + break; + + case R_TYPE(TPREL32): + def = _rtld_find_symdef(symnum, obj, &defobj, false); + if (def == NULL) + return -1; + + if (!defobj->tls_done && _rtld_tls_offset_allocate(obj)) + return -1; + + *where = (Elf_Addr)(def->st_value + rela->r_addend + + defobj->tlsoffset - TLS_TP_OFFSET); + rdbg(("TPREL32 %s in %s --> %p in %s", + obj->strtab + obj->symtab[symnum].st_name, + obj->path, (void *)*where, defobj->path)); + break; + default: rdbg(("sym = %lu, type = %lu, offset = %p, " "addend = %p, contents = %p, symbol = %s", diff --git a/libexec/ld.elf_so/tls.c b/libexec/ld.elf_so/tls.c index 7f17951c82f..8bc2f7f2ac7 100644 --- a/libexec/ld.elf_so/tls.c +++ b/libexec/ld.elf_so/tls.c @@ -1,4 +1,4 @@ -/* $NetBSD: tls.c,v 1.2 2011/03/10 14:27:31 joerg Exp $ */ +/* $NetBSD: tls.c,v 1.3 2011/03/12 07:43:53 matt Exp $ */ /*- * Copyright (c) 2011 The NetBSD Foundation, Inc. * All rights reserved. @@ -29,7 +29,7 @@ */ #include <sys/cdefs.h> -__RCSID("$NetBSD: tls.c,v 1.2 2011/03/10 14:27:31 joerg Exp $"); +__RCSID("$NetBSD: tls.c,v 1.3 2011/03/12 07:43:53 matt Exp $"); #include <sys/param.h> #include <sys/ucontext.h> @@ -39,6 +39,10 @@ __RCSID("$NetBSD: tls.c,v 1.2 2011/03/10 14:27:31 joerg Exp $"); #if defined(__HAVE_TLS_VARIANT_I) || defined(__HAVE_TLS_VARIANT_II) +#ifndef TLS_DTV_OFFSET +#define TLS_DTV_OFFSET 0 +#endif + static size_t _rtld_tls_static_space; /* Static TLS space allocated */ static size_t _rtld_tls_static_offset; /* Next offset for static TLS to use */ size_t _rtld_tls_dtv_generation = 1; @@ -91,7 +95,11 @@ _rtld_tls_initial_allocation(void) #endif tcb = _rtld_tls_allocate(); +#ifdef __HAVE___LWP_SETTCB + __lwp_settcb(tcb); +#else _lwp_setprivate(tcb); +#endif } struct tls_tcb * @@ -245,8 +253,12 @@ __tls_get_addr(void *arg_) { size_t *arg = (size_t *)arg_; void **dtv; - struct tls_tcb *tcb = __lwp_getprivate_fast(); - size_t idx = arg[0], offset = arg[1]; +#ifdef __HAVE___LWP_GETTCB_FAST + struct tls_tcb * const tcb = __lwp_gettcb_fast(); +#else + struct tls_tcb * const tcb = __lwp_getprivate_fast(); +#endif + size_t idx = arg[0], offset = arg[1] + TLS_DTV_OFFSET; dtv = tcb->tcb_dtv; |
