about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog19
-rw-r--r--csu/libc-start.c29
-rw-r--r--csu/libc-tls.c17
-rw-r--r--nptl/nptl-init.c16
-rw-r--r--sysdeps/generic/ldsodefs.h11
5 files changed, 49 insertions, 43 deletions
diff --git a/ChangeLog b/ChangeLog
index f1b95e0e79..f17669931b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,23 @@
 2016-12-26  Nick Alcock  <nick.alcock@oracle.com>
+	    Florian Weimer  <fweimer@redhat.com>
+
+	[BZ #7065]
+	Initialize the stack guard earlier when linking statically.
+	* sysdeps/generic/ldsodefs.h (__libc_setup_tls)
+	(__pthread_initialize_minimal): Declare.
+	* csu/libc-start.c (__pthread_initialize_minimal): Remove
+	declaration.
+	(LIBC_START_MAIN): Call __libc_setup_tls early and directly.  Move
+	stack canary and apply_irel initialization up.  Call
+	__pthread_initialize_minimal only if linked in.
+	* csu/libc-tls.c (__libc_setup_tls): Replace arguments with their
+	constant values.
+	(__pthread_initialize_minimal): Remove.
+	* nptl/nptl-init.c (__libc_setup_tls): Remove declaration.
+	(__pthread_initialize_minimal_internal): Do not call
+	__libc_setup_tls.
+
+2016-12-26  Nick Alcock  <nick.alcock@oracle.com>
 
 	[BZ #7065]
 	* configure.ac (libc_cv_ssp): Move up.
diff --git a/csu/libc-start.c b/csu/libc-start.c
index 99c040ab97..cc59073abe 100644
--- a/csu/libc-start.c
+++ b/csu/libc-start.c
@@ -29,7 +29,6 @@ extern int __libc_multiple_libcs;
 #include <tls.h>
 #ifndef SHARED
 # include <dl-osinfo.h>
-extern void __pthread_initialize_minimal (void);
 # ifndef THREAD_SET_STACK_GUARD
 /* Only exported for architectures that don't store the stack guard canary
    in thread local area.  */
@@ -175,22 +174,11 @@ LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL),
         }
     }
 
-# ifdef DL_SYSDEP_OSCHECK
-  if (!__libc_multiple_libcs)
-    {
-      /* This needs to run to initiliaze _dl_osversion before TLS
-	 setup might check it.  */
-      DL_SYSDEP_OSCHECK (__libc_fatal);
-    }
-# endif
-
   /* Perform IREL{,A} relocations.  */
   apply_irel ();
 
-  /* Initialize the thread library at least a bit since the libgcc
-     functions are using thread functions if these are available and
-     we need to setup errno.  */
-  __pthread_initialize_minimal ();
+  /* The stack guard goes into the TCB, so initialize it early.  */
+  __libc_setup_tls ();
 
   /* Set up the stack checker's canary.  */
   uintptr_t stack_chk_guard = _dl_setup_stack_chk_guard (_dl_random);
@@ -200,6 +188,19 @@ LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL),
   __stack_chk_guard = stack_chk_guard;
 # endif
 
+# ifdef DL_SYSDEP_OSCHECK
+  if (!__libc_multiple_libcs)
+    {
+      /* This needs to run to initiliaze _dl_osversion before TLS
+	 setup might check it.  */
+      DL_SYSDEP_OSCHECK (__libc_fatal);
+    }
+# endif
+
+  /* Initialize libpthread if linked in.  */
+  if (__pthread_initialize_minimal != NULL)
+    __pthread_initialize_minimal ();
+
   /* Set up the pointer guard value.  */
   uintptr_t pointer_chk_guard = _dl_setup_pointer_guard (_dl_random,
 							 stack_chk_guard);
diff --git a/csu/libc-tls.c b/csu/libc-tls.c
index 8f922341de..454f165457 100644
--- a/csu/libc-tls.c
+++ b/csu/libc-tls.c
@@ -102,14 +102,14 @@ init_static_tls (size_t memsz, size_t align)
 }
 
 void
