(root)/
glibc-2.38/
csu/
libc-start.c
       1  /* Perform initialization and invoke main.
       2     Copyright (C) 1998-2023 Free Software Foundation, Inc.
       3     This file is part of the GNU C Library.
       4  
       5     The GNU C Library is free software; you can redistribute it and/or
       6     modify it under the terms of the GNU Lesser General Public
       7     License as published by the Free Software Foundation; either
       8     version 2.1 of the License, or (at your option) any later version.
       9  
      10     The GNU C Library is distributed in the hope that it will be useful,
      11     but WITHOUT ANY WARRANTY; without even the implied warranty of
      12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      13     Lesser General Public License for more details.
      14  
      15     You should have received a copy of the GNU Lesser General Public
      16     License along with the GNU C Library; if not, see
      17     <https://www.gnu.org/licenses/>.  */
      18  
      19  /* Note: This code is only part of the startup code proper for
      20     statically linked binaries.  For dynamically linked binaries, it
      21     resides in libc.so.  */
      22  
      23  /* Mark symbols hidden in static PIE for early self relocation to work.  */
      24  #if BUILD_PIE_DEFAULT
      25  # pragma GCC visibility push(hidden)
      26  #endif
      27  
      28  #include <assert.h>
      29  #include <stdlib.h>
      30  #include <stdio.h>
      31  #include <unistd.h>
      32  #include <ldsodefs.h>
      33  #include <libc-diag.h>
      34  #include <libc-internal.h>
      35  #include <elf/libc-early-init.h>
      36  #include <stdbool.h>
      37  #include <elf-initfini.h>
      38  #include <shlib-compat.h>
      39  
      40  #include <elf/dl-tunables.h>
      41  
      42  extern void __libc_init_first (int argc, char **argv, char **envp);
      43  
      44  #include <tls.h>
      45  #ifndef SHARED
      46  # include <dl-osinfo.h>
      47  # ifndef THREAD_SET_STACK_GUARD
      48  /* Only exported for architectures that don't store the stack guard canary
      49     in thread local area.  */
      50  uintptr_t __stack_chk_guard attribute_relro;
      51  # endif
      52  # ifndef  THREAD_SET_POINTER_GUARD
      53  /* Only exported for architectures that don't store the pointer guard
      54     value in thread local area.  */
      55  uintptr_t __pointer_chk_guard_local attribute_relro attribute_hidden;
      56  # endif
      57  #endif
      58  
      59  #ifndef SHARED
      60  # include <link.h>
      61  # include <dl-irel.h>
      62  
      63  # ifdef ELF_MACHINE_IRELA
      64  #  define IREL_T	ElfW(Rela)
      65  #  define IPLT_START	__rela_iplt_start
      66  #  define IPLT_END	__rela_iplt_end
      67  #  define IREL		elf_irela
      68  # elif defined ELF_MACHINE_IREL
      69  #  define IREL_T	ElfW(Rel)
      70  #  define IPLT_START	__rel_iplt_start
      71  #  define IPLT_END	__rel_iplt_end
      72  #  define IREL		elf_irel
      73  # endif
      74  
      75  static void
      76  apply_irel (void)
      77  {
      78  # ifdef IREL
      79    /* We use weak references for these so that we'll still work with a linker
      80       that doesn't define them.  Such a linker doesn't support IFUNC at all
      81       and so uses won't work, but a statically-linked program that doesn't
      82       use any IFUNC symbols won't have a problem.  */
      83    extern const IREL_T IPLT_START[] __attribute__ ((weak));
      84    extern const IREL_T IPLT_END[] __attribute__ ((weak));
      85    for (const IREL_T *ipltent = IPLT_START; ipltent < IPLT_END; ++ipltent)
      86      IREL (ipltent);
      87  # endif
      88  }
      89  #endif
      90  
      91  
      92  #ifdef LIBC_START_MAIN
      93  # ifdef LIBC_START_DISABLE_INLINE
      94  #  define STATIC static
      95  # else
      96  #  define STATIC static inline __attribute__ ((always_inline))
      97  # endif
      98  # define DO_DEFINE_LIBC_START_MAIN_VERSION 0
      99  #else
     100  # define STATIC
     101  # define LIBC_START_MAIN __libc_start_main_impl
     102  # define DO_DEFINE_LIBC_START_MAIN_VERSION 1
     103  #endif
     104  
     105  #ifdef MAIN_AUXVEC_ARG
     106  /* main gets passed a pointer to the auxiliary.  */
     107  # define MAIN_AUXVEC_DECL	, void *
     108  # define MAIN_AUXVEC_PARAM	, auxvec
     109  #else
     110  # define MAIN_AUXVEC_DECL
     111  # define MAIN_AUXVEC_PARAM
     112  #endif
     113  
     114  #ifndef ARCH_INIT_CPU_FEATURES
     115  # define ARCH_INIT_CPU_FEATURES()
     116  #endif
     117  
     118  /* Obtain the definition of __libc_start_call_main.  */
     119  #include <libc_start_call_main.h>
     120  
     121  #ifdef SHARED
     122  /* Initialization for dynamic executables.  Find the main executable
     123     link map and run its init functions.  */
     124  static void
     125  call_init (int argc, char **argv, char **env)
     126  {
     127    /* Obtain the main map of the executable.  */
     128    struct link_map *l = GL(dl_ns)[LM_ID_BASE]._ns_loaded;
     129  
     130    /* DT_PREINIT_ARRAY is not processed here.  It is already handled in
     131       _dl_init in elf/dl-init.c.  Also see the call_init function in
     132       the same file.  */
     133  
     134    if (ELF_INITFINI && l->l_info[DT_INIT] != NULL)
     135      DL_CALL_DT_INIT(l, l->l_addr + l->l_info[DT_INIT]->d_un.d_ptr,
     136  		    argc, argv, env);
     137  
     138    ElfW(Dyn) *init_array = l->l_info[DT_INIT_ARRAY];
     139    if (init_array != NULL)
     140      {
     141        unsigned int jm
     142  	= l->l_info[DT_INIT_ARRAYSZ]->d_un.d_val / sizeof (ElfW(Addr));
     143        ElfW(Addr) *addrs = (void *) (init_array->d_un.d_ptr + l->l_addr);
     144        for (unsigned int j = 0; j < jm; ++j)
     145  	((dl_init_t) addrs[j]) (argc, argv, env);
     146      }
     147  }
     148  
     149  #else /* !SHARED */
     150  
     151  /* These magic symbols are provided by the linker.  */
     152  extern void (*__preinit_array_start []) (int, char **, char **)
     153    attribute_hidden;
     154  extern void (*__preinit_array_end []) (int, char **, char **)
     155    attribute_hidden;
     156  extern void (*__init_array_start []) (int, char **, char **)
     157    attribute_hidden;
     158  extern void (*__init_array_end []) (int, char **, char **)
     159    attribute_hidden;
     160  extern void (*__fini_array_start []) (void) attribute_hidden;
     161  extern void (*__fini_array_end []) (void) attribute_hidden;
     162  
     163  # if ELF_INITFINI
     164  /* These function symbols are provided for the .init/.fini section entry
     165     points automagically by the linker.  */
     166  extern void _init (void);
     167  extern void _fini (void);
     168  # endif
     169  
     170  /* Initialization for static executables.  There is no dynamic
     171     segment, so we access the symbols directly.  */
     172  static void
     173  call_init (int argc, char **argv, char **envp)
     174  {
     175    /* For static executables, preinit happens right before init.  */
     176    {
     177      const size_t size = __preinit_array_end - __preinit_array_start;
     178      size_t i;
     179      for (i = 0; i < size; i++)
     180        (*__preinit_array_start [i]) (argc, argv, envp);
     181    }
     182  
     183  # if ELF_INITFINI
     184    _init ();
     185  # endif
     186  
     187    const size_t size = __init_array_end - __init_array_start;
     188    for (size_t i = 0; i < size; i++)
     189        (*__init_array_start [i]) (argc, argv, envp);
     190  }
     191  
     192  /* Likewise for the destructor.  */
     193  static void
     194  call_fini (void *unused)
     195  {
     196    size_t i = __fini_array_end - __fini_array_start;
     197    while (i-- > 0)
     198      (*__fini_array_start [i]) ();
     199  
     200  # if ELF_INITFINI
     201    _fini ();
     202  # endif
     203  }
     204  
     205  #endif /* !SHARED */
     206  
     207  #include <libc-start.h>
     208  
     209  STATIC int LIBC_START_MAIN (int (*main) (int, char **, char **
     210  					 MAIN_AUXVEC_DECL),
     211  			    int argc,
     212  			    char **argv,
     213  #ifdef LIBC_START_MAIN_AUXVEC_ARG
     214  			    ElfW(auxv_t) *auxvec,
     215  #endif
     216  			    __typeof (main) init,
     217  			    void (*fini) (void),
     218  			    void (*rtld_fini) (void),
     219  			    void *stack_end)
     220       __attribute__ ((noreturn));
     221  
     222  
     223  /* Note: The init and fini parameters are no longer used.  fini is
     224     completely unused, init is still called if not NULL, but the
     225     current startup code always passes NULL.  (In the future, it would
     226     be possible to use fini to pass a version code if init is NULL, to
     227     indicate the link-time glibc without introducing a hard
     228     incompatibility for new programs with older glibc versions.)
     229  
     230     For dynamically linked executables, the dynamic segment is used to
     231     locate constructors and destructors.  For statically linked
     232     executables, the relevant symbols are access directly.  */
     233  STATIC int
     234  LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL),
     235  		 int argc, char **argv,
     236  #ifdef LIBC_START_MAIN_AUXVEC_ARG
     237  		 ElfW(auxv_t) *auxvec,
     238  #endif
     239  		 __typeof (main) init,
     240  		 void (*fini) (void),
     241  		 void (*rtld_fini) (void), void *stack_end)
     242  {
     243  #ifndef SHARED
     244    char **ev = &argv[argc + 1];
     245  
     246    __environ = ev;
     247  
     248    /* Store the lowest stack address.  This is done in ld.so if this is
     249       the code for the DSO.  */
     250    __libc_stack_end = stack_end;
     251  
     252  # ifdef HAVE_AUX_VECTOR
     253    /* First process the auxiliary vector since we need to find the
     254       program header to locate an eventually present PT_TLS entry.  */
     255  #  ifndef LIBC_START_MAIN_AUXVEC_ARG
     256    ElfW(auxv_t) *auxvec;
     257    {
     258      char **evp = ev;
     259      while (*evp++ != NULL)
     260        ;
     261      auxvec = (ElfW(auxv_t) *) evp;
     262    }
     263  #  endif
     264    _dl_aux_init (auxvec);
     265  # endif
     266  
     267    __tunables_init (__environ);
     268  
     269    ARCH_INIT_CPU_FEATURES ();
     270  
     271    /* Do static pie self relocation after tunables and cpu features
     272       are setup for ifunc resolvers. Before this point relocations
     273       must be avoided.  */
     274    _dl_relocate_static_pie ();
     275  
     276    /* Perform IREL{,A} relocations.  */
     277    ARCH_SETUP_IREL ();
     278  
     279    /* The stack guard goes into the TCB, so initialize it early.  */
     280    ARCH_SETUP_TLS ();
     281  
     282    /* In some architectures, IREL{,A} relocations happen after TLS setup in
     283       order to let IFUNC resolvers benefit from TCB information, e.g. powerpc's
     284       hwcap and platform fields available in the TCB.  */
     285    ARCH_APPLY_IREL ();
     286  
     287    /* Set up the stack checker's canary.  */
     288    uintptr_t stack_chk_guard = _dl_setup_stack_chk_guard (_dl_random);
     289  # ifdef THREAD_SET_STACK_GUARD
     290    THREAD_SET_STACK_GUARD (stack_chk_guard);
     291  # else
     292    __stack_chk_guard = stack_chk_guard;
     293  # endif
     294  
     295    /* Initialize libpthread if linked in.  */
     296    if (__pthread_initialize_minimal != NULL)
     297      __pthread_initialize_minimal ();
     298  
     299    /* Set up the pointer guard value.  */
     300    uintptr_t pointer_chk_guard = _dl_setup_pointer_guard (_dl_random,
     301  							 stack_chk_guard);
     302  # ifdef THREAD_SET_POINTER_GUARD
     303    THREAD_SET_POINTER_GUARD (pointer_chk_guard);
     304  # else
     305    __pointer_chk_guard_local = pointer_chk_guard;
     306  # endif
     307  
     308  #endif /* !SHARED  */
     309  
     310    /* Register the destructor of the dynamic linker if there is any.  */
     311    if (__glibc_likely (rtld_fini != NULL))
     312      __cxa_atexit ((void (*) (void *)) rtld_fini, NULL, NULL);
     313  
     314  #ifndef SHARED
     315    /* Perform early initialization.  In the shared case, this function
     316       is called from the dynamic loader as early as possible.  */
     317    __libc_early_init (true);
     318  
     319    /* Call the initializer of the libc.  This is only needed here if we
     320       are compiling for the static library in which case we haven't
     321       run the constructors in `_dl_start_user'.  */
     322    __libc_init_first (argc, argv, __environ);
     323  
     324    /* Register the destructor of the statically-linked program.  */
     325    __cxa_atexit (call_fini, NULL, NULL);
     326  
     327    /* Some security at this point.  Prevent starting a SUID binary where
     328       the standard file descriptors are not opened.  We have to do this
     329       only for statically linked applications since otherwise the dynamic
     330       loader did the work already.  */
     331    if (__builtin_expect (__libc_enable_secure, 0))
     332      __libc_check_standard_fds ();
     333  #endif /* !SHARED */
     334  
     335    /* Call the initializer of the program, if any.  */
     336  #ifdef SHARED
     337    if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_IMPCALLS, 0))
     338      GLRO(dl_debug_printf) ("\ninitialize program: %s\n\n", argv[0]);
     339  
     340    if (init != NULL)
     341      /* This is a legacy program which supplied its own init
     342         routine.  */
     343      (*init) (argc, argv, __environ MAIN_AUXVEC_PARAM);
     344    else
     345      /* This is a current program.  Use the dynamic segment to find
     346         constructors.  */
     347      call_init (argc, argv, __environ);
     348  
     349    /* Auditing checkpoint: we have a new object.  */
     350    _dl_audit_preinit (GL(dl_ns)[LM_ID_BASE]._ns_loaded);
     351  
     352    if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_IMPCALLS))
     353      GLRO(dl_debug_printf) ("\ntransferring control: %s\n\n", argv[0]);
     354  #else /* !SHARED */
     355    call_init (argc, argv, __environ);
     356  
     357    _dl_debug_initialize (0, LM_ID_BASE);
     358  #endif
     359  
     360    __libc_start_call_main (main, argc, argv MAIN_AUXVEC_PARAM);
     361  }
     362  
     363  /* Starting with glibc 2.34, the init parameter is always NULL.  Older
     364     libcs are not prepared to handle that.  The macro
     365     DEFINE_LIBC_START_MAIN_VERSION creates GLIBC_2.34 alias, so that
     366     newly linked binaries reflect that dependency.  The macros below
     367     expect that the exported function is called
     368     __libc_start_main_impl.  */
     369  #ifdef SHARED
     370  # define DEFINE_LIBC_START_MAIN_VERSION \
     371    DEFINE_LIBC_START_MAIN_VERSION_1 \
     372    strong_alias (__libc_start_main_impl, __libc_start_main_alias_2)	\
     373    versioned_symbol (libc, __libc_start_main_alias_2, __libc_start_main, \
     374  		    GLIBC_2_34);
     375  
     376  # if SHLIB_COMPAT(libc, GLIBC_2_0, GLIBC_2_34)
     377  #  define DEFINE_LIBC_START_MAIN_VERSION_1 \
     378    strong_alias (__libc_start_main_impl, __libc_start_main_alias_1)	\
     379    compat_symbol (libc, __libc_start_main_alias_1, __libc_start_main, GLIBC_2_0);
     380  #  else
     381  #  define DEFINE_LIBC_START_MAIN_VERSION_1
     382  # endif
     383  #else  /* !SHARED */
     384  /* Enable calling the function under its exported name.  */
     385  # define DEFINE_LIBC_START_MAIN_VERSION \
     386    strong_alias (__libc_start_main_impl, __libc_start_main)
     387  #endif
     388  
     389  /* Only define the version information if LIBC_START_MAIN was not set.
     390     If there is a wrapper file, it must expand
     391     DEFINE_LIBC_START_MAIN_VERSION on its own.  */
     392  #if DO_DEFINE_LIBC_START_MAIN_VERSION
     393  DEFINE_LIBC_START_MAIN_VERSION
     394  #endif