]> git.ipfire.org Git - thirdparty/glibc.git/blame - elf/dl-init.c
Fix ChangeLog formatting
[thirdparty/glibc.git] / elf / dl-init.c
CommitLineData
6ac2f2df 1/* Run initializers for newly loaded objects.
568035b7 2 Copyright (C) 1995-2013 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
41bdb6e2
AJ
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.
afd4eb37
UD
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
41bdb6e2 13 Lesser General Public License for more details.
afd4eb37 14
41bdb6e2 15 You should have received a copy of the GNU Lesser General Public
59ba27a6
PE
16 License along with the GNU C Library; if not, see
17 <http://www.gnu.org/licenses/>. */
d66e34cd
RM
18
19#include <stddef.h>
a42195db 20#include <ldsodefs.h>
d66e34cd
RM
21
22
dacc8ffa
UD
23/* Type of the initializer. */
24typedef void (*init_t) (int, char **, char **);
f68b86cc 25
ce6e047f 26#ifndef HAVE_INLINED_SYSCALLS
7688db91
UD
27/* Flag, nonzero during startup phase. */
28extern int _dl_starting_up;
e6caf4e1 29extern int _dl_starting_up_internal attribute_hidden;
ce6e047f 30#endif
7688db91 31
5d916713
UD
32
33static void
34call_init (struct link_map *l, int argc, char **argv, char **env)
35{
36 if (l->l_init_called)
37 /* This object is all done. */
38 return;
39
40 /* Avoid handling this constructor again in case we have a circular
41 dependency. */
42 l->l_init_called = 1;
43
44 /* Check for object which constructors we do not run here. */
bd929413
UD
45 if (__builtin_expect (l->l_name[0], 'a') == '\0'
46 && l->l_type == lt_executable)
5d916713
UD
47 return;
48
49 /* Are there any constructors? */
bd929413
UD
50 if (l->l_info[DT_INIT] == NULL
51 && __builtin_expect (l->l_info[DT_INIT_ARRAY] == NULL, 1))
5d916713
UD
52 return;
53
54 /* Print a debug message if wanted. */
afdca0f2 55 if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_IMPCALLS, 0))
154d10bd
UD
56 _dl_debug_printf ("\ncalling init: %s\n\n",
57 l->l_name[0] ? l->l_name : rtld_progname);
5d916713
UD
58
59 /* Now run the local constructors. There are two forms of them:
60 - the one named by DT_INIT
61 - the others in the DT_INIT_ARRAY.
62 */
63 if (l->l_info[DT_INIT] != NULL)
64 {
65 init_t init = (init_t) DL_DT_INIT_ADDRESS
66 (l, l->l_addr + l->l_info[DT_INIT]->d_un.d_ptr);
67
68 /* Call the function. */
69 init (argc, argv, env);
70 }
71
72 /* Next see whether there is an array with initialization functions. */
53fe2758
UD
73 ElfW(Dyn) *init_array = l->l_info[DT_INIT_ARRAY];
74 if (init_array != NULL)
5d916713
UD
75 {
76 unsigned int j;
77 unsigned int jm;
78 ElfW(Addr) *addrs;
79
80 jm = l->l_info[DT_INIT_ARRAYSZ]->d_un.d_val / sizeof (ElfW(Addr));
81
53fe2758 82 addrs = (ElfW(Addr) *) (init_array->d_un.d_ptr + l->l_addr);
5d916713
UD
83 for (j = 0; j < jm; ++j)
84 ((init_t) addrs[j]) (argc, argv, env);
85 }
86}
87
dacc8ffa 88
841288ec 89void
d0fc4041 90internal_function
841288ec 91_dl_init (struct link_map *main_map, int argc, char **argv, char **env)
d66e34cd 92{
a7f91846 93 ElfW(Dyn) *preinit_array = main_map->l_info[DT_PREINIT_ARRAY];
53fe2758 94 ElfW(Dyn) *preinit_array_size = main_map->l_info[DT_PREINIT_ARRAYSZ];
f68b86cc
RM
95 unsigned int i;
96
d6b5d570 97 if (__builtin_expect (GL(dl_initfirst) != NULL, 0))
5d916713 98 {
d6b5d570
UD
99 call_init (GL(dl_initfirst), argc, argv, env);
100 GL(dl_initfirst) = NULL;
5d916713
UD
101 }
102
d7926ed9 103 /* Don't do anything if there is no preinit array. */
bd929413 104 if (__builtin_expect (preinit_array != NULL, 0)
53fe2758
UD
105 && preinit_array_size != NULL
106 && (i = preinit_array_size->d_un.d_val / sizeof (ElfW(Addr))) > 0)
d7926ed9
UD
107 {
108 ElfW(Addr) *addrs;
109 unsigned int cnt;
110
afdca0f2 111 if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_IMPCALLS, 0))
154d10bd
UD
112 _dl_debug_printf ("\ncalling preinit: %s\n\n",
113 main_map->l_name[0]
114 ? main_map->l_name : rtld_progname);
d7926ed9 115
53fe2758 116 addrs = (ElfW(Addr) *) (preinit_array->d_un.d_ptr + main_map->l_addr);
d7926ed9
UD
117 for (cnt = 0; cnt < i; ++cnt)
118 ((init_t) addrs[cnt]) (argc, argv, env);
119 }
120
bd929413 121 /* Stupid users forced the ELF specification to be changed. It now
dacc8ffa
UD
122 says that the dynamic loader is responsible for determining the
123 order in which the constructors have to run. The constructors
124 for all dependencies of an object must run before the constructor
125 for the object itself. Circular dependencies are left unspecified.
126
127 This is highly questionable since it puts the burden on the dynamic
128 loader which has to find the dependencies at runtime instead of
129 letting the user do it right. Stupidity rules! */
d66e34cd 130
841288ec 131 i = main_map->l_searchlist.r_nlist;
f68b86cc 132 while (i-- > 0)
5d916713 133 call_init (main_map->l_initfini[i], argc, argv, env);
dacc8ffa 134
ce6e047f 135#ifndef HAVE_INLINED_SYSCALLS
7688db91 136 /* Finished starting up. */
e6caf4e1 137 INTUSE(_dl_starting_up) = 0;
ce6e047f 138#endif
d66e34cd 139}
7969407a 140INTDEF (_dl_init)