]> git.ipfire.org Git - thirdparty/glibc.git/blame - elf/dl-support.c
Update copyright notices with scripts/update-copyrights.
[thirdparty/glibc.git] / elf / dl-support.c
CommitLineData
266180eb 1/* Support for dynamic linking code in static libc.
568035b7 2 Copyright (C) 1996-2013 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
PE
16 License along with the GNU C Library; if not, see
17 <http://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
3c720987 22#include <errno.h>
8e17ea58 23#include <libintl.h>
b13927da 24#include <stdlib.h>
0a54e401 25#include <unistd.h>
32b4c839 26#include <sys/param.h>
a42195db 27#include <ldsodefs.h>
0a54e401 28#include <dl-machine.h>
cf197e41 29#include <bits/libc-lock.h>
5688da55 30#include <dl-cache.h>
74955460 31#include <dl-librecon.h>
594d423a 32#include <dl-procinfo.h>
74955460 33#include <unsecvars.h>
3b5c1b57 34#include <hp-timing.h>
30950a5f 35#include <stackinfo.h>
b13927da 36
266180eb
RM
37extern char *__progname;
38char **_dl_argv = &__progname; /* This is checked for some error messages. */
39
0a54e401
UD
40/* Name of the architecture. */
41const char *_dl_platform;
42size_t _dl_platformlen;
3c720987 43
62dcee57 44int _dl_debug_mask;
12b5b6b7 45int _dl_lazy;
97fd3a30 46ElfW(Addr) _dl_use_load_bias = -2;
dec126b4 47int _dl_dynamic_weak;
0a54e401 48
b13927da
UD
49/* If nonzero print warnings about problematic situations. */
50int _dl_verbose;
51
3996f34b
UD
52/* We never do profiling. */
53const char *_dl_profile;
53bfdc1c 54const char *_dl_profile_output;
3996f34b 55
fcf70d41
UD
56/* Names of shared object for which the RUNPATHs and RPATHs should be
57 ignored. */
b0a01055 58const char *_dl_inhibit_rpath;
310930c1 59
a3d6fb9b
UD
60/* The map for the object we will profile. */
61struct link_map *_dl_profile_map;
62
c0fb8a56
UD
63/* This is the address of the last stack address ever used. */
64void *__libc_stack_end;
65
f787edde
UD
66/* Path where the binary is found. */
67const char *_dl_origin_path;
68
f53c03c2
UD
69/* Nonzero if runtime lookup should not update the .got/.plt. */
70int _dl_bind_not;
71
c0f62c56
UD
72/* Namespace information. */
73struct link_namespaces _dl_ns[DL_NNS];
22c83193 74size_t _dl_nns;
be935610 75
bed12f78
UD
76/* Incremented whenever something may have been added to dl_loaded. */
77unsigned long long _dl_load_adds;
bed12f78 78
be935610 79/* Fake scope. In dynamically linked binaries this is the scope of the
604510f7 80 main application but here we don't have something like this. So
be935610 81 create a fake scope containing nothing. */
604510f7 82struct r_scope_elem _dl_initial_searchlist;
be935610 83
ce6e047f 84#ifndef HAVE_INLINED_SYSCALLS
9ad04ff7
UD
85/* Nonzero during startup. */
86int _dl_starting_up = 1;
ce6e047f 87#endif
9ad04ff7 88
965cb60a
UD
89/* Random data provided by the kernel. */
90void *_dl_random;
91
ccdf0cab
UD
92/* Get architecture specific initializer. */
93#include <dl-procinfo.c>
94
eaad82e0
UD
95/* We expect less than a second for relocation. */
96#ifdef HP_SMALL_TIMING_AVAIL
97# undef HP_TIMING_AVAIL
98# define HP_TIMING_AVAIL HP_SMALL_TIMING_AVAIL
99#endif
100
5fc48cd7 101/* Initial value of the CPU clock. */
eaad82e0 102#ifndef HP_TIMING_NONAVAIL
3b5c1b57 103hp_timing_t _dl_cpuclock_offset;
5fc48cd7
UD
104#endif
105
adc12574 106void (*_dl_init_static_tls) (struct link_map *) = &_dl_nothread_init_static_tls;
adc12574 107
32b4c839 108size_t _dl_pagesize = EXEC_PAGESIZE;
d6b5d570 109
73d65cc3
SP
110int _dl_inhibit_cache;
111
d6b5d570
UD
112unsigned int _dl_osversion;
113
114/* All known directories in sorted order. */
115struct r_search_path_elem *_dl_all_dirs;
116
117/* All directories after startup. */
118struct r_search_path_elem *_dl_init_all_dirs;
119
120/* The object to be initialized first. */
121struct link_map *_dl_initfirst;
122
5688da55
UD
123/* Descriptor to write debug messages to. */
124int _dl_debug_fd = STDERR_FILENO;
125
126int _dl_correct_cache_id = _DL_CACHE_DEFAULT_ID;
127
c7683a6d 128ElfW(auxv_t) *_dl_auxv;
172ce013 129ElfW(Phdr) *_dl_phdr;
fcda29e2 130size_t _dl_phnum;
ab1d521d 131uint64_t _dl_hwcap __attribute__ ((nocommon));
172ce013 132
7bfa311f
RM
133/* This is not initialized to HWCAP_IMPORTANT, matching the definition
134 of _dl_important_hwcaps, below, where no hwcap strings are ever
135 used. This mask is still used to mediate the lookups in the cache
136 file. Since there is no way to set this nonzero (we don't grok the
137 LD_HWCAP_MASK environment variable here), there is no real point in
138 setting _dl_hwcap nonzero below, but we do anyway. */
139uint64_t _dl_hwcap_mask __attribute__ ((nocommon));
140
30950a5f
RA
141/* Prevailing state of the stack. Generally this includes PF_X, indicating it's
142 * executable but this isn't true for all platforms. */
143ElfW(Word) _dl_stack_flags = DEFAULT_STACK_PERMS;
ecdeaac0
RM
144
145/* If loading a shared object requires that we make the stack executable
146 when it was not, we do it by calling this function.
147 It returns an errno code or zero on success. */
d1fc817e 148int (*_dl_make_stack_executable_hook) (void **) internal_function
ecdeaac0
RM
149 = _dl_make_stack_executable;
150
151
df94b641
UD
152/* Function in libpthread to wait for termination of lookups. */
153void (*_dl_wait_lookup_done) (void);
154
e4eb675d
UD
155struct dl_scope_free_list *_dl_scope_free_list;
156
5e289179
UD
157#ifdef NEED_DL_SYSINFO
158/* Needed for improved syscall handling on at least x86/Linux. */
159uintptr_t _dl_sysinfo = DL_SYSINFO_DEFAULT;
30e32d23
RM
160#endif
161#if defined NEED_DL_SYSINFO || defined NEED_DL_SYSINFO_DSO
f866314b
UD
162/* Address of the ELF headers in the vsyscall page. */
163const ElfW(Ehdr) *_dl_sysinfo_dso;
9cee5585
L
164
165struct link_map *_dl_sysinfo_map;
166
167# include "get-dynamic-info.h"
5e289179 168#endif
d0d4f868 169#include "setup-vdso.h"
5e289179 170
cf197e41
UD
171/* During the program run we must not modify the global data of
172 loaded shared object simultanously in two threads. Therefore we
173 protect `_dl_open' and `_dl_close' in dl-close.c.
174
175 This must be a recursive lock since the initializer function of
176 the loaded object might as well require a call to this function.
177 At this time it is not anymore a problem to modify the tables. */
d3c9f895 178__rtld_lock_define_initialized_recursive (, _dl_load_lock)
5a2a1d75
AS
179/* This lock is used to keep __dl_iterate_phdr from inspecting the
180 list of loaded objects while an object is added to or removed from
181 that list. */
182__rtld_lock_define_initialized_recursive (, _dl_load_write_lock)
cf197e41 183
f8f900ec 184
e4a5f77d 185#ifdef HAVE_AUX_VECTOR
d6b5d570 186int _dl_clktck;
0a54e401 187
e4a5f77d
UD
188void
189internal_function
190_dl_aux_init (ElfW(auxv_t) *av)
b13927da 191{
be4d8038
UD
192 int seen = 0;
193 uid_t uid = 0;
194 gid_t gid = 0;
195
c7683a6d 196 _dl_auxv = av;
f8f900ec
UD
197 for (; av->a_type != AT_NULL; ++av)
198 switch (av->a_type)
199 {
200 case AT_PAGESZ:
afdca0f2 201 GLRO(dl_pagesize) = av->a_un.a_val;
f8f900ec 202 break;
f8f900ec 203 case AT_CLKTCK:
afdca0f2 204 GLRO(dl_clktck) = av->a_un.a_val;
f8f900ec 205 break;
fcda29e2 206 case AT_PHDR:
39fb308f 207 GL(dl_phdr) = (void *) av->a_un.a_val;
fcda29e2
UD
208 break;
209 case AT_PHNUM:
210 GL(dl_phnum) = av->a_un.a_val;
211 break;
11bf8ce1 212 case AT_HWCAP:
ab1d521d 213 GLRO(dl_hwcap) = (unsigned long int) av->a_un.a_val;
11bf8ce1 214 break;
5df8349b
UD
215#ifdef NEED_DL_SYSINFO
216 case AT_SYSINFO:
217 GL(dl_sysinfo) = av->a_un.a_val;
218 break;
30e32d23
RM
219#endif
220#if defined NEED_DL_SYSINFO || defined NEED_DL_SYSINFO_DSO
221 case AT_SYSINFO_EHDR:
39fb308f 222 GL(dl_sysinfo_dso) = (void *) av->a_un.a_val;
30e32d23 223 break;
5df8349b 224#endif
be4d8038
UD
225 case AT_UID:
226 uid ^= av->a_un.a_val;
227 seen |= 1;
228 break;
229 case AT_EUID:
230 uid ^= av->a_un.a_val;
231 seen |= 2;
232 break;
233 case AT_GID:
234 gid ^= av->a_un.a_val;
235 seen |= 4;
236 break;
237 case AT_EGID:
238 gid ^= av->a_un.a_val;
239 seen |= 8;
240 break;
c801e765
RM
241 case AT_SECURE:
242 seen = -1;
243 __libc_enable_secure = av->a_un.a_val;
244 __libc_enable_secure_decided = 1;
245 break;
965cb60a
UD
246 case AT_RANDOM:
247 _dl_random = (void *) av->a_un.a_val;
248 break;
47dbe62b
RH
249# ifdef DL_PLATFORM_AUXV
250 DL_PLATFORM_AUXV
251# endif
f8f900ec 252 }
be4d8038
UD
253 if (seen == 0xf)
254 {
255 __libc_enable_secure = uid != 0 || gid != 0;
256 __libc_enable_secure_decided = 1;
257 }
e4a5f77d 258}
155fd00c 259#endif
f8f900ec 260
e4a5f77d 261
d417e0ff
UD
262void
263internal_function
264_dl_non_dynamic_init (void)
e4a5f77d 265{
eaad82e0
UD
266 if (HP_TIMING_AVAIL)
267 HP_TIMING_NOW (_dl_cpuclock_offset);
5fc48cd7 268
f8f900ec
UD
269 if (!_dl_pagesize)
270 _dl_pagesize = __getpagesize ();
271
272 _dl_verbose = *(getenv ("LD_WARN") ?: "") == '\0' ? 0 : 1;
e34b0f29 273
9cee5585
L
274 /* Set up the data structures for the system-supplied DSO early,
275 so they can influence _dl_init_paths. */
276 setup_vdso (NULL, NULL);
277
0a54e401
UD
278 /* Initialize the data structures for the search paths for shared
279 objects. */
b4debac9 280 _dl_init_paths (getenv ("LD_LIBRARY_PATH"));
0a54e401 281
bc5fb037
AS
282 /* Remember the last search directory added at startup. */
283 _dl_init_all_dirs = GL(dl_all_dirs);
284
12b5b6b7
UD
285 _dl_lazy = *(getenv ("LD_BIND_NOW") ?: "") == '\0';
286
f53c03c2
UD
287 _dl_bind_not = *(getenv ("LD_BIND_NOT") ?: "") != '\0';
288
dec126b4
UD
289 _dl_dynamic_weak = *(getenv ("LD_DYNAMIC_WEAK") ?: "") == '\0';
290
53bfdc1c
UD
291 _dl_profile_output = getenv ("LD_PROFILE_OUTPUT");
292 if (_dl_profile_output == NULL || _dl_profile_output[0] == '\0')
293 _dl_profile_output
294 = &"/var/tmp\0/var/profile"[__libc_enable_secure ? 9 : 0];
295
74955460
UD
296 if (__libc_enable_secure)
297 {
c4e328a1
UD
298 static const char unsecure_envvars[] =
299 UNSECURE_ENVVARS
74955460
UD
300#ifdef EXTRA_UNSECURE_ENVVARS
301 EXTRA_UNSECURE_ENVVARS
302#endif
c4e328a1
UD
303 ;
304 const char *cp = unsecure_envvars;
74955460 305
c4e328a1
UD
306 while (cp < unsecure_envvars + sizeof (unsecure_envvars))
307 {
308 __unsetenv (cp);
309 cp = (const char *) __rawmemchr (cp, '\0') + 1;
310 }
74955460
UD
311
312 if (__access ("/etc/suid-debug", F_OK) != 0)
c4e328a1 313 __unsetenv ("MALLOC_CHECK_");
74955460
UD
314 }
315
0a54e401
UD
316#ifdef DL_PLATFORM_INIT
317 DL_PLATFORM_INIT;
318#endif
319
2402cdf3
RM
320#ifdef DL_OSVERSION_INIT
321 DL_OSVERSION_INIT;
322#endif
323
0a54e401
UD
324 /* Now determine the length of the platform string. */
325 if (_dl_platform != NULL)
326 _dl_platformlen = strlen (_dl_platform);
ecdeaac0
RM
327
328 /* Scan for a program header telling us the stack is nonexecutable. */
329 if (_dl_phdr != NULL)
330 for (uint_fast16_t i = 0; i < _dl_phnum; ++i)
331 if (_dl_phdr[i].p_type == PT_GNU_STACK)
332 {
333 _dl_stack_flags = _dl_phdr[i].p_flags;
334 break;
335 }
b13927da 336}
d417e0ff 337
5e289179
UD
338#ifdef DL_SYSINFO_IMPLEMENTATION
339DL_SYSINFO_IMPLEMENTATION
340#endif