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