* sysdeps/m68k/dl-machine.h (elf_machine_runtime_setup): Make
[glibc/pb-stable.git] / elf / rtld.c
blobb8e7f9af6ba18867d652fbaf893787c437e149b5
1 /* Run time dynamic linker.
2 Copyright (C) 1995-1999, 2000, 2001, 2002 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, write to the Free
17 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18 02111-1307 USA. */
20 #include <errno.h>
21 #include <fcntl.h>
22 #include <stdbool.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <unistd.h>
26 #include <sys/mman.h> /* Check if MAP_ANON is defined. */
27 #include <sys/param.h>
28 #include <sys/stat.h>
29 #include <ldsodefs.h>
30 #include <stdio-common/_itoa.h>
31 #include <entry.h>
32 #include <fpu_control.h>
33 #include <hp-timing.h>
34 #include <bits/libc-lock.h>
35 #include "dynamic-link.h"
36 #include "dl-librecon.h"
37 #include <unsecvars.h>
38 #include <dl-cache.h>
39 #include <dl-procinfo.h>
40 #include <tls.h>
42 #include <assert.h>
44 /* Avoid PLT use for our local calls at startup. */
45 extern __typeof (__mempcpy) __mempcpy attribute_hidden;
47 /* GCC has mental blocks about _exit. */
48 extern __typeof (_exit) exit_internal asm ("_exit") attribute_hidden;
49 #define _exit exit_internal
51 /* Helper function to handle errors while resolving symbols. */
52 static void print_unresolved (int errcode, const char *objname,
53 const char *errsting);
55 /* Helper function to handle errors when a version is missing. */
56 static void print_missing_version (int errcode, const char *objname,
57 const char *errsting);
59 /* Print the various times we collected. */
60 static void print_statistics (void);
62 /* This is a list of all the modes the dynamic loader can be in. */
63 enum mode { normal, list, verify, trace };
65 /* Process all environments variables the dynamic linker must recognize.
66 Since all of them start with `LD_' we are a bit smarter while finding
67 all the entries. */
68 static void process_envvars (enum mode *modep);
70 int _dl_argc attribute_hidden;
71 char **_dl_argv = NULL;
72 INTDEF(_dl_argv)
74 /* Nonzero if we were run directly. */
75 unsigned int _dl_skip_args attribute_hidden;
77 /* Set nonzero during loading and initialization of executable and
78 libraries, cleared before the executable's entry point runs. This
79 must not be initialized to nonzero, because the unused dynamic
80 linker loaded in for libc.so's "ld.so.1" dep will provide the
81 definition seen by libc.so's initializer; that value must be zero,
82 and will be since that dynamic linker's _dl_start and dl_main will
83 never be called. */
84 int _dl_starting_up = 0;
85 INTVARDEF(_dl_starting_up)
87 /* This is the structure which defines all variables global to ld.so
88 (except those which cannot be added for some reason). */
89 struct rtld_global _rtld_global =
91 /* Get architecture specific initializer. */
92 #include <dl-procinfo.c>
93 ._dl_debug_fd = STDERR_FILENO,
94 #ifndef RTLD_CORRECT_DYNAMIC_WEAK
95 /* XXX I know about at least one case where we depend on the old
96 weak behavior (it has to do with librt). Until we get DSO
97 groups implemented we have to make this the default.
98 Bummer. --drepper */
99 ._dl_dynamic_weak = 1,
100 #endif
101 #ifdef NEED_DL_SYSINFO
102 ._dl_sysinfo = DL_SYSINFO_DEFAULT,
103 #endif
104 ._dl_lazy = 1,
105 ._dl_fpu_control = _FPU_DEFAULT,
106 ._dl_correct_cache_id = _DL_CACHE_DEFAULT_ID,
107 ._dl_hwcap_mask = HWCAP_IMPORTANT,
108 #ifdef _LIBC_REENTRANT
109 ._dl_load_lock = _RTLD_LOCK_RECURSIVE_INITIALIZER
110 #endif
112 strong_alias (_rtld_global, _rtld_local);
114 static void dl_main (const ElfW(Phdr) *phdr, ElfW(Word) phnum,
115 ElfW(Addr) *user_entry);
117 static struct libname_list _dl_rtld_libname;
118 static struct libname_list _dl_rtld_libname2;
120 /* We expect less than a second for relocation. */
121 #ifdef HP_SMALL_TIMING_AVAIL
122 # undef HP_TIMING_AVAIL
123 # define HP_TIMING_AVAIL HP_SMALL_TIMING_AVAIL
124 #endif
126 /* Variable for statistics. */
127 #ifndef HP_TIMING_NONAVAIL
128 static hp_timing_t rtld_total_time;
129 static hp_timing_t relocate_time;
130 static hp_timing_t load_time;
131 static hp_timing_t start_time;
132 #endif
134 /* Additional definitions needed by TLS initialization. */
135 #ifdef TLS_INIT_HELPER
136 TLS_INIT_HELPER
137 #endif
139 /* Helper function for syscall implementation. */
140 #ifdef DL_SYSINFO_IMPLEMENTATION
141 DL_SYSINFO_IMPLEMENTATION
142 #endif
144 /* Before ld.so is relocated we must not access variables which need
145 relocations. This means variables which are exported. Variables
146 declared as static are fine. If we can mark a variable hidden this
147 is fine, too. The latter is impotant here. We can avoid setting
148 up a temporary link map for ld.so if we can mark _rtld_global as
149 hidden. */
150 #if defined PI_STATIC_AND_HIDDEN && defined HAVE_HIDDEN \
151 && defined HAVE_VISIBILITY_ATTRIBUTE
152 # define DONT_USE_BOOTSTRAP_MAP 1
153 #endif
155 #ifdef DONT_USE_BOOTSTRAP_MAP
156 static ElfW(Addr) _dl_start_final (void *arg);
157 #else
158 struct dl_start_final_info
160 struct link_map l;
161 #if !defined HP_TIMING_NONAVAIL && HP_TIMING_INLINE
162 hp_timing_t start_time;
163 #endif
165 static ElfW(Addr) _dl_start_final (void *arg,
166 struct dl_start_final_info *info);
167 #endif
169 /* These defined magically in the linker script. */
170 extern char _begin[] attribute_hidden;
171 extern char _end[] attribute_hidden;
174 #ifdef RTLD_START
175 RTLD_START
176 #else
177 # error "sysdeps/MACHINE/dl-machine.h fails to define RTLD_START"
178 #endif
180 #ifndef VALIDX
181 # define VALIDX(tag) (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGNUM \
182 + DT_EXTRANUM + DT_VALTAGIDX (tag))
183 #endif
184 #ifndef ADDRIDX
185 # define ADDRIDX(tag) (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGNUM \
186 + DT_EXTRANUM + DT_VALNUM + DT_ADDRTAGIDX (tag))
187 #endif
189 /* This is the second half of _dl_start (below). It can be inlined safely
190 under DONT_USE_BOOTSTRAP_MAP, where it is careful not to make any GOT
191 references. When the tools don't permit us to avoid using a GOT entry
192 for _dl_rtld_global (no attribute_hidden support), we must make sure
193 this function is not inlined (see below). */
195 #ifdef DONT_USE_BOOTSTRAP_MAP
196 static inline ElfW(Addr) __attribute__ ((always_inline))
197 _dl_start_final (void *arg)
198 #else
199 static ElfW(Addr) __attribute__ ((noinline))
200 _dl_start_final (void *arg, struct dl_start_final_info *info)
201 #endif
203 ElfW(Addr) start_addr;
205 if (HP_TIMING_AVAIL)
207 /* If it hasn't happen yet record the startup time. */
208 if (! HP_TIMING_INLINE)
209 HP_TIMING_NOW (start_time);
210 #if !defined DONT_USE_BOOTSTRAP_MAP && !defined HP_TIMING_NONAVAIL
211 else
212 start_time = info->start_time;
213 #endif
215 /* Initialize the timing functions. */
216 HP_TIMING_DIFF_INIT ();
219 /* Transfer data about ourselves to the permanent link_map structure. */
220 #ifndef DONT_USE_BOOTSTRAP_MAP
221 GL(dl_rtld_map).l_addr = info->l.l_addr;
222 GL(dl_rtld_map).l_ld = info->l.l_ld;
223 memcpy (GL(dl_rtld_map).l_info, info->l.l_info,
224 sizeof GL(dl_rtld_map).l_info);
225 GL(dl_rtld_map).l_mach = info->l.l_mach;
226 #endif
227 _dl_setup_hash (&GL(dl_rtld_map));
228 GL(dl_rtld_map).l_opencount = 1;
229 GL(dl_rtld_map).l_map_start = (ElfW(Addr)) _begin;
230 GL(dl_rtld_map).l_map_end = (ElfW(Addr)) _end;
231 /* Copy the TLS related data if necessary. */
232 #if USE_TLS && !defined DONT_USE_BOOTSTRAP_MAP
233 # if USE___THREAD
234 assert (info->l.l_tls_modid != 0);
235 GL(dl_rtld_map).l_tls_blocksize = info->l.l_tls_blocksize;
236 GL(dl_rtld_map).l_tls_align = info->l.l_tls_align;
237 GL(dl_rtld_map).l_tls_initimage_size = info->l.l_tls_initimage_size;
238 GL(dl_rtld_map).l_tls_initimage = info->l.l_tls_initimage;
239 GL(dl_rtld_map).l_tls_offset = info->l.l_tls_offset;
240 GL(dl_rtld_map).l_tls_modid = 1;
241 # else
242 assert (info->l.l_tls_modid == 0);
243 # endif
245 #endif
247 #if HP_TIMING_AVAIL
248 HP_TIMING_NOW (GL(dl_cpuclock_offset));
249 #endif
251 /* Call the OS-dependent function to set up life so we can do things like
252 file access. It will call `dl_main' (below) to do all the real work
253 of the dynamic linker, and then unwind our frame and run the user
254 entry point on the same stack we entered on. */
255 start_addr = _dl_sysdep_start (arg, &dl_main);
257 #ifndef HP_TIMING_NONAVAIL
258 if (HP_TIMING_AVAIL)
260 hp_timing_t end_time;
262 /* Get the current time. */
263 HP_TIMING_NOW (end_time);
265 /* Compute the difference. */
266 HP_TIMING_DIFF (rtld_total_time, start_time, end_time);
268 #endif
270 if (__builtin_expect (GL(dl_debug_mask) & DL_DEBUG_STATISTICS, 0))
271 print_statistics ();
273 return start_addr;
276 static ElfW(Addr) __attribute_used__ internal_function
277 _dl_start (void *arg)
279 #ifdef DONT_USE_BOOTSTRAP_MAP
280 # define bootstrap_map GL(dl_rtld_map)
281 #else
282 struct dl_start_final_info info;
283 # define bootstrap_map info.l
284 #endif
286 /* This #define produces dynamic linking inline functions for
287 bootstrap relocation instead of general-purpose relocation. */
288 #define RTLD_BOOTSTRAP
289 #define RESOLVE_MAP(sym, version, flags) \
290 ((*(sym))->st_shndx == SHN_UNDEF ? 0 : &bootstrap_map)
291 #define RESOLVE(sym, version, flags) \
292 ((*(sym))->st_shndx == SHN_UNDEF ? 0 : bootstrap_map.l_addr)
293 #include "dynamic-link.h"
295 if (HP_TIMING_INLINE && HP_TIMING_AVAIL)
296 #ifdef DONT_USE_BOOTSTRAP_MAP
297 HP_TIMING_NOW (start_time);
298 #else
299 HP_TIMING_NOW (info.start_time);
300 #endif
302 /* Partly clean the `bootstrap_map' structure up. Don't use
303 `memset' since it might not be built in or inlined and we cannot
304 make function calls at this point. Use '__builtin_memset' if we
305 know it is available. We do not have to clear the memory if we
306 do not have to use the temporary bootstrap_map. Global variables
307 are initialized to zero by default. */
308 #ifndef DONT_USE_BOOTSTRAP_MAP
309 # ifdef HAVE_BUILTIN_MEMSET
310 __builtin_memset (bootstrap_map.l_info, '\0', sizeof (bootstrap_map.l_info));
311 # else
312 for (size_t cnt = 0;
313 cnt < sizeof (bootstrap_map.l_info) / sizeof (bootstrap_map.l_info[0]);
314 ++cnt)
315 bootstrap_map.l_info[cnt] = 0;
316 # endif
317 #endif
319 /* Figure out the run-time load address of the dynamic linker itself. */
320 bootstrap_map.l_addr = elf_machine_load_address ();
322 /* Read our own dynamic section and fill in the info array. */
323 bootstrap_map.l_ld = (void *) bootstrap_map.l_addr + elf_machine_dynamic ();
324 elf_get_dynamic_info (&bootstrap_map);
326 #if USE___THREAD
327 /* Get the dynamic linker's own program header. First we need the ELF
328 file header. The `_begin' symbol created by the linker script points
329 to it. When we have something like GOTOFF relocs, we can use a plain
330 reference to find the runtime address. Without that, we have to rely
331 on the `l_addr' value, which is not the value we want when prelinked. */
332 dtv_t initdtv[3];
333 ElfW(Ehdr) *ehdr
334 # ifdef DONT_USE_BOOTSTRAP_MAP
335 = (ElfW(Ehdr) *) &_begin;
336 # else
337 = (ElfW(Ehdr) *) bootstrap_map.l_addr;
338 # endif
339 ElfW(Phdr) *phdr = (ElfW(Phdr) *) ((void *) ehdr + ehdr->e_phoff);
340 size_t cnt = ehdr->e_phnum; /* PT_TLS is usually the last phdr. */
341 while (cnt-- > 0)
342 if (phdr[cnt].p_type == PT_TLS)
344 void *tlsblock;
345 size_t max_align = MAX (TLS_INIT_TCB_ALIGN, phdr[cnt].p_align);
346 char *p;
348 bootstrap_map.l_tls_blocksize = phdr[cnt].p_memsz;
349 bootstrap_map.l_tls_align = phdr[cnt].p_align;
350 assert (bootstrap_map.l_tls_blocksize != 0);
351 bootstrap_map.l_tls_initimage_size = phdr[cnt].p_filesz;
352 bootstrap_map.l_tls_initimage = (void *) (bootstrap_map.l_addr
353 + phdr[cnt].p_vaddr);
355 /* We can now allocate the initial TLS block. This can happen
356 on the stack. We'll get the final memory later when we
357 know all about the various objects loaded at startup
358 time. */
359 # if TLS_TCB_AT_TP
360 tlsblock = alloca (roundup (bootstrap_map.l_tls_blocksize,
361 TLS_INIT_TCB_ALIGN)
362 + TLS_INIT_TCB_SIZE
363 + max_align);
364 # elif TLS_DTV_AT_TP
365 tlsblock = alloca (roundup (TLS_INIT_TCB_SIZE,
366 bootstrap_map.l_tls_align)
367 + bootstrap_map.l_tls_blocksize
368 + max_align);
369 # else
370 /* In case a model with a different layout for the TCB and DTV
371 is defined add another #elif here and in the following #ifs. */
372 # error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
373 # endif
374 /* Align the TLS block. */
375 tlsblock = (void *) (((uintptr_t) tlsblock + max_align - 1)
376 & ~(max_align - 1));
378 /* Initialize the dtv. [0] is the length, [1] the generation
379 counter. */
380 initdtv[0].counter = 1;
381 initdtv[1].counter = 0;
383 /* Initialize the TLS block. */
384 # if TLS_TCB_AT_TP
385 initdtv[2].pointer = tlsblock;
386 # elif TLS_DTV_AT_TP
387 bootstrap_map.l_tls_offset = roundup (TLS_INIT_TCB_SIZE,
388 bootstrap_map.l_tls_align);
389 initdtv[2].pointer = (char *) tlsblock + bootstrap_map.l_tls_offset;
390 # else
391 # error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
392 # endif
393 p = __mempcpy (initdtv[2].pointer, bootstrap_map.l_tls_initimage,
394 bootstrap_map.l_tls_initimage_size);
395 # ifdef HAVE_BUILTIN_MEMSET
396 __builtin_memset (p, '\0', (bootstrap_map.l_tls_blocksize
397 - bootstrap_map.l_tls_initimage_size));
398 # else
400 size_t remaining = (bootstrap_map.l_tls_blocksize
401 - bootstrap_map.l_tls_initimage_size);
402 while (remaining-- > 0)
403 *p++ = '\0';
405 #endif
407 /* Install the pointer to the dtv. */
409 /* Initialize the thread pointer. */
410 # if TLS_TCB_AT_TP
411 bootstrap_map.l_tls_offset
412 = roundup (bootstrap_map.l_tls_blocksize, TLS_INIT_TCB_ALIGN);
414 INSTALL_DTV ((char *) tlsblock + bootstrap_map.l_tls_offset,
415 initdtv);
417 const char *lossage = TLS_INIT_TP ((char *) tlsblock
418 + bootstrap_map.l_tls_offset, 0);
419 # elif TLS_DTV_AT_TP
420 INSTALL_DTV (tlsblock, initdtv);
421 const char *lossage = TLS_INIT_TP (tlsblock, 0);
422 # else
423 # error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
424 # endif
425 if (__builtin_expect (lossage != NULL, 0))
426 _dl_fatal_printf ("cannot set up thread-local storage: %s\n",
427 lossage);
429 /* So far this is module number one. */
430 bootstrap_map.l_tls_modid = 1;
432 /* There can only be one PT_TLS entry. */
433 break;
435 #endif /* USE___THREAD */
437 #ifdef ELF_MACHINE_BEFORE_RTLD_RELOC
438 ELF_MACHINE_BEFORE_RTLD_RELOC (bootstrap_map.l_info);
439 #endif
441 if (bootstrap_map.l_addr || ! bootstrap_map.l_info[VALIDX(DT_GNU_PRELINKED)])
443 /* Relocate ourselves so we can do normal function calls and
444 data access using the global offset table. */
446 ELF_DYNAMIC_RELOCATE (&bootstrap_map, 0, 0);
449 /* Please note that we don't allow profiling of this object and
450 therefore need not test whether we have to allocate the array
451 for the relocation results (as done in dl-reloc.c). */
453 /* Now life is sane; we can call functions and access global data.
454 Set up to use the operating system facilities, and find out from
455 the operating system's program loader where to find the program
456 header table in core. Put the rest of _dl_start into a separate
457 function, that way the compiler cannot put accesses to the GOT
458 before ELF_DYNAMIC_RELOCATE. */
460 #ifdef DONT_USE_BOOTSTRAP_MAP
461 ElfW(Addr) entry = _dl_start_final (arg);
462 #else
463 ElfW(Addr) entry = _dl_start_final (arg, &info);
464 #endif
466 #ifndef ELF_MACHINE_START_ADDRESS
467 # define ELF_MACHINE_START_ADDRESS(map, start) (start)
468 #endif
470 return ELF_MACHINE_START_ADDRESS (GL(dl_loaded), entry);
476 /* Now life is peachy; we can do all normal operations.
477 On to the real work. */
479 /* Some helper functions. */
481 /* Arguments to relocate_doit. */
482 struct relocate_args
484 struct link_map *l;
485 int lazy;
488 struct map_args
490 /* Argument to map_doit. */
491 char *str;
492 /* Return value of map_doit. */
493 struct link_map *main_map;
496 /* Arguments to version_check_doit. */
497 struct version_check_args
499 int doexit;
500 int dotrace;
503 static void
504 relocate_doit (void *a)
506 struct relocate_args *args = (struct relocate_args *) a;
508 INTUSE(_dl_relocate_object) (args->l, args->l->l_scope, args->lazy, 0);
511 static void
512 map_doit (void *a)
514 struct map_args *args = (struct map_args *) a;
515 args->main_map = INTUSE(_dl_map_object) (NULL, args->str, 0, lt_library, 0, 0);
518 static void
519 version_check_doit (void *a)
521 struct version_check_args *args = (struct version_check_args *) a;
522 if (_dl_check_all_versions (GL(dl_loaded), 1, args->dotrace) && args->doexit)
523 /* We cannot start the application. Abort now. */
524 _exit (1);
528 static inline struct link_map *
529 find_needed (const char *name)
531 unsigned int n = GL(dl_loaded)->l_searchlist.r_nlist;
533 while (n-- > 0)
534 if (_dl_name_match_p (name, GL(dl_loaded)->l_searchlist.r_list[n]))
535 return GL(dl_loaded)->l_searchlist.r_list[n];
537 /* Should never happen. */
538 return NULL;
541 static int
542 match_version (const char *string, struct link_map *map)
544 const char *strtab = (const void *) D_PTR (map, l_info[DT_STRTAB]);
545 ElfW(Verdef) *def;
547 #define VERDEFTAG (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGIDX (DT_VERDEF))
548 if (map->l_info[VERDEFTAG] == NULL)
549 /* The file has no symbol versioning. */
550 return 0;
552 def = (ElfW(Verdef) *) ((char *) map->l_addr
553 + map->l_info[VERDEFTAG]->d_un.d_ptr);
554 while (1)
556 ElfW(Verdaux) *aux = (ElfW(Verdaux) *) ((char *) def + def->vd_aux);
558 /* Compare the version strings. */
559 if (strcmp (string, strtab + aux->vda_name) == 0)
560 /* Bingo! */
561 return 1;
563 /* If no more definitions we failed to find what we want. */
564 if (def->vd_next == 0)
565 break;
567 /* Next definition. */
568 def = (ElfW(Verdef) *) ((char *) def + def->vd_next);
571 return 0;
574 #ifdef _LIBC_REENTRANT
575 /* _dl_error_catch_tsd points to this for the single-threaded case.
576 It's reset by the thread library for multithreaded programs. */
577 void ** __attribute__ ((const))
578 _dl_initial_error_catch_tsd (void)
580 static void *data;
581 return &data;
583 #endif
585 static const char *library_path; /* The library search path. */
586 static const char *preloadlist; /* The list preloaded objects. */
587 static int version_info; /* Nonzero if information about
588 versions has to be printed. */
590 static void
591 dl_main (const ElfW(Phdr) *phdr,
592 ElfW(Word) phnum,
593 ElfW(Addr) *user_entry)
595 const ElfW(Phdr) *ph;
596 enum mode mode;
597 struct link_map **preloads;
598 unsigned int npreloads;
599 size_t file_size;
600 char *file;
601 bool has_interp = false;
602 unsigned int i;
603 bool prelinked = false;
604 bool rtld_is_main = false;
605 #ifndef HP_TIMING_NONAVAIL
606 hp_timing_t start;
607 hp_timing_t stop;
608 hp_timing_t diff;
609 #endif
610 #ifdef USE_TLS
611 void *tcbp;
612 #endif
614 #ifdef _LIBC_REENTRANT
615 /* Explicit initialization since the reloc would just be more work. */
616 GL(dl_error_catch_tsd) = &_dl_initial_error_catch_tsd;
617 #endif
619 /* Process the environment variable which control the behaviour. */
620 process_envvars (&mode);
622 /* Set up a flag which tells we are just starting. */
623 INTUSE(_dl_starting_up) = 1;
625 if (*user_entry == (ElfW(Addr)) ENTRY_POINT)
627 /* Ho ho. We are not the program interpreter! We are the program
628 itself! This means someone ran ld.so as a command. Well, that
629 might be convenient to do sometimes. We support it by
630 interpreting the args like this:
632 ld.so PROGRAM ARGS...
634 The first argument is the name of a file containing an ELF
635 executable we will load and run with the following arguments.
636 To simplify life here, PROGRAM is searched for using the
637 normal rules for shared objects, rather than $PATH or anything
638 like that. We just load it and use its entry point; we don't
639 pay attention to its PT_INTERP command (we are the interpreter
640 ourselves). This is an easy way to test a new ld.so before
641 installing it. */
642 rtld_is_main = true;
644 /* Note the place where the dynamic linker actually came from. */
645 GL(dl_rtld_map).l_name = rtld_progname;
647 while (_dl_argc > 1)
648 if (! strcmp (INTUSE(_dl_argv)[1], "--list"))
650 mode = list;
651 GL(dl_lazy) = -1; /* This means do no dependency analysis. */
653 ++_dl_skip_args;
654 --_dl_argc;
655 ++INTUSE(_dl_argv);
657 else if (! strcmp (INTUSE(_dl_argv)[1], "--verify"))
659 mode = verify;
661 ++_dl_skip_args;
662 --_dl_argc;
663 ++INTUSE(_dl_argv);
665 else if (! strcmp (INTUSE(_dl_argv)[1], "--library-path")
666 && _dl_argc > 2)
668 library_path = INTUSE(_dl_argv)[2];
670 _dl_skip_args += 2;
671 _dl_argc -= 2;
672 INTUSE(_dl_argv) += 2;
674 else if (! strcmp (INTUSE(_dl_argv)[1], "--inhibit-rpath")
675 && _dl_argc > 2)
677 GL(dl_inhibit_rpath) = INTUSE(_dl_argv)[2];
679 _dl_skip_args += 2;
680 _dl_argc -= 2;
681 INTUSE(_dl_argv) += 2;
683 else
684 break;
686 /* If we have no further argument the program was called incorrectly.
687 Grant the user some education. */
688 if (_dl_argc < 2)
689 _dl_fatal_printf ("\
690 Usage: ld.so [OPTION]... EXECUTABLE-FILE [ARGS-FOR-PROGRAM...]\n\
691 You have invoked `ld.so', the helper program for shared library executables.\n\
692 This program usually lives in the file `/lib/ld.so', and special directives\n\
693 in executable files using ELF shared libraries tell the system's program\n\
694 loader to load the helper program from this file. This helper program loads\n\
695 the shared libraries needed by the program executable, prepares the program\n\
696 to run, and runs it. You may invoke this helper program directly from the\n\
697 command line to load and run an ELF executable file; this is like executing\n\
698 that file itself, but always uses this helper program from the file you\n\
699 specified, instead of the helper program file specified in the executable\n\
700 file you run. This is mostly of use for maintainers to test new versions\n\
701 of this helper program; chances are you did not intend to run this program.\n\
703 --list list all dependencies and how they are resolved\n\
704 --verify verify that given object really is a dynamically linked\n\
705 object we can handle\n\
706 --library-path PATH use given PATH instead of content of the environment\n\
707 variable LD_LIBRARY_PATH\n\
708 --inhibit-rpath LIST ignore RUNPATH and RPATH information in object names\n\
709 in LIST\n");
711 ++_dl_skip_args;
712 --_dl_argc;
713 ++INTUSE(_dl_argv);
715 /* Initialize the data structures for the search paths for shared
716 objects. */
717 _dl_init_paths (library_path);
719 if (__builtin_expect (mode, normal) == verify)
721 const char *objname;
722 const char *err_str = NULL;
723 struct map_args args;
725 args.str = rtld_progname;
726 (void) INTUSE(_dl_catch_error) (&objname, &err_str, map_doit, &args);
727 if (__builtin_expect (err_str != NULL, 0))
728 /* We don't free the returned string, the programs stops
729 anyway. */
730 _exit (EXIT_FAILURE);
732 else
734 HP_TIMING_NOW (start);
735 INTUSE(_dl_map_object) (NULL, rtld_progname, 0, lt_library, 0, 0);
736 HP_TIMING_NOW (stop);
738 HP_TIMING_DIFF (load_time, start, stop);
741 phdr = GL(dl_loaded)->l_phdr;
742 phnum = GL(dl_loaded)->l_phnum;
743 /* We overwrite here a pointer to a malloc()ed string. But since
744 the malloc() implementation used at this point is the dummy
745 implementations which has no real free() function it does not
746 makes sense to free the old string first. */
747 GL(dl_loaded)->l_name = (char *) "";
748 *user_entry = GL(dl_loaded)->l_entry;
750 else
752 /* Create a link_map for the executable itself.
753 This will be what dlopen on "" returns. */
754 _dl_new_object ((char *) "", "", lt_executable, NULL);
755 if (GL(dl_loaded) == NULL)
756 _dl_fatal_printf ("cannot allocate memory for link map\n");
757 GL(dl_loaded)->l_phdr = phdr;
758 GL(dl_loaded)->l_phnum = phnum;
759 GL(dl_loaded)->l_entry = *user_entry;
761 /* At this point we are in a bit of trouble. We would have to
762 fill in the values for l_dev and l_ino. But in general we
763 do not know where the file is. We also do not handle AT_EXECFD
764 even if it would be passed up.
766 We leave the values here defined to 0. This is normally no
767 problem as the program code itself is normally no shared
768 object and therefore cannot be loaded dynamically. Nothing
769 prevent the use of dynamic binaries and in these situations
770 we might get problems. We might not be able to find out
771 whether the object is already loaded. But since there is no
772 easy way out and because the dynamic binary must also not
773 have an SONAME we ignore this program for now. If it becomes
774 a problem we can force people using SONAMEs. */
776 /* We delay initializing the path structure until we got the dynamic
777 information for the program. */
780 GL(dl_loaded)->l_map_end = 0;
781 /* Perhaps the executable has no PT_LOAD header entries at all. */
782 GL(dl_loaded)->l_map_start = ~0;
783 /* We opened the file, account for it. */
784 ++GL(dl_loaded)->l_opencount;
786 /* Scan the program header table for the dynamic section. */
787 for (ph = phdr; ph < &phdr[phnum]; ++ph)
788 switch (ph->p_type)
790 case PT_PHDR:
791 /* Find out the load address. */
792 GL(dl_loaded)->l_addr = (ElfW(Addr)) phdr - ph->p_vaddr;
793 break;
794 case PT_DYNAMIC:
795 /* This tells us where to find the dynamic section,
796 which tells us everything we need to do. */
797 GL(dl_loaded)->l_ld = (void *) GL(dl_loaded)->l_addr + ph->p_vaddr;
798 break;
799 case PT_INTERP:
800 /* This "interpreter segment" was used by the program loader to
801 find the program interpreter, which is this program itself, the
802 dynamic linker. We note what name finds us, so that a future
803 dlopen call or DT_NEEDED entry, for something that wants to link
804 against the dynamic linker as a shared library, will know that
805 the shared object is already loaded. */
806 _dl_rtld_libname.name = ((const char *) GL(dl_loaded)->l_addr
807 + ph->p_vaddr);
808 /* _dl_rtld_libname.next = NULL; Already zero. */
809 GL(dl_rtld_map).l_libname = &_dl_rtld_libname;
811 /* Ordinarilly, we would get additional names for the loader from
812 our DT_SONAME. This can't happen if we were actually linked as
813 a static executable (detect this case when we have no DYNAMIC).
814 If so, assume the filename component of the interpreter path to
815 be our SONAME, and add it to our name list. */
816 if (GL(dl_rtld_map).l_ld == NULL)
818 const char *p = NULL;
819 const char *cp = _dl_rtld_libname.name;
821 /* Find the filename part of the path. */
822 while (*cp != '\0')
823 if (*cp++ == '/')
824 p = cp;
826 if (p != NULL)
828 _dl_rtld_libname2.name = p;
829 /* _dl_rtld_libname2.next = NULL; Already zero. */
830 _dl_rtld_libname.next = &_dl_rtld_libname2;
834 has_interp = true;
835 break;
836 case PT_LOAD:
838 ElfW(Addr) mapstart;
839 ElfW(Addr) allocend;
841 /* Remember where the main program starts in memory. */
842 mapstart = (GL(dl_loaded)->l_addr
843 + (ph->p_vaddr & ~(ph->p_align - 1)));
844 if (GL(dl_loaded)->l_map_start > mapstart)
845 GL(dl_loaded)->l_map_start = mapstart;
847 /* Also where it ends. */
848 allocend = GL(dl_loaded)->l_addr + ph->p_vaddr + ph->p_memsz;
849 if (GL(dl_loaded)->l_map_end < allocend)
850 GL(dl_loaded)->l_map_end = allocend;
852 break;
853 #ifdef USE_TLS
854 case PT_TLS:
855 if (ph->p_memsz > 0)
857 /* Note that in the case the dynamic linker we duplicate work
858 here since we read the PT_TLS entry already in
859 _dl_start_final. But the result is repeatable so do not
860 check for this special but unimportant case. */
861 GL(dl_loaded)->l_tls_blocksize = ph->p_memsz;
862 GL(dl_loaded)->l_tls_align = ph->p_align;
863 GL(dl_loaded)->l_tls_initimage_size = ph->p_filesz;
864 GL(dl_loaded)->l_tls_initimage = (void *) ph->p_vaddr;
866 /* This image gets the ID one. */
867 GL(dl_tls_max_dtv_idx) = GL(dl_loaded)->l_tls_modid = 1;
869 break;
870 #endif
872 #ifdef USE_TLS
873 /* Adjust the address of the TLS initialization image in case
874 the executable is actually an ET_DYN object. */
875 if (GL(dl_loaded)->l_tls_initimage != NULL)
876 GL(dl_loaded)->l_tls_initimage
877 = (char *) GL(dl_loaded)->l_tls_initimage + GL(dl_loaded)->l_addr;
878 #endif
879 if (! GL(dl_loaded)->l_map_end)
880 GL(dl_loaded)->l_map_end = ~0;
881 if (! GL(dl_rtld_map).l_libname && GL(dl_rtld_map).l_name)
883 /* We were invoked directly, so the program might not have a
884 PT_INTERP. */
885 _dl_rtld_libname.name = GL(dl_rtld_map).l_name;
886 /* _dl_rtld_libname.next = NULL; Already zero. */
887 GL(dl_rtld_map).l_libname = &_dl_rtld_libname;
889 else
890 assert (GL(dl_rtld_map).l_libname); /* How else did we get here? */
892 if (! rtld_is_main)
894 /* Extract the contents of the dynamic section for easy access. */
895 elf_get_dynamic_info (GL(dl_loaded));
896 if (GL(dl_loaded)->l_info[DT_HASH])
897 /* Set up our cache of pointers into the hash table. */
898 _dl_setup_hash (GL(dl_loaded));
901 if (__builtin_expect (mode, normal) == verify)
903 /* We were called just to verify that this is a dynamic
904 executable using us as the program interpreter. Exit with an
905 error if we were not able to load the binary or no interpreter
906 is specified (i.e., this is no dynamically linked binary. */
907 if (GL(dl_loaded)->l_ld == NULL)
908 _exit (1);
910 /* We allow here some platform specific code. */
911 #ifdef DISTINGUISH_LIB_VERSIONS
912 DISTINGUISH_LIB_VERSIONS;
913 #endif
914 _exit (has_interp ? 0 : 2);
917 if (! rtld_is_main)
918 /* Initialize the data structures for the search paths for shared
919 objects. */
920 _dl_init_paths (library_path);
922 /* Put the link_map for ourselves on the chain so it can be found by
923 name. Note that at this point the global chain of link maps contains
924 exactly one element, which is pointed to by dl_loaded. */
925 if (! GL(dl_rtld_map).l_name)
926 /* If not invoked directly, the dynamic linker shared object file was
927 found by the PT_INTERP name. */
928 GL(dl_rtld_map).l_name = (char *) GL(dl_rtld_map).l_libname->name;
929 GL(dl_rtld_map).l_type = lt_library;
930 GL(dl_loaded)->l_next = &GL(dl_rtld_map);
931 GL(dl_rtld_map).l_prev = GL(dl_loaded);
932 ++GL(dl_nloaded);
934 /* We have two ways to specify objects to preload: via environment
935 variable and via the file /etc/ld.so.preload. The latter can also
936 be used when security is enabled. */
937 preloads = NULL;
938 npreloads = 0;
940 if (__builtin_expect (preloadlist != NULL, 0))
942 /* The LD_PRELOAD environment variable gives list of libraries
943 separated by white space or colons that are loaded before the
944 executable's dependencies and prepended to the global scope
945 list. If the binary is running setuid all elements
946 containing a '/' are ignored since it is insecure. */
947 char *list = strdupa (preloadlist);
948 char *p;
950 HP_TIMING_NOW (start);
952 /* Prevent optimizing strsep. Speed is not important here. */
953 while ((p = (strsep) (&list, " :")) != NULL)
954 if (p[0] != '\0'
955 && (__builtin_expect (! INTUSE(__libc_enable_secure), 1)
956 || strchr (p, '/') == NULL))
958 struct link_map *new_map = INTUSE(_dl_map_object) (GL(dl_loaded),
959 p, 1,
960 lt_library,
961 0, 0);
962 if (++new_map->l_opencount == 1)
963 /* It is no duplicate. */
964 ++npreloads;
967 HP_TIMING_NOW (stop);
968 HP_TIMING_DIFF (diff, start, stop);
969 HP_TIMING_ACCUM_NT (load_time, diff);
972 /* Read the contents of the file. */
973 file = _dl_sysdep_read_whole_file ("/etc/ld.so.preload", &file_size,
974 PROT_READ | PROT_WRITE);
975 if (__builtin_expect (file != MAP_FAILED, 0))
977 /* Parse the file. It contains names of libraries to be loaded,
978 separated by white spaces or `:'. It may also contain
979 comments introduced by `#'. */
980 char *problem;
981 char *runp;
982 size_t rest;
984 /* Eliminate comments. */
985 runp = file;
986 rest = file_size;
987 while (rest > 0)
989 char *comment = memchr (runp, '#', rest);
990 if (comment == NULL)
991 break;
993 rest -= comment - runp;
995 *comment = ' ';
996 while (--rest > 0 && *++comment != '\n');
999 /* We have one problematic case: if we have a name at the end of
1000 the file without a trailing terminating characters, we cannot
1001 place the \0. Handle the case separately. */
1002 if (file[file_size - 1] != ' ' && file[file_size - 1] != '\t'
1003 && file[file_size - 1] != '\n' && file[file_size - 1] != ':')
1005 problem = &file[file_size];
1006 while (problem > file && problem[-1] != ' ' && problem[-1] != '\t'
1007 && problem[-1] != '\n' && problem[-1] != ':')
1008 --problem;
1010 if (problem > file)
1011 problem[-1] = '\0';
1013 else
1015 problem = NULL;
1016 file[file_size - 1] = '\0';
1019 HP_TIMING_NOW (start);
1021 if (file != problem)
1023 char *p;
1024 runp = file;
1025 while ((p = strsep (&runp, ": \t\n")) != NULL)
1026 if (p[0] != '\0')
1028 struct link_map *new_map = INTUSE(_dl_map_object) (GL(dl_loaded),
1029 p, 1,
1030 lt_library,
1031 0, 0);
1032 if (++new_map->l_opencount == 1)
1033 /* It is no duplicate. */
1034 ++npreloads;
1038 if (problem != NULL)
1040 char *p = strndupa (problem, file_size - (problem - file));
1041 struct link_map *new_map = INTUSE(_dl_map_object) (GL(dl_loaded), p,
1042 1, lt_library,
1043 0, 0);
1044 if (++new_map->l_opencount == 1)
1045 /* It is no duplicate. */
1046 ++npreloads;
1049 HP_TIMING_NOW (stop);
1050 HP_TIMING_DIFF (diff, start, stop);
1051 HP_TIMING_ACCUM_NT (load_time, diff);
1053 /* We don't need the file anymore. */
1054 __munmap (file, file_size);
1057 if (__builtin_expect (npreloads, 0) != 0)
1059 /* Set up PRELOADS with a vector of the preloaded libraries. */
1060 struct link_map *l;
1061 preloads = __alloca (npreloads * sizeof preloads[0]);
1062 l = GL(dl_rtld_map).l_next; /* End of the chain before preloads. */
1063 i = 0;
1066 preloads[i++] = l;
1067 l = l->l_next;
1068 } while (l);
1069 assert (i == npreloads);
1072 /* Load all the libraries specified by DT_NEEDED entries. If LD_PRELOAD
1073 specified some libraries to load, these are inserted before the actual
1074 dependencies in the executable's searchlist for symbol resolution. */
1075 HP_TIMING_NOW (start);
1076 INTUSE(_dl_map_object_deps) (GL(dl_loaded), preloads, npreloads,
1077 mode == trace, 0);
1078 HP_TIMING_NOW (stop);
1079 HP_TIMING_DIFF (diff, start, stop);
1080 HP_TIMING_ACCUM_NT (load_time, diff);
1082 /* Mark all objects as being in the global scope and set the open
1083 counter. */
1084 for (i = GL(dl_loaded)->l_searchlist.r_nlist; i > 0; )
1086 --i;
1087 GL(dl_loaded)->l_searchlist.r_list[i]->l_global = 1;
1088 ++GL(dl_loaded)->l_searchlist.r_list[i]->l_opencount;
1091 #ifndef MAP_ANON
1092 /* We are done mapping things, so close the zero-fill descriptor. */
1093 __close (_dl_zerofd);
1094 _dl_zerofd = -1;
1095 #endif
1097 /* Remove _dl_rtld_map from the chain. */
1098 GL(dl_rtld_map).l_prev->l_next = GL(dl_rtld_map).l_next;
1099 if (GL(dl_rtld_map).l_next)
1100 GL(dl_rtld_map).l_next->l_prev = GL(dl_rtld_map).l_prev;
1102 if (__builtin_expect (GL(dl_rtld_map).l_opencount > 1, 1))
1104 /* Some DT_NEEDED entry referred to the interpreter object itself, so
1105 put it back in the list of visible objects. We insert it into the
1106 chain in symbol search order because gdb uses the chain's order as
1107 its symbol search order. */
1108 i = 1;
1109 while (GL(dl_loaded)->l_searchlist.r_list[i] != &GL(dl_rtld_map))
1110 ++i;
1111 GL(dl_rtld_map).l_prev = GL(dl_loaded)->l_searchlist.r_list[i - 1];
1112 if (__builtin_expect (mode, normal) == normal)
1113 GL(dl_rtld_map).l_next = (i + 1 < GL(dl_loaded)->l_searchlist.r_nlist
1114 ? GL(dl_loaded)->l_searchlist.r_list[i + 1]
1115 : NULL);
1116 else
1117 /* In trace mode there might be an invisible object (which we
1118 could not find) after the previous one in the search list.
1119 In this case it doesn't matter much where we put the
1120 interpreter object, so we just initialize the list pointer so
1121 that the assertion below holds. */
1122 GL(dl_rtld_map).l_next = GL(dl_rtld_map).l_prev->l_next;
1124 assert (GL(dl_rtld_map).l_prev->l_next == GL(dl_rtld_map).l_next);
1125 GL(dl_rtld_map).l_prev->l_next = &GL(dl_rtld_map);
1126 if (GL(dl_rtld_map).l_next != NULL)
1128 assert (GL(dl_rtld_map).l_next->l_prev == GL(dl_rtld_map).l_prev);
1129 GL(dl_rtld_map).l_next->l_prev = &GL(dl_rtld_map);
1133 /* Now let us see whether all libraries are available in the
1134 versions we need. */
1136 struct version_check_args args;
1137 args.doexit = mode == normal;
1138 args.dotrace = mode == trace;
1139 _dl_receive_error (print_missing_version, version_check_doit, &args);
1142 #ifdef USE_TLS
1143 /* Now it is time to determine the layout of the static TLS block
1144 and allocate it for the initial thread. Note that we always
1145 allocate the static block, we never defer it even if no
1146 DF_STATIC_TLS bit is set. The reason is that we know glibc will
1147 use the static model. First add the dynamic linker to the list
1148 if it also uses TLS. */
1149 if (GL(dl_rtld_map).l_tls_blocksize != 0)
1150 /* Assign a module ID. */
1151 GL(dl_rtld_map).l_tls_modid = _dl_next_tls_modid ();
1153 # ifndef TLS_INIT_TP_EXPENSIVE
1154 # define TLS_INIT_TP_EXPENSIVE 0
1155 # endif
1157 /* We do not initialize any of the TLS functionality unless any of the
1158 initial modules uses TLS. This makes dynamic loading of modules with
1159 TLS impossible, but to support it requires either eagerly doing setup
1160 now or lazily doing it later. Doing it now makes us incompatible with
1161 an old kernel that can't perform TLS_INIT_TP, even if no TLS is ever
1162 used. Trying to do it lazily is too hairy to try when there could be
1163 multiple threads (from a non-TLS-using libpthread). */
1164 if (GL(dl_tls_max_dtv_idx) > 0 || !TLS_INIT_TP_EXPENSIVE)
1166 struct link_map *l;
1167 size_t nelem;
1168 struct dtv_slotinfo *slotinfo;
1170 /* Number of elements in the static TLS block. */
1171 GL(dl_tls_static_nelem) = GL(dl_tls_max_dtv_idx);
1173 /* Allocate the array which contains the information about the
1174 dtv slots. We allocate a few entries more than needed to
1175 avoid the need for reallocation. */
1176 nelem = GL(dl_tls_max_dtv_idx) + 1 + TLS_SLOTINFO_SURPLUS;
1178 /* Allocate. */
1179 GL(dl_tls_dtv_slotinfo_list) = (struct dtv_slotinfo_list *)
1180 malloc (sizeof (struct dtv_slotinfo_list)
1181 + nelem * sizeof (struct dtv_slotinfo));
1182 /* No need to check the return value. If memory allocation failed
1183 the program would have been terminated. */
1185 slotinfo = memset (GL(dl_tls_dtv_slotinfo_list)->slotinfo, '\0',
1186 nelem * sizeof (struct dtv_slotinfo));
1187 GL(dl_tls_dtv_slotinfo_list)->len = nelem;
1188 GL(dl_tls_dtv_slotinfo_list)->next = NULL;
1190 /* Fill in the information from the loaded modules. */
1191 for (l = GL(dl_loaded), i = 0; l != NULL; l = l->l_next)
1192 if (l->l_tls_blocksize != 0)
1193 /* This is a module with TLS data. Store the map reference.
1194 The generation counter is zero. */
1195 slotinfo[++i].map = l;
1196 assert (i == GL(dl_tls_max_dtv_idx));
1198 /* Compute the TLS offsets for the various blocks. */
1199 _dl_determine_tlsoffset ();
1201 /* Construct the static TLS block and the dtv for the initial
1202 thread. For some platforms this will include allocating memory
1203 for the thread descriptor. The memory for the TLS block will
1204 never be freed. It should be allocated accordingly. The dtv
1205 array can be changed if dynamic loading requires it. */
1206 tcbp = _dl_allocate_tls_storage ();
1207 if (tcbp == NULL)
1208 _dl_fatal_printf ("\
1209 cannot allocate TLS data structures for initial thread");
1211 /* Store for detection of the special case by __tls_get_addr
1212 so it knows not to pass this dtv to the normal realloc. */
1213 GL(dl_initial_dtv) = GET_DTV (tcbp);
1215 #endif
1217 if (__builtin_expect (mode, normal) != normal)
1219 /* We were run just to list the shared libraries. It is
1220 important that we do this before real relocation, because the
1221 functions we call below for output may no longer work properly
1222 after relocation. */
1223 if (! GL(dl_loaded)->l_info[DT_NEEDED])
1224 _dl_printf ("\tstatically linked\n");
1225 else
1227 struct link_map *l;
1229 if (GL(dl_debug_mask) & DL_DEBUG_PRELINK)
1231 struct r_scope_elem *scope = &GL(dl_loaded)->l_searchlist;
1233 for (i = 0; i < scope->r_nlist; i++)
1235 l = scope->r_list [i];
1236 if (l->l_faked)
1238 _dl_printf ("\t%s => not found\n", l->l_libname->name);
1239 continue;
1241 if (_dl_name_match_p (GL(dl_trace_prelink), l))
1242 GL(dl_trace_prelink_map) = l;
1243 _dl_printf ("\t%s => %s (0x%0*Zx, 0x%0*Zx)",
1244 l->l_libname->name[0] ? l->l_libname->name
1245 : rtld_progname ?: "<main program>",
1246 l->l_name[0] ? l->l_name
1247 : rtld_progname ?: "<main program>",
1248 (int) sizeof l->l_map_start * 2,
1249 l->l_map_start,
1250 (int) sizeof l->l_addr * 2,
1251 l->l_addr);
1252 #ifdef USE_TLS
1253 if (l->l_tls_modid)
1254 _dl_printf (" TLS(0x%Zx, 0x%0*Zx)\n", l->l_tls_modid,
1255 (int) sizeof l->l_tls_offset * 2,
1256 l->l_tls_offset);
1257 else
1258 #endif
1259 _dl_printf ("\n");
1262 else
1264 for (l = GL(dl_loaded)->l_next; l; l = l->l_next)
1265 if (l->l_faked)
1266 /* The library was not found. */
1267 _dl_printf ("\t%s => not found\n", l->l_libname->name);
1268 else
1269 _dl_printf ("\t%s => %s (0x%0*Zx)\n", l->l_libname->name,
1270 l->l_name, (int) sizeof l->l_map_start * 2,
1271 l->l_map_start);
1275 if (__builtin_expect (mode, trace) != trace)
1276 for (i = 1; i < (unsigned int) _dl_argc; ++i)
1278 const ElfW(Sym) *ref = NULL;
1279 ElfW(Addr) loadbase;
1280 lookup_t result;
1282 result = INTUSE(_dl_lookup_symbol) (INTUSE(_dl_argv)[i],
1283 GL(dl_loaded),
1284 &ref, GL(dl_loaded)->l_scope,
1285 ELF_RTYPE_CLASS_PLT, 1);
1287 loadbase = LOOKUP_VALUE_ADDRESS (result);
1289 _dl_printf ("%s found at 0x%0*Zd in object at 0x%0*Zd\n",
1290 INTUSE(_dl_argv)[i],
1291 (int) sizeof ref->st_value * 2, ref->st_value,
1292 (int) sizeof loadbase * 2, loadbase);
1294 else
1296 /* If LD_WARN is set warn about undefined symbols. */
1297 if (GL(dl_lazy) >= 0 && GL(dl_verbose))
1299 /* We have to do symbol dependency testing. */
1300 struct relocate_args args;
1301 struct link_map *l;
1303 args.lazy = GL(dl_lazy);
1305 l = GL(dl_loaded);
1306 while (l->l_next)
1307 l = l->l_next;
1310 if (l != &GL(dl_rtld_map) && ! l->l_faked)
1312 args.l = l;
1313 _dl_receive_error (print_unresolved, relocate_doit,
1314 &args);
1316 l = l->l_prev;
1317 } while (l);
1319 if ((GL(dl_debug_mask) & DL_DEBUG_PRELINK)
1320 && GL(dl_rtld_map).l_opencount > 1)
1321 INTUSE(_dl_relocate_object) (&GL(dl_rtld_map),
1322 GL(dl_loaded)->l_scope, 0, 0);
1325 #define VERNEEDTAG (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGIDX (DT_VERNEED))
1326 if (version_info)
1328 /* Print more information. This means here, print information
1329 about the versions needed. */
1330 int first = 1;
1331 struct link_map *map = GL(dl_loaded);
1333 for (map = GL(dl_loaded); map != NULL; map = map->l_next)
1335 const char *strtab;
1336 ElfW(Dyn) *dyn = map->l_info[VERNEEDTAG];
1337 ElfW(Verneed) *ent;
1339 if (dyn == NULL)
1340 continue;
1342 strtab = (const void *) D_PTR (map, l_info[DT_STRTAB]);
1343 ent = (ElfW(Verneed) *) (map->l_addr + dyn->d_un.d_ptr);
1345 if (first)
1347 _dl_printf ("\n\tVersion information:\n");
1348 first = 0;
1351 _dl_printf ("\t%s:\n",
1352 map->l_name[0] ? map->l_name : rtld_progname);
1354 while (1)
1356 ElfW(Vernaux) *aux;
1357 struct link_map *needed;
1359 needed = find_needed (strtab + ent->vn_file);
1360 aux = (ElfW(Vernaux) *) ((char *) ent + ent->vn_aux);
1362 while (1)
1364 const char *fname = NULL;
1366 if (needed != NULL
1367 && match_version (strtab + aux->vna_name,
1368 needed))
1369 fname = needed->l_name;
1371 _dl_printf ("\t\t%s (%s) %s=> %s\n",
1372 strtab + ent->vn_file,
1373 strtab + aux->vna_name,
1374 aux->vna_flags & VER_FLG_WEAK
1375 ? "[WEAK] " : "",
1376 fname ?: "not found");
1378 if (aux->vna_next == 0)
1379 /* No more symbols. */
1380 break;
1382 /* Next symbol. */
1383 aux = (ElfW(Vernaux) *) ((char *) aux
1384 + aux->vna_next);
1387 if (ent->vn_next == 0)
1388 /* No more dependencies. */
1389 break;
1391 /* Next dependency. */
1392 ent = (ElfW(Verneed) *) ((char *) ent + ent->vn_next);
1398 _exit (0);
1401 if (GL(dl_loaded)->l_info [ADDRIDX (DT_GNU_LIBLIST)]
1402 && ! __builtin_expect (GL(dl_profile) != NULL, 0))
1404 ElfW(Lib) *liblist, *liblistend;
1405 struct link_map **r_list, **r_listend, *l;
1406 const char *strtab = (const void *) D_PTR (GL(dl_loaded),
1407 l_info[DT_STRTAB]);
1409 assert (GL(dl_loaded)->l_info [VALIDX (DT_GNU_LIBLISTSZ)] != NULL);
1410 liblist = (ElfW(Lib) *)
1411 GL(dl_loaded)->l_info [ADDRIDX (DT_GNU_LIBLIST)]->d_un.d_ptr;
1412 liblistend = (ElfW(Lib) *)
1413 ((char *) liblist
1414 + GL(dl_loaded)->l_info [VALIDX (DT_GNU_LIBLISTSZ)]->d_un.d_val);
1415 r_list = GL(dl_loaded)->l_searchlist.r_list;
1416 r_listend = r_list + GL(dl_loaded)->l_searchlist.r_nlist;
1418 for (; r_list < r_listend && liblist < liblistend; r_list++)
1420 l = *r_list;
1422 if (l == GL(dl_loaded))
1423 continue;
1425 /* If the library is not mapped where it should, fail. */
1426 if (l->l_addr)
1427 break;
1429 /* Next, check if checksum matches. */
1430 if (l->l_info [VALIDX(DT_CHECKSUM)] == NULL
1431 || l->l_info [VALIDX(DT_CHECKSUM)]->d_un.d_val
1432 != liblist->l_checksum)
1433 break;
1435 if (l->l_info [VALIDX(DT_GNU_PRELINKED)] == NULL
1436 || l->l_info [VALIDX(DT_GNU_PRELINKED)]->d_un.d_val
1437 != liblist->l_time_stamp)
1438 break;
1440 if (! _dl_name_match_p (strtab + liblist->l_name, l))
1441 break;
1443 ++liblist;
1447 if (r_list == r_listend && liblist == liblistend)
1448 prelinked = true;
1450 if (__builtin_expect (GL(dl_debug_mask) & DL_DEBUG_LIBS, 0))
1451 _dl_printf ("\nprelink checking: %s\n", prelinked ? "ok" : "failed");
1454 if (prelinked)
1456 struct link_map *l;
1458 if (GL(dl_loaded)->l_info [ADDRIDX (DT_GNU_CONFLICT)] != NULL)
1460 ElfW(Rela) *conflict, *conflictend;
1461 #ifndef HP_TIMING_NONAVAIL
1462 hp_timing_t start;
1463 hp_timing_t stop;
1464 #endif
1466 HP_TIMING_NOW (start);
1467 assert (GL(dl_loaded)->l_info [VALIDX (DT_GNU_CONFLICTSZ)] != NULL);
1468 conflict = (ElfW(Rela) *)
1469 GL(dl_loaded)->l_info [ADDRIDX (DT_GNU_CONFLICT)]->d_un.d_ptr;
1470 conflictend = (ElfW(Rela) *)
1471 ((char *) conflict
1472 + GL(dl_loaded)->l_info [VALIDX (DT_GNU_CONFLICTSZ)]->d_un.d_val);
1473 _dl_resolve_conflicts (GL(dl_loaded), conflict, conflictend);
1474 HP_TIMING_NOW (stop);
1475 HP_TIMING_DIFF (relocate_time, start, stop);
1479 /* Mark all the objects so we know they have been already relocated. */
1480 for (l = GL(dl_loaded); l != NULL; l = l->l_next)
1481 l->l_relocated = 1;
1483 _dl_sysdep_start_cleanup ();
1485 else
1487 /* Now we have all the objects loaded. Relocate them all except for
1488 the dynamic linker itself. We do this in reverse order so that copy
1489 relocs of earlier objects overwrite the data written by later
1490 objects. We do not re-relocate the dynamic linker itself in this
1491 loop because that could result in the GOT entries for functions we
1492 call being changed, and that would break us. It is safe to relocate
1493 the dynamic linker out of order because it has no copy relocs (we
1494 know that because it is self-contained). */
1496 struct link_map *l;
1497 int consider_profiling = GL(dl_profile) != NULL;
1498 #ifndef HP_TIMING_NONAVAIL
1499 hp_timing_t start;
1500 hp_timing_t stop;
1501 hp_timing_t add;
1502 #endif
1504 /* If we are profiling we also must do lazy reloaction. */
1505 GL(dl_lazy) |= consider_profiling;
1507 l = GL(dl_loaded);
1508 while (l->l_next)
1509 l = l->l_next;
1511 HP_TIMING_NOW (start);
1514 /* While we are at it, help the memory handling a bit. We have to
1515 mark some data structures as allocated with the fake malloc()
1516 implementation in ld.so. */
1517 struct libname_list *lnp = l->l_libname->next;
1519 while (__builtin_expect (lnp != NULL, 0))
1521 lnp->dont_free = 1;
1522 lnp = lnp->next;
1525 if (l != &GL(dl_rtld_map))
1526 INTUSE(_dl_relocate_object) (l, l->l_scope, GL(dl_lazy),
1527 consider_profiling);
1529 l = l->l_prev;
1531 while (l);
1532 HP_TIMING_NOW (stop);
1534 HP_TIMING_DIFF (relocate_time, start, stop);
1536 /* Do any necessary cleanups for the startup OS interface code.
1537 We do these now so that no calls are made after rtld re-relocation
1538 which might be resolved to different functions than we expect.
1539 We cannot do this before relocating the other objects because
1540 _dl_relocate_object might need to call `mprotect' for DT_TEXTREL. */
1541 _dl_sysdep_start_cleanup ();
1543 /* Now enable profiling if needed. Like the previous call,
1544 this has to go here because the calls it makes should use the
1545 rtld versions of the functions (particularly calloc()), but it
1546 needs to have _dl_profile_map set up by the relocator. */
1547 if (__builtin_expect (GL(dl_profile_map) != NULL, 0))
1548 /* We must prepare the profiling. */
1549 INTUSE(_dl_start_profile) (GL(dl_profile_map), GL(dl_profile_output));
1551 if (GL(dl_rtld_map).l_opencount > 1)
1553 /* There was an explicit ref to the dynamic linker as a shared lib.
1554 Re-relocate ourselves with user-controlled symbol definitions. */
1555 HP_TIMING_NOW (start);
1556 INTUSE(_dl_relocate_object) (&GL(dl_rtld_map), GL(dl_loaded)->l_scope,
1557 0, 0);
1558 HP_TIMING_NOW (stop);
1559 HP_TIMING_DIFF (add, start, stop);
1560 HP_TIMING_ACCUM_NT (relocate_time, add);
1564 /* Now set up the variable which helps the assembler startup code. */
1565 GL(dl_main_searchlist) = &GL(dl_loaded)->l_searchlist;
1566 GL(dl_global_scope)[0] = &GL(dl_loaded)->l_searchlist;
1568 /* Save the information about the original global scope list since
1569 we need it in the memory handling later. */
1570 GL(dl_initial_searchlist) = *GL(dl_main_searchlist);
1572 #ifndef NONTLS_INIT_TP
1573 # define NONTLS_INIT_TP do { } while (0)
1574 #endif
1576 #ifdef USE_TLS
1577 if (GL(dl_tls_max_dtv_idx) > 0 || USE___THREAD || !TLS_INIT_TP_EXPENSIVE)
1579 /* Now that we have completed relocation, the initializer data
1580 for the TLS blocks has its final values and we can copy them
1581 into the main thread's TLS area, which we allocated above. */
1582 _dl_allocate_tls_init (tcbp);
1584 /* And finally install it for the main thread. If ld.so itself uses
1585 TLS we know the thread pointer was initialized earlier. */
1586 const char *lossage = TLS_INIT_TP (tcbp, USE___THREAD);
1587 if (__builtin_expect (lossage != NULL, 0))
1588 _dl_fatal_printf ("cannot set up thread-local storage: %s\n", lossage);
1590 else
1591 #endif
1592 NONTLS_INIT_TP;
1595 /* Initialize _r_debug. */
1596 struct r_debug *r = _dl_debug_initialize (GL(dl_rtld_map).l_addr);
1597 struct link_map *l;
1599 l = GL(dl_loaded);
1601 #ifdef ELF_MACHINE_DEBUG_SETUP
1603 /* Some machines (e.g. MIPS) don't use DT_DEBUG in this way. */
1605 ELF_MACHINE_DEBUG_SETUP (l, r);
1606 ELF_MACHINE_DEBUG_SETUP (&GL(dl_rtld_map), r);
1608 #else
1610 if (l->l_info[DT_DEBUG] != NULL)
1611 /* There is a DT_DEBUG entry in the dynamic section. Fill it in
1612 with the run-time address of the r_debug structure */
1613 l->l_info[DT_DEBUG]->d_un.d_ptr = (ElfW(Addr)) r;
1615 /* Fill in the pointer in the dynamic linker's own dynamic section, in
1616 case you run gdb on the dynamic linker directly. */
1617 if (GL(dl_rtld_map).l_info[DT_DEBUG] != NULL)
1618 GL(dl_rtld_map).l_info[DT_DEBUG]->d_un.d_ptr = (ElfW(Addr)) r;
1620 #endif
1622 /* Notify the debugger that all objects are now mapped in. */
1623 r->r_state = RT_ADD;
1624 INTUSE(_dl_debug_state) ();
1627 #ifndef MAP_COPY
1628 /* We must munmap() the cache file. */
1629 INTUSE(_dl_unload_cache) ();
1630 #endif
1632 /* Once we return, _dl_sysdep_start will invoke
1633 the DT_INIT functions and then *USER_ENTRY. */
1636 /* This is a little helper function for resolving symbols while
1637 tracing the binary. */
1638 static void
1639 print_unresolved (int errcode __attribute__ ((unused)), const char *objname,
1640 const char *errstring)
1642 if (objname[0] == '\0')
1643 objname = rtld_progname ?: "<main program>";
1644 _dl_error_printf ("%s (%s)\n", errstring, objname);
1647 /* This is a little helper function for resolving symbols while
1648 tracing the binary. */
1649 static void
1650 print_missing_version (int errcode __attribute__ ((unused)),
1651 const char *objname, const char *errstring)
1653 _dl_error_printf ("%s: %s: %s\n", rtld_progname ?: "<program name unknown>",
1654 objname, errstring);
1657 /* Nonzero if any of the debugging options is enabled. */
1658 static int any_debug;
1660 /* Process the string given as the parameter which explains which debugging
1661 options are enabled. */
1662 static void
1663 process_dl_debug (const char *dl_debug)
1665 /* When adding new entries make sure that the maximal length of a name
1666 is correctly handled in the LD_DEBUG_HELP code below. */
1667 static const struct
1669 unsigned char len;
1670 const char name[10];
1671 const char helptext[41];
1672 unsigned short int mask;
1673 } debopts[] =
1675 #define LEN_AND_STR(str) sizeof (str) - 1, str
1676 { LEN_AND_STR ("libs"), "display library search paths",
1677 DL_DEBUG_LIBS | DL_DEBUG_IMPCALLS },
1678 { LEN_AND_STR ("reloc"), "display relocation processing",
1679 DL_DEBUG_RELOC | DL_DEBUG_IMPCALLS },
1680 { LEN_AND_STR ("files"), "display progress for input file",
1681 DL_DEBUG_FILES | DL_DEBUG_IMPCALLS },
1682 { LEN_AND_STR ("symbols"), "display symbol table processing",
1683 DL_DEBUG_SYMBOLS | DL_DEBUG_IMPCALLS },
1684 { LEN_AND_STR ("bindings"), "display information about symbol binding",
1685 DL_DEBUG_BINDINGS | DL_DEBUG_IMPCALLS },
1686 { LEN_AND_STR ("versions"), "display version dependencies",
1687 DL_DEBUG_VERSIONS | DL_DEBUG_IMPCALLS },
1688 { LEN_AND_STR ("all"), "all previous options combined",
1689 DL_DEBUG_LIBS | DL_DEBUG_RELOC | DL_DEBUG_FILES | DL_DEBUG_SYMBOLS
1690 | DL_DEBUG_BINDINGS | DL_DEBUG_VERSIONS | DL_DEBUG_IMPCALLS },
1691 { LEN_AND_STR ("statistics"), "display relocation statistics",
1692 DL_DEBUG_STATISTICS },
1693 { LEN_AND_STR ("help"), "display this help message and exit",
1694 DL_DEBUG_HELP },
1696 #define ndebopts (sizeof (debopts) / sizeof (debopts[0]))
1698 /* Skip separating white spaces and commas. */
1699 while (*dl_debug != '\0')
1701 if (*dl_debug != ' ' && *dl_debug != ',' && *dl_debug != ':')
1703 size_t cnt;
1704 size_t len = 1;
1706 while (dl_debug[len] != '\0' && dl_debug[len] != ' '
1707 && dl_debug[len] != ',' && dl_debug[len] != ':')
1708 ++len;
1710 for (cnt = 0; cnt < ndebopts; ++cnt)
1711 if (debopts[cnt].len == len
1712 && memcmp (dl_debug, debopts[cnt].name, len) == 0)
1714 GL(dl_debug_mask) |= debopts[cnt].mask;
1715 any_debug = 1;
1716 break;
1719 if (cnt == ndebopts)
1721 /* Display a warning and skip everything until next
1722 separator. */
1723 char *copy = strndupa (dl_debug, len);
1724 _dl_error_printf ("\
1725 warning: debug option `%s' unknown; try LD_DEBUG=help\n", copy);
1728 dl_debug += len;
1729 continue;
1732 ++dl_debug;
1735 if (GL(dl_debug_mask) & DL_DEBUG_HELP)
1737 size_t cnt;
1739 _dl_printf ("\
1740 Valid options for the LD_DEBUG environment variable are:\n\n");
1742 for (cnt = 0; cnt < ndebopts; ++cnt)
1743 _dl_printf (" %.*s%s%s\n", debopts[cnt].len, debopts[cnt].name,
1744 " " + debopts[cnt].len - 3,
1745 debopts[cnt].helptext);
1747 _dl_printf ("\n\
1748 To direct the debugging output into a file instead of standard output\n\
1749 a filename can be specified using the LD_DEBUG_OUTPUT environment variable.\n");
1750 _exit (0);
1754 /* Process all environments variables the dynamic linker must recognize.
1755 Since all of them start with `LD_' we are a bit smarter while finding
1756 all the entries. */
1757 extern char **_environ attribute_hidden;
1760 static void
1761 process_envvars (enum mode *modep)
1763 char **runp = _environ;
1764 char *envline;
1765 enum mode mode = normal;
1766 char *debug_output = NULL;
1768 /* This is the default place for profiling data file. */
1769 GL(dl_profile_output)
1770 = &"/var/tmp\0/var/profile"[INTUSE(__libc_enable_secure) ? 9 : 0];
1772 while ((envline = _dl_next_ld_env_entry (&runp)) != NULL)
1774 size_t len = 0;
1776 while (envline[len] != '\0' && envline[len] != '=')
1777 ++len;
1779 if (envline[len] != '=')
1780 /* This is a "LD_" variable at the end of the string without
1781 a '=' character. Ignore it since otherwise we will access
1782 invalid memory below. */
1783 continue;
1785 switch (len)
1787 case 4:
1788 /* Warning level, verbose or not. */
1789 if (memcmp (envline, "WARN", 4) == 0)
1790 GL(dl_verbose) = envline[5] != '\0';
1791 break;
1793 case 5:
1794 /* Debugging of the dynamic linker? */
1795 if (memcmp (envline, "DEBUG", 5) == 0)
1796 process_dl_debug (&envline[6]);
1797 break;
1799 case 7:
1800 /* Print information about versions. */
1801 if (memcmp (envline, "VERBOSE", 7) == 0)
1803 version_info = envline[8] != '\0';
1804 break;
1807 /* List of objects to be preloaded. */
1808 if (memcmp (envline, "PRELOAD", 7) == 0)
1810 preloadlist = &envline[8];
1811 break;
1814 /* Which shared object shall be profiled. */
1815 if (memcmp (envline, "PROFILE", 7) == 0 && envline[8] != '\0')
1816 GL(dl_profile) = &envline[8];
1817 break;
1819 case 8:
1820 /* Do we bind early? */
1821 if (memcmp (envline, "BIND_NOW", 8) == 0)
1823 GL(dl_lazy) = envline[9] == '\0';
1824 break;
1826 if (memcmp (envline, "BIND_NOT", 8) == 0)
1827 GL(dl_bind_not) = envline[9] != '\0';
1828 break;
1830 case 9:
1831 /* Test whether we want to see the content of the auxiliary
1832 array passed up from the kernel. */
1833 if (memcmp (envline, "SHOW_AUXV", 9) == 0)
1834 _dl_show_auxv ();
1835 break;
1837 case 10:
1838 /* Mask for the important hardware capabilities. */
1839 if (memcmp (envline, "HWCAP_MASK", 10) == 0)
1840 GL(dl_hwcap_mask) = __strtoul_internal (&envline[11], NULL, 0, 0);
1841 break;
1843 case 11:
1844 /* Path where the binary is found. */
1845 if (!INTUSE(__libc_enable_secure)
1846 && memcmp (envline, "ORIGIN_PATH", 11) == 0)
1847 GL(dl_origin_path) = &envline[12];
1848 break;
1850 case 12:
1851 /* The library search path. */
1852 if (memcmp (envline, "LIBRARY_PATH", 12) == 0)
1854 library_path = &envline[13];
1855 break;
1858 /* Where to place the profiling data file. */
1859 if (memcmp (envline, "DEBUG_OUTPUT", 12) == 0)
1861 debug_output = &envline[13];
1862 break;
1865 if (memcmp (envline, "DYNAMIC_WEAK", 12) == 0)
1866 GL(dl_dynamic_weak) = 1;
1867 break;
1869 case 14:
1870 /* Where to place the profiling data file. */
1871 if (!INTUSE(__libc_enable_secure)
1872 && memcmp (envline, "PROFILE_OUTPUT", 14) == 0
1873 && envline[15] != '\0')
1874 GL(dl_profile_output) = &envline[15];
1875 break;
1877 case 16:
1878 /* The mode of the dynamic linker can be set. */
1879 if (memcmp (envline, "TRACE_PRELINKING", 16) == 0)
1881 mode = trace;
1882 GL(dl_verbose) = 1;
1883 GL(dl_debug_mask) |= DL_DEBUG_PRELINK;
1884 GL(dl_trace_prelink) = &envline[17];
1886 break;
1888 case 20:
1889 /* The mode of the dynamic linker can be set. */
1890 if (memcmp (envline, "TRACE_LOADED_OBJECTS", 20) == 0)
1891 mode = trace;
1892 break;
1894 /* We might have some extra environment variable to handle. This
1895 is tricky due to the pre-processing of the length of the name
1896 in the switch statement here. The code here assumes that added
1897 environment variables have a different length. */
1898 #ifdef EXTRA_LD_ENVVARS
1899 EXTRA_LD_ENVVARS
1900 #endif
1904 /* The caller wants this information. */
1905 *modep = mode;
1907 /* Extra security for SUID binaries. Remove all dangerous environment
1908 variables. */
1909 if (__builtin_expect (INTUSE(__libc_enable_secure), 0))
1911 static const char unsecure_envvars[] =
1912 #ifdef EXTRA_UNSECURE_ENVVARS
1913 EXTRA_UNSECURE_ENVVARS
1914 #endif
1915 UNSECURE_ENVVARS;
1916 const char *nextp;
1918 nextp = unsecure_envvars;
1921 unsetenv (nextp);
1922 /* We could use rawmemchr but this need not be fast. */
1923 nextp = (char *) (strchr) (nextp, '\0') + 1;
1925 while (*nextp != '\0');
1927 if (__access ("/etc/suid-debug", F_OK) != 0)
1928 unsetenv ("MALLOC_CHECK_");
1930 /* If we have to run the dynamic linker in debugging mode and the
1931 LD_DEBUG_OUTPUT environment variable is given, we write the debug
1932 messages to this file. */
1933 else if (any_debug && debug_output != NULL)
1935 #ifdef O_NOFOLLOW
1936 const int flags = O_WRONLY | O_APPEND | O_CREAT | O_NOFOLLOW;
1937 #else
1938 const int flags = O_WRONLY | O_APPEND | O_CREAT;
1939 #endif
1940 size_t name_len = strlen (debug_output);
1941 char buf[name_len + 12];
1942 char *startp;
1944 buf[name_len + 11] = '\0';
1945 startp = _itoa (__getpid (), &buf[name_len + 11], 10, 0);
1946 *--startp = '.';
1947 startp = memcpy (startp - name_len, debug_output, name_len);
1949 GL(dl_debug_fd) = __open (startp, flags, DEFFILEMODE);
1950 if (GL(dl_debug_fd) == -1)
1951 /* We use standard output if opening the file failed. */
1952 GL(dl_debug_fd) = STDOUT_FILENO;
1957 /* Print the various times we collected. */
1958 static void
1959 print_statistics (void)
1961 #ifndef HP_TIMING_NONAVAIL
1962 char buf[200];
1963 char *cp;
1964 char *wp;
1966 /* Total time rtld used. */
1967 if (HP_TIMING_AVAIL)
1969 HP_TIMING_PRINT (buf, sizeof (buf), rtld_total_time);
1970 INTUSE(_dl_debug_printf) ("\nruntime linker statistics:\n"
1971 " total startup time in dynamic loader: %s\n",
1972 buf);
1975 /* Print relocation statistics. */
1976 if (HP_TIMING_AVAIL)
1978 char pbuf[30];
1979 HP_TIMING_PRINT (buf, sizeof (buf), relocate_time);
1980 cp = _itoa ((1000ULL * relocate_time) / rtld_total_time,
1981 pbuf + sizeof (pbuf), 10, 0);
1982 wp = pbuf;
1983 switch (pbuf + sizeof (pbuf) - cp)
1985 case 3:
1986 *wp++ = *cp++;
1987 case 2:
1988 *wp++ = *cp++;
1989 case 1:
1990 *wp++ = '.';
1991 *wp++ = *cp++;
1993 *wp = '\0';
1994 INTUSE(_dl_debug_printf) ("\
1995 time needed for relocation: %s (%s%%)\n",
1996 buf, pbuf);
1998 #endif
1999 INTUSE(_dl_debug_printf) (" number of relocations: %lu\n",
2000 GL(dl_num_relocations));
2001 INTUSE(_dl_debug_printf) (" number of relocations from cache: %lu\n",
2002 GL(dl_num_cache_relocations));
2004 #ifndef HP_TIMING_NONAVAIL
2005 /* Time spend while loading the object and the dependencies. */
2006 if (HP_TIMING_AVAIL)
2008 char pbuf[30];
2009 HP_TIMING_PRINT (buf, sizeof (buf), load_time);
2010 cp = _itoa ((1000ULL * load_time) / rtld_total_time,
2011 pbuf + sizeof (pbuf), 10, 0);
2012 wp = pbuf;
2013 switch (pbuf + sizeof (pbuf) - cp)
2015 case 3:
2016 *wp++ = *cp++;
2017 case 2:
2018 *wp++ = *cp++;
2019 case 1:
2020 *wp++ = '.';
2021 *wp++ = *cp++;
2023 *wp = '\0';
2024 INTUSE(_dl_debug_printf) ("\
2025 time needed to load objects: %s (%s%%)\n",
2026 buf, pbuf);
2028 #endif