]> git.ipfire.org Git - thirdparty/glibc.git/blame - elf/dl-init.c
Update.
[thirdparty/glibc.git] / elf / dl-init.c
CommitLineData
d66e34cd 1/* Return the next shared object initializer function not yet run.
a42195db 2 Copyright (C) 1995, 1996, 1998, 1999, 2000 Free Software Foundation, Inc.
afd4eb37
UD
3 This file is part of the GNU C Library.
4
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public License as
7 published by the Free Software Foundation; either version 2 of the
8 License, or (at your option) any later version.
9
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 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public
16 License along with the GNU C Library; see the file COPYING.LIB. If not,
17 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA. */
d66e34cd
RM
19
20#include <stddef.h>
a42195db 21#include <ldsodefs.h>
d66e34cd
RM
22
23
dacc8ffa
UD
24/* Type of the initializer. */
25typedef void (*init_t) (int, char **, char **);
f68b86cc 26
7688db91
UD
27/* Flag, nonzero during startup phase. */
28extern int _dl_starting_up;
29
dacc8ffa 30
841288ec 31void
d0fc4041 32internal_function
841288ec 33_dl_init (struct link_map *main_map, int argc, char **argv, char **env)
d66e34cd 34{
a7f91846 35 ElfW(Dyn) *preinit_array = main_map->l_info[DT_PREINIT_ARRAY];
841288ec 36 struct r_debug *r;
f68b86cc
RM
37 unsigned int i;
38
d7926ed9
UD
39 /* Don't do anything if there is no preinit array. */
40 if (preinit_array != NULL
41 && (i = preinit_array->d_un.d_val / sizeof (ElfW(Addr))) > 0)
42 {
43 ElfW(Addr) *addrs;
44 unsigned int cnt;
45
466a0ec9 46 if (__builtin_expect (_dl_debug_impcalls, 0))
d7926ed9
UD
47 _dl_debug_message (1, "\ncalling preinit: ",
48 main_map->l_name[0]
49 ? main_map->l_name : _dl_argv[0], "\n\n", NULL);
50
51 addrs = (ElfW(Addr) *) (main_map->l_info[DT_PREINIT_ARRAY]->d_un.d_ptr
52 + main_map->l_addr);
53 for (cnt = 0; cnt < i; ++cnt)
54 ((init_t) addrs[cnt]) (argc, argv, env);
55 }
56
841288ec
UD
57 /* Notify the debugger we have added some objects. We need to call
58 _dl_debug_initialize in a static program in case dynamic linking has
59 not been used before. */
60 r = _dl_debug_initialize (0);
61 r->r_state = RT_ADD;
62 _dl_debug_state ();
63
dacc8ffa
UD
64 /* Stupid users forces the ELF specification to be changed. It now
65 says that the dynamic loader is responsible for determining the
66 order in which the constructors have to run. The constructors
67 for all dependencies of an object must run before the constructor
68 for the object itself. Circular dependencies are left unspecified.
69
70 This is highly questionable since it puts the burden on the dynamic
71 loader which has to find the dependencies at runtime instead of
72 letting the user do it right. Stupidity rules! */
d66e34cd 73
841288ec 74 i = main_map->l_searchlist.r_nlist;
f68b86cc 75 while (i-- > 0)
d66e34cd 76 {
841288ec 77 struct link_map *l = main_map->l_initfini[i];
dacc8ffa 78 init_t init;
f68b86cc 79
d66e34cd
RM
80 if (l->l_init_called)
81 /* This object is all done. */
f68b86cc
RM
82 continue;
83
dacc8ffa
UD
84 /* Avoid handling this constructor again in case we have a circular
85 dependency. */
86 l->l_init_called = 1;
d66e34cd 87
dacc8ffa
UD
88 /* Check for object which constructors we do not run here. */
89 if (l->l_name[0] == '\0' && l->l_type == lt_executable)
90 continue;
7dea968e 91
841288ec
UD
92 /* Are there any constructors? */
93 if (l->l_info[DT_INIT] == NULL && l->l_info[DT_INIT_ARRAY] == NULL)
94 continue;
95
96 /* Print a debug message if wanted. */
466a0ec9 97 if (__builtin_expect (_dl_debug_impcalls, 0))
841288ec
UD
98 _dl_debug_message (1, "\ncalling init: ",
99 l->l_name[0] ? l->l_name : _dl_argv[0],
100 "\n\n", NULL);
dacc8ffa 101
841288ec 102 /* Now run the local constructors. There are two forms of them:
dacc8ffa
UD
103 - the one named by DT_INIT
104 - the others in the DT_INIT_ARRAY.
105 */
841288ec 106 if (l->l_info[DT_INIT] != NULL)
fcf70d41 107 {
dacc8ffa
UD
108 init = (init_t) (l->l_addr + l->l_info[DT_INIT]->d_un.d_ptr);
109
110 /* Call the function. */
111 init (argc, argv, env);
fcf70d41 112 }
7dea968e 113
c0c2af07 114 /* Next see whether there is an array with initialization functions. */
841288ec 115 if (l->l_info[DT_INIT_ARRAY] != NULL)
fcf70d41 116 {
dacc8ffa
UD
117 unsigned int j;
118 unsigned int jm;
119 ElfW(Addr) *addrs;
d66e34cd 120
dacc8ffa 121 jm = l->l_info[DT_INIT_ARRAYSZ]->d_un.d_val / sizeof (ElfW(Addr));
fcf70d41 122
dacc8ffa
UD
123 addrs = (ElfW(Addr) *) (l->l_info[DT_INIT_ARRAY]->d_un.d_ptr
124 + l->l_addr);
125 for (j = 0; j < jm; ++j)
126 ((init_t) addrs[j]) (argc, argv, env);
127 }
d66e34cd 128 }
dacc8ffa
UD
129
130 /* Notify the debugger all new objects are now ready to go. */
131 r->r_state = RT_CONSISTENT;
132 _dl_debug_state ();
7688db91
UD
133
134 /* Finished starting up. */
135 _dl_starting_up = 0;
d66e34cd 136}