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.
This commit is contained in:
matt 2011-03-12 07:43:53 +00:00
parent 290d35338f
commit 130f2d3d4c
2 changed files with 59 additions and 6 deletions

View File

@ -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",

View File

@ -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;