1- /* Copyright (C) 1998-2021 Free Software Foundation, Inc.
1+ /* Perform initialization and invoke main.
2+ Copyright (C) 1998-2021 Free Software Foundation, Inc.
23 This file is part of the GNU C Library.
34
45 The GNU C Library is free software; you can redistribute it and/or
1516 License along with the GNU C Library; if not, see
1617 <https://www.gnu.org/licenses/>. */
1718
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+
1823/* Mark symbols hidden in static PIE for early self relocation to work. */
1924#if BUILD_PIE_DEFAULT
2025# pragma GCC visibility push(hidden)
2126#endif
27+
2228#include <assert.h>
2329#include <stdlib.h>
2430#include <stdio.h>
2935#include <libc-internal.h>
3036#include <elf/libc-early-init.h>
3137#include <stdbool.h>
38+ #include <elf-initfini.h>
39+ #include <shlib-compat.h>
3240
3341#include <elf/dl-tunables.h>
3442
@@ -95,9 +103,11 @@ apply_irel (void)
95103# else
96104# define STATIC static inline __attribute__ ((always_inline))
97105# endif
106+ # define DO_DEFINE_LIBC_START_MAIN_VERSION 0
98107#else
99108# define STATIC
100- # define LIBC_START_MAIN __libc_start_main
109+ # define LIBC_START_MAIN __libc_start_main_impl
110+ # define DO_DEFINE_LIBC_START_MAIN_VERSION 1
101111#endif
102112
103113#ifdef MAIN_AUXVEC_ARG
@@ -113,6 +123,92 @@ apply_irel (void)
113123# define ARCH_INIT_CPU_FEATURES ()
114124#endif
115125
126+ #ifdef SHARED
127+ /* Initialization for dynamic executables. Find the main executable
128+ link map and run its init functions. */
129+ static void
130+ call_init (int argc , char * * argv , char * * env )
131+ {
132+ /* Obtain the main map of the executable. */
133+ struct link_map * l = GL (dl_ns )[LM_ID_BASE ]._ns_loaded ;
134+
135+ /* DT_PREINIT_ARRAY is not processed here. It is already handled in
136+ _dl_init in elf/dl-init.c. Also see the call_init function in
137+ the same file. */
138+
139+ if (ELF_INITFINI && l -> l_info [DT_INIT ] != NULL )
140+ DL_CALL_DT_INIT (l , l -> l_addr + l -> l_info [DT_INIT ]-> d_un .d_ptr ,
141+ argc , argv , env );
142+
143+ ElfW (Dyn ) * init_array = l -> l_info [DT_INIT_ARRAY ];
144+ if (init_array != NULL )
145+ {
146+ unsigned int jm
147+ = l -> l_info [DT_INIT_ARRAYSZ ]-> d_un .d_val / sizeof (ElfW (Addr ));
148+ ElfW (Addr ) * addrs = (void * ) (init_array -> d_un .d_ptr + l -> l_addr );
149+ for (unsigned int j = 0 ; j < jm ; ++ j )
150+ ((dl_init_t ) addrs [j ]) (argc , argv , env );
151+ }
152+ }
153+
154+ #else /* !SHARED */
155+
156+ /* These magic symbols are provided by the linker. */
157+ extern void (* __preinit_array_start []) (int , char * * , char * * )
158+ attribute_hidden ;
159+ extern void (* __preinit_array_end []) (int , char * * , char * * )
160+ attribute_hidden ;
161+ extern void (* __init_array_start []) (int , char * * , char * * )
162+ attribute_hidden ;
163+ extern void (* __init_array_end []) (int , char * * , char * * )
164+ attribute_hidden ;
165+ extern void (* __fini_array_start []) (void ) attribute_hidden ;
166+ extern void (* __fini_array_end []) (void ) attribute_hidden ;
167+
168+ # if ELF_INITFINI
169+ /* These function symbols are provided for the .init/.fini section entry
170+ points automagically by the linker. */
171+ extern void _init (void );
172+ extern void _fini (void );
173+ # endif
174+
175+ /* Initialization for static executables. There is no dynamic
176+ segment, so we access the symbols directly. */
177+ static void
178+ call_init (int argc , char * * argv , char * * envp )
179+ {
180+ /* For static executables, preinit happens right before init. */
181+ {
182+ const size_t size = __preinit_array_end - __preinit_array_start ;
183+ size_t i ;
184+ for (i = 0 ; i < size ; i ++ )
185+ (* __preinit_array_start [i ]) (argc , argv , envp );
186+ }
187+
188+ # if ELF_INITFINI
189+ _init ();
190+ # endif
191+
192+ const size_t size = __init_array_end - __init_array_start ;
193+ for (size_t i = 0 ; i < size ; i ++ )
194+ (* __init_array_start [i ]) (argc , argv , envp );
195+ }
196+
197+ /* Likewise for the destructor. */
198+ static void
199+ call_fini (void * unused )
200+ {
201+ size_t i = __fini_array_end - __fini_array_start ;
202+ while (i -- > 0 )
203+ (* __fini_array_start [i ]) ();
204+
205+ # if ELF_INITFINI
206+ _fini ();
207+ # endif
208+ }
209+
210+ #endif /* !SHARED */
211+
116212#include <libc-start.h>
117213
118214STATIC int LIBC_START_MAIN (int (* main ) (int , char * * , char * *
@@ -129,9 +225,16 @@ STATIC int LIBC_START_MAIN (int (*main) (int, char **, char **
129225 __attribute__ ((noreturn ));
130226
131227
132- /* Note: the fini parameter is ignored here for shared library. It
133- is registered with __cxa_atexit. This had the disadvantage that
134- finalizers were called in more than one place. */
228+ /* Note: The init and fini parameters are no longer used. fini is
229+ completely unused, init is still called if not NULL, but the
230+ current startup code always passes NULL. (In the future, it would
231+ be possible to use fini to pass a version code if init is NULL, to
232+ indicate the link-time glibc without introducing a hard
233+ incompatibility for new programs with older glibc versions.)
234+
235+ For dynamically linked executables, the dynamic segment is used to
236+ locate constructors and destructors. For statically linked
237+ executables, the relevant symbols are access directly. */
135238STATIC int
136239LIBC_START_MAIN (int (* main ) (int , char * * , char * * MAIN_AUXVEC_DECL ),
137240 int argc , char * * argv ,
@@ -258,25 +361,33 @@ LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL),
258361 run the constructors in `_dl_start_user'. */
259362 __libc_init_first (argc , argv , __environ );
260363
261- /* Register the destructor of the program, if any. */
262- if (fini )
263- __cxa_atexit ((void (* ) (void * )) fini , NULL , NULL );
364+ /* Register the destructor of the statically-linked program. */
365+ __cxa_atexit (call_fini , NULL , NULL );
264366
265367 /* Some security at this point. Prevent starting a SUID binary where
266368 the standard file descriptors are not opened. We have to do this
267369 only for statically linked applications since otherwise the dynamic
268370 loader did the work already. */
269371 if (__builtin_expect (__libc_enable_secure , 0 ))
270372 __libc_check_standard_fds ();
271- #endif
373+ #endif /* !SHARED */
272374
273375 /* Call the initializer of the program, if any. */
274376#ifdef SHARED
275377 if (__builtin_expect (GLRO (dl_debug_mask ) & DL_DEBUG_IMPCALLS , 0 ))
276378 GLRO (dl_debug_printf ) ("\ninitialize program: %s\n\n" , argv [0 ]);
277- #endif
278- if (init )
379+
380+ if (init != NULL )
381+ /* This is a legacy program which supplied its own init
382+ routine. */
279383 (* init ) (argc , argv , __environ MAIN_AUXVEC_PARAM );
384+ else
385+ /* This is a current program. Use the dynamic segment to find
386+ constructors. */
387+ call_init (argc , argv , __environ );
388+ #else /* !SHARED */
389+ call_init (argc , argv , __environ );
390+ #endif /* SHARED */
280391
281392#ifdef SHARED
282393 /* Auditing checkpoint: we have a new object. */
@@ -365,3 +476,36 @@ LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL),
365476
366477 exit (result );
367478}
479+
480+ /* Starting with glibc 2.34, the init parameter is always NULL. Older
481+ libcs are not prepared to handle that. The macro
482+ DEFINE_LIBC_START_MAIN_VERSION creates GLIBC_2.34 alias, so that
483+ newly linked binaries reflect that dependency. The macros below
484+ expect that the exported function is called
485+ __libc_start_main_impl. */
486+ #ifdef SHARED
487+ # define DEFINE_LIBC_START_MAIN_VERSION \
488+ DEFINE_LIBC_START_MAIN_VERSION_1 \
489+ strong_alias (__libc_start_main_impl, __libc_start_main_alias_2) \
490+ versioned_symbol (libc, __libc_start_main_alias_2, __libc_start_main, \
491+ GLIBC_2_34);
492+
493+ # if SHLIB_COMPAT (libc , GLIBC_2_0 , GLIBC_2_34 )
494+ # define DEFINE_LIBC_START_MAIN_VERSION_1 \
495+ strong_alias (__libc_start_main_impl, __libc_start_main_alias_1) \
496+ compat_symbol (libc, __libc_start_main_alias_1, __libc_start_main, GLIBC_2_0);
497+ # else
498+ # define DEFINE_LIBC_START_MAIN_VERSION_1
499+ # endif
500+ #else /* !SHARED */
501+ /* Enable calling the function under its exported name. */
502+ # define DEFINE_LIBC_START_MAIN_VERSION \
503+ strong_alias (__libc_start_main_impl, __libc_start_main)
504+ #endif
505+
506+ /* Only define the version information if LIBC_START_MAIN was not set.
507+ If there is a wrapper file, it must expand
508+ DEFINE_LIBC_START_MAIN_VERSION on its own. */
509+ #if DO_DEFINE_LIBC_START_MAIN_VERSION
510+ DEFINE_LIBC_START_MAIN_VERSION
511+ #endif
0 commit comments