1 /* Copyright (C) 1998-2017 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
14 You should have received a copy of the GNU Lesser General Public
15 License along with the GNU C Library; if not, see
16 <http://www.gnu.org/licenses/>. */
23 #include <exit-thread.h>
24 #include <libc-internal.h>
26 #include <elf/dl-tunables.h>
28 extern void __libc_init_first (int argc
, char **argv
, char **envp
);
32 # include <dl-osinfo.h>
33 # ifndef THREAD_SET_STACK_GUARD
34 /* Only exported for architectures that don't store the stack guard canary
35 in thread local area. */
36 uintptr_t __stack_chk_guard attribute_relro
;
38 # ifndef THREAD_SET_POINTER_GUARD
39 /* Only exported for architectures that don't store the pointer guard
40 value in thread local area. */
41 uintptr_t __pointer_chk_guard_local
42 attribute_relro attribute_hidden
__attribute__ ((nocommon
));
46 #ifdef HAVE_PTR_NTHREADS
47 /* We need atomic operations. */
56 # ifdef ELF_MACHINE_IRELA
57 # define IREL_T ElfW(Rela)
58 # define IPLT_START __rela_iplt_start
59 # define IPLT_END __rela_iplt_end
60 # define IREL elf_irela
61 # elif defined ELF_MACHINE_IREL
62 # define IREL_T ElfW(Rel)
63 # define IPLT_START __rel_iplt_start
64 # define IPLT_END __rel_iplt_end
65 # define IREL elf_irel
72 /* We use weak references for these so that we'll still work with a linker
73 that doesn't define them. Such a linker doesn't support IFUNC at all
74 and so uses won't work, but a statically-linked program that doesn't
75 use any IFUNC symbols won't have a problem. */
76 extern const IREL_T IPLT_START
[] __attribute__ ((weak
));
77 extern const IREL_T IPLT_END
[] __attribute__ ((weak
));
78 for (const IREL_T
*ipltent
= IPLT_START
; ipltent
< IPLT_END
; ++ipltent
)
85 #ifdef LIBC_START_MAIN
86 # ifdef LIBC_START_DISABLE_INLINE
87 # define STATIC static
89 # define STATIC static inline __attribute__ ((always_inline))
93 # define LIBC_START_MAIN __libc_start_main
96 #ifdef MAIN_AUXVEC_ARG
97 /* main gets passed a pointer to the auxiliary. */
98 # define MAIN_AUXVEC_DECL , void *
99 # define MAIN_AUXVEC_PARAM , auxvec
101 # define MAIN_AUXVEC_DECL
102 # define MAIN_AUXVEC_PARAM
105 #ifndef ARCH_INIT_CPU_FEATURES
106 # define ARCH_INIT_CPU_FEATURES()
109 #include <libc-start.h>
111 STATIC
int LIBC_START_MAIN (int (*main
) (int, char **, char **
115 #ifdef LIBC_START_MAIN_AUXVEC_ARG
116 ElfW(auxv_t
) *auxvec
,
118 __typeof (main
) init
,
120 void (*rtld_fini
) (void),
122 __attribute__ ((noreturn
));
125 /* Note: the fini parameter is ignored here for shared library. It
126 is registered with __cxa_atexit. This had the disadvantage that
127 finalizers were called in more than one place. */
129 LIBC_START_MAIN (int (*main
) (int, char **, char ** MAIN_AUXVEC_DECL
),
130 int argc
, char **argv
,
131 #ifdef LIBC_START_MAIN_AUXVEC_ARG
132 ElfW(auxv_t
) *auxvec
,
134 __typeof (main
) init
,
136 void (*rtld_fini
) (void), void *stack_end
)
138 /* Result of the 'main' function. */
141 __libc_multiple_libcs
= &_dl_starting_up
&& !_dl_starting_up
;
144 char **ev
= &argv
[argc
+ 1];
148 /* Store the lowest stack address. This is done in ld.so if this is
149 the code for the DSO. */
150 __libc_stack_end
= stack_end
;
152 # ifdef HAVE_AUX_VECTOR
153 /* First process the auxiliary vector since we need to find the
154 program header to locate an eventually present PT_TLS entry. */
155 # ifndef LIBC_START_MAIN_AUXVEC_ARG
156 ElfW(auxv_t
) *auxvec
;
159 while (*evp
++ != NULL
)
161 auxvec
= (ElfW(auxv_t
) *) evp
;
164 _dl_aux_init (auxvec
);
165 if (GL(dl_phdr
) == NULL
)
168 /* Starting from binutils-2.23, the linker will define the
169 magic symbol __ehdr_start to point to our own ELF header
170 if it is visible in a segment that also includes the phdrs.
171 So we can set up _dl_phdr and _dl_phnum even without any
172 information from auxv. */
174 extern const ElfW(Ehdr
) __ehdr_start
175 __attribute__ ((weak
, visibility ("hidden")));
176 if (&__ehdr_start
!= NULL
)
178 assert (__ehdr_start
.e_phentsize
== sizeof *GL(dl_phdr
));
179 GL(dl_phdr
) = (const void *) &__ehdr_start
+ __ehdr_start
.e_phoff
;
180 GL(dl_phnum
) = __ehdr_start
.e_phnum
;
184 /* Initialize very early so that tunables can use it. */
185 __libc_init_secure ();
187 __tunables_init (__environ
);
189 ARCH_INIT_CPU_FEATURES ();
191 /* Perform IREL{,A} relocations. */
194 /* The stack guard goes into the TCB, so initialize it early. */
197 /* In some architectures, IREL{,A} relocations happen after TLS setup in
198 order to let IFUNC resolvers benefit from TCB information, e.g. powerpc's
199 hwcap and platform fields available in the TCB. */
202 /* Set up the stack checker's canary. */
203 uintptr_t stack_chk_guard
= _dl_setup_stack_chk_guard (_dl_random
);
204 # ifdef THREAD_SET_STACK_GUARD
205 THREAD_SET_STACK_GUARD (stack_chk_guard
);
207 __stack_chk_guard
= stack_chk_guard
;
210 # ifdef DL_SYSDEP_OSCHECK
211 if (!__libc_multiple_libcs
)
213 /* This needs to run to initiliaze _dl_osversion before TLS
214 setup might check it. */
215 DL_SYSDEP_OSCHECK (__libc_fatal
);
219 /* Initialize libpthread if linked in. */
220 if (__pthread_initialize_minimal
!= NULL
)
221 __pthread_initialize_minimal ();
223 /* Set up the pointer guard value. */
224 uintptr_t pointer_chk_guard
= _dl_setup_pointer_guard (_dl_random
,
226 # ifdef THREAD_SET_POINTER_GUARD
227 THREAD_SET_POINTER_GUARD (pointer_chk_guard
);
229 __pointer_chk_guard_local
= pointer_chk_guard
;
234 /* Register the destructor of the dynamic linker if there is any. */
235 if (__glibc_likely (rtld_fini
!= NULL
))
236 __cxa_atexit ((void (*) (void *)) rtld_fini
, NULL
, NULL
);
239 /* Call the initializer of the libc. This is only needed here if we
240 are compiling for the static library in which case we haven't
241 run the constructors in `_dl_start_user'. */
242 __libc_init_first (argc
, argv
, __environ
);
244 /* Register the destructor of the program, if any. */
246 __cxa_atexit ((void (*) (void *)) fini
, NULL
, NULL
);
248 /* Some security at this point. Prevent starting a SUID binary where
249 the standard file descriptors are not opened. We have to do this
250 only for statically linked applications since otherwise the dynamic
251 loader did the work already. */
252 if (__builtin_expect (__libc_enable_secure
, 0))
253 __libc_check_standard_fds ();
256 /* Call the initializer of the program, if any. */
258 if (__builtin_expect (GLRO(dl_debug_mask
) & DL_DEBUG_IMPCALLS
, 0))
259 GLRO(dl_debug_printf
) ("\ninitialize program: %s\n\n", argv
[0]);
262 (*init
) (argc
, argv
, __environ MAIN_AUXVEC_PARAM
);
265 /* Auditing checkpoint: we have a new object. */
266 if (__glibc_unlikely (GLRO(dl_naudit
) > 0))
268 struct audit_ifaces
*afct
= GLRO(dl_audit
);
269 struct link_map
*head
= GL(dl_ns
)[LM_ID_BASE
]._ns_loaded
;
270 for (unsigned int cnt
= 0; cnt
< GLRO(dl_naudit
); ++cnt
)
272 if (afct
->preinit
!= NULL
)
273 afct
->preinit (&head
->l_audit
[cnt
].cookie
);
281 if (__glibc_unlikely (GLRO(dl_debug_mask
) & DL_DEBUG_IMPCALLS
))
282 GLRO(dl_debug_printf
) ("\ntransferring control: %s\n\n", argv
[0]);
286 _dl_debug_initialize (0, LM_ID_BASE
);
288 #ifdef HAVE_CLEANUP_JMP_BUF
289 /* Memory for the cancellation buffer. */
290 struct pthread_unwind_buf unwind_buf
;
293 not_first_call
= setjmp ((struct __jmp_buf_tag
*) unwind_buf
.cancel_jmp_buf
);
294 if (__glibc_likely (! not_first_call
))
296 struct pthread
*self
= THREAD_SELF
;
298 /* Store old info. */
299 unwind_buf
.priv
.data
.prev
= THREAD_GETMEM (self
, cleanup_jmp_buf
);
300 unwind_buf
.priv
.data
.cleanup
= THREAD_GETMEM (self
, cleanup
);
302 /* Store the new cleanup handler info. */
303 THREAD_SETMEM (self
, cleanup_jmp_buf
, &unwind_buf
);
305 /* Run the program. */
306 result
= main (argc
, argv
, __environ MAIN_AUXVEC_PARAM
);
310 /* Remove the thread-local data. */
312 PTHFCT_CALL (ptr__nptl_deallocate_tsd
, ());
314 extern void __nptl_deallocate_tsd (void) __attribute ((weak
));
315 __nptl_deallocate_tsd ();
318 /* One less thread. Decrement the counter. If it is zero we
319 terminate the entire process. */
322 unsigned int *ptr
= __libc_pthread_functions
.ptr_nthreads
;
327 extern unsigned int __nptl_nthreads
__attribute ((weak
));
328 unsigned int *const ptr
= &__nptl_nthreads
;
331 if (! atomic_decrement_and_test (ptr
))
332 /* Not much left to do but to exit the thread, not the process. */
336 /* Nothing fancy, just call the function. */
337 result
= main (argc
, argv
, __environ MAIN_AUXVEC_PARAM
);