1 /* vi: set sw=4 ts=4: */
3 * Program to load an ELF binary on a linux system, and run it
4 * after resolving ELF shared library symbols
6 * Copyright (C) 2005 by Joakim Tjernlund
7 * Copyright (C) 2000-2006 by Erik Andersen <andersen@codepoet.org>
8 * Copyright (c) 1994-2000 Eric Youngdale, Peter MacDonald,
9 * David Engel, Hongjiu Lu and Mitch D'Souza
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. The name of the above contributors may not be
17 * used to endorse or promote products derived from this software
18 * without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 #include "unsecvars.h"
36 /* Pull in common debug code */
39 #define ALLOW_ZERO_PLTGOT
41 #if defined(USE_TLS) && USE_TLS
45 /* Pull in the value of _dl_progname */
46 #include LDSO_ELFINTERP
48 /* Global variables used within the shared library loader */
49 char *_dl_library_path = NULL; /* Where we look for libraries */
50 #ifdef __LDSO_PRELOAD_ENV_SUPPORT__
51 char *_dl_preload = NULL; /* Things to be loaded before the libs */
53 char *_dl_ldsopath = NULL; /* Location of the shared lib loader */
54 int _dl_errno = 0; /* We can't use the real errno in ldso */
55 size_t _dl_pagesize = 0; /* Store the page size for use later */
56 struct r_debug *_dl_debug_addr = NULL; /* Used to communicate with the gdb debugger */
57 void *(*_dl_malloc_function) (size_t size) = NULL;
58 void (*_dl_free_function) (void *p) = NULL;
60 static int _dl_secure = 1; /* Are we dealing with setuid stuff? */
62 #ifdef __SUPPORT_LD_DEBUG__
63 char *_dl_debug = NULL;
64 char *_dl_debug_symbols = NULL;
65 char *_dl_debug_move = NULL;
66 char *_dl_debug_reloc = NULL;
67 char *_dl_debug_detail = NULL;
68 char *_dl_debug_nofixups = NULL;
69 char *_dl_debug_bindings = NULL;
70 int _dl_debug_file = 2;
73 /* Needed for standalone execution. */
74 unsigned long attribute_hidden _dl_skip_args = 0;
75 const char *_dl_progname = UCLIBC_LDSO; /* The name of the executable being run */
76 #include "dl-startup.c"
77 #include "dl-symbols.c"
81 * This stub function is used by some debuggers. The idea is that they
82 * can set an internal breakpoint on it, so that we are notified when the
83 * address mapping is changed in some way.
85 void _dl_debug_state(void);
86 rtld_hidden_proto(_dl_debug_state, noinline);
87 void _dl_debug_state(void)
89 /* Make sure GCC doesn't recognize this function as pure, to avoid
90 * having the calls optimized away.
94 rtld_hidden_def(_dl_debug_state);
96 static unsigned char *_dl_malloc_addr = NULL; /* Lets _dl_malloc use the already allocated memory page */
97 static unsigned char *_dl_mmap_zero = NULL; /* Also used by _dl_malloc */
99 static struct elf_resolve **init_fini_list;
100 static unsigned int nlist; /* # items in init_fini_list */
101 extern void _start(void);
103 #ifdef __UCLIBC_HAS_SSP__
104 # include <dl-osinfo.h>
105 uintptr_t stack_chk_guard;
106 # ifndef THREAD_SET_STACK_GUARD
107 /* Only exported for architectures that don't store the stack guard canary
108 * in local thread area. */
109 uintptr_t __stack_chk_guard attribute_relro;
110 # ifdef __UCLIBC_HAS_SSP_COMPAT__
111 strong_alias(__stack_chk_guard,__guard)
113 # elif __UCLIBC_HAS_SSP_COMPAT__
114 uintptr_t __guard attribute_relro;
118 char *_dl_getenv(const char *symbol, char **envp)
123 while ((pnt = *envp++)) {
125 while (*pnt && *pnt == *pnt1)
127 if (!*pnt || *pnt != '=' || *pnt1)
134 void _dl_unsetenv(const char *symbol, char **envp)
138 char **newenvp = envp;
140 for (pnt = *envp; pnt; pnt = *++envp) {
142 while (*pnt && *pnt == *pnt1)
144 if (!*pnt || *pnt != '=' || *pnt1)
151 static int _dl_suid_ok(void)
153 __kernel_uid_t uid, euid;
154 __kernel_gid_t gid, egid;
157 euid = _dl_geteuid();
159 egid = _dl_getegid();
161 if (uid == euid && gid == egid) {
167 void *_dl_malloc(size_t size)
172 _dl_debug_early("request for %d bytes\n", size);
175 if (_dl_malloc_function)
176 return (*_dl_malloc_function) (size);
178 if (_dl_malloc_addr - _dl_mmap_zero + size > _dl_pagesize) {
181 /* Since the above assumes we get a full page even if
182 we request less than that, make sure we request a
183 full page, since uClinux may give us less than than
184 a full page. We might round even
185 larger-than-a-page sizes, but we end up never
186 reusing _dl_mmap_zero/_dl_malloc_addr in that case,
189 The actual page size doesn't really matter; as long
190 as we're self-consistent here, we're safe. */
191 if (size < _dl_pagesize)
192 rounded_size = (size + ADDR_ALIGN) & _dl_pagesize;
196 _dl_debug_early("mmapping more memory\n");
197 _dl_mmap_zero = _dl_malloc_addr = _dl_mmap((void *) 0, rounded_size,
198 PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_UNINITIALIZE, -1, 0);
199 if (_dl_mmap_check_error(_dl_mmap_zero)) {
200 _dl_dprintf(_dl_debug_file, "%s: mmap of a spare page failed!\n", _dl_progname);
204 retval = _dl_malloc_addr;
205 _dl_malloc_addr += size;
208 * Align memory to DL_MALLOC_ALIGN byte boundary. Some
209 * platforms require this, others simply get better
212 _dl_malloc_addr = (unsigned char *) (((unsigned long) _dl_malloc_addr + DL_MALLOC_ALIGN - 1) & ~(DL_MALLOC_ALIGN - 1));
216 static void *_dl_zalloc(size_t size)
218 void *p = _dl_malloc(size);
220 _dl_memset(p, 0, size);
224 void _dl_free(void *p)
226 if (_dl_free_function)
227 (*_dl_free_function) (p);
230 #if defined(USE_TLS) && USE_TLS
231 void *_dl_memalign(size_t __boundary, size_t __size)
238 if (_dl_memalign_function)
239 return (*_dl_memalign_function) (__boundary, __size);
241 while (rounded < __boundary) {
242 rounded = (1 << i++);
245 delta = (((size_t) _dl_malloc_addr + __size) & (rounded - 1));
247 if ((result = _dl_malloc(rounded - delta)) == NULL)
250 result = _dl_malloc(__size);
256 static void __attribute__ ((destructor)) __attribute_used__ _dl_fini(void)
259 struct elf_resolve * tpnt;
261 for (i = 0; i < nlist; ++i) {
262 tpnt = init_fini_list[i];
263 if (tpnt->init_flag & FINI_FUNCS_CALLED)
265 tpnt->init_flag |= FINI_FUNCS_CALLED;
266 _dl_run_fini_array(tpnt);
267 if (tpnt->dynamic_info[DT_FINI]) {
268 void (*dl_elf_func) (void);
270 dl_elf_func = (void (*)(void)) (intptr_t) DL_RELOC_ADDR(tpnt->loadaddr, tpnt->dynamic_info[DT_FINI]);
271 _dl_if_debug_dprint("\ncalling FINI: %s\n\n", tpnt->libname);
272 DL_CALL_FUNC_AT_ADDR (dl_elf_func, tpnt->loadaddr, (void(*)(void)));
277 void _dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr,
278 ElfW(auxv_t) auxvt[AT_EGID + 1], char **envp,
280 DL_GET_READY_TO_RUN_EXTRA_PARMS)
282 ElfW(Addr) app_mapaddr = 0;
287 int unlazy = 0, trace_loaded_objects = 0;
288 struct dyn_elf *rpnt;
289 struct elf_resolve *tcurr;
290 struct elf_resolve *tpnt1;
291 struct elf_resolve app_tpnt_tmp;
292 struct elf_resolve *app_tpnt = &app_tpnt_tmp;
293 struct r_debug *debug_addr;
295 unsigned long *_dl_envp; /* The environment address */
296 ElfW(Addr) relro_addr = 0;
297 size_t relro_size = 0;
299 #if defined(USE_TLS) && USE_TLS
303 /* Wahoo!!! We managed to make a function call! Get malloc
304 * setup so we can use _dl_dprintf() to print debug noise
305 * instead of the SEND_STDERR macros used in dl-startup.c */
307 _dl_memset(app_tpnt, 0, sizeof(*app_tpnt));
309 /* Store the page size for later use */
310 _dl_pagesize = (auxvt[AT_PAGESZ].a_un.a_val) ? (size_t) auxvt[AT_PAGESZ].a_un.a_val : PAGE_SIZE;
311 /* Make it so _dl_malloc can use the page of memory we have already
312 * allocated. We shouldn't need to grab any more memory. This must
313 * be first since things like _dl_dprintf() use _dl_malloc()...
315 _dl_malloc_addr = (unsigned char *)_dl_pagesize;
319 _dl_debug_early("Cool, ldso survived making function calls\n");
321 /* Now we have done the mandatory linking of some things. We are now
322 * free to start using global variables, since these things have all
323 * been fixed up by now. Still no function calls outside of this
324 * library, since the dynamic resolver is not yet ready.
327 _dl_progname = argv[0];
330 if (_start == (void *) auxvt[AT_ENTRY].a_un.a_val) {
331 _dl_dprintf(_dl_debug_file, "Standalone execution is not supported yet\n");
335 /* Start to build the tables of the modules that are required for
336 * this beast to run. We start with the basic executable, and then
337 * go from there. Eventually we will run across ourself, and we
338 * will need to properly deal with that as well.
341 if (_dl_getenv("LD_BIND_NOW", envp))
344 /* Now we need to figure out what kind of options are selected.
345 * Note that for SUID programs we ignore the settings in
348 if ((auxvt[AT_UID].a_un.a_val == (size_t)-1 && _dl_suid_ok()) ||
349 (auxvt[AT_UID].a_un.a_val != (size_t)-1 &&
350 auxvt[AT_UID].a_un.a_val == auxvt[AT_EUID].a_un.a_val &&
351 auxvt[AT_GID].a_un.a_val == auxvt[AT_EGID].a_un.a_val)) {
353 #ifdef __LDSO_PRELOAD_ENV_SUPPORT__
354 _dl_preload = _dl_getenv("LD_PRELOAD", envp);
356 _dl_library_path = _dl_getenv("LD_LIBRARY_PATH", envp);
358 static const char unsecure_envvars[] =
359 #ifdef EXTRA_UNSECURE_ENVVARS
360 EXTRA_UNSECURE_ENVVARS
366 nextp = unsecure_envvars;
368 _dl_unsetenv (nextp, envp);
369 /* We could use rawmemchr but this need not be fast. */
370 nextp = _dl_strchr(nextp, '\0') + 1;
371 } while (*nextp != '\0');
372 #ifdef __LDSO_PRELOAD_ENV_SUPPORT__
375 _dl_library_path = NULL;
376 /* SUID binaries can be exploited if they do LAZY relocation. */
380 #if defined(USE_TLS) && USE_TLS
381 _dl_error_catch_tsd = &_dl_initial_error_catch_tsd;
382 _dl_init_static_tls = &_dl_nothread_init_static_tls;
385 /* At this point we are now free to examine the user application,
386 * and figure out which libraries are supposed to be called. Until
387 * we have this list, we will not be completely ready for dynamic
391 /* Find the runtime load address of the main executable. This may be
392 * different from what the ELF header says for ET_DYN/PIE executables.
396 ElfW(Phdr) *phdr = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_val;
398 for (idx = 0; idx < auxvt[AT_PHNUM].a_un.a_val; idx++, phdr++)
399 if (phdr->p_type == PT_PHDR) {
400 DL_INIT_LOADADDR_PROG(app_tpnt->loadaddr, auxvt[AT_PHDR].a_un.a_val - phdr->p_vaddr);
404 if (DL_LOADADDR_BASE(app_tpnt->loadaddr))
405 _dl_debug_early("Position Independent Executable: "
406 "app_tpnt->loadaddr=%x\n", DL_LOADADDR_BASE(app_tpnt->loadaddr));
410 * This is used by gdb to locate the chain of shared libraries that are
413 debug_addr = _dl_zalloc(sizeof(struct r_debug));
415 ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_val;
416 for (i = 0; i < auxvt[AT_PHNUM].a_un.a_val; i++, ppnt++) {
417 if (ppnt->p_type == PT_GNU_RELRO) {
418 relro_addr = ppnt->p_vaddr;
419 relro_size = ppnt->p_memsz;
421 if (!app_mapaddr && (ppnt->p_type == PT_LOAD)) {
422 app_mapaddr = DL_RELOC_ADDR (app_tpnt->loadaddr, ppnt->p_vaddr);
424 if (ppnt->p_type == PT_DYNAMIC) {
425 dpnt = (ElfW(Dyn) *) DL_RELOC_ADDR(app_tpnt->loadaddr, ppnt->p_vaddr);
426 _dl_parse_dynamic_info(dpnt, app_tpnt->dynamic_info, debug_addr, app_tpnt->loadaddr);
427 #ifndef __FORCE_SHAREABLE_TEXT_SEGMENTS__
428 /* Ugly, ugly. We need to call mprotect to change the
429 * protection of the text pages so that we can do the
430 * dynamic linking. We can set the protection back
431 * again once we are done.
433 _dl_debug_early("calling mprotect on the application program\n");
434 /* Now cover the application program. */
435 if (app_tpnt->dynamic_info[DT_TEXTREL]) {
436 ElfW(Phdr) *ppnt_outer = ppnt;
437 ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_val;
438 for (i = 0; i < auxvt[AT_PHNUM].a_un.a_val; i++, ppnt++) {
439 if (ppnt->p_type == PT_LOAD && !(ppnt->p_flags & PF_W))
440 _dl_mprotect((void *) (DL_RELOC_ADDR(app_tpnt->loadaddr, ppnt->p_vaddr) & PAGE_ALIGN),
441 (DL_RELOC_ADDR(app_tpnt->loadaddr, ppnt->p_vaddr) & ADDR_ALIGN) +
442 (unsigned long) ppnt->p_filesz,
443 PROT_READ | PROT_WRITE | PROT_EXEC);
448 if (app_tpnt->dynamic_info[DT_TEXTREL]) {
449 _dl_dprintf(_dl_debug_file, "Can't modify application's text section; use the GCC option -fPIE for position-independent executables.\n");
454 #ifndef ALLOW_ZERO_PLTGOT
455 /* make sure it's really there. */
456 if (app_tpnt->dynamic_info[DT_PLTGOT] == 0)
459 /* OK, we have what we need - slip this one into the list. */
460 app_tpnt = _dl_add_elf_hash_table(_dl_progname, app_tpnt->loadaddr,
461 app_tpnt->dynamic_info,
462 (unsigned long) DL_RELOC_ADDR(app_tpnt->loadaddr, ppnt->p_vaddr),
464 _dl_loaded_modules->libtype = elf_executable;
465 _dl_loaded_modules->ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_val;
466 _dl_loaded_modules->n_phent = auxvt[AT_PHNUM].a_un.a_val;
467 _dl_symbol_tables = rpnt = _dl_zalloc(sizeof(struct dyn_elf));
468 rpnt->dyn = _dl_loaded_modules;
469 app_tpnt->mapaddr = app_mapaddr;
470 app_tpnt->rtld_flags = unlazy | RTLD_GLOBAL;
471 app_tpnt->usage_count++;
472 app_tpnt->symbol_scope = _dl_symbol_tables;
473 lpnt = (unsigned long *) (app_tpnt->dynamic_info[DT_PLTGOT]);
474 #ifdef ALLOW_ZERO_PLTGOT
477 INIT_GOT(lpnt, _dl_loaded_modules);
480 /* OK, fill this in - we did not have this before */
481 if (ppnt->p_type == PT_INTERP) {
482 tpnt->libname = (char *) DL_RELOC_ADDR(app_tpnt->loadaddr, ppnt->p_vaddr);
483 #ifdef __LDSO_SEARCH_INTERP_PATH__
486 /* Store the path where the shared lib loader was found
489 _dl_ldsopath = _dl_strdup(tpnt->libname);
490 ptmp = _dl_strrchr(_dl_ldsopath, '/');
491 if (ptmp != _dl_ldsopath)
494 _dl_debug_early("Lib Loader: (%x) %s\n", (unsigned) DL_LOADADDR_BASE(tpnt->loadaddr), tpnt->libname);
498 /* Discover any TLS sections if the target supports them. */
499 if (ppnt->p_type == PT_TLS) {
500 #if defined(USE_TLS) && USE_TLS
501 if (ppnt->p_memsz > 0) {
502 app_tpnt->l_tls_blocksize = ppnt->p_memsz;
503 app_tpnt->l_tls_align = ppnt->p_align;
504 if (ppnt->p_align == 0)
505 app_tpnt->l_tls_firstbyte_offset = 0;
507 app_tpnt->l_tls_firstbyte_offset =
508 (ppnt->p_vaddr & (ppnt->p_align - 1));
509 app_tpnt->l_tls_initimage_size = ppnt->p_filesz;
510 app_tpnt->l_tls_initimage = (void *) ppnt->p_vaddr;
512 /* This image gets the ID one. */
513 _dl_tls_max_dtv_idx = app_tpnt->l_tls_modid = 1;
516 _dl_debug_early("Found TLS header for appplication program\n");
519 _dl_dprintf(_dl_debug_file, "Program uses unsupported TLS data!\n");
524 app_tpnt->relro_addr = relro_addr;
525 app_tpnt->relro_size = relro_size;
527 #if defined(USE_TLS) && USE_TLS
529 * Adjust the address of the TLS initialization image in
530 * case the executable is actually an ET_DYN object.
532 if (app_tpnt->l_tls_initimage != NULL) {
533 app_tpnt->l_tls_initimage =
534 (char *) app_tpnt->l_tls_initimage + app_tpnt->loadaddr;
535 _dl_debug_early("Relocated TLS initial image from %x to %x (size = %x)\n",
536 (unsigned int)app_tpnt->l_tls_initimage,
537 app_tpnt->l_tls_initimage, app_tpnt->l_tls_initimage_size);
541 #ifdef __SUPPORT_LD_DEBUG__
542 _dl_debug = _dl_getenv("LD_DEBUG", envp);
544 if (_dl_strstr(_dl_debug, "all")) {
545 _dl_debug_detail = _dl_debug_move = _dl_debug_symbols
546 = _dl_debug_reloc = _dl_debug_bindings = _dl_debug_nofixups = (void*)1;
548 _dl_debug_detail = _dl_strstr(_dl_debug, "detail");
549 _dl_debug_move = _dl_strstr(_dl_debug, "move");
550 _dl_debug_symbols = _dl_strstr(_dl_debug, "sym");
551 _dl_debug_reloc = _dl_strstr(_dl_debug, "reloc");
552 _dl_debug_nofixups = _dl_strstr(_dl_debug, "nofix");
553 _dl_debug_bindings = _dl_strstr(_dl_debug, "bind");
558 const char *dl_debug_output;
560 dl_debug_output = _dl_getenv("LD_DEBUG_OUTPUT", envp);
562 if (dl_debug_output) {
563 char tmp[22], *tmp1, *filename;
566 _dl_memset(tmp, 0, sizeof(tmp));
567 tmp1 = _dl_simple_ltoa( tmp, (unsigned long)_dl_getpid());
569 len1 = _dl_strlen(dl_debug_output);
570 len2 = _dl_strlen(tmp1);
572 filename = _dl_malloc(len1 + len2 + 2);
575 _dl_strcpy (filename, dl_debug_output);
576 filename[len1] = '.';
577 _dl_strcpy (&filename[len1+1], tmp1);
579 _dl_debug_file = _dl_open(filename, O_WRONLY|O_CREAT, 0644);
580 if (_dl_debug_file < 0) {
582 _dl_dprintf(_dl_debug_file, "can't open file: '%s'\n",filename);
589 if (_dl_getenv("LD_TRACE_LOADED_OBJECTS", envp) != NULL) {
590 trace_loaded_objects++;
593 #ifndef __LDSO_LDD_SUPPORT__
594 if (trace_loaded_objects) {
595 _dl_dprintf(_dl_debug_file, "Use the ldd provided by uClibc\n");
601 * OK, fix one more thing - set up debug_addr so it will point
602 * to our chain. Later we may need to fill in more fields, but this
603 * should be enough for now.
605 debug_addr->r_map = (struct link_map *) _dl_loaded_modules;
606 debug_addr->r_version = 1;
607 debug_addr->r_ldbase = (ElfW(Addr)) DL_LOADADDR_BASE(load_addr);
608 debug_addr->r_brk = (unsigned long) &_dl_debug_state;
609 _dl_debug_addr = debug_addr;
611 /* Do not notify the debugger until the interpreter is in the list */
613 /* OK, we now have the application in the list, and we have some
614 * basic stuff in place. Now search through the list for other shared
615 * libraries that should be loaded, and insert them on the list in the
621 #ifdef __LDSO_PRELOAD_ENV_SUPPORT__
626 while (*str == ':' || *str == ' ' || *str == '\t')
631 while (*str2 && *str2 != ':' && *str2 != ' ' && *str2 != '\t')
636 if (!_dl_secure || _dl_strchr(str, '/') == NULL) {
637 _dl_if_debug_dprint("\tfile='%s'; needed by '%s'\n", str, _dl_progname);
639 tpnt1 = _dl_load_shared_library(_dl_secure, &rpnt, NULL, str, trace_loaded_objects);
641 #ifdef __LDSO_LDD_SUPPORT__
642 if (trace_loaded_objects)
643 _dl_dprintf(1, "\t%s => not found\n", str);
647 _dl_dprintf(_dl_debug_file, "%s: can't load " "library '%s'\n", _dl_progname, str);
651 tpnt1->rtld_flags = unlazy | RTLD_GLOBAL;
653 _dl_debug_early("Loading: (%x) %s\n", DL_LOADADDR_BASE(tpnt1->loadaddr), tpnt1->libname);
655 #ifdef __LDSO_LDD_SUPPORT__
656 if (trace_loaded_objects &&
657 tpnt1->usage_count == 1) {
658 /* This is a real hack to make
659 * ldd not print the library
660 * itself when run on a
663 if (_dl_strcmp(_dl_progname, str) != 0)
664 _dl_dprintf(1, "\t%s => %s (%x)\n", str, tpnt1->libname,
665 DL_LOADADDR_BASE(tpnt1->loadaddr));
673 while (*str == ':' || *str == ' ' || *str == '\t')
677 #endif /* __LDSO_PRELOAD_ENV_SUPPORT__ */
679 #ifdef __LDSO_PRELOAD_FILE_SUPPORT__
685 if (_dl_stat(LDSO_PRELOAD, &st) || st.st_size == 0) {
689 if ((fd = _dl_open(LDSO_PRELOAD, O_RDONLY, 0)) < 0) {
690 _dl_dprintf(_dl_debug_file, "%s: can't open file '%s'\n",
691 _dl_progname, LDSO_PRELOAD);
695 preload = (caddr_t) _dl_mmap(0, st.st_size + 1,
696 PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
698 if (preload == (caddr_t) -1) {
699 _dl_dprintf(_dl_debug_file, "%s:%i: can't map '%s'\n",
700 _dl_progname, __LINE__, LDSO_PRELOAD);
704 /* convert all separators and comments to spaces */
705 for (cp = preload; *cp; /*nada */ ) {
706 if (*cp == ':' || *cp == '\t' || *cp == '\n') {
708 } else if (*cp == '#') {
711 } while (*cp != '\n' && *cp != '\0');
717 /* find start of first library */
718 for (cp = preload; *cp && *cp == ' '; cp++)
722 /* find end of library */
723 for (cp2 = cp; *cp && *cp != ' '; cp++)
728 _dl_if_debug_dprint("\tfile='%s'; needed by '%s'\n", cp2, _dl_progname);
730 tpnt1 = _dl_load_shared_library(0, &rpnt, NULL, cp2, trace_loaded_objects);
732 # ifdef __LDSO_LDD_SUPPORT__
733 if (trace_loaded_objects)
734 _dl_dprintf(1, "\t%s => not found\n", cp2);
738 _dl_dprintf(_dl_debug_file, "%s: can't load library '%s'\n", _dl_progname, cp2);
742 tpnt1->rtld_flags = unlazy | RTLD_GLOBAL;
744 _dl_debug_early("Loading: (%x) %s\n", DL_LOADADDR_BASE(tpnt1->loadaddr), tpnt1->libname);
746 # ifdef __LDSO_LDD_SUPPORT__
747 if (trace_loaded_objects &&
748 tpnt1->usage_count == 1) {
749 _dl_dprintf(1, "\t%s => %s (%x)\n",
751 DL_LOADADDR_BASE(tpnt1->loadaddr));
756 /* find start of next library */
758 for ( /*nada */ ; *cp && *cp == ' '; cp++)
762 _dl_munmap(preload, st.st_size + 1);
764 #endif /* __LDSO_PRELOAD_FILE_SUPPORT__ */
767 for (tcurr = _dl_loaded_modules; tcurr; tcurr = tcurr->next) {
768 ElfW(Dyn) *this_dpnt;
771 for (this_dpnt = (ElfW(Dyn) *) tcurr->dynamic_addr; this_dpnt->d_tag; this_dpnt++) {
772 if (this_dpnt->d_tag == DT_NEEDED) {
774 struct init_fini_list *tmp;
776 lpntstr = (char*) (tcurr->dynamic_info[DT_STRTAB] + this_dpnt->d_un.d_val);
777 name = _dl_get_last_path_component(lpntstr);
778 if (_dl_strcmp(name, UCLIBC_LDSO) == 0)
781 _dl_if_debug_dprint("\tfile='%s'; needed by '%s'\n", lpntstr, _dl_progname);
783 if (!(tpnt1 = _dl_load_shared_library(0, &rpnt, tcurr, lpntstr, trace_loaded_objects))) {
784 #ifdef __LDSO_LDD_SUPPORT__
785 if (trace_loaded_objects) {
786 _dl_dprintf(1, "\t%s => not found\n", lpntstr);
791 _dl_dprintf(_dl_debug_file, "%s: can't load library '%s'\n", _dl_progname, lpntstr);
796 tmp = alloca(sizeof(struct init_fini_list)); /* Allocates on stack, no need to free this memory */
798 tmp->next = tcurr->init_fini;
799 tcurr->init_fini = tmp;
801 tpnt1->rtld_flags = unlazy | RTLD_GLOBAL;
803 _dl_debug_early("Loading: (%x) %s\n", DL_LOADADDR_BASE(tpnt1->loadaddr), tpnt1->libname);
805 #ifdef __LDSO_LDD_SUPPORT__
806 if (trace_loaded_objects &&
807 tpnt1->usage_count == 1) {
808 _dl_dprintf(1, "\t%s => %s (%x)\n",
809 lpntstr, tpnt1->libname,
810 DL_LOADADDR_BASE(tpnt1->loadaddr));
818 --nlist; /* Exclude the application. */
819 init_fini_list = _dl_malloc(nlist * sizeof(struct elf_resolve *));
821 for (tcurr = _dl_loaded_modules->next; tcurr; tcurr = tcurr->next) {
822 init_fini_list[i++] = tcurr;
825 /* Sort the INIT/FINI list in dependency order. */
826 for (tcurr = _dl_loaded_modules->next; tcurr; tcurr = tcurr->next) {
829 for (j = 0; init_fini_list[j] != tcurr; ++j)
831 for (k = j + 1; k < nlist; ++k) {
832 struct init_fini_list *runp = init_fini_list[k]->init_fini;
834 for (; runp; runp = runp->next) {
835 if (runp->tpnt == tcurr) {
836 struct elf_resolve *here = init_fini_list[k];
837 _dl_if_debug_dprint("Move %s from pos %d to %d in INIT/FINI list\n", here->libname, k, j);
838 for (i = (k - j); i; --i)
839 init_fini_list[i+j] = init_fini_list[i+j-1];
840 init_fini_list[j] = here;
847 #ifdef __SUPPORT_LD_DEBUG__
849 _dl_dprintf(_dl_debug_file, "\nINIT/FINI order and dependencies:\n");
850 for (i = 0; i < nlist; i++) {
851 struct init_fini_list *tmp;
853 _dl_dprintf(_dl_debug_file, "lib: %s has deps:\n",
854 init_fini_list[i]->libname);
855 tmp = init_fini_list[i]->init_fini;
856 for (; tmp; tmp = tmp->next)
857 _dl_dprintf(_dl_debug_file, " %s ", tmp->tpnt->libname);
858 _dl_dprintf(_dl_debug_file, "\n");
864 * If the program interpreter is not in the module chain, add it.
865 * This will be required for dlopen to be able to access the internal
866 * functions in the dynamic linker and to relocate the interpreter
867 * again once all libs are loaded.
870 ElfW(Ehdr) *epnt = (ElfW(Ehdr) *) auxvt[AT_BASE].a_un.a_val;
871 ElfW(Phdr) *myppnt = (ElfW(Phdr) *) DL_RELOC_ADDR(load_addr, epnt->e_phoff);
874 tpnt = _dl_add_elf_hash_table(tpnt->libname, load_addr,
876 (unsigned long)tpnt->dynamic_addr,
879 if (_dl_stat(tpnt->libname, &st) >= 0) {
880 tpnt->st_dev = st.st_dev;
881 tpnt->st_ino = st.st_ino;
883 tpnt->n_phent = epnt->e_phnum;
885 for (j = 0; j < epnt->e_phnum; j++, myppnt++) {
886 if (myppnt->p_type == PT_GNU_RELRO) {
887 tpnt->relro_addr = myppnt->p_vaddr;
888 tpnt->relro_size = myppnt->p_memsz;
892 tpnt->libtype = program_interpreter;
894 tpnt->symbol_scope = _dl_symbol_tables;
896 rpnt->next = _dl_zalloc(sizeof(struct dyn_elf));
897 rpnt->next->prev = rpnt;
900 rpnt = _dl_zalloc(sizeof(struct dyn_elf));
903 tpnt->rtld_flags = RTLD_NOW | RTLD_GLOBAL; /* Must not be LAZY */
904 #ifdef RERELOCATE_LDSO
905 /* Only rerelocate functions for now. */
906 tpnt->init_flag = RELOCS_DONE;
907 lpnt = (unsigned long *) (tpnt->dynamic_info[DT_PLTGOT]);
908 # ifdef ALLOW_ZERO_PLTGOT
909 if (tpnt->dynamic_info[DT_PLTGOT])
911 INIT_GOT(lpnt, tpnt);
913 tpnt->init_flag = RELOCS_DONE | JMP_RELOCS_DONE;
918 #ifdef __LDSO_LDD_SUPPORT__
919 /* End of the line for ldd.... */
920 if (trace_loaded_objects) {
921 _dl_dprintf(1, "\t%s => %s (%x)\n",
922 rpnt->dyn->libname + _dl_strlen(_dl_ldsopath) + 1,
923 rpnt->dyn->libname, DL_LOADADDR_BASE(rpnt->dyn->loadaddr));
928 #if defined(USE_TLS) && USE_TLS
929 /* We do not initialize any of the TLS functionality unless any of the
930 * initial modules uses TLS. This makes dynamic loading of modules with
931 * TLS impossible, but to support it requires either eagerly doing setup
932 * now or lazily doing it later. Doing it now makes us incompatible with
933 * an old kernel that can't perform TLS_INIT_TP, even if no TLS is ever
934 * used. Trying to do it lazily is too hairy to try when there could be
935 * multiple threads (from a non-TLS-using libpthread). */
936 bool was_tls_init_tp_called = tls_init_tp_called;
938 _dl_debug_early("Calling init_tls()!\n");
942 #ifdef __UCLIBC_HAS_SSP__
943 /* Set up the stack checker's canary. */
944 stack_chk_guard = _dl_setup_stack_chk_guard ();
945 # ifdef THREAD_SET_STACK_GUARD
946 THREAD_SET_STACK_GUARD (stack_chk_guard);
947 # ifdef __UCLIBC_HAS_SSP_COMPAT__
948 __guard = stack_chk_guard;
951 __stack_chk_guard = stack_chk_guard;
956 _dl_debug_early("Beginning relocation fixups\n");
960 * Relocation of the GOT entries for MIPS have to be done
961 * after all the libraries have been loaded.
963 _dl_perform_mips_global_got_relocations(_dl_loaded_modules, !unlazy);
967 * OK, now all of the kids are tucked into bed in their proper
968 * addresses. Now we go through and look for REL and RELA records that
969 * indicate fixups to the GOT tables. We need to do this in reverse
970 * order so that COPY directives work correctly.
972 if (_dl_symbol_tables)
973 if (_dl_fixup(_dl_symbol_tables, unlazy))
976 for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) {
977 if (tpnt->relro_size)
978 _dl_protect_relro (tpnt);
981 #if defined(USE_TLS) && USE_TLS
982 if (!was_tls_init_tp_called && _dl_tls_max_dtv_idx > 0)
983 ++_dl_tls_generation;
985 _dl_debug_early("Calling _dl_allocate_tls_init()!\n");
987 /* Now that we have completed relocation, the initializer data
988 for the TLS blocks has its final values and we can copy them
989 into the main thread's TLS area, which we allocated above. */
990 _dl_allocate_tls_init (tcbp);
992 /* And finally install it for the main thread. If ld.so itself uses
993 TLS we know the thread pointer was initialized earlier. */
994 if (! tls_init_tp_called) {
995 const char *lossage = (char *) TLS_INIT_TP (tcbp, USE___THREAD);
996 if (__builtin_expect (lossage != NULL, 0)) {
997 _dl_debug_early("cannot set up thread-local storage: %s\n", lossage);
1001 #endif /* USE_TLS */
1003 /* OK, at this point things are pretty much ready to run. Now we need
1004 * to touch up a few items that are required, and then we can let the
1005 * user application have at it. Note that the dynamic linker itself
1006 * is not guaranteed to be fully dynamicly linked if we are using
1007 * ld.so.1, so we have to look up each symbol individually.
1010 _dl_envp = (unsigned long *) (intptr_t) _dl_find_hash(__C_SYMBOL_PREFIX__ "__environ", _dl_symbol_tables, NULL, 0, NULL);
1012 *_dl_envp = (unsigned long) envp;
1014 #ifndef __FORCE_SHAREABLE_TEXT_SEGMENTS__
1019 /* We had to set the protections of all pages to R/W for
1020 * dynamic linking. Set text pages back to R/O.
1022 for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) {
1023 for (myppnt = tpnt->ppnt, j = 0; j < tpnt->n_phent; j++, myppnt++) {
1024 if (myppnt->p_type == PT_LOAD && !(myppnt->p_flags & PF_W) && tpnt->dynamic_info[DT_TEXTREL]) {
1025 _dl_mprotect((void *) (DL_RELOC_ADDR(tpnt->loadaddr, myppnt->p_vaddr) & PAGE_ALIGN),
1026 (myppnt->p_vaddr & ADDR_ALIGN) + (unsigned long) myppnt->p_filesz, LXFLAGS(myppnt->p_flags));
1033 /* Notify the debugger we have added some objects. */
1034 _dl_debug_addr->r_state = RT_ADD;
1037 /* Run pre-initialization functions for the executable. */
1038 _dl_run_array_forward(_dl_loaded_modules->dynamic_info[DT_PREINIT_ARRAY],
1039 _dl_loaded_modules->dynamic_info[DT_PREINIT_ARRAYSZ],
1040 _dl_loaded_modules->loadaddr);
1042 /* Run initialization functions for loaded objects. For the
1043 main executable, they will be run from __uClibc_main. */
1044 for (i = nlist; i; --i) {
1045 tpnt = init_fini_list[i-1];
1046 tpnt->init_fini = NULL; /* Clear, since alloca was used */
1047 if (tpnt->init_flag & INIT_FUNCS_CALLED)
1049 tpnt->init_flag |= INIT_FUNCS_CALLED;
1051 if (tpnt->dynamic_info[DT_INIT]) {
1052 void (*dl_elf_func) (void);
1054 dl_elf_func = (void (*)(void)) DL_RELOC_ADDR(tpnt->loadaddr, tpnt->dynamic_info[DT_INIT]);
1056 _dl_if_debug_dprint("calling INIT: %s\n\n", tpnt->libname);
1058 DL_CALL_FUNC_AT_ADDR (dl_elf_func, tpnt->loadaddr, (void(*)(void)));
1061 _dl_run_init_array(tpnt);
1064 /* Find the real malloc function and make ldso functions use that from now on */
1065 _dl_malloc_function = (void* (*)(size_t)) (intptr_t) _dl_find_hash(__C_SYMBOL_PREFIX__ "malloc",
1066 _dl_symbol_tables, NULL, ELF_RTYPE_CLASS_PLT, NULL);
1068 #if defined(USE_TLS) && USE_TLS
1069 /* Find the real functions and make ldso functions use them from now on */
1070 _dl_calloc_function = (void* (*)(size_t, size_t)) (intptr_t)
1071 _dl_find_hash(__C_SYMBOL_PREFIX__ "calloc", _dl_symbol_tables, NULL, ELF_RTYPE_CLASS_PLT, NULL);
1073 _dl_realloc_function = (void* (*)(void *, size_t)) (intptr_t)
1074 _dl_find_hash(__C_SYMBOL_PREFIX__ "realloc", _dl_symbol_tables, NULL, ELF_RTYPE_CLASS_PLT, NULL);
1076 _dl_free_function = (void (*)(void *)) (intptr_t)
1077 _dl_find_hash(__C_SYMBOL_PREFIX__ "free", _dl_symbol_tables, NULL, ELF_RTYPE_CLASS_PLT, NULL);
1079 _dl_memalign_function = (void* (*)(size_t, size_t)) (intptr_t)
1080 _dl_find_hash(__C_SYMBOL_PREFIX__ "memalign", _dl_symbol_tables, NULL, ELF_RTYPE_CLASS_PLT, NULL);
1084 /* Notify the debugger that all objects are now mapped in. */
1085 _dl_debug_addr->r_state = RT_CONSISTENT;
1089 #include "dl-hash.c"