summaryrefslogtreecommitdiff
path: root/libexec
diff options
context:
space:
mode:
authormatt <matt@NetBSD.org>2011-03-12 07:43:53 +0000
committermatt <matt@NetBSD.org>2011-03-12 07:43:53 +0000
commit7d1d54b5992b2ca31b4929b926df522b82304a74 (patch)
tree0d4c68c7fe17bc8f5db15a945d02b381b2dc5223 /libexec
parent53931d6dfd1108d6b067852e509e387337e1a136 (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.c45
-rw-r--r--libexec/ld.elf_so/tls.c20
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;