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