]> git.ipfire.org Git - thirdparty/glibc.git/blame - sysdeps/generic/libc-start.c
(_dl_phdr): New variable. (_dl_phnum): New variable. (_dl_aux_init): Initialize _dl_p...
[thirdparty/glibc.git] / sysdeps / generic / libc-start.c
CommitLineData
d6b5d570 1/* Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
7dea968e
UD
2 This file is part of the GNU C Library.
3
4 The GNU C Library is free software; you can redistribute it and/or
41bdb6e2
AJ
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.
7dea968e
UD
8
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
41bdb6e2 12 Lesser General Public License for more details.
7dea968e 13
41bdb6e2
AJ
14 You should have received a copy of the GNU Lesser General Public
15 License along with the GNU C Library; if not, write to the Free
16 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
17 02111-1307 USA. */
7dea968e 18
3db52d94
UD
19#include <stdlib.h>
20#include <unistd.h>
a42195db 21#include <ldsodefs.h>
ab95290c
UD
22#include <bp-start.h>
23#include <bp-sym.h>
3db52d94 24
31161268
UD
25extern void __libc_init_first (int argc, char **argv, char **envp);
26
27extern int _dl_starting_up;
28weak_extern (_dl_starting_up)
29extern int __libc_multiple_libcs;
5785c39f 30extern void *__libc_stack_end;
31161268 31
4fb7a71f
AJ
32#ifndef SHARED
33extern void __pthread_initialize_minimal (void) __attribute__ ((weak));
34#endif
35
17427edd
UD
36
37extern int BP_SYM (__libc_start_main) (int (*main) (int, char **, char **),
38 int argc,
39 char *__unbounded *__unbounded ubp_av,
40 void (*init) (void),
41 void (*fini) (void),
42 void (*rtld_fini) (void),
43 void *__unbounded stack_end)
44 __attribute__ ((noreturn));
a828c2f5 45
7dea968e 46int
ab95290c
UD
47/* GKM FIXME: GCC: this should get __BP_ prefix by virtue of the
48 BPs in the arglist of startup_info.main and startup_info.init. */
49BP_SYM (__libc_start_main) (int (*main) (int, char **, char **),
50 int argc, char *__unbounded *__unbounded ubp_av,
51 void (*init) (void), void (*fini) (void),
52 void (*rtld_fini) (void), void *__unbounded stack_end)
7dea968e 53{
ab95290c
UD
54 char *__unbounded *__unbounded ubp_ev = &ubp_av[argc + 1];
55#if __BOUNDED_POINTERS__
56 char **argv;
57#else
58# define argv ubp_av
59#endif
60
b5567b2a 61#ifndef SHARED
e4a5f77d
UD
62# ifdef HAVE_AUX_VECTOR
63 void *__unbounded *__unbounded auxvec;
64# endif
65
31161268
UD
66 /* The next variable is only here to work around a bug in gcc <= 2.7.2.2.
67 If the address would be taken inside the expression the optimizer
68 would try to be too smart and throws it away. Grrr. */
69 int *dummy_addr = &_dl_starting_up;
70
71 __libc_multiple_libcs = dummy_addr && !_dl_starting_up;
69f234e8 72#endif
c0fb8a56 73
ab95290c
UD
74 INIT_ARGV_and_ENVIRON;
75
c0fb8a56
UD
76 /* Store the lowest stack address. */
77 __libc_stack_end = stack_end;
31161268 78
db33f7d4 79#ifndef SHARED
4fb7a71f
AJ
80 /* Initialize the thread library at least a bit since the libgcc
81 functions are using thread functions if these are available and
82 we need to setup errno. */
83 if (__pthread_initialize_minimal)
84 __pthread_initialize_minimal ();
85
a828c2f5 86 /* Some security at this point. Prevent starting a SUID binary where
db33f7d4
UD
87 the standard file descriptors are not opened. We have to do this
88 only for statically linked applications since otherwise the dynamic
89 loader did the work already. */
cf197e41 90 if (__builtin_expect (__libc_enable_secure, 0))
db33f7d4 91 __libc_check_standard_fds ();
e4a5f77d
UD
92
93# ifdef HAVE_AUX_VECTOR
94 for (auxvec = (void *__unbounded *__unbounded) ubp_ev;
c08bc50a 95 *auxvec != NULL; ++auxvec);
e4a5f77d
UD
96 ++auxvec;
97 _dl_aux_init ((ElfW(auxv_t) *) auxvec);
98# endif
db33f7d4 99#endif
a828c2f5 100
3db52d94 101 /* Register the destructor of the dynamic linker if there is any. */
cf197e41 102 if (__builtin_expect (rtld_fini != NULL, 1))
c08bc50a 103 __cxa_atexit ((void (*) (void *)) rtld_fini, NULL, NULL);
3db52d94 104
dacc8ffa
UD
105 /* Call the initializer of the libc. This is only needed here if we
106 are compiling for the static library in which case we haven't
107 run the constructors in `_dl_start_user'. */
b5567b2a 108#ifndef SHARED
31161268 109 __libc_init_first (argc, argv, __environ);
dacc8ffa 110#endif
31161268 111
4194bc66
RH
112 /* Register the destructor of the program, if any. */
113 if (fini)
c08bc50a 114 __cxa_atexit ((void (*) (void *)) fini, NULL, NULL);
4194bc66
RH
115
116 /* Call the initializer of the program, if any. */
b5567b2a 117#ifdef SHARED
d6b5d570 118 if (__builtin_expect (GL(dl_debug_mask) & DL_DEBUG_IMPCALLS, 0))
35fc382a 119 _dl_debug_printf ("\ninitialize program: %s\n\n", argv[0]);
31161268 120#endif
4194bc66
RH
121 if (init)
122 (*init) ();
3db52d94 123
b5567b2a 124#ifdef SHARED
d6b5d570 125 if (__builtin_expect (GL(dl_debug_mask) & DL_DEBUG_IMPCALLS, 0))
35fc382a 126 _dl_debug_printf ("\ntransferring control: %s\n\n", argv[0]);
31161268
UD
127#endif
128
129 exit ((*main) (argc, argv, __environ));
7dea968e 130}