Module Name:    src
Committed By:   matt
Date:           Sat Mar 12 07:43:53 UTC 2011

Modified Files:
        src/libexec/ld.elf_so: tls.c
        src/libexec/ld.elf_so/arch/powerpc: ppc_reloc.c

Log Message:
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.


To generate a diff of this commit:
cvs rdiff -u -r1.2 -r1.3 src/libexec/ld.elf_so/tls.c
cvs rdiff -u -r1.47 -r1.48 src/libexec/ld.elf_so/arch/powerpc/ppc_reloc.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/libexec/ld.elf_so/tls.c
diff -u src/libexec/ld.elf_so/tls.c:1.2 src/libexec/ld.elf_so/tls.c:1.3
--- src/libexec/ld.elf_so/tls.c:1.2	Thu Mar 10 14:27:31 2011
+++ src/libexec/ld.elf_so/tls.c	Sat Mar 12 07:43:53 2011
@@ -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 @@
 
 #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 @@
 #endif
 
 	tcb = _rtld_tls_allocate();
+#ifdef __HAVE___LWP_SETTCB
+	__lwp_settcb(tcb);
+#else
 	_lwp_setprivate(tcb);
+#endif
 }
 
 struct tls_tcb *
@@ -245,8 +253,12 @@
 {
 	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;
 

Index: src/libexec/ld.elf_so/arch/powerpc/ppc_reloc.c
diff -u src/libexec/ld.elf_so/arch/powerpc/ppc_reloc.c:1.47 src/libexec/ld.elf_so/arch/powerpc/ppc_reloc.c:1.48
--- src/libexec/ld.elf_so/arch/powerpc/ppc_reloc.c:1.47	Thu Feb 10 02:28:20 2011
+++ src/libexec/ld.elf_so/arch/powerpc/ppc_reloc.c	Sat Mar 12 07:43:53 2011
@@ -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 @@
 			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",

Reply via email to