1 /* Initialization code run first thing by the XCOFF startup code. AIX version.
2 Copyright (C) 2001, 2002 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
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.
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.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, write to the Free
17 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
22 #include <sys/types.h>
24 /* hack to use uchar's */
25 typedef unsigned char uchar
;
29 #include <bits/libc-lock.h>
31 extern void __libc_init_first (int argc
, char **argv
, char **envp
);
33 /* XXX disable for now
34 extern int __libc_multiple_libcs; */
36 /* XXX normally defined in generic/dl-sydep.c, hack it into existance
37 extern void *__libc_stack_end; */
38 void *__libc_stack_end
;
40 struct __libc_start_data_rec
{
50 int (*main
)(int, char **, char **);
53 void (*rtld_fini
)(void);
56 extern struct __libc_start_data_rec __libc_start_data
;
59 /* The first piece of initialized data. */
63 /* Since gcc/crtstuff.c won't define it unless the ELF format is used
64 we will need to define it here. */
65 void *__dso_handle
= NULL
;
68 /* AIX kernel function */
69 extern int __loadx (int flag
, void *module
, void *arg1
, void *arg2
,
71 /* Needed by setenv */
75 * Find __rtinit symbol
77 * __RTINIT *find_rtinit()
79 * __RTINIT *rti - pointer to __rtinit data structure
85 struct xcoffhdr
*xcoff_hdr
;
92 xcoff_hdr
= (struct xcoffhdr
*) __libc_start_data
.text
;
93 sec_hdr
= (SCNHDR
*) ((caddr_t
) &xcoff_hdr
->aouthdr
94 + xcoff_hdr
->filehdr
.f_opthdr
);
95 ldr_sec_hdr
= (SCNHDR
*) (sec_hdr
+ (xcoff_hdr
->aouthdr
.o_snloader
- 1));
96 ldsym_hdr
= (LDSYM
*) ((caddr_t
) xcoff_hdr
+ ldr_sec_hdr
->s_scnptr
99 if (__libc_start_data
.mcount
<= 0)
101 if (!ldr_sec_hdr
->s_scnptr
)
104 if (memcmp (ldsym_hdr
, RTINIT_NAME
, sizeof(RTINIT_NAME
) - 1) != 0)
108 data_sec_hdr
= (SCNHDR
*) (sec_hdr
+ (xcoff_hdr
->aouthdr
.o_sndata
- 1));
109 rtl
= (__RTINIT
*) (ldsym_hdr
->l_value
110 + (__libc_start_data
.data
- data_sec_hdr
->s_vaddr
));
114 /* The mod_init1 calls every initialization function
117 void mod_init1(handler, rti)
119 void *handler - if NULL init funtions for modules loaded at exec time
120 are being executed. Otherwise, the handler points to the
123 __RTINIT *rti - pointer to __rtinit data structure (with rti->init_offset
128 mod_init1 (void *handler
,__RTINIT
*rtl
)
130 __RTINIT_DESCRIPTOR
*descriptor
;
132 descriptor
= (__RTINIT_DESCRIPTOR
*) ((caddr_t
) &rtl
->rtl
134 while (descriptor
->f
!= NULL
)
136 if (!(descriptor
->flags
& _RT_CALLED
))
138 descriptor
->flags
|= _RT_CALLED
;
139 /* Execute init/fini. */
140 descriptor
->f (handler
, rtl
, descriptor
);
142 descriptor
= (__RTINIT_DESCRIPTOR
*) ((caddr_t
) descriptor
143 + rtl
->__rtinit_descriptor_size
);
147 /* The modinit() function performs run-time linking, if enabled, and calling
148 the init() function for all loaded modules.
153 #define DL_BUFFER_SIZE 1000
159 __RTINIT
*rtinit_info
= NULL
;
161 DL_INFO dl_buffer
[DL_BUFFER_SIZE
];
162 DL_INFO
*dl_info
= dl_buffer
;
165 /* Find __rtinit symbols */
166 rtinit_info
= find_rtinit ();
169 if (rtinit_info
&& rtinit_info
->rtl
)
172 /* Get a list of modules that have __rtinit. */
173 if (__loadx (flag
, dl_info
, (void *) sizeof (dl_buffer
), NULL
, NULL
))
176 if (( dl_info
[0].dlinfo_xflags
& DL_INFO_OK
))
178 rtinit_info
= find_rtinit ();
179 if ((rtinit_info
!= NULL
) & (rtinit_info
->rtl
!= NULL
))
181 if ((*rtinit_info
->rtl
) (dl_info
, 0))
186 /* Initialization each module loaded that has __rtinit. */
187 if (dl_info
[0].dlinfo_xflags
& DL_INFO_OK
)
189 for (i
= 1; i
< dl_info
[0].dlinfo_arraylen
+ 1; ++i
)
190 if (dl_info
[i
].dlinfo_flags
& DL_HAS_RTINIT
)
192 rtinit_info
= find_rtinit ();
194 mod_init1 (handler
, rtinit_info
);
203 __libc_start_init (void)
205 /* Do run-time linking, if enabled and call the init()
206 for all loaded modules. */
207 if (__libc_start_data
.mcount
!= __libc_start_data
.special
)
211 /* For now these are just stubs. */
213 __libc_start_fini (void)
218 __libc_start_rtld_fini (void)
223 __libc_start_main (void)
227 /* The next variable is only here to work around a bug in gcc <= 2.7.2.2.
228 If the address would be taken inside the expression the optimizer
229 would try to be too smart and throws it away. Grrr. */
231 /* XXX disable for now
232 int *dummy_addr = &_dl_starting_up;
234 __libc_multiple_libcs = dummy_addr && !_dl_starting_up; */
237 /* Store the lowest stack address. */
238 __libc_stack_end
= __libc_start_data
.stack
;
241 __environ
= __libc_start_data
.envp
;
247 /* Some security at this point. Prevent starting a SUID binary where
248 the standard file descriptors are not opened. We have to do this
249 only for statically linked applications since otherwise the dynamic
250 loader did the work already. */
251 if (__builtin_expect (__libc_enable_secure
, 0))
252 __libc_check_standard_fds ();
256 /* Register the destructor of the dynamic linker if there is any. */
257 if (__builtin_expect (__libc_start_data
.rtld_fini
!= NULL
, 1))
258 __cxa_atexit ((void (*) (void *)) __libc_start_data
.rtld_fini
, NULL
, NULL
);
260 /* Call the initializer of the libc. This is only needed here if we
261 are compiling for the static library in which case we haven't
262 run the constructors in `_dl_start_user'. */
264 __libc_init_first (__libc_start_data
.argc
, __libc_start_data
.argv
,
265 __libc_start_data
.envp
);
268 /* Register the destructor of the program, if any. */
269 if (__libc_start_data
.fini
)
270 __cxa_atexit ((void (*) (void *)) __libc_start_data
.fini
, NULL
, NULL
);
272 /* Call the initializer of the program, if any. */
274 if (__builtin_expect (GL(dl_debug_mask
) & DL_DEBUG_IMPCALLS
, 0))
275 _dl_debug_printf ("\ninitialize program: %s\n\n",
276 __libc_start_data
.argv
[0]);
278 if (__libc_start_data
.init
)
279 (*__libc_start_data
.init
) ();
282 if (__builtin_expect (GL(dl_debug_mask
) & DL_DEBUG_IMPCALLS
, 0))
283 _dl_debug_printf ("\ntransferring control: %s\n\n",
284 __libc_start_data
.argv
[0]);
287 exit ((*__libc_start_data
.main
) (__libc_start_data
.argc
,
288 __libc_start_data
.argv
,
289 __libc_start_data
.envp
));