Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 21 Jun 2012 13:01:00 +0000 (UTC)
From:      Marius Strobl <marius@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org
Subject:   svn commit: r237394 - in stable/9/libexec/rtld-elf: . arm
Message-ID:  <201206211301.q5LD11fw014192@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: marius
Date: Thu Jun 21 13:01:00 2012
New Revision: 237394
URL: http://svn.freebsd.org/changeset/base/237394

Log:
  MFC: r231618, r233231 (partial)
  
  Add thread-local storage support for ARM to rtld-elf
  
  Reviewed by:    cognet
  Obtained from:  NetBSD

Modified:
  stable/9/libexec/rtld-elf/arm/reloc.c
  stable/9/libexec/rtld-elf/arm/rtld_machdep.h
  stable/9/libexec/rtld-elf/rtld.c
Directory Properties:
  stable/9/libexec/rtld-elf/   (props changed)

Modified: stable/9/libexec/rtld-elf/arm/reloc.c
==============================================================================
--- stable/9/libexec/rtld-elf/arm/reloc.c	Thu Jun 21 12:52:15 2012	(r237393)
+++ stable/9/libexec/rtld-elf/arm/reloc.c	Thu Jun 21 13:01:00 2012	(r237394)
@@ -10,6 +10,9 @@ __FBSDID("$FreeBSD$");
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+
+#include "machine/sysarch.h"
+
 #include "debug.h"
 #include "rtld.h"
 
@@ -235,6 +238,63 @@ reloc_nonplt_object(Obj_Entry *obj, cons
 			dbg("COPY (avoid in main)");
 			break;
 
+		case R_ARM_TLS_DTPOFF32:
+			def = find_symdef(symnum, obj, &defobj, flags, cache,
+			    lockstate);
+			if (def == NULL)
+				return -1;
+
+			tmp = (Elf_Addr)(def->st_value);
+			if (__predict_true(RELOC_ALIGNED_P(where)))
+				*where = tmp;
+			else
+				store_ptr(where, tmp);
+
+			dbg("TLS_DTPOFF32 %s in %s --> %p",
+			    obj->strtab + obj->symtab[symnum].st_name,
+			    obj->path, (void *)tmp);
+
+			break;
+		case R_ARM_TLS_DTPMOD32:
+			def = find_symdef(symnum, obj, &defobj, flags, cache,
+			    lockstate);
+			if (def == NULL)
+				return -1;
+
+			tmp = (Elf_Addr)(defobj->tlsindex);
+			if (__predict_true(RELOC_ALIGNED_P(where)))
+				*where = tmp;
+			else
+				store_ptr(where, tmp);
+
+			dbg("TLS_DTPMOD32 %s in %s --> %p",
+			    obj->strtab + obj->symtab[symnum].st_name,
+			    obj->path, (void *)tmp);
+
+			break;
+
+		case R_ARM_TLS_TPOFF32:
+			def = find_symdef(symnum, obj, &defobj, flags, cache,
+			    lockstate);
+			if (def == NULL)
+				return -1;
+
+			if (!defobj->tls_done && allocate_tls_offset(obj))
+				return -1;
+
+			/* XXX: FIXME */
+			tmp = (Elf_Addr)def->st_value + defobj->tlsoffset +
+			    TLS_TCB_SIZE;
+			if (__predict_true(RELOC_ALIGNED_P(where)))
+				*where = tmp;
+			else
+				store_ptr(where, tmp);
+			dbg("TLS_TPOFF32 %s in %s --> %p",
+			    obj->strtab + obj->symtab[symnum].st_name,
+			    obj->path, (void *)tmp);
+			break;
+
+
 		default:
 			dbg("sym = %lu, type = %lu, offset = %p, "
 			    "contents = %p, symbol = %s",
@@ -373,11 +433,26 @@ reloc_jmpslot(Elf_Addr *where, Elf_Addr 
 void
 allocate_initial_tls(Obj_Entry *objs)
 {
-	
+	void **_tp = (void **)ARM_TP_ADDRESS;
+
+	/*
+	* Fix the size of the static TLS block by using the maximum
+	* offset allocated so far and adding a bit for dynamic modules to
+	* use.
+	*/
+
+	tls_static_space = tls_last_offset + tls_last_size + RTLD_STATIC_TLS_EXTRA;
+
+	(*_tp) = (void *) allocate_tls(objs, NULL, TLS_TCB_SIZE, 8);
 }
 
 void *
 __tls_get_addr(tls_index* ti)
 {
-	return (NULL);
+	void **_tp = (void **)ARM_TP_ADDRESS;
+	char *p;
+
+	p = tls_get_addr_common((Elf_Addr **)(*_tp), ti->ti_module, ti->ti_offset);
+
+	return (p);
 }

Modified: stable/9/libexec/rtld-elf/arm/rtld_machdep.h
==============================================================================
--- stable/9/libexec/rtld-elf/arm/rtld_machdep.h	Thu Jun 21 12:52:15 2012	(r237393)
+++ stable/9/libexec/rtld-elf/arm/rtld_machdep.h	Thu Jun 21 13:01:00 2012	(r237394)
@@ -51,20 +51,20 @@ Elf_Addr reloc_jmpslot(Elf_Addr *where, 
 #define call_init_pointer(obj, target) \
 	(((InitArrFunc)(target))(main_argc, main_argv, environ))
 
+#define	TLS_TCB_SIZE	8
 typedef struct {
 	unsigned long ti_module;
 	unsigned long ti_offset;
 } tls_index;
 
 #define round(size, align) \
-	(((size) + (align) - 1) & ~((align) - 1))
+    (((size) + (align) - 1) & ~((align) - 1))
 #define calculate_first_tls_offset(size, align) \
-	round(size, align)                                     
+    round(8, align)
 #define calculate_tls_offset(prev_offset, prev_size, size, align) \
-	    round(prev_offset + prev_size, align)
+    round(prev_offset + prev_size, align)
 #define calculate_tls_end(off, size)    ((off) + (size))
 	
-	
 /*
  * Lazy binding entry point, called via PLT.
  */

Modified: stable/9/libexec/rtld-elf/rtld.c
==============================================================================
--- stable/9/libexec/rtld-elf/rtld.c	Thu Jun 21 12:52:15 2012	(r237393)
+++ stable/9/libexec/rtld-elf/rtld.c	Thu Jun 21 13:01:00 2012	(r237394)
@@ -3937,9 +3937,7 @@ tls_get_addr_common(Elf_Addr **dtvp, int
 	return (tls_get_addr_slow(dtvp, index, offset));
 }
 
-/* XXX not sure what variants to use for arm. */
-
-#if defined(__ia64__) || defined(__powerpc__)
+#if defined(__arm__) || defined(__ia64__) || defined(__powerpc__)
 
 /*
  * Allocate Static TLS using the Variant I method.
@@ -4021,7 +4019,7 @@ free_tls(void *tcb, size_t tcbsize, size
 #endif
 
 #if defined(__i386__) || defined(__amd64__) || defined(__sparc64__) || \
-    defined(__arm__) || defined(__mips__)
+    defined(__mips__)
 
 /*
  * Allocate Static TLS using the Variant II method.



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201206211301.q5LD11fw014192>