about summary refs log tree commit diff
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2002-02-07 08:44:37 +0000
committerUlrich Drepper <drepper@redhat.com>2002-02-07 08:44:37 +0000
commitcd30b01ee9cdefd2e6f81b1c25ee6897243706fc (patch)
tree39d460bf6b86baf4199f85a9f26d64913b82992e
parent8d4b5a8a50fad0ed1005380aa8d1c13dcfdab08d (diff)
downloadglibc-cd30b01ee9cdefd2e6f81b1c25ee6897243706fc.tar.gz
glibc-cd30b01ee9cdefd2e6f81b1c25ee6897243706fc.tar.xz
glibc-cd30b01ee9cdefd2e6f81b1c25ee6897243706fc.zip
Update.
2002-02-07  Ulrich Drepper  <drepper@redhat.com>

	* sysdeps/generic/dl-tls.c (_dl_determine_tlsoffset): Account for
	alignment of the TCB and store total size and alignment of static
	TLS block in _dl_tls_static_size and _dl_tls_static_align.
	tls_index is a typedef.
	* sysdeps/generic/ldsodefs.h: Declare _dl_tls_static_size and
	_dl_tls_static_align.
	* sysdeps/i386/dl-tls.h: tls_index is a typedef.
	* elf/dl-support.c: Define _dl_tls_static_size and
	_dl_tls_static_align.
-rw-r--r--ChangeLog12
-rw-r--r--elf/dl-support.c5
-rw-r--r--linuxthreads/ChangeLog11
-rw-r--r--linuxthreads/descr.h67
-rw-r--r--linuxthreads/internals.h65
-rw-r--r--linuxthreads/sysdeps/i386/tls.h13
-rw-r--r--sysdeps/generic/dl-tls.c25
-rw-r--r--sysdeps/generic/ldsodefs.h5
-rw-r--r--sysdeps/i386/dl-tls.h8
9 files changed, 136 insertions, 75 deletions
diff --git a/ChangeLog b/ChangeLog
index 82c1059fea..9de0606432 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2002-02-07  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/generic/dl-tls.c (_dl_determine_tlsoffset): Account for
+	alignment of the TCB and store total size and alignment of static
+	TLS block in _dl_tls_static_size and _dl_tls_static_align.
+	tls_index is a typedef.
+	* sysdeps/generic/ldsodefs.h: Declare _dl_tls_static_size and
+	_dl_tls_static_align.
+	* sysdeps/i386/dl-tls.h: tls_index is a typedef.
+	* elf/dl-support.c: Define _dl_tls_static_size and
+	_dl_tls_static_align.
+
 2002-02-06  Ulrich Drepper  <drepper@redhat.com>
 
 	* configure.in: Add --without-tls option.
diff --git a/elf/dl-support.c b/elf/dl-support.c
index 4eaa6757a2..914b43f057 100644
--- a/elf/dl-support.c
+++ b/elf/dl-support.c
@@ -147,6 +147,11 @@ struct link_map *_dl_initimage_list;
 size_t _dl_tls_max_dtv_idx;
 /* Flag signalling whether there are gaps in the module ID allocation.  */
 bool _dl_tls_dtv_gaps;
+
+/* Size of the static TLS block.  */
+size_t _dl_tls_static_size;
+/* Alignment requirement of the static TLS block.  */
+size_t _dl_tls_static_align;
 #endif
 
 
diff --git a/linuxthreads/ChangeLog b/linuxthreads/ChangeLog
index a4ab63ca2e..49f1aa752a 100644
--- a/linuxthreads/ChangeLog
+++ b/linuxthreads/ChangeLog
@@ -1,3 +1,14 @@
+2002-02-07  Ulrich Drepper  <drepper@redhat.com>
+
+	* internals.h: Move declarations/definitions of
+	__pthread_initial_thread_bos, __pthread_initial_thread,
+	__pthread_manager_thread_bos, __pthread_manager_thread_tos,
+	__pthread_manager_thread, __pthread_nonstandard_stacks, STACK_SIZE,
+	CURRENT_STACK_FRAME, __pthread_find_self, and thread_self...
+	* descr.h: ...here.
+	* sysdeps/i386/tls.h: Add TLS definitions also for !FLOATING_STACKS.
+	Define THREAD_GETMEM accordingly.
+
 2002-02-06  Ulrich Drepper  <drepper@redhat.com>
 
 	* sysdeps/i386/tls.h: Include <stddef.h> for size_t.
