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 #ifdef __LDSO_PRELINK_SUPPORT__
61 char *_dl_trace_prelink = NULL; /* Library for prelinking trace */
62 struct elf_resolve *_dl_trace_prelink_map = NULL; /* Library module for prelinking trace */
63 bool _dl_verbose = true; /* On by default */
64 bool prelinked = false;
66 static int _dl_secure = 1; /* Are we dealing with setuid stuff? */
68 #ifdef __SUPPORT_LD_DEBUG__
69 char *_dl_debug = NULL;
70 char *_dl_debug_symbols = NULL;
71 char *_dl_debug_move = NULL;
72 char *_dl_debug_reloc = NULL;
73 char *_dl_debug_detail = NULL;
74 char *_dl_debug_nofixups = NULL;
75 char *_dl_debug_bindings = NULL;
76 int _dl_debug_file = 2;
79 #if defined (__LDSO_STANDALONE_SUPPORT__) && defined (__sh__)
80 /* Not hidden, needed for standalone execution. */
82 * FIXME: align dl_start for SH to other archs so that we can keep this symbol
83 * hidden and we don't need to handle in __uClibc_main
86 unsigned long _dl_skip_args = 0;
88 unsigned long attribute_hidden _dl_skip_args = 0;
91 const char *_dl_progname = UCLIBC_LDSO; /* The name of the executable being run */
92 #include "dl-startup.c"
93 #include "dl-symbols.c"
97 * This stub function is used by some debuggers. The idea is that they
98 * can set an internal breakpoint on it, so that we are notified when the
99 * address mapping is changed in some way.
101 void _dl_debug_state(void);
102 rtld_hidden_proto(_dl_debug_state, noinline);
103 void _dl_debug_state(void)
105 /* Make sure GCC doesn't recognize this function as pure, to avoid
106 * having the calls optimized away.
110 rtld_hidden_def(_dl_debug_state);
112 static unsigned char *_dl_malloc_addr = NULL; /* Lets _dl_malloc use the already allocated memory page */
113 static unsigned char *_dl_mmap_zero = NULL; /* Also used by _dl_malloc */
115 static struct elf_resolve **init_fini_list;
116 static struct elf_resolve **scope_elem_list;
117 static unsigned int nlist; /* # items in init_fini_list */
118 extern void _start(void);
120 #ifdef __UCLIBC_HAS_SSP__
121 # include <dl-osinfo.h>
122 uintptr_t stack_chk_guard;
123 # ifndef THREAD_SET_STACK_GUARD
124 /* Only exported for architectures that don't store the stack guard canary
125 * in local thread area. */
126 uintptr_t __stack_chk_guard attribute_relro;
127 # ifdef __UCLIBC_HAS_SSP_COMPAT__
128 strong_alias(__stack_chk_guard,__guard)
130 # elif __UCLIBC_HAS_SSP_COMPAT__
131 uintptr_t __guard attribute_relro;
135 char *_dl_getenv(const char *symbol, char **envp)
140 while ((pnt = *envp++)) {
142 while (*pnt && *pnt == *pnt1)
144 if (!*pnt || *pnt != '=' || *pnt1)
151 void _dl_unsetenv(const char *symbol, char **envp)
155 char **newenvp = envp;
157 for (pnt = *envp; pnt; pnt = *++envp) {
159 while (*pnt && *pnt == *pnt1)
161 if (!*pnt || *pnt != '=' || *pnt1)
168 static int _dl_suid_ok(void)
170 __kernel_uid_t uid, euid;
171 __kernel_gid_t gid, egid;
174 euid = _dl_geteuid();
176 egid = _dl_getegid();
178 if (uid == euid && gid == egid) {
184 void *_dl_malloc(size_t size)
189 _dl_debug_early("request for %d bytes\n", size);
192 if (_dl_malloc_function)
193 return (*_dl_malloc_function) (size);
195 if (_dl_malloc_addr - _dl_mmap_zero + size > _dl_pagesize) {
198 /* Since the above assumes we get a full page even if
199 we request less than that, make sure we request a
200 full page, since uClinux may give us less than than
201 a full page. We might round even
202 larger-than-a-page sizes, but we end up never
203 reusing _dl_mmap_zero/_dl_malloc_addr in that case,
206 The actual page size doesn't really matter; as long
207 as we're self-consistent here, we're safe. */
208 if (size < _dl_pagesize)
209 rounded_size = (size + ADDR_ALIGN) & _dl_pagesize;
213 _dl_debug_early("mmapping more memory\n");
214 _dl_mmap_zero = _dl_malloc_addr = _dl_mmap((void *) 0, rounded_size,
215 PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_UNINITIALIZE, -1, 0);
216 if (_dl_mmap_check_error(_dl_mmap_zero)) {
217 _dl_dprintf(_dl_debug_file, "%s: mmap of a spare page failed!\n", _dl_progname);
221 retval = _dl_malloc_addr;
222 _dl_malloc_addr += size;
225 * Align memory to DL_MALLOC_ALIGN byte boundary. Some
226 * platforms require this, others simply get better
229 _dl_malloc_addr = (unsigned char *) (((unsigned long) _dl_malloc_addr + DL_MALLOC_ALIGN - 1) & ~(DL_MALLOC_ALIGN - 1));
233 static void *_dl_zalloc(size_t size)
235 void *p = _dl_malloc(size);
237 _dl_memset(p, 0, size);
241 void _dl_free(void *p)
243 if (_dl_free_function)
244 (*_dl_free_function) (p);
247 #if defined(USE_TLS) && USE_TLS
248 void *_dl_memalign(size_t __boundary, size_t __size)
255 if (_dl_memalign_function)
256 return (*_dl_memalign_function) (__boundary, __size);
258 while (rounded < __boundary) {
259 rounded = (1 << i++);
262 delta = (((size_t) _dl_malloc_addr + __size) & (rounded - 1));
264 if ((result = _dl_malloc(rounded - delta)) == NULL)
267 result = _dl_malloc(__size);
273 static void __attribute__ ((destructor)) __attribute_used__ _dl_fini(void)
276 struct elf_resolve * tpnt;
278 for (i = 0; i < nlist; ++i) {
279 tpnt = init_fini_list[i];
280 if (tpnt->init_flag & FINI_FUNCS_CALLED)
282 tpnt->init_flag |= FINI_FUNCS_CALLED;
283 _dl_run_fini_array(tpnt);
284 if (tpnt->dynamic_info[DT_FINI]) {
285 void (*dl_elf_func) (void);
287 dl_elf_func = (void (*)(void)) (intptr_t) DL_RELOC_ADDR(tpnt->loadaddr, tpnt->dynamic_info[DT_FINI]);
288 _dl_if_debug_dprint("\ncalling FINI: %s\n\n", tpnt->libname);
289 DL_CALL_FUNC_AT_ADDR (dl_elf_func, tpnt->loadaddr, (void(*)(void)));
294 #ifdef __LDSO_PRELINK_SUPPORT__
295 static void trace_objects(struct elf_resolve *tpnt, char *str_name)
297 if (_dl_strcmp(_dl_trace_prelink, tpnt->libname) == 0)
298 _dl_trace_prelink_map = tpnt;
299 if (tpnt->libtype == elf_executable) {
300 /* Main executeble */
301 _dl_dprintf(1, "\t%s => %s (%x, %x)", tpnt->libname, tpnt->libname,
302 tpnt->mapaddr, DL_LOADADDR_BASE(tpnt->loadaddr));
304 /* Preloaded, Needed or interpreter */
305 _dl_dprintf(1, "\t%s => %s (%x, %x)", str_name, tpnt->libname,
306 tpnt->mapaddr, DL_LOADADDR_BASE(tpnt->loadaddr));
309 if ((tpnt->libtype != program_interpreter) && (tpnt->l_tls_modid))
310 _dl_dprintf (1, " TLS(%x, %x)\n", tpnt->l_tls_modid,
311 (size_t) tpnt->l_tls_offset);
313 _dl_dprintf (1, "\n");
317 static struct elf_resolve * add_ldso(struct elf_resolve *tpnt,
318 DL_LOADADDR_TYPE load_addr,
319 ElfW(auxv_t) auxvt[AT_EGID + 1],
320 struct dyn_elf *rpnt)
322 ElfW(Ehdr) *epnt = (ElfW(Ehdr) *) auxvt[AT_BASE].a_un.a_val;
323 ElfW(Phdr) *myppnt = (ElfW(Phdr) *)
324 DL_RELOC_ADDR(load_addr, epnt->e_phoff);
328 tpnt = _dl_add_elf_hash_table(tpnt->libname, tpnt->loadaddr,
329 tpnt->dynamic_info, (unsigned long)tpnt->dynamic_addr,
332 tpnt->mapaddr = load_addr;
333 if (_dl_stat(tpnt->libname, &st) >= 0) {
334 tpnt->st_dev = st.st_dev;
335 tpnt->st_ino = st.st_ino;
337 tpnt->n_phent = epnt->e_phnum;
339 for (j = 0; j < epnt->e_phnum; j++, myppnt++) {
340 if (myppnt->p_type == PT_GNU_RELRO) {
341 tpnt->relro_addr = myppnt->p_vaddr;
342 tpnt->relro_size = myppnt->p_memsz;
346 tpnt->libtype = program_interpreter;
348 rpnt->next = _dl_zalloc(sizeof(struct dyn_elf));
349 rpnt->next->prev = rpnt;
352 rpnt = _dl_zalloc(sizeof(struct dyn_elf));
355 tpnt->rtld_flags = RTLD_NOW | RTLD_GLOBAL; /* Must not be LAZY */
360 static ptrdiff_t _dl_build_local_scope (struct elf_resolve **list,
361 struct elf_resolve *map)
363 struct elf_resolve **p = list;
364 struct init_fini_list *q;
367 map->init_flag |= DL_RESERVED;
369 for (q = map->init_fini; q; q = q->next)
370 if (! (q->tpnt->init_flag & DL_RESERVED))
371 p += _dl_build_local_scope (p, q->tpnt);
375 void *_dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr,
376 ElfW(auxv_t) auxvt[AT_EGID + 1], char **envp, char **argv
377 DL_GET_READY_TO_RUN_EXTRA_PARMS)
379 ElfW(Addr) app_mapaddr = 0;
383 unsigned int i, cnt, nscope_elem;
384 int unlazy = 0, trace_loaded_objects = 0;
385 struct dyn_elf *rpnt;
386 struct elf_resolve *tcurr;
387 struct elf_resolve *tpnt1;
388 struct elf_resolve *ldso_tpnt = NULL;
389 struct elf_resolve app_tpnt_tmp;
390 struct elf_resolve *app_tpnt = &app_tpnt_tmp;
391 struct r_debug *debug_addr;
393 unsigned long *_dl_envp; /* The environment address */
394 ElfW(Addr) relro_addr = 0;
395 size_t relro_size = 0;
396 struct r_scope_elem *global_scope;
397 struct elf_resolve **local_scope;
399 #if defined(USE_TLS) && USE_TLS
403 /* Wahoo!!! We managed to make a function call! Get malloc
404 * setup so we can use _dl_dprintf() to print debug noise
405 * instead of the SEND_STDERR macros used in dl-startup.c */
407 _dl_memset(app_tpnt, 0, sizeof(*app_tpnt));
409 /* Store the page size for later use */
410 _dl_pagesize = (auxvt[AT_PAGESZ].a_un.a_val) ? (size_t) auxvt[AT_PAGESZ].a_un.a_val : PAGE_SIZE;
411 /* Make it so _dl_malloc can use the page of memory we have already
412 * allocated. We shouldn't need to grab any more memory. This must
413 * be first since things like _dl_dprintf() use _dl_malloc()...
415 _dl_malloc_addr = (unsigned char *)_dl_pagesize;
419 _dl_debug_early("Cool, ldso survived making function calls\n");
421 /* Now we have done the mandatory linking of some things. We are now
422 * free to start using global variables, since these things have all
423 * been fixed up by now. Still no function calls outside of this
424 * library, since the dynamic resolver is not yet ready.
427 _dl_progname = argv[0];
430 #ifndef __LDSO_STANDALONE_SUPPORT__
431 if (_start == (void *) auxvt[AT_ENTRY].a_un.a_val) {
432 _dl_dprintf(_dl_debug_file, "Standalone execution is not enabled\n");
437 /* Start to build the tables of the modules that are required for
438 * this beast to run. We start with the basic executable, and then
439 * go from there. Eventually we will run across ourself, and we
440 * will need to properly deal with that as well.
443 if (_dl_getenv("LD_BIND_NOW", envp))
446 /* Now we need to figure out what kind of options are selected.
447 * Note that for SUID programs we ignore the settings in
450 if ((auxvt[AT_UID].a_un.a_val == (size_t)-1 && _dl_suid_ok()) ||
451 (auxvt[AT_UID].a_un.a_val != (size_t)-1 &&
452 auxvt[AT_UID].a_un.a_val == auxvt[AT_EUID].a_un.a_val &&
453 auxvt[AT_GID].a_un.a_val == auxvt[AT_EGID].a_un.a_val)) {
455 #ifdef __LDSO_PRELOAD_ENV_SUPPORT__
456 _dl_preload = _dl_getenv("LD_PRELOAD", envp);
458 _dl_library_path = _dl_getenv("LD_LIBRARY_PATH", envp);
460 static const char unsecure_envvars[] =
461 #ifdef EXTRA_UNSECURE_ENVVARS
462 EXTRA_UNSECURE_ENVVARS
468 nextp = unsecure_envvars;
470 _dl_unsetenv (nextp, envp);
471 /* We could use rawmemchr but this need not be fast. */
472 nextp = _dl_strchr(nextp, '\0') + 1;
473 } while (*nextp != '\0');
474 #ifdef __LDSO_PRELOAD_ENV_SUPPORT__
477 _dl_library_path = NULL;
478 /* SUID binaries can be exploited if they do LAZY relocation. */
482 #if defined(USE_TLS) && USE_TLS
483 _dl_error_catch_tsd = &_dl_initial_error_catch_tsd;
484 _dl_init_static_tls = &_dl_nothread_init_static_tls;
487 #ifdef __LDSO_STANDALONE_SUPPORT__
488 if (_start == (void *) auxvt[AT_ENTRY].a_un.a_val) {
490 unsigned int *aux_dat = (unsigned int *) argv;
491 int argc = aux_dat[-1];
493 tpnt->libname = argv[0];
495 if (! _dl_strcmp (argv[1], "--library-path") && argc > 2) {
496 _dl_library_path = argv[2];
504 * If we have no further argument the program was called incorrectly.
505 * Grant the user some education.
510 Usage: ld.so [OPTION]... EXECUTABLE-FILE [ARGS-FOR-PROGRAM...]\n\
511 You have invoked `ld.so', the helper program for shared library executables.\n\
512 This program usually lives in the file `/lib/ld.so', and special directives\n\
513 in executable files using ELF shared libraries tell the system's program\n\
514 loader to load the helper program from this file. This helper program loads\n\
515 the shared libraries needed by the program executable, prepares the program\n\
516 to run, and runs it. You may invoke this helper program directly from the\n\
517 command line to load and run an ELF executable file; this is like executing\n\
518 that file itself, but always uses this helper program from the file you\n\
519 specified, instead of the helper program file specified in the executable\n\
520 file you run. This is mostly of use for maintainers to test new versions\n\
521 of this helper program; chances are you did not intend to run this program.\n\
523 --library-path PATH use given PATH instead of content of the environment\n\
524 variable LD_LIBRARY_PATH\n");
530 _dl_progname = argv[0];
532 _dl_symbol_tables = rpnt = _dl_zalloc(sizeof(struct dyn_elf));
534 * It needs to load the _dl_progname and to map it
535 * Usually it is the main application launched by means of the ld.so
536 * but it could be also a shared object (when ld.so used for tracing)
537 * We keep the misleading app_tpnt name to avoid variable pollution
539 app_tpnt = _dl_load_elf_shared_library(_dl_secure, &rpnt, _dl_progname);
541 _dl_dprintf(_dl_debug_file, "can't load '%s'\n", _dl_progname);
545 * FIXME: it needs to properly handle a PIE executable
546 * Usually for a main application, loadaddr is computed as difference
547 * between auxvt entry points and phdr, so if it is not 0, that it is a
548 * PIE executable. In this case instead we need to set the loadaddr to 0
549 * because we are actually mapping the ELF for the main application by
550 * ourselves. So the PIE case must be checked.
553 app_tpnt->rtld_flags = unlazy | RTLD_GLOBAL;
556 * This is used by gdb to locate the chain of shared libraries that are
559 debug_addr = _dl_zalloc(sizeof(struct r_debug));
560 ppnt = (ElfW(Phdr) *)app_tpnt->ppnt;
561 for (i = 0; i < app_tpnt->n_phent; i++, ppnt++) {
562 if (ppnt->p_type == PT_DYNAMIC) {
563 dpnt = (ElfW(Dyn) *) DL_RELOC_ADDR(app_tpnt->loadaddr, ppnt->p_vaddr);
564 _dl_parse_dynamic_info(dpnt, app_tpnt->dynamic_info, debug_addr, app_tpnt->loadaddr);
568 /* Store the path where the shared lib loader was found
571 _dl_ldsopath = _dl_strdup(tpnt->libname);
572 ptmp = _dl_strrchr(_dl_ldsopath, '/');
573 if (ptmp != _dl_ldsopath)
576 _dl_debug_early("Lib Loader: (%x) %s\n", (unsigned) DL_LOADADDR_BASE(tpnt->loadaddr), tpnt->libname);
580 /* At this point we are now free to examine the user application,
581 * and figure out which libraries are supposed to be called. Until
582 * we have this list, we will not be completely ready for dynamic
586 /* Find the runtime load address of the main executable. This may be
587 * different from what the ELF header says for ET_DYN/PIE executables.
591 ElfW(Phdr) *phdr = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_val;
593 for (idx = 0; idx < auxvt[AT_PHNUM].a_un.a_val; idx++, phdr++)
594 if (phdr->p_type == PT_PHDR) {
595 DL_INIT_LOADADDR_PROG(app_tpnt->loadaddr, auxvt[AT_PHDR].a_un.a_val - phdr->p_vaddr);
599 if (DL_LOADADDR_BASE(app_tpnt->loadaddr))
600 _dl_debug_early("Position Independent Executable: "
601 "app_tpnt->loadaddr=%x\n", DL_LOADADDR_BASE(app_tpnt->loadaddr));
605 * This is used by gdb to locate the chain of shared libraries that are
608 debug_addr = _dl_zalloc(sizeof(struct r_debug));
610 ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_val;
611 for (i = 0; i < auxvt[AT_PHNUM].a_un.a_val; i++, ppnt++) {
612 if (ppnt->p_type == PT_GNU_RELRO) {
613 relro_addr = ppnt->p_vaddr;
614 relro_size = ppnt->p_memsz;
616 if (!app_mapaddr && (ppnt->p_type == PT_LOAD)) {
617 app_mapaddr = DL_RELOC_ADDR (app_tpnt->loadaddr, ppnt->p_vaddr);
619 if (ppnt->p_type == PT_DYNAMIC) {
620 dpnt = (ElfW(Dyn) *) DL_RELOC_ADDR(app_tpnt->loadaddr, ppnt->p_vaddr);
621 _dl_parse_dynamic_info(dpnt, app_tpnt->dynamic_info, debug_addr, app_tpnt->loadaddr);
622 #ifndef __FORCE_SHAREABLE_TEXT_SEGMENTS__
623 /* Ugly, ugly. We need to call mprotect to change the
624 * protection of the text pages so that we can do the
625 * dynamic linking. We can set the protection back
626 * again once we are done.
628 _dl_debug_early("calling mprotect on the application program\n");
629 /* Now cover the application program. */
630 if (app_tpnt->dynamic_info[DT_TEXTREL]) {
631 ElfW(Phdr) *ppnt_outer = ppnt;
632 ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_val;
633 for (i = 0; i < auxvt[AT_PHNUM].a_un.a_val; i++, ppnt++) {
634 if (ppnt->p_type == PT_LOAD && !(ppnt->p_flags & PF_W))
635 _dl_mprotect((void *) (DL_RELOC_ADDR(app_tpnt->loadaddr, ppnt->p_vaddr) & PAGE_ALIGN),
636 (DL_RELOC_ADDR(app_tpnt->loadaddr, ppnt->p_vaddr) & ADDR_ALIGN) +
637 (unsigned long) ppnt->p_filesz,
638 PROT_READ | PROT_WRITE | PROT_EXEC);
643 if (app_tpnt->dynamic_info[DT_TEXTREL]) {
644 _dl_dprintf(_dl_debug_file, "Can't modify application's text section; use the GCC option -fPIE for position-independent executables.\n");
649 #ifndef ALLOW_ZERO_PLTGOT
650 /* make sure it's really there. */
651 if (app_tpnt->dynamic_info[DT_PLTGOT] == 0)
654 /* OK, we have what we need - slip this one into the list. */
655 app_tpnt = _dl_add_elf_hash_table(_dl_progname, app_tpnt->loadaddr,
656 app_tpnt->dynamic_info,
657 (unsigned long) DL_RELOC_ADDR(app_tpnt->loadaddr, ppnt->p_vaddr),
659 _dl_loaded_modules->libtype = elf_executable;
660 _dl_loaded_modules->ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_val;
661 _dl_loaded_modules->n_phent = auxvt[AT_PHNUM].a_un.a_val;
662 _dl_symbol_tables = rpnt = _dl_zalloc(sizeof(struct dyn_elf));
663 rpnt->dyn = _dl_loaded_modules;
664 app_tpnt->mapaddr = app_mapaddr;
665 app_tpnt->rtld_flags = unlazy | RTLD_GLOBAL;
666 app_tpnt->usage_count++;
667 lpnt = (unsigned long *) (app_tpnt->dynamic_info[DT_PLTGOT]);
668 #ifdef ALLOW_ZERO_PLTGOT
671 INIT_GOT(lpnt, _dl_loaded_modules);
674 /* OK, fill this in - we did not have this before */
675 if (ppnt->p_type == PT_INTERP) {
676 tpnt->libname = (char *) DL_RELOC_ADDR(app_tpnt->loadaddr, ppnt->p_vaddr);
677 #ifdef __LDSO_SEARCH_INTERP_PATH__
680 /* Store the path where the shared lib loader was found
683 _dl_ldsopath = _dl_strdup(tpnt->libname);
684 ptmp = _dl_strrchr(_dl_ldsopath, '/');
685 if (ptmp != _dl_ldsopath)
688 _dl_debug_early("Lib Loader: (%x) %s\n", (unsigned) DL_LOADADDR_BASE(tpnt->loadaddr), tpnt->libname);
692 /* Discover any TLS sections if the target supports them. */
693 if (ppnt->p_type == PT_TLS) {
694 #if defined(USE_TLS) && USE_TLS
695 if (ppnt->p_memsz > 0) {
696 app_tpnt->l_tls_blocksize = ppnt->p_memsz;
697 app_tpnt->l_tls_align = ppnt->p_align;
698 if (ppnt->p_align == 0)
699 app_tpnt->l_tls_firstbyte_offset = 0;
701 app_tpnt->l_tls_firstbyte_offset =
702 (ppnt->p_vaddr & (ppnt->p_align - 1));
703 app_tpnt->l_tls_initimage_size = ppnt->p_filesz;
704 app_tpnt->l_tls_initimage = (void *) ppnt->p_vaddr;
706 /* This image gets the ID one. */
707 _dl_tls_max_dtv_idx = app_tpnt->l_tls_modid = 1;
710 _dl_debug_early("Found TLS header for appplication program\n");
713 _dl_dprintf(_dl_debug_file, "Program uses unsupported TLS data!\n");
718 app_tpnt->relro_addr = relro_addr;
719 app_tpnt->relro_size = relro_size;
721 #if defined(USE_TLS) && USE_TLS
723 * Adjust the address of the TLS initialization image in
724 * case the executable is actually an ET_DYN object.
726 if (app_tpnt->l_tls_initimage != NULL) {
727 unsigned int tmp = (unsigned int) app_tpnt->l_tls_initimage;
728 app_tpnt->l_tls_initimage =
729 (char *) app_tpnt->l_tls_initimage + app_tpnt->loadaddr;
730 _dl_debug_early("Relocated TLS initial image from %x to %x (size = %x)\n",
731 tmp, app_tpnt->l_tls_initimage, app_tpnt->l_tls_initimage_size);
735 #ifdef __LDSO_STANDALONE_SUPPORT__
736 } /* ! ldso standalone mode */
739 #ifdef __SUPPORT_LD_DEBUG__
740 _dl_debug = _dl_getenv("LD_DEBUG", envp);
742 if (_dl_strstr(_dl_debug, "all")) {
743 _dl_debug_detail = _dl_debug_move = _dl_debug_symbols
744 = _dl_debug_reloc = _dl_debug_bindings = _dl_debug_nofixups = (void*)1;
746 _dl_debug_detail = _dl_strstr(_dl_debug, "detail");
747 _dl_debug_move = _dl_strstr(_dl_debug, "move");
748 _dl_debug_symbols = _dl_strstr(_dl_debug, "sym");
749 _dl_debug_reloc = _dl_strstr(_dl_debug, "reloc");
750 _dl_debug_nofixups = _dl_strstr(_dl_debug, "nofix");
751 _dl_debug_bindings = _dl_strstr(_dl_debug, "bind");
756 const char *dl_debug_output;
758 dl_debug_output = _dl_getenv("LD_DEBUG_OUTPUT", envp);
760 if (dl_debug_output) {
761 char tmp[22], *tmp1, *filename;
764 _dl_memset(tmp, 0, sizeof(tmp));
765 tmp1 = _dl_simple_ltoa( tmp, (unsigned long)_dl_getpid());
767 len1 = _dl_strlen(dl_debug_output);
768 len2 = _dl_strlen(tmp1);
770 filename = _dl_malloc(len1 + len2 + 2);
773 _dl_strcpy (filename, dl_debug_output);
774 filename[len1] = '.';
775 _dl_strcpy (&filename[len1+1], tmp1);
777 _dl_debug_file = _dl_open(filename, O_WRONLY|O_CREAT, 0644);
778 if (_dl_debug_file < 0) {
780 _dl_dprintf(_dl_debug_file, "can't open file: '%s'\n",filename);
787 #ifdef __LDSO_PRELINK_SUPPORT__
789 char *ld_warn = _dl_getenv ("LD_WARN", envp);
791 if (ld_warn && *ld_warn == '\0')
794 _dl_trace_prelink = _dl_getenv("LD_TRACE_PRELINKING", envp);
797 if (_dl_getenv("LD_TRACE_LOADED_OBJECTS", envp) != NULL) {
798 trace_loaded_objects++;
801 #ifndef __LDSO_LDD_SUPPORT__
802 if (trace_loaded_objects) {
803 _dl_dprintf(_dl_debug_file, "Use the ldd provided by uClibc\n");
809 * OK, fix one more thing - set up debug_addr so it will point
810 * to our chain. Later we may need to fill in more fields, but this
811 * should be enough for now.
813 debug_addr->r_map = (struct link_map *) _dl_loaded_modules;
814 debug_addr->r_version = 1;
815 debug_addr->r_ldbase = (ElfW(Addr)) DL_LOADADDR_BASE(load_addr);
816 debug_addr->r_brk = (unsigned long) &_dl_debug_state;
817 _dl_debug_addr = debug_addr;
819 /* Do not notify the debugger until the interpreter is in the list */
821 /* OK, we now have the application in the list, and we have some
822 * basic stuff in place. Now search through the list for other shared
823 * libraries that should be loaded, and insert them on the list in the
829 #ifdef __LDSO_PRELOAD_ENV_SUPPORT__
834 while (*str == ':' || *str == ' ' || *str == '\t')
839 while (*str2 && *str2 != ':' && *str2 != ' ' && *str2 != '\t')
844 if (!_dl_secure || _dl_strchr(str, '/') == NULL) {
845 _dl_if_debug_dprint("\tfile='%s'; needed by '%s'\n", str, _dl_progname);
847 tpnt1 = _dl_load_shared_library(_dl_secure, &rpnt, NULL, str, trace_loaded_objects);
849 #ifdef __LDSO_LDD_SUPPORT__
850 if (trace_loaded_objects || _dl_trace_prelink)
851 _dl_dprintf(1, "\t%s => not found\n", str);
855 _dl_dprintf(_dl_debug_file, "%s: can't load " "library '%s'\n", _dl_progname, str);
859 tpnt1->rtld_flags = unlazy | RTLD_GLOBAL;
861 _dl_debug_early("Loading: (%x) %s\n", DL_LOADADDR_BASE(tpnt1->loadaddr), tpnt1->libname);
863 #ifdef __LDSO_LDD_SUPPORT__
864 if (trace_loaded_objects && !_dl_trace_prelink &&
865 tpnt1->usage_count == 1) {
866 /* This is a real hack to make
867 * ldd not print the library
868 * itself when run on a
871 if (_dl_strcmp(_dl_progname, str) != 0)
872 _dl_dprintf(1, "\t%s => %s (%x)\n", str, tpnt1->libname,
873 DL_LOADADDR_BASE(tpnt1->loadaddr));
881 while (*str == ':' || *str == ' ' || *str == '\t')
885 #endif /* __LDSO_PRELOAD_ENV_SUPPORT__ */
887 #ifdef __LDSO_PRELOAD_FILE_SUPPORT__
893 if (_dl_stat(LDSO_PRELOAD, &st) || st.st_size == 0) {
897 if ((fd = _dl_open(LDSO_PRELOAD, O_RDONLY, 0)) < 0) {
898 _dl_dprintf(_dl_debug_file, "%s: can't open file '%s'\n",
899 _dl_progname, LDSO_PRELOAD);
903 preload = (caddr_t) _dl_mmap(0, st.st_size + 1,
904 PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
906 if (preload == (caddr_t) -1) {
907 _dl_dprintf(_dl_debug_file, "%s:%i: can't map '%s'\n",
908 _dl_progname, __LINE__, LDSO_PRELOAD);
912 /* convert all separators and comments to spaces */
913 for (cp = preload; *cp; /*nada */ ) {
914 if (*cp == ':' || *cp == '\t' || *cp == '\n') {
916 } else if (*cp == '#') {
919 } while (*cp != '\n' && *cp != '\0');
925 /* find start of first library */
926 for (cp = preload; *cp && *cp == ' '; cp++)
930 /* find end of library */
931 for (cp2 = cp; *cp && *cp != ' '; cp++)
936 _dl_if_debug_dprint("\tfile='%s'; needed by '%s'\n", cp2, _dl_progname);
938 tpnt1 = _dl_load_shared_library(0, &rpnt, NULL, cp2, trace_loaded_objects);
940 # ifdef __LDSO_LDD_SUPPORT__
941 if (trace_loaded_objects || _dl_trace_prelink)
942 _dl_dprintf(1, "\t%s => not found\n", cp2);
946 _dl_dprintf(_dl_debug_file, "%s: can't load library '%s'\n", _dl_progname, cp2);
950 tpnt1->rtld_flags = unlazy | RTLD_GLOBAL;
952 _dl_debug_early("Loading: (%x) %s\n", DL_LOADADDR_BASE(tpnt1->loadaddr), tpnt1->libname);
954 # ifdef __LDSO_LDD_SUPPORT__
955 if (trace_loaded_objects && !_dl_trace_prelink &&
956 tpnt1->usage_count == 1) {
957 _dl_dprintf(1, "\t%s => %s (%x)\n",
959 DL_LOADADDR_BASE(tpnt1->loadaddr));
964 /* find start of next library */
966 for ( /*nada */ ; *cp && *cp == ' '; cp++)
970 _dl_munmap(preload, st.st_size + 1);
972 #endif /* __LDSO_PRELOAD_FILE_SUPPORT__ */
975 for (tcurr = _dl_loaded_modules; tcurr; tcurr = tcurr->next) {
976 ElfW(Dyn) *this_dpnt;
979 for (this_dpnt = (ElfW(Dyn) *) tcurr->dynamic_addr; this_dpnt->d_tag; this_dpnt++) {
980 if (this_dpnt->d_tag == DT_NEEDED) {
982 struct init_fini_list *tmp;
984 lpntstr = (char*) (tcurr->dynamic_info[DT_STRTAB] + this_dpnt->d_un.d_val);
985 name = _dl_get_last_path_component(lpntstr);
986 _dl_if_debug_dprint("\tfile='%s'; needed by '%s'\n", lpntstr, _dl_progname);
988 if (_dl_strcmp(name, UCLIBC_LDSO) == 0) {
990 /* Insert the ld.so only once */
991 ldso_tpnt = add_ldso(tpnt, load_addr, auxvt, rpnt);
993 ldso_tpnt->usage_count++;
996 tpnt1 = _dl_load_shared_library(0, &rpnt, tcurr, lpntstr, trace_loaded_objects);
999 #ifdef __LDSO_LDD_SUPPORT__
1000 if (trace_loaded_objects || _dl_trace_prelink) {
1001 _dl_dprintf(1, "\t%s => not found\n", lpntstr);
1006 _dl_dprintf(_dl_debug_file, "%s: can't load library '%s'\n", _dl_progname, lpntstr);
1011 tmp = alloca(sizeof(struct init_fini_list)); /* Allocates on stack, no need to free this memory */
1013 tmp->next = tcurr->init_fini;
1014 tcurr->init_fini = tmp;
1016 tpnt1->rtld_flags = unlazy | RTLD_GLOBAL;
1018 _dl_debug_early("Loading: (%x) %s\n", DL_LOADADDR_BASE(tpnt1->loadaddr), tpnt1->libname);
1020 #ifdef __LDSO_LDD_SUPPORT__
1021 if (trace_loaded_objects && !_dl_trace_prelink &&
1022 tpnt1->usage_count == 1) {
1023 _dl_dprintf(1, "\t%s => %s (%x)\n",
1024 lpntstr, tpnt1->libname,
1025 DL_LOADADDR_BASE(tpnt1->loadaddr));
1033 /* Keep track of the number of elements in the global scope */
1034 nscope_elem = nlist;
1036 if (_dl_loaded_modules->libtype == elf_executable) {
1037 --nlist; /* Exclude the application. */
1038 tcurr = _dl_loaded_modules->next;
1040 tcurr = _dl_loaded_modules;
1041 init_fini_list = _dl_malloc(nlist * sizeof(struct elf_resolve *));
1043 for (; tcurr; tcurr = tcurr->next)
1044 init_fini_list[i++] = tcurr;
1046 /* Sort the INIT/FINI list in dependency order. */
1047 for (tcurr = _dl_loaded_modules->next; tcurr; tcurr = tcurr->next) {
1050 for (j = 0; init_fini_list[j] != tcurr; ++j)
1052 for (k = j + 1; k < nlist; ++k) {
1053 struct init_fini_list *runp = init_fini_list[k]->init_fini;
1055 for (; runp; runp = runp->next) {
1056 if (runp->tpnt == tcurr) {
1057 struct elf_resolve *here = init_fini_list[k];
1058 _dl_if_debug_dprint("Move %s from pos %d to %d in INIT/FINI list\n", here->libname, k, j);
1059 for (i = (k - j); i; --i)
1060 init_fini_list[i+j] = init_fini_list[i+j-1];
1061 init_fini_list[j] = here;
1068 #ifdef __SUPPORT_LD_DEBUG__
1070 _dl_dprintf(_dl_debug_file, "\nINIT/FINI order and dependencies:\n");
1071 for (i = 0; i < nlist; i++) {
1072 struct init_fini_list *tmp;
1074 _dl_dprintf(_dl_debug_file, "lib: %s has deps:\n",
1075 init_fini_list[i]->libname);
1076 tmp = init_fini_list[i]->init_fini;
1077 for (; tmp; tmp = tmp->next)
1078 _dl_dprintf(_dl_debug_file, " %s ", tmp->tpnt->libname);
1079 _dl_dprintf(_dl_debug_file, "\n");
1085 * If the program interpreter is not in the module chain, add it.
1086 * This will be required for dlopen to be able to access the internal
1087 * functions in the dynamic linker and to relocate the interpreter
1088 * again once all libs are loaded.
1091 tpnt = add_ldso(tpnt, load_addr, auxvt, rpnt);
1092 tpnt->usage_count++;
1097 #ifdef RERELOCATE_LDSO
1098 /* Only rerelocate functions for now. */
1099 tpnt->init_flag = RELOCS_DONE;
1100 lpnt = (unsigned long *) (tpnt->dynamic_info[DT_PLTGOT]);
1101 # ifdef ALLOW_ZERO_PLTGOT
1102 if (tpnt->dynamic_info[DT_PLTGOT])
1104 INIT_GOT(lpnt, tpnt);
1106 tpnt->init_flag = RELOCS_DONE | JMP_RELOCS_DONE;
1111 * Allocate the global scope array.
1113 scope_elem_list = (struct elf_resolve **) _dl_malloc(nscope_elem * sizeof(struct elf_resolve *));
1115 for (i = 0, tcurr = _dl_loaded_modules; tcurr; tcurr = tcurr->next)
1116 scope_elem_list[i++] = tcurr;
1118 _dl_loaded_modules->symbol_scope.r_list = scope_elem_list;
1119 _dl_loaded_modules->symbol_scope.r_nlist = nscope_elem;
1121 * The symbol scope of the application, that is the first entry of the
1122 * _dl_loaded_modules list, is just the global scope to be used for the
1125 global_scope = &_dl_loaded_modules->symbol_scope;
1127 /* Build the local scope for each loaded modules. */
1128 local_scope = _dl_malloc(nscope_elem * sizeof(struct elf_resolve *));
1130 for (tcurr = _dl_loaded_modules->next; tcurr; tcurr = tcurr->next) {
1132 cnt = _dl_build_local_scope(local_scope, scope_elem_list[i++]);
1133 tcurr->symbol_scope.r_list = _dl_malloc(cnt * sizeof(struct elf_resolve *));
1134 tcurr->symbol_scope.r_nlist = cnt;
1135 _dl_memcpy (tcurr->symbol_scope.r_list, local_scope, cnt * sizeof (struct elf_resolve *));
1136 /* Restoring the init_flag.*/
1137 for (k = 1; k < nscope_elem; k++)
1138 scope_elem_list[k]->init_flag &= ~DL_RESERVED;
1141 _dl_free(local_scope);
1143 #ifdef __LDSO_LDD_SUPPORT__
1144 /* Exit if LD_TRACE_LOADED_OBJECTS is on. */
1145 if (trace_loaded_objects && !_dl_trace_prelink)
1149 #if defined(USE_TLS) && USE_TLS
1150 /* We do not initialize any of the TLS functionality unless any of the
1151 * initial modules uses TLS. This makes dynamic loading of modules with
1152 * TLS impossible, but to support it requires either eagerly doing setup
1153 * now or lazily doing it later. Doing it now makes us incompatible with
1154 * an old kernel that can't perform TLS_INIT_TP, even if no TLS is ever
1155 * used. Trying to do it lazily is too hairy to try when there could be
1156 * multiple threads (from a non-TLS-using libpthread). */
1157 bool was_tls_init_tp_called = tls_init_tp_called;
1159 _dl_debug_early("Calling init_tls()!\n");
1163 #ifdef __UCLIBC_HAS_SSP__
1164 /* Set up the stack checker's canary. */
1165 stack_chk_guard = _dl_setup_stack_chk_guard ();
1166 # ifdef THREAD_SET_STACK_GUARD
1167 THREAD_SET_STACK_GUARD (stack_chk_guard);
1168 # ifdef __UCLIBC_HAS_SSP_COMPAT__
1169 __guard = stack_chk_guard;
1172 __stack_chk_guard = stack_chk_guard;
1176 #ifdef __LDSO_PRELINK_SUPPORT__
1177 if (_dl_trace_prelink) {
1179 unsigned int nscope_trace = ldso_tpnt ? nscope_elem : (nscope_elem - 1);
1181 for (i = 0; i < nscope_trace; i++)
1182 trace_objects(scope_elem_list[i],
1183 _dl_get_last_path_component(scope_elem_list[i]->libname));
1186 /* Warn about undefined symbols. */
1187 if (_dl_symbol_tables)
1188 if (_dl_fixup(_dl_symbol_tables, global_scope, unlazy))
1193 if (_dl_loaded_modules->dynamic_info[DT_GNU_LIBLIST_IDX]) {
1194 ElfW(Lib) *liblist, *liblistend;
1195 struct elf_resolve **r_list, **r_listend, *l;
1196 const char *strtab = (const char *)_dl_loaded_modules->dynamic_info[DT_STRTAB];
1198 _dl_assert (_dl_loaded_modules->dynamic_info[DT_GNU_LIBLISTSZ_IDX] != 0);
1199 liblist = (ElfW(Lib) *) _dl_loaded_modules->dynamic_info[DT_GNU_LIBLIST_IDX];
1200 liblistend = (ElfW(Lib) *)
1201 ((char *) liblist + _dl_loaded_modules->dynamic_info[DT_GNU_LIBLISTSZ_IDX]);
1202 r_list = _dl_loaded_modules->symbol_scope.r_list;
1203 r_listend = r_list + nscope_elem;
1205 for (; r_list < r_listend && liblist < liblistend; r_list++) {
1208 if (l == _dl_loaded_modules)
1211 /* If the library is not mapped where it should, fail. */
1215 /* Next, check if checksum matches. */
1216 if (l->dynamic_info[DT_CHECKSUM_IDX] == 0 ||
1217 l->dynamic_info[DT_CHECKSUM_IDX] != liblist->l_checksum)
1220 if (l->dynamic_info[DT_GNU_PRELINKED_IDX] == 0 ||
1221 (l->dynamic_info[DT_GNU_PRELINKED_IDX] != liblist->l_time_stamp))
1224 if (_dl_strcmp(strtab + liblist->l_name, _dl_get_last_path_component(l->libname)) != 0)
1231 if (r_list == r_listend && liblist == liblistend)
1236 _dl_debug_early ("\nprelink checking: %s\n", prelinked ? "ok" : "failed");
1239 if (_dl_loaded_modules->dynamic_info[DT_GNU_CONFLICT_IDX]) {
1240 ELF_RELOC *conflict;
1241 unsigned long conflict_size;
1243 _dl_assert (_dl_loaded_modules->dynamic_info[DT_GNU_CONFLICTSZ_IDX] != 0);
1244 conflict = (ELF_RELOC *) _dl_loaded_modules->dynamic_info[DT_GNU_CONFLICT_IDX];
1245 conflict_size = _dl_loaded_modules->dynamic_info[DT_GNU_CONFLICTSZ_IDX];
1246 _dl_parse_relocation_information(_dl_symbol_tables, global_scope,
1247 (unsigned long) conflict, conflict_size);
1250 /* Mark all the objects so we know they have been already relocated. */
1251 for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) {
1252 tpnt->init_flag |= RELOCS_DONE;
1253 if (tpnt->relro_size)
1254 _dl_protect_relro (tpnt);
1261 _dl_debug_early("Beginning relocation fixups\n");
1265 * Relocation of the GOT entries for MIPS have to be done
1266 * after all the libraries have been loaded.
1268 _dl_perform_mips_global_got_relocations(_dl_loaded_modules, !unlazy);
1272 * OK, now all of the kids are tucked into bed in their proper
1273 * addresses. Now we go through and look for REL and RELA records that
1274 * indicate fixups to the GOT tables. We need to do this in reverse
1275 * order so that COPY directives work correctly.
1277 if (_dl_symbol_tables)
1278 if (_dl_fixup(_dl_symbol_tables, global_scope, unlazy))
1281 for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) {
1282 if (tpnt->relro_size)
1283 _dl_protect_relro (tpnt);
1285 } /* not prelinked */
1287 #if defined(USE_TLS) && USE_TLS
1288 if (!was_tls_init_tp_called && _dl_tls_max_dtv_idx > 0)
1289 ++_dl_tls_generation;
1291 _dl_debug_early("Calling _dl_allocate_tls_init()!\n");
1293 /* Now that we have completed relocation, the initializer data
1294 for the TLS blocks has its final values and we can copy them
1295 into the main thread's TLS area, which we allocated above. */
1296 _dl_allocate_tls_init (tcbp);
1298 /* And finally install it for the main thread. If ld.so itself uses
1299 TLS we know the thread pointer was initialized earlier. */
1300 if (! tls_init_tp_called) {
1301 const char *lossage = (char *) TLS_INIT_TP (tcbp, USE___THREAD);
1302 if (__builtin_expect (lossage != NULL, 0)) {
1303 _dl_debug_early("cannot set up thread-local storage: %s\n", lossage);
1307 #endif /* USE_TLS */
1309 /* OK, at this point things are pretty much ready to run. Now we need
1310 * to touch up a few items that are required, and then we can let the
1311 * user application have at it. Note that the dynamic linker itself
1312 * is not guaranteed to be fully dynamicly linked if we are using
1313 * ld.so.1, so we have to look up each symbol individually.
1316 _dl_envp = (unsigned long *) (intptr_t) _dl_find_hash(__C_SYMBOL_PREFIX__ "__environ", global_scope, NULL, 0, NULL);
1318 *_dl_envp = (unsigned long) envp;
1320 #ifndef __FORCE_SHAREABLE_TEXT_SEGMENTS__
1325 /* We had to set the protections of all pages to R/W for
1326 * dynamic linking. Set text pages back to R/O.
1328 for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) {
1329 for (myppnt = tpnt->ppnt, j = 0; j < tpnt->n_phent; j++, myppnt++) {
1330 if (myppnt->p_type == PT_LOAD && !(myppnt->p_flags & PF_W) && tpnt->dynamic_info[DT_TEXTREL]) {
1331 _dl_mprotect((void *) (DL_RELOC_ADDR(tpnt->loadaddr, myppnt->p_vaddr) & PAGE_ALIGN),
1332 (myppnt->p_vaddr & ADDR_ALIGN) + (unsigned long) myppnt->p_filesz, LXFLAGS(myppnt->p_flags));
1339 /* Notify the debugger we have added some objects. */
1340 _dl_debug_addr->r_state = RT_ADD;
1343 /* Run pre-initialization functions for the executable. */
1344 _dl_run_array_forward(_dl_loaded_modules->dynamic_info[DT_PREINIT_ARRAY],
1345 _dl_loaded_modules->dynamic_info[DT_PREINIT_ARRAYSZ],
1346 _dl_loaded_modules->loadaddr);
1348 /* Run initialization functions for loaded objects. For the
1349 main executable, they will be run from __uClibc_main. */
1350 for (i = nlist; i; --i) {
1351 tpnt = init_fini_list[i-1];
1352 tpnt->init_fini = NULL; /* Clear, since alloca was used */
1353 if (tpnt->init_flag & INIT_FUNCS_CALLED)
1355 tpnt->init_flag |= INIT_FUNCS_CALLED;
1357 if (tpnt->dynamic_info[DT_INIT]) {
1358 void (*dl_elf_func) (void);
1360 dl_elf_func = (void (*)(void)) DL_RELOC_ADDR(tpnt->loadaddr, tpnt->dynamic_info[DT_INIT]);
1362 _dl_if_debug_dprint("calling INIT: %s\n\n", tpnt->libname);
1364 DL_CALL_FUNC_AT_ADDR (dl_elf_func, tpnt->loadaddr, (void(*)(void)));
1367 _dl_run_init_array(tpnt);
1370 /* Find the real malloc function and make ldso functions use that from now on */
1371 _dl_malloc_function = (void* (*)(size_t)) (intptr_t) _dl_find_hash(__C_SYMBOL_PREFIX__ "malloc",
1372 global_scope, NULL, ELF_RTYPE_CLASS_PLT, NULL);
1374 #if defined(USE_TLS) && USE_TLS
1375 /* Find the real functions and make ldso functions use them from now on */
1376 _dl_calloc_function = (void* (*)(size_t, size_t)) (intptr_t)
1377 _dl_find_hash(__C_SYMBOL_PREFIX__ "calloc", global_scope, NULL, ELF_RTYPE_CLASS_PLT, NULL);
1379 _dl_realloc_function = (void* (*)(void *, size_t)) (intptr_t)
1380 _dl_find_hash(__C_SYMBOL_PREFIX__ "realloc", global_scope, NULL, ELF_RTYPE_CLASS_PLT, NULL);
1382 _dl_free_function = (void (*)(void *)) (intptr_t)
1383 _dl_find_hash(__C_SYMBOL_PREFIX__ "free", global_scope, NULL, ELF_RTYPE_CLASS_PLT, NULL);
1385 _dl_memalign_function = (void* (*)(size_t, size_t)) (intptr_t)
1386 _dl_find_hash(__C_SYMBOL_PREFIX__ "memalign", global_scope, NULL, ELF_RTYPE_CLASS_PLT, NULL);
1390 /* Notify the debugger that all objects are now mapped in. */
1391 _dl_debug_addr->r_state = RT_CONSISTENT;
1394 #ifdef __LDSO_STANDALONE_SUPPORT__
1395 if (_start == (void *) auxvt[AT_ENTRY].a_un.a_val)
1396 return (void *) app_tpnt->l_entry;
1399 return (void *) auxvt[AT_ENTRY].a_un.a_val;
1402 #include "dl-hash.c"