Module Name:    src
Committed By:   joerg
Date:           Thu Mar 10 14:27:32 UTC 2011

Modified Files:
        src/libexec/ld.elf_so: README.TLS rtld.h tls.c

Log Message:
Fix prototype for __tls_get_addr. Add a generic implementation of it
using __tls_get_addr. Update TLS notes.


To generate a diff of this commit:
cvs rdiff -u -r1.1 -r1.2 src/libexec/ld.elf_so/README.TLS \
    src/libexec/ld.elf_so/tls.c
cvs rdiff -u -r1.101 -r1.102 src/libexec/ld.elf_so/rtld.h

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/README.TLS
diff -u src/libexec/ld.elf_so/README.TLS:1.1 src/libexec/ld.elf_so/README.TLS:1.2
--- src/libexec/ld.elf_so/README.TLS:1.1	Wed Mar  9 23:10:07 2011
+++ src/libexec/ld.elf_so/README.TLS	Thu Mar 10 14:27:31 2011
@@ -3,11 +3,7 @@
 (1) Declare TLS variant in machine/types.h by defining either
 __HAVE_TLS_VARIANT_I or __HAVE_TLS_VARIANT_II.
 
-(2) crt0.o has to call _rtld_tls_static_setup() if _DYNAMIC == NULL.
-This part is already done if the new src/lib/csu/arch layout is used
-by the architecture.
-
-(3) _lwp_makecontext has to set the reserved register or kernel transfer
+(2) _lwp_makecontext has to set the reserved register or kernel transfer
 variable in uc_mcontext to the provided value of 'private'.
 
 This is not possible on the VAX as there is no free space in ucontext_t.
@@ -15,38 +11,21 @@
 everything using ucontext_t. Debug support depends on getting the data from
 ucontext_t, so the second option is possibly required.
 
-(4) _lwp_setprivate(2) has to update the same register as
+(3) _lwp_setprivate(2) has to update the same register as
 _lwp_makecontext. cpu_lwp_setprivate has to call _lwp_setprivate(2) to
 reflect the kernel view. cpu_switch has to update the mapping.
 
 _lwp_setprivate is used for the initial thread, all other threads
 created by libpthread use _lwp_makecontext for this purpose.
 
-(5) Provide __tls_get_addr and possible other MD functions for dynamic
+(4) Provide __tls_get_addr and possible other MD functions for dynamic
 TLS offset computation. If such alternative entry points exist (currently
 only i386), also add a weak reference to 0 in src/lib/libc/tls/tls.c.
 
-The generic implementation is:
-
-#include <sys/cdefs.h>
-#include <sys/tls.h>
-#include <lwp.h>
-
-/* Weak entry is overriden by ld.elf_so for dynamic linkage */
-weak_alias(__tls_get_addr, __libc__tls_get_addr)
-
-void *
-__libc__tls_get_addr(size_t idx[2])
-{
-	struct tls_tcb *tcb;
-
-	tcb = _lwp_getprivate();
-	return _rtld_tls_get_addr(tcb, idx[0], idx[1]);
-}
-
-XXX Document optimisations based idx[0]
+The generic implementation can be found in tls.c and is used with
+__HAVE_COMMON___TLS_GET_ADDR. It depends on ___lwp_getprivate_fast.
 
-(6) Implement the necessary relocation records in mdreloc.c.  There are
+(5) Implement the necessary relocation records in mdreloc.c.  There are
 typically three relocation types found in dynamic binaries:
 
 (a) R_TYPE(TLS_DTPOFF): Offset inside the module.  The common TLS code
@@ -73,7 +52,7 @@
 
 e.g. starting offset is counting down from the TCB.
 
-(7) Implement _lwp_getprivate_fast() in machine/mcontext.h and set
+(6) Implement _lwp_getprivate_fast() in machine/mcontext.h and set
 __HAVE___LWP_GETPRIVATE_FAST.
 
 (8) Test using src/tests/lib/libc/tls.  Make sure with "objdump -R" that
Index: src/libexec/ld.elf_so/tls.c
diff -u src/libexec/ld.elf_so/tls.c:1.1 src/libexec/ld.elf_so/tls.c:1.2
--- src/libexec/ld.elf_so/tls.c:1.1	Wed Mar  9 23:10:07 2011
+++ src/libexec/ld.elf_so/tls.c	Thu Mar 10 14:27:31 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: tls.c,v 1.1 2011/03/09 23:10:07 joerg Exp $	*/
+/*	$NetBSD: tls.c,v 1.2 2011/03/10 14:27:31 joerg Exp $	*/
 /*-
  * Copyright (c) 2011 The NetBSD Foundation, Inc.
  * All rights reserved.
@@ -29,9 +29,10 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: tls.c,v 1.1 2011/03/09 23:10:07 joerg Exp $");
+__RCSID("$NetBSD: tls.c,v 1.2 2011/03/10 14:27:31 joerg Exp $");
 
 #include <sys/param.h>
+#include <sys/ucontext.h>
 #include <lwp.h>
 #include <string.h>
 #include "rtld.h"
@@ -232,4 +233,28 @@
 	return;
 }
 
+#ifdef __HAVE_COMMON___TLS_GET_ADDR
+/*
+ * The fast path is access to an already allocated DTV entry.
+ * This checks the current limit and the entry without needing any
+ * locking. Entries are only freed on dlclose() and it is an application
+ * bug if code of the module is still running at that point.
+ */
+void *
+__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];
+
+	dtv = tcb->tcb_dtv;
+
+	if (__predict_true(idx < DTV_MAX_INDEX(dtv) && dtv[idx] != NULL))
+		return (uint8_t *)dtv[idx] + offset;
+
+	return _rtld_tls_get_addr(tcb, idx, offset);
+}
+#endif
+
 #endif /* __HAVE_TLS_VARIANT_I || __HAVE_TLS_VARIANT_II */

Index: src/libexec/ld.elf_so/rtld.h
diff -u src/libexec/ld.elf_so/rtld.h:1.101 src/libexec/ld.elf_so/rtld.h:1.102
--- src/libexec/ld.elf_so/rtld.h:1.101	Wed Mar  9 23:10:07 2011
+++ src/libexec/ld.elf_so/rtld.h	Thu Mar 10 14:27:31 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: rtld.h,v 1.101 2011/03/09 23:10:07 joerg Exp $	 */
+/*	$NetBSD: rtld.h,v 1.102 2011/03/10 14:27:31 joerg Exp $	 */
 
 /*
  * Copyright 1996 John D. Polstra.
@@ -374,7 +374,7 @@
 extern size_t _rtld_tls_dtv_generation;
 extern size_t _rtld_tls_max_index;
 
-__dso_public extern void __tls_get_addr(void *);
+__dso_public extern void *__tls_get_addr(void *);
 #endif
 
 /* map_object.c */

Reply via email to