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
51
int (*main) (int, char **, char **);
54
void (*rtld_fini) (void);
57
extern struct __libc_start_data_rec __libc_start_data;
60
/* The first piece of initialized data. */
64
/* Since gcc/crtstuff.c won't define it unless the ELF format is used
65
we will need to define it here. */
66
void *__dso_handle = NULL;
69
/* AIX kernel function */
70
extern int __loadx (int flag, void *module, void *arg1, void *arg2,
72
/* Needed by setenv */
78
__RTINIT *find_rtinit()
80
__RTINIT *rti - pointer to __rtinit data structure
86
struct xcoffhdr *xcoff_hdr;
93
xcoff_hdr = (struct xcoffhdr *) __libc_start_data.text;
94
sec_hdr = (SCNHDR *) ((caddr_t) &xcoff_hdr->aouthdr
95
+ xcoff_hdr->filehdr.f_opthdr);
96
ldr_sec_hdr = (SCNHDR *) (sec_hdr + (xcoff_hdr->aouthdr.o_snloader - 1));
97
ldsym_hdr = (LDSYM *) ((caddr_t)xcoff_hdr + ldr_sec_hdr->s_scnptr
100
if ( __libc_start_data.mcount <= 0)
102
if (!ldr_sec_hdr->s_scnptr)
103
return (__RTINIT *) 0;
105
if (memcmp (ldsym_hdr, RTINIT_NAME, sizeof (RTINIT_NAME) - 1))
106
return (__RTINIT *) 0;
109
data_sec_hdr = (SCNHDR *) (sec_hdr + (xcoff_hdr->aouthdr.o_sndata - 1));
110
rtl = (__RTINIT *) (ldsym_hdr->l_value
111
+ (__libc_start_data.data - data_sec_hdr->s_vaddr));
116
The mod_init1 calls every initialization function for a given module.
118
void mod_init1(handler, rti)
120
void *handler - if NULL init funtions for modules loaded at exec time
121
are being executed. Otherwise, the handler points to the
124
__RTINIT *rti - pointer to __rtinit data structure (with rti->init_offset
129
mod_init1 (void *handler,__RTINIT *rtl)
131
__RTINIT_DESCRIPTOR *descriptor;
133
descriptor = (__RTINIT_DESCRIPTOR *) ((caddr_t) &rtl->rtl
135
while (descriptor->f != NULL)
137
if (!(descriptor->flags & _RT_CALLED))
139
descriptor->flags |= _RT_CALLED;
140
(descriptor->f) (handler, rtl, descriptor); /* execute init/fini */
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. */
150
#define DL_BUFFER_SIZE 1000
156
__RTINIT *rtinit_info = 0;
158
DL_INFO dl_buffer[DL_BUFFER_SIZE];
159
DL_INFO *dl_info = dl_buffer;
162
/* Find __rtinit symbols */
163
rtinit_info = find_rtinit ();
166
if (rtinit_info && rtinit_info->rtl)
169
/* Get a list of modules that have __rtinit */
170
if (__loadx (flag, dl_info, (void *) sizeof (dl_buffer), NULL, NULL))
173
if (dl_info[0].dlinfo_xflags & DL_INFO_OK)
175
rtinit_info = find_rtinit ();
176
if ((rtinit_info != NULL) & (rtinit_info->rtl != NULL))
178
if ((*rtinit_info->rtl) (dl_info, 0))
183
/* Initialization each module loaded that has __rtinit. */
184
if (dl_info[0].dlinfo_xflags & DL_INFO_OK)
186
for (i = 1; i < dl_info[0].dlinfo_arraylen + 1; ++i)
187
if (dl_info[i].dlinfo_flags & DL_HAS_RTINIT)
189
rtinit_info = find_rtini t();
191
mod_init1 (handler, rtinit_info);
200
__libc_start_init (void)
202
/* Do run-time linking, if enabled and call the init()
203
for all loaded modules. */
204
if (__libc_start_data.mcount != __libc_start_data.special)
208
/* For now these are just stubs. */
210
__libc_start_fini (void)
215
__libc_start_rtld_fini (void)
221
__libc_start_main (void)
223
/* Store the lowest stack address. */
224
__libc_stack_end = __libc_start_data.stack;
227
__environ = __libc_start_data.envp;
233
/* Some security at this point. Prevent starting a SUID binary where
234
the standard file descriptors are not opened. We have to do this
235
only for statically linked applications since otherwise the dynamic
236
loader did the work already. */
237
if (__builtin_expect (__libc_enable_secure, 0))
238
__libc_check_standard_fds ();
242
/* Register the destructor of the dynamic linker if there is any. */
243
if (__builtin_expect (__libc_start_data.rtld_fini != NULL, 1))
244
__cxa_atexit ((void (*) (void *)) __libc_start_data.rtld_fini, NULL, NULL);
246
/* Call the initializer of the libc. This is only needed here if we
247
are compiling for the static library in which case we haven't
248
run the constructors in `_dl_start_user'. */
250
__libc_init_first (__libc_start_data.argc, __libc_start_data.argv,
251
__libc_start_data.envp);
254
/* Register the destructor of the program, if any. */
255
if (__libc_start_data.fini)
256
__cxa_atexit ((void (*) (void *)) __libc_start_data.fini, NULL, NULL);
258
/* Call the initializer of the program, if any. */
259
if (__libc_start_data.init)
260
(*__libc_start_data.init) ();
262
exit ((*__libc_start_data.main) (__libc_start_data.argc,
263
__libc_start_data.argv,
264
__libc_start_data.envp));