diff options
Diffstat (limited to 'csu/libc-start.c')
-rw-r--r-- | csu/libc-start.c | 63 |
1 files changed, 40 insertions, 23 deletions
diff --git a/csu/libc-start.c b/csu/libc-start.c index bf5eb69b27..494132368f 100644 --- a/csu/libc-start.c +++ b/csu/libc-start.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1998-2016 Free Software Foundation, Inc. +/* Copyright (C) 1998-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -21,18 +21,15 @@ #include <unistd.h> #include <ldsodefs.h> #include <exit-thread.h> +#include <libc-internal.h> -extern void __libc_init_first (int argc, char **argv, char **envp); -#ifndef SHARED -extern void __libc_csu_irel (void); -#endif +#include <elf/dl-tunables.h> -extern int __libc_multiple_libcs; +extern void __libc_init_first (int argc, char **argv, char **envp); #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. */ @@ -105,6 +102,12 @@ apply_irel (void) # define MAIN_AUXVEC_PARAM #endif +#ifndef ARCH_INIT_CPU_FEATURES +# define ARCH_INIT_CPU_FEATURES() +#endif + +#include <libc-start.h> + STATIC int LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL), int argc, @@ -138,6 +141,8 @@ LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL), __libc_multiple_libcs = &_dl_starting_up && !_dl_starting_up; #ifndef SHARED + _dl_relocate_static_pie (); + char **ev = &argv[argc + 1]; __environ = ev; @@ -178,24 +183,23 @@ 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 + /* Initialize very early so that tunables can use it. */ + __libc_init_secure (); + + __tunables_init (__environ); + + ARCH_INIT_CPU_FEATURES (); /* Perform IREL{,A} relocations. */ - apply_irel (); + ARCH_SETUP_IREL (); -#ifndef __GNU__ - /* 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 (); -#endif + /* The stack guard goes into the TCB, so initialize it early. */ + ARCH_SETUP_TLS (); + + /* In some architectures, IREL{,A} relocations happen after TLS setup in + order to let IFUNC resolvers benefit from TCB information, e.g. powerpc's + hwcap and platform fields available in the TCB. */ + ARCH_APPLY_IREL (); /* Set up the stack checker's canary. */ uintptr_t stack_chk_guard = _dl_setup_stack_chk_guard (_dl_random); @@ -205,6 +209,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); @@ -214,7 +231,7 @@ LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL), __pointer_chk_guard_local = pointer_chk_guard; # endif -#endif +#endif /* !SHARED */ /* Register the destructor of the dynamic linker if there is any. */ if (__glibc_likely (rtld_fini != NULL)) |