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 static 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;
128 # ifdef __UCLIBC_HAS_SSP_COMPAT__
129 uintptr_t __guard attribute_relro;
133 char *_dl_getenv(const char *symbol, char **envp)
138 while ((pnt = *envp++)) {
140 while (*pnt && *pnt == *pnt1)
142 if (!*pnt || *pnt != '=' || *pnt1)
149 void _dl_unsetenv(const char *symbol, char **envp)
153 char **newenvp = envp;
155 for (pnt = *envp; pnt; pnt = *++envp) {
157 while (*pnt && *pnt == *pnt1)
159 if (!*pnt || *pnt != '=' || *pnt1)
166 static int _dl_suid_ok(void)
168 __kernel_uid_t uid, euid;
169 __kernel_gid_t gid, egid;
172 euid = _dl_geteuid();
174 egid = _dl_getegid();
176 if (uid == euid && gid == egid) {
182 void *_dl_malloc(size_t size)
187 _dl_debug_early("request for %d bytes\n", size);
190 if (_dl_malloc_function)
191 return (*_dl_malloc_function) (size);
193 if (_dl_malloc_addr - _dl_mmap_zero + size > _dl_pagesize) {
196 /* Since the above assumes we get a full page even if
197 we request less than that, make sure we request a
198 full page, since uClinux may give us less than than
199 a full page. We might round even
200 larger-than-a-page sizes, but we end up never
201 reusing _dl_mmap_zero/_dl_malloc_addr in that case,
204 The actual page size doesn't really matter; as long
205 as we're self-consistent here, we're safe. */
206 if (size < _dl_pagesize)
207 rounded_size = (size + ADDR_ALIGN) & _dl_pagesize;
211 _dl_debug_early("mmapping more memory\n");
212 _dl_mmap_zero = _dl_malloc_addr = _dl_mmap((void *) 0, rounded_size,
213 PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_UNINITIALIZE, -1, 0);
214 if (_dl_mmap_check_error(_dl_mmap_zero)) {
215 _dl_dprintf(_dl_debug_file, "%s: mmap of a spare page failed!\n", _dl_progname);
219 retval = _dl_malloc_addr;
220 _dl_malloc_addr += size;
223 * Align memory to DL_MALLOC_ALIGN byte boundary. Some
224 * platforms require this, others simply get better
227 _dl_malloc_addr = (unsigned char *) (((unsigned long) _dl_malloc_addr + DL_MALLOC_ALIGN - 1) & ~(DL_MALLOC_ALIGN - 1));
231 static void *_dl_zalloc(size_t size)
233 void *p = _dl_malloc(size);
235 _dl_memset(p, 0, size);
239 void _dl_free(void *p)
241 if (_dl_free_function)
242 (*_dl_free_function) (p);
245 #if defined(USE_TLS) && USE_TLS
246 void *_dl_memalign(size_t __boundary, size_t __size)
253 if (_dl_memalign_function)
254 return (*_dl_memalign_function) (__boundary, __size);
256 while (rounded < __boundary) {
257 rounded = (1 << i++);
260 delta = (((size_t) _dl_malloc_addr + __size) & (rounded - 1));
262 if ((result = _dl_malloc(rounded - delta)) == NULL)
265 result = _dl_malloc(__size);
271 static void __attribute__ ((destructor)) __attribute_used__ _dl_fini(void)
274 struct elf_resolve * tpnt;
276 for (i = 0; i < nlist; ++i) {
277 tpnt = init_fini_list[i];
278 if (tpnt->init_flag & FINI_FUNCS_CALLED)
280 tpnt->init_flag |= FINI_FUNCS_CALLED;
281 _dl_run_fini_array(tpnt);
282 if (tpnt->dynamic_info[DT_FINI]) {
283 void (*dl_elf_func) (void);
285 dl_elf_func = (void (*)(void)) (intptr_t) DL_RELOC_ADDR(tpnt->loadaddr, tpnt->dynamic_info[DT_FINI]);
286 _dl_if_debug_dprint("\ncalling FINI: %s\n\n", tpnt->libname);
287 DL_CALL_FUNC_AT_ADDR (dl_elf_func, tpnt->loadaddr, (void(*)(void)));
292 #ifdef __LDSO_PRELINK_SUPPORT__
293 static void trace_objects(struct elf_resolve *tpnt, char *str_name)
295 if (_dl_strcmp(_dl_trace_prelink, tpnt->libname) == 0)
296 _dl_trace_prelink_map = tpnt;
297 if (tpnt->libtype == elf_executable) {
298 /* Main executeble */
299 _dl_dprintf(1, "\t%s => %s (%x, %x)", tpnt->libname, tpnt->libname,
300 tpnt->mapaddr, DL_LOADADDR_BASE(tpnt->loadaddr));
302 /* Preloaded, Needed or interpreter */
303 _dl_dprintf(1, "\t%s => %s (%x, %x)", str_name, tpnt->libname,
304 tpnt->mapaddr, DL_LOADADDR_BASE(tpnt->loadaddr));
307 #if defined USE_TLS && USE_TLS
308 if ((tpnt->libtype != program_interpreter) && (tpnt->l_tls_modid))
309 _dl_dprintf (1, " TLS(%x, %x)\n", tpnt->l_tls_modid,
310 (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__
894 if (_dl_stat(LDSO_PRELOAD, &st) || st.st_size == 0) {
898 if ((fd = _dl_open(LDSO_PRELOAD, O_RDONLY, 0)) < 0) {
899 _dl_dprintf(_dl_debug_file, "%s: can't open file '%s'\n",
900 _dl_progname, LDSO_PRELOAD);
904 preload = (caddr_t) _dl_mmap(0, st.st_size + 1,
905 PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
907 if (preload == (caddr_t) -1) {
908 _dl_dprintf(_dl_debug_file, "%s:%i: can't map '%s'\n",
909 _dl_progname, __LINE__, LDSO_PRELOAD);
913 /* convert all separators and comments to spaces */
914 for (cp = preload; *cp; /*nada */ ) {
915 if (*cp == ':' || *cp == '\t' || *cp == '\n') {
917 } else if (*cp == '#') {
920 } while (*cp != '\n' && *cp != '\0');
926 /* find start of first library */
927 for (cp = preload; *cp && *cp == ' '; cp++)
931 /* find end of library */
932 for (cp2 = cp; *cp && *cp != ' '; cp++)
937 _dl_if_debug_dprint("\tfile='%s'; needed by '%s'\n", cp2, _dl_progname);
939 tpnt1 = _dl_load_shared_library(0, &rpnt, NULL, cp2, trace_loaded_objects);
941 # ifdef __LDSO_LDD_SUPPORT__
942 if (trace_loaded_objects || _dl_trace_prelink)
943 _dl_dprintf(1, "\t%s => not found\n", cp2);
947 _dl_dprintf(_dl_debug_file, "%s: can't load library '%s'\n", _dl_progname, cp2);
951 tpnt1->rtld_flags = unlazy | RTLD_GLOBAL;
953 _dl_debug_early("Loading: (%x) %s\n", DL_LOADADDR_BASE(tpnt1->loadaddr), tpnt1->libname);
955 # ifdef __LDSO_LDD_SUPPORT__
956 if (trace_loaded_objects && !_dl_trace_prelink &&
957 tpnt1->usage_count == 1) {
958 _dl_dprintf(1, "\t%s => %s (%x)\n",
960 DL_LOADADDR_BASE(tpnt1->loadaddr));
965 /* find start of next library */
967 for ( /*nada */ ; *cp && *cp == ' '; cp++)
971 _dl_munmap(preload, st.st_size + 1);
973 #endif /* __LDSO_PRELOAD_FILE_SUPPORT__ */
976 for (tcurr = _dl_loaded_modules; tcurr; tcurr = tcurr->next) {
977 ElfW(Dyn) *this_dpnt;
980 for (this_dpnt = (ElfW(Dyn) *) tcurr->dynamic_addr; this_dpnt->d_tag; this_dpnt++) {
981 if (this_dpnt->d_tag == DT_NEEDED) {
983 struct init_fini_list *tmp;
985 lpntstr = (char*) (tcurr->dynamic_info[DT_STRTAB] + this_dpnt->d_un.d_val);
986 name = _dl_get_last_path_component(lpntstr);
987 _dl_if_debug_dprint("\tfile='%s'; needed by '%s'\n", lpntstr, _dl_progname);
989 if (_dl_strcmp(name, UCLIBC_LDSO) == 0) {
991 /* Insert the ld.so only once */
992 ldso_tpnt = add_ldso(tpnt, load_addr, auxvt, rpnt);
994 ldso_tpnt->usage_count++;
997 tpnt1 = _dl_load_shared_library(0, &rpnt, tcurr, lpntstr, trace_loaded_objects);
1000 #ifdef __LDSO_LDD_SUPPORT__
1001 if (trace_loaded_objects || _dl_trace_prelink) {
1002 _dl_dprintf(1, "\t%s => not found\n", lpntstr);
1007 _dl_dprintf(_dl_debug_file, "%s: can't load library '%s'\n", _dl_progname, lpntstr);
1012 tmp = alloca(sizeof(struct init_fini_list)); /* Allocates on stack, no need to free this memory */
1014 tmp->next = tcurr->init_fini;
1015 tcurr->init_fini = tmp;
1017 tpnt1->rtld_flags = unlazy | RTLD_GLOBAL;
1019 _dl_debug_early("Loading: (%x) %s\n", DL_LOADADDR_BASE(tpnt1->loadaddr), tpnt1->libname);
1021 #ifdef __LDSO_LDD_SUPPORT__
1022 if (trace_loaded_objects && !_dl_trace_prelink &&
1023 tpnt1->usage_count == 1) {
1024 _dl_dprintf(1, "\t%s => %s (%x)\n",
1025 lpntstr, tpnt1->libname,
1026 DL_LOADADDR_BASE(tpnt1->loadaddr));
1034 /* Keep track of the number of elements in the global scope */
1035 nscope_elem = nlist;
1037 if (_dl_loaded_modules->libtype == elf_executable) {
1038 --nlist; /* Exclude the application. */
1039 tcurr = _dl_loaded_modules->next;
1041 tcurr = _dl_loaded_modules;
1042 init_fini_list = _dl_malloc(nlist * sizeof(struct elf_resolve *));
1044 for (; tcurr; tcurr = tcurr->next)
1045 init_fini_list[i++] = tcurr;
1047 /* Sort the INIT/FINI list in dependency order. */
1048 for (tcurr = _dl_loaded_modules->next; tcurr; tcurr = tcurr->next) {
1051 for (j = 0; init_fini_list[j] != tcurr; ++j)
1053 for (k = j + 1; k < nlist; ++k) {
1054 struct init_fini_list *runp = init_fini_list[k]->init_fini;
1056 for (; runp; runp = runp->next) {
1057 if (runp->tpnt == tcurr) {
1058 struct elf_resolve *here = init_fini_list[k];
1059 _dl_if_debug_dprint("Move %s from pos %d to %d in INIT/FINI list\n", here->libname, k, j);
1060 for (i = (k - j); i; --i)
1061 init_fini_list[i+j] = init_fini_list[i+j-1];
1062 init_fini_list[j] = here;
1069 #ifdef __SUPPORT_LD_DEBUG__
1071 _dl_dprintf(_dl_debug_file, "\nINIT/FINI order and dependencies:\n");
1072 for (i = 0; i < nlist; i++) {
1073 struct init_fini_list *tmp;
1075 _dl_dprintf(_dl_debug_file, "lib: %s has deps:\n",
1076 init_fini_list[i]->libname);
1077 tmp = init_fini_list[i]->init_fini;
1078 for (; tmp; tmp = tmp->next)
1079 _dl_dprintf(_dl_debug_file, " %s ", tmp->tpnt->libname);
1080 _dl_dprintf(_dl_debug_file, "\n");
1086 * If the program interpreter is not in the module chain, add it.
1087 * This will be required for dlopen to be able to access the internal
1088 * functions in the dynamic linker and to relocate the interpreter
1089 * again once all libs are loaded.
1092 tpnt = add_ldso(tpnt, load_addr, auxvt, rpnt);
1093 tpnt->usage_count++;
1098 #ifdef RERELOCATE_LDSO
1099 /* Only rerelocate functions for now. */
1100 tpnt->init_flag = RELOCS_DONE;
1101 lpnt = (unsigned long *) (tpnt->dynamic_info[DT_PLTGOT]);
1102 # ifdef ALLOW_ZERO_PLTGOT
1103 if (tpnt->dynamic_info[DT_PLTGOT])
1105 INIT_GOT(lpnt, tpnt);
1107 tpnt->init_flag = RELOCS_DONE | JMP_RELOCS_DONE;
1112 * Allocate the global scope array.
1114 scope_elem_list = (struct elf_resolve **) _dl_malloc(nscope_elem * sizeof(struct elf_resolve *));
1116 for (i = 0, tcurr = _dl_loaded_modules; tcurr; tcurr = tcurr->next)
1117 scope_elem_list[i++] = tcurr;
1119 _dl_loaded_modules->symbol_scope.r_list = scope_elem_list;
1120 _dl_loaded_modules->symbol_scope.r_nlist = nscope_elem;
1122 * The symbol scope of the application, that is the first entry of the
1123 * _dl_loaded_modules list, is just the global scope to be used for the
1126 global_scope = &_dl_loaded_modules->symbol_scope;
1128 /* Build the local scope for each loaded modules. */
1129 local_scope = _dl_malloc(nscope_elem * sizeof(struct elf_resolve *));
1131 for (tcurr = _dl_loaded_modules->next; tcurr; tcurr = tcurr->next) {
1133 cnt = _dl_build_local_scope(local_scope, scope_elem_list[i++]);
1134 tcurr->symbol_scope.r_list = _dl_malloc(cnt * sizeof(struct elf_resolve *));
1135 tcurr->symbol_scope.r_nlist = cnt;
1136 _dl_memcpy (tcurr->symbol_scope.r_list, local_scope, cnt * sizeof (struct elf_resolve *));
1137 /* Restoring the init_flag.*/
1138 for (k = 1; k < nscope_elem; k++)
1139 scope_elem_list[k]->init_flag &= ~DL_RESERVED;
1142 _dl_free(local_scope);
1144 #ifdef __LDSO_LDD_SUPPORT__
1145 /* Exit if LD_TRACE_LOADED_OBJECTS is on. */
1146 if (trace_loaded_objects && !_dl_trace_prelink)
1150 #if defined(USE_TLS) && USE_TLS
1151 /* We do not initialize any of the TLS functionality unless any of the
1152 * initial modules uses TLS. This makes dynamic loading of modules with
1153 * TLS impossible, but to support it requires either eagerly doing setup
1154 * now or lazily doing it later. Doing it now makes us incompatible with
1155 * an old kernel that can't perform TLS_INIT_TP, even if no TLS is ever
1156 * used. Trying to do it lazily is too hairy to try when there could be
1157 * multiple threads (from a non-TLS-using libpthread). */
1158 bool was_tls_init_tp_called = tls_init_tp_called;
1160 _dl_debug_early("Calling init_tls()!\n");
1164 #ifdef __UCLIBC_HAS_SSP__
1165 /* Set up the stack checker's canary. */
1166 stack_chk_guard = _dl_setup_stack_chk_guard ();
1167 # ifdef THREAD_SET_STACK_GUARD
1168 THREAD_SET_STACK_GUARD (stack_chk_guard);
1170 __stack_chk_guard = stack_chk_guard;
1172 # ifdef __UCLIBC_HAS_SSP_COMPAT__
1173 __guard = stack_chk_guard;
1177 #ifdef __LDSO_PRELINK_SUPPORT__
1178 if (_dl_trace_prelink) {
1180 unsigned int nscope_trace = ldso_tpnt ? nscope_elem : (nscope_elem - 1);
1182 for (i = 0; i < nscope_trace; i++)
1183 trace_objects(scope_elem_list[i],
1184 _dl_get_last_path_component(scope_elem_list[i]->libname));
1187 /* Warn about undefined symbols. */
1188 if (_dl_symbol_tables)
1189 if (_dl_fixup(_dl_symbol_tables, global_scope, unlazy))
1194 if (_dl_loaded_modules->dynamic_info[DT_GNU_LIBLIST_IDX]) {
1195 ElfW(Lib) *liblist, *liblistend;
1196 struct elf_resolve **r_list, **r_listend, *l;
1197 const char *strtab = (const char *)_dl_loaded_modules->dynamic_info[DT_STRTAB];
1199 _dl_assert (_dl_loaded_modules->dynamic_info[DT_GNU_LIBLISTSZ_IDX] != 0);
1200 liblist = (ElfW(Lib) *) _dl_loaded_modules->dynamic_info[DT_GNU_LIBLIST_IDX];
1201 liblistend = (ElfW(Lib) *)
1202 ((char *) liblist + _dl_loaded_modules->dynamic_info[DT_GNU_LIBLISTSZ_IDX]);
1203 r_list = _dl_loaded_modules->symbol_scope.r_list;
1204 r_listend = r_list + nscope_elem;
1206 for (; r_list < r_listend && liblist < liblistend; r_list++) {
1209 if (l == _dl_loaded_modules)
1212 /* If the library is not mapped where it should, fail. */
1216 /* Next, check if checksum matches. */
1217 if (l->dynamic_info[DT_CHECKSUM_IDX] == 0 ||
1218 l->dynamic_info[DT_CHECKSUM_IDX] != liblist->l_checksum)
1221 if (l->dynamic_info[DT_GNU_PRELINKED_IDX] == 0 ||
1222 (l->dynamic_info[DT_GNU_PRELINKED_IDX] != liblist->l_time_stamp))
1225 if (_dl_strcmp(strtab + liblist->l_name, _dl_get_last_path_component(l->libname)) != 0)
1232 if (r_list == r_listend && liblist == liblistend)
1237 _dl_debug_early ("\nprelink checking: %s\n", prelinked ? "ok" : "failed");
1240 if (_dl_loaded_modules->dynamic_info[DT_GNU_CONFLICT_IDX]) {
1241 ELF_RELOC *conflict;
1242 unsigned long conflict_size;
1244 _dl_assert (_dl_loaded_modules->dynamic_info[DT_GNU_CONFLICTSZ_IDX] != 0);
1245 conflict = (ELF_RELOC *) _dl_loaded_modules->dynamic_info[DT_GNU_CONFLICT_IDX];
1246 conflict_size = _dl_loaded_modules->dynamic_info[DT_GNU_CONFLICTSZ_IDX];
1247 _dl_parse_relocation_information(_dl_symbol_tables, global_scope,
1248 (unsigned long) conflict, conflict_size);
1251 /* Mark all the objects so we know they have been already relocated. */
1252 for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) {
1253 tpnt->init_flag |= RELOCS_DONE;
1254 if (tpnt->relro_size)
1255 _dl_protect_relro (tpnt);
1262 _dl_debug_early("Beginning relocation fixups\n");
1266 * Relocation of the GOT entries for MIPS have to be done
1267 * after all the libraries have been loaded.
1269 _dl_perform_mips_global_got_relocations(_dl_loaded_modules, !unlazy);
1273 * OK, now all of the kids are tucked into bed in their proper
1274 * addresses. Now we go through and look for REL and RELA records that
1275 * indicate fixups to the GOT tables. We need to do this in reverse
1276 * order so that COPY directives work correctly.
1278 if (_dl_symbol_tables)
1279 if (_dl_fixup(_dl_symbol_tables, global_scope, unlazy))
1282 for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) {
1283 if (tpnt->relro_size)
1284 _dl_protect_relro (tpnt);
1286 } /* not prelinked */
1288 #if defined(USE_TLS) && USE_TLS
1289 if (!was_tls_init_tp_called && _dl_tls_max_dtv_idx > 0)
1290 ++_dl_tls_generation;
1292 _dl_debug_early("Calling _dl_allocate_tls_init()!\n");
1294 /* Now that we have completed relocation, the initializer data
1295 for the TLS blocks has its final values and we can copy them
1296 into the main thread's TLS area, which we allocated above. */
1297 _dl_allocate_tls_init (tcbp);
1299 /* And finally install it for the main thread. If ld.so itself uses
1300 TLS we know the thread pointer was initialized earlier. */
1301 if (! tls_init_tp_called) {
1302 const char *lossage = (char *) TLS_INIT_TP (tcbp, USE___THREAD);
1303 if (__builtin_expect (lossage != NULL, 0)) {
1304 _dl_debug_early("cannot set up thread-local storage: %s\n", lossage);
1308 #endif /* USE_TLS */
1310 /* OK, at this point things are pretty much ready to run. Now we need
1311 * to touch up a few items that are required, and then we can let the
1312 * user application have at it. Note that the dynamic linker itself
1313 * is not guaranteed to be fully dynamicly linked if we are using
1314 * ld.so.1, so we have to look up each symbol individually.
1317 _dl_envp = (unsigned long *) (intptr_t) _dl_find_hash(__C_SYMBOL_PREFIX__ "__environ", global_scope, NULL, 0, NULL);
1319 *_dl_envp = (unsigned long) envp;
1321 #ifndef __FORCE_SHAREABLE_TEXT_SEGMENTS__
1326 /* We had to set the protections of all pages to R/W for
1327 * dynamic linking. Set text pages back to R/O.
1329 for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) {
1330 for (myppnt = tpnt->ppnt, j = 0; j < tpnt->n_phent; j++, myppnt++) {
1331 if (myppnt->p_type == PT_LOAD && !(myppnt->p_flags & PF_W) && tpnt->dynamic_info[DT_TEXTREL]) {
1332 _dl_mprotect((void *) (DL_RELOC_ADDR(tpnt->loadaddr, myppnt->p_vaddr) & PAGE_ALIGN),
1333 (myppnt->p_vaddr & ADDR_ALIGN) + (unsigned long) myppnt->p_filesz, LXFLAGS(myppnt->p_flags));
1340 /* Notify the debugger we have added some objects. */
1341 _dl_debug_addr->r_state = RT_ADD;
1344 /* Run pre-initialization functions for the executable. */
1345 _dl_run_array_forward(_dl_loaded_modules->dynamic_info[DT_PREINIT_ARRAY],
1346 _dl_loaded_modules->dynamic_info[DT_PREINIT_ARRAYSZ],
1347 _dl_loaded_modules->loadaddr);
1349 /* Run initialization functions for loaded objects. For the
1350 main executable, they will be run from __uClibc_main. */
1351 for (i = nlist; i; --i) {
1352 tpnt = init_fini_list[i-1];
1353 tpnt->init_fini = NULL; /* Clear, since alloca was used */
1354 if (tpnt->init_flag & INIT_FUNCS_CALLED)
1356 tpnt->init_flag |= INIT_FUNCS_CALLED;
1358 if (tpnt->dynamic_info[DT_INIT]) {
1359 void (*dl_elf_func) (void);
1361 dl_elf_func = (void (*)(void)) DL_RELOC_ADDR(tpnt->loadaddr, tpnt->dynamic_info[DT_INIT]);
1363 _dl_if_debug_dprint("calling INIT: %s\n\n", tpnt->libname);
1365 DL_CALL_FUNC_AT_ADDR (dl_elf_func, tpnt->loadaddr, (void(*)(void)));
1368 _dl_run_init_array(tpnt);
1371 /* Find the real malloc function and make ldso functions use that from now on */
1372 _dl_malloc_function = (void* (*)(size_t)) (intptr_t) _dl_find_hash(__C_SYMBOL_PREFIX__ "malloc",
1373 global_scope, NULL, ELF_RTYPE_CLASS_PLT, NULL);
1375 #if defined(USE_TLS) && USE_TLS
1376 /* Find the real functions and make ldso functions use them from now on */
1377 _dl_calloc_function = (void* (*)(size_t, size_t)) (intptr_t)
1378 _dl_find_hash(__C_SYMBOL_PREFIX__ "calloc", global_scope, NULL, ELF_RTYPE_CLASS_PLT, NULL);
1380 _dl_realloc_function = (void* (*)(void *, size_t)) (intptr_t)
1381 _dl_find_hash(__C_SYMBOL_PREFIX__ "realloc", global_scope, NULL, ELF_RTYPE_CLASS_PLT, NULL);
1383 _dl_free_function = (void (*)(void *)) (intptr_t)
1384 _dl_find_hash(__C_SYMBOL_PREFIX__ "free", global_scope, NULL, ELF_RTYPE_CLASS_PLT, NULL);
1386 _dl_memalign_function = (void* (*)(size_t, size_t)) (intptr_t)
1387 _dl_find_hash(__C_SYMBOL_PREFIX__ "memalign", global_scope, NULL, ELF_RTYPE_CLASS_PLT, NULL);
1391 /* Notify the debugger that all objects are now mapped in. */
1392 _dl_debug_addr->r_state = RT_CONSISTENT;
1395 #ifdef __LDSO_STANDALONE_SUPPORT__
1396 if (_start == (void *) auxvt[AT_ENTRY].a_un.a_val)
1397 return (void *) app_tpnt->l_entry;
1400 return (void *) auxvt[AT_ENTRY].a_un.a_val;
1403 #include "dl-hash.c"