aboutsummaryrefslogtreecommitdiff
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 f1b95e0..f176699 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 99c040a..cc59073 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 8f92234..454f165 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 0fd54a0..8494b26 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 34d7ec1..bb67840 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)