Updated.
[glibc.git] / elf / rtld.c
blobfe521176e47becd7d32a7eb826849f759767c39f
1 /* Run time dynamic linker.
2 Copyright (C) 1995-1999, 2000, 2001 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
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.
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
13 Lesser General Public License for more details.
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. */
20 #include <fcntl.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <unistd.h>
24 #include <sys/mman.h> /* Check if MAP_ANON is defined. */
25 #include <sys/param.h>
26 #include <sys/stat.h>
27 #include <ldsodefs.h>
28 #include <stdio-common/_itoa.h>
29 #include <entry.h>
30 #include <fpu_control.h>
31 #include <hp-timing.h>
32 #include <bits/libc-lock.h>
33 #include "dynamic-link.h"
34 #include "dl-librecon.h"
35 #include <unsecvars.h>
37 #include <assert.h>
39 /* Helper function to handle errors while resolving symbols. */
40 static void print_unresolved (int errcode, const char *objname,
41 const char *errsting);
43 /* Helper function to handle errors when a version is missing. */
44 static void print_missing_version (int errcode, const char *objname,
45 const char *errsting);
47 /* Print the various times we collected. */
48 static void print_statistics (void);
50 /* This is a list of all the modes the dynamic loader can be in. */
51 enum mode { normal, list, verify, trace };
53 /* Process all environments variables the dynamic linker must recognize.
54 Since all of them start with `LD_' we are a bit smarter while finding
55 all the entries. */
56 static void process_envvars (enum mode *modep);
58 int _dl_argc;
59 char **_dl_argv;
60 unsigned int _dl_skip_args; /* Nonzero if we were run directly. */
61 int _dl_verbose;
62 const char *_dl_platform;
63 size_t _dl_platformlen;
64 unsigned long _dl_hwcap;
65 fpu_control_t _dl_fpu_control = _FPU_DEFAULT;
66 struct r_search_path *_dl_search_paths;
67 const char *_dl_profile;
68 const char *_dl_profile_output;
69 struct link_map *_dl_profile_map;
70 int _dl_lazy = 1;
71 /* XXX I know about at least one case where we depend on the old weak
72 behavior (it has to do with librt). Until we get DSO groups implemented
73 we have to make this the default. Bummer. --drepper */
74 #if 0
75 int _dl_dynamic_weak;
76 #else
77 int _dl_dynamic_weak = 1;
78 #endif
79 int _dl_debug_mask;
80 const char *_dl_inhibit_rpath; /* RPATH values which should be
81 ignored. */
82 const char *_dl_origin_path;
83 int _dl_bind_not;
85 /* This is a pointer to the map for the main object and through it to
86 all loaded objects. */
87 struct link_map *_dl_loaded;
88 /* Number of object in the _dl_loaded list. */
89 unsigned int _dl_nloaded;
90 /* Pointer to the l_searchlist element of the link map of the main object. */
91 struct r_scope_elem *_dl_main_searchlist;
92 /* Copy of the content of `_dl_main_searchlist'. */
93 struct r_scope_elem _dl_initial_searchlist;
94 /* Array which is used when looking up in the global scope. */
95 struct r_scope_elem *_dl_global_scope[2];
97 /* During the program run we must not modify the global data of
98 loaded shared object simultanously in two threads. Therefore we
99 protect `_dl_open' and `_dl_close' in dl-close.c.
101 This must be a recursive lock since the initializer function of
102 the loaded object might as well require a call to this function.
103 At this time it is not anymore a problem to modify the tables. */
104 __libc_lock_define_initialized_recursive (, _dl_load_lock)
106 /* Set nonzero during loading and initialization of executable and
107 libraries, cleared before the executable's entry point runs. This
108 must not be initialized to nonzero, because the unused dynamic
109 linker loaded in for libc.so's "ld.so.1" dep will provide the
110 definition seen by libc.so's initializer; that value must be zero,
111 and will be since that dynamic linker's _dl_start and dl_main will
112 never be called. */
113 int _dl_starting_up;
116 static void dl_main (const ElfW(Phdr) *phdr,
117 ElfW(Word) phnum,
118 ElfW(Addr) *user_entry);
120 struct link_map _dl_rtld_map;
121 struct libname_list _dl_rtld_libname;
122 struct libname_list _dl_rtld_libname2;
124 /* Variable for statistics. */
125 #ifndef HP_TIMING_NONAVAIL
126 static hp_timing_t rtld_total_time;
127 static hp_timing_t relocate_time;
128 static hp_timing_t load_time;
129 #endif
130 extern unsigned long int _dl_num_relocations; /* in dl-lookup.c */
131 extern unsigned long int _dl_num_cache_relocations; /* in dl-lookup.c */
133 static ElfW(Addr) _dl_start_final (void *arg, struct link_map *bootstrap_map_p,
134 hp_timing_t start_time);
136 #ifdef RTLD_START
137 RTLD_START
138 #else
139 #error "sysdeps/MACHINE/dl-machine.h fails to define RTLD_START"
140 #endif
142 static ElfW(Addr)
143 _dl_start (void *arg)
145 struct link_map bootstrap_map;
146 hp_timing_t start_time;
147 size_t cnt;
149 /* This #define produces dynamic linking inline functions for
150 bootstrap relocation instead of general-purpose relocation. */
151 #define RTLD_BOOTSTRAP
152 #define RESOLVE_MAP(sym, version, flags) \
153 ((*(sym))->st_shndx == SHN_UNDEF ? 0 : &bootstrap_map)
154 #define RESOLVE(sym, version, flags) \
155 ((*(sym))->st_shndx == SHN_UNDEF ? 0 : bootstrap_map.l_addr)
156 #include "dynamic-link.h"
158 if (HP_TIMING_INLINE && HP_TIMING_AVAIL)
159 HP_TIMING_NOW (start_time);
161 /* Partly clean the `bootstrap_map' structure up. Don't use `memset'
162 since it might not be built in or inlined and we cannot make function
163 calls at this point. */
164 for (cnt = 0;
165 cnt < sizeof (bootstrap_map.l_info) / sizeof (bootstrap_map.l_info[0]);
166 ++cnt)
167 bootstrap_map.l_info[cnt] = 0;
169 /* Figure out the run-time load address of the dynamic linker itself. */
170 bootstrap_map.l_addr = elf_machine_load_address ();
172 /* Read our own dynamic section and fill in the info array. */
173 bootstrap_map.l_ld = (void *) bootstrap_map.l_addr + elf_machine_dynamic ();
174 elf_get_dynamic_info (&bootstrap_map);
176 #ifdef ELF_MACHINE_BEFORE_RTLD_RELOC
177 ELF_MACHINE_BEFORE_RTLD_RELOC (bootstrap_map.l_info);
178 #endif
180 /* Relocate ourselves so we can do normal function calls and
181 data access using the global offset table. */
183 ELF_DYNAMIC_RELOCATE (&bootstrap_map, 0, 0);
184 /* Please note that we don't allow profiling of this object and
185 therefore need not test whether we have to allocate the array
186 for the relocation results (as done in dl-reloc.c). */
188 /* Now life is sane; we can call functions and access global data.
189 Set up to use the operating system facilities, and find out from
190 the operating system's program loader where to find the program
191 header table in core. Put the rest of _dl_start into a separate
192 function, that way the compiler cannot put accesses to the GOT
193 before ELF_DYNAMIC_RELOCATE. */
195 ElfW(Addr) entry = _dl_start_final (arg, &bootstrap_map, start_time);
197 #ifndef ELF_MACHINE_START_ADDRESS
198 # define ELF_MACHINE_START_ADDRESS(map, start) (start)
199 #endif
201 return ELF_MACHINE_START_ADDRESS (_dl_loaded, entry);
206 static ElfW(Addr)
207 _dl_start_final (void *arg, struct link_map *bootstrap_map_p,
208 hp_timing_t start_time)
210 /* The use of `alloca' here looks ridiculous but it helps. The goal
211 is to avoid the function from being inlined. There is no official
212 way to do this so we use this trick. gcc never inlines functions
213 which use `alloca'. */
214 ElfW(Addr) *start_addr = alloca (sizeof (ElfW(Addr)));
216 if (HP_TIMING_AVAIL)
218 /* If it hasn't happen yet record the startup time. */
219 if (! HP_TIMING_INLINE)
220 HP_TIMING_NOW (start_time);
222 /* Initialize the timing functions. */
223 HP_TIMING_DIFF_INIT ();
226 /* Transfer data about ourselves to the permanent link_map structure. */
227 _dl_rtld_map.l_addr = bootstrap_map_p->l_addr;
228 _dl_rtld_map.l_ld = bootstrap_map_p->l_ld;
229 _dl_rtld_map.l_opencount = 1;
230 memcpy (_dl_rtld_map.l_info, bootstrap_map_p->l_info,
231 sizeof _dl_rtld_map.l_info);
232 _dl_setup_hash (&_dl_rtld_map);
233 _dl_rtld_map.l_mach = bootstrap_map_p->l_mach;
235 /* Don't bother trying to work out how ld.so is mapped in memory. */
236 _dl_rtld_map.l_map_start = ~0;
237 _dl_rtld_map.l_map_end = ~0;
239 /* Call the OS-dependent function to set up life so we can do things like
240 file access. It will call `dl_main' (below) to do all the real work
241 of the dynamic linker, and then unwind our frame and run the user
242 entry point on the same stack we entered on. */
243 *start_addr = _dl_sysdep_start (arg, &dl_main);
244 #ifndef HP_TIMING_NONAVAIL
245 if (HP_TIMING_AVAIL)
247 hp_timing_t end_time;
249 /* Get the current time. */
250 HP_TIMING_NOW (end_time);
252 /* Compute the difference. */
253 HP_TIMING_DIFF (rtld_total_time, start_time, end_time);
255 #endif
257 if (__builtin_expect (_dl_debug_mask & DL_DEBUG_STATISTICS, 0))
258 print_statistics ();
260 return *start_addr;
263 /* Now life is peachy; we can do all normal operations.
264 On to the real work. */
266 /* Some helper functions. */
268 /* Arguments to relocate_doit. */
269 struct relocate_args
271 struct link_map *l;
272 int lazy;
275 struct map_args
277 /* Argument to map_doit. */
278 char *str;
279 /* Return value of map_doit. */
280 struct link_map *main_map;
283 /* Arguments to version_check_doit. */
284 struct version_check_args
286 int doexit;
287 int dotrace;
290 static void
291 relocate_doit (void *a)
293 struct relocate_args *args = (struct relocate_args *) a;
295 _dl_relocate_object (args->l, args->l->l_scope,
296 args->lazy, 0);
299 static void
300 map_doit (void *a)
302 struct map_args *args = (struct map_args *) a;
303 args->main_map = _dl_map_object (NULL, args->str, 0, lt_library, 0, 0);
306 static void
307 version_check_doit (void *a)
309 struct version_check_args *args = (struct version_check_args *) a;
310 if (_dl_check_all_versions (_dl_loaded, 1, args->dotrace) && args->doexit)
311 /* We cannot start the application. Abort now. */
312 _exit (1);
316 static inline struct link_map *
317 find_needed (const char *name)
319 unsigned int n = _dl_loaded->l_searchlist.r_nlist;
321 while (n-- > 0)
322 if (_dl_name_match_p (name, _dl_loaded->l_searchlist.r_list[n]))
323 return _dl_loaded->l_searchlist.r_list[n];
325 /* Should never happen. */
326 return NULL;
329 static int
330 match_version (const char *string, struct link_map *map)
332 const char *strtab = (const void *) D_PTR (map, l_info[DT_STRTAB]);
333 ElfW(Verdef) *def;
335 #define VERDEFTAG (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGIDX (DT_VERDEF))
336 if (map->l_info[VERDEFTAG] == NULL)
337 /* The file has no symbol versioning. */
338 return 0;
340 def = (ElfW(Verdef) *) ((char *) map->l_addr
341 + map->l_info[VERDEFTAG]->d_un.d_ptr);
342 while (1)
344 ElfW(Verdaux) *aux = (ElfW(Verdaux) *) ((char *) def + def->vd_aux);
346 /* Compare the version strings. */
347 if (strcmp (string, strtab + aux->vda_name) == 0)
348 /* Bingo! */
349 return 1;
351 /* If no more definitions we failed to find what we want. */
352 if (def->vd_next == 0)
353 break;
355 /* Next definition. */
356 def = (ElfW(Verdef) *) ((char *) def + def->vd_next);
359 return 0;
362 static const char *library_path; /* The library search path. */
363 static const char *preloadlist; /* The list preloaded objects. */
364 static int version_info; /* Nonzero if information about
365 versions has to be printed. */
367 static void
368 dl_main (const ElfW(Phdr) *phdr,
369 ElfW(Word) phnum,
370 ElfW(Addr) *user_entry)
372 const ElfW(Phdr) *ph;
373 enum mode mode;
374 struct link_map **preloads;
375 unsigned int npreloads;
376 size_t file_size;
377 char *file;
378 int has_interp = 0;
379 unsigned int i;
380 int rtld_is_main = 0;
381 #ifndef HP_TIMING_NONAVAIL
382 hp_timing_t start;
383 hp_timing_t stop;
384 hp_timing_t diff;
385 #endif
387 /* Process the environment variable which control the behaviour. */
388 process_envvars (&mode);
390 /* Set up a flag which tells we are just starting. */
391 _dl_starting_up = 1;
393 if (*user_entry == (ElfW(Addr)) ENTRY_POINT)
395 /* Ho ho. We are not the program interpreter! We are the program
396 itself! This means someone ran ld.so as a command. Well, that
397 might be convenient to do sometimes. We support it by
398 interpreting the args like this:
400 ld.so PROGRAM ARGS...
402 The first argument is the name of a file containing an ELF
403 executable we will load and run with the following arguments.
404 To simplify life here, PROGRAM is searched for using the
405 normal rules for shared objects, rather than $PATH or anything
406 like that. We just load it and use its entry point; we don't
407 pay attention to its PT_INTERP command (we are the interpreter
408 ourselves). This is an easy way to test a new ld.so before
409 installing it. */
410 rtld_is_main = 1;
412 /* Note the place where the dynamic linker actually came from. */
413 _dl_rtld_map.l_name = _dl_argv[0];
415 while (_dl_argc > 1)
416 if (! strcmp (_dl_argv[1], "--list"))
418 mode = list;
419 _dl_lazy = -1; /* This means do no dependency analysis. */
421 ++_dl_skip_args;
422 --_dl_argc;
423 ++_dl_argv;
425 else if (! strcmp (_dl_argv[1], "--verify"))
427 mode = verify;
429 ++_dl_skip_args;
430 --_dl_argc;
431 ++_dl_argv;
433 else if (! strcmp (_dl_argv[1], "--library-path") && _dl_argc > 2)
435 library_path = _dl_argv[2];
437 _dl_skip_args += 2;
438 _dl_argc -= 2;
439 _dl_argv += 2;
441 else if (! strcmp (_dl_argv[1], "--inhibit-rpath") && _dl_argc > 2)
443 _dl_inhibit_rpath = _dl_argv[2];
445 _dl_skip_args += 2;
446 _dl_argc -= 2;
447 _dl_argv += 2;
449 else
450 break;
452 /* If we have no further argument the program was called incorrectly.
453 Grant the user some education. */
454 if (_dl_argc < 2)
455 _dl_fatal_printf ("\
456 Usage: ld.so [OPTION]... EXECUTABLE-FILE [ARGS-FOR-PROGRAM...]\n\
457 You have invoked `ld.so', the helper program for shared library executables.\n\
458 This program usually lives in the file `/lib/ld.so', and special directives\n\
459 in executable files using ELF shared libraries tell the system's program\n\
460 loader to load the helper program from this file. This helper program loads\n\
461 the shared libraries needed by the program executable, prepares the program\n\
462 to run, and runs it. You may invoke this helper program directly from the\n\
463 command line to load and run an ELF executable file; this is like executing\n\
464 that file itself, but always uses this helper program from the file you\n\
465 specified, instead of the helper program file specified in the executable\n\
466 file you run. This is mostly of use for maintainers to test new versions\n\
467 of this helper program; chances are you did not intend to run this program.\n\
469 --list list all dependencies and how they are resolved\n\
470 --verify verify that given object really is a dynamically linked\n\
471 object we can handle\n\
472 --library-path PATH use given PATH instead of content of the environment\n\
473 variable LD_LIBRARY_PATH\n\
474 --inhibit-rpath LIST ignore RUNPATH and RPATH information in object names\n\
475 in LIST\n");
477 ++_dl_skip_args;
478 --_dl_argc;
479 ++_dl_argv;
481 /* Initialize the data structures for the search paths for shared
482 objects. */
483 _dl_init_paths (library_path);
485 if (__builtin_expect (mode, normal) == verify)
487 const char *objname;
488 const char *err_str = NULL;
489 struct map_args args;
491 args.str = _dl_argv[0];
492 (void) _dl_catch_error (&objname, &err_str, map_doit, &args);
493 if (__builtin_expect (err_str != NULL, 0))
495 if (err_str != _dl_out_of_memory)
496 free ((char *) err_str);
497 _exit (EXIT_FAILURE);
500 else
502 HP_TIMING_NOW (start);
503 _dl_map_object (NULL, _dl_argv[0], 0, lt_library, 0, 0);
504 HP_TIMING_NOW (stop);
506 HP_TIMING_DIFF (load_time, start, stop);
509 phdr = _dl_loaded->l_phdr;
510 phnum = _dl_loaded->l_phnum;
511 /* We overwrite here a pointer to a malloc()ed string. But since
512 the malloc() implementation used at this point is the dummy
513 implementations which has no real free() function it does not
514 makes sense to free the old string first. */
515 _dl_loaded->l_name = (char *) "";
516 *user_entry = _dl_loaded->l_entry;
518 else
520 /* Create a link_map for the executable itself.
521 This will be what dlopen on "" returns. */
522 _dl_new_object ((char *) "", "", lt_executable, NULL);
523 if (_dl_loaded == NULL)
524 _dl_fatal_printf ("cannot allocate memory for link map\n");
525 _dl_loaded->l_phdr = phdr;
526 _dl_loaded->l_phnum = phnum;
527 _dl_loaded->l_entry = *user_entry;
529 /* At this point we are in a bit of trouble. We would have to
530 fill in the values for l_dev and l_ino. But in general we
531 do not know where the file is. We also do not handle AT_EXECFD
532 even if it would be passed up.
534 We leave the values here defined to 0. This is normally no
535 problem as the program code itself is normally no shared
536 object and therefore cannot be loaded dynamically. Nothing
537 prevent the use of dynamic binaries and in these situations
538 we might get problems. We might not be able to find out
539 whether the object is already loaded. But since there is no
540 easy way out and because the dynamic binary must also not
541 have an SONAME we ignore this program for now. If it becomes
542 a problem we can force people using SONAMEs. */
544 /* We delay initializing the path structure until we got the dynamic
545 information for the program. */
548 _dl_loaded->l_map_end = 0;
549 /* Perhaps the executable has no PT_LOAD header entries at all. */
550 _dl_loaded->l_map_start = ~0;
552 /* Scan the program header table for the dynamic section. */
553 for (ph = phdr; ph < &phdr[phnum]; ++ph)
554 switch (ph->p_type)
556 case PT_PHDR:
557 /* Find out the load address. */
558 _dl_loaded->l_addr = (ElfW(Addr)) phdr - ph->p_vaddr;
559 break;
560 case PT_DYNAMIC:
561 /* This tells us where to find the dynamic section,
562 which tells us everything we need to do. */
563 _dl_loaded->l_ld = (void *) _dl_loaded->l_addr + ph->p_vaddr;
564 break;
565 case PT_INTERP:
566 /* This "interpreter segment" was used by the program loader to
567 find the program interpreter, which is this program itself, the
568 dynamic linker. We note what name finds us, so that a future
569 dlopen call or DT_NEEDED entry, for something that wants to link
570 against the dynamic linker as a shared library, will know that
571 the shared object is already loaded. */
572 _dl_rtld_libname.name = ((const char *) _dl_loaded->l_addr
573 + ph->p_vaddr);
574 /* _dl_rtld_libname.next = NULL; Already zero. */
575 _dl_rtld_map.l_libname = &_dl_rtld_libname;
577 /* Ordinarilly, we would get additional names for the loader from
578 our DT_SONAME. This can't happen if we were actually linked as
579 a static executable (detect this case when we have no DYNAMIC).
580 If so, assume the filename component of the interpreter path to
581 be our SONAME, and add it to our name list. */
582 if (_dl_rtld_map.l_ld == NULL)
584 char *p = strrchr (_dl_rtld_libname.name, '/');
585 if (p)
587 _dl_rtld_libname2.name = p+1;
588 /* _dl_rtld_libname2.next = NULL; Already zero. */
589 _dl_rtld_libname.next = &_dl_rtld_libname2;
593 has_interp = 1;
594 break;
595 case PT_LOAD:
597 ElfW(Addr) mapstart;
598 ElfW(Addr) allocend;
600 /* Remember where the main program starts in memory. */
601 mapstart = _dl_loaded->l_addr + (ph->p_vaddr & ~(ph->p_align - 1));
602 if (_dl_loaded->l_map_start > mapstart)
603 _dl_loaded->l_map_start = mapstart;
605 /* Also where it ends. */
606 allocend = _dl_loaded->l_addr + ph->p_vaddr + ph->p_memsz;
607 if (_dl_loaded->l_map_end < allocend)
608 _dl_loaded->l_map_end = allocend;
610 break;
612 if (! _dl_loaded->l_map_end)
613 _dl_loaded->l_map_end = ~0;
614 if (! _dl_rtld_map.l_libname && _dl_rtld_map.l_name)
616 /* We were invoked directly, so the program might not have a
617 PT_INTERP. */
618 _dl_rtld_libname.name = _dl_rtld_map.l_name;
619 /* _dl_rtld_libname.next = NULL; Alread zero. */
620 _dl_rtld_map.l_libname = &_dl_rtld_libname;
622 else
623 assert (_dl_rtld_map.l_libname); /* How else did we get here? */
625 if (! rtld_is_main)
627 /* Extract the contents of the dynamic section for easy access. */
628 elf_get_dynamic_info (_dl_loaded);
629 if (_dl_loaded->l_info[DT_HASH])
630 /* Set up our cache of pointers into the hash table. */
631 _dl_setup_hash (_dl_loaded);
634 if (__builtin_expect (mode, normal) == verify)
636 /* We were called just to verify that this is a dynamic
637 executable using us as the program interpreter. Exit with an
638 error if we were not able to load the binary or no interpreter
639 is specified (i.e., this is no dynamically linked binary. */
640 if (_dl_loaded->l_ld == NULL)
641 _exit (1);
643 /* We allow here some platform specific code. */
644 #ifdef DISTINGUISH_LIB_VERSIONS
645 DISTINGUISH_LIB_VERSIONS;
646 #endif
647 _exit (has_interp ? 0 : 2);
650 if (! rtld_is_main)
651 /* Initialize the data structures for the search paths for shared
652 objects. */
653 _dl_init_paths (library_path);
655 /* Put the link_map for ourselves on the chain so it can be found by
656 name. Note that at this point the global chain of link maps contains
657 exactly one element, which is pointed to by _dl_loaded. */
658 if (! _dl_rtld_map.l_name)
659 /* If not invoked directly, the dynamic linker shared object file was
660 found by the PT_INTERP name. */
661 _dl_rtld_map.l_name = (char *) _dl_rtld_map.l_libname->name;
662 _dl_rtld_map.l_type = lt_library;
663 _dl_loaded->l_next = &_dl_rtld_map;
664 _dl_rtld_map.l_prev = _dl_loaded;
665 ++_dl_nloaded;
667 /* We have two ways to specify objects to preload: via environment
668 variable and via the file /etc/ld.so.preload. The latter can also
669 be used when security is enabled. */
670 preloads = NULL;
671 npreloads = 0;
673 if (__builtin_expect (preloadlist != NULL, 0))
675 /* The LD_PRELOAD environment variable gives list of libraries
676 separated by white space or colons that are loaded before the
677 executable's dependencies and prepended to the global scope
678 list. If the binary is running setuid all elements
679 containing a '/' are ignored since it is insecure. */
680 char *list = strdupa (preloadlist);
681 char *p;
683 HP_TIMING_NOW (start);
685 while ((p = strsep (&list, " :")) != NULL)
686 if (p[0] != '\0'
687 && (__builtin_expect (! __libc_enable_secure, 1)
688 || strchr (p, '/') == NULL))
690 struct link_map *new_map = _dl_map_object (_dl_loaded, p, 1,
691 lt_library, 0, 0);
692 if (++new_map->l_opencount == 1)
693 /* It is no duplicate. */
694 ++npreloads;
697 HP_TIMING_NOW (stop);
698 HP_TIMING_DIFF (diff, start, stop);
699 HP_TIMING_ACCUM_NT (load_time, diff);
702 /* Read the contents of the file. */
703 file = _dl_sysdep_read_whole_file ("/etc/ld.so.preload", &file_size,
704 PROT_READ | PROT_WRITE);
705 if (__builtin_expect (file != NULL, 0))
707 /* Parse the file. It contains names of libraries to be loaded,
708 separated by white spaces or `:'. It may also contain
709 comments introduced by `#'. */
710 char *problem;
711 char *runp;
712 size_t rest;
714 /* Eliminate comments. */
715 runp = file;
716 rest = file_size;
717 while (rest > 0)
719 char *comment = memchr (runp, '#', rest);
720 if (comment == NULL)
721 break;
723 rest -= comment - runp;
725 *comment = ' ';
726 while (--rest > 0 && *++comment != '\n');
729 /* We have one problematic case: if we have a name at the end of
730 the file without a trailing terminating characters, we cannot
731 place the \0. Handle the case separately. */
732 if (file[file_size - 1] != ' ' && file[file_size - 1] != '\t'
733 && file[file_size - 1] != '\n' && file[file_size - 1] != ':')
735 problem = &file[file_size];
736 while (problem > file && problem[-1] != ' ' && problem[-1] != '\t'
737 && problem[-1] != '\n' && problem[-1] != ':')
738 --problem;
740 if (problem > file)
741 problem[-1] = '\0';
743 else
745 problem = NULL;
746 file[file_size - 1] = '\0';
749 HP_TIMING_NOW (start);
751 if (file != problem)
753 char *p;
754 runp = file;
755 while ((p = strsep (&runp, ": \t\n")) != NULL)
756 if (p[0] != '\0')
758 struct link_map *new_map = _dl_map_object (_dl_loaded, p, 1,
759 lt_library, 0, 0);
760 if (++new_map->l_opencount == 1)
761 /* It is no duplicate. */
762 ++npreloads;
766 if (problem != NULL)
768 char *p = strndupa (problem, file_size - (problem - file));
769 struct link_map *new_map = _dl_map_object (_dl_loaded, p, 1,
770 lt_library, 0, 0);
771 if (++new_map->l_opencount == 1)
772 /* It is no duplicate. */
773 ++npreloads;
776 HP_TIMING_NOW (stop);
777 HP_TIMING_DIFF (diff, start, stop);
778 HP_TIMING_ACCUM_NT (load_time, diff);
780 /* We don't need the file anymore. */
781 __munmap (file, file_size);
784 if (__builtin_expect (npreloads, 0) != 0)
786 /* Set up PRELOADS with a vector of the preloaded libraries. */
787 struct link_map *l;
788 preloads = __alloca (npreloads * sizeof preloads[0]);
789 l = _dl_rtld_map.l_next; /* End of the chain before preloads. */
790 i = 0;
793 preloads[i++] = l;
794 l = l->l_next;
795 } while (l);
796 assert (i == npreloads);
799 /* Load all the libraries specified by DT_NEEDED entries. If LD_PRELOAD
800 specified some libraries to load, these are inserted before the actual
801 dependencies in the executable's searchlist for symbol resolution. */
802 HP_TIMING_NOW (start);
803 _dl_map_object_deps (_dl_loaded, preloads, npreloads, mode == trace);
804 HP_TIMING_NOW (stop);
805 HP_TIMING_DIFF (diff, start, stop);
806 HP_TIMING_ACCUM_NT (load_time, diff);
808 /* Mark all objects as being in the global scope and set the open
809 counter. */
810 for (i = _dl_loaded->l_searchlist.r_nlist; i > 0; )
812 --i;
813 _dl_loaded->l_searchlist.r_list[i]->l_global = 1;
814 ++_dl_loaded->l_searchlist.r_list[i]->l_opencount;
817 #ifndef MAP_ANON
818 /* We are done mapping things, so close the zero-fill descriptor. */
819 __close (_dl_zerofd);
820 _dl_zerofd = -1;
821 #endif
823 /* Remove _dl_rtld_map from the chain. */
824 _dl_rtld_map.l_prev->l_next = _dl_rtld_map.l_next;
825 if (_dl_rtld_map.l_next)
826 _dl_rtld_map.l_next->l_prev = _dl_rtld_map.l_prev;
828 if (__builtin_expect (_dl_rtld_map.l_opencount > 1, 1))
830 /* Some DT_NEEDED entry referred to the interpreter object itself, so
831 put it back in the list of visible objects. We insert it into the
832 chain in symbol search order because gdb uses the chain's order as
833 its symbol search order. */
834 i = 1;
835 while (_dl_loaded->l_searchlist.r_list[i] != &_dl_rtld_map)
836 ++i;
837 _dl_rtld_map.l_prev = _dl_loaded->l_searchlist.r_list[i - 1];
838 if (__builtin_expect (mode, normal) == normal)
839 _dl_rtld_map.l_next = (i + 1 < _dl_loaded->l_searchlist.r_nlist
840 ? _dl_loaded->l_searchlist.r_list[i + 1]
841 : NULL);
842 else
843 /* In trace mode there might be an invisible object (which we
844 could not find) after the previous one in the search list.
845 In this case it doesn't matter much where we put the
846 interpreter object, so we just initialize the list pointer so
847 that the assertion below holds. */
848 _dl_rtld_map.l_next = _dl_rtld_map.l_prev->l_next;
850 assert (_dl_rtld_map.l_prev->l_next == _dl_rtld_map.l_next);
851 _dl_rtld_map.l_prev->l_next = &_dl_rtld_map;
852 if (_dl_rtld_map.l_next)
854 assert (_dl_rtld_map.l_next->l_prev == _dl_rtld_map.l_prev);
855 _dl_rtld_map.l_next->l_prev = &_dl_rtld_map;
859 /* Now let us see whether all libraries are available in the
860 versions we need. */
862 struct version_check_args args;
863 args.doexit = mode == normal;
864 args.dotrace = mode == trace;
865 _dl_receive_error (print_missing_version, version_check_doit, &args);
868 if (__builtin_expect (mode, normal) != normal)
870 /* We were run just to list the shared libraries. It is
871 important that we do this before real relocation, because the
872 functions we call below for output may no longer work properly
873 after relocation. */
874 if (! _dl_loaded->l_info[DT_NEEDED])
875 _dl_printf ("\tstatically linked\n");
876 else
878 struct link_map *l;
880 for (l = _dl_loaded->l_next; l; l = l->l_next)
881 if (l->l_faked)
882 /* The library was not found. */
883 _dl_printf ("\t%s => not found\n", l->l_libname->name);
884 else
885 _dl_printf ("\t%s => %s (0x%0*Zx)\n", l->l_libname->name,
886 l->l_name, (int) sizeof l->l_addr * 2, l->l_addr);
889 if (__builtin_expect (mode, trace) != trace)
890 for (i = 1; i < _dl_argc; ++i)
892 const ElfW(Sym) *ref = NULL;
893 ElfW(Addr) loadbase;
894 lookup_t result;
896 result = _dl_lookup_symbol (_dl_argv[i], _dl_loaded,
897 &ref, _dl_loaded->l_scope,
898 ELF_RTYPE_CLASS_PLT, 1);
900 loadbase = LOOKUP_VALUE_ADDRESS (result);
902 _dl_printf ("%s found at 0x%0*Zd in object at 0x%0*Zd\n",
903 _dl_argv[i],
904 (int) sizeof ref->st_value * 2, ref->st_value,
905 (int) sizeof loadbase * 2, loadbase);
907 else
909 /* If LD_WARN is set warn about undefined symbols. */
910 if (_dl_lazy >= 0 && _dl_verbose)
912 /* We have to do symbol dependency testing. */
913 struct relocate_args args;
914 struct link_map *l;
916 args.lazy = _dl_lazy;
918 l = _dl_loaded;
919 while (l->l_next)
920 l = l->l_next;
923 if (l != &_dl_rtld_map && ! l->l_faked)
925 args.l = l;
926 _dl_receive_error (print_unresolved, relocate_doit,
927 &args);
929 l = l->l_prev;
930 } while (l);
933 #define VERNEEDTAG (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGIDX (DT_VERNEED))
934 if (version_info)
936 /* Print more information. This means here, print information
937 about the versions needed. */
938 int first = 1;
939 struct link_map *map = _dl_loaded;
941 for (map = _dl_loaded; map != NULL; map = map->l_next)
943 const char *strtab;
944 ElfW(Dyn) *dyn = map->l_info[VERNEEDTAG];
945 ElfW(Verneed) *ent;
947 if (dyn == NULL)
948 continue;
950 strtab = (const void *) D_PTR (map, l_info[DT_STRTAB]);
951 ent = (ElfW(Verneed) *) (map->l_addr + dyn->d_un.d_ptr);
953 if (first)
955 _dl_printf ("\n\tVersion information:\n");
956 first = 0;
959 _dl_printf ("\t%s:\n",
960 map->l_name[0] ? map->l_name : _dl_argv[0]);
962 while (1)
964 ElfW(Vernaux) *aux;
965 struct link_map *needed;
967 needed = find_needed (strtab + ent->vn_file);
968 aux = (ElfW(Vernaux) *) ((char *) ent + ent->vn_aux);
970 while (1)
972 const char *fname = NULL;
974 if (needed != NULL
975 && match_version (strtab + aux->vna_name,
976 needed))
977 fname = needed->l_name;
979 _dl_printf ("\t\t%s (%s) %s=> %s\n",
980 strtab + ent->vn_file,
981 strtab + aux->vna_name,
982 aux->vna_flags & VER_FLG_WEAK
983 ? "[WEAK] " : "",
984 fname ?: "not found");
986 if (aux->vna_next == 0)
987 /* No more symbols. */
988 break;
990 /* Next symbol. */
991 aux = (ElfW(Vernaux) *) ((char *) aux
992 + aux->vna_next);
995 if (ent->vn_next == 0)
996 /* No more dependencies. */
997 break;
999 /* Next dependency. */
1000 ent = (ElfW(Verneed) *) ((char *) ent + ent->vn_next);
1006 _exit (0);
1010 /* Now we have all the objects loaded. Relocate them all except for
1011 the dynamic linker itself. We do this in reverse order so that copy
1012 relocs of earlier objects overwrite the data written by later
1013 objects. We do not re-relocate the dynamic linker itself in this
1014 loop because that could result in the GOT entries for functions we
1015 call being changed, and that would break us. It is safe to relocate
1016 the dynamic linker out of order because it has no copy relocs (we
1017 know that because it is self-contained). */
1019 struct link_map *l;
1020 int consider_profiling = _dl_profile != NULL;
1021 #ifndef HP_TIMING_NONAVAIL
1022 hp_timing_t start;
1023 hp_timing_t stop;
1024 hp_timing_t add;
1025 #endif
1027 /* If we are profiling we also must do lazy reloaction. */
1028 _dl_lazy |= consider_profiling;
1030 l = _dl_loaded;
1031 while (l->l_next)
1032 l = l->l_next;
1034 HP_TIMING_NOW (start);
1037 /* While we are at it, help the memory handling a bit. We have to
1038 mark some data structures as allocated with the fake malloc()
1039 implementation in ld.so. */
1040 struct libname_list *lnp = l->l_libname->next;
1042 while (__builtin_expect (lnp != NULL, 0))
1044 lnp->dont_free = 1;
1045 lnp = lnp->next;
1048 if (l != &_dl_rtld_map)
1049 _dl_relocate_object (l, l->l_scope, _dl_lazy, consider_profiling);
1051 l = l->l_prev;
1053 while (l);
1054 HP_TIMING_NOW (stop);
1056 HP_TIMING_DIFF (relocate_time, start, stop);
1058 /* Do any necessary cleanups for the startup OS interface code.
1059 We do these now so that no calls are made after rtld re-relocation
1060 which might be resolved to different functions than we expect.
1061 We cannot do this before relocating the other objects because
1062 _dl_relocate_object might need to call `mprotect' for DT_TEXTREL. */
1063 _dl_sysdep_start_cleanup ();
1065 /* Now enable profiling if needed. Like the previous call,
1066 this has to go here because the calls it makes should use the
1067 rtld versions of the functions (particularly calloc()), but it
1068 needs to have _dl_profile_map set up by the relocator. */
1069 if (__builtin_expect (_dl_profile_map != NULL, 0))
1070 /* We must prepare the profiling. */
1071 _dl_start_profile (_dl_profile_map, _dl_profile_output);
1073 if (_dl_rtld_map.l_opencount > 1)
1075 /* There was an explicit ref to the dynamic linker as a shared lib.
1076 Re-relocate ourselves with user-controlled symbol definitions. */
1077 HP_TIMING_NOW (start);
1078 _dl_relocate_object (&_dl_rtld_map, _dl_loaded->l_scope, 0, 0);
1079 HP_TIMING_NOW (stop);
1080 HP_TIMING_DIFF (add, start, stop);
1081 HP_TIMING_ACCUM_NT (relocate_time, add);
1085 /* Now set up the variable which helps the assembler startup code. */
1086 _dl_main_searchlist = &_dl_loaded->l_searchlist;
1087 _dl_global_scope[0] = &_dl_loaded->l_searchlist;
1089 /* Safe the information about the original global scope list since
1090 we need it in the memory handling later. */
1091 _dl_initial_searchlist = *_dl_main_searchlist;
1094 /* Initialize _r_debug. */
1095 struct r_debug *r = _dl_debug_initialize (_dl_rtld_map.l_addr);
1096 struct link_map *l;
1098 l = _dl_loaded;
1100 #ifdef ELF_MACHINE_DEBUG_SETUP
1102 /* Some machines (e.g. MIPS) don't use DT_DEBUG in this way. */
1104 ELF_MACHINE_DEBUG_SETUP (l, r);
1105 ELF_MACHINE_DEBUG_SETUP (&_dl_rtld_map, r);
1107 #else
1109 if (l->l_info[DT_DEBUG])
1110 /* There is a DT_DEBUG entry in the dynamic section. Fill it in
1111 with the run-time address of the r_debug structure */
1112 l->l_info[DT_DEBUG]->d_un.d_ptr = (ElfW(Addr)) r;
1114 /* Fill in the pointer in the dynamic linker's own dynamic section, in
1115 case you run gdb on the dynamic linker directly. */
1116 if (_dl_rtld_map.l_info[DT_DEBUG])
1117 _dl_rtld_map.l_info[DT_DEBUG]->d_un.d_ptr = (ElfW(Addr)) r;
1119 #endif
1121 /* Notify the debugger that all objects are now mapped in. */
1122 r->r_state = RT_ADD;
1123 _dl_debug_state ();
1126 #ifndef MAP_COPY
1127 /* We must munmap() the cache file. */
1128 _dl_unload_cache ();
1129 #endif
1131 /* Once we return, _dl_sysdep_start will invoke
1132 the DT_INIT functions and then *USER_ENTRY. */
1135 /* This is a little helper function for resolving symbols while
1136 tracing the binary. */
1137 static void
1138 print_unresolved (int errcode __attribute__ ((unused)), const char *objname,
1139 const char *errstring)
1141 if (objname[0] == '\0')
1142 objname = _dl_argv[0] ?: "<main program>";
1143 _dl_error_printf ("%s (%s)\n", errstring, objname);
1146 /* This is a little helper function for resolving symbols while
1147 tracing the binary. */
1148 static void
1149 print_missing_version (int errcode __attribute__ ((unused)),
1150 const char *objname, const char *errstring)
1152 _dl_error_printf ("%s: %s: %s\n", _dl_argv[0] ?: "<program name unknown>",
1153 objname, errstring);
1156 /* Nonzero if any of the debugging options is enabled. */
1157 static int any_debug;
1159 /* Process the string given as the parameter which explains which debugging
1160 options are enabled. */
1161 static void
1162 process_dl_debug (const char *dl_debug)
1164 size_t len;
1165 #define separators " ,:"
1168 len = 0;
1169 /* Skip separating white spaces and commas. */
1170 dl_debug += strspn (dl_debug, separators);
1171 if (*dl_debug != '\0')
1173 len = strcspn (dl_debug, separators);
1175 switch (len)
1177 case 3:
1178 /* This option is not documented since it is not generally
1179 useful. */
1180 if (memcmp (dl_debug, "all", 3) == 0)
1182 _dl_debug_mask = (DL_DEBUG_LIBS | DL_DEBUG_IMPCALLS
1183 | DL_DEBUG_RELOC | DL_DEBUG_FILES
1184 | DL_DEBUG_SYMBOLS | DL_DEBUG_BINDINGS
1185 | DL_DEBUG_VERSIONS);
1186 any_debug = 1;
1187 continue;
1189 break;
1191 case 4:
1192 if (memcmp (dl_debug, "help", 4) == 0)
1194 _dl_printf ("\
1195 Valid options for the LD_DEBUG environment variable are:\n\
1197 bindings display information about symbol binding\n\
1198 files display processing of files and libraries\n\
1199 help display this help message and exit\n\
1200 libs display library search paths\n\
1201 reloc display relocation processing\n\
1202 statistics display relocation statistics\n\
1203 symbols display symbol table processing\n\
1204 versions display version dependencies\n\
1206 To direct the debugging output into a file instead of standard output\n\
1207 a filename can be specified using the LD_DEBUG_OUTPUT environment variable.\n");
1208 _exit (0);
1211 if (memcmp (dl_debug, "libs", 4) == 0)
1213 _dl_debug_mask |= DL_DEBUG_LIBS | DL_DEBUG_IMPCALLS;
1214 any_debug = 1;
1215 continue;
1217 break;
1219 case 5:
1220 if (memcmp (dl_debug, "reloc", 5) == 0)
1222 _dl_debug_mask |= DL_DEBUG_RELOC | DL_DEBUG_IMPCALLS;
1223 any_debug = 1;
1224 continue;
1227 if (memcmp (dl_debug, "files", 5) == 0)
1229 _dl_debug_mask |= DL_DEBUG_FILES | DL_DEBUG_IMPCALLS;
1230 any_debug = 1;
1231 continue;
1233 break;
1235 case 7:
1236 if (memcmp (dl_debug, "symbols", 7) == 0)
1238 _dl_debug_mask |= DL_DEBUG_SYMBOLS | DL_DEBUG_IMPCALLS;
1239 any_debug = 1;
1240 continue;
1242 break;
1244 case 8:
1245 if (memcmp (dl_debug, "bindings", 8) == 0)
1247 _dl_debug_mask |= DL_DEBUG_BINDINGS | DL_DEBUG_IMPCALLS;
1248 any_debug = 1;
1249 continue;
1252 if (memcmp (dl_debug, "versions", 8) == 0)
1254 _dl_debug_mask |= DL_DEBUG_VERSIONS | DL_DEBUG_IMPCALLS;
1255 any_debug = 1;
1256 continue;
1258 break;
1260 case 10:
1261 if (memcmp (dl_debug, "statistics", 10) == 0)
1263 _dl_debug_mask |= DL_DEBUG_STATISTICS;
1264 continue;
1266 break;
1268 default:
1269 break;
1273 /* Display a warning and skip everything until next separator. */
1274 char *startp = strndupa (dl_debug, len);
1275 _dl_error_printf ("\
1276 warning: debug option `%s' unknown; try LD_DEBUG=help\n", startp);
1277 break;
1281 while (*(dl_debug += len) != '\0');
1284 /* Process all environments variables the dynamic linker must recognize.
1285 Since all of them start with `LD_' we are a bit smarter while finding
1286 all the entries. */
1287 extern char **_environ;
1289 static void
1290 process_envvars (enum mode *modep)
1292 char **runp = _environ;
1293 char *envline;
1294 enum mode mode = normal;
1295 char *debug_output = NULL;
1297 /* This is the default place for profiling data file. */
1298 _dl_profile_output = __libc_enable_secure ? "/var/profile" : "/var/tmp";
1300 while ((envline = _dl_next_ld_env_entry (&runp)) != NULL)
1302 size_t len = strcspn (envline, "=");
1304 if (envline[len] != '=')
1305 /* This is a "LD_" variable at the end of the string without
1306 a '=' character. Ignore it since otherwise we will access
1307 invalid memory below. */
1308 continue;
1310 switch (len)
1312 case 4:
1313 /* Warning level, verbose or not. */
1314 if (memcmp (envline, "WARN", 4) == 0)
1315 _dl_verbose = envline[5] != '\0';
1316 break;
1318 case 5:
1319 /* Debugging of the dynamic linker? */
1320 if (memcmp (envline, "DEBUG", 5) == 0)
1321 process_dl_debug (&envline[6]);
1322 break;
1324 case 7:
1325 /* Print information about versions. */
1326 if (memcmp (envline, "VERBOSE", 7) == 0)
1328 version_info = envline[8] != '\0';
1329 break;
1332 /* List of objects to be preloaded. */
1333 if (memcmp (envline, "PRELOAD", 7) == 0)
1335 preloadlist = &envline[8];
1336 break;
1339 /* Which shared object shall be profiled. */
1340 if (memcmp (envline, "PROFILE", 7) == 0)
1341 _dl_profile = &envline[8];
1342 break;
1344 case 8:
1345 /* Do we bind early? */
1346 if (memcmp (envline, "BIND_NOW", 8) == 0)
1348 _dl_lazy = envline[9] == '\0';
1349 break;
1351 if (memcmp (envline, "BIND_NOT", 8) == 0)
1352 _dl_bind_not = envline[9] != '\0';
1353 break;
1355 case 9:
1356 /* Test whether we want to see the content of the auxiliary
1357 array passed up from the kernel. */
1358 if (memcmp (envline, "SHOW_AUXV", 9) == 0)
1359 _dl_show_auxv ();
1360 break;
1362 case 10:
1363 /* Mask for the important hardware capabilities. */
1364 if (memcmp (envline, "HWCAP_MASK", 10) == 0)
1365 _dl_hwcap_mask = __strtoul_internal (&envline[11], NULL, 0, 0);
1366 break;
1368 case 11:
1369 /* Path where the binary is found. */
1370 if (!__libc_enable_secure
1371 && memcmp (envline, "ORIGIN_PATH", 11) == 0)
1372 _dl_origin_path = &envline[12];
1373 break;
1375 case 12:
1376 /* The library search path. */
1377 if (memcmp (envline, "LIBRARY_PATH", 12) == 0)
1379 library_path = &envline[13];
1380 break;
1383 /* Where to place the profiling data file. */
1384 if (memcmp (envline, "DEBUG_OUTPUT", 12) == 0)
1386 debug_output = &envline[13];
1387 break;
1390 if (memcmp (envline, "DYNAMIC_WEAK", 12) == 0)
1391 _dl_dynamic_weak = 1;
1392 break;
1394 case 14:
1395 /* Where to place the profiling data file. */
1396 if (!__libc_enable_secure
1397 && memcmp (envline, "PROFILE_OUTPUT", 14) == 0)
1399 _dl_profile_output = &envline[15];
1400 if (*_dl_profile_output == '\0')
1401 _dl_profile_output = "/var/tmp";
1403 break;
1405 case 20:
1406 /* The mode of the dynamic linker can be set. */
1407 if (memcmp (envline, "TRACE_LOADED_OBJECTS", 20) == 0)
1408 mode = trace;
1409 break;
1411 /* We might have some extra environment variable to handle. This
1412 is tricky due to the pre-processing of the length of the name
1413 in the switch statement here. The code here assumes that added
1414 environment variables have a different length. */
1415 #ifdef EXTRA_LD_ENVVARS
1416 EXTRA_LD_ENVVARS
1417 #endif
1421 /* Extra security for SUID binaries. Remove all dangerous environment
1422 variables. */
1423 if (__builtin_expect (__libc_enable_secure, 0))
1425 static const char *unsecure_envvars[] =
1427 UNSECURE_ENVVARS,
1428 #ifdef EXTRA_UNSECURE_ENVVARS
1429 EXTRA_UNSECURE_ENVVARS
1430 #endif
1432 size_t cnt;
1434 if (preloadlist != NULL)
1435 unsetenv ("LD_PRELOAD");
1436 if (library_path != NULL)
1437 unsetenv ("LD_LIBRARY_PATH");
1438 if (_dl_origin_path != NULL)
1439 unsetenv ("LD_ORIGIN_PATH");
1440 if (debug_output != NULL)
1441 unsetenv ("LD_DEBUG_OUTPUT");
1442 if (_dl_profile != NULL)
1443 unsetenv ("LD_PROFILE");
1445 for (cnt = 0;
1446 cnt < sizeof (unsecure_envvars) / sizeof (unsecure_envvars[0]);
1447 ++cnt)
1448 unsetenv (unsecure_envvars[cnt]);
1450 if (__access ("/etc/suid-debug", F_OK) != 0)
1451 unsetenv ("MALLOC_CHECK_");
1454 /* The name of the object to profile cannot be empty. */
1455 if (_dl_profile != NULL && *_dl_profile == '\0')
1456 _dl_profile = NULL;
1458 /* If we have to run the dynamic linker in debugging mode and the
1459 LD_DEBUG_OUTPUT environment variable is given, we write the debug
1460 messages to this file. */
1461 if (any_debug && debug_output != NULL && !__libc_enable_secure)
1463 #ifdef O_NOFOLLOW
1464 const int flags = O_WRONLY | O_APPEND | O_CREAT | O_NOFOLLOW;
1465 #else
1466 const int flags = O_WRONLY | O_APPEND | O_CREAT;
1467 #endif
1468 size_t name_len = strlen (debug_output);
1469 char buf[name_len + 12];
1470 char *startp;
1472 buf[name_len + 11] = '\0';
1473 startp = _itoa_word (__getpid (), &buf[name_len + 11], 10, 0);
1474 *--startp = '.';
1475 startp = memcpy (startp - name_len, debug_output, name_len);
1477 _dl_debug_fd = __open (startp, flags, DEFFILEMODE);
1478 if (_dl_debug_fd == -1)
1479 /* We use standard output if opening the file failed. */
1480 _dl_debug_fd = STDOUT_FILENO;
1483 *modep = mode;
1487 /* Print the various times we collected. */
1488 static void
1489 print_statistics (void)
1491 #ifndef HP_TIMING_NONAVAIL
1492 char buf[200];
1493 char *cp;
1494 char *wp;
1496 /* Total time rtld used. */
1497 if (HP_TIMING_AVAIL)
1499 HP_TIMING_PRINT (buf, sizeof (buf), rtld_total_time);
1500 _dl_debug_printf ("\nruntime linker statistics:\n"
1501 " total startup time in dynamic loader: %s\n", buf);
1504 /* Print relocation statistics. */
1505 if (HP_TIMING_AVAIL)
1507 char pbuf[30];
1508 HP_TIMING_PRINT (buf, sizeof (buf), relocate_time);
1509 cp = _itoa_word ((1000 * relocate_time) / rtld_total_time,
1510 pbuf + sizeof (pbuf), 10, 0);
1511 wp = pbuf;
1512 switch (pbuf + sizeof (pbuf) - cp)
1514 case 3:
1515 *wp++ = *cp++;
1516 case 2:
1517 *wp++ = *cp++;
1518 case 1:
1519 *wp++ = '.';
1520 *wp++ = *cp++;
1522 *wp = '\0';
1523 _dl_debug_printf (" time needed for relocation: %s (%s%%)\n",
1524 buf, pbuf);
1526 #endif
1527 _dl_debug_printf (" number of relocations: %lu\n",
1528 _dl_num_relocations);
1529 _dl_debug_printf (" number of relocations from cache: %lu\n",
1530 _dl_num_cache_relocations);
1532 #ifndef HP_TIMING_NONAVAIL
1533 /* Time spend while loading the object and the dependencies. */
1534 if (HP_TIMING_AVAIL)
1536 char pbuf[30];
1537 HP_TIMING_PRINT (buf, sizeof (buf), load_time);
1538 cp = _itoa_word ((1000 * load_time) / rtld_total_time,
1539 pbuf + sizeof (pbuf), 10, 0);
1540 wp = pbuf;
1541 switch (pbuf + sizeof (pbuf) - cp)
1543 case 3:
1544 *wp++ = *cp++;
1545 case 2:
1546 *wp++ = *cp++;
1547 case 1:
1548 *wp++ = '.';
1549 *wp++ = *cp++;
1551 *wp = '\0';
1552 _dl_debug_printf (" time needed to load objects: %s (%s%%)\n",
1553 buf, pbuf);
1555 #endif