]> git.ipfire.org Git - thirdparty/glibc.git/blame - elf/dl-init.c
Update copyright dates with scripts/update-copyrights
[thirdparty/glibc.git] / elf / dl-init.c
CommitLineData
6ac2f2df 1/* Run initializers for newly loaded objects.
2b778ceb 2 Copyright (C) 1995-2021 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 16 License along with the GNU C Library; if not, see
5a82c748 17 <https://www.gnu.org/licenses/>. */
d66e34cd 18
7b5bfe77 19#include <assert.h>
d66e34cd 20#include <stddef.h>
a42195db 21#include <ldsodefs.h>
f4349837 22#include <elf-initfini.h>
d66e34cd
RM
23
24
dacc8ffa
UD
25/* Type of the initializer. */
26typedef void (*init_t) (int, char **, char **);
f68b86cc 27
5d916713
UD
28
29static void
30call_init (struct link_map *l, int argc, char **argv, char **env)
31{
7b5bfe77
FW
32 /* If the object has not been relocated, this is a bug. The
33 function pointers are invalid in this case. (Executables do not
34 need relocation, and neither do proxy objects.) */
35 assert (l->l_real->l_relocated || l->l_real->l_type == lt_executable);
36
5d916713
UD
37 if (l->l_init_called)
38 /* This object is all done. */
39 return;
40
41 /* Avoid handling this constructor again in case we have a circular
42 dependency. */
43 l->l_init_called = 1;
44
45 /* Check for object which constructors we do not run here. */
bd929413
UD
46 if (__builtin_expect (l->l_name[0], 'a') == '\0'
47 && l->l_type == lt_executable)
5d916713
UD
48 return;
49
5d916713 50 /* Print a debug message if wanted. */
a1ffb40e 51 if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_IMPCALLS))
154d10bd 52 _dl_debug_printf ("\ncalling init: %s\n\n",
b9375348 53 DSO_FILENAME (l->l_name));
5d916713
UD
54
55 /* Now run the local constructors. There are two forms of them:
56 - the one named by DT_INIT
57 - the others in the DT_INIT_ARRAY.
58 */
f4349837 59 if (ELF_INITFINI && l->l_info[DT_INIT] != NULL)
daf75146 60 DL_CALL_DT_INIT(l, l->l_addr + l->l_info[DT_INIT]->d_un.d_ptr, argc, argv, env);
5d916713
UD
61
62 /* Next see whether there is an array with initialization functions. */
53fe2758
UD
63 ElfW(Dyn) *init_array = l->l_info[DT_INIT_ARRAY];
64 if (init_array != NULL)
5d916713
UD
65 {
66 unsigned int j;
67 unsigned int jm;
68 ElfW(Addr) *addrs;
69
70 jm = l->l_info[DT_INIT_ARRAYSZ]->d_un.d_val / sizeof (ElfW(Addr));
71
53fe2758 72 addrs = (ElfW(Addr) *) (init_array->d_un.d_ptr + l->l_addr);
5d916713
UD
73 for (j = 0; j < jm; ++j)
74 ((init_t) addrs[j]) (argc, argv, env);
75 }
76}
77
dacc8ffa 78
841288ec 79void
841288ec 80_dl_init (struct link_map *main_map, int argc, char **argv, char **env)
d66e34cd 81{
a7f91846 82 ElfW(Dyn) *preinit_array = main_map->l_info[DT_PREINIT_ARRAY];
53fe2758 83 ElfW(Dyn) *preinit_array_size = main_map->l_info[DT_PREINIT_ARRAYSZ];
f68b86cc
RM
84 unsigned int i;
85
a1ffb40e 86 if (__glibc_unlikely (GL(dl_initfirst) != NULL))
5d916713 87 {
d6b5d570
UD
88 call_init (GL(dl_initfirst), argc, argv, env);
89 GL(dl_initfirst) = NULL;
5d916713
UD
90 }
91
d7926ed9 92 /* Don't do anything if there is no preinit array. */
bd929413 93 if (__builtin_expect (preinit_array != NULL, 0)
53fe2758
UD
94 && preinit_array_size != NULL
95 && (i = preinit_array_size->d_un.d_val / sizeof (ElfW(Addr))) > 0)
d7926ed9
UD
96 {
97 ElfW(Addr) *addrs;
98 unsigned int cnt;
99
a1ffb40e 100 if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_IMPCALLS))
154d10bd 101 _dl_debug_printf ("\ncalling preinit: %s\n\n",
b9375348 102 DSO_FILENAME (main_map->l_name));
d7926ed9 103
53fe2758 104 addrs = (ElfW(Addr) *) (preinit_array->d_un.d_ptr + main_map->l_addr);
d7926ed9
UD
105 for (cnt = 0; cnt < i; ++cnt)
106 ((init_t) addrs[cnt]) (argc, argv, env);
107 }
108
bd929413 109 /* Stupid users forced the ELF specification to be changed. It now
dacc8ffa
UD
110 says that the dynamic loader is responsible for determining the
111 order in which the constructors have to run. The constructors
112 for all dependencies of an object must run before the constructor
113 for the object itself. Circular dependencies are left unspecified.
114
115 This is highly questionable since it puts the burden on the dynamic
116 loader which has to find the dependencies at runtime instead of
117 letting the user do it right. Stupidity rules! */
d66e34cd 118
841288ec 119 i = main_map->l_searchlist.r_nlist;
f68b86cc 120 while (i-- > 0)
5d916713 121 call_init (main_map->l_initfini[i], argc, argv, env);
dacc8ffa 122
ce6e047f 123#ifndef HAVE_INLINED_SYSCALLS
7688db91 124 /* Finished starting up. */
9cf27b8d 125 _dl_starting_up = 0;
ce6e047f 126#endif
d66e34cd 127}