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
));