]> git.ipfire.org Git - thirdparty/glibc.git/blame - elf/dl-support.c
test-container: Fix "unused code" warnings on HURD
[thirdparty/glibc.git] / elf / dl-support.c
CommitLineData
266180eb 1/* Support for dynamic linking code in static libc.
581c785b 2 Copyright (C) 1996-2022 Free Software Foundation, Inc.
afd4eb37 3 This file is part of the GNU C Library.
266180eb 4
afd4eb37 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.
266180eb 9
afd4eb37
UD
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.
266180eb 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/>. */
266180eb 18
266180eb
RM
19/* This file defines some things that for the dynamic linker are defined in
20 rtld.c and dl-sysdep.c in ways appropriate to bootstrap dynamic linking. */
21
47618209
SN
22#include <string.h>
23/* Mark symbols hidden in static PIE for early self relocation to work.
24 Note: string.h may have ifuncs which cannot be hidden on i686. */
25#if BUILD_PIE_DEFAULT
26# pragma GCC visibility push(hidden)
27#endif
3c720987 28#include <errno.h>
8e17ea58 29#include <libintl.h>
b13927da 30#include <stdlib.h>
0a54e401 31#include <unistd.h>
32b4c839 32#include <sys/param.h>
e054f494 33#include <stdint.h>
a42195db 34#include <ldsodefs.h>
0a54e401 35#include <dl-machine.h>
ec999b8e 36#include <libc-lock.h>
5688da55 37#include <dl-cache.h>
74955460 38#include <dl-librecon.h>
594d423a 39#include <dl-procinfo.h>
74955460 40#include <unsecvars.h>
3b5c1b57 41#include <hp-timing.h>
30950a5f 42#include <stackinfo.h>
1bdda52f
AZ
43#include <dl-vdso.h>
44#include <dl-vdso-setup.h>
18363b4f 45#include <dl-auxv.h>
5d28a896 46#include <dl-find_object.h>
73fc4e28 47#include <array_length.h>
b13927da 48
266180eb
RM
49extern char *__progname;
50char **_dl_argv = &__progname; /* This is checked for some error messages. */
51
0a54e401
UD
52/* Name of the architecture. */
53const char *_dl_platform;
54size_t _dl_platformlen;
3c720987 55
62dcee57 56int _dl_debug_mask;
12b5b6b7 57int _dl_lazy;
dec126b4 58int _dl_dynamic_weak;
0a54e401 59
b13927da
UD
60/* If nonzero print warnings about problematic situations. */
61int _dl_verbose;
62
3996f34b
UD
63/* We never do profiling. */
64const char *_dl_profile;
53bfdc1c 65const char *_dl_profile_output;
3996f34b 66
fcf70d41
UD
67/* Names of shared object for which the RUNPATHs and RPATHs should be
68 ignored. */
b0a01055 69const char *_dl_inhibit_rpath;
310930c1 70
a3d6fb9b
UD
71/* The map for the object we will profile. */
72struct link_map *_dl_profile_map;
73
c0fb8a56
UD
74/* This is the address of the last stack address ever used. */
75void *__libc_stack_end;
76
f787edde
UD
77/* Path where the binary is found. */
78const char *_dl_origin_path;
79
f53c03c2
UD
80/* Nonzero if runtime lookup should not update the .got/.plt. */
81int _dl_bind_not;
82
f91f1c0f
MR
83/* A dummy link map for the executable, used by dlopen to access the global
84 scope. We don't export any symbols ourselves, so this can be minimal. */
85static struct link_map _dl_main_map =
86 {
87 .l_name = (char *) "",
88 .l_real = &_dl_main_map,
89 .l_ns = LM_ID_BASE,
90 .l_libname = &(struct libname_list) { .name = "", .dont_free = 1 },
91 .l_searchlist =
92 {
93 .r_list = &(struct link_map *) { &_dl_main_map },
94 .r_nlist = 1,
95 },
96 .l_symbolic_searchlist = { .r_list = &(struct link_map *) { NULL } },
97 .l_type = lt_executable,
98 .l_scope_mem = { &_dl_main_map.l_searchlist },
99 .l_scope_max = (sizeof (_dl_main_map.l_scope_mem)
100 / sizeof (_dl_main_map.l_scope_mem[0])),
101 .l_scope = _dl_main_map.l_scope_mem,
102 .l_local_scope = { &_dl_main_map.l_searchlist },
103 .l_used = 1,
104 .l_tls_offset = NO_TLS_OFFSET,
105 .l_serial = 1,
106 };
107
c0f62c56 108/* Namespace information. */
f91f1c0f
MR
109struct link_namespaces _dl_ns[DL_NNS] =
110 {
111 [LM_ID_BASE] =
112 {
113 ._ns_loaded = &_dl_main_map,
114 ._ns_nloaded = 1,
115 ._ns_main_searchlist = &_dl_main_map.l_searchlist,
116 }
117 };
118size_t _dl_nns = 1;
be935610 119
bed12f78 120/* Incremented whenever something may have been added to dl_loaded. */
f91f1c0f 121unsigned long long _dl_load_adds = 1;
bed12f78 122
f91f1c0f
MR
123/* Fake scope of the main application. */
124struct r_scope_elem _dl_initial_searchlist =
125 {
126 .r_list = &(struct link_map *) { &_dl_main_map },
127 .r_nlist = 1,
128 };
be935610 129
ce6e047f 130#ifndef HAVE_INLINED_SYSCALLS
9ad04ff7
UD
131/* Nonzero during startup. */
132int _dl_starting_up = 1;
ce6e047f 133#endif
9ad04ff7 134
965cb60a
UD
135/* Random data provided by the kernel. */
136void *_dl_random;
137
ccdf0cab 138/* Get architecture specific initializer. */
4a306ef1 139#include <dl-procruntime.c>
ccdf0cab
UD
140#include <dl-procinfo.c>
141
32b4c839 142size_t _dl_pagesize = EXEC_PAGESIZE;
d6b5d570 143
6c57d320
L
144size_t _dl_minsigstacksize = CONSTANT_MINSIGSTKSZ;
145
73d65cc3
SP
146int _dl_inhibit_cache;
147
d6b5d570
UD
148unsigned int _dl_osversion;
149
150/* All known directories in sorted order. */
151struct r_search_path_elem *_dl_all_dirs;
152
153/* All directories after startup. */
154struct r_search_path_elem *_dl_init_all_dirs;
155
156/* The object to be initialized first. */
157struct link_map *_dl_initfirst;
158
5688da55
UD
159/* Descriptor to write debug messages to. */
160int _dl_debug_fd = STDERR_FILENO;
161
162int _dl_correct_cache_id = _DL_CACHE_DEFAULT_ID;
163
c7683a6d 164ElfW(auxv_t) *_dl_auxv;
dc0a0263 165const ElfW(Phdr) *_dl_phdr;
fcda29e2 166size_t _dl_phnum;
7c241325
FW
167uint64_t _dl_hwcap;
168uint64_t _dl_hwcap2;
172ce013 169
15a0c573
CLT
170enum dso_sort_algorithm _dl_dso_sort_algo;
171
95e7cf29
MR
172/* The value of the FPU control word the kernel will preset in hardware. */
173fpu_control_t _dl_fpu_control = _FPU_DEFAULT;
174
ff08fc59 175#if !HAVE_TUNABLES
7bfa311f
RM
176/* This is not initialized to HWCAP_IMPORTANT, matching the definition
177 of _dl_important_hwcaps, below, where no hwcap strings are ever
178 used. This mask is still used to mediate the lookups in the cache
179 file. Since there is no way to set this nonzero (we don't grok the
180 LD_HWCAP_MASK environment variable here), there is no real point in
181 setting _dl_hwcap nonzero below, but we do anyway. */
7c241325 182uint64_t _dl_hwcap_mask;
ff08fc59 183#endif
7bfa311f 184
30950a5f
RA
185/* Prevailing state of the stack. Generally this includes PF_X, indicating it's
186 * executable but this isn't true for all platforms. */
187ElfW(Word) _dl_stack_flags = DEFAULT_STACK_PERMS;
ecdeaac0 188
520a5887 189#if PTHREAD_IN_LIBC
1daccf40
FW
190list_t _dl_stack_used;
191list_t _dl_stack_user;
9d124d81
FW
192list_t _dl_stack_cache;
193size_t _dl_stack_cache_actsize;
194uintptr_t _dl_in_flight_stack;
1daccf40
FW
195int _dl_stack_cache_lock;
196#else
2dd87703
FW
197/* If loading a shared object requires that we make the stack executable
198 when it was not, we do it by calling this function.
199 It returns an errno code or zero on success. */
200int (*_dl_make_stack_executable_hook) (void **) = _dl_make_stack_executable;
7cbf1c84 201void (*_dl_init_static_tls) (struct link_map *) = &_dl_nothread_init_static_tls;
a5df0318 202#endif
e4eb675d
UD
203struct dl_scope_free_list *_dl_scope_free_list;
204
5e289179 205#ifdef NEED_DL_SYSINFO
cabc8a29
L
206/* Needed for improved syscall handling on at least x86/Linux. NB: Don't
207 initialize it here to avoid RELATIVE relocation in static PIE. */
208uintptr_t _dl_sysinfo;
30e32d23 209#endif
7775448e 210#ifdef NEED_DL_SYSINFO_DSO
f866314b
UD
211/* Address of the ELF headers in the vsyscall page. */
212const ElfW(Ehdr) *_dl_sysinfo_dso;
9cee5585
L
213
214struct link_map *_dl_sysinfo_map;
215
216# include "get-dynamic-info.h"
5e289179 217#endif
d0d4f868 218#include "setup-vdso.h"
1bdda52f
AZ
219/* Define the vDSO function pointers. */
220#include <dl-vdso-setup.c>
5e289179 221
cf197e41
UD
222/* During the program run we must not modify the global data of
223 loaded shared object simultanously in two threads. Therefore we
224 protect `_dl_open' and `_dl_close' in dl-close.c.
225
226 This must be a recursive lock since the initializer function of
227 the loaded object might as well require a call to this function.
228 At this time it is not anymore a problem to modify the tables. */
d3c9f895 229__rtld_lock_define_initialized_recursive (, _dl_load_lock)
5a2a1d75
AS
230/* This lock is used to keep __dl_iterate_phdr from inspecting the
231 list of loaded objects while an object is added to or removed from
232 that list. */
233__rtld_lock_define_initialized_recursive (, _dl_load_write_lock)
83b53232
SN
234 /* This lock protects global and module specific TLS related data.
235 E.g. it is held in dlopen and dlclose when GL(dl_tls_generation),
236 GL(dl_tls_max_dtv_idx) or GL(dl_tls_dtv_slotinfo_list) are
237 accessed and when TLS related relocations are processed for a
238 module. It was introduced to keep pthread_create accessing TLS
239 state that is being set up. */
240__rtld_lock_define_initialized_recursive (, _dl_load_tls_lock)
cf197e41 241
f8f900ec 242
e4a5f77d 243#ifdef HAVE_AUX_VECTOR
73fc4e28
FW
244#include <dl-parse_auxv.h>
245
d6b5d570 246int _dl_clktck;
0a54e401 247
e4a5f77d 248void
e4a5f77d 249_dl_aux_init (ElfW(auxv_t) *av)
b13927da 250{
cabc8a29
L
251#ifdef NEED_DL_SYSINFO
252 /* NB: Avoid RELATIVE relocation in static PIE. */
253 GL(dl_sysinfo) = DL_SYSINFO_DEFAULT;
254#endif
255
c7683a6d 256 _dl_auxv = av;
73fc4e28
FW
257 dl_parse_auxv_t auxv_values;
258 /* Use an explicit initialization loop here because memset may not
259 be available yet. */
260 for (int i = 0; i < array_length (auxv_values); ++i)
261 auxv_values[i] = 0;
262 _dl_parse_auxv (av, auxv_values);
e4a5f77d 263}
155fd00c 264#endif
f8f900ec 265
e4a5f77d 266
d417e0ff 267void
d417e0ff 268_dl_non_dynamic_init (void)
e4a5f77d 269{
f91f1c0f 270 _dl_main_map.l_origin = _dl_get_origin ();
0d23a5c1
MR
271 _dl_main_map.l_phdr = GL(dl_phdr);
272 _dl_main_map.l_phnum = GL(dl_phnum);
f91f1c0f 273
f8f900ec 274 _dl_verbose = *(getenv ("LD_WARN") ?: "") == '\0' ? 0 : 1;
e34b0f29 275
9cee5585
L
276 /* Set up the data structures for the system-supplied DSO early,
277 so they can influence _dl_init_paths. */
278 setup_vdso (NULL, NULL);
279
1bdda52f
AZ
280 /* With vDSO setup we can initialize the function pointers. */
281 setup_vdso_pointers ();
282
0a54e401
UD
283 /* Initialize the data structures for the search paths for shared
284 objects. */
dad90d52
FW
285 _dl_init_paths (getenv ("LD_LIBRARY_PATH"), "LD_LIBRARY_PATH",
286 /* No glibc-hwcaps selection support in statically
287 linked binaries. */
288 NULL, NULL);
0a54e401 289
bc5fb037
AS
290 /* Remember the last search directory added at startup. */
291 _dl_init_all_dirs = GL(dl_all_dirs);
292
12b5b6b7
UD
293 _dl_lazy = *(getenv ("LD_BIND_NOW") ?: "") == '\0';
294
f53c03c2
UD
295 _dl_bind_not = *(getenv ("LD_BIND_NOT") ?: "") != '\0';
296
dec126b4
UD
297 _dl_dynamic_weak = *(getenv ("LD_DYNAMIC_WEAK") ?: "") == '\0';
298
53bfdc1c
UD
299 _dl_profile_output = getenv ("LD_PROFILE_OUTPUT");
300 if (_dl_profile_output == NULL || _dl_profile_output[0] == '\0')
301 _dl_profile_output
302 = &"/var/tmp\0/var/profile"[__libc_enable_secure ? 9 : 0];
303
74955460
UD
304 if (__libc_enable_secure)
305 {
c4e328a1
UD
306 static const char unsecure_envvars[] =
307 UNSECURE_ENVVARS
74955460
UD
308#ifdef EXTRA_UNSECURE_ENVVARS
309 EXTRA_UNSECURE_ENVVARS
310#endif
c4e328a1
UD
311 ;
312 const char *cp = unsecure_envvars;
74955460 313
c4e328a1
UD
314 while (cp < unsecure_envvars + sizeof (unsecure_envvars))
315 {
316 __unsetenv (cp);
317 cp = (const char *) __rawmemchr (cp, '\0') + 1;
318 }
74955460 319
67e58f39 320#if !HAVE_TUNABLES
74955460 321 if (__access ("/etc/suid-debug", F_OK) != 0)
c4e328a1 322 __unsetenv ("MALLOC_CHECK_");
67e58f39 323#endif
74955460
UD
324 }
325
0a54e401
UD
326#ifdef DL_PLATFORM_INIT
327 DL_PLATFORM_INIT;
328#endif
329
2402cdf3
RM
330#ifdef DL_OSVERSION_INIT
331 DL_OSVERSION_INIT;
332#endif
333
0a54e401
UD
334 /* Now determine the length of the platform string. */
335 if (_dl_platform != NULL)
336 _dl_platformlen = strlen (_dl_platform);
ecdeaac0 337
ecdeaac0 338 if (_dl_phdr != NULL)
57013650
AZ
339 for (const ElfW(Phdr) *ph = _dl_phdr; ph < &_dl_phdr[_dl_phnum]; ++ph)
340 switch (ph->p_type)
ecdeaac0 341 {
57013650
AZ
342 /* Check if the stack is nonexecutable. */
343 case PT_GNU_STACK:
344 _dl_stack_flags = ph->p_flags;
345 break;
346
347 case PT_GNU_RELRO:
348 _dl_main_map.l_relro_addr = ph->p_vaddr;
349 _dl_main_map.l_relro_size = ph->p_memsz;
ecdeaac0
RM
350 break;
351 }
57013650 352
5d28a896
FW
353 call_function_static_weak (_dl_find_object_init);
354
57013650
AZ
355 /* Setup relro on the binary itself. */
356 if (_dl_main_map.l_relro_size != 0)
357 _dl_protect_relro (&_dl_main_map);
b13927da 358}
d417e0ff 359
5e289179
UD
360#ifdef DL_SYSINFO_IMPLEMENTATION
361DL_SYSINFO_IMPLEMENTATION
362#endif
9d7a3741
L
363
364#if ENABLE_STATIC_PIE
365/* Since relocation to hidden _dl_main_map causes relocation overflow on
366 aarch64, a function is used to get the address of _dl_main_map. */
367
368struct link_map *
369_dl_get_dl_main_map (void)
370{
371 return &_dl_main_map;
372}
373#endif
8c0664e2
AZ
374
375/* This is used by _dl_runtime_profile, not used on static code. */
376void
377DL_ARCH_FIXUP_ATTRIBUTE
378_dl_audit_pltexit (struct link_map *l, ElfW(Word) reloc_arg,
379 const void *inregs, void *outregs)
380{
381}