]> git.ipfire.org Git - thirdparty/glibc.git/blame - elf/rtld.c
(_dl_map_object_from_fd): Store alignment requirement along with the other info in...
[thirdparty/glibc.git] / elf / rtld.c
CommitLineData
d66e34cd 1/* Run time dynamic linker.
e66d0a4c 2 Copyright (C) 1995-1999, 2000, 2001, 2002 Free Software Foundation, Inc.
afd4eb37 3 This file is part of the GNU C Library.
d66e34cd 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.
d66e34cd 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.
d66e34cd 14
41bdb6e2
AJ
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, write to the Free
17 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18 02111-1307 USA. */
d66e34cd 19
7dea968e 20#include <fcntl.h>
164a7164 21#include <stdbool.h>
d66e34cd 22#include <stdlib.h>
f51d1dfd 23#include <string.h>
d66e34cd 24#include <unistd.h>
2064087b 25#include <sys/mman.h> /* Check if MAP_ANON is defined. */
af8bf6bd 26#include <sys/param.h>
ba9fcb3f 27#include <sys/stat.h>
a42195db 28#include <ldsodefs.h>
ce37fa88 29#include <stdio-common/_itoa.h>
f21acc89 30#include <entry.h>
c94a8080 31#include <fpu_control.h>
db276fa1 32#include <hp-timing.h>
cf197e41 33#include <bits/libc-lock.h>
f5348425 34#include "dynamic-link.h"
e2102c14 35#include "dl-librecon.h"
74955460 36#include <unsecvars.h>
5688da55
UD
37#include <dl-cache.h>
38#include <dl-procinfo.h>
f5348425 39
a853022c 40#include <assert.h>
f5348425 41
fd26970f 42/* Helper function to handle errors while resolving symbols. */
c84142e8
UD
43static void print_unresolved (int errcode, const char *objname,
44 const char *errsting);
45
46/* Helper function to handle errors when a version is missing. */
47static void print_missing_version (int errcode, const char *objname,
48 const char *errsting);
fd26970f 49
db276fa1
UD
50/* Print the various times we collected. */
51static void print_statistics (void);
ea278354
UD
52
53/* This is a list of all the modes the dynamic loader can be in. */
54enum mode { normal, list, verify, trace };
55
56/* Process all environments variables the dynamic linker must recognize.
57 Since all of them start with `LD_' we are a bit smarter while finding
58 all the entries. */
ba9fcb3f 59static void process_envvars (enum mode *modep);
ea278354 60
d66e34cd
RM
61int _dl_argc;
62char **_dl_argv;
ceb27555 63unsigned int _dl_skip_args; /* Nonzero if we were run directly. */
cf197e41 64
39778c6c
UD
65/* Set nonzero during loading and initialization of executable and
66 libraries, cleared before the executable's entry point runs. This
67 must not be initialized to nonzero, because the unused dynamic
68 linker loaded in for libc.so's "ld.so.1" dep will provide the
69 definition seen by libc.so's initializer; that value must be zero,
70 and will be since that dynamic linker's _dl_start and dl_main will
71 never be called. */
72int _dl_starting_up;
73
d6b5d570
UD
74/* This is the structure which defines all variables global to ld.so
75 (except those which cannot be added for some reason). */
5688da55
UD
76struct rtld_global _rtld_global =
77 {
ccdf0cab
UD
78 /* Get architecture specific initializer. */
79#include <dl-procinfo.c>
5688da55
UD
80 ._dl_debug_fd = STDERR_FILENO,
81#if 1
82 /* XXX I know about at least one case where we depend on the old
83 weak behavior (it has to do with librt). Until we get DSO
84 groups implemented we have to make this the default.
85 Bummer. --drepper */
86 ._dl_dynamic_weak = 1,
87#endif
88 ._dl_lazy = 1,
89 ._dl_fpu_control = _FPU_DEFAULT,
90 ._dl_correct_cache_id = _DL_CACHE_DEFAULT_ID,
91 ._dl_hwcap_mask = HWCAP_IMPORTANT,
92 ._dl_load_lock = _LIBC_LOCK_RECURSIVE_INITIALIZER
93 };
94/* There must only be the definition in ld.so itself. */
95#ifdef HAVE_PROTECTED
96asm (".protected _rtld_global");
97#endif
d6b5d570 98
c0fb8a56 99
67ddea92 100static void dl_main (const ElfW(Phdr) *phdr, ElfW(Word) phnum,
266180eb 101 ElfW(Addr) *user_entry);
d66e34cd 102
d6b5d570
UD
103static struct libname_list _dl_rtld_libname;
104static struct libname_list _dl_rtld_libname2;
86d2c878 105
eaad82e0
UD
106/* We expect less than a second for relocation. */
107#ifdef HP_SMALL_TIMING_AVAIL
108# undef HP_TIMING_AVAIL
109# define HP_TIMING_AVAIL HP_SMALL_TIMING_AVAIL
110#endif
111
db276fa1 112/* Variable for statistics. */
5732c4df 113#ifndef HP_TIMING_NONAVAIL
db276fa1
UD
114static hp_timing_t rtld_total_time;
115static hp_timing_t relocate_time;
116static hp_timing_t load_time;
5732c4df 117#endif
db276fa1 118
6a1db4ff
UD
119static ElfW(Addr) _dl_start_final (void *arg, struct link_map *bootstrap_map_p,
120 hp_timing_t start_time);
121
b1dbbaa4
RM
122#ifdef RTLD_START
123RTLD_START
124#else
eaad82e0 125# error "sysdeps/MACHINE/dl-machine.h fails to define RTLD_START"
b1dbbaa4
RM
126#endif
127
50746436 128static ElfW(Addr) __attribute_used__ internal_function
d66e34cd
RM
129_dl_start (void *arg)
130{
86d2c878 131 struct link_map bootstrap_map;
db276fa1 132 hp_timing_t start_time;
1b4575ae 133#if !__GNUC_PREREQ (2, 96)
264ec183 134 size_t cnt;
1b4575ae 135#endif
d66e34cd 136
b1dbbaa4
RM
137 /* This #define produces dynamic linking inline functions for
138 bootstrap relocation instead of general-purpose relocation. */
139#define RTLD_BOOTSTRAP
c0282c06
UD
140#define RESOLVE_MAP(sym, version, flags) \
141 ((*(sym))->st_shndx == SHN_UNDEF ? 0 : &bootstrap_map)
50463d27
UD
142#define RESOLVE(sym, version, flags) \
143 ((*(sym))->st_shndx == SHN_UNDEF ? 0 : bootstrap_map.l_addr)
b1dbbaa4
RM
144#include "dynamic-link.h"
145
db276fa1
UD
146 if (HP_TIMING_INLINE && HP_TIMING_AVAIL)
147 HP_TIMING_NOW (start_time);
148
e66d0a4c
UD
149 /* Partly clean the `bootstrap_map' structure up. Don't use
150 `memset' since it might not be built in or inlined and we cannot
151 make function calls at this point. Use '__builtin_memset' if we
152 know it is available. */
153#if __GNUC_PREREQ (2, 96)
154 __builtin_memset (bootstrap_map.l_info, '\0', sizeof (bootstrap_map.l_info));
155#else
264ec183
UD
156 for (cnt = 0;
157 cnt < sizeof (bootstrap_map.l_info) / sizeof (bootstrap_map.l_info[0]);
158 ++cnt)
159 bootstrap_map.l_info[cnt] = 0;
e66d0a4c 160#endif
264ec183 161
d66e34cd 162 /* Figure out the run-time load address of the dynamic linker itself. */
86d2c878 163 bootstrap_map.l_addr = elf_machine_load_address ();
d66e34cd 164
47707456
UD
165 /* Read our own dynamic section and fill in the info array. */
166 bootstrap_map.l_ld = (void *) bootstrap_map.l_addr + elf_machine_dynamic ();
d3ac2d47 167 elf_get_dynamic_info (&bootstrap_map);
d66e34cd
RM
168
169#ifdef ELF_MACHINE_BEFORE_RTLD_RELOC
86d2c878 170 ELF_MACHINE_BEFORE_RTLD_RELOC (bootstrap_map.l_info);
d66e34cd
RM
171#endif
172
32e6df36
UD
173 if (bootstrap_map.l_addr || ! bootstrap_map.l_info[VALIDX(DT_GNU_PRELINKED)])
174 {
175 /* Relocate ourselves so we can do normal function calls and
176 data access using the global offset table. */
177
178 ELF_DYNAMIC_RELOCATE (&bootstrap_map, 0, 0);
179 }
421f82e5 180
ea7eb7e3
UD
181 /* Please note that we don't allow profiling of this object and
182 therefore need not test whether we have to allocate the array
183 for the relocation results (as done in dl-reloc.c). */
421f82e5 184
d66e34cd
RM
185 /* Now life is sane; we can call functions and access global data.
186 Set up to use the operating system facilities, and find out from
187 the operating system's program loader where to find the program
6a1db4ff
UD
188 header table in core. Put the rest of _dl_start into a separate
189 function, that way the compiler cannot put accesses to the GOT
190 before ELF_DYNAMIC_RELOCATE. */
c0282c06
UD
191 {
192 ElfW(Addr) entry = _dl_start_final (arg, &bootstrap_map, start_time);
193
194#ifndef ELF_MACHINE_START_ADDRESS
195# define ELF_MACHINE_START_ADDRESS(map, start) (start)
196#endif
197
d6b5d570 198 return ELF_MACHINE_START_ADDRESS (GL(dl_loaded), entry);
c0282c06 199 }
6a1db4ff
UD
200}
201
202
32e6df36
UD
203#ifndef VALIDX
204# define VALIDX(tag) (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGNUM \
205 + DT_EXTRANUM + DT_VALTAGIDX (tag))
206#endif
207#ifndef ADDRIDX
208# define ADDRIDX(tag) (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGNUM \
209 + DT_EXTRANUM + DT_VALNUM + DT_ADDRTAGIDX (tag))
210#endif
211
6a1db4ff
UD
212static ElfW(Addr)
213_dl_start_final (void *arg, struct link_map *bootstrap_map_p,
214 hp_timing_t start_time)
215{
216 /* The use of `alloca' here looks ridiculous but it helps. The goal
217 is to avoid the function from being inlined. There is no official
218 way to do this so we use this trick. gcc never inlines functions
219 which use `alloca'. */
220 ElfW(Addr) *start_addr = alloca (sizeof (ElfW(Addr)));
32e6df36 221 extern char _begin[], _end[];
535b764d
UD
222#ifdef USE_TLS
223 ElfW(Ehdr) *ehdr;
224 ElfW(Phdr) *phdr;
225 size_t cnt;
535b764d
UD
226 dtv_t initdtv[2];
227#endif
d66e34cd 228
db276fa1
UD
229 if (HP_TIMING_AVAIL)
230 {
231 /* If it hasn't happen yet record the startup time. */
232 if (! HP_TIMING_INLINE)
233 HP_TIMING_NOW (start_time);
234
235 /* Initialize the timing functions. */
236 HP_TIMING_DIFF_INIT ();
237 }
238
86d2c878 239 /* Transfer data about ourselves to the permanent link_map structure. */
d6b5d570
UD
240 GL(dl_rtld_map).l_addr = bootstrap_map_p->l_addr;
241 GL(dl_rtld_map).l_ld = bootstrap_map_p->l_ld;
242 GL(dl_rtld_map).l_opencount = 1;
243 memcpy (GL(dl_rtld_map).l_info, bootstrap_map_p->l_info,
244 sizeof GL(dl_rtld_map).l_info);
245 _dl_setup_hash (&GL(dl_rtld_map));
246 GL(dl_rtld_map).l_mach = bootstrap_map_p->l_mach;
247 GL(dl_rtld_map).l_map_start = (ElfW(Addr)) _begin;
248 GL(dl_rtld_map).l_map_end = (ElfW(Addr)) _end;
052b6a6c 249
67ddea92
UD
250#if HP_TIMING_AVAIL
251 HP_TIMING_NOW (GL(dl_cpuclock_offset));
252#endif
253
535b764d
UD
254#if USE_TLS
255 /* Get the dynamic linkers program header. */
47536120
UD
256 ehdr = (ElfW(Ehdr) *) GL(dl_rtld_map).l_map_start;
257 phdr = (ElfW(Phdr) *) (GL(dl_rtld_map).l_map_start + ehdr->e_phoff);
535b764d
UD
258 for (cnt = 0; cnt < ehdr->e_phnum; ++cnt)
259 if (phdr[cnt].p_type == PT_TLS)
260 {
5d6feea8 261 void *tlsblock;
37d8b778 262 size_t align = MAX (TLS_INIT_TCB_ALIGN, phdr[cnt].p_align);
535b764d 263
5d6feea8
UD
264 GL(dl_rtld_map).l_tls_blocksize = phdr[cnt].p_memsz;
265 GL(dl_rtld_map).l_tls_initimage_size = phdr[cnt].p_filesz;
37d8b778 266 GL(dl_rtld_map).l_tls_initimage = (void *) (GL(dl_rtld_map).l_map_start
5d6feea8 267 + phdr[cnt].p_offset);
535b764d
UD
268
269 /* We can now allocate the initial TLS block. This can happen
270 on the stack. We'll get the final memory later when we
271 know all about the various objects loaded at startup
272 time. */
273# if TLS_TCB_AT_TP
5d6feea8
UD
274 tlsblock = alloca (roundup (GL(dl_rtld_map).l_tls_blocksize,
275 TLS_INIT_TCB_ALIGN)
535b764d
UD
276 + TLS_INIT_TCB_SIZE
277 + align);
278# elif TLS_DTV_AT_TP
279 tlsblock = alloca (roundup (TLS_INIT_TCB_SIZE, phdr[cnt].p_align)
5d6feea8 280 + GL(dl_rtld_map).l_tls_blocksize
535b764d
UD
281 + align);
282# else
283 /* In case a model with a different layout for the TCB and DTV
284 is defined add another #elif here and in the following #ifs. */
285# error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
286# endif
287 /* Align the TLS block. */
288 tlsblock = (void *) (((uintptr_t) tlsblock + align - 1)
289 & ~(align - 1));
290
291 /* Initialize the dtv. */
292 initdtv[0].counter = 1;
293
294 /* Initialize the TLS block. */
295# if TLS_TCB_AT_TP
296 initdtv[1].pointer = tlsblock;
297# elif TLS_DTV_AT_TP
5d6feea8
UD
298 GL(dl_rtld_map).l_tls_offset = roundup (TLS_INIT_TCB_SIZE,
299 phdr[cnt].p_align);
300 initdtv[1].pointer = (char *) tlsblock + GL(dl_rtld_map).l_tls_offset);
535b764d
UD
301# else
302# error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
303# endif
5d6feea8
UD
304 memset (__mempcpy (initdtv[1].pointer, GL(dl_rtld_map).l_tls_initimage,
305 GL(dl_rtld_map).l_tls_initimage_size),
306 '\0', (GL(dl_rtld_map).l_tls_blocksize
307 - GL(dl_rtld_map).l_tls_initimage_size));
535b764d
UD
308
309 /* Initialize the thread pointer. */
310# if TLS_TCB_AT_TP
5d6feea8
UD
311 GL(dl_rtld_map).l_tls_offset
312 = roundup (GL(dl_rtld_map).l_tls_blocksize, TLS_INIT_TCB_ALIGN);
313 TLS_INIT_TP ((char *) tlsblock + GL(dl_rtld_map).l_tls_offset,
314 initdtv);
535b764d 315# elif TLS_DTV_AT_TP
5d6feea8 316 TLS_INIT_TP (tlsblock, initdtv);
535b764d
UD
317# else
318# error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
319# endif
320
5d6feea8
UD
321 /* So far this is module number one. */
322 GL(dl_rtld_map).l_tls_modid = 1;
323
535b764d
UD
324 /* There can only be one PT_TLS entry. */
325 break;
326 }
327#endif /* use TLS */
328
d66e34cd
RM
329 /* Call the OS-dependent function to set up life so we can do things like
330 file access. It will call `dl_main' (below) to do all the real work
331 of the dynamic linker, and then unwind our frame and run the user
332 entry point on the same stack we entered on. */
6a1db4ff 333 *start_addr = _dl_sysdep_start (arg, &dl_main);
535b764d 334
8b07d6a8 335#ifndef HP_TIMING_NONAVAIL
db276fa1
UD
336 if (HP_TIMING_AVAIL)
337 {
338 hp_timing_t end_time;
339
340 /* Get the current time. */
341 HP_TIMING_NOW (end_time);
342
343 /* Compute the difference. */
344 HP_TIMING_DIFF (rtld_total_time, start_time, end_time);
345 }
8b07d6a8 346#endif
db276fa1 347
d6b5d570 348 if (__builtin_expect (GL(dl_debug_mask) & DL_DEBUG_STATISTICS, 0))
db276fa1
UD
349 print_statistics ();
350
6a1db4ff 351 return *start_addr;
d66e34cd
RM
352}
353
d66e34cd
RM
354/* Now life is peachy; we can do all normal operations.
355 On to the real work. */
356
993b3242
UD
357/* Some helper functions. */
358
359/* Arguments to relocate_doit. */
360struct relocate_args
361{
362 struct link_map *l;
363 int lazy;
364};
365
366struct map_args
367{
368 /* Argument to map_doit. */
369 char *str;
370 /* Return value of map_doit. */
371 struct link_map *main_map;
372};
373
374/* Arguments to version_check_doit. */
375struct version_check_args
376{
993b3242 377 int doexit;
145b8413 378 int dotrace;
993b3242
UD
379};
380
381static void
382relocate_doit (void *a)
383{
384 struct relocate_args *args = (struct relocate_args *) a;
385
cff26a3e 386 INTUSE(_dl_relocate_object) (args->l, args->l->l_scope, args->lazy, 0);
993b3242
UD
387}
388
389static void
390map_doit (void *a)
391{
be935610 392 struct map_args *args = (struct map_args *) a;
cff26a3e 393 args->main_map = INTUSE(_dl_map_object) (NULL, args->str, 0, lt_library, 0, 0);
993b3242
UD
394}
395
396static void
397version_check_doit (void *a)
398{
be935610 399 struct version_check_args *args = (struct version_check_args *) a;
d6b5d570 400 if (_dl_check_all_versions (GL(dl_loaded), 1, args->dotrace) && args->doexit)
993b3242
UD
401 /* We cannot start the application. Abort now. */
402 _exit (1);
403}
404
ce37fa88
UD
405
406static inline struct link_map *
407find_needed (const char *name)
408{
d6b5d570 409 unsigned int n = GL(dl_loaded)->l_searchlist.r_nlist;
ce37fa88 410
be935610 411 while (n-- > 0)
d6b5d570
UD
412 if (_dl_name_match_p (name, GL(dl_loaded)->l_searchlist.r_list[n]))
413 return GL(dl_loaded)->l_searchlist.r_list[n];
ce37fa88
UD
414
415 /* Should never happen. */
416 return NULL;
417}
418
419static int
420match_version (const char *string, struct link_map *map)
421{
a42195db 422 const char *strtab = (const void *) D_PTR (map, l_info[DT_STRTAB]);
ce37fa88
UD
423 ElfW(Verdef) *def;
424
b0982c4a 425#define VERDEFTAG (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGIDX (DT_VERDEF))
ce37fa88
UD
426 if (map->l_info[VERDEFTAG] == NULL)
427 /* The file has no symbol versioning. */
428 return 0;
429
430 def = (ElfW(Verdef) *) ((char *) map->l_addr
431 + map->l_info[VERDEFTAG]->d_un.d_ptr);
432 while (1)
433 {
434 ElfW(Verdaux) *aux = (ElfW(Verdaux) *) ((char *) def + def->vd_aux);
435
436 /* Compare the version strings. */
437 if (strcmp (string, strtab + aux->vda_name) == 0)
438 /* Bingo! */
439 return 1;
440
441 /* If no more definitions we failed to find what we want. */
442 if (def->vd_next == 0)
443 break;
444
445 /* Next definition. */
446 def = (ElfW(Verdef) *) ((char *) def + def->vd_next);
447 }
448
449 return 0;
450}
451
120b4c49
UD
452static const char *library_path; /* The library search path. */
453static const char *preloadlist; /* The list preloaded objects. */
454static int version_info; /* Nonzero if information about
455 versions has to be printed. */
a1a9d215 456
d66e34cd 457static void
266180eb 458dl_main (const ElfW(Phdr) *phdr,
72f70279 459 ElfW(Word) phnum,
266180eb 460 ElfW(Addr) *user_entry)
d66e34cd 461{
266180eb 462 const ElfW(Phdr) *ph;
ea278354 463 enum mode mode;
2064087b
RM
464 struct link_map **preloads;
465 unsigned int npreloads;
14bab8de
UD
466 size_t file_size;
467 char *file;
164a7164 468 bool has_interp = false;
77aba05b 469 unsigned int i;
164a7164
UD
470 bool prelinked = false;
471 bool rtld_is_main = false;
5732c4df 472#ifndef HP_TIMING_NONAVAIL
db276fa1
UD
473 hp_timing_t start;
474 hp_timing_t stop;
475 hp_timing_t diff;
5732c4df 476#endif
d66e34cd 477
ea278354 478 /* Process the environment variable which control the behaviour. */
ba9fcb3f 479 process_envvars (&mode);
3996f34b 480
46ec036d
UD
481 /* Set up a flag which tells we are just starting. */
482 _dl_starting_up = 1;
483
a16956f3 484 if (*user_entry == (ElfW(Addr)) ENTRY_POINT)
0200214b
RM
485 {
486 /* Ho ho. We are not the program interpreter! We are the program
487 itself! This means someone ran ld.so as a command. Well, that
488 might be convenient to do sometimes. We support it by
489 interpreting the args like this:
490
491 ld.so PROGRAM ARGS...
492
493 The first argument is the name of a file containing an ELF
494 executable we will load and run with the following arguments.
495 To simplify life here, PROGRAM is searched for using the
496 normal rules for shared objects, rather than $PATH or anything
497 like that. We just load it and use its entry point; we don't
498 pay attention to its PT_INTERP command (we are the interpreter
499 ourselves). This is an easy way to test a new ld.so before
500 installing it. */
164a7164 501 rtld_is_main = true;
421f82e5 502
ffee1316 503 /* Note the place where the dynamic linker actually came from. */
d6b5d570 504 GL(dl_rtld_map).l_name = _dl_argv[0];
6a76c115 505
fd26970f
UD
506 while (_dl_argc > 1)
507 if (! strcmp (_dl_argv[1], "--list"))
508 {
509 mode = list;
5688da55 510 GL(dl_lazy) = -1; /* This means do no dependency analysis. */
61965e9b 511
fd26970f
UD
512 ++_dl_skip_args;
513 --_dl_argc;
514 ++_dl_argv;
515 }
516 else if (! strcmp (_dl_argv[1], "--verify"))
517 {
518 mode = verify;
6a76c115 519
fd26970f
UD
520 ++_dl_skip_args;
521 --_dl_argc;
522 ++_dl_argv;
523 }
310930c1 524 else if (! strcmp (_dl_argv[1], "--library-path") && _dl_argc > 2)
880f421f
UD
525 {
526 library_path = _dl_argv[2];
527
310930c1
UD
528 _dl_skip_args += 2;
529 _dl_argc -= 2;
530 _dl_argv += 2;
531 }
b0a01055 532 else if (! strcmp (_dl_argv[1], "--inhibit-rpath") && _dl_argc > 2)
310930c1 533 {
d6b5d570 534 GL(dl_inhibit_rpath) = _dl_argv[2];
310930c1 535
880f421f
UD
536 _dl_skip_args += 2;
537 _dl_argc -= 2;
538 _dl_argv += 2;
539 }
fd26970f
UD
540 else
541 break;
d66e34cd 542
61eb22d3
UD
543 /* If we have no further argument the program was called incorrectly.
544 Grant the user some education. */
545 if (_dl_argc < 2)
35fc382a 546 _dl_fatal_printf ("\
2bcf29ba 547Usage: ld.so [OPTION]... EXECUTABLE-FILE [ARGS-FOR-PROGRAM...]\n\
61eb22d3
UD
548You have invoked `ld.so', the helper program for shared library executables.\n\
549This program usually lives in the file `/lib/ld.so', and special directives\n\
550in executable files using ELF shared libraries tell the system's program\n\
551loader to load the helper program from this file. This helper program loads\n\
552the shared libraries needed by the program executable, prepares the program\n\
553to run, and runs it. You may invoke this helper program directly from the\n\
554command line to load and run an ELF executable file; this is like executing\n\
555that file itself, but always uses this helper program from the file you\n\
556specified, instead of the helper program file specified in the executable\n\
557file you run. This is mostly of use for maintainers to test new versions\n\
2bcf29ba
UD
558of this helper program; chances are you did not intend to run this program.\n\
559\n\
b0a01055
UD
560 --list list all dependencies and how they are resolved\n\
561 --verify verify that given object really is a dynamically linked\n\
e8b1163e 562 object we can handle\n\
b0a01055
UD
563 --library-path PATH use given PATH instead of content of the environment\n\
564 variable LD_LIBRARY_PATH\n\
fcf70d41 565 --inhibit-rpath LIST ignore RUNPATH and RPATH information in object names\n\
35fc382a 566 in LIST\n");
61eb22d3 567
0200214b
RM
568 ++_dl_skip_args;
569 --_dl_argc;
570 ++_dl_argv;
91f62ce6 571
da832465
UD
572 /* Initialize the data structures for the search paths for shared
573 objects. */
574 _dl_init_paths (library_path);
575
9a821cf9 576 if (__builtin_expect (mode, normal) == verify)
2de99474 577 {
8e17ea58
UD
578 const char *objname;
579 const char *err_str = NULL;
993b3242 580 struct map_args args;
2de99474 581
993b3242 582 args.str = _dl_argv[0];
cff26a3e 583 (void) INTUSE(_dl_catch_error) (&objname, &err_str, map_doit, &args);
8e17ea58 584 if (__builtin_expect (err_str != NULL, 0))
dcf0671d 585 {
ca3c0135
UD
586 if (err_str != _dl_out_of_memory)
587 free ((char *) err_str);
dcf0671d
UD
588 _exit (EXIT_FAILURE);
589 }
2de99474
UD
590 }
591 else
db276fa1
UD
592 {
593 HP_TIMING_NOW (start);
cff26a3e 594 INTUSE(_dl_map_object) (NULL, _dl_argv[0], 0, lt_library, 0, 0);
db276fa1 595 HP_TIMING_NOW (stop);
61e0617a 596
db276fa1
UD
597 HP_TIMING_DIFF (load_time, start, stop);
598 }
2de99474 599
d6b5d570
UD
600 phdr = GL(dl_loaded)->l_phdr;
601 phnum = GL(dl_loaded)->l_phnum;
143e2b96
UD
602 /* We overwrite here a pointer to a malloc()ed string. But since
603 the malloc() implementation used at this point is the dummy
604 implementations which has no real free() function it does not
605 makes sense to free the old string first. */
d6b5d570
UD
606 GL(dl_loaded)->l_name = (char *) "";
607 *user_entry = GL(dl_loaded)->l_entry;
0200214b
RM
608 }
609 else
610 {
611 /* Create a link_map for the executable itself.
612 This will be what dlopen on "" returns. */
87c812c2 613 _dl_new_object ((char *) "", "", lt_executable, NULL);
d6b5d570 614 if (GL(dl_loaded) == NULL)
35fc382a 615 _dl_fatal_printf ("cannot allocate memory for link map\n");
d6b5d570
UD
616 GL(dl_loaded)->l_phdr = phdr;
617 GL(dl_loaded)->l_phnum = phnum;
618 GL(dl_loaded)->l_entry = *user_entry;
da832465 619
61e0617a
UD
620 /* At this point we are in a bit of trouble. We would have to
621 fill in the values for l_dev and l_ino. But in general we
622 do not know where the file is. We also do not handle AT_EXECFD
623 even if it would be passed up.
624
625 We leave the values here defined to 0. This is normally no
626 problem as the program code itself is normally no shared
627 object and therefore cannot be loaded dynamically. Nothing
628 prevent the use of dynamic binaries and in these situations
629 we might get problems. We might not be able to find out
630 whether the object is already loaded. But since there is no
631 easy way out and because the dynamic binary must also not
632 have an SONAME we ignore this program for now. If it becomes
633 a problem we can force people using SONAMEs. */
634
97a51d8a
UD
635 /* We delay initializing the path structure until we got the dynamic
636 information for the program. */
0200214b
RM
637 }
638
d6b5d570 639 GL(dl_loaded)->l_map_end = 0;
052b6a6c 640 /* Perhaps the executable has no PT_LOAD header entries at all. */
d6b5d570 641 GL(dl_loaded)->l_map_start = ~0;
e7beef5f 642 /* We opened the file, account for it. */
d6b5d570 643 ++GL(dl_loaded)->l_opencount;
052b6a6c 644
0200214b 645 /* Scan the program header table for the dynamic section. */
72f70279 646 for (ph = phdr; ph < &phdr[phnum]; ++ph)
0200214b
RM
647 switch (ph->p_type)
648 {
da832465
UD
649 case PT_PHDR:
650 /* Find out the load address. */
d6b5d570 651 GL(dl_loaded)->l_addr = (ElfW(Addr)) phdr - ph->p_vaddr;
da832465 652 break;
0200214b
RM
653 case PT_DYNAMIC:
654 /* This tells us where to find the dynamic section,
655 which tells us everything we need to do. */
d6b5d570 656 GL(dl_loaded)->l_ld = (void *) GL(dl_loaded)->l_addr + ph->p_vaddr;
0200214b
RM
657 break;
658 case PT_INTERP:
659 /* This "interpreter segment" was used by the program loader to
660 find the program interpreter, which is this program itself, the
661 dynamic linker. We note what name finds us, so that a future
662 dlopen call or DT_NEEDED entry, for something that wants to link
663 against the dynamic linker as a shared library, will know that
664 the shared object is already loaded. */
d6b5d570 665 _dl_rtld_libname.name = ((const char *) GL(dl_loaded)->l_addr
be935610 666 + ph->p_vaddr);
752a2a50 667 /* _dl_rtld_libname.next = NULL; Already zero. */
d6b5d570 668 GL(dl_rtld_map).l_libname = &_dl_rtld_libname;
f41c8091
UD
669
670 /* Ordinarilly, we would get additional names for the loader from
671 our DT_SONAME. This can't happen if we were actually linked as
672 a static executable (detect this case when we have no DYNAMIC).
673 If so, assume the filename component of the interpreter path to
674 be our SONAME, and add it to our name list. */
d6b5d570 675 if (GL(dl_rtld_map).l_ld == NULL)
f41c8091 676 {
88794e30
UD
677 const char *p = NULL;
678 const char *cp = _dl_rtld_libname.name;
679
680 /* Find the filename part of the path. */
681 while (*cp != '\0')
682 if (*cp++ == '/')
683 p = cp;
684
685 if (p != NULL)
f41c8091 686 {
88794e30 687 _dl_rtld_libname2.name = p;
752a2a50 688 /* _dl_rtld_libname2.next = NULL; Already zero. */
f41c8091
UD
689 _dl_rtld_libname.next = &_dl_rtld_libname2;
690 }
691 }
692
164a7164 693 has_interp = true;
0200214b 694 break;
052b6a6c 695 case PT_LOAD:
052b6a6c
UD
696 {
697 ElfW(Addr) mapstart;
2373b30e
UD
698 ElfW(Addr) allocend;
699
700 /* Remember where the main program starts in memory. */
d6b5d570
UD
701 mapstart = (GL(dl_loaded)->l_addr
702 + (ph->p_vaddr & ~(ph->p_align - 1)));
703 if (GL(dl_loaded)->l_map_start > mapstart)
704 GL(dl_loaded)->l_map_start = mapstart;
2373b30e
UD
705
706 /* Also where it ends. */
d6b5d570
UD
707 allocend = GL(dl_loaded)->l_addr + ph->p_vaddr + ph->p_memsz;
708 if (GL(dl_loaded)->l_map_end < allocend)
709 GL(dl_loaded)->l_map_end = allocend;
052b6a6c
UD
710 }
711 break;
a2f1f5cb
UD
712#ifdef USE_TLS
713 case PT_TLS:
714 /* Note that in the case the dynamic linker we duplicate work
715 here since we read the PT_TLS entry already in
716 _dl_start_final. But the result is repeatable so do not
717 check for this special but unimportant case. */
718 GL(dl_loaded)->l_tls_blocksize = ph->p_memsz;
719 GL(dl_loaded)->l_tls_initimage_size = ph->p_filesz;
720 GL(dl_loaded)->l_tls_initimage = (void *) (GL(dl_loaded)->l_addr
721 + ph->p_offset);
722 /* This is the first element of the initialization image list.
723 It is created as a circular list so that we can easily
724 append to it. */
725 GL(dl_initimage_list) = GL(dl_loaded)->l_tls_nextimage = GL(dl_loaded);
726
727 /* This image get the ID one. */
728 GL(dl_tls_module_cnt) = GL(dl_loaded)->l_tls_modid = 1;
729 break;
730#endif
0200214b 731 }
d6b5d570
UD
732 if (! GL(dl_loaded)->l_map_end)
733 GL(dl_loaded)->l_map_end = ~0;
734 if (! GL(dl_rtld_map).l_libname && GL(dl_rtld_map).l_name)
c84142e8
UD
735 {
736 /* We were invoked directly, so the program might not have a
737 PT_INTERP. */
d6b5d570 738 _dl_rtld_libname.name = GL(dl_rtld_map).l_name;
752a2a50 739 /* _dl_rtld_libname.next = NULL; Alread zero. */
d6b5d570 740 GL(dl_rtld_map).l_libname = &_dl_rtld_libname;
c84142e8 741 }
ffee1316 742 else
d6b5d570 743 assert (GL(dl_rtld_map).l_libname); /* How else did we get here? */
0200214b 744
9a51759b
UD
745 if (! rtld_is_main)
746 {
747 /* Extract the contents of the dynamic section for easy access. */
d6b5d570
UD
748 elf_get_dynamic_info (GL(dl_loaded));
749 if (GL(dl_loaded)->l_info[DT_HASH])
9a51759b 750 /* Set up our cache of pointers into the hash table. */
d6b5d570 751 _dl_setup_hash (GL(dl_loaded));
9a51759b 752 }
0200214b 753
9a821cf9 754 if (__builtin_expect (mode, normal) == verify)
e2102c14
UD
755 {
756 /* We were called just to verify that this is a dynamic
757 executable using us as the program interpreter. Exit with an
758 error if we were not able to load the binary or no interpreter
759 is specified (i.e., this is no dynamically linked binary. */
d6b5d570 760 if (GL(dl_loaded)->l_ld == NULL)
e2102c14 761 _exit (1);
e2102c14
UD
762
763 /* We allow here some platform specific code. */
764#ifdef DISTINGUISH_LIB_VERSIONS
765 DISTINGUISH_LIB_VERSIONS;
766#endif
eb406346 767 _exit (has_interp ? 0 : 2);
e2102c14
UD
768 }
769
9a51759b 770 if (! rtld_is_main)
97a51d8a
UD
771 /* Initialize the data structures for the search paths for shared
772 objects. */
120b4c49 773 _dl_init_paths (library_path);
97a51d8a 774
0200214b 775 /* Put the link_map for ourselves on the chain so it can be found by
ceb2d9aa 776 name. Note that at this point the global chain of link maps contains
d6b5d570
UD
777 exactly one element, which is pointed to by dl_loaded. */
778 if (! GL(dl_rtld_map).l_name)
ffee1316
RM
779 /* If not invoked directly, the dynamic linker shared object file was
780 found by the PT_INTERP name. */
d6b5d570
UD
781 GL(dl_rtld_map).l_name = (char *) GL(dl_rtld_map).l_libname->name;
782 GL(dl_rtld_map).l_type = lt_library;
783 GL(dl_loaded)->l_next = &GL(dl_rtld_map);
784 GL(dl_rtld_map).l_prev = GL(dl_loaded);
785 ++GL(dl_nloaded);
0200214b 786
14bab8de 787 /* We have two ways to specify objects to preload: via environment
49c091e5 788 variable and via the file /etc/ld.so.preload. The latter can also
14bab8de 789 be used when security is enabled. */
2064087b
RM
790 preloads = NULL;
791 npreloads = 0;
14bab8de 792
db33f7d4 793 if (__builtin_expect (preloadlist != NULL, 0))
c4029823 794 {
566efee2
UD
795 /* The LD_PRELOAD environment variable gives list of libraries
796 separated by white space or colons that are loaded before the
fd26970f
UD
797 executable's dependencies and prepended to the global scope
798 list. If the binary is running setuid all elements
799 containing a '/' are ignored since it is insecure. */
800 char *list = strdupa (preloadlist);
801 char *p;
db276fa1
UD
802
803 HP_TIMING_NOW (start);
804
9710f75d
UD
805 /* Prevent optimizing strsep. Speed is not important here. */
806 while ((p = (strsep) (&list, " :")) != NULL)
e2102c14 807 if (p[0] != '\0'
db33f7d4
UD
808 && (__builtin_expect (! __libc_enable_secure, 1)
809 || strchr (p, '/') == NULL))
fd26970f 810 {
cff26a3e
AJ
811 struct link_map *new_map = INTUSE(_dl_map_object) (GL(dl_loaded), p,
812 1, lt_library,
813 0, 0);
42c4f32a 814 if (++new_map->l_opencount == 1)
bd355af0
UD
815 /* It is no duplicate. */
816 ++npreloads;
fd26970f 817 }
db276fa1
UD
818
819 HP_TIMING_NOW (stop);
820 HP_TIMING_DIFF (diff, start, stop);
821 HP_TIMING_ACCUM_NT (load_time, diff);
c4029823
UD
822 }
823
14bab8de
UD
824 /* Read the contents of the file. */
825 file = _dl_sysdep_read_whole_file ("/etc/ld.so.preload", &file_size,
826 PROT_READ | PROT_WRITE);
40b07f5b 827 if (__builtin_expect (file != MAP_FAILED, 0))
14bab8de
UD
828 {
829 /* Parse the file. It contains names of libraries to be loaded,
830 separated by white spaces or `:'. It may also contain
831 comments introduced by `#'. */
832 char *problem;
833 char *runp;
834 size_t rest;
835
836 /* Eliminate comments. */
837 runp = file;
838 rest = file_size;
839 while (rest > 0)
840 {
841 char *comment = memchr (runp, '#', rest);
842 if (comment == NULL)
843 break;
844
845 rest -= comment - runp;
846 do
847 *comment = ' ';
848 while (--rest > 0 && *++comment != '\n');
849 }
850
851 /* We have one problematic case: if we have a name at the end of
852 the file without a trailing terminating characters, we cannot
853 place the \0. Handle the case separately. */
49891c10
UD
854 if (file[file_size - 1] != ' ' && file[file_size - 1] != '\t'
855 && file[file_size - 1] != '\n' && file[file_size - 1] != ':')
14bab8de
UD
856 {
857 problem = &file[file_size];
858 while (problem > file && problem[-1] != ' ' && problem[-1] != '\t'
49891c10 859 && problem[-1] != '\n' && problem[-1] != ':')
14bab8de
UD
860 --problem;
861
862 if (problem > file)
863 problem[-1] = '\0';
864 }
865 else
49891c10
UD
866 {
867 problem = NULL;
868 file[file_size - 1] = '\0';
869 }
14bab8de 870
db276fa1
UD
871 HP_TIMING_NOW (start);
872
14bab8de
UD
873 if (file != problem)
874 {
875 char *p;
e2102c14 876 runp = file;
14bab8de 877 while ((p = strsep (&runp, ": \t\n")) != NULL)
e2102c14
UD
878 if (p[0] != '\0')
879 {
cff26a3e
AJ
880 struct link_map *new_map = INTUSE(_dl_map_object) (GL(dl_loaded),
881 p, 1,
882 lt_library,
883 0, 0);
42c4f32a 884 if (++new_map->l_opencount == 1)
e2102c14
UD
885 /* It is no duplicate. */
886 ++npreloads;
887 }
14bab8de
UD
888 }
889
890 if (problem != NULL)
891 {
892 char *p = strndupa (problem, file_size - (problem - file));
cff26a3e
AJ
893 struct link_map *new_map = INTUSE(_dl_map_object) (GL(dl_loaded), p, 1,
894 lt_library, 0, 0);
42c4f32a 895 if (++new_map->l_opencount == 1)
bd355af0
UD
896 /* It is no duplicate. */
897 ++npreloads;
14bab8de
UD
898 }
899
db276fa1
UD
900 HP_TIMING_NOW (stop);
901 HP_TIMING_DIFF (diff, start, stop);
902 HP_TIMING_ACCUM_NT (load_time, diff);
903
14bab8de
UD
904 /* We don't need the file anymore. */
905 __munmap (file, file_size);
906 }
907
db33f7d4 908 if (__builtin_expect (npreloads, 0) != 0)
14bab8de
UD
909 {
910 /* Set up PRELOADS with a vector of the preloaded libraries. */
911 struct link_map *l;
14bab8de 912 preloads = __alloca (npreloads * sizeof preloads[0]);
d6b5d570 913 l = GL(dl_rtld_map).l_next; /* End of the chain before preloads. */
14bab8de
UD
914 i = 0;
915 do
916 {
917 preloads[i++] = l;
918 l = l->l_next;
919 } while (l);
920 assert (i == npreloads);
921 }
922
2064087b
RM
923 /* Load all the libraries specified by DT_NEEDED entries. If LD_PRELOAD
924 specified some libraries to load, these are inserted before the actual
925 dependencies in the executable's searchlist for symbol resolution. */
db276fa1 926 HP_TIMING_NOW (start);
cff26a3e 927 INTUSE(_dl_map_object_deps) (GL(dl_loaded), preloads, npreloads, mode == trace);
db276fa1
UD
928 HP_TIMING_NOW (stop);
929 HP_TIMING_DIFF (diff, start, stop);
930 HP_TIMING_ACCUM_NT (load_time, diff);
e3e35cfc 931
42c4f32a
UD
932 /* Mark all objects as being in the global scope and set the open
933 counter. */
d6b5d570 934 for (i = GL(dl_loaded)->l_searchlist.r_nlist; i > 0; )
42c4f32a
UD
935 {
936 --i;
d6b5d570
UD
937 GL(dl_loaded)->l_searchlist.r_list[i]->l_global = 1;
938 ++GL(dl_loaded)->l_searchlist.r_list[i]->l_opencount;
42c4f32a 939 }
d66e34cd 940
2064087b 941#ifndef MAP_ANON
f332db02
RM
942 /* We are done mapping things, so close the zero-fill descriptor. */
943 __close (_dl_zerofd);
944 _dl_zerofd = -1;
2064087b 945#endif
f332db02 946
f9496a7b 947 /* Remove _dl_rtld_map from the chain. */
d6b5d570
UD
948 GL(dl_rtld_map).l_prev->l_next = GL(dl_rtld_map).l_next;
949 if (GL(dl_rtld_map).l_next)
950 GL(dl_rtld_map).l_next->l_prev = GL(dl_rtld_map).l_prev;
f9496a7b 951
d6b5d570 952 if (__builtin_expect (GL(dl_rtld_map).l_opencount > 1, 1))
0200214b 953 {
f9496a7b
RM
954 /* Some DT_NEEDED entry referred to the interpreter object itself, so
955 put it back in the list of visible objects. We insert it into the
956 chain in symbol search order because gdb uses the chain's order as
957 its symbol search order. */
77aba05b 958 i = 1;
d6b5d570 959 while (GL(dl_loaded)->l_searchlist.r_list[i] != &GL(dl_rtld_map))
f9496a7b 960 ++i;
d6b5d570 961 GL(dl_rtld_map).l_prev = GL(dl_loaded)->l_searchlist.r_list[i - 1];
b2bcd61a 962 if (__builtin_expect (mode, normal) == normal)
d6b5d570
UD
963 GL(dl_rtld_map).l_next = (i + 1 < GL(dl_loaded)->l_searchlist.r_nlist
964 ? GL(dl_loaded)->l_searchlist.r_list[i + 1]
965 : NULL);
b2bcd61a
UD
966 else
967 /* In trace mode there might be an invisible object (which we
968 could not find) after the previous one in the search list.
969 In this case it doesn't matter much where we put the
970 interpreter object, so we just initialize the list pointer so
971 that the assertion below holds. */
d6b5d570 972 GL(dl_rtld_map).l_next = GL(dl_rtld_map).l_prev->l_next;
b2bcd61a 973
d6b5d570
UD
974 assert (GL(dl_rtld_map).l_prev->l_next == GL(dl_rtld_map).l_next);
975 GL(dl_rtld_map).l_prev->l_next = &GL(dl_rtld_map);
976 if (GL(dl_rtld_map).l_next)
f9496a7b 977 {
d6b5d570
UD
978 assert (GL(dl_rtld_map).l_next->l_prev == GL(dl_rtld_map).l_prev);
979 GL(dl_rtld_map).l_next->l_prev = &GL(dl_rtld_map);
f9496a7b 980 }
0200214b 981 }
d66e34cd 982
c84142e8
UD
983 /* Now let us see whether all libraries are available in the
984 versions we need. */
985 {
993b3242
UD
986 struct version_check_args args;
987 args.doexit = mode == normal;
145b8413 988 args.dotrace = mode == trace;
993b3242 989 _dl_receive_error (print_missing_version, version_check_doit, &args);
c84142e8
UD
990 }
991
9a821cf9 992 if (__builtin_expect (mode, normal) != normal)
0200214b
RM
993 {
994 /* We were run just to list the shared libraries. It is
995 important that we do this before real relocation, because the
996 functions we call below for output may no longer work properly
997 after relocation. */
d6b5d570 998 if (! GL(dl_loaded)->l_info[DT_NEEDED])
35fc382a 999 _dl_printf ("\tstatically linked\n");
0200214b 1000 else
ceb2d9aa
UD
1001 {
1002 struct link_map *l;
1003
d6b5d570 1004 if (GL(dl_debug_mask) & DL_DEBUG_PRELINK)
32e6df36 1005 {
d6b5d570 1006 struct r_scope_elem *scope = &GL(dl_loaded)->l_searchlist;
32e6df36
UD
1007
1008 for (i = 0; i < scope->r_nlist; i++)
1009 {
1010 l = scope->r_list [i];
1011 if (l->l_faked)
1012 {
1013 _dl_printf ("\t%s => not found\n", l->l_libname->name);
1014 continue;
1015 }
d6b5d570
UD
1016 if (_dl_name_match_p (GL(dl_trace_prelink), l))
1017 GL(dl_trace_prelink_map) = l;
32e6df36
UD
1018 _dl_printf ("\t%s => %s (0x%0*Zx, 0x%0*Zx)\n",
1019 l->l_libname->name[0] ? l->l_libname->name
1020 : _dl_argv[0] ?: "<main program>",
1021 l->l_name[0] ? l->l_name
1022 : _dl_argv[0] ?: "<main program>",
1023 (int) sizeof l->l_map_start * 2,
1024 l->l_map_start,
1025 (int) sizeof l->l_addr * 2,
1026 l->l_addr);
1027 }
1028 }
1029 else
1030 {
d6b5d570 1031 for (l = GL(dl_loaded)->l_next; l; l = l->l_next)
32e6df36
UD
1032 if (l->l_faked)
1033 /* The library was not found. */
1034 _dl_printf ("\t%s => not found\n", l->l_libname->name);
1035 else
1036 _dl_printf ("\t%s => %s (0x%0*Zx)\n", l->l_libname->name,
1037 l->l_name, (int) sizeof l->l_map_start * 2,
1038 l->l_map_start);
1039 }
ceb2d9aa 1040 }
1a3a58fd 1041
9a821cf9 1042 if (__builtin_expect (mode, trace) != trace)
cddcfecf
RM
1043 for (i = 1; i < _dl_argc; ++i)
1044 {
1045 const ElfW(Sym) *ref = NULL;
c0282c06
UD
1046 ElfW(Addr) loadbase;
1047 lookup_t result;
c0282c06 1048
cff26a3e
AJ
1049 result = INTUSE(_dl_lookup_symbol) (_dl_argv[i], GL(dl_loaded),
1050 &ref, GL(dl_loaded)->l_scope,
1051 ELF_RTYPE_CLASS_PLT, 1);
c0282c06
UD
1052
1053 loadbase = LOOKUP_VALUE_ADDRESS (result);
1054
35fc382a 1055 _dl_printf ("%s found at 0x%0*Zd in object at 0x%0*Zd\n",
8a0746ae
RM
1056 _dl_argv[i],
1057 (int) sizeof ref->st_value * 2, ref->st_value,
1058 (int) sizeof loadbase * 2, loadbase);
cddcfecf 1059 }
ce37fa88 1060 else
fd26970f 1061 {
667b0577 1062 /* If LD_WARN is set warn about undefined symbols. */
5688da55 1063 if (GL(dl_lazy) >= 0 && GL(dl_verbose))
ce37fa88
UD
1064 {
1065 /* We have to do symbol dependency testing. */
1066 struct relocate_args args;
1067 struct link_map *l;
993b3242 1068
5688da55 1069 args.lazy = GL(dl_lazy);
fd26970f 1070
d6b5d570 1071 l = GL(dl_loaded);
ce37fa88
UD
1072 while (l->l_next)
1073 l = l->l_next;
1074 do
1075 {
d6b5d570 1076 if (l != &GL(dl_rtld_map) && ! l->l_faked)
ce37fa88
UD
1077 {
1078 args.l = l;
1079 _dl_receive_error (print_unresolved, relocate_doit,
1080 &args);
ce37fa88
UD
1081 }
1082 l = l->l_prev;
1083 } while (l);
32e6df36 1084
d6b5d570
UD
1085 if ((GL(dl_debug_mask) & DL_DEBUG_PRELINK)
1086 && GL(dl_rtld_map).l_opencount > 1)
cff26a3e
AJ
1087 INTUSE(_dl_relocate_object) (&GL(dl_rtld_map),
1088 GL(dl_loaded)->l_scope, 0, 0);
ce37fa88
UD
1089 }
1090
b0982c4a 1091#define VERNEEDTAG (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGIDX (DT_VERNEED))
120b4c49 1092 if (version_info)
fd26970f 1093 {
ce37fa88
UD
1094 /* Print more information. This means here, print information
1095 about the versions needed. */
1096 int first = 1;
d6b5d570 1097 struct link_map *map = GL(dl_loaded);
ce37fa88 1098
d6b5d570 1099 for (map = GL(dl_loaded); map != NULL; map = map->l_next)
fd26970f 1100 {
f41c8091 1101 const char *strtab;
ce37fa88 1102 ElfW(Dyn) *dyn = map->l_info[VERNEEDTAG];
f41c8091
UD
1103 ElfW(Verneed) *ent;
1104
1105 if (dyn == NULL)
1106 continue;
1107
a42195db 1108 strtab = (const void *) D_PTR (map, l_info[DT_STRTAB]);
f41c8091 1109 ent = (ElfW(Verneed) *) (map->l_addr + dyn->d_un.d_ptr);
ce37fa88 1110
f41c8091 1111 if (first)
ce37fa88 1112 {
35fc382a 1113 _dl_printf ("\n\tVersion information:\n");
f41c8091
UD
1114 first = 0;
1115 }
ce37fa88 1116
35fc382a
UD
1117 _dl_printf ("\t%s:\n",
1118 map->l_name[0] ? map->l_name : _dl_argv[0]);
f41c8091
UD
1119
1120 while (1)
1121 {
1122 ElfW(Vernaux) *aux;
1123 struct link_map *needed;
ce37fa88 1124
f41c8091
UD
1125 needed = find_needed (strtab + ent->vn_file);
1126 aux = (ElfW(Vernaux) *) ((char *) ent + ent->vn_aux);
ce37fa88
UD
1127
1128 while (1)
1129 {
f41c8091
UD
1130 const char *fname = NULL;
1131
f41c8091 1132 if (needed != NULL
ba9fcb3f
UD
1133 && match_version (strtab + aux->vna_name,
1134 needed))
f41c8091
UD
1135 fname = needed->l_name;
1136
35fc382a
UD
1137 _dl_printf ("\t\t%s (%s) %s=> %s\n",
1138 strtab + ent->vn_file,
1139 strtab + aux->vna_name,
1140 aux->vna_flags & VER_FLG_WEAK
1141 ? "[WEAK] " : "",
1142 fname ?: "not found");
ce37fa88 1143
f41c8091
UD
1144 if (aux->vna_next == 0)
1145 /* No more symbols. */
ce37fa88
UD
1146 break;
1147
f41c8091
UD
1148 /* Next symbol. */
1149 aux = (ElfW(Vernaux) *) ((char *) aux
1150 + aux->vna_next);
ce37fa88 1151 }
f41c8091
UD
1152
1153 if (ent->vn_next == 0)
1154 /* No more dependencies. */
1155 break;
1156
1157 /* Next dependency. */
1158 ent = (ElfW(Verneed) *) ((char *) ent + ent->vn_next);
ce37fa88 1159 }
fd26970f 1160 }
ce37fa88 1161 }
fd26970f 1162 }
d66e34cd 1163
0200214b
RM
1164 _exit (0);
1165 }
86d2c878 1166
d6b5d570
UD
1167 if (GL(dl_loaded)->l_info [ADDRIDX (DT_GNU_LIBLIST)]
1168 && ! __builtin_expect (GL(dl_profile) != NULL, 0))
32e6df36
UD
1169 {
1170 ElfW(Lib) *liblist, *liblistend;
1171 struct link_map **r_list, **r_listend, *l;
9710f75d
UD
1172 const char *strtab = (const void *) D_PTR (GL(dl_loaded),
1173 l_info[DT_STRTAB]);
32e6df36 1174
d6b5d570 1175 assert (GL(dl_loaded)->l_info [VALIDX (DT_GNU_LIBLISTSZ)] != NULL);
32e6df36 1176 liblist = (ElfW(Lib) *)
d6b5d570 1177 GL(dl_loaded)->l_info [ADDRIDX (DT_GNU_LIBLIST)]->d_un.d_ptr;
32e6df36
UD
1178 liblistend = (ElfW(Lib) *)
1179 ((char *) liblist
d6b5d570
UD
1180 + GL(dl_loaded)->l_info [VALIDX (DT_GNU_LIBLISTSZ)]->d_un.d_val);
1181 r_list = GL(dl_loaded)->l_searchlist.r_list;
1182 r_listend = r_list + GL(dl_loaded)->l_searchlist.r_nlist;
32e6df36
UD
1183
1184 for (; r_list < r_listend && liblist < liblistend; r_list++)
1185 {
1186 l = *r_list;
1187
d6b5d570 1188 if (l == GL(dl_loaded))
32e6df36
UD
1189 continue;
1190
1191 /* If the library is not mapped where it should, fail. */
1192 if (l->l_addr)
1193 break;
1194
1195 /* Next, check if checksum matches. */
1196 if (l->l_info [VALIDX(DT_CHECKSUM)] == NULL
1197 || l->l_info [VALIDX(DT_CHECKSUM)]->d_un.d_val
1198 != liblist->l_checksum)
1199 break;
1200
1201 if (l->l_info [VALIDX(DT_GNU_PRELINKED)] == NULL
1202 || l->l_info [VALIDX(DT_GNU_PRELINKED)]->d_un.d_val
1203 != liblist->l_time_stamp)
1204 break;
1205
1206 if (! _dl_name_match_p (strtab + liblist->l_name, l))
1207 break;
1208
1209 ++liblist;
1210 }
1211
1212
1213 if (r_list == r_listend && liblist == liblistend)
164a7164 1214 prelinked = true;
32e6df36 1215
d6b5d570 1216 if (__builtin_expect (GL(dl_debug_mask) & DL_DEBUG_LIBS, 0))
32e6df36
UD
1217 _dl_printf ("\nprelink checking: %s\n", prelinked ? "ok" : "failed");
1218 }
1219
1220 if (prelinked)
1221 {
d6b5d570 1222 if (GL(dl_loaded)->l_info [ADDRIDX (DT_GNU_CONFLICT)] != NULL)
32e6df36
UD
1223 {
1224 ElfW(Rela) *conflict, *conflictend;
1225#ifndef HP_TIMING_NONAVAIL
1226 hp_timing_t start;
1227 hp_timing_t stop;
1228#endif
1229
1230 HP_TIMING_NOW (start);
d6b5d570 1231 assert (GL(dl_loaded)->l_info [VALIDX (DT_GNU_CONFLICTSZ)] != NULL);
32e6df36 1232 conflict = (ElfW(Rela) *)
d6b5d570 1233 GL(dl_loaded)->l_info [ADDRIDX (DT_GNU_CONFLICT)]->d_un.d_ptr;
32e6df36
UD
1234 conflictend = (ElfW(Rela) *)
1235 ((char *) conflict
d6b5d570
UD
1236 + GL(dl_loaded)->l_info [VALIDX (DT_GNU_CONFLICTSZ)]->d_un.d_val);
1237 _dl_resolve_conflicts (GL(dl_loaded), conflict, conflictend);
32e6df36
UD
1238 HP_TIMING_NOW (stop);
1239 HP_TIMING_DIFF (relocate_time, start, stop);
1240 }
1241
1242 _dl_sysdep_start_cleanup ();
1243 }
1244 else
164a7164
UD
1245 {
1246 /* Now we have all the objects loaded. Relocate them all except for
1247 the dynamic linker itself. We do this in reverse order so that copy
1248 relocs of earlier objects overwrite the data written by later
1249 objects. We do not re-relocate the dynamic linker itself in this
1250 loop because that could result in the GOT entries for functions we
1251 call being changed, and that would break us. It is safe to relocate
1252 the dynamic linker out of order because it has no copy relocs (we
1253 know that because it is self-contained). */
1254
1255 struct link_map *l;
1256 int consider_profiling = GL(dl_profile) != NULL;
8b07d6a8 1257#ifndef HP_TIMING_NONAVAIL
164a7164
UD
1258 hp_timing_t start;
1259 hp_timing_t stop;
1260 hp_timing_t add;
8b07d6a8 1261#endif
c0fb8a56 1262
164a7164
UD
1263 /* If we are profiling we also must do lazy reloaction. */
1264 GL(dl_lazy) |= consider_profiling;
c0fb8a56 1265
164a7164
UD
1266 l = GL(dl_loaded);
1267 while (l->l_next)
1268 l = l->l_next;
db276fa1 1269
164a7164
UD
1270 HP_TIMING_NOW (start);
1271 do
1272 {
1273 /* While we are at it, help the memory handling a bit. We have to
1274 mark some data structures as allocated with the fake malloc()
1275 implementation in ld.so. */
1276 struct libname_list *lnp = l->l_libname->next;
752a2a50 1277
164a7164
UD
1278 while (__builtin_expect (lnp != NULL, 0))
1279 {
1280 lnp->dont_free = 1;
1281 lnp = lnp->next;
1282 }
752a2a50 1283
164a7164 1284 if (l != &GL(dl_rtld_map))
cff26a3e
AJ
1285 INTUSE(_dl_relocate_object) (l, l->l_scope, GL(dl_lazy),
1286 consider_profiling);
be935610 1287
164a7164
UD
1288 l = l->l_prev;
1289 }
1290 while (l);
1291 HP_TIMING_NOW (stop);
1292
1293 HP_TIMING_DIFF (relocate_time, start, stop);
1294
1295 /* Do any necessary cleanups for the startup OS interface code.
1296 We do these now so that no calls are made after rtld re-relocation
1297 which might be resolved to different functions than we expect.
1298 We cannot do this before relocating the other objects because
1299 _dl_relocate_object might need to call `mprotect' for DT_TEXTREL. */
1300 _dl_sysdep_start_cleanup ();
1301
1302 /* Now enable profiling if needed. Like the previous call,
1303 this has to go here because the calls it makes should use the
1304 rtld versions of the functions (particularly calloc()), but it
1305 needs to have _dl_profile_map set up by the relocator. */
1306 if (__builtin_expect (GL(dl_profile_map) != NULL, 0))
1307 /* We must prepare the profiling. */
cff26a3e 1308 INTUSE(_dl_start_profile) (GL(dl_profile_map), GL(dl_profile_output));
164a7164
UD
1309
1310 if (GL(dl_rtld_map).l_opencount > 1)
1311 {
1312 /* There was an explicit ref to the dynamic linker as a shared lib.
1313 Re-relocate ourselves with user-controlled symbol definitions. */
1314 HP_TIMING_NOW (start);
cff26a3e
AJ
1315 INTUSE(_dl_relocate_object) (&GL(dl_rtld_map), GL(dl_loaded)->l_scope,
1316 0, 0);
164a7164
UD
1317 HP_TIMING_NOW (stop);
1318 HP_TIMING_DIFF (add, start, stop);
1319 HP_TIMING_ACCUM_NT (relocate_time, add);
1320 }
1321 }
ac16e905 1322
be935610 1323 /* Now set up the variable which helps the assembler startup code. */
d6b5d570
UD
1324 GL(dl_main_searchlist) = &GL(dl_loaded)->l_searchlist;
1325 GL(dl_global_scope)[0] = &GL(dl_loaded)->l_searchlist;
be935610 1326
32e6df36 1327 /* Save the information about the original global scope list since
604510f7 1328 we need it in the memory handling later. */
d6b5d570 1329 GL(dl_initial_searchlist) = *GL(dl_main_searchlist);
604510f7 1330
4d6acc61
RM
1331 {
1332 /* Initialize _r_debug. */
d6b5d570 1333 struct r_debug *r = _dl_debug_initialize (GL(dl_rtld_map).l_addr);
ceb2d9aa 1334 struct link_map *l;
4d6acc61 1335
d6b5d570 1336 l = GL(dl_loaded);
ec42724d
RM
1337
1338#ifdef ELF_MACHINE_DEBUG_SETUP
1339
1340 /* Some machines (e.g. MIPS) don't use DT_DEBUG in this way. */
1341
1342 ELF_MACHINE_DEBUG_SETUP (l, r);
d6b5d570 1343 ELF_MACHINE_DEBUG_SETUP (&GL(dl_rtld_map), r);
ec42724d
RM
1344
1345#else
1346
4d6acc61
RM
1347 if (l->l_info[DT_DEBUG])
1348 /* There is a DT_DEBUG entry in the dynamic section. Fill it in
1349 with the run-time address of the r_debug structure */
1350 l->l_info[DT_DEBUG]->d_un.d_ptr = (ElfW(Addr)) r;
1351
d746b89c
RM
1352 /* Fill in the pointer in the dynamic linker's own dynamic section, in
1353 case you run gdb on the dynamic linker directly. */
d6b5d570
UD
1354 if (GL(dl_rtld_map).l_info[DT_DEBUG])
1355 GL(dl_rtld_map).l_info[DT_DEBUG]->d_un.d_ptr = (ElfW(Addr)) r;
d746b89c 1356
ec42724d
RM
1357#endif
1358
4d6acc61
RM
1359 /* Notify the debugger that all objects are now mapped in. */
1360 r->r_state = RT_ADD;
cff26a3e 1361 INTUSE(_dl_debug_state) ();
4d6acc61 1362 }
0200214b 1363
08cac4ac
UD
1364#ifndef MAP_COPY
1365 /* We must munmap() the cache file. */
cff26a3e 1366 INTUSE(_dl_unload_cache) ();
08cac4ac
UD
1367#endif
1368
d66e34cd
RM
1369 /* Once we return, _dl_sysdep_start will invoke
1370 the DT_INIT functions and then *USER_ENTRY. */
1371}
fd26970f
UD
1372\f
1373/* This is a little helper function for resolving symbols while
1374 tracing the binary. */
1375static void
c84142e8
UD
1376print_unresolved (int errcode __attribute__ ((unused)), const char *objname,
1377 const char *errstring)
fd26970f 1378{
3996f34b
UD
1379 if (objname[0] == '\0')
1380 objname = _dl_argv[0] ?: "<main program>";
35fc382a 1381 _dl_error_printf ("%s (%s)\n", errstring, objname);
fd26970f 1382}
c84142e8
UD
1383\f
1384/* This is a little helper function for resolving symbols while
1385 tracing the binary. */
1386static void
1387print_missing_version (int errcode __attribute__ ((unused)),
1388 const char *objname, const char *errstring)
1389{
35fc382a
UD
1390 _dl_error_printf ("%s: %s: %s\n", _dl_argv[0] ?: "<program name unknown>",
1391 objname, errstring);
c84142e8 1392}
ea278354 1393\f
7dea968e
UD
1394/* Nonzero if any of the debugging options is enabled. */
1395static int any_debug;
1396
b5efde2f
UD
1397/* Process the string given as the parameter which explains which debugging
1398 options are enabled. */
1399static void
14c44e2e 1400process_dl_debug (const char *dl_debug)
b5efde2f 1401{
3e2040c8
UD
1402 /* When adding new entries make sure that the maximal length of a name
1403 is correctly handled in the LD_DEBUG_HELP code below. */
1404 static const struct
1405 {
379d4ec4
UD
1406 unsigned char len;
1407 const char name[10];
3e2040c8
UD
1408 const char helptext[41];
1409 unsigned short int mask;
1410 } debopts[] =
1411 {
379d4ec4
UD
1412#define LEN_AND_STR(str) sizeof (str) - 1, str
1413 { LEN_AND_STR ("libs"), "display library search paths",
3e2040c8 1414 DL_DEBUG_LIBS | DL_DEBUG_IMPCALLS },
379d4ec4 1415 { LEN_AND_STR ("reloc"), "display relocation processing",
3e2040c8 1416 DL_DEBUG_RELOC | DL_DEBUG_IMPCALLS },
379d4ec4 1417 { LEN_AND_STR ("files"), "display progress for input file",
3e2040c8 1418 DL_DEBUG_FILES | DL_DEBUG_IMPCALLS },
379d4ec4 1419 { LEN_AND_STR ("symbols"), "display symbol table processing",
3e2040c8 1420 DL_DEBUG_SYMBOLS | DL_DEBUG_IMPCALLS },
379d4ec4 1421 { LEN_AND_STR ("bindings"), "display information about symbol binding",
3e2040c8 1422 DL_DEBUG_BINDINGS | DL_DEBUG_IMPCALLS },
379d4ec4 1423 { LEN_AND_STR ("versions"), "display version dependencies",
3e2040c8 1424 DL_DEBUG_VERSIONS | DL_DEBUG_IMPCALLS },
379d4ec4 1425 { LEN_AND_STR ("all"), "all previous options combined",
3e2040c8
UD
1426 DL_DEBUG_LIBS | DL_DEBUG_RELOC | DL_DEBUG_FILES | DL_DEBUG_SYMBOLS
1427 | DL_DEBUG_BINDINGS | DL_DEBUG_VERSIONS | DL_DEBUG_IMPCALLS },
379d4ec4 1428 { LEN_AND_STR ("statistics"), "display relocation statistics",
3e2040c8 1429 DL_DEBUG_STATISTICS },
379d4ec4 1430 { LEN_AND_STR ("help"), "display this help message and exit",
3e2040c8
UD
1431 DL_DEBUG_HELP },
1432 };
1433#define ndebopts (sizeof (debopts) / sizeof (debopts[0]))
3e2040c8 1434
379d4ec4
UD
1435 /* Skip separating white spaces and commas. */
1436 while (*dl_debug != '\0')
b5efde2f 1437 {
379d4ec4 1438 if (*dl_debug != ' ' && *dl_debug != ',' && *dl_debug != ':')
b5efde2f 1439 {
3e2040c8 1440 size_t cnt;
379d4ec4 1441 size_t len = 1;
77aba05b 1442
379d4ec4
UD
1443 while (dl_debug[len] != '\0' && dl_debug[len] != ' '
1444 && dl_debug[len] != ',' && dl_debug[len] != ':')
1445 ++len;
14c44e2e 1446
3e2040c8 1447 for (cnt = 0; cnt < ndebopts; ++cnt)
379d4ec4
UD
1448 if (debopts[cnt].len == len
1449 && memcmp (dl_debug, debopts[cnt].name, len) == 0)
3e2040c8 1450 {
d6b5d570 1451 GL(dl_debug_mask) |= debopts[cnt].mask;
5688da55 1452 any_debug = 1;
3e2040c8
UD
1453 break;
1454 }
77aba05b 1455
3e2040c8
UD
1456 if (cnt == ndebopts)
1457 {
1458 /* Display a warning and skip everything until next
1459 separator. */
1460 char *copy = strndupa (dl_debug, len);
1461 _dl_error_printf ("\
1462warning: debug option `%s' unknown; try LD_DEBUG=help\n", copy);
379d4ec4
UD
1463 }
1464
1465 dl_debug += len;
1466 continue;
3e2040c8 1467 }
379d4ec4
UD
1468
1469 ++dl_debug;
3e2040c8 1470 }
77aba05b 1471
d6b5d570 1472 if (GL(dl_debug_mask) & DL_DEBUG_HELP)
3e2040c8
UD
1473 {
1474 size_t cnt;
14c44e2e 1475
3e2040c8
UD
1476 _dl_printf ("\
1477Valid options for the LD_DEBUG environment variable are:\n\n");
db276fa1 1478
3e2040c8 1479 for (cnt = 0; cnt < ndebopts; ++cnt)
37d8b778
UD
1480 _dl_printf (" %.*s%s%s\n", debopts[cnt].len, debopts[cnt].name,
1481 " " + debopts[cnt].len - 3,
3e2040c8 1482 debopts[cnt].helptext);
14c44e2e 1483
3e2040c8
UD
1484 _dl_printf ("\n\
1485To direct the debugging output into a file instead of standard output\n\
1486a filename can be specified using the LD_DEBUG_OUTPUT environment variable.\n");
1487 _exit (0);
b5efde2f 1488 }
b5efde2f
UD
1489}
1490\f
ea278354
UD
1491/* Process all environments variables the dynamic linker must recognize.
1492 Since all of them start with `LD_' we are a bit smarter while finding
1493 all the entries. */
67c94753
UD
1494extern char **_environ;
1495
d6b5d570 1496
ea278354 1497static void
ba9fcb3f 1498process_envvars (enum mode *modep)
ea278354 1499{
67c94753 1500 char **runp = _environ;
ea278354
UD
1501 char *envline;
1502 enum mode mode = normal;
7dea968e 1503 char *debug_output = NULL;
ea278354
UD
1504
1505 /* This is the default place for profiling data file. */
d6b5d570
UD
1506 GL(dl_profile_output) = &"/var/tmp\0/var/profile"[__libc_enable_secure
1507 ? 9 : 0];
ea278354
UD
1508
1509 while ((envline = _dl_next_ld_env_entry (&runp)) != NULL)
1510 {
379d4ec4
UD
1511 size_t len = 0;
1512
1513 while (envline[len] != '\0' && envline[len] != '=')
1514 ++len;
ea278354 1515
75e8d1f5
UD
1516 if (envline[len] != '=')
1517 /* This is a "LD_" variable at the end of the string without
1518 a '=' character. Ignore it since otherwise we will access
1519 invalid memory below. */
67c94753 1520 continue;
75e8d1f5 1521
67c94753 1522 switch (len)
ea278354 1523 {
14c44e2e
UD
1524 case 4:
1525 /* Warning level, verbose or not. */
67c94753 1526 if (memcmp (envline, "WARN", 4) == 0)
d6b5d570 1527 GL(dl_verbose) = envline[5] != '\0';
14c44e2e 1528 break;
ea278354 1529
14c44e2e
UD
1530 case 5:
1531 /* Debugging of the dynamic linker? */
67c94753
UD
1532 if (memcmp (envline, "DEBUG", 5) == 0)
1533 process_dl_debug (&envline[6]);
14c44e2e 1534 break;
b5efde2f 1535
14c44e2e
UD
1536 case 7:
1537 /* Print information about versions. */
67c94753 1538 if (memcmp (envline, "VERBOSE", 7) == 0)
14c44e2e 1539 {
67c94753 1540 version_info = envline[8] != '\0';
14c44e2e
UD
1541 break;
1542 }
7dea968e 1543
14c44e2e 1544 /* List of objects to be preloaded. */
67c94753 1545 if (memcmp (envline, "PRELOAD", 7) == 0)
14c44e2e 1546 {
67c94753 1547 preloadlist = &envline[8];
14c44e2e
UD
1548 break;
1549 }
120b4c49 1550
14c44e2e 1551 /* Which shared object shall be profiled. */
c95f3fd4 1552 if (memcmp (envline, "PROFILE", 7) == 0 && envline[8] != '\0')
d6b5d570 1553 GL(dl_profile) = &envline[8];
14c44e2e 1554 break;
120b4c49 1555
14c44e2e
UD
1556 case 8:
1557 /* Do we bind early? */
67c94753 1558 if (memcmp (envline, "BIND_NOW", 8) == 0)
f53c03c2 1559 {
5688da55 1560 GL(dl_lazy) = envline[9] == '\0';
f53c03c2
UD
1561 break;
1562 }
67c94753 1563 if (memcmp (envline, "BIND_NOT", 8) == 0)
d6b5d570 1564 GL(dl_bind_not) = envline[9] != '\0';
14c44e2e 1565 break;
ea278354 1566
14c44e2e
UD
1567 case 9:
1568 /* Test whether we want to see the content of the auxiliary
1569 array passed up from the kernel. */
67c94753 1570 if (memcmp (envline, "SHOW_AUXV", 9) == 0)
14c44e2e
UD
1571 _dl_show_auxv ();
1572 break;
ea278354 1573
12264bd7 1574 case 10:
3081378b 1575 /* Mask for the important hardware capabilities. */
67c94753 1576 if (memcmp (envline, "HWCAP_MASK", 10) == 0)
d6b5d570 1577 GL(dl_hwcap_mask) = __strtoul_internal (&envline[11], NULL, 0, 0);
12264bd7
UD
1578 break;
1579
f787edde
UD
1580 case 11:
1581 /* Path where the binary is found. */
45769315 1582 if (!__libc_enable_secure
67c94753 1583 && memcmp (envline, "ORIGIN_PATH", 11) == 0)
d6b5d570 1584 GL(dl_origin_path) = &envline[12];
f787edde
UD
1585 break;
1586
14c44e2e 1587 case 12:
dec126b4 1588 /* The library search path. */
67c94753 1589 if (memcmp (envline, "LIBRARY_PATH", 12) == 0)
dec126b4 1590 {
67c94753 1591 library_path = &envline[13];
dec126b4
UD
1592 break;
1593 }
1594
14c44e2e 1595 /* Where to place the profiling data file. */
67c94753 1596 if (memcmp (envline, "DEBUG_OUTPUT", 12) == 0)
14c44e2e 1597 {
67c94753 1598 debug_output = &envline[13];
14c44e2e
UD
1599 break;
1600 }
ea278354 1601
67c94753 1602 if (memcmp (envline, "DYNAMIC_WEAK", 12) == 0)
5688da55 1603 GL(dl_dynamic_weak) = 1;
14c44e2e 1604 break;
ea278354 1605
14c44e2e
UD
1606 case 14:
1607 /* Where to place the profiling data file. */
3081378b 1608 if (!__libc_enable_secure
3e2040c8
UD
1609 && memcmp (envline, "PROFILE_OUTPUT", 14) == 0
1610 && envline[15] != '\0')
d6b5d570 1611 GL(dl_profile_output) = &envline[15];
14c44e2e 1612 break;
120b4c49 1613
32e6df36
UD
1614 case 16:
1615 /* The mode of the dynamic linker can be set. */
1616 if (memcmp (envline, "TRACE_PRELINKING", 16) == 0)
1617 {
1618 mode = trace;
d6b5d570
UD
1619 GL(dl_verbose) = 1;
1620 GL(dl_debug_mask) |= DL_DEBUG_PRELINK;
1621 GL(dl_trace_prelink) = &envline[17];
32e6df36
UD
1622 }
1623 break;
1624
14c44e2e
UD
1625 case 20:
1626 /* The mode of the dynamic linker can be set. */
67c94753 1627 if (memcmp (envline, "TRACE_LOADED_OBJECTS", 20) == 0)
14c44e2e
UD
1628 mode = trace;
1629 break;
e2102c14
UD
1630
1631 /* We might have some extra environment variable to handle. This
1632 is tricky due to the pre-processing of the length of the name
1633 in the switch statement here. The code here assumes that added
1634 environment variables have a different length. */
1635#ifdef EXTRA_LD_ENVVARS
1636 EXTRA_LD_ENVVARS
1637#endif
ea278354
UD
1638 }
1639 }
1640
3e2040c8
UD
1641 /* The caller wants this information. */
1642 *modep = mode;
1643
4bae5567
UD
1644 /* Extra security for SUID binaries. Remove all dangerous environment
1645 variables. */
ba9fcb3f 1646 if (__builtin_expect (__libc_enable_secure, 0))
4bae5567 1647 {
c95f3fd4 1648 static const char unsecure_envvars[] =
4bae5567
UD
1649#ifdef EXTRA_UNSECURE_ENVVARS
1650 EXTRA_UNSECURE_ENVVARS
1651#endif
c95f3fd4
UD
1652 UNSECURE_ENVVARS;
1653 const char *nextp;
1654
1655 nextp = unsecure_envvars;
1656 do
1657 {
1658 unsetenv (nextp);
9710f75d
UD
1659 /* We could use rawmemchr but this need not be fast. */
1660 nextp = (char *) (strchr) (nextp, '\0') + 1;
c95f3fd4
UD
1661 }
1662 while (*nextp != '\0');
74955460
UD
1663
1664 if (__access ("/etc/suid-debug", F_OK) != 0)
1665 unsetenv ("MALLOC_CHECK_");
4bae5567 1666 }
7dea968e
UD
1667 /* If we have to run the dynamic linker in debugging mode and the
1668 LD_DEBUG_OUTPUT environment variable is given, we write the debug
1669 messages to this file. */
3e2040c8 1670 else if (any_debug && debug_output != NULL)
7dea968e 1671 {
5f2de337
UD
1672#ifdef O_NOFOLLOW
1673 const int flags = O_WRONLY | O_APPEND | O_CREAT | O_NOFOLLOW;
1674#else
1675 const int flags = O_WRONLY | O_APPEND | O_CREAT;
1676#endif
7a2fd787
UD
1677 size_t name_len = strlen (debug_output);
1678 char buf[name_len + 12];
1679 char *startp;
1680
1681 buf[name_len + 11] = '\0';
9710f75d 1682 startp = _itoa (__getpid (), &buf[name_len + 11], 10, 0);
7a2fd787
UD
1683 *--startp = '.';
1684 startp = memcpy (startp - name_len, debug_output, name_len);
1685
5688da55
UD
1686 GL(dl_debug_fd) = __open (startp, flags, DEFFILEMODE);
1687 if (GL(dl_debug_fd) == -1)
7dea968e 1688 /* We use standard output if opening the file failed. */
5688da55 1689 GL(dl_debug_fd) = STDOUT_FILENO;
7dea968e 1690 }
ea278354 1691}
db276fa1
UD
1692
1693
1694/* Print the various times we collected. */
1695static void
1696print_statistics (void)
1697{
8b07d6a8 1698#ifndef HP_TIMING_NONAVAIL
f457369d 1699 char buf[200];
db276fa1
UD
1700 char *cp;
1701 char *wp;
1702
1703 /* Total time rtld used. */
1704 if (HP_TIMING_AVAIL)
1705 {
1706 HP_TIMING_PRINT (buf, sizeof (buf), rtld_total_time);
cff26a3e
AJ
1707 INTUSE(_dl_debug_printf) ("\nruntime linker statistics:\n"
1708 " total startup time in dynamic loader: %s\n",
1709 buf);
db276fa1
UD
1710 }
1711
1712 /* Print relocation statistics. */
1713 if (HP_TIMING_AVAIL)
1714 {
35fc382a 1715 char pbuf[30];
db276fa1 1716 HP_TIMING_PRINT (buf, sizeof (buf), relocate_time);
9710f75d
UD
1717 cp = _itoa ((1000ULL * relocate_time) / rtld_total_time,
1718 pbuf + sizeof (pbuf), 10, 0);
35fc382a
UD
1719 wp = pbuf;
1720 switch (pbuf + sizeof (pbuf) - cp)
db276fa1
UD
1721 {
1722 case 3:
1723 *wp++ = *cp++;
1724 case 2:
1725 *wp++ = *cp++;
1726 case 1:
1727 *wp++ = '.';
1728 *wp++ = *cp++;
1729 }
1730 *wp = '\0';
cff26a3e 1731 INTUSE(_dl_debug_printf) ("\
7969407a 1732 time needed for relocation: %s (%s%%)\n",
cff26a3e 1733 buf, pbuf);
db276fa1 1734 }
1531e094 1735#endif
cff26a3e
AJ
1736 INTUSE(_dl_debug_printf) (" number of relocations: %lu\n",
1737 GL(dl_num_relocations));
1738 INTUSE(_dl_debug_printf) (" number of relocations from cache: %lu\n",
1739 GL(dl_num_cache_relocations));
db276fa1 1740
1531e094 1741#ifndef HP_TIMING_NONAVAIL
db276fa1
UD
1742 /* Time spend while loading the object and the dependencies. */
1743 if (HP_TIMING_AVAIL)
1744 {
35fc382a 1745 char pbuf[30];
db276fa1 1746 HP_TIMING_PRINT (buf, sizeof (buf), load_time);
9710f75d
UD
1747 cp = _itoa ((1000ULL * load_time) / rtld_total_time,
1748 pbuf + sizeof (pbuf), 10, 0);
35fc382a
UD
1749 wp = pbuf;
1750 switch (pbuf + sizeof (pbuf) - cp)
db276fa1
UD
1751 {
1752 case 3:
1753 *wp++ = *cp++;
1754 case 2:
1755 *wp++ = *cp++;
1756 case 1:
1757 *wp++ = '.';
1758 *wp++ = *cp++;
1759 }
1760 *wp = '\0';
cff26a3e 1761 INTUSE(_dl_debug_printf) ("\
7969407a 1762 time needed to load objects: %s (%s%%)\n",
cff26a3e 1763 buf, pbuf);
db276fa1 1764 }
1531e094 1765#endif
db276fa1 1766}