diff --git a/linuxthreads/descr.h b/linuxthreads/descr.h
index 4cfad89dcb..a2cddb1212 100644
--- a/linuxthreads/descr.h
+++ b/linuxthreads/descr.h
@@ -165,4 +165,71 @@ struct _pthread_descr_struct {
 				    32 bytes might give better cache
 				    utilization.  */
 
+
+
+/* Limit between the stack of the initial thread (above) and the
+   stacks of other threads (below). Aligned on a STACK_SIZE boundary.
+   Initially 0, meaning that the current thread is (by definition)
+   the initial thread. */
+
+extern char *__pthread_initial_thread_bos;
+
+/* Descriptor of the initial thread */
+
+extern struct _pthread_descr_struct __pthread_initial_thread;
+
+/* Limits of the thread manager stack. */
+
+extern char *__pthread_manager_thread_bos;
+extern char *__pthread_manager_thread_tos;
+
+/* Descriptor of the manager thread */
+
+extern struct _pthread_descr_struct __pthread_manager_thread;
+
+/* Indicate whether at least one thread has a user-defined stack (if 1),
+   or all threads have stacks supplied by LinuxThreads (if 0). */
+
+extern int __pthread_nonstandard_stacks;
+
+/* The max size of the thread stack segments.  If the default
+   THREAD_SELF implementation is used, this must be a power of two and
+   a multiple of PAGE_SIZE.  */
+#ifndef STACK_SIZE
+#define STACK_SIZE  (2 * 1024 * 1024)
+#endif
+
+/* Get some notion of the current stack.  Need not be exactly the top
+   of the stack, just something somewhere in the current frame.  */
+#ifndef CURRENT_STACK_FRAME
+#define CURRENT_STACK_FRAME  ({ char __csf; &__csf; })
+#endif
+
+/* Recover thread descriptor for the current thread */
+
+extern pthread_descr __pthread_find_self (void) __attribute__ ((const));
+
+static inline pthread_descr thread_self (void) __attribute__ ((const));
+static inline pthread_descr thread_self (void)
+{
+#ifdef THREAD_SELF
+  return THREAD_SELF;
+#else
+  char *sp = CURRENT_STACK_FRAME;
+  if (sp >= __pthread_initial_thread_bos)
+    return &__pthread_initial_thread;
+  else if (sp >= __pthread_manager_thread_bos
+	   && sp < __pthread_manager_thread_tos)
+    return &__pthread_manager_thread;
+  else if (__pthread_nonstandard_stacks)
+    return __pthread_find_self();
+  else
+#ifdef _STACK_GROWS_DOWN
+    return (pthread_descr)(((unsigned long)sp | (STACK_SIZE-1))+1) - 1;
+#else
+    return (pthread_descr)((unsigned long)sp &~ (STACK_SIZE-1));
+#endif
+#endif
+}
+
 #endif	/* descr.h */
diff --git a/linuxthreads/internals.h b/linuxthreads/internals.h
index e1768b4a1f..056e36d885 100644
--- a/linuxthreads/internals.h
+++ b/linuxthreads/internals.h
@@ -110,30 +110,10 @@ extern int __pthread_sig_debug;
 
 extern struct pthread_handle_struct __pthread_handles[PTHREAD_THREADS_MAX];
 
-/* Descriptor of the initial thread */
-
-extern struct _pthread_descr_struct __pthread_initial_thread;
-
-/* Descriptor of the manager thread */
-
-extern struct _pthread_descr_struct __pthread_manager_thread;
-
 /* Descriptor of the main thread */
 
 extern pthread_descr __pthread_main_thread;
 
-/* Limit between the stack of the initial thread (above) and the
-   stacks of other threads (below). Aligned on a STACK_SIZE boundary.
-   Initially 0, meaning that the current thread is (by definition)
-   the initial thread. */
-
-extern char *__pthread_initial_thread_bos;
-
-/* Indicate whether at least one thread has a user-defined stack (if 1),
-   or all threads have stacks supplied by LinuxThreads (if 0). */
-
-extern int __pthread_nonstandard_stacks;
-
 /* File descriptor for sending requests to the thread manager.
    Initially -1, meaning that __pthread_initialize_manager must be called. */
 
@@ -143,11 +123,6 @@ extern int __pthread_manager_request;
 
 extern int __pthread_manager_reader;
 
-/* Limits of the thread manager stack. */
-
-extern char *__pthread_manager_thread_bos;
-extern char *__pthread_manager_thread_tos;
-
 #ifdef FLOATING_STACKS
 /* Maximum stack size.  */
 extern size_t __pthread_max_stacksize;
@@ -202,13 +177,6 @@ static inline int nonexisting_handle(pthread_handle h, pthread_t id)
 #define PAGE_SIZE  (sysconf (_SC_PAGE_SIZE))
 #endif
 
-/* The max size of the thread stack segments.  If the default
-   THREAD_SELF implementation is used, this must be a power of two and
-   a multiple of PAGE_SIZE.  */
-#ifndef STACK_SIZE
-#define STACK_SIZE  (2 * 1024 * 1024)
-#endif
-
 /* The initial size of the thread stack.  Must be a multiple of PAGE_SIZE.  */
 #ifndef INITIAL_STACK_SIZE
 #define INITIAL_STACK_SIZE  (4 * PAGE_SIZE)
@@ -227,39 +195,6 @@ static inline int nonexisting_handle(pthread_handle h, pthread_t id)
 #define THREAD_STACK_START_ADDRESS  __pthread_initial_thread_bos
 #endif
 
-/* Get some notion of the current stack.  Need not be exactly the top
-   of the stack, just something somewhere in the current frame.  */
-#ifndef CURRENT_STACK_FRAME
-#define CURRENT_STACK_FRAME  ({ char __csf; &__csf; })
-#endif
-
-/* Recover thread descriptor for the current thread */
-
-extern pthread_descr __pthread_find_self (void) __attribute__ ((const));
-
-static inline pthread_descr thread_self (void) __attribute__ ((const));
-static inline pthread_descr thread_self (void)
-{
-#ifdef THREAD_SELF
-  return THREAD_SELF;
-#else
-  char *sp = CURRENT_STACK_FRAME;
-  if (sp >= __pthread_initial_thread_bos)
-    return &__pthread_initial_thread;
-  else if (sp >= __pthread_manager_thread_bos
-	   && sp < __pthread_manager_thread_tos)
-    return &__pthread_manager_thread;
-  else if (__pthread_nonstandard_stacks)
-    return __pthread_find_self();
-  else
-#ifdef _STACK_GROWS_DOWN
-    return (pthread_descr)(((unsigned long)sp | (STACK_SIZE-1))+1) - 1;
-#else
-    return (pthread_descr)((unsigned long)sp &~ (STACK_SIZE-1));
-#endif
-#endif
-}
-
 /* If MEMORY_BARRIER isn't defined in pt-machine.h, assume the architecture
    doesn't need a memory barrier instruction (e.g. Intel x86).  Some
    architectures distinguish between full, read and write barriers.  */
diff --git a/linuxthreads/sysdeps/i386/tls.h b/linuxthreads/sysdeps/i386/tls.h
index 870832c6f0..ed5e634a82 100644
--- a/linuxthreads/sysdeps/i386/tls.h
+++ b/linuxthreads/sysdeps/i386/tls.h
@@ -42,7 +42,7 @@ typedef struct
 
 
 /* We can support TLS only if the floating-stack support is available.  */
-#if FLOATING_STACKS && defined HAVE_TLS_SUPPORT
+#ifdef HAVE_TLS_SUPPORT
 
 /* Get system call information.  */
 # include <sysdep.h>
@@ -94,11 +94,16 @@ typedef struct
 
 
 /* Return the address of the dtv for the current thread.  */
-# define THREAD_DTV() \
+# if FLOATING_STACKS
+#  define THREAD_DTV() \
   ({ struct _pthread_descr_struct *__descr;				      \
      THREAD_GETMEM (__descr, p_header.data.dtvp); })
+# else
+#  define THREAD_DTV() \
+  ({ struct _pthread_descr_struct *__descr = thread_self ();		      \
+     THREAD_GETMEM (__descr, p_header.data.dtvp); })
+# endif
 
-
-#endif
+#endif	/* HAVE_TLS_SUPPORT */
 
 #endif	/* tls.h */
diff --git a/sysdeps/generic/dl-tls.c b/sysdeps/generic/dl-tls.c
index 729adf0040..1b16bd58f4 100644
--- a/sysdeps/generic/dl-tls.c
+++ b/sysdeps/generic/dl-tls.c
@@ -103,7 +103,21 @@ _dl_determine_tlsoffset (struct link_map *firstp)
 
   /* The thread descriptor (pointed to by the thread pointer) has its
      own alignment requirement.  Adjust the static TLS size
-     appropriately.  */
+     and TLS offsets appropriately.  */
+  if (offset % TLS_TCB_ALIGN != 0)
+    {
+      size_t add = TLS_TCB_ALIGN - offset % TLS_TCB_ALIGN;
+
+      /* XXX If the offset stored is negative we must subtract here.  */
+      offset += add;
+
+      runp = firstp;
+      do
+	runp->l_tls_offset += add;
+      while ((runp = runp->l_tls_nextimage) != firstp);
+    }
+
+  GL(dl_tls_static_size) = offset + TLS_TCB_SIZE;
 # elif TLS_DTV_AT_TP
   struct link_map *lastp;
 
@@ -121,10 +135,17 @@ _dl_determine_tlsoffset (struct link_map *firstp)
       offset = roundup (offset + lastp->l_tls_blocksize, runp->l_tls_align);
 
       runp->l_tls_offset = offset;
+
+      lastp = runp;
     }
