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
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 char *_dl_preload = NULL; /* Things to be loaded before the libs */
51 char *_dl_ldsopath = NULL; /* Location of the shared lib loader */
52 int _dl_errno = 0; /* We can't use the real errno in ldso */
53 size_t _dl_pagesize = 0; /* Store the page size for use later */
54 struct r_debug *_dl_debug_addr = NULL; /* Used to communicate with the gdb debugger */
55 void *(*_dl_malloc_function) (size_t size) = NULL;
56 void (*_dl_free_function) (void *p) = NULL;
58 static int _dl_secure = 1; /* Are we dealing with setuid stuff? */
60 #ifdef __SUPPORT_LD_DEBUG__
61 char *_dl_debug = NULL;
62 char *_dl_debug_symbols = NULL;
63 char *_dl_debug_move = NULL;
64 char *_dl_debug_reloc = NULL;
65 char *_dl_debug_detail = NULL;
66 char *_dl_debug_nofixups = NULL;
67 char *_dl_debug_bindings = NULL;
68 int _dl_debug_file = 2;
71 /* Needed for standalone execution. */
72 unsigned long attribute_hidden _dl_skip_args = 0;
73 const char *_dl_progname = UCLIBC_LDSO; /* The name of the executable being run */
74 #include "dl-startup.c"
75 #include "dl-symbols.c"
79 * This stub function is used by some debuggers. The idea is that they
80 * can set an internal breakpoint on it, so that we are notified when the
81 * address mapping is changed in some way.
83 void _dl_debug_state(void);
84 rtld_hidden_proto(_dl_debug_state, noinline);
85 void _dl_debug_state(void)
87 /* Make sure GCC doesn't recognize this function as pure, to avoid
88 * having the calls optimized away.
92 rtld_hidden_def(_dl_debug_state);
94 static unsigned char *_dl_malloc_addr = NULL; /* Lets _dl_malloc use the already allocated memory page */
95 static unsigned char *_dl_mmap_zero = NULL; /* Also used by _dl_malloc */
97 static struct elf_resolve **init_fini_list;
98 static unsigned int nlist; /* # items in init_fini_list */
99 extern void _start(void);
101 #ifdef __UCLIBC_HAS_SSP__
102 # include <dl-osinfo.h>
103 uintptr_t stack_chk_guard;
104 # ifndef THREAD_SET_STACK_GUARD
105 /* Only exported for architectures that don't store the stack guard canary
106 * in local thread area. */
107 uintptr_t __stack_chk_guard attribute_relro;
108 # ifdef __UCLIBC_HAS_SSP_COMPAT__
109 strong_alias(__stack_chk_guard,__guard)
111 # elif __UCLIBC_HAS_SSP_COMPAT__
112 uintptr_t __guard attribute_relro;
116 char *_dl_getenv(const char *symbol, char **envp)
121 while ((pnt = *envp++)) {
123 while (*pnt && *pnt == *pnt1)
125 if (!*pnt || *pnt != '=' || *pnt1)
132 void _dl_unsetenv(const char *symbol, char **envp)
136 char **newenvp = envp;
138 for (pnt = *envp; pnt; pnt = *++envp) {
140 while (*pnt && *pnt == *pnt1)
142 if (!*pnt || *pnt != '=' || *pnt1)
149 static int _dl_suid_ok(void)
151 __kernel_uid_t uid, euid;
152 __kernel_gid_t gid, egid;
155 euid = _dl_geteuid();
157 egid = _dl_getegid();
159 if (uid == euid && gid == egid) {
165 void *_dl_malloc(size_t size)
170 _dl_debug_early("request for %d bytes\n", size);
173 if (_dl_malloc_function)
174 return (*_dl_malloc_function) (size);
176 if (_dl_malloc_addr - _dl_mmap_zero + size > _dl_pagesize) {
179 /* Since the above assumes we get a full page even if
180 we request less than that, make sure we request a
181 full page, since uClinux may give us less than than
182 a full page. We might round even
183 larger-than-a-page sizes, but we end up never
184 reusing _dl_mmap_zero/_dl_malloc_addr in that case,
187 The actual page size doesn't really matter; as long
188 as we're self-consistent here, we're safe. */
189 if (size < _dl_pagesize)
190 rounded_size = (size + ADDR_ALIGN) & _dl_pagesize;
194 _dl_debug_early("mmapping more memory\n");
195 _dl_mmap_zero = _dl_malloc_addr = _dl_mmap((void *) 0, rounded_size,
196 PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
197 if (_dl_mmap_check_error(_dl_mmap_zero)) {
198 _dl_dprintf(_dl_debug_file, "%s: mmap of a spare page failed!\n", _dl_progname);
202 retval = _dl_malloc_addr;
203 _dl_malloc_addr += size;
206 * Align memory to DL_MALLOC_ALIGN byte boundary. Some
207 * platforms require this, others simply get better
210 _dl_malloc_addr = (unsigned char *) (((unsigned long) _dl_malloc_addr + DL_MALLOC_ALIGN - 1) & ~(DL_MALLOC_ALIGN - 1));
214 static void *_dl_zalloc(size_t size)
216 void *p = _dl_malloc(size);
218 _dl_memset(p, 0, size);
223 void * _dl_memalign (size_t __boundary, size_t __size)
230 if (_dl_memalign_function)
231 return (*_dl_memalign_function) (__boundary, __size);
233 while (rounded < __boundary) {
234 rounded = (1 << i++);
237 delta = (((size_t) _dl_malloc_addr + __size) & (rounded - 1));
239 if ((result = _dl_malloc(rounded - delta)) == NULL)
242 result = _dl_malloc(__size);
248 static void __attribute__ ((destructor)) __attribute_used__ _dl_fini(void)
251 struct elf_resolve * tpnt;
253 for (i = 0; i < nlist; ++i) {
254 tpnt = init_fini_list[i];
255 if (tpnt->init_flag & FINI_FUNCS_CALLED)
257 tpnt->init_flag |= FINI_FUNCS_CALLED;
258 _dl_run_fini_array(tpnt);
259 if (tpnt->dynamic_info[DT_FINI]) {
260 void (*dl_elf_func) (void);
262 dl_elf_func = (void (*)(void)) (intptr_t) DL_RELOC_ADDR(tpnt->loadaddr, tpnt->dynamic_info[DT_FINI]);
263 _dl_if_debug_dprint("\ncalling FINI: %s\n\n", tpnt->libname);
264 DL_CALL_FUNC_AT_ADDR (dl_elf_func, tpnt->loadaddr, (void(*)(void)));
269 void _dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr,
270 ElfW(auxv_t) auxvt[AT_EGID + 1], char **envp,
272 DL_GET_READY_TO_RUN_EXTRA_PARMS)
274 ElfW(Addr) app_mapaddr = 0;
279 int unlazy = 0, trace_loaded_objects = 0;
280 struct dyn_elf *rpnt;
281 struct elf_resolve *tcurr;
282 struct elf_resolve *tpnt1;
283 struct elf_resolve app_tpnt_tmp;
284 struct elf_resolve *app_tpnt = &app_tpnt_tmp;
285 struct r_debug *debug_addr;
287 unsigned long *_dl_envp; /* The environment address */
288 ElfW(Addr) relro_addr = 0;
289 size_t relro_size = 0;
296 /* Wahoo!!! We managed to make a function call! Get malloc
297 * setup so we can use _dl_dprintf() to print debug noise
298 * instead of the SEND_STDERR macros used in dl-startup.c */
300 _dl_memset(app_tpnt, 0, sizeof(*app_tpnt));
302 /* Store the page size for later use */
303 _dl_pagesize = (auxvt[AT_PAGESZ].a_un.a_val) ? (size_t) auxvt[AT_PAGESZ].a_un.a_val : PAGE_SIZE;
304 /* Make it so _dl_malloc can use the page of memory we have already
305 * allocated. We shouldn't need to grab any more memory. This must
306 * be first since things like _dl_dprintf() use _dl_malloc()...
308 _dl_malloc_addr = (unsigned char *)_dl_pagesize;
312 _dl_debug_early("Cool, ldso survived making function calls\n");
314 /* Now we have done the mandatory linking of some things. We are now
315 * free to start using global variables, since these things have all
316 * been fixed up by now. Still no function calls outside of this
317 * library, since the dynamic resolver is not yet ready.
320 _dl_progname = argv[0];
323 if (_start == (void *) auxvt[AT_ENTRY].a_un.a_val) {
324 _dl_dprintf(_dl_debug_file, "Standalone execution is not supported yet\n");
328 /* Start to build the tables of the modules that are required for
329 * this beast to run. We start with the basic executable, and then
330 * go from there. Eventually we will run across ourself, and we
331 * will need to properly deal with that as well.
334 if (_dl_getenv("LD_BIND_NOW", envp))
337 /* Now we need to figure out what kind of options are selected.
338 * Note that for SUID programs we ignore the settings in
341 if ((auxvt[AT_UID].a_un.a_val == (size_t)-1 && _dl_suid_ok()) ||
342 (auxvt[AT_UID].a_un.a_val != (size_t)-1 &&
343 auxvt[AT_UID].a_un.a_val == auxvt[AT_EUID].a_un.a_val &&
344 auxvt[AT_GID].a_un.a_val == auxvt[AT_EGID].a_un.a_val)) {
346 _dl_preload = _dl_getenv("LD_PRELOAD", envp);
347 _dl_library_path = _dl_getenv("LD_LIBRARY_PATH", envp);
349 static const char unsecure_envvars[] =
350 #ifdef EXTRA_UNSECURE_ENVVARS
351 EXTRA_UNSECURE_ENVVARS
357 nextp = unsecure_envvars;
359 _dl_unsetenv (nextp, envp);
360 /* We could use rawmemchr but this need not be fast. */
361 nextp = _dl_strchr(nextp, '\0') + 1;
362 } while (*nextp != '\0');
364 _dl_library_path = NULL;
365 /* SUID binaries can be exploited if they do LAZY relocation. */
370 _dl_error_catch_tsd = &_dl_initial_error_catch_tsd;
371 _dl_init_static_tls = &_dl_nothread_init_static_tls;
374 #ifdef __UCLIBC_HAS_SSP__
375 /* Set up the stack checker's canary. */
376 stack_chk_guard = _dl_setup_stack_chk_guard ();
377 # ifdef THREAD_SET_STACK_GUARD
378 THREAD_SET_STACK_GUARD (stack_chk_guard);
379 # ifdef __UCLIBC_HAS_SSP_COMPAT__
380 __guard = stack_chk_guard;
383 __stack_chk_guard = stack_chk_guard;
387 /* At this point we are now free to examine the user application,
388 * and figure out which libraries are supposed to be called. Until
389 * we have this list, we will not be completely ready for dynamic
393 /* Find the runtime load address of the main executable. This may be
394 * different from what the ELF header says for ET_DYN/PIE executables.
398 ElfW(Phdr) *phdr = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_val;
400 for (idx = 0; idx < auxvt[AT_PHNUM].a_un.a_val; idx++, phdr++)
401 if (phdr->p_type == PT_PHDR) {
402 DL_INIT_LOADADDR_PROG(app_tpnt->loadaddr, auxvt[AT_PHDR].a_un.a_val - phdr->p_vaddr);
406 if (DL_LOADADDR_BASE(app_tpnt->loadaddr))
407 _dl_debug_early("Position Independent Executable: "
408 "app_tpnt->loadaddr=%x\n", DL_LOADADDR_BASE(app_tpnt->loadaddr));
412 * This is used by gdb to locate the chain of shared libraries that are
415 debug_addr = _dl_zalloc(sizeof(struct r_debug));
417 ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_val;
418 for (i = 0; i < auxvt[AT_PHNUM].a_un.a_val; i++, ppnt++) {
419 if (ppnt->p_type == PT_GNU_RELRO) {
420 relro_addr = ppnt->p_vaddr;
421 relro_size = ppnt->p_memsz;
423 if (!app_mapaddr && (ppnt->p_type == PT_LOAD)) {
424 app_mapaddr = DL_RELOC_ADDR (app_tpnt->loadaddr, ppnt->p_vaddr);
426 if (ppnt->p_type == PT_DYNAMIC) {
427 dpnt = (ElfW(Dyn) *) DL_RELOC_ADDR(app_tpnt->loadaddr, ppnt->p_vaddr);
428 _dl_parse_dynamic_info(dpnt, app_tpnt->dynamic_info, debug_addr, app_tpnt->loadaddr);
429 #ifndef __FORCE_SHAREABLE_TEXT_SEGMENTS__
430 /* Ugly, ugly. We need to call mprotect to change the
431 * protection of the text pages so that we can do the
432 * dynamic linking. We can set the protection back
433 * again once we are done.
435 _dl_debug_early("calling mprotect on the application program\n");
436 /* Now cover the application program. */
437 if (app_tpnt->dynamic_info[DT_TEXTREL]) {
438 ElfW(Phdr) *ppnt_outer = ppnt;
439 ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_val;
440 for (i = 0; i < auxvt[AT_PHNUM].a_un.a_val; i++, ppnt++) {
441 if (ppnt->p_type == PT_LOAD && !(ppnt->p_flags & PF_W))
442 _dl_mprotect((void *) (DL_RELOC_ADDR(app_tpnt->loadaddr, ppnt->p_vaddr) & PAGE_ALIGN),
443 (DL_RELOC_ADDR(app_tpnt->loadaddr, ppnt->p_vaddr) & ADDR_ALIGN) +
444 (unsigned long) ppnt->p_filesz,
445 PROT_READ | PROT_WRITE | PROT_EXEC);
450 if (app_tpnt->dynamic_info[DT_TEXTREL]) {
451 _dl_dprintf(_dl_debug_file, "Can't modify application's text section; use the GCC option -fPIE for position-independent executables.\n");
456 #ifndef ALLOW_ZERO_PLTGOT
457 /* make sure it's really there. */
458 if (app_tpnt->dynamic_info[DT_PLTGOT] == 0)
461 /* OK, we have what we need - slip this one into the list. */
462 app_tpnt = _dl_add_elf_hash_table(_dl_progname, app_tpnt->loadaddr,
463 app_tpnt->dynamic_info,
464 (unsigned long) DL_RELOC_ADDR(app_tpnt->loadaddr, ppnt->p_vaddr),
466 _dl_loaded_modules->libtype = elf_executable;
467 _dl_loaded_modules->ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_val;
468 _dl_loaded_modules->n_phent = auxvt[AT_PHNUM].a_un.a_val;
469 _dl_symbol_tables = rpnt = _dl_zalloc(sizeof(struct dyn_elf));
470 rpnt->dyn = _dl_loaded_modules;
471 app_tpnt->mapaddr = app_mapaddr;
472 app_tpnt->rtld_flags = unlazy | RTLD_GLOBAL;
473 app_tpnt->usage_count++;
474 app_tpnt->symbol_scope = _dl_symbol_tables;
475 lpnt = (unsigned long *) (app_tpnt->dynamic_info[DT_PLTGOT]);
476 #ifdef ALLOW_ZERO_PLTGOT
479 INIT_GOT(lpnt, _dl_loaded_modules);
482 /* OK, fill this in - we did not have this before */
483 if (ppnt->p_type == PT_INTERP) {
486 tpnt->libname = (char *) DL_RELOC_ADDR(app_tpnt->loadaddr, ppnt->p_vaddr);
488 /* Store the path where the shared lib loader was found
491 _dl_ldsopath = _dl_strdup(tpnt->libname);
492 ptmp = _dl_strrchr(_dl_ldsopath, '/');
493 if (ptmp != _dl_ldsopath)
496 _dl_debug_early("Lib Loader: (%x) %s\n", (unsigned) DL_LOADADDR_BASE(tpnt->loadaddr), tpnt->libname);
499 /* Discover any TLS sections if the target supports them. */
500 if (ppnt->p_type == PT_TLS) {
502 if (ppnt->p_memsz > 0) {
503 app_tpnt->l_tls_blocksize = ppnt->p_memsz;
504 app_tpnt->l_tls_align = ppnt->p_align;
505 if (ppnt->p_align == 0)
506 app_tpnt->l_tls_firstbyte_offset = 0;
508 app_tpnt->l_tls_firstbyte_offset =
509 (ppnt->p_vaddr & (ppnt->p_align - 1));
510 app_tpnt->l_tls_initimage_size = ppnt->p_filesz;
511 app_tpnt->l_tls_initimage = (void *) ppnt->p_vaddr;
513 /* This image gets the ID one. */
514 _dl_tls_max_dtv_idx = app_tpnt->l_tls_modid = 1;
517 _dl_debug_early("Found TLS header for appplication program\n");
520 _dl_dprintf(_dl_debug_file, "Program uses unsupported TLS data!\n");
525 app_tpnt->relro_addr = relro_addr;
526 app_tpnt->relro_size = relro_size;
530 * Adjust the address of the TLS initialization image in
531 * case the executable is actually an ET_DYN object.
533 if (app_tpnt->l_tls_initimage != NULL)
535 #ifdef __SUPPORT_LD_DEBUG_EARLY__
536 unsigned int tmp = (unsigned int) app_tpnt->l_tls_initimage;
538 app_tpnt->l_tls_initimage =
539 (char *) app_tpnt->l_tls_initimage + app_tpnt->loadaddr;
540 _dl_debug_early("Relocated TLS initial image from %x to %x (size = %x)\n", tmp, app_tpnt->l_tls_initimage, app_tpnt->l_tls_initimage_size);
545 #ifdef __SUPPORT_LD_DEBUG__
546 _dl_debug = _dl_getenv("LD_DEBUG", envp);
548 if (_dl_strstr(_dl_debug, "all")) {
549 _dl_debug_detail = _dl_debug_move = _dl_debug_symbols
550 = _dl_debug_reloc = _dl_debug_bindings = _dl_debug_nofixups = (void*)1;
552 _dl_debug_detail = _dl_strstr(_dl_debug, "detail");
553 _dl_debug_move = _dl_strstr(_dl_debug, "move");
554 _dl_debug_symbols = _dl_strstr(_dl_debug, "sym");
555 _dl_debug_reloc = _dl_strstr(_dl_debug, "reloc");
556 _dl_debug_nofixups = _dl_strstr(_dl_debug, "nofix");
557 _dl_debug_bindings = _dl_strstr(_dl_debug, "bind");
562 const char *dl_debug_output;
564 dl_debug_output = _dl_getenv("LD_DEBUG_OUTPUT", envp);
566 if (dl_debug_output) {
567 char tmp[22], *tmp1, *filename;
570 _dl_memset(tmp, 0, sizeof(tmp));
571 tmp1 = _dl_simple_ltoa( tmp, (unsigned long)_dl_getpid());
573 len1 = _dl_strlen(dl_debug_output);
574 len2 = _dl_strlen(tmp1);
576 filename = _dl_malloc(len1 + len2 + 2);
579 _dl_strcpy (filename, dl_debug_output);
580 filename[len1] = '.';
581 _dl_strcpy (&filename[len1+1], tmp1);
583 _dl_debug_file = _dl_open(filename, O_WRONLY|O_CREAT, 0644);
584 if (_dl_debug_file < 0) {
586 _dl_dprintf(_dl_debug_file, "can't open file: '%s'\n",filename);
593 if (_dl_getenv("LD_TRACE_LOADED_OBJECTS", envp) != NULL) {
594 trace_loaded_objects++;
597 #ifndef __LDSO_LDD_SUPPORT__
598 if (trace_loaded_objects) {
599 _dl_dprintf(_dl_debug_file, "Use the ldd provided by uClibc\n");
605 * OK, fix one more thing - set up debug_addr so it will point
606 * to our chain. Later we may need to fill in more fields, but this
607 * should be enough for now.
609 debug_addr->r_map = (struct link_map *) _dl_loaded_modules;
610 debug_addr->r_version = 1;
611 debug_addr->r_ldbase = (ElfW(Addr)) DL_LOADADDR_BASE(load_addr);
612 debug_addr->r_brk = (unsigned long) &_dl_debug_state;
613 _dl_debug_addr = debug_addr;
615 /* Do not notify the debugger until the interpreter is in the list */
617 /* OK, we now have the application in the list, and we have some
618 * basic stuff in place. Now search through the list for other shared
619 * libraries that should be loaded, and insert them on the list in the
629 while (*str == ':' || *str == ' ' || *str == '\t')
634 while (*str2 && *str2 != ':' && *str2 != ' ' && *str2 != '\t')
639 if (!_dl_secure || _dl_strchr(str, '/') == NULL) {
640 _dl_if_debug_dprint("\tfile='%s'; needed by '%s'\n", str, _dl_progname);
642 tpnt1 = _dl_load_shared_library(_dl_secure, &rpnt, NULL, str, trace_loaded_objects);
644 #ifdef __LDSO_LDD_SUPPORT__
645 if (trace_loaded_objects)
646 _dl_dprintf(1, "\t%s => not found\n", str);
650 _dl_dprintf(_dl_debug_file, "%s: can't load " "library '%s'\n", _dl_progname, str);
654 tpnt1->rtld_flags = unlazy | RTLD_GLOBAL;
656 _dl_debug_early("Loading: (%x) %s\n", DL_LOADADDR_BASE(tpnt1->loadaddr), tpnt1->libname);
658 #ifdef __LDSO_LDD_SUPPORT__
659 if (trace_loaded_objects &&
660 tpnt1->usage_count == 1) {
661 /* This is a real hack to make
662 * ldd not print the library
663 * itself when run on a
666 if (_dl_strcmp(_dl_progname, str) != 0)
667 _dl_dprintf(1, "\t%s => %s (%x)\n", str, tpnt1->libname,
668 DL_LOADADDR_BASE(tpnt1->loadaddr));
676 while (*str == ':' || *str == ' ' || *str == '\t')
681 #ifdef __LDSO_PRELOAD_FILE_SUPPORT__
688 if (_dl_stat(LDSO_PRELOAD, &st) || st.st_size == 0) {
692 if ((fd = _dl_open(LDSO_PRELOAD, O_RDONLY, 0)) < 0) {
693 _dl_dprintf(_dl_debug_file, "%s: can't open file '%s'\n",
694 _dl_progname, LDSO_PRELOAD);
698 preload = (caddr_t) _dl_mmap(0, st.st_size + 1,
699 PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
701 if (preload == (caddr_t) -1) {
702 _dl_dprintf(_dl_debug_file, "%s:%i: can't map '%s'\n",
703 _dl_progname, __LINE__, LDSO_PRELOAD);
707 /* convert all separators and comments to spaces */
708 for (cp = preload; *cp; /*nada */ ) {
709 if (*cp == ':' || *cp == '\t' || *cp == '\n') {
711 } else if (*cp == '#') {
714 } while (*cp != '\n' && *cp != '\0');
720 /* find start of first library */
721 for (cp = preload; *cp && *cp == ' '; cp++)
725 /* find end of library */
726 for (cp2 = cp; *cp && *cp != ' '; cp++)
731 _dl_if_debug_dprint("\tfile='%s'; needed by '%s'\n", cp2, _dl_progname);
733 tpnt1 = _dl_load_shared_library(0, &rpnt, NULL, cp2, trace_loaded_objects);
735 #ifdef __LDSO_LDD_SUPPORT__
736 if (trace_loaded_objects)
737 _dl_dprintf(1, "\t%s => not found\n", cp2);
741 _dl_dprintf(_dl_debug_file, "%s: can't load library '%s'\n", _dl_progname, cp2);
745 tpnt1->rtld_flags = unlazy | RTLD_GLOBAL;
747 _dl_debug_early("Loading: (%x) %s\n", DL_LOADADDR_BASE(tpnt1->loadaddr), tpnt1->libname);
749 #ifdef __LDSO_LDD_SUPPORT__
750 if (trace_loaded_objects &&
751 tpnt1->usage_count == 1) {
752 _dl_dprintf(1, "\t%s => %s (%x)\n",
754 DL_LOADADDR_BASE(tpnt1->loadaddr));
759 /* find start of next library */
761 for ( /*nada */ ; *cp && *cp == ' '; cp++)
765 _dl_munmap(preload, st.st_size + 1);
767 #endif /* __LDSO_PRELOAD_FILE_SUPPORT__ */
770 for (tcurr = _dl_loaded_modules; tcurr; tcurr = tcurr->next) {
771 ElfW(Dyn) *this_dpnt;
774 for (this_dpnt = (ElfW(Dyn) *) tcurr->dynamic_addr; this_dpnt->d_tag; this_dpnt++) {
775 if (this_dpnt->d_tag == DT_NEEDED) {
777 struct init_fini_list *tmp;
779 lpntstr = (char*) (tcurr->dynamic_info[DT_STRTAB] + this_dpnt->d_un.d_val);
780 name = _dl_get_last_path_component(lpntstr);
781 if (_dl_strcmp(name, UCLIBC_LDSO) == 0)
784 _dl_if_debug_dprint("\tfile='%s'; needed by '%s'\n", lpntstr, _dl_progname);
786 if (!(tpnt1 = _dl_load_shared_library(0, &rpnt, tcurr, lpntstr, trace_loaded_objects))) {
787 #ifdef __LDSO_LDD_SUPPORT__
788 if (trace_loaded_objects) {
789 _dl_dprintf(1, "\t%s => not found\n", lpntstr);
794 _dl_dprintf(_dl_debug_file, "%s: can't load library '%s'\n", _dl_progname, lpntstr);
799 tmp = alloca(sizeof(struct init_fini_list)); /* Allocates on stack, no need to free this memory */
801 tmp->next = tcurr->init_fini;
802 tcurr->init_fini = tmp;
804 tpnt1->rtld_flags = unlazy | RTLD_GLOBAL;
806 _dl_debug_early("Loading: (%x) %s\n", DL_LOADADDR_BASE(tpnt1->loadaddr), tpnt1->libname);
808 #ifdef __LDSO_LDD_SUPPORT__
809 if (trace_loaded_objects &&
810 tpnt1->usage_count == 1) {
811 _dl_dprintf(1, "\t%s => %s (%x)\n",
812 lpntstr, tpnt1->libname,
813 DL_LOADADDR_BASE(tpnt1->loadaddr));
821 --nlist; /* Exclude the application. */
822 init_fini_list = _dl_malloc(nlist * sizeof(struct elf_resolve *));
824 for (tcurr = _dl_loaded_modules->next; tcurr; tcurr = tcurr->next) {
825 init_fini_list[i++] = tcurr;
828 /* Sort the INIT/FINI list in dependency order. */
829 for (tcurr = _dl_loaded_modules->next; tcurr; tcurr = tcurr->next) {
832 for (j = 0; init_fini_list[j] != tcurr; ++j)
834 for (k = j + 1; k < nlist; ++k) {
835 struct init_fini_list *runp = init_fini_list[k]->init_fini;
837 for (; runp; runp = runp->next) {
838 if (runp->tpnt == tcurr) {
839 struct elf_resolve *here = init_fini_list[k];
840 _dl_if_debug_dprint("Move %s from pos %d to %d in INIT/FINI list\n", here->libname, k, j);
841 for (i = (k - j); i; --i)
842 init_fini_list[i+j] = init_fini_list[i+j-1];
843 init_fini_list[j] = here;
850 #ifdef __SUPPORT_LD_DEBUG__
852 _dl_dprintf(_dl_debug_file, "\nINIT/FINI order and dependencies:\n");
853 for (i = 0; i < nlist; i++) {
854 struct init_fini_list *tmp;
856 _dl_dprintf(_dl_debug_file, "lib: %s has deps:\n",
857 init_fini_list[i]->libname);
858 tmp = init_fini_list[i]->init_fini;
859 for (; tmp; tmp = tmp->next)
860 _dl_dprintf(_dl_debug_file, " %s ", tmp->tpnt->libname);
861 _dl_dprintf(_dl_debug_file, "\n");
867 * If the program interpreter is not in the module chain, add it.
868 * This will be required for dlopen to be able to access the internal
869 * functions in the dynamic linker and to relocate the interpreter
870 * again once all libs are loaded.
873 ElfW(Ehdr) *epnt = (ElfW(Ehdr) *) auxvt[AT_BASE].a_un.a_val;
874 ElfW(Phdr) *myppnt = (ElfW(Phdr) *) DL_RELOC_ADDR(load_addr, epnt->e_phoff);
877 tpnt = _dl_add_elf_hash_table(tpnt->libname, load_addr,
879 (unsigned long)tpnt->dynamic_addr,
882 if (_dl_stat(tpnt->libname, &st) >= 0) {
883 tpnt->st_dev = st.st_dev;
884 tpnt->st_ino = st.st_ino;
886 tpnt->n_phent = epnt->e_phnum;
888 for (j = 0; j < epnt->e_phnum; j++, myppnt++) {
889 if (myppnt->p_type == PT_GNU_RELRO) {
890 tpnt->relro_addr = myppnt->p_vaddr;
891 tpnt->relro_size = myppnt->p_memsz;
895 tpnt->libtype = program_interpreter;
897 tpnt->symbol_scope = _dl_symbol_tables;
899 rpnt->next = _dl_zalloc(sizeof(struct dyn_elf));
900 rpnt->next->prev = rpnt;
903 rpnt = _dl_zalloc(sizeof(struct dyn_elf));
906 tpnt->rtld_flags = RTLD_NOW | RTLD_GLOBAL; /* Must not be LAZY */
907 #ifdef RERELOCATE_LDSO
908 /* Only rerelocate functions for now. */
909 tpnt->init_flag = RELOCS_DONE;
910 lpnt = (unsigned long *) (tpnt->dynamic_info[DT_PLTGOT]);
911 # ifdef ALLOW_ZERO_PLTGOT
912 if (tpnt->dynamic_info[DT_PLTGOT])
914 INIT_GOT(lpnt, tpnt);
916 tpnt->init_flag = RELOCS_DONE | JMP_RELOCS_DONE;
921 #ifdef __LDSO_LDD_SUPPORT__
922 /* End of the line for ldd.... */
923 if (trace_loaded_objects) {
924 _dl_dprintf(1, "\t%s => %s (%x)\n",
925 rpnt->dyn->libname + _dl_strlen(_dl_ldsopath) + 1,
926 rpnt->dyn->libname, DL_LOADADDR_BASE(rpnt->dyn->loadaddr));
932 /* We do not initialize any of the TLS functionality unless any of the
933 * initial modules uses TLS. This makes dynamic loading of modules with
934 * TLS impossible, but to support it requires either eagerly doing setup
935 * now or lazily doing it later. Doing it now makes us incompatible with
936 * an old kernel that can't perform TLS_INIT_TP, even if no TLS is ever
937 * used. Trying to do it lazily is too hairy to try when there could be
938 * multiple threads (from a non-TLS-using libpthread). */
939 bool was_tls_init_tp_called = tls_init_tp_called;
942 _dl_debug_early("Calling init_tls()!\n");
947 _dl_debug_early("Beginning relocation fixups\n");
951 * Relocation of the GOT entries for MIPS have to be done
952 * after all the libraries have been loaded.
954 _dl_perform_mips_global_got_relocations(_dl_loaded_modules, !unlazy);
958 * OK, now all of the kids are tucked into bed in their proper
959 * addresses. Now we go through and look for REL and RELA records that
960 * indicate fixups to the GOT tables. We need to do this in reverse
961 * order so that COPY directives work correctly.
963 if (_dl_symbol_tables)
964 if (_dl_fixup(_dl_symbol_tables, unlazy))
967 for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) {
968 if (tpnt->relro_size)
969 _dl_protect_relro (tpnt);
973 if (!was_tls_init_tp_called && _dl_tls_max_dtv_idx > 0)
974 ++_dl_tls_generation;
976 _dl_debug_early("Calling _dl_allocate_tls_init()!\n");
978 /* Now that we have completed relocation, the initializer data
979 for the TLS blocks has its final values and we can copy them
980 into the main thread's TLS area, which we allocated above. */
981 _dl_allocate_tls_init (tcbp);
983 /* And finally install it for the main thread. If ld.so itself uses
984 TLS we know the thread pointer was initialized earlier. */
985 if (! tls_init_tp_called)
987 const char *lossage = (char *) TLS_INIT_TP (tcbp, USE___THREAD);
988 if (__builtin_expect (lossage != NULL, 0))
990 _dl_debug_early("cannot set up thread-local storage: %s\n", lossage);
996 /* OK, at this point things are pretty much ready to run. Now we need
997 * to touch up a few items that are required, and then we can let the
998 * user application have at it. Note that the dynamic linker itself
999 * is not guaranteed to be fully dynamicly linked if we are using
1000 * ld.so.1, so we have to look up each symbol individually.
1003 _dl_envp = (unsigned long *) (intptr_t) _dl_find_hash(__C_SYMBOL_PREFIX__ "__environ", _dl_symbol_tables, NULL, 0, NULL);
1005 *_dl_envp = (unsigned long) envp;
1007 #ifndef __FORCE_SHAREABLE_TEXT_SEGMENTS__
1012 /* We had to set the protections of all pages to R/W for
1013 * dynamic linking. Set text pages back to R/O.
1015 for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) {
1016 for (myppnt = tpnt->ppnt, j = 0; j < tpnt->n_phent; j++, myppnt++) {
1017 if (myppnt->p_type == PT_LOAD && !(myppnt->p_flags & PF_W) && tpnt->dynamic_info[DT_TEXTREL]) {
1018 _dl_mprotect((void *) (DL_RELOC_ADDR(tpnt->loadaddr, myppnt->p_vaddr) & PAGE_ALIGN),
1019 (myppnt->p_vaddr & ADDR_ALIGN) + (unsigned long) myppnt->p_filesz, LXFLAGS(myppnt->p_flags));
1026 /* Notify the debugger we have added some objects. */
1027 _dl_debug_addr->r_state = RT_ADD;
1030 /* Run pre-initialization functions for the executable. */
1031 _dl_run_array_forward(_dl_loaded_modules->dynamic_info[DT_PREINIT_ARRAY],
1032 _dl_loaded_modules->dynamic_info[DT_PREINIT_ARRAYSZ],
1033 _dl_loaded_modules->loadaddr);
1035 /* Run initialization functions for loaded objects. For the
1036 main executable, they will be run from __uClibc_main. */
1037 for (i = nlist; i; --i) {
1038 tpnt = init_fini_list[i-1];
1039 tpnt->init_fini = NULL; /* Clear, since alloca was used */
1040 if (tpnt->init_flag & INIT_FUNCS_CALLED)
1042 tpnt->init_flag |= INIT_FUNCS_CALLED;
1044 if (tpnt->dynamic_info[DT_INIT]) {
1045 void (*dl_elf_func) (void);
1047 dl_elf_func = (void (*)(void)) DL_RELOC_ADDR(tpnt->loadaddr, tpnt->dynamic_info[DT_INIT]);
1049 _dl_if_debug_dprint("calling INIT: %s\n\n", tpnt->libname);
1051 DL_CALL_FUNC_AT_ADDR (dl_elf_func, tpnt->loadaddr, (void(*)(void)));
1054 _dl_run_init_array(tpnt);
1057 /* Find the real malloc function and make ldso functions use that from now on */
1058 _dl_malloc_function = (void* (*)(size_t)) (intptr_t) _dl_find_hash(__C_SYMBOL_PREFIX__ "malloc",
1059 _dl_symbol_tables, NULL, ELF_RTYPE_CLASS_PLT, NULL);
1062 /* Find the real functions and make ldso functions use them from now on */
1063 _dl_calloc_function = (void* (*)(size_t, size_t)) (intptr_t)
1064 _dl_find_hash(__C_SYMBOL_PREFIX__ "calloc", _dl_symbol_tables, NULL, ELF_RTYPE_CLASS_PLT, NULL);
1066 _dl_realloc_function = (void* (*)(void *, size_t)) (intptr_t)
1067 _dl_find_hash(__C_SYMBOL_PREFIX__ "realloc", _dl_symbol_tables, NULL, ELF_RTYPE_CLASS_PLT, NULL);
1069 _dl_free_function = (void (*)(void *)) (intptr_t)
1070 _dl_find_hash(__C_SYMBOL_PREFIX__ "free", _dl_symbol_tables, NULL, ELF_RTYPE_CLASS_PLT, NULL);
1072 _dl_memalign_function = (void* (*)(size_t, size_t)) (intptr_t)
1073 _dl_find_hash(__C_SYMBOL_PREFIX__ "memalign", _dl_symbol_tables, NULL, ELF_RTYPE_CLASS_PLT, NULL);
1077 /* Notify the debugger that all objects are now mapped in. */
1078 _dl_debug_addr->r_state = RT_CONSISTENT;
1082 #include "dl-hash.c"