-__libc_setup_tls (size_t tcbsize, size_t tcbalign)
+__libc_setup_tls (void)
 {
   void *tlsblock;
   size_t memsz = 0;
   size_t filesz = 0;
   void *initimage = NULL;
   size_t align = 0;
-  size_t max_align = tcbalign;
+  size_t max_align = TCB_ALIGNMENT;
   size_t tcb_offset;
   const ElfW(Phdr) *phdr;
 
@@ -142,9 +142,9 @@ __libc_setup_tls (size_t tcbsize, size_t tcbalign)
      _dl_allocate_tls_storage (in elf/dl-tls.c) does using __libc_memalign
      and dl_tls_static_align.  */
   tcb_offset = roundup (memsz + GL(dl_tls_static_size), max_align);
-  tlsblock = __sbrk (tcb_offset + tcbsize + max_align);
+  tlsblock = __sbrk (tcb_offset + TLS_INIT_TCB_SIZE + max_align);
 #elif TLS_DTV_AT_TP
-  tcb_offset = roundup (tcbsize, align ?: 1);
+  tcb_offset = roundup (TLS_INIT_TCB_SIZE, align ?: 1);
   tlsblock = __sbrk (tcb_offset + memsz + max_align
 		     + TLS_PRE_TCB_SIZE + GL(dl_tls_static_size));
   tlsblock += TLS_PRE_TCB_SIZE;
@@ -215,12 +215,3 @@ __libc_setup_tls (size_t tcbsize, size_t tcbalign)
 
   init_static_tls (memsz, MAX (TLS_TCB_ALIGN, max_align));
 }
-
-/* This is the minimal initialization function used when libpthread is
-   not used.  */
-void
-__attribute__ ((weak))
-__pthread_initialize_minimal (void)
-{
-  __libc_setup_tls (TLS_INIT_TCB_SIZE, TLS_INIT_TCB_ALIGN);
-}
diff --git a/nptl/nptl-init.c b/nptl/nptl-init.c
index 0fd54a0a93..8494b26115 100644
--- a/nptl/nptl-init.c
+++ b/nptl/nptl-init.c
@@ -70,10 +70,6 @@ int __have_futex_clock_realtime;
 static const char nptl_version[] __attribute_used__ = VERSION;
 
 
-#ifndef SHARED
-extern void __libc_setup_tls (size_t tcbsize, size_t tcbalign);
-#endif
-
 #ifdef SHARED
 static
 #else
@@ -288,18 +284,6 @@ static bool __nptl_initial_report_events __attribute_used__;
 void
 __pthread_initialize_minimal_internal (void)
 {
-#ifndef SHARED
-  /* Unlike in the dynamically linked case the dynamic linker has not
-     taken care of initializing the TLS data structures.  */
-  __libc_setup_tls (TLS_TCB_SIZE, TLS_TCB_ALIGN);
-
-  /* We must prevent gcc from being clever and move any of the
-     following code ahead of the __libc_setup_tls call.  This function
-     will initialize the thread register which is subsequently
-     used.  */
-  __asm __volatile ("");
-#endif
-
   /* Minimal initialization of the thread descriptor.  */
   struct pthread *pd = THREAD_SELF;
   __pthread_initialize_pids (pd);
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
index 34d7ec152d..bb67840b22 100644
--- a/sysdeps/generic/ldsodefs.h
+++ b/sysdeps/generic/ldsodefs.h
@@ -994,6 +994,17 @@ extern size_t _dl_count_modids (void) internal_function attribute_hidden;
 /* Calculate offset of the TLS blocks in the static TLS block.  */
 extern void _dl_determine_tlsoffset (void) internal_function attribute_hidden;
 
+#ifndef SHARED
+/* Set up the TCB for statically linked applications.  This is called
+   early during startup because we always use TLS (for errno and the
+   stack protector, among other things).  */
+void __libc_setup_tls (void);
+
+/* Initialization of libpthread for statically linked applications.
+   If libpthread is not linked in, this is an empty function.  */
+void __pthread_initialize_minimal (void) weak_function;
+#endif
+
 /* Allocate memory for static TLS block (unless MEM is nonzero) and dtv.  */
 extern void *_dl_allocate_tls (void *mem) internal_function;
 rtld_hidden_proto (_dl_allocate_tls)