]>
Commit | Line | Data |
---|---|---|
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 |
25 | extern void __libc_init_first (int argc, char **argv, char **envp); |
26 | ||
27 | extern int _dl_starting_up; | |
28 | weak_extern (_dl_starting_up) | |
29 | extern int __libc_multiple_libcs; | |
5785c39f | 30 | extern void *__libc_stack_end; |
31161268 | 31 | |
4fb7a71f AJ |
32 | #ifndef SHARED |
33 | extern void __pthread_initialize_minimal (void) __attribute__ ((weak)); | |
34 | #endif | |
35 | ||
17427edd UD |
36 | |
37 | extern 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 | 46 | int |
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. */ | |
49 | BP_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 | } |