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