+
+  GL(dl_tls_static_size) = offset + lastp->l_tls_blocksize;
 # else
 #  error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
 # endif
+
+  /* The alignment requirement for the static TLS block.  */
+  GL(dl_tls_static_align) = MAX (TLS_TCB_ALIGN, max_align);
 }
 
 
@@ -136,7 +157,7 @@ _dl_determine_tlsoffset (struct link_map *firstp)
    it.  Users of the IA-64 form have to provide adequate definitions
    of the following macros.  */
 # ifndef GET_ADDR_ARGS
-#  define GET_ADDR_ARGS struct tls_index *ti
+#  define GET_ADDR_ARGS tls_index *ti
 # endif
 # ifndef GET_ADDR_MODULE
 #  define GET_ADDR_MODULE ti->ti_module
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
index 9913820b03..f049878cbd 100644
--- a/sysdeps/generic/ldsodefs.h
+++ b/sysdeps/generic/ldsodefs.h
@@ -298,6 +298,11 @@ struct rtld_global
   EXTERN size_t _dl_tls_max_dtv_idx;
   /* Flag signalling whether there are gaps in the module ID allocation.  */
   EXTERN bool _dl_tls_dtv_gaps;
+
+  /* Size of the static TLS block.  */
+  EXTERN size_t _dl_tls_static_size;
+  /* Alignment requirement of the static TLS block.  */
+  EXTERN size_t _dl_tls_static_align;
 #endif
 
   /* Name of the shared object to be profiled (if any).  */
diff --git a/sysdeps/i386/dl-tls.h b/sysdeps/i386/dl-tls.h
index 5398609748..7fe4be8e62 100644
--- a/sysdeps/i386/dl-tls.h
+++ b/sysdeps/i386/dl-tls.h
@@ -19,15 +19,15 @@
 
 #ifdef USE_TLS
 /* Type used for the representation of TLS information in the GOT.  */
-struct tls_index
+typedef struct
 {
   unsigned long int ti_module;
   unsigned long int ti_offset;
-};
+} tls_index;
 
 
 /* This is the prototype for the GNU version.  */
-extern void *___tls_get_addr (struct tls_index *ti)
+extern void *___tls_get_addr (tls_index *ti)
      __attribute__ ((__regparm__ (1)));
 
 /* The special thing about the x86 TLS ABI is that we have two
@@ -37,7 +37,7 @@ extern void *___tls_get_addr (struct tls_index *ti)
    an additional underscore at the beginning.  The Sun version uses
    the normal calling convention.  */
 void *
-__tls_get_addr (struct tls_index *ti)
+__tls_get_addr (tls_index *ti)
 {
   return ___tls_get_addr (ti);
 }