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