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