fgetws implementation.
[kopensolaris-gnu/glibc.git] / elf / rtld.c
1 /* Run time dynamic linker.
2    Copyright (C) 1995, 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Library General Public License as
7    published by the Free Software Foundation; either version 2 of the
8    License, or (at your option) any later version.
9
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Library General Public License for more details.
14
15    You should have received a copy of the GNU Library General Public
16    License along with the GNU C Library; see the file COPYING.LIB.  If not,
17    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18    Boston, MA 02111-1307, USA.  */
19
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 <elf/ldsodefs.h>
26 #include <stdio-common/_itoa.h>
27 #include <entry.h>
28 #include <fpu_control.h>
29 #include <hp-timing.h>
30 #include "dynamic-link.h"
31 #include "dl-librecon.h"
32
33 #include <assert.h>
34
35 /* System-specific function to do initial startup for the dynamic linker.
36    After this, file access calls and getenv must work.  This is responsible
37    for setting __libc_enable_secure if we need to be secure (e.g. setuid),
38    and for setting _dl_argc and _dl_argv, and then calling _dl_main.  */
39 extern ElfW(Addr) _dl_sysdep_start (void **start_argptr,
40                                     void (*dl_main) (const ElfW(Phdr) *phdr,
41                                                      ElfW(Half) phent,
42                                                      ElfW(Addr) *user_entry));
43 extern void _dl_sysdep_start_cleanup (void);
44
45 /* This function is used to unload the cache file if necessary.  */
46 extern void _dl_unload_cache (void);
47
48 /* System-dependent function to read a file's whole contents
49    in the most convenient manner available.  */
50 extern void *_dl_sysdep_read_whole_file (const char *filename,
51                                          size_t *filesize_ptr,
52                                          int mmap_prot);
53
54 /* Helper function to handle errors while resolving symbols.  */
55 static void print_unresolved (int errcode, const char *objname,
56                               const char *errsting);
57
58 /* Helper function to handle errors when a version is missing.  */
59 static void print_missing_version (int errcode, const char *objname,
60                                    const char *errsting);
61
62 /* Print the various times we collected.  */
63 static void print_statistics (void);
64
65 /* This is a list of all the modes the dynamic loader can be in.  */
66 enum mode { normal, list, verify, trace };
67
68 /* Process all environments variables the dynamic linker must recognize.
69    Since all of them start with `LD_' we are a bit smarter while finding
70    all the entries.  */
71 static void process_envvars (enum mode *modep, int *lazyp);
72
73 int _dl_argc;
74 char **_dl_argv;
75 unsigned int _dl_skip_args;     /* Nonzero if we were run directly.  */
76 int _dl_verbose;
77 const char *_dl_platform;
78 size_t _dl_platformlen;
79 unsigned long _dl_hwcap;
80 fpu_control_t _dl_fpu_control = _FPU_DEFAULT;
81 struct r_search_path *_dl_search_paths;
82 const char *_dl_profile;
83 const char *_dl_profile_output;
84 struct link_map *_dl_profile_map;
85 int _dl_lazy;
86 int _dl_debug_libs;
87 int _dl_debug_impcalls;
88 int _dl_debug_bindings;
89 int _dl_debug_symbols;
90 int _dl_debug_versions;
91 int _dl_debug_reloc;
92 int _dl_debug_files;
93 int _dl_debug_statistics;
94 const char *_dl_inhibit_rpath;          /* RPATH values which should be
95                                            ignored.  */
96 const char *_dl_origin_path;
97
98 /* This is a pointer to the map for the main object and through it to
99    all loaded objects.  */
100 struct link_map *_dl_loaded;
101 /* Pointer to the l_searchlist element of the link map of the main object.  */
102 struct r_scope_elem *_dl_main_searchlist;
103 /* Copy of the content of `_dl_main_searchlist'.  */
104 struct r_scope_elem _dl_initial_searchlist;
105 /* Array which is used when looking up in the global scope.  */
106 struct r_scope_elem *_dl_global_scope[2];
107
108 /* Set nonzero during loading and initialization of executable and
109    libraries, cleared before the executable's entry point runs.  This
110    must not be initialized to nonzero, because the unused dynamic
111    linker loaded in for libc.so's "ld.so.1" dep will provide the
112    definition seen by libc.so's initializer; that value must be zero,
113    and will be since that dynamic linker's _dl_start and dl_main will
114    never be called.  */
115 int _dl_starting_up;
116
117
118 static void dl_main (const ElfW(Phdr) *phdr,
119                      ElfW(Half) phent,
120                      ElfW(Addr) *user_entry);
121
122 struct link_map _dl_rtld_map;
123 struct libname_list _dl_rtld_libname;
124 struct libname_list _dl_rtld_libname2;
125
126 /* Variable for statistics.  */
127 static hp_timing_t rtld_total_time;
128 static hp_timing_t relocate_time;
129 static hp_timing_t load_time;
130 extern unsigned long int _dl_num_relocations;   /* in dl-lookup.c */
131
132 #ifdef RTLD_START
133 RTLD_START
134 #else
135 #error "sysdeps/MACHINE/dl-machine.h fails to define RTLD_START"
136 #endif
137
138 static ElfW(Addr)
139 _dl_start (void *arg)
140 {
141   struct link_map bootstrap_map;
142   hp_timing_t start_time;
143   ElfW(Addr) start_addr;
144
145   /* This #define produces dynamic linking inline functions for
146      bootstrap relocation instead of general-purpose relocation.  */
147 #define RTLD_BOOTSTRAP
148 #define RESOLVE(sym, version, flags) \
149   ((*(sym))->st_shndx == SHN_UNDEF ? 0 : bootstrap_map.l_addr)
150 #include "dynamic-link.h"
151
152   if (HP_TIMING_INLINE && HP_TIMING_AVAIL)
153     HP_TIMING_NOW (start_time);
154
155   /* Figure out the run-time load address of the dynamic linker itself.  */
156   bootstrap_map.l_addr = elf_machine_load_address ();
157
158   /* Read our own dynamic section and fill in the info array.  */
159   bootstrap_map.l_ld = (void *) bootstrap_map.l_addr + elf_machine_dynamic ();
160   elf_get_dynamic_info (bootstrap_map.l_ld, bootstrap_map.l_addr,
161                         bootstrap_map.l_info);
162
163 #ifdef ELF_MACHINE_BEFORE_RTLD_RELOC
164   ELF_MACHINE_BEFORE_RTLD_RELOC (bootstrap_map.l_info);
165 #endif
166
167   /* Relocate ourselves so we can do normal function calls and
168      data access using the global offset table.  */
169
170   ELF_DYNAMIC_RELOCATE (&bootstrap_map, 0, 0);
171   /* Please note that we don't allow profiling of this object and
172      therefore need not test whether we have to allocate the array
173      for the relocation results (as done in dl-reloc.c).  */
174
175   /* Now life is sane; we can call functions and access global data.
176      Set up to use the operating system facilities, and find out from
177      the operating system's program loader where to find the program
178      header table in core.  */
179
180   if (HP_TIMING_AVAIL)
181     {
182       /* If it hasn't happen yet record the startup time.  */
183       if (! HP_TIMING_INLINE)
184         HP_TIMING_NOW (start_time);
185
186       /* Initialize the timing functions.  */
187       HP_TIMING_DIFF_INIT ();
188     }
189
190   /* Transfer data about ourselves to the permanent link_map structure.  */
191   _dl_rtld_map.l_addr = bootstrap_map.l_addr;
192   _dl_rtld_map.l_ld = bootstrap_map.l_ld;
193   _dl_rtld_map.l_opencount = 1;
194   memcpy (_dl_rtld_map.l_info, bootstrap_map.l_info,
195           sizeof _dl_rtld_map.l_info);
196   _dl_setup_hash (&_dl_rtld_map);
197
198 /* Don't bother trying to work out how ld.so is mapped in memory.  */
199   _dl_rtld_map.l_map_start = ~0;
200   _dl_rtld_map.l_map_end = ~0;
201
202   /* Call the OS-dependent function to set up life so we can do things like
203      file access.  It will call `dl_main' (below) to do all the real work
204      of the dynamic linker, and then unwind our frame and run the user
205      entry point on the same stack we entered on.  */
206   start_addr =  _dl_sysdep_start (arg, &dl_main);
207
208   if (HP_TIMING_AVAIL)
209     {
210       hp_timing_t end_time;
211
212       /* Get the current time.  */
213       HP_TIMING_NOW (end_time);
214
215       /* Compute the difference.  */
216       HP_TIMING_DIFF (rtld_total_time, start_time, end_time);
217     }
218
219   if (_dl_debug_statistics)
220     print_statistics ();
221
222   return start_addr;
223 }
224
225 /* Now life is peachy; we can do all normal operations.
226    On to the real work.  */
227
228 void ENTRY_POINT (void);
229
230 /* Some helper functions.  */
231
232 /* Arguments to relocate_doit.  */
233 struct relocate_args
234 {
235   struct link_map *l;
236   int lazy;
237 };
238
239 struct map_args
240 {
241   /* Argument to map_doit.  */
242   char *str;
243   /* Return value of map_doit.  */
244   struct link_map *main_map;
245 };
246
247 /* Arguments to version_check_doit.  */
248 struct version_check_args
249 {
250   int doexit;
251 };
252
253 static void
254 relocate_doit (void *a)
255 {
256   struct relocate_args *args = (struct relocate_args *) a;
257
258   _dl_relocate_object (args->l, args->l->l_scope,
259                        args->lazy, 0);
260 }
261
262 static void
263 map_doit (void *a)
264 {
265   struct map_args *args = (struct map_args *) a;
266   args->main_map = _dl_map_object (NULL, args->str, 0, lt_library, 0);
267 }
268
269 static void
270 version_check_doit (void *a)
271 {
272   struct version_check_args *args = (struct version_check_args *) a;
273   if (_dl_check_all_versions (_dl_loaded, 1) && args->doexit)
274     /* We cannot start the application.  Abort now.  */
275     _exit (1);
276 }
277
278
279 static inline struct link_map *
280 find_needed (const char *name)
281 {
282   unsigned int n = _dl_loaded->l_searchlist.r_nlist;
283
284   while (n-- > 0)
285     if (_dl_name_match_p (name, _dl_loaded->l_searchlist.r_list[n]))
286       return _dl_loaded->l_searchlist.r_list[n];
287
288   /* Should never happen.  */
289   return NULL;
290 }
291
292 static int
293 match_version (const char *string, struct link_map *map)
294 {
295   const char *strtab = (const void *) map->l_info[DT_STRTAB]->d_un.d_ptr;
296   ElfW(Verdef) *def;
297
298 #define VERDEFTAG (DT_NUM + DT_PROCNUM + DT_VERSIONTAGIDX (DT_VERDEF))
299   if (map->l_info[VERDEFTAG] == NULL)
300     /* The file has no symbol versioning.  */
301     return 0;
302
303   def = (ElfW(Verdef) *) ((char *) map->l_addr
304                           + map->l_info[VERDEFTAG]->d_un.d_ptr);
305   while (1)
306     {
307       ElfW(Verdaux) *aux = (ElfW(Verdaux) *) ((char *) def + def->vd_aux);
308
309       /* Compare the version strings.  */
310       if (strcmp (string, strtab + aux->vda_name) == 0)
311         /* Bingo!  */
312         return 1;
313
314       /* If no more definitions we failed to find what we want.  */
315       if (def->vd_next == 0)
316         break;
317
318       /* Next definition.  */
319       def = (ElfW(Verdef) *) ((char *) def + def->vd_next);
320     }
321
322   return 0;
323 }
324
325 static const char *library_path;        /* The library search path.  */
326 static const char *preloadlist;         /* The list preloaded objects.  */
327 static int version_info;                /* Nonzero if information about
328                                            versions has to be printed.  */
329
330 static void
331 dl_main (const ElfW(Phdr) *phdr,
332          ElfW(Half) phent,
333          ElfW(Addr) *user_entry)
334 {
335   const ElfW(Phdr) *ph;
336   enum mode mode;
337   struct link_map **preloads;
338   unsigned int npreloads;
339   size_t file_size;
340   char *file;
341   int has_interp = 0;
342   unsigned int i;
343   int rtld_is_main = 0;
344   hp_timing_t start;
345   hp_timing_t stop;
346   hp_timing_t diff;
347
348   /* Process the environment variable which control the behaviour.  */
349   process_envvars (&mode, &_dl_lazy);
350
351   /* Set up a flag which tells we are just starting.  */
352   _dl_starting_up = 1;
353
354   if (*user_entry == (ElfW(Addr)) &ENTRY_POINT)
355     {
356       /* Ho ho.  We are not the program interpreter!  We are the program
357          itself!  This means someone ran ld.so as a command.  Well, that
358          might be convenient to do sometimes.  We support it by
359          interpreting the args like this:
360
361          ld.so PROGRAM ARGS...
362
363          The first argument is the name of a file containing an ELF
364          executable we will load and run with the following arguments.
365          To simplify life here, PROGRAM is searched for using the
366          normal rules for shared objects, rather than $PATH or anything
367          like that.  We just load it and use its entry point; we don't
368          pay attention to its PT_INTERP command (we are the interpreter
369          ourselves).  This is an easy way to test a new ld.so before
370          installing it.  */
371       rtld_is_main = 1;
372
373       /* Note the place where the dynamic linker actually came from.  */
374       _dl_rtld_map.l_name = _dl_argv[0];
375
376       while (_dl_argc > 1)
377         if (! strcmp (_dl_argv[1], "--list"))
378           {
379             mode = list;
380             _dl_lazy = -1;      /* This means do no dependency analysis.  */
381
382             ++_dl_skip_args;
383             --_dl_argc;
384             ++_dl_argv;
385           }
386         else if (! strcmp (_dl_argv[1], "--verify"))
387           {
388             mode = verify;
389
390             ++_dl_skip_args;
391             --_dl_argc;
392             ++_dl_argv;
393           }
394         else if (! strcmp (_dl_argv[1], "--library-path") && _dl_argc > 2)
395           {
396             library_path = _dl_argv[2];
397
398             _dl_skip_args += 2;
399             _dl_argc -= 2;
400             _dl_argv += 2;
401           }
402         else if (! strcmp (_dl_argv[1], "--inhibit-rpath") && _dl_argc > 2)
403           {
404             _dl_inhibit_rpath = _dl_argv[2];
405
406             _dl_skip_args += 2;
407             _dl_argc -= 2;
408             _dl_argv += 2;
409           }
410         else
411           break;
412
413       /* If we have no further argument the program was called incorrectly.
414          Grant the user some education.  */
415       if (_dl_argc < 2)
416         _dl_sysdep_fatal ("\
417 Usage: ld.so [OPTION]... EXECUTABLE-FILE [ARGS-FOR-PROGRAM...]\n\
418 You have invoked `ld.so', the helper program for shared library executables.\n\
419 This program usually lives in the file `/lib/ld.so', and special directives\n\
420 in executable files using ELF shared libraries tell the system's program\n\
421 loader to load the helper program from this file.  This helper program loads\n\
422 the shared libraries needed by the program executable, prepares the program\n\
423 to run, and runs it.  You may invoke this helper program directly from the\n\
424 command line to load and run an ELF executable file; this is like executing\n\
425 that file itself, but always uses this helper program from the file you\n\
426 specified, instead of the helper program file specified in the executable\n\
427 file you run.  This is mostly of use for maintainers to test new versions\n\
428 of this helper program; chances are you did not intend to run this program.\n\
429 \n\
430   --list                list all dependencies and how they are resolved\n\
431   --verify              verify that given object really is a dynamically linked\n\
432                         object we get handle\n\
433   --library-path PATH   use given PATH instead of content of the environment\n\
434                         variable LD_LIBRARY_PATH\n\
435   --inhibit-rpath LIST  ignore RPATH information in object names in LIST\n",
436                           NULL);
437
438       ++_dl_skip_args;
439       --_dl_argc;
440       ++_dl_argv;
441
442       /* Initialize the data structures for the search paths for shared
443          objects.  */
444       _dl_init_paths (library_path);
445
446       if (__builtin_expect (mode, normal) == verify)
447         {
448           char *err_str = NULL;
449           struct map_args args;
450
451           args.str = _dl_argv[0];
452           (void) _dl_catch_error (&err_str, map_doit, &args);
453           if (err_str != NULL)
454             {
455               free (err_str);
456               _exit (EXIT_FAILURE);
457             }
458         }
459       else
460         {
461           HP_TIMING_NOW (start);
462           _dl_map_object (NULL, _dl_argv[0], 0, lt_library, 0);
463           HP_TIMING_NOW (stop);
464
465           HP_TIMING_DIFF (load_time, start, stop);
466         }
467
468       phdr = _dl_loaded->l_phdr;
469       phent = _dl_loaded->l_phnum;
470       /* We overwrite here a pointer to a malloc()ed string.  But since
471          the malloc() implementation used at this point is the dummy
472          implementations which has no real free() function it does not
473          makes sense to free the old string first.  */
474       _dl_loaded->l_name = (char *) "";
475       *user_entry = _dl_loaded->l_entry;
476     }
477   else
478     {
479       /* Create a link_map for the executable itself.
480          This will be what dlopen on "" returns.  */
481       _dl_new_object ((char *) "", "", lt_executable, NULL);
482       if (_dl_loaded == NULL)
483         _dl_sysdep_fatal ("cannot allocate memory for link map\n", NULL);
484       _dl_loaded->l_phdr = phdr;
485       _dl_loaded->l_phnum = phent;
486       _dl_loaded->l_entry = *user_entry;
487       _dl_loaded->l_opencount = 1;
488
489       /* At this point we are in a bit of trouble.  We would have to
490          fill in the values for l_dev and l_ino.  But in general we
491          do not know where the file is.  We also do not handle AT_EXECFD
492          even if it would be passed up.
493
494          We leave the values here defined to 0.  This is normally no
495          problem as the program code itself is normally no shared
496          object and therefore cannot be loaded dynamically.  Nothing
497          prevent the use of dynamic binaries and in these situations
498          we might get problems.  We might not be able to find out
499          whether the object is already loaded.  But since there is no
500          easy way out and because the dynamic binary must also not
501          have an SONAME we ignore this program for now.  If it becomes
502          a problem we can force people using SONAMEs.  */
503
504       /* We delay initializing the path structure until we got the dynamic
505          information for the program.  */
506     }
507
508   /* It is not safe to load stuff after the main program.  */
509   _dl_loaded->l_map_end = ~0;
510   /* Perhaps the executable has no PT_LOAD header entries at all.  */
511   _dl_loaded->l_map_start = ~0;
512
513   /* Scan the program header table for the dynamic section.  */
514   for (ph = phdr; ph < &phdr[phent]; ++ph)
515     switch (ph->p_type)
516       {
517       case PT_PHDR:
518         /* Find out the load address.  */
519         _dl_loaded->l_addr = (ElfW(Addr)) phdr - ph->p_vaddr;
520         break;
521       case PT_DYNAMIC:
522         /* This tells us where to find the dynamic section,
523            which tells us everything we need to do.  */
524         _dl_loaded->l_ld = (void *) _dl_loaded->l_addr + ph->p_vaddr;
525         break;
526       case PT_INTERP:
527         /* This "interpreter segment" was used by the program loader to
528            find the program interpreter, which is this program itself, the
529            dynamic linker.  We note what name finds us, so that a future
530            dlopen call or DT_NEEDED entry, for something that wants to link
531            against the dynamic linker as a shared library, will know that
532            the shared object is already loaded.  */
533         _dl_rtld_libname.name = ((const char *) _dl_loaded->l_addr
534                                  + ph->p_vaddr);
535         _dl_rtld_libname.next = NULL;
536         _dl_rtld_map.l_libname = &_dl_rtld_libname;
537
538         /* Ordinarilly, we would get additional names for the loader from
539            our DT_SONAME.  This can't happen if we were actually linked as
540            a static executable (detect this case when we have no DYNAMIC).
541            If so, assume the filename component of the interpreter path to
542            be our SONAME, and add it to our name list.  */
543         if (_dl_rtld_map.l_ld == NULL)
544           {
545             char *p = strrchr (_dl_rtld_libname.name, '/');
546             if (p)
547               {
548                 _dl_rtld_libname2.name = p+1;
549                 _dl_rtld_libname2.next = NULL;
550                 _dl_rtld_libname.next = &_dl_rtld_libname2;
551               }
552           }
553
554         has_interp = 1;
555         break;
556       case PT_LOAD:
557         /* Remember where the main program starts in memory.  */
558         {
559           ElfW(Addr) mapstart;
560           mapstart = _dl_loaded->l_addr + (ph->p_vaddr & ~(ph->p_align - 1));
561           if (_dl_loaded->l_map_start > mapstart)
562             _dl_loaded->l_map_start = mapstart;
563         }
564         break;
565       }
566   if (! _dl_rtld_map.l_libname && _dl_rtld_map.l_name)
567     {
568       /* We were invoked directly, so the program might not have a
569          PT_INTERP.  */
570       _dl_rtld_libname.name = _dl_rtld_map.l_name;
571       _dl_rtld_libname.next = NULL;
572       _dl_rtld_map.l_libname =  &_dl_rtld_libname;
573     }
574   else
575     assert (_dl_rtld_map.l_libname); /* How else did we get here?  */
576
577   if (! rtld_is_main)
578     {
579       /* Extract the contents of the dynamic section for easy access.  */
580       elf_get_dynamic_info (_dl_loaded->l_ld, _dl_loaded->l_addr,
581                             _dl_loaded->l_info);
582       if (_dl_loaded->l_info[DT_HASH])
583         /* Set up our cache of pointers into the hash table.  */
584         _dl_setup_hash (_dl_loaded);
585     }
586
587   if (__builtin_expect (mode, normal) == verify)
588     {
589       /* We were called just to verify that this is a dynamic
590          executable using us as the program interpreter.  Exit with an
591          error if we were not able to load the binary or no interpreter
592          is specified (i.e., this is no dynamically linked binary.  */
593       if (_dl_loaded->l_ld == NULL)
594         _exit (1);
595
596       /* We allow here some platform specific code.  */
597 #ifdef DISTINGUISH_LIB_VERSIONS
598       DISTINGUISH_LIB_VERSIONS;
599 #endif
600       _exit (has_interp ? 0 : 2);
601     }
602
603   if (! rtld_is_main)
604     /* Initialize the data structures for the search paths for shared
605        objects.  */
606     _dl_init_paths (library_path);
607
608   /* Put the link_map for ourselves on the chain so it can be found by
609      name.  Note that at this point the global chain of link maps contains
610      exactly one element, which is pointed to by _dl_loaded.  */
611   if (! _dl_rtld_map.l_name)
612     /* If not invoked directly, the dynamic linker shared object file was
613        found by the PT_INTERP name.  */
614     _dl_rtld_map.l_name = (char *) _dl_rtld_map.l_libname->name;
615   _dl_rtld_map.l_type = lt_library;
616   _dl_loaded->l_next = &_dl_rtld_map;
617   _dl_rtld_map.l_prev = _dl_loaded;
618
619   /* We have two ways to specify objects to preload: via environment
620      variable and via the file /etc/ld.so.preload.  The later can also
621      be used when security is enabled.  */
622   preloads = NULL;
623   npreloads = 0;
624
625   if (preloadlist)
626     {
627       /* The LD_PRELOAD environment variable gives list of libraries
628          separated by white space or colons that are loaded before the
629          executable's dependencies and prepended to the global scope
630          list.  If the binary is running setuid all elements
631          containing a '/' are ignored since it is insecure.  */
632       char *list = strdupa (preloadlist);
633       char *p;
634
635       HP_TIMING_NOW (start);
636
637       while ((p = strsep (&list, " :")) != NULL)
638         if (p[0] != '\0'
639             && (! __libc_enable_secure || strchr (p, '/') == NULL))
640           {
641             struct link_map *new_map = _dl_map_object (_dl_loaded, p, 1,
642                                                        lt_library, 0);
643             if (new_map->l_opencount == 1)
644               /* It is no duplicate.  */
645               ++npreloads;
646           }
647
648       HP_TIMING_NOW (stop);
649       HP_TIMING_DIFF (diff, start, stop);
650       HP_TIMING_ACCUM_NT (load_time, diff);
651     }
652
653   /* Read the contents of the file.  */
654   file = _dl_sysdep_read_whole_file ("/etc/ld.so.preload", &file_size,
655                                      PROT_READ | PROT_WRITE);
656   if (file)
657     {
658       /* Parse the file.  It contains names of libraries to be loaded,
659          separated by white spaces or `:'.  It may also contain
660          comments introduced by `#'.  */
661       char *problem;
662       char *runp;
663       size_t rest;
664
665       /* Eliminate comments.  */
666       runp = file;
667       rest = file_size;
668       while (rest > 0)
669         {
670           char *comment = memchr (runp, '#', rest);
671           if (comment == NULL)
672             break;
673
674           rest -= comment - runp;
675           do
676             *comment = ' ';
677           while (--rest > 0 && *++comment != '\n');
678         }
679
680       /* We have one problematic case: if we have a name at the end of
681          the file without a trailing terminating characters, we cannot
682          place the \0.  Handle the case separately.  */
683       if (file[file_size - 1] != ' ' && file[file_size - 1] != '\t'
684           && file[file_size - 1] != '\n' && file[file_size - 1] != ':')
685         {
686           problem = &file[file_size];
687           while (problem > file && problem[-1] != ' ' && problem[-1] != '\t'
688                  && problem[-1] != '\n' && problem[-1] != ':')
689             --problem;
690
691           if (problem > file)
692             problem[-1] = '\0';
693         }
694       else
695         {
696           problem = NULL;
697           file[file_size - 1] = '\0';
698         }
699
700       HP_TIMING_NOW (start);
701
702       if (file != problem)
703         {
704           char *p;
705           runp = file;
706           while ((p = strsep (&runp, ": \t\n")) != NULL)
707             if (p[0] != '\0')
708               {
709                 struct link_map *new_map = _dl_map_object (_dl_loaded, p, 1,
710                                                            lt_library, 0);
711                 if (new_map->l_opencount == 1)
712                   /* It is no duplicate.  */
713                   ++npreloads;
714               }
715         }
716
717       if (problem != NULL)
718         {
719           char *p = strndupa (problem, file_size - (problem - file));
720           struct link_map *new_map = _dl_map_object (_dl_loaded, p, 1,
721                                                      lt_library, 0);
722           if (new_map->l_opencount == 1)
723             /* It is no duplicate.  */
724             ++npreloads;
725         }
726
727       HP_TIMING_NOW (stop);
728       HP_TIMING_DIFF (diff, start, stop);
729       HP_TIMING_ACCUM_NT (load_time, diff);
730
731       /* We don't need the file anymore.  */
732       __munmap (file, file_size);
733     }
734
735   if (npreloads != 0)
736     {
737       /* Set up PRELOADS with a vector of the preloaded libraries.  */
738       struct link_map *l;
739       preloads = __alloca (npreloads * sizeof preloads[0]);
740       l = _dl_rtld_map.l_next; /* End of the chain before preloads.  */
741       i = 0;
742       do
743         {
744           preloads[i++] = l;
745           l = l->l_next;
746         } while (l);
747       assert (i == npreloads);
748     }
749
750   /* Load all the libraries specified by DT_NEEDED entries.  If LD_PRELOAD
751      specified some libraries to load, these are inserted before the actual
752      dependencies in the executable's searchlist for symbol resolution.  */
753   HP_TIMING_NOW (start);
754   _dl_map_object_deps (_dl_loaded, preloads, npreloads, mode == trace, 0);
755   HP_TIMING_NOW (stop);
756   HP_TIMING_DIFF (diff, start, stop);
757   HP_TIMING_ACCUM_NT (load_time, diff);
758
759   /* Mark all objects as being in the global scope.  */
760   for (i = _dl_loaded->l_searchlist.r_nlist; i > 0; )
761     _dl_loaded->l_searchlist.r_list[--i]->l_global = 1;
762
763 #ifndef MAP_ANON
764   /* We are done mapping things, so close the zero-fill descriptor.  */
765   __close (_dl_zerofd);
766   _dl_zerofd = -1;
767 #endif
768
769   /* Remove _dl_rtld_map from the chain.  */
770   _dl_rtld_map.l_prev->l_next = _dl_rtld_map.l_next;
771   if (_dl_rtld_map.l_next)
772     _dl_rtld_map.l_next->l_prev = _dl_rtld_map.l_prev;
773
774   if (__builtin_expect (_dl_rtld_map.l_opencount, 2) > 1)
775     {
776       /* Some DT_NEEDED entry referred to the interpreter object itself, so
777          put it back in the list of visible objects.  We insert it into the
778          chain in symbol search order because gdb uses the chain's order as
779          its symbol search order.  */
780       i = 1;
781       while (_dl_loaded->l_searchlist.r_list[i] != &_dl_rtld_map)
782         ++i;
783       _dl_rtld_map.l_prev = _dl_loaded->l_searchlist.r_list[i - 1];
784       _dl_rtld_map.l_next = (i + 1 < _dl_loaded->l_searchlist.r_nlist
785                              ? _dl_loaded->l_searchlist.r_list[i + 1]
786                              : NULL);
787       assert (_dl_rtld_map.l_prev->l_next == _dl_rtld_map.l_next);
788       _dl_rtld_map.l_prev->l_next = &_dl_rtld_map;
789       if (_dl_rtld_map.l_next)
790         {
791           assert (_dl_rtld_map.l_next->l_prev == _dl_rtld_map.l_prev);
792           _dl_rtld_map.l_next->l_prev = &_dl_rtld_map;
793         }
794     }
795
796   /* Now let us see whether all libraries are available in the
797      versions we need.  */
798   {
799     struct version_check_args args;
800     args.doexit = mode == normal;
801     _dl_receive_error (print_missing_version, version_check_doit, &args);
802   }
803
804   if (__builtin_expect (mode, normal) != normal)
805     {
806       /* We were run just to list the shared libraries.  It is
807          important that we do this before real relocation, because the
808          functions we call below for output may no longer work properly
809          after relocation.  */
810       if (! _dl_loaded->l_info[DT_NEEDED])
811         _dl_sysdep_message ("\t", "statically linked\n", NULL);
812       else
813         {
814           struct link_map *l;
815
816           for (l = _dl_loaded->l_next; l; l = l->l_next)
817             if (l->l_opencount == 0)
818               /* The library was not found.  */
819               _dl_sysdep_message ("\t", l->l_libname->name, " => not found\n",
820                                   NULL);
821             else
822               {
823                 char buf[20], *bp;
824                 buf[sizeof buf - 1] = '\0';
825                 bp = _itoa_word (l->l_addr, &buf[sizeof buf - 1], 16, 0);
826                 while ((size_t) (&buf[sizeof buf - 1] - bp)
827                        < sizeof l->l_addr * 2)
828                   *--bp = '0';
829                 _dl_sysdep_message ("\t", l->l_libname->name, " => ",
830                                     l->l_name, " (0x", bp, ")\n", NULL);
831               }
832         }
833
834       if (__builtin_expect (mode, trace) != trace)
835         for (i = 1; i < _dl_argc; ++i)
836           {
837             const ElfW(Sym) *ref = NULL;
838             ElfW(Addr) loadbase = _dl_lookup_symbol (_dl_argv[i], &ref,
839                                                      _dl_loaded->l_scope,
840                                                      "argument",
841                                                      ELF_MACHINE_JMP_SLOT);
842             char buf[20], *bp;
843             buf[sizeof buf - 1] = '\0';
844             bp = _itoa_word (ref->st_value, &buf[sizeof buf - 1], 16, 0);
845             while ((size_t) (&buf[sizeof buf - 1] - bp) < sizeof loadbase * 2)
846               *--bp = '0';
847             _dl_sysdep_message (_dl_argv[i], " found at 0x", bp, NULL);
848             buf[sizeof buf - 1] = '\0';
849             bp = _itoa_word (loadbase, &buf[sizeof buf - 1], 16, 0);
850             while ((size_t) (&buf[sizeof buf - 1] - bp) < sizeof loadbase * 2)
851               *--bp = '0';
852             _dl_sysdep_message (" in object at 0x", bp, "\n", NULL);
853           }
854       else
855         {
856           if (_dl_lazy >= 0)
857             {
858               /* We have to do symbol dependency testing.  */
859               struct relocate_args args;
860               struct link_map *l;
861
862               args.lazy = _dl_lazy;
863
864               l = _dl_loaded;
865               while (l->l_next)
866                 l = l->l_next;
867               do
868                 {
869                   if (l != &_dl_rtld_map && l->l_opencount > 0)
870                     {
871                       args.l = l;
872                       _dl_receive_error (print_unresolved, relocate_doit,
873                                          &args);
874                     }
875                   l = l->l_prev;
876                 } while (l);
877             }
878
879 #define VERNEEDTAG (DT_NUM + DT_PROCNUM + DT_VERSIONTAGIDX (DT_VERNEED))
880           if (version_info)
881             {
882               /* Print more information.  This means here, print information
883                  about the versions needed.  */
884               int first = 1;
885               struct link_map *map = _dl_loaded;
886
887               for (map = _dl_loaded; map != NULL; map = map->l_next)
888                 {
889                   const char *strtab;
890                   ElfW(Dyn) *dyn = map->l_info[VERNEEDTAG];
891                   ElfW(Verneed) *ent;
892
893                   if (dyn == NULL)
894                     continue;
895
896                   strtab = (const void *) map->l_info[DT_STRTAB]->d_un.d_ptr;
897                   ent = (ElfW(Verneed) *) (map->l_addr + dyn->d_un.d_ptr);
898
899                   if (first)
900                     {
901                       _dl_sysdep_message ("\n\tVersion information:\n", NULL);
902                       first = 0;
903                     }
904
905                   _dl_sysdep_message ("\t", (map->l_name[0]
906                                              ? map->l_name : _dl_argv[0]),
907                                       ":\n", NULL);
908
909                   while (1)
910                     {
911                       ElfW(Vernaux) *aux;
912                       struct link_map *needed;
913
914                       needed = find_needed (strtab + ent->vn_file);
915                       aux = (ElfW(Vernaux) *) ((char *) ent + ent->vn_aux);
916
917                       while (1)
918                         {
919                           const char *fname = NULL;
920
921                           _dl_sysdep_message ("\t\t",
922                                               strtab + ent->vn_file,
923                                               " (", strtab + aux->vna_name,
924                                               ") ",
925                                               (aux->vna_flags
926                                                & VER_FLG_WEAK
927                                                ? "[WEAK] " : ""),
928                                               "=> ", NULL);
929
930                           if (needed != NULL
931                               && match_version (strtab+aux->vna_name, needed))
932                             fname = needed->l_name;
933
934                           _dl_sysdep_message (fname ?: "not found", "\n",
935                                               NULL);
936
937                           if (aux->vna_next == 0)
938                             /* No more symbols.  */
939                             break;
940
941                           /* Next symbol.  */
942                           aux = (ElfW(Vernaux) *) ((char *) aux
943                                                    + aux->vna_next);
944                         }
945
946                       if (ent->vn_next == 0)
947                         /* No more dependencies.  */
948                         break;
949
950                       /* Next dependency.  */
951                       ent = (ElfW(Verneed) *) ((char *) ent + ent->vn_next);
952                     }
953                 }
954             }
955         }
956
957       _exit (0);
958     }
959
960   {
961     /* Now we have all the objects loaded.  Relocate them all except for
962        the dynamic linker itself.  We do this in reverse order so that copy
963        relocs of earlier objects overwrite the data written by later
964        objects.  We do not re-relocate the dynamic linker itself in this
965        loop because that could result in the GOT entries for functions we
966        call being changed, and that would break us.  It is safe to relocate
967        the dynamic linker out of order because it has no copy relocs (we
968        know that because it is self-contained).  */
969
970     struct link_map *l;
971     int consider_profiling = _dl_profile != NULL;
972     hp_timing_t start;
973     hp_timing_t stop;
974     hp_timing_t add;
975
976     /* If we are profiling we also must do lazy reloaction.  */
977     _dl_lazy |= consider_profiling;
978
979     l = _dl_loaded;
980     while (l->l_next)
981       l = l->l_next;
982
983     HP_TIMING_NOW (start);
984     do
985       {
986         if (l != &_dl_rtld_map)
987           _dl_relocate_object (l, l->l_scope, _dl_lazy, consider_profiling);
988
989         l = l->l_prev;
990       }
991     while (l);
992     HP_TIMING_NOW (stop);
993
994     HP_TIMING_DIFF (relocate_time, start, stop);
995
996     /* Do any necessary cleanups for the startup OS interface code.
997        We do these now so that no calls are made after rtld re-relocation
998        which might be resolved to different functions than we expect.
999        We cannot do this before relocating the other objects because
1000        _dl_relocate_object might need to call `mprotect' for DT_TEXTREL.  */
1001     _dl_sysdep_start_cleanup ();
1002
1003     if (_dl_rtld_map.l_opencount > 0)
1004       {
1005         /* There was an explicit ref to the dynamic linker as a shared lib.
1006            Re-relocate ourselves with user-controlled symbol definitions.  */
1007         HP_TIMING_NOW (start);
1008         _dl_relocate_object (&_dl_rtld_map, _dl_loaded->l_scope, 0, 0);
1009         HP_TIMING_NOW (stop);
1010         HP_TIMING_DIFF (add, start, stop);
1011         HP_TIMING_ACCUM_NT (relocate_time, add);
1012       }
1013   }
1014
1015   /* Now set up the variable which helps the assembler startup code.  */
1016   _dl_main_searchlist = &_dl_loaded->l_searchlist;
1017   _dl_global_scope[0] = &_dl_loaded->l_searchlist;
1018
1019   /* Safe the information about the original global scope list since
1020      we need it in the memory handling later.  */
1021   _dl_initial_searchlist = *_dl_main_searchlist;
1022
1023   {
1024     /* Initialize _r_debug.  */
1025     struct r_debug *r = _dl_debug_initialize (_dl_rtld_map.l_addr);
1026     struct link_map *l;
1027
1028     l = _dl_loaded;
1029
1030 #ifdef ELF_MACHINE_DEBUG_SETUP
1031
1032     /* Some machines (e.g. MIPS) don't use DT_DEBUG in this way.  */
1033
1034     ELF_MACHINE_DEBUG_SETUP (l, r);
1035     ELF_MACHINE_DEBUG_SETUP (&_dl_rtld_map, r);
1036
1037 #else
1038
1039     if (l->l_info[DT_DEBUG])
1040       /* There is a DT_DEBUG entry in the dynamic section.  Fill it in
1041          with the run-time address of the r_debug structure  */
1042       l->l_info[DT_DEBUG]->d_un.d_ptr = (ElfW(Addr)) r;
1043
1044     /* Fill in the pointer in the dynamic linker's own dynamic section, in
1045        case you run gdb on the dynamic linker directly.  */
1046     if (_dl_rtld_map.l_info[DT_DEBUG])
1047       _dl_rtld_map.l_info[DT_DEBUG]->d_un.d_ptr = (ElfW(Addr)) r;
1048
1049 #endif
1050
1051     /* Notify the debugger that all objects are now mapped in.  */
1052     r->r_state = RT_ADD;
1053     _dl_debug_state ();
1054   }
1055
1056 #ifndef MAP_COPY
1057   /* We must munmap() the cache file.  */
1058   _dl_unload_cache ();
1059 #endif
1060
1061   /* Now enable profiling if needed.  */
1062   if (_dl_profile_map != NULL)
1063     /* We must prepare the profiling.  */
1064     _dl_start_profile (_dl_profile_map, _dl_profile_output);
1065
1066   /* Once we return, _dl_sysdep_start will invoke
1067      the DT_INIT functions and then *USER_ENTRY.  */
1068 }
1069 \f
1070 /* This is a little helper function for resolving symbols while
1071    tracing the binary.  */
1072 static void
1073 print_unresolved (int errcode __attribute__ ((unused)), const char *objname,
1074                   const char *errstring)
1075 {
1076   if (objname[0] == '\0')
1077     objname = _dl_argv[0] ?: "<main program>";
1078   _dl_sysdep_error (errstring, "        (", objname, ")\n", NULL);
1079 }
1080 \f
1081 /* This is a little helper function for resolving symbols while
1082    tracing the binary.  */
1083 static void
1084 print_missing_version (int errcode __attribute__ ((unused)),
1085                        const char *objname, const char *errstring)
1086 {
1087   _dl_sysdep_error (_dl_argv[0] ?: "<program name unknown>", ": ",
1088                     objname, ": ", errstring, "\n", NULL);
1089 }
1090 \f
1091 /* Nonzero if any of the debugging options is enabled.  */
1092 static int any_debug;
1093
1094 /* Process the string given as the parameter which explains which debugging
1095    options are enabled.  */
1096 static void
1097 process_dl_debug (const char *dl_debug)
1098 {
1099   size_t len;
1100 #define separators " ,:"
1101   do
1102     {
1103       len = 0;
1104       /* Skip separating white spaces and commas.  */
1105       dl_debug += strspn (dl_debug, separators);
1106       if (*dl_debug != '\0')
1107         {
1108           len = strcspn (dl_debug, separators);
1109
1110           switch (len)
1111             {
1112             case 3:
1113               /* This option is not documented since it is not generally
1114                  useful.  */
1115               if (memcmp (dl_debug, "all", 3) == 0)
1116                 {
1117                   _dl_debug_libs = 1;
1118                   _dl_debug_impcalls = 1;
1119                   _dl_debug_reloc = 1;
1120                   _dl_debug_files = 1;
1121                   _dl_debug_symbols = 1;
1122                   _dl_debug_bindings = 1;
1123                   _dl_debug_versions = 1;
1124                   any_debug = 1;
1125                   continue;
1126                 }
1127               break;
1128
1129             case 4:
1130               if (memcmp (dl_debug, "help", 4) == 0)
1131                 {
1132                   _dl_sysdep_message ("\
1133 Valid options for the LD_DEBUG environment variable are:\n\
1134 \n\
1135   bindings  display information about symbol binding\n\
1136   files     display processing of files and libraries\n\
1137   help      display this help message and exit\n\
1138   libs      display library search paths\n\
1139   reloc     display relocation processing\n\
1140   symbols   display symbol table processing\n\
1141   versions  display version dependencies\n\
1142 \n\
1143 To direct the debugging output into a file instead of standard output\n\
1144 a filename can be specified using the LD_DEBUG_OUTPUT environment variable.\n",
1145                                   NULL);
1146                   _exit (0);
1147                 }
1148
1149               if (memcmp (dl_debug, "libs", 4) == 0)
1150                 {
1151                   _dl_debug_libs = 1;
1152                   _dl_debug_impcalls = 1;
1153                   any_debug = 1;
1154                   continue;
1155                 }
1156               break;
1157
1158             case 5:
1159               if (memcmp (dl_debug, "reloc", 5) == 0)
1160                 {
1161                   _dl_debug_reloc = 1;
1162                   _dl_debug_impcalls = 1;
1163                   any_debug = 1;
1164                   continue;
1165                 }
1166
1167               if (memcmp (dl_debug, "files", 5) == 0)
1168                 {
1169                   _dl_debug_files = 1;
1170                   _dl_debug_impcalls = 1;
1171                   any_debug = 1;
1172                   continue;
1173                 }
1174               break;
1175
1176             case 7:
1177               if (memcmp (dl_debug, "symbols", 7) == 0)
1178                 {
1179                   _dl_debug_symbols = 1;
1180                   _dl_debug_impcalls = 1;
1181                   any_debug = 1;
1182                   continue;
1183                 }
1184               break;
1185
1186             case 8:
1187               if (memcmp (dl_debug, "bindings", 8) == 0)
1188                 {
1189                   _dl_debug_bindings = 1;
1190                   _dl_debug_impcalls = 1;
1191                   any_debug = 1;
1192                   continue;
1193                 }
1194
1195               if (memcmp (dl_debug, "versions", 8) == 0)
1196                 {
1197                   _dl_debug_versions = 1;
1198                   _dl_debug_impcalls = 1;
1199                   any_debug = 1;
1200                   continue;
1201                 }
1202               break;
1203
1204             case 10:
1205               if (memcmp (dl_debug, "statistics", 10) == 0)
1206                 {
1207                   _dl_debug_statistics = 1;
1208                   continue;
1209                 }
1210               break;
1211
1212             default:
1213               break;
1214             }
1215
1216           {
1217             /* Display a warning and skip everything until next separator.  */
1218             char *startp = strndupa (dl_debug, len);
1219             _dl_sysdep_error ("warning: debug option `", startp,
1220                               "' unknown; try LD_DEBUG=help\n", NULL);
1221             break;
1222           }
1223         }
1224     }
1225   while (*(dl_debug += len) != '\0');
1226 }
1227 \f
1228 /* Process all environments variables the dynamic linker must recognize.
1229    Since all of them start with `LD_' we are a bit smarter while finding
1230    all the entries.  */
1231 static void
1232 process_envvars (enum mode *modep, int *lazyp)
1233 {
1234   char **runp = NULL;
1235   char *envline;
1236   enum mode mode = normal;
1237   int bind_now = 0;
1238   char *debug_output = NULL;
1239
1240   /* This is the default place for profiling data file.  */
1241   _dl_profile_output = "/var/tmp";
1242
1243   while ((envline = _dl_next_ld_env_entry (&runp)) != NULL)
1244     {
1245       size_t len = strcspn (envline, "=") - 3;
1246
1247       switch (len)
1248         {
1249         case 4:
1250           /* Warning level, verbose or not.  */
1251           if (memcmp (&envline[3], "WARN", 4) == 0)
1252             _dl_verbose = envline[8] != '\0';
1253           break;
1254
1255         case 5:
1256           /* Debugging of the dynamic linker?  */
1257           if (memcmp (&envline[3], "DEBUG", 5) == 0)
1258             process_dl_debug (&envline[9]);
1259           break;
1260
1261         case 7:
1262           /* Print information about versions.  */
1263           if (memcmp (&envline[3], "VERBOSE", 7) == 0)
1264             {
1265               version_info = envline[11] != '\0';
1266               break;
1267             }
1268
1269           /* List of objects to be preloaded.  */
1270           if (memcmp (&envline[3], "PRELOAD", 7) == 0)
1271             {
1272               preloadlist = &envline[11];
1273               break;
1274             }
1275
1276           /* Which shared object shall be profiled.  */
1277           if (memcmp (&envline[3], "PROFILE", 7) == 0)
1278             {
1279               _dl_profile = &envline[11];
1280               if (*_dl_profile == '\0')
1281                 _dl_profile = NULL;
1282             }
1283           break;
1284
1285         case 8:
1286           /* Do we bind early?  */
1287           if (memcmp (&envline[3], "BIND_NOW", 8) == 0)
1288             bind_now = envline[12] != '\0';
1289           break;
1290
1291         case 9:
1292           /* Test whether we want to see the content of the auxiliary
1293              array passed up from the kernel.  */
1294           if (memcmp (&envline[3], "SHOW_AUXV", 9) == 0)
1295             _dl_show_auxv ();
1296           break;
1297
1298         case 10:
1299           /* Mask for the important hardware capabilities.  */
1300           if (memcmp (&envline[3], "HWCAP_MASK", 10) == 0)
1301             _dl_hwcap_mask = strtoul (&envline[14], NULL, 0);
1302           break;
1303
1304         case 11:
1305           /* Path where the binary is found.  */
1306           if (!__libc_enable_secure
1307               && memcmp (&envline[3], "ORIGIN_PATH", 11) == 0)
1308             _dl_origin_path = &envline[15];
1309           break;
1310
1311         case 12:
1312           /* Where to place the profiling data file.  */
1313           if (memcmp (&envline[3], "DEBUG_OUTPUT", 12) == 0)
1314             {
1315               debug_output = &envline[16];
1316               break;
1317             }
1318
1319           /* The library search path.  */
1320           if (memcmp (&envline[3], "LIBRARY_PATH", 12) == 0)
1321             library_path = &envline[16];
1322           break;
1323
1324         case 14:
1325           /* Where to place the profiling data file.  */
1326           if (!__libc_enable_secure
1327               && memcmp (&envline[3], "PROFILE_OUTPUT", 14) == 0)
1328             {
1329               _dl_profile_output = &envline[18];
1330               if (*_dl_profile_output == '\0')
1331                 _dl_profile_output = "/var/tmp";
1332             }
1333           break;
1334
1335         case 20:
1336           /* The mode of the dynamic linker can be set.  */
1337           if (memcmp (&envline[3], "TRACE_LOADED_OBJECTS", 20) == 0)
1338             mode = trace;
1339           break;
1340
1341           /* We might have some extra environment variable to handle.  This
1342              is tricky due to the pre-processing of the length of the name
1343              in the switch statement here.  The code here assumes that added
1344              environment variables have a different length.  */
1345 #ifdef EXTRA_LD_ENVVARS
1346           EXTRA_LD_ENVVARS
1347 #endif
1348         }
1349     }
1350
1351   /* Extra security for SUID binaries.  Remove all dangerous environment
1352      variables.  */
1353   if (__libc_enable_secure)
1354     {
1355       static const char *unsecure_envvars[] =
1356       {
1357 #ifdef EXTRA_UNSECURE_ENVVARS
1358         EXTRA_UNSECURE_ENVVARS
1359 #endif
1360       };
1361       size_t cnt;
1362
1363       if (preloadlist != NULL)
1364         unsetenv ("LD_PRELOAD");
1365       if (library_path != NULL)
1366         unsetenv ("LD_LIBRARY_PATH");
1367
1368       for (cnt = 0;
1369            cnt < sizeof (unsecure_envvars) / sizeof (unsecure_envvars[0]);
1370            ++cnt)
1371         unsetenv (unsecure_envvars[cnt]);
1372     }
1373
1374   /* If we have to run the dynamic linker in debugging mode and the
1375      LD_DEBUG_OUTPUT environment variable is given, we write the debug
1376      messages to this file.  */
1377   if (any_debug && debug_output != NULL && !__libc_enable_secure)
1378     {
1379       size_t name_len = strlen (debug_output);
1380       char buf[name_len + 12];
1381       char *startp;
1382
1383       buf[name_len + 11] = '\0';
1384       startp = _itoa_word (__getpid (), &buf[name_len + 11], 10, 0);
1385       *--startp = '.';
1386       startp = memcpy (startp - name_len, debug_output, name_len);
1387
1388       _dl_debug_fd = __open (startp, O_WRONLY | O_APPEND | O_CREAT, 0666);
1389       if (_dl_debug_fd == -1)
1390         /* We use standard output if opening the file failed.  */
1391         _dl_debug_fd = STDOUT_FILENO;
1392     }
1393
1394   /* LAZY is determined by the environment variable LD_WARN and
1395      LD_BIND_NOW if we trace the binary.  */
1396   if (__builtin_expect (mode, normal) == trace)
1397     *lazyp = _dl_verbose ? !bind_now : -1;
1398   else
1399     *lazyp = !bind_now;
1400
1401   *modep = mode;
1402 }
1403
1404
1405 /* Print the various times we collected.  */
1406 static void
1407 print_statistics (void)
1408 {
1409   char buf[200];
1410   char *cp;
1411   char *wp;
1412
1413   /* Total time rtld used.  */
1414   if (HP_TIMING_AVAIL)
1415     {
1416       HP_TIMING_PRINT (buf, sizeof (buf), rtld_total_time);
1417       _dl_debug_message (1, "\nruntime linker statistics:\n"
1418                          "  total startup time in dynamic loader: ",
1419                          buf, "\n", NULL);
1420     }
1421
1422   /* Print relocation statistics.  */
1423   if (HP_TIMING_AVAIL)
1424     {
1425       HP_TIMING_PRINT (buf, sizeof (buf), relocate_time);
1426       _dl_debug_message (1, "            time needed for relocation: ", buf,
1427                          NULL);
1428       cp = _itoa_word ((1000 * relocate_time) / rtld_total_time,
1429                        buf + sizeof (buf), 10, 0);
1430       wp = buf;
1431       switch (buf + sizeof (buf) - cp)
1432         {
1433         case 3:
1434           *wp++ = *cp++;
1435         case 2:
1436           *wp++ = *cp++;
1437         case 1:
1438           *wp++ = '.';
1439           *wp++ = *cp++;
1440         }
1441       *wp = '\0';
1442       _dl_debug_message (0, " (", buf, "%)\n", NULL);
1443     }
1444
1445   buf[sizeof (buf) - 1] = '\0';
1446   _dl_debug_message (1, "                 number of relocations: ",
1447                      _itoa_word (_dl_num_relocations,
1448                                  buf + sizeof (buf) - 1, 10, 0),
1449                      "\n", NULL);
1450
1451   /* Time spend while loading the object and the dependencies.  */
1452   if (HP_TIMING_AVAIL)
1453     {
1454       HP_TIMING_PRINT (buf, sizeof (buf), load_time);
1455       _dl_debug_message (1, "           time needed to load objects: ", buf,
1456                          NULL);
1457       cp = _itoa_word ((1000 * load_time) / rtld_total_time,
1458                        buf + sizeof (buf), 10, 0);
1459       wp = buf;
1460       switch (buf + sizeof (buf) - cp)
1461         {
1462         case 3:
1463           *wp++ = *cp++;
1464         case 2:
1465           *wp++ = *cp++;
1466         case 1:
1467           *wp++ = '.';
1468           *wp++ = *cp++;
1469         }
1470       *wp = '\0';
1471       _dl_debug_message (0, " (", buf, "%)\n", NULL);
1472     }
1473 }