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 #ifdef __LDSO_LD_LIBRARY_PATH__
50 char *_dl_library_path = NULL; /* Where we look for libraries */
52 #ifdef __LDSO_PRELOAD_ENV_SUPPORT__
53 char *_dl_preload = NULL; /* Things to be loaded before the libs */
55 int _dl_errno = 0; /* We can't use the real errno in ldso */
56 size_t _dl_pagesize = 0; /* Store the page size for use later */
57 struct r_debug *_dl_debug_addr = NULL; /* Used to communicate with the gdb debugger */
58 void *(*_dl_malloc_function) (size_t size) = NULL;
59 void (*_dl_free_function) (void *p) = NULL;
61 #ifdef __LDSO_PRELINK_SUPPORT__
62 char *_dl_trace_prelink = NULL; /* Library for prelinking trace */
63 struct elf_resolve *_dl_trace_prelink_map = NULL; /* Library module for prelinking trace */
64 bool _dl_verbose = true; /* On by default */
65 bool prelinked = false;
67 static int _dl_secure = 1; /* Are we dealing with setuid stuff? */
69 #ifdef __SUPPORT_LD_DEBUG__
70 char *_dl_debug = NULL;
71 char *_dl_debug_symbols = NULL;
72 char *_dl_debug_move = NULL;
73 char *_dl_debug_reloc = NULL;
74 char *_dl_debug_detail = NULL;
75 char *_dl_debug_nofixups = NULL;
76 char *_dl_debug_bindings = NULL;
77 int _dl_debug_file = 2;
80 #if defined (__LDSO_STANDALONE_SUPPORT__) && defined (__sh__)
81 /* Not hidden, needed for standalone execution. */
83 * FIXME: align dl_start for SH to other archs so that we can keep this symbol
84 * hidden and we don't need to handle in __uClibc_main
87 unsigned long _dl_skip_args = 0;
89 unsigned long attribute_hidden _dl_skip_args = 0;
92 const char *_dl_progname = UCLIBC_LDSO; /* The name of the executable being run */
93 #include "dl-startup.c"
94 #include "dl-symbols.c"
98 * This stub function is used by some debuggers. The idea is that they
99 * can set an internal breakpoint on it, so that we are notified when the
100 * address mapping is changed in some way.
102 void _dl_debug_state(void);
103 rtld_hidden_proto(_dl_debug_state, noinline);
104 void _dl_debug_state(void)
106 /* Make sure GCC doesn't recognize this function as pure, to avoid
107 * having the calls optimized away.
111 rtld_hidden_def(_dl_debug_state);
113 static unsigned char *_dl_malloc_addr = NULL; /* Lets _dl_malloc use the already allocated memory page */
114 static unsigned char *_dl_mmap_zero = NULL; /* Also used by _dl_malloc */
116 static struct elf_resolve **init_fini_list;
117 static struct elf_resolve **scope_elem_list;
118 static unsigned int nlist; /* # items in init_fini_list */
119 extern void _start(void);
121 #ifdef __UCLIBC_HAS_SSP__
122 # include <dl-osinfo.h>
123 static uintptr_t stack_chk_guard;
124 # ifndef THREAD_SET_STACK_GUARD
125 /* Only exported for architectures that don't store the stack guard canary
126 * in local thread area. */
127 uintptr_t __stack_chk_guard attribute_relro;
129 # ifdef __UCLIBC_HAS_SSP_COMPAT__
130 uintptr_t __guard attribute_relro;
134 #ifdef __LDSO_SEARCH_INTERP_PATH__
135 const char *_dl_ldsopath = NULL; /* Location of the shared lib loader */
137 static void _dl_ldsopath_init(struct elf_resolve *tpnt)
139 char *ldsopath, *ptmp;
141 /* Store the path where the shared lib loader was found for later use */
142 ldsopath = _dl_strdup(tpnt->libname);
143 ptmp = _dl_strrchr(ldsopath, '/');
144 if (ptmp != ldsopath)
147 _dl_ldsopath = ldsopath;
148 _dl_debug_early("Lib Loader: (%x) %s: using path: %s\n",
149 (unsigned) DL_LOADADDR_BASE(tpnt->loadaddr), tpnt->libname,
153 #define _dl_ldsopath_init(tpnt)
156 char *_dl_getenv(const char *symbol, char **envp)
161 while ((pnt = *envp++)) {
163 while (*pnt && *pnt == *pnt1)
165 if (!*pnt || *pnt != '=' || *pnt1)
172 void _dl_unsetenv(const char *symbol, char **envp)
176 char **newenvp = envp;
178 for (pnt = *envp; pnt; pnt = *++envp) {
180 while (*pnt && *pnt == *pnt1)
182 if (!*pnt || *pnt != '=' || *pnt1)
189 static int _dl_suid_ok(void)
191 __kernel_uid_t uid, euid;
192 __kernel_gid_t gid, egid;
195 euid = _dl_geteuid();
197 egid = _dl_getegid();
199 if (uid == euid && gid == egid) {
205 void *_dl_malloc(size_t size)
210 _dl_debug_early("request for %d bytes\n", size);
213 if (_dl_malloc_function)
214 return (*_dl_malloc_function) (size);
216 if (_dl_malloc_addr - _dl_mmap_zero + size > _dl_pagesize) {
219 /* Since the above assumes we get a full page even if
220 we request less than that, make sure we request a
221 full page, since uClinux may give us less than than
222 a full page. We might round even
223 larger-than-a-page sizes, but we end up never
224 reusing _dl_mmap_zero/_dl_malloc_addr in that case,
227 The actual page size doesn't really matter; as long
228 as we're self-consistent here, we're safe. */
229 if (size < _dl_pagesize)
230 rounded_size = (size + ADDR_ALIGN) & _dl_pagesize;
234 _dl_debug_early("mmapping more memory\n");
235 _dl_mmap_zero = _dl_malloc_addr = _dl_mmap((void *) 0, rounded_size,
236 PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_UNINITIALIZE, -1, 0);
237 if (_dl_mmap_check_error(_dl_mmap_zero)) {
238 _dl_dprintf(_dl_debug_file, "%s: mmap of a spare page failed!\n", _dl_progname);
242 retval = _dl_malloc_addr;
243 _dl_malloc_addr += size;
246 * Align memory to DL_MALLOC_ALIGN byte boundary. Some
247 * platforms require this, others simply get better
250 _dl_malloc_addr = (unsigned char *) (((unsigned long) _dl_malloc_addr + DL_MALLOC_ALIGN - 1) & ~(DL_MALLOC_ALIGN - 1));
254 static void *_dl_zalloc(size_t size)
256 void *p = _dl_malloc(size);
258 _dl_memset(p, 0, size);
262 void _dl_free(void *p)
264 if (_dl_free_function)
265 (*_dl_free_function) (p);
268 #if defined(USE_TLS) && USE_TLS
269 void *_dl_memalign(size_t __boundary, size_t __size)
276 if (_dl_memalign_function)
277 return (*_dl_memalign_function) (__boundary, __size);
279 while (rounded < __boundary) {
280 rounded = (1 << i++);
283 delta = (((size_t) _dl_malloc_addr + __size) & (rounded - 1));
285 if ((result = _dl_malloc(rounded - delta)) == NULL)
288 result = _dl_malloc(__size);
294 static void __attribute__ ((destructor)) __attribute_used__ _dl_fini(void)
297 struct elf_resolve * tpnt;
299 for (i = 0; i < nlist; ++i) {
300 tpnt = init_fini_list[i];
301 if (tpnt->init_flag & FINI_FUNCS_CALLED)
303 tpnt->init_flag |= FINI_FUNCS_CALLED;
304 _dl_run_fini_array(tpnt);
305 if (tpnt->dynamic_info[DT_FINI]) {
306 void (*dl_elf_func) (void);
308 dl_elf_func = (void (*)(void)) (intptr_t) DL_RELOC_ADDR(tpnt->loadaddr, tpnt->dynamic_info[DT_FINI]);
309 _dl_if_debug_dprint("\ncalling FINI: %s\n\n", tpnt->libname);
310 DL_CALL_FUNC_AT_ADDR (dl_elf_func, tpnt->loadaddr, (void(*)(void)));
315 #ifdef __LDSO_PRELINK_SUPPORT__
316 static void trace_objects(struct elf_resolve *tpnt, char *str_name)
318 if (_dl_strcmp(_dl_trace_prelink, tpnt->libname) == 0)
319 _dl_trace_prelink_map = tpnt;
320 if (tpnt->libtype == elf_executable) {
321 /* Main executeble */
322 _dl_dprintf(1, "\t%s => %s (%x, %x)", tpnt->libname, tpnt->libname,
323 tpnt->mapaddr, DL_LOADADDR_BASE(tpnt->loadaddr));
325 /* Preloaded, Needed or interpreter */
326 _dl_dprintf(1, "\t%s => %s (%x, %x)", str_name, tpnt->libname,
327 tpnt->mapaddr, DL_LOADADDR_BASE(tpnt->loadaddr));
330 #if defined USE_TLS && USE_TLS
331 if ((tpnt->libtype != program_interpreter) && (tpnt->l_tls_modid))
332 _dl_dprintf (1, " TLS(%x, %x)\n", tpnt->l_tls_modid,
333 (size_t) tpnt->l_tls_offset);
336 _dl_dprintf (1, "\n");
340 static struct elf_resolve * add_ldso(struct elf_resolve *tpnt,
341 DL_LOADADDR_TYPE load_addr,
342 ElfW(auxv_t) auxvt[AT_EGID + 1],
343 struct dyn_elf *rpnt)
345 ElfW(Ehdr) *epnt = (ElfW(Ehdr) *) auxvt[AT_BASE].a_un.a_val;
346 ElfW(Phdr) *myppnt = (ElfW(Phdr) *)
347 DL_RELOC_ADDR(load_addr, epnt->e_phoff);
351 tpnt = _dl_add_elf_hash_table(tpnt->libname, tpnt->loadaddr,
352 tpnt->dynamic_info, (unsigned long)tpnt->dynamic_addr,
355 tpnt->mapaddr = load_addr;
356 if (_dl_stat(tpnt->libname, &st) >= 0) {
357 tpnt->st_dev = st.st_dev;
358 tpnt->st_ino = st.st_ino;
360 tpnt->n_phent = epnt->e_phnum;
362 for (j = 0; j < epnt->e_phnum; j++, myppnt++) {
363 if (myppnt->p_type == PT_GNU_RELRO) {
364 tpnt->relro_addr = myppnt->p_vaddr;
365 tpnt->relro_size = myppnt->p_memsz;
369 tpnt->libtype = program_interpreter;
371 rpnt->next = _dl_zalloc(sizeof(struct dyn_elf));
372 rpnt->next->prev = rpnt;
375 rpnt = _dl_zalloc(sizeof(struct dyn_elf));
378 tpnt->rtld_flags = RTLD_NOW | RTLD_GLOBAL; /* Must not be LAZY */
383 static ptrdiff_t _dl_build_local_scope (struct elf_resolve **list,
384 struct elf_resolve *map)
386 struct elf_resolve **p = list;
387 struct init_fini_list *q;
390 map->init_flag |= DL_RESERVED;
392 for (q = map->init_fini; q; q = q->next)
393 if (! (q->tpnt->init_flag & DL_RESERVED))
394 p += _dl_build_local_scope (p, q->tpnt);
398 void *_dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr,
399 ElfW(auxv_t) auxvt[AT_EGID + 1], char **envp, char **argv
400 DL_GET_READY_TO_RUN_EXTRA_PARMS)
402 ElfW(Addr) app_mapaddr = 0;
406 unsigned int i, cnt, nscope_elem;
407 int unlazy = 0, trace_loaded_objects = 0;
408 struct dyn_elf *rpnt;
409 struct elf_resolve *tcurr;
410 struct elf_resolve *tpnt1;
411 struct elf_resolve *ldso_tpnt = NULL;
412 struct elf_resolve app_tpnt_tmp;
413 struct elf_resolve *app_tpnt = &app_tpnt_tmp;
414 struct r_debug *debug_addr;
416 unsigned long *_dl_envp; /* The environment address */
417 ElfW(Addr) relro_addr = 0;
418 size_t relro_size = 0;
419 struct r_scope_elem *global_scope;
420 struct elf_resolve **local_scope;
422 #if defined(USE_TLS) && USE_TLS
426 /* Wahoo!!! We managed to make a function call! Get malloc
427 * setup so we can use _dl_dprintf() to print debug noise
428 * instead of the SEND_STDERR macros used in dl-startup.c */
430 _dl_memset(app_tpnt, 0, sizeof(*app_tpnt));
432 /* Store the page size for later use */
433 _dl_pagesize = (auxvt[AT_PAGESZ].a_un.a_val) ? (size_t) auxvt[AT_PAGESZ].a_un.a_val : PAGE_SIZE;
434 /* Make it so _dl_malloc can use the page of memory we have already
435 * allocated. We shouldn't need to grab any more memory. This must
436 * be first since things like _dl_dprintf() use _dl_malloc()...
438 _dl_malloc_addr = (unsigned char *)_dl_pagesize;
442 _dl_debug_early("Cool, ldso survived making function calls\n");
444 /* Now we have done the mandatory linking of some things. We are now
445 * free to start using global variables, since these things have all
446 * been fixed up by now. Still no function calls outside of this
447 * library, since the dynamic resolver is not yet ready.
450 _dl_progname = argv[0];
453 #ifndef __LDSO_STANDALONE_SUPPORT__
454 if (_start == (void *) auxvt[AT_ENTRY].a_un.a_val) {
455 _dl_dprintf(_dl_debug_file, "Standalone execution is not enabled\n");
460 /* Start to build the tables of the modules that are required for
461 * this beast to run. We start with the basic executable, and then
462 * go from there. Eventually we will run across ourself, and we
463 * will need to properly deal with that as well.
466 if (_dl_getenv("LD_BIND_NOW", envp))
469 /* Now we need to figure out what kind of options are selected.
470 * Note that for SUID programs we ignore the settings in
473 if ((auxvt[AT_UID].a_un.a_val == (size_t)-1 && _dl_suid_ok()) ||
474 (auxvt[AT_UID].a_un.a_val != (size_t)-1 &&
475 auxvt[AT_UID].a_un.a_val == auxvt[AT_EUID].a_un.a_val &&
476 auxvt[AT_GID].a_un.a_val == auxvt[AT_EGID].a_un.a_val)) {
478 #ifdef __LDSO_PRELOAD_ENV_SUPPORT__
479 _dl_preload = _dl_getenv("LD_PRELOAD", envp);
481 #ifdef __LDSO_LD_LIBRARY_PATH__
482 _dl_library_path = _dl_getenv("LD_LIBRARY_PATH", envp);
485 static const char unsecure_envvars[] =
486 #ifdef EXTRA_UNSECURE_ENVVARS
487 EXTRA_UNSECURE_ENVVARS
493 nextp = unsecure_envvars;
495 _dl_unsetenv (nextp, envp);
496 /* We could use rawmemchr but this need not be fast. */
497 nextp = _dl_strchr(nextp, '\0') + 1;
498 } while (*nextp != '\0');
499 #ifdef __LDSO_PRELOAD_ENV_SUPPORT__
502 #ifdef __LDSO_LD_LIBRARY_PATH__
503 _dl_library_path = NULL;
505 /* SUID binaries can be exploited if they do LAZY relocation. */
509 #if defined(USE_TLS) && USE_TLS
510 _dl_error_catch_tsd = &_dl_initial_error_catch_tsd;
511 _dl_init_static_tls = &_dl_nothread_init_static_tls;
514 #ifdef __LDSO_STANDALONE_SUPPORT__
515 if (_start == (void *) auxvt[AT_ENTRY].a_un.a_val) {
516 unsigned int *aux_dat = (unsigned int *) argv;
517 int argc = aux_dat[-1];
519 tpnt->libname = argv[0];
521 if (! _dl_strcmp (argv[1], "--library-path") && argc > 2) {
522 #ifdef __LDSO_LD_LIBRARY_PATH__
523 _dl_library_path = argv[2];
532 * If we have no further argument the program was called incorrectly.
533 * Grant the user some education.
538 Usage: ld.so [OPTION]... EXECUTABLE-FILE [ARGS-FOR-PROGRAM...]\n\
539 You have invoked `ld.so', the helper program for shared library executables.\n\
540 This program usually lives in the file `/lib/ld.so', and special directives\n\
541 in executable files using ELF shared libraries tell the system's program\n\
542 loader to load the helper program from this file. This helper program loads\n\
543 the shared libraries needed by the program executable, prepares the program\n\
544 to run, and runs it. You may invoke this helper program directly from the\n\
545 command line to load and run an ELF executable file; this is like executing\n\
546 that file itself, but always uses this helper program from the file you\n\
547 specified, instead of the helper program file specified in the executable\n\
548 file you run. This is mostly of use for maintainers to test new versions\n\
549 of this helper program; chances are you did not intend to run this program.\n\
551 --library-path PATH use given PATH instead of content of the environment\n\
552 variable LD_LIBRARY_PATH\n");
558 _dl_progname = argv[0];
560 _dl_symbol_tables = rpnt = _dl_zalloc(sizeof(struct dyn_elf));
562 * It needs to load the _dl_progname and to map it
563 * Usually it is the main application launched by means of the ld.so
564 * but it could be also a shared object (when ld.so used for tracing)
565 * We keep the misleading app_tpnt name to avoid variable pollution
567 app_tpnt = _dl_load_elf_shared_library(_dl_secure, &rpnt, _dl_progname);
569 _dl_dprintf(_dl_debug_file, "can't load '%s'\n", _dl_progname);
573 * FIXME: it needs to properly handle a PIE executable
574 * Usually for a main application, loadaddr is computed as difference
575 * between auxvt entry points and phdr, so if it is not 0, that it is a
576 * PIE executable. In this case instead we need to set the loadaddr to 0
577 * because we are actually mapping the ELF for the main application by
578 * ourselves. So the PIE case must be checked.
581 app_tpnt->rtld_flags = unlazy | RTLD_GLOBAL;
584 * This is used by gdb to locate the chain of shared libraries that are
587 debug_addr = _dl_zalloc(sizeof(struct r_debug));
588 ppnt = (ElfW(Phdr) *)app_tpnt->ppnt;
589 for (i = 0; i < app_tpnt->n_phent; i++, ppnt++) {
590 if (ppnt->p_type == PT_DYNAMIC) {
591 dpnt = (ElfW(Dyn) *) DL_RELOC_ADDR(app_tpnt->loadaddr, ppnt->p_vaddr);
592 _dl_parse_dynamic_info(dpnt, app_tpnt->dynamic_info, debug_addr, app_tpnt->loadaddr);
596 _dl_ldsopath_init(tpnt);
600 /* At this point we are now free to examine the user application,
601 * and figure out which libraries are supposed to be called. Until
602 * we have this list, we will not be completely ready for dynamic
606 /* Find the runtime load address of the main executable. This may be
607 * different from what the ELF header says for ET_DYN/PIE executables.
611 ElfW(Phdr) *phdr = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_val;
613 for (idx = 0; idx < auxvt[AT_PHNUM].a_un.a_val; idx++, phdr++)
614 if (phdr->p_type == PT_PHDR) {
615 DL_INIT_LOADADDR_PROG(app_tpnt->loadaddr, auxvt[AT_PHDR].a_un.a_val - phdr->p_vaddr);
619 if (DL_LOADADDR_BASE(app_tpnt->loadaddr))
620 _dl_debug_early("Position Independent Executable: "
621 "app_tpnt->loadaddr=%x\n", DL_LOADADDR_BASE(app_tpnt->loadaddr));
625 * This is used by gdb to locate the chain of shared libraries that are
628 debug_addr = _dl_zalloc(sizeof(struct r_debug));
630 ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_val;
631 for (i = 0; i < auxvt[AT_PHNUM].a_un.a_val; i++, ppnt++) {
632 if (ppnt->p_type == PT_GNU_RELRO) {
633 relro_addr = ppnt->p_vaddr;
634 relro_size = ppnt->p_memsz;
636 if (!app_mapaddr && (ppnt->p_type == PT_LOAD)) {
637 app_mapaddr = DL_RELOC_ADDR (app_tpnt->loadaddr, ppnt->p_vaddr);
639 if (ppnt->p_type == PT_DYNAMIC) {
640 dpnt = (ElfW(Dyn) *) DL_RELOC_ADDR(app_tpnt->loadaddr, ppnt->p_vaddr);
641 _dl_parse_dynamic_info(dpnt, app_tpnt->dynamic_info, debug_addr, app_tpnt->loadaddr);
642 #ifndef __FORCE_SHAREABLE_TEXT_SEGMENTS__
643 /* Ugly, ugly. We need to call mprotect to change the
644 * protection of the text pages so that we can do the
645 * dynamic linking. We can set the protection back
646 * again once we are done.
648 _dl_debug_early("calling mprotect on the application program\n");
649 /* Now cover the application program. */
650 if (app_tpnt->dynamic_info[DT_TEXTREL]) {
651 ElfW(Phdr) *ppnt_outer = ppnt;
652 ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_val;
653 for (i = 0; i < auxvt[AT_PHNUM].a_un.a_val; i++, ppnt++) {
654 if (ppnt->p_type == PT_LOAD && !(ppnt->p_flags & PF_W))
655 _dl_mprotect((void *) (DL_RELOC_ADDR(app_tpnt->loadaddr, ppnt->p_vaddr) & PAGE_ALIGN),
656 (DL_RELOC_ADDR(app_tpnt->loadaddr, ppnt->p_vaddr) & ADDR_ALIGN) +
657 (unsigned long) ppnt->p_filesz,
658 PROT_READ | PROT_WRITE | PROT_EXEC);
663 if (app_tpnt->dynamic_info[DT_TEXTREL]) {
664 _dl_dprintf(_dl_debug_file, "Can't modify application's text section; use the GCC option -fPIE for position-independent executables.\n");
669 #ifndef ALLOW_ZERO_PLTGOT
670 /* make sure it's really there. */
671 if (app_tpnt->dynamic_info[DT_PLTGOT] == 0)
674 /* OK, we have what we need - slip this one into the list. */
675 app_tpnt = _dl_add_elf_hash_table(_dl_progname, app_tpnt->loadaddr,
676 app_tpnt->dynamic_info,
677 (unsigned long) DL_RELOC_ADDR(app_tpnt->loadaddr, ppnt->p_vaddr),
679 _dl_loaded_modules->libtype = elf_executable;
680 _dl_loaded_modules->ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_val;
681 _dl_loaded_modules->n_phent = auxvt[AT_PHNUM].a_un.a_val;
682 _dl_symbol_tables = rpnt = _dl_zalloc(sizeof(struct dyn_elf));
683 rpnt->dyn = _dl_loaded_modules;
684 app_tpnt->mapaddr = app_mapaddr;
685 app_tpnt->rtld_flags = unlazy | RTLD_GLOBAL;
686 app_tpnt->usage_count++;
687 lpnt = (unsigned long *) (app_tpnt->dynamic_info[DT_PLTGOT]);
688 #ifdef ALLOW_ZERO_PLTGOT
691 INIT_GOT(lpnt, _dl_loaded_modules);
694 /* OK, fill this in - we did not have this before */
695 if (ppnt->p_type == PT_INTERP) {
696 tpnt->libname = (char *) DL_RELOC_ADDR(app_tpnt->loadaddr, ppnt->p_vaddr);
698 _dl_ldsopath_init(tpnt);
701 /* Discover any TLS sections if the target supports them. */
702 if (ppnt->p_type == PT_TLS) {
703 #if defined(USE_TLS) && USE_TLS
704 if (ppnt->p_memsz > 0) {
705 app_tpnt->l_tls_blocksize = ppnt->p_memsz;
706 app_tpnt->l_tls_align = ppnt->p_align;
707 if (ppnt->p_align == 0)
708 app_tpnt->l_tls_firstbyte_offset = 0;
710 app_tpnt->l_tls_firstbyte_offset =
711 (ppnt->p_vaddr & (ppnt->p_align - 1));
712 app_tpnt->l_tls_initimage_size = ppnt->p_filesz;
713 app_tpnt->l_tls_initimage = (void *) ppnt->p_vaddr;
715 /* This image gets the ID one. */
716 _dl_tls_max_dtv_idx = app_tpnt->l_tls_modid = 1;
719 _dl_debug_early("Found TLS header for appplication program\n");
722 _dl_dprintf(_dl_debug_file, "Program uses unsupported TLS data!\n");
727 app_tpnt->relro_addr = relro_addr;
728 app_tpnt->relro_size = relro_size;
730 #if defined(USE_TLS) && USE_TLS
732 * Adjust the address of the TLS initialization image in
733 * case the executable is actually an ET_DYN object.
735 if (app_tpnt->l_tls_initimage != NULL) {
736 unsigned int tmp = (unsigned int) app_tpnt->l_tls_initimage;
737 app_tpnt->l_tls_initimage =
738 (char *) app_tpnt->l_tls_initimage + app_tpnt->loadaddr;
739 _dl_debug_early("Relocated TLS initial image from %x to %x (size = %x)\n",
740 tmp, app_tpnt->l_tls_initimage, app_tpnt->l_tls_initimage_size);
744 #ifdef __LDSO_STANDALONE_SUPPORT__
745 } /* ! ldso standalone mode */
748 #ifdef __SUPPORT_LD_DEBUG__
749 _dl_debug = _dl_getenv("LD_DEBUG", envp);
751 if (_dl_strstr(_dl_debug, "all")) {
752 _dl_debug_detail = _dl_debug_move = _dl_debug_symbols
753 = _dl_debug_reloc = _dl_debug_bindings = _dl_debug_nofixups = (void*)1;
755 _dl_debug_detail = _dl_strstr(_dl_debug, "detail");
756 _dl_debug_move = _dl_strstr(_dl_debug, "move");
757 _dl_debug_symbols = _dl_strstr(_dl_debug, "sym");
758 _dl_debug_reloc = _dl_strstr(_dl_debug, "reloc");
759 _dl_debug_nofixups = _dl_strstr(_dl_debug, "nofix");
760 _dl_debug_bindings = _dl_strstr(_dl_debug, "bind");
765 const char *dl_debug_output;
767 dl_debug_output = _dl_getenv("LD_DEBUG_OUTPUT", envp);
769 if (dl_debug_output) {
770 char tmp[22], *tmp1, *filename;
773 _dl_memset(tmp, 0, sizeof(tmp));
774 tmp1 = _dl_simple_ltoa( tmp, (unsigned long)_dl_getpid());
776 len1 = _dl_strlen(dl_debug_output);
777 len2 = _dl_strlen(tmp1);
779 filename = _dl_malloc(len1 + len2 + 2);
782 _dl_strcpy (filename, dl_debug_output);
783 filename[len1] = '.';
784 _dl_strcpy (&filename[len1+1], tmp1);
786 _dl_debug_file = _dl_open(filename, O_WRONLY|O_CREAT, 0644);
787 if (_dl_debug_file < 0) {
789 _dl_dprintf(_dl_debug_file, "can't open file: '%s'\n",filename);
796 #ifdef __LDSO_PRELINK_SUPPORT__
798 char *ld_warn = _dl_getenv ("LD_WARN", envp);
800 if (ld_warn && *ld_warn == '\0')
803 _dl_trace_prelink = _dl_getenv("LD_TRACE_PRELINKING", envp);
806 if (_dl_getenv("LD_TRACE_LOADED_OBJECTS", envp) != NULL) {
807 trace_loaded_objects++;
810 #ifndef __LDSO_LDD_SUPPORT__
811 if (trace_loaded_objects) {
812 _dl_dprintf(_dl_debug_file, "Use the ldd provided by uClibc\n");
818 * OK, fix one more thing - set up debug_addr so it will point
819 * to our chain. Later we may need to fill in more fields, but this
820 * should be enough for now.
822 debug_addr->r_map = (struct link_map *) _dl_loaded_modules;
823 debug_addr->r_version = 1;
824 debug_addr->r_ldbase = (ElfW(Addr)) DL_LOADADDR_BASE(load_addr);
825 debug_addr->r_brk = (unsigned long) &_dl_debug_state;
826 _dl_debug_addr = debug_addr;
828 /* Do not notify the debugger until the interpreter is in the list */
830 /* OK, we now have the application in the list, and we have some
831 * basic stuff in place. Now search through the list for other shared
832 * libraries that should be loaded, and insert them on the list in the
838 #ifdef __LDSO_PRELOAD_ENV_SUPPORT__
843 while (*str == ':' || *str == ' ' || *str == '\t')
848 while (*str2 && *str2 != ':' && *str2 != ' ' && *str2 != '\t')
853 if (!_dl_secure || _dl_strchr(str, '/') == NULL) {
854 _dl_if_debug_dprint("\tfile='%s'; needed by '%s'\n", str, _dl_progname);
856 tpnt1 = _dl_load_shared_library(
857 _dl_secure ? DL_RESOLVE_SECURE : 0,
858 &rpnt, NULL, str, trace_loaded_objects);
860 #ifdef __LDSO_LDD_SUPPORT__
861 if (trace_loaded_objects || _dl_trace_prelink)
862 _dl_dprintf(1, "\t%s => not found\n", str);
866 _dl_dprintf(_dl_debug_file, "%s: can't load " "library '%s'\n", _dl_progname, str);
870 tpnt1->rtld_flags = unlazy | RTLD_GLOBAL;
872 _dl_debug_early("Loading: (%x) %s\n", DL_LOADADDR_BASE(tpnt1->loadaddr), tpnt1->libname);
874 #ifdef __LDSO_LDD_SUPPORT__
875 if (trace_loaded_objects && !_dl_trace_prelink &&
876 tpnt1->usage_count == 1) {
877 /* This is a real hack to make
878 * ldd not print the library
879 * itself when run on a
882 if (_dl_strcmp(_dl_progname, str) != 0)
883 _dl_dprintf(1, "\t%s => %s (%x)\n", str, tpnt1->libname,
884 DL_LOADADDR_BASE(tpnt1->loadaddr));
892 while (*str == ':' || *str == ' ' || *str == '\t')
896 #endif /* __LDSO_PRELOAD_ENV_SUPPORT__ */
898 #ifdef __LDSO_PRELOAD_FILE_SUPPORT__
905 if (_dl_stat(LDSO_PRELOAD, &st) || st.st_size == 0) {
909 if ((fd = _dl_open(LDSO_PRELOAD, O_RDONLY, 0)) < 0) {
910 _dl_dprintf(_dl_debug_file, "%s: can't open file '%s'\n",
911 _dl_progname, LDSO_PRELOAD);
915 preload = (caddr_t) _dl_mmap(0, st.st_size + 1,
916 PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
918 if (preload == (caddr_t) -1) {
919 _dl_dprintf(_dl_debug_file, "%s:%i: can't map '%s'\n",
920 _dl_progname, __LINE__, LDSO_PRELOAD);
924 /* convert all separators and comments to spaces */
925 for (cp = preload; *cp; /*nada */ ) {
926 if (*cp == ':' || *cp == '\t' || *cp == '\n') {
928 } else if (*cp == '#') {
931 } while (*cp != '\n' && *cp != '\0');
937 /* find start of first library */
938 for (cp = preload; *cp && *cp == ' '; cp++)
942 /* find end of library */
943 for (cp2 = cp; *cp && *cp != ' '; cp++)
948 _dl_if_debug_dprint("\tfile='%s'; needed by '%s'\n", cp2, _dl_progname);
950 tpnt1 = _dl_load_shared_library(0, &rpnt, NULL, cp2, trace_loaded_objects);
952 # ifdef __LDSO_LDD_SUPPORT__
953 if (trace_loaded_objects || _dl_trace_prelink)
954 _dl_dprintf(1, "\t%s => not found\n", cp2);
958 _dl_dprintf(_dl_debug_file, "%s: can't load library '%s'\n", _dl_progname, cp2);
962 tpnt1->rtld_flags = unlazy | RTLD_GLOBAL;
964 _dl_debug_early("Loading: (%x) %s\n", DL_LOADADDR_BASE(tpnt1->loadaddr), tpnt1->libname);
966 # ifdef __LDSO_LDD_SUPPORT__
967 if (trace_loaded_objects && !_dl_trace_prelink &&
968 tpnt1->usage_count == 1) {
969 _dl_dprintf(1, "\t%s => %s (%x)\n",
971 DL_LOADADDR_BASE(tpnt1->loadaddr));
976 /* find start of next library */
978 for ( /*nada */ ; *cp && *cp == ' '; cp++)
982 _dl_munmap(preload, st.st_size + 1);
984 #endif /* __LDSO_PRELOAD_FILE_SUPPORT__ */
987 for (tcurr = _dl_loaded_modules; tcurr; tcurr = tcurr->next) {
988 ElfW(Dyn) *this_dpnt;
991 for (this_dpnt = (ElfW(Dyn) *) tcurr->dynamic_addr; this_dpnt->d_tag; this_dpnt++) {
992 if (this_dpnt->d_tag == DT_NEEDED) {
994 struct init_fini_list *tmp;
996 lpntstr = (char*) (tcurr->dynamic_info[DT_STRTAB] + this_dpnt->d_un.d_val);
997 name = _dl_get_last_path_component(lpntstr);
998 _dl_if_debug_dprint("\tfile='%s'; needed by '%s'\n", lpntstr, _dl_progname);
1000 if (_dl_strcmp(name, UCLIBC_LDSO) == 0) {
1002 /* Insert the ld.so only once */
1003 ldso_tpnt = add_ldso(tpnt, load_addr, auxvt, rpnt);
1005 ldso_tpnt->usage_count++;
1008 tpnt1 = _dl_load_shared_library(0, &rpnt, tcurr, lpntstr, trace_loaded_objects);
1011 #ifdef __LDSO_LDD_SUPPORT__
1012 if (trace_loaded_objects || _dl_trace_prelink) {
1013 _dl_dprintf(1, "\t%s => not found\n", lpntstr);
1018 _dl_dprintf(_dl_debug_file, "%s: can't load library '%s'\n", _dl_progname, lpntstr);
1023 tmp = alloca(sizeof(struct init_fini_list)); /* Allocates on stack, no need to free this memory */
1025 tmp->next = tcurr->init_fini;
1026 tcurr->init_fini = tmp;
1028 tpnt1->rtld_flags = unlazy | RTLD_GLOBAL;
1030 _dl_debug_early("Loading: (%x) %s\n", DL_LOADADDR_BASE(tpnt1->loadaddr), tpnt1->libname);
1032 #ifdef __LDSO_LDD_SUPPORT__
1033 if (trace_loaded_objects && !_dl_trace_prelink &&
1034 tpnt1->usage_count == 1) {
1035 _dl_dprintf(1, "\t%s => %s (%x)\n",
1036 lpntstr, tpnt1->libname,
1037 DL_LOADADDR_BASE(tpnt1->loadaddr));
1045 /* Keep track of the number of elements in the global scope */
1046 nscope_elem = nlist;
1048 if (_dl_loaded_modules->libtype == elf_executable) {
1049 --nlist; /* Exclude the application. */
1050 tcurr = _dl_loaded_modules->next;
1052 tcurr = _dl_loaded_modules;
1053 init_fini_list = _dl_malloc(nlist * sizeof(struct elf_resolve *));
1055 for (; tcurr; tcurr = tcurr->next)
1056 init_fini_list[i++] = tcurr;
1058 /* Sort the INIT/FINI list in dependency order. */
1059 for (tcurr = _dl_loaded_modules->next; tcurr; tcurr = tcurr->next) {
1062 for (j = 0; init_fini_list[j] != tcurr; ++j)
1064 for (k = j + 1; k < nlist; ++k) {
1065 struct init_fini_list *runp = init_fini_list[k]->init_fini;
1067 for (; runp; runp = runp->next) {
1068 if (runp->tpnt == tcurr) {
1069 struct elf_resolve *here = init_fini_list[k];
1070 _dl_if_debug_dprint("Move %s from pos %d to %d in INIT/FINI list\n", here->libname, k, j);
1071 for (i = (k - j); i; --i)
1072 init_fini_list[i+j] = init_fini_list[i+j-1];
1073 init_fini_list[j] = here;
1080 #ifdef __SUPPORT_LD_DEBUG__
1082 _dl_dprintf(_dl_debug_file, "\nINIT/FINI order and dependencies:\n");
1083 for (i = 0; i < nlist; i++) {
1084 struct init_fini_list *tmp;
1086 _dl_dprintf(_dl_debug_file, "lib: %s has deps:\n",
1087 init_fini_list[i]->libname);
1088 tmp = init_fini_list[i]->init_fini;
1089 for (; tmp; tmp = tmp->next)
1090 _dl_dprintf(_dl_debug_file, " %s ", tmp->tpnt->libname);
1091 _dl_dprintf(_dl_debug_file, "\n");
1097 * If the program interpreter is not in the module chain, add it.
1098 * This will be required for dlopen to be able to access the internal
1099 * functions in the dynamic linker and to relocate the interpreter
1100 * again once all libs are loaded.
1103 tpnt = add_ldso(tpnt, load_addr, auxvt, rpnt);
1104 tpnt->usage_count++;
1109 #ifdef RERELOCATE_LDSO
1110 /* Only rerelocate functions for now. */
1111 tpnt->init_flag = RELOCS_DONE;
1112 lpnt = (unsigned long *) (tpnt->dynamic_info[DT_PLTGOT]);
1113 # ifdef ALLOW_ZERO_PLTGOT
1114 if (tpnt->dynamic_info[DT_PLTGOT])
1116 INIT_GOT(lpnt, tpnt);
1118 tpnt->init_flag = RELOCS_DONE | JMP_RELOCS_DONE;
1123 * Allocate the global scope array.
1125 scope_elem_list = (struct elf_resolve **) _dl_malloc(nscope_elem * sizeof(struct elf_resolve *));
1127 for (i = 0, tcurr = _dl_loaded_modules; tcurr; tcurr = tcurr->next)
1128 scope_elem_list[i++] = tcurr;
1130 _dl_loaded_modules->symbol_scope.r_list = scope_elem_list;
1131 _dl_loaded_modules->symbol_scope.r_nlist = nscope_elem;
1133 * The symbol scope of the application, that is the first entry of the
1134 * _dl_loaded_modules list, is just the global scope to be used for the
1137 global_scope = &_dl_loaded_modules->symbol_scope;
1139 /* Build the local scope for each loaded modules. */
1140 local_scope = _dl_malloc(nscope_elem * sizeof(struct elf_resolve *));
1142 for (tcurr = _dl_loaded_modules->next; tcurr; tcurr = tcurr->next) {
1144 cnt = _dl_build_local_scope(local_scope, scope_elem_list[i++]);
1145 tcurr->symbol_scope.r_list = _dl_malloc(cnt * sizeof(struct elf_resolve *));
1146 tcurr->symbol_scope.r_nlist = cnt;
1147 _dl_memcpy (tcurr->symbol_scope.r_list, local_scope, cnt * sizeof (struct elf_resolve *));
1148 /* Restoring the init_flag.*/
1149 for (k = 1; k < nscope_elem; k++)
1150 scope_elem_list[k]->init_flag &= ~DL_RESERVED;
1153 _dl_free(local_scope);
1155 #ifdef __LDSO_LDD_SUPPORT__
1156 /* Exit if LD_TRACE_LOADED_OBJECTS is on. */
1157 if (trace_loaded_objects && !_dl_trace_prelink)
1161 #if defined(USE_TLS) && USE_TLS
1162 /* We do not initialize any of the TLS functionality unless any of the
1163 * initial modules uses TLS. This makes dynamic loading of modules with
1164 * TLS impossible, but to support it requires either eagerly doing setup
1165 * now or lazily doing it later. Doing it now makes us incompatible with
1166 * an old kernel that can't perform TLS_INIT_TP, even if no TLS is ever
1167 * used. Trying to do it lazily is too hairy to try when there could be
1168 * multiple threads (from a non-TLS-using libpthread). */
1169 bool was_tls_init_tp_called = tls_init_tp_called;
1171 _dl_debug_early("Calling init_tls()!\n");
1175 #ifdef __UCLIBC_HAS_SSP__
1176 /* Set up the stack checker's canary. */
1177 stack_chk_guard = _dl_setup_stack_chk_guard ();
1178 # ifdef THREAD_SET_STACK_GUARD
1179 THREAD_SET_STACK_GUARD (stack_chk_guard);
1181 __stack_chk_guard = stack_chk_guard;
1183 # ifdef __UCLIBC_HAS_SSP_COMPAT__
1184 __guard = stack_chk_guard;
1188 #ifdef __LDSO_PRELINK_SUPPORT__
1189 if (_dl_trace_prelink) {
1191 unsigned int nscope_trace = ldso_tpnt ? nscope_elem : (nscope_elem - 1);
1193 for (i = 0; i < nscope_trace; i++)
1194 trace_objects(scope_elem_list[i],
1195 _dl_get_last_path_component(scope_elem_list[i]->libname));
1198 /* Warn about undefined symbols. */
1199 if (_dl_symbol_tables)
1200 if (_dl_fixup(_dl_symbol_tables, global_scope, unlazy))
1205 if (_dl_loaded_modules->dynamic_info[DT_GNU_LIBLIST_IDX]) {
1206 ElfW(Lib) *liblist, *liblistend;
1207 struct elf_resolve **r_list, **r_listend, *l;
1208 const char *strtab = (const char *)_dl_loaded_modules->dynamic_info[DT_STRTAB];
1210 _dl_assert (_dl_loaded_modules->dynamic_info[DT_GNU_LIBLISTSZ_IDX] != 0);
1211 liblist = (ElfW(Lib) *) _dl_loaded_modules->dynamic_info[DT_GNU_LIBLIST_IDX];
1212 liblistend = (ElfW(Lib) *)
1213 ((char *) liblist + _dl_loaded_modules->dynamic_info[DT_GNU_LIBLISTSZ_IDX]);
1214 r_list = _dl_loaded_modules->symbol_scope.r_list;
1215 r_listend = r_list + nscope_elem;
1217 for (; r_list < r_listend && liblist < liblistend; r_list++) {
1220 if (l == _dl_loaded_modules)
1223 /* If the library is not mapped where it should, fail. */
1227 /* Next, check if checksum matches. */
1228 if (l->dynamic_info[DT_CHECKSUM_IDX] == 0 ||
1229 l->dynamic_info[DT_CHECKSUM_IDX] != liblist->l_checksum)
1232 if (l->dynamic_info[DT_GNU_PRELINKED_IDX] == 0 ||
1233 (l->dynamic_info[DT_GNU_PRELINKED_IDX] != liblist->l_time_stamp))
1236 if (_dl_strcmp(strtab + liblist->l_name, _dl_get_last_path_component(l->libname)) != 0)
1243 if (r_list == r_listend && liblist == liblistend)
1248 _dl_debug_early ("\nprelink checking: %s\n", prelinked ? "ok" : "failed");
1251 if (_dl_loaded_modules->dynamic_info[DT_GNU_CONFLICT_IDX]) {
1252 ELF_RELOC *conflict;
1253 unsigned long conflict_size;
1255 _dl_assert (_dl_loaded_modules->dynamic_info[DT_GNU_CONFLICTSZ_IDX] != 0);
1256 conflict = (ELF_RELOC *) _dl_loaded_modules->dynamic_info[DT_GNU_CONFLICT_IDX];
1257 conflict_size = _dl_loaded_modules->dynamic_info[DT_GNU_CONFLICTSZ_IDX];
1258 _dl_parse_relocation_information(_dl_symbol_tables, global_scope,
1259 (unsigned long) conflict, conflict_size);
1262 /* Mark all the objects so we know they have been already relocated. */
1263 for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) {
1264 tpnt->init_flag |= RELOCS_DONE;
1265 if (tpnt->relro_size)
1266 _dl_protect_relro (tpnt);
1273 _dl_debug_early("Beginning relocation fixups\n");
1277 * Relocation of the GOT entries for MIPS have to be done
1278 * after all the libraries have been loaded.
1280 _dl_perform_mips_global_got_relocations(_dl_loaded_modules, !unlazy);
1284 * OK, now all of the kids are tucked into bed in their proper
1285 * addresses. Now we go through and look for REL and RELA records that
1286 * indicate fixups to the GOT tables. We need to do this in reverse
1287 * order so that COPY directives work correctly.
1289 if (_dl_symbol_tables)
1290 if (_dl_fixup(_dl_symbol_tables, global_scope, unlazy))
1293 for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) {
1294 if (tpnt->relro_size)
1295 _dl_protect_relro (tpnt);
1297 } /* not prelinked */
1299 #if defined(USE_TLS) && USE_TLS
1300 if (!was_tls_init_tp_called && _dl_tls_max_dtv_idx > 0)
1301 ++_dl_tls_generation;
1303 _dl_debug_early("Calling _dl_allocate_tls_init()!\n");
1305 /* Now that we have completed relocation, the initializer data
1306 for the TLS blocks has its final values and we can copy them
1307 into the main thread's TLS area, which we allocated above. */
1308 _dl_allocate_tls_init (tcbp);
1310 /* And finally install it for the main thread. If ld.so itself uses
1311 TLS we know the thread pointer was initialized earlier. */
1312 if (! tls_init_tp_called) {
1313 const char *lossage = (char *) TLS_INIT_TP (tcbp, USE___THREAD);
1314 if (__builtin_expect (lossage != NULL, 0)) {
1315 _dl_debug_early("cannot set up thread-local storage: %s\n", lossage);
1319 #endif /* USE_TLS */
1321 /* OK, at this point things are pretty much ready to run. Now we need
1322 * to touch up a few items that are required, and then we can let the
1323 * user application have at it. Note that the dynamic linker itself
1324 * is not guaranteed to be fully dynamicly linked if we are using
1325 * ld.so.1, so we have to look up each symbol individually.
1328 _dl_envp = (unsigned long *) (intptr_t) _dl_find_hash(__C_SYMBOL_PREFIX__ "__environ", global_scope, NULL, 0, NULL);
1330 *_dl_envp = (unsigned long) envp;
1332 #ifndef __FORCE_SHAREABLE_TEXT_SEGMENTS__
1337 /* We had to set the protections of all pages to R/W for
1338 * dynamic linking. Set text pages back to R/O.
1340 for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) {
1341 for (myppnt = tpnt->ppnt, j = 0; j < tpnt->n_phent; j++, myppnt++) {
1342 if (myppnt->p_type == PT_LOAD && !(myppnt->p_flags & PF_W) && tpnt->dynamic_info[DT_TEXTREL]) {
1343 _dl_mprotect((void *) (DL_RELOC_ADDR(tpnt->loadaddr, myppnt->p_vaddr) & PAGE_ALIGN),
1344 (myppnt->p_vaddr & ADDR_ALIGN) + (unsigned long) myppnt->p_filesz, LXFLAGS(myppnt->p_flags));
1351 /* Notify the debugger we have added some objects. */
1352 _dl_debug_addr->r_state = RT_ADD;
1355 /* Run pre-initialization functions for the executable. */
1356 _dl_run_array_forward(_dl_loaded_modules->dynamic_info[DT_PREINIT_ARRAY],
1357 _dl_loaded_modules->dynamic_info[DT_PREINIT_ARRAYSZ],
1358 _dl_loaded_modules->loadaddr);
1360 /* Run initialization functions for loaded objects. For the
1361 main executable, they will be run from __uClibc_main. */
1362 for (i = nlist; i; --i) {
1363 tpnt = init_fini_list[i-1];
1364 tpnt->init_fini = NULL; /* Clear, since alloca was used */
1365 if (tpnt->init_flag & INIT_FUNCS_CALLED)
1367 tpnt->init_flag |= INIT_FUNCS_CALLED;
1369 if (tpnt->dynamic_info[DT_INIT]) {
1370 void (*dl_elf_func) (void);
1372 dl_elf_func = (void (*)(void)) DL_RELOC_ADDR(tpnt->loadaddr, tpnt->dynamic_info[DT_INIT]);
1374 _dl_if_debug_dprint("calling INIT: %s\n\n", tpnt->libname);
1376 DL_CALL_FUNC_AT_ADDR (dl_elf_func, tpnt->loadaddr, (void(*)(void)));
1379 _dl_run_init_array(tpnt);
1382 /* Find the real malloc function and make ldso functions use that from now on */
1383 _dl_malloc_function = (void* (*)(size_t)) (intptr_t) _dl_find_hash(__C_SYMBOL_PREFIX__ "malloc",
1384 global_scope, NULL, ELF_RTYPE_CLASS_PLT, NULL);
1386 #if defined(USE_TLS) && USE_TLS
1387 /* Find the real functions and make ldso functions use them from now on */
1388 _dl_calloc_function = (void* (*)(size_t, size_t)) (intptr_t)
1389 _dl_find_hash(__C_SYMBOL_PREFIX__ "calloc", global_scope, NULL, ELF_RTYPE_CLASS_PLT, NULL);
1391 _dl_realloc_function = (void* (*)(void *, size_t)) (intptr_t)
1392 _dl_find_hash(__C_SYMBOL_PREFIX__ "realloc", global_scope, NULL, ELF_RTYPE_CLASS_PLT, NULL);
1394 _dl_free_function = (void (*)(void *)) (intptr_t)
1395 _dl_find_hash(__C_SYMBOL_PREFIX__ "free", global_scope, NULL, ELF_RTYPE_CLASS_PLT, NULL);
1397 _dl_memalign_function = (void* (*)(size_t, size_t)) (intptr_t)
1398 _dl_find_hash(__C_SYMBOL_PREFIX__ "memalign", global_scope, NULL, ELF_RTYPE_CLASS_PLT, NULL);
1402 /* Notify the debugger that all objects are now mapped in. */
1403 _dl_debug_addr->r_state = RT_CONSISTENT;
1406 #ifdef __LDSO_STANDALONE_SUPPORT__
1407 if (_start == (void *) auxvt[AT_ENTRY].a_un.a_val)
1408 return (void *) app_tpnt->l_entry;
1411 return (void *) auxvt[AT_ENTRY].a_un.a_val;
1414 #include "dl-hash.c"