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 if (_dl_stat(tpnt->libname, &st) >= 0) {
333 tpnt->st_dev = st.st_dev;
334 tpnt->st_ino = st.st_ino;
336 tpnt->n_phent = epnt->e_phnum;
338 for (j = 0; j < epnt->e_phnum; j++, myppnt++) {
339 if (myppnt->p_type == PT_GNU_RELRO) {
340 tpnt->relro_addr = myppnt->p_vaddr;
341 tpnt->relro_size = myppnt->p_memsz;
345 tpnt->libtype = program_interpreter;
347 rpnt->next = _dl_zalloc(sizeof(struct dyn_elf));
348 rpnt->next->prev = rpnt;
351 rpnt = _dl_zalloc(sizeof(struct dyn_elf));
354 tpnt->rtld_flags = RTLD_NOW | RTLD_GLOBAL; /* Must not be LAZY */
359 static ptrdiff_t _dl_build_local_scope (struct elf_resolve **list,
360 struct elf_resolve *map)
362 struct elf_resolve **p = list;
363 struct init_fini_list *q;
366 map->init_flag |= DL_RESERVED;
368 for (q = map->init_fini; q; q = q->next)
369 if (! (q->tpnt->init_flag & DL_RESERVED))
370 p += _dl_build_local_scope (p, q->tpnt);
374 void *_dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr,
375 ElfW(auxv_t) auxvt[AT_EGID + 1], char **envp, char **argv
376 DL_GET_READY_TO_RUN_EXTRA_PARMS)
378 ElfW(Addr) app_mapaddr = 0;
382 unsigned int i, cnt, k, nscope_elem;
383 int unlazy = 0, trace_loaded_objects = 0;
384 struct dyn_elf *rpnt;
385 struct elf_resolve *tcurr;
386 struct elf_resolve *tpnt1;
387 struct elf_resolve *ldso_tpnt = NULL;
388 struct elf_resolve app_tpnt_tmp;
389 struct elf_resolve *app_tpnt = &app_tpnt_tmp;
390 struct r_debug *debug_addr;
392 unsigned long *_dl_envp; /* The environment address */
393 ElfW(Addr) relro_addr = 0;
394 size_t relro_size = 0;
395 struct r_scope_elem *global_scope;
396 struct elf_resolve **local_scope;
398 #if defined(USE_TLS) && USE_TLS
402 /* Wahoo!!! We managed to make a function call! Get malloc
403 * setup so we can use _dl_dprintf() to print debug noise
404 * instead of the SEND_STDERR macros used in dl-startup.c */
406 _dl_memset(app_tpnt, 0, sizeof(*app_tpnt));
408 /* Store the page size for later use */
409 _dl_pagesize = (auxvt[AT_PAGESZ].a_un.a_val) ? (size_t) auxvt[AT_PAGESZ].a_un.a_val : PAGE_SIZE;
410 /* Make it so _dl_malloc can use the page of memory we have already
411 * allocated. We shouldn't need to grab any more memory. This must
412 * be first since things like _dl_dprintf() use _dl_malloc()...
414 _dl_malloc_addr = (unsigned char *)_dl_pagesize;
418 _dl_debug_early("Cool, ldso survived making function calls\n");
420 /* Now we have done the mandatory linking of some things. We are now
421 * free to start using global variables, since these things have all
422 * been fixed up by now. Still no function calls outside of this
423 * library, since the dynamic resolver is not yet ready.
426 _dl_progname = argv[0];
429 #ifndef __LDSO_STANDALONE_SUPPORT__
430 if (_start == (void *) auxvt[AT_ENTRY].a_un.a_val) {
431 _dl_dprintf(_dl_debug_file, "Standalone execution is not enabled\n");
436 /* Start to build the tables of the modules that are required for
437 * this beast to run. We start with the basic executable, and then
438 * go from there. Eventually we will run across ourself, and we
439 * will need to properly deal with that as well.
442 if (_dl_getenv("LD_BIND_NOW", envp))
445 /* Now we need to figure out what kind of options are selected.
446 * Note that for SUID programs we ignore the settings in
449 if ((auxvt[AT_UID].a_un.a_val == (size_t)-1 && _dl_suid_ok()) ||
450 (auxvt[AT_UID].a_un.a_val != (size_t)-1 &&
451 auxvt[AT_UID].a_un.a_val == auxvt[AT_EUID].a_un.a_val &&
452 auxvt[AT_GID].a_un.a_val == auxvt[AT_EGID].a_un.a_val)) {
454 #ifdef __LDSO_PRELOAD_ENV_SUPPORT__
455 _dl_preload = _dl_getenv("LD_PRELOAD", envp);
457 _dl_library_path = _dl_getenv("LD_LIBRARY_PATH", envp);
459 static const char unsecure_envvars[] =
460 #ifdef EXTRA_UNSECURE_ENVVARS
461 EXTRA_UNSECURE_ENVVARS
467 nextp = unsecure_envvars;
469 _dl_unsetenv (nextp, envp);
470 /* We could use rawmemchr but this need not be fast. */
471 nextp = _dl_strchr(nextp, '\0') + 1;
472 } while (*nextp != '\0');
473 #ifdef __LDSO_PRELOAD_ENV_SUPPORT__
476 _dl_library_path = NULL;
477 /* SUID binaries can be exploited if they do LAZY relocation. */
481 #if defined(USE_TLS) && USE_TLS
482 _dl_error_catch_tsd = &_dl_initial_error_catch_tsd;
483 _dl_init_static_tls = &_dl_nothread_init_static_tls;
486 #ifdef __LDSO_STANDALONE_SUPPORT__
487 if (_start == (void *) auxvt[AT_ENTRY].a_un.a_val) {
489 unsigned int *aux_dat = (unsigned int *) argv;
490 int argc = aux_dat[-1];
492 tpnt->libname = argv[0];
494 if (! _dl_strcmp (argv[1], "--library-path") && argc > 2) {
495 _dl_library_path = argv[2];
503 * If we have no further argument the program was called incorrectly.
504 * Grant the user some education.
509 Usage: ld.so [OPTION]... EXECUTABLE-FILE [ARGS-FOR-PROGRAM...]\n\
510 You have invoked `ld.so', the helper program for shared library executables.\n\
511 This program usually lives in the file `/lib/ld.so', and special directives\n\
512 in executable files using ELF shared libraries tell the system's program\n\
513 loader to load the helper program from this file. This helper program loads\n\
514 the shared libraries needed by the program executable, prepares the program\n\
515 to run, and runs it. You may invoke this helper program directly from the\n\
516 command line to load and run an ELF executable file; this is like executing\n\
517 that file itself, but always uses this helper program from the file you\n\
518 specified, instead of the helper program file specified in the executable\n\
519 file you run. This is mostly of use for maintainers to test new versions\n\
520 of this helper program; chances are you did not intend to run this program.\n\
522 --library-path PATH use given PATH instead of content of the environment\n\
523 variable LD_LIBRARY_PATH\n");
529 _dl_progname = argv[0];
531 _dl_symbol_tables = rpnt = _dl_zalloc(sizeof(struct dyn_elf));
533 * It needs to load the _dl_progname and to map it
534 * Usually it is the main application launched by means of the ld.so
535 * but it could be also a shared object (when ld.so used for tracing)
536 * We keep the misleading app_tpnt name to avoid variable pollution
538 app_tpnt = _dl_load_elf_shared_library(_dl_secure, &rpnt, _dl_progname);
540 _dl_dprintf(_dl_debug_file, "can't load '%s'\n", _dl_progname);
544 * FIXME: it needs to properly handle a PIE executable
545 * Usually for a main application, loadaddr is computed as difference
546 * between auxvt entry points and phdr, so if it is not 0, that it is a
547 * PIE executable. In this case instead we need to set the loadaddr to 0
548 * because we are actually mapping the ELF for the main application by
549 * ourselves. So the PIE case must be checked.
552 app_tpnt->rtld_flags = unlazy | RTLD_GLOBAL;
554 if (app_tpnt->libtype == elf_executable)
555 app_tpnt->loadaddr = 0;
558 * This is used by gdb to locate the chain of shared libraries that are
561 debug_addr = _dl_zalloc(sizeof(struct r_debug));
562 ppnt = (ElfW(Phdr) *)app_tpnt->ppnt;
563 for (i = 0; i < app_tpnt->n_phent; i++, ppnt++) {
564 if (ppnt->p_type == PT_DYNAMIC) {
565 dpnt = (ElfW(Dyn) *) DL_RELOC_ADDR(app_tpnt->loadaddr, ppnt->p_vaddr);
566 _dl_parse_dynamic_info(dpnt, app_tpnt->dynamic_info, debug_addr, app_tpnt->loadaddr);
570 /* Store the path where the shared lib loader was found
573 _dl_ldsopath = _dl_strdup(tpnt->libname);
574 ptmp = _dl_strrchr(_dl_ldsopath, '/');
575 if (ptmp != _dl_ldsopath)
578 _dl_debug_early("Lib Loader: (%x) %s\n", (unsigned) DL_LOADADDR_BASE(tpnt->loadaddr), tpnt->libname);
582 /* At this point we are now free to examine the user application,
583 * and figure out which libraries are supposed to be called. Until
584 * we have this list, we will not be completely ready for dynamic
588 /* Find the runtime load address of the main executable. This may be
589 * different from what the ELF header says for ET_DYN/PIE executables.
593 ElfW(Phdr) *phdr = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_val;
595 for (idx = 0; idx < auxvt[AT_PHNUM].a_un.a_val; idx++, phdr++)
596 if (phdr->p_type == PT_PHDR) {
597 DL_INIT_LOADADDR_PROG(app_tpnt->loadaddr, auxvt[AT_PHDR].a_un.a_val - phdr->p_vaddr);
601 if (DL_LOADADDR_BASE(app_tpnt->loadaddr))
602 _dl_debug_early("Position Independent Executable: "
603 "app_tpnt->loadaddr=%x\n", DL_LOADADDR_BASE(app_tpnt->loadaddr));
607 * This is used by gdb to locate the chain of shared libraries that are
610 debug_addr = _dl_zalloc(sizeof(struct r_debug));
612 ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_val;
613 for (i = 0; i < auxvt[AT_PHNUM].a_un.a_val; i++, ppnt++) {
614 if (ppnt->p_type == PT_GNU_RELRO) {
615 relro_addr = ppnt->p_vaddr;
616 relro_size = ppnt->p_memsz;
618 if (!app_mapaddr && (ppnt->p_type == PT_LOAD)) {
619 app_mapaddr = DL_RELOC_ADDR (app_tpnt->loadaddr, ppnt->p_vaddr);
621 if (ppnt->p_type == PT_DYNAMIC) {
622 dpnt = (ElfW(Dyn) *) DL_RELOC_ADDR(app_tpnt->loadaddr, ppnt->p_vaddr);
623 _dl_parse_dynamic_info(dpnt, app_tpnt->dynamic_info, debug_addr, app_tpnt->loadaddr);
624 #ifndef __FORCE_SHAREABLE_TEXT_SEGMENTS__
625 /* Ugly, ugly. We need to call mprotect to change the
626 * protection of the text pages so that we can do the
627 * dynamic linking. We can set the protection back
628 * again once we are done.
630 _dl_debug_early("calling mprotect on the application program\n");
631 /* Now cover the application program. */
632 if (app_tpnt->dynamic_info[DT_TEXTREL]) {
633 ElfW(Phdr) *ppnt_outer = ppnt;
634 ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_val;
635 for (i = 0; i < auxvt[AT_PHNUM].a_un.a_val; i++, ppnt++) {
636 if (ppnt->p_type == PT_LOAD && !(ppnt->p_flags & PF_W))
637 _dl_mprotect((void *) (DL_RELOC_ADDR(app_tpnt->loadaddr, ppnt->p_vaddr) & PAGE_ALIGN),
638 (DL_RELOC_ADDR(app_tpnt->loadaddr, ppnt->p_vaddr) & ADDR_ALIGN) +
639 (unsigned long) ppnt->p_filesz,
640 PROT_READ | PROT_WRITE | PROT_EXEC);
645 if (app_tpnt->dynamic_info[DT_TEXTREL]) {
646 _dl_dprintf(_dl_debug_file, "Can't modify application's text section; use the GCC option -fPIE for position-independent executables.\n");
651 #ifndef ALLOW_ZERO_PLTGOT
652 /* make sure it's really there. */
653 if (app_tpnt->dynamic_info[DT_PLTGOT] == 0)
656 /* OK, we have what we need - slip this one into the list. */
657 app_tpnt = _dl_add_elf_hash_table(_dl_progname, app_tpnt->loadaddr,
658 app_tpnt->dynamic_info,
659 (unsigned long) DL_RELOC_ADDR(app_tpnt->loadaddr, ppnt->p_vaddr),
661 _dl_loaded_modules->libtype = elf_executable;
662 _dl_loaded_modules->ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_val;
663 _dl_loaded_modules->n_phent = auxvt[AT_PHNUM].a_un.a_val;
664 _dl_symbol_tables = rpnt = _dl_zalloc(sizeof(struct dyn_elf));
665 rpnt->dyn = _dl_loaded_modules;
666 app_tpnt->mapaddr = app_mapaddr;
667 app_tpnt->rtld_flags = unlazy | RTLD_GLOBAL;
668 app_tpnt->usage_count++;
669 lpnt = (unsigned long *) (app_tpnt->dynamic_info[DT_PLTGOT]);
670 #ifdef ALLOW_ZERO_PLTGOT
673 INIT_GOT(lpnt, _dl_loaded_modules);
676 /* OK, fill this in - we did not have this before */
677 if (ppnt->p_type == PT_INTERP) {
678 tpnt->libname = (char *) DL_RELOC_ADDR(app_tpnt->loadaddr, ppnt->p_vaddr);
679 #ifdef __LDSO_SEARCH_INTERP_PATH__
682 /* Store the path where the shared lib loader was found
685 _dl_ldsopath = _dl_strdup(tpnt->libname);
686 ptmp = _dl_strrchr(_dl_ldsopath, '/');
687 if (ptmp != _dl_ldsopath)
690 _dl_debug_early("Lib Loader: (%x) %s\n", (unsigned) DL_LOADADDR_BASE(tpnt->loadaddr), tpnt->libname);
694 /* Discover any TLS sections if the target supports them. */
695 if (ppnt->p_type == PT_TLS) {
696 #if defined(USE_TLS) && USE_TLS
697 if (ppnt->p_memsz > 0) {
698 app_tpnt->l_tls_blocksize = ppnt->p_memsz;
699 app_tpnt->l_tls_align = ppnt->p_align;
700 if (ppnt->p_align == 0)
701 app_tpnt->l_tls_firstbyte_offset = 0;
703 app_tpnt->l_tls_firstbyte_offset =
704 (ppnt->p_vaddr & (ppnt->p_align - 1));
705 app_tpnt->l_tls_initimage_size = ppnt->p_filesz;
706 app_tpnt->l_tls_initimage = (void *) ppnt->p_vaddr;
708 /* This image gets the ID one. */
709 _dl_tls_max_dtv_idx = app_tpnt->l_tls_modid = 1;
712 _dl_debug_early("Found TLS header for appplication program\n");
715 _dl_dprintf(_dl_debug_file, "Program uses unsupported TLS data!\n");
720 app_tpnt->relro_addr = relro_addr;
721 app_tpnt->relro_size = relro_size;
723 #if defined(USE_TLS) && USE_TLS
725 * Adjust the address of the TLS initialization image in
726 * case the executable is actually an ET_DYN object.
728 if (app_tpnt->l_tls_initimage != NULL) {
729 unsigned int tmp = (unsigned int) app_tpnt->l_tls_initimage;
730 app_tpnt->l_tls_initimage =
731 (char *) app_tpnt->l_tls_initimage + app_tpnt->loadaddr;
732 _dl_debug_early("Relocated TLS initial image from %x to %x (size = %x)\n",
733 tmp, app_tpnt->l_tls_initimage, app_tpnt->l_tls_initimage_size);
737 #ifdef __LDSO_STANDALONE_SUPPORT__
738 } /* ! ldso standalone mode */
741 #ifdef __SUPPORT_LD_DEBUG__
742 _dl_debug = _dl_getenv("LD_DEBUG", envp);
744 if (_dl_strstr(_dl_debug, "all")) {
745 _dl_debug_detail = _dl_debug_move = _dl_debug_symbols
746 = _dl_debug_reloc = _dl_debug_bindings = _dl_debug_nofixups = (void*)1;
748 _dl_debug_detail = _dl_strstr(_dl_debug, "detail");
749 _dl_debug_move = _dl_strstr(_dl_debug, "move");
750 _dl_debug_symbols = _dl_strstr(_dl_debug, "sym");
751 _dl_debug_reloc = _dl_strstr(_dl_debug, "reloc");
752 _dl_debug_nofixups = _dl_strstr(_dl_debug, "nofix");
753 _dl_debug_bindings = _dl_strstr(_dl_debug, "bind");
758 const char *dl_debug_output;
760 dl_debug_output = _dl_getenv("LD_DEBUG_OUTPUT", envp);
762 if (dl_debug_output) {
763 char tmp[22], *tmp1, *filename;
766 _dl_memset(tmp, 0, sizeof(tmp));
767 tmp1 = _dl_simple_ltoa( tmp, (unsigned long)_dl_getpid());
769 len1 = _dl_strlen(dl_debug_output);
770 len2 = _dl_strlen(tmp1);
772 filename = _dl_malloc(len1 + len2 + 2);
775 _dl_strcpy (filename, dl_debug_output);
776 filename[len1] = '.';
777 _dl_strcpy (&filename[len1+1], tmp1);
779 _dl_debug_file = _dl_open(filename, O_WRONLY|O_CREAT, 0644);
780 if (_dl_debug_file < 0) {
782 _dl_dprintf(_dl_debug_file, "can't open file: '%s'\n",filename);
789 #ifdef __LDSO_PRELINK_SUPPORT__
791 char *ld_warn = _dl_getenv ("LD_WARN", envp);
793 if (ld_warn && *ld_warn == '\0')
796 _dl_trace_prelink = _dl_getenv("LD_TRACE_PRELINKING", envp);
799 if (_dl_getenv("LD_TRACE_LOADED_OBJECTS", envp) != NULL) {
800 trace_loaded_objects++;
803 #ifndef __LDSO_LDD_SUPPORT__
804 if (trace_loaded_objects) {
805 _dl_dprintf(_dl_debug_file, "Use the ldd provided by uClibc\n");
811 * OK, fix one more thing - set up debug_addr so it will point
812 * to our chain. Later we may need to fill in more fields, but this
813 * should be enough for now.
815 debug_addr->r_map = (struct link_map *) _dl_loaded_modules;
816 debug_addr->r_version = 1;
817 debug_addr->r_ldbase = (ElfW(Addr)) DL_LOADADDR_BASE(load_addr);
818 debug_addr->r_brk = (unsigned long) &_dl_debug_state;
819 _dl_debug_addr = debug_addr;
821 /* Do not notify the debugger until the interpreter is in the list */
823 /* OK, we now have the application in the list, and we have some
824 * basic stuff in place. Now search through the list for other shared
825 * libraries that should be loaded, and insert them on the list in the
831 #ifdef __LDSO_PRELOAD_ENV_SUPPORT__
836 while (*str == ':' || *str == ' ' || *str == '\t')
841 while (*str2 && *str2 != ':' && *str2 != ' ' && *str2 != '\t')
846 if (!_dl_secure || _dl_strchr(str, '/') == NULL) {
847 _dl_if_debug_dprint("\tfile='%s'; needed by '%s'\n", str, _dl_progname);
849 tpnt1 = _dl_load_shared_library(_dl_secure, &rpnt, NULL, str, trace_loaded_objects);
851 #ifdef __LDSO_LDD_SUPPORT__
852 if (trace_loaded_objects || _dl_trace_prelink)
853 _dl_dprintf(1, "\t%s => not found\n", str);
857 _dl_dprintf(_dl_debug_file, "%s: can't load " "library '%s'\n", _dl_progname, str);
861 tpnt1->rtld_flags = unlazy | RTLD_GLOBAL;
863 _dl_debug_early("Loading: (%x) %s\n", DL_LOADADDR_BASE(tpnt1->loadaddr), tpnt1->libname);
865 #ifdef __LDSO_LDD_SUPPORT__
866 if (trace_loaded_objects && !_dl_trace_prelink &&
867 tpnt1->usage_count == 1) {
868 /* This is a real hack to make
869 * ldd not print the library
870 * itself when run on a
873 if (_dl_strcmp(_dl_progname, str) != 0)
874 _dl_dprintf(1, "\t%s => %s (%x)\n", str, tpnt1->libname,
875 DL_LOADADDR_BASE(tpnt1->loadaddr));
883 while (*str == ':' || *str == ' ' || *str == '\t')
887 #endif /* __LDSO_PRELOAD_ENV_SUPPORT__ */
889 #ifdef __LDSO_PRELOAD_FILE_SUPPORT__
895 if (_dl_stat(LDSO_PRELOAD, &st) || st.st_size == 0) {
899 if ((fd = _dl_open(LDSO_PRELOAD, O_RDONLY, 0)) < 0) {
900 _dl_dprintf(_dl_debug_file, "%s: can't open file '%s'\n",
901 _dl_progname, LDSO_PRELOAD);
905 preload = (caddr_t) _dl_mmap(0, st.st_size + 1,
906 PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
908 if (preload == (caddr_t) -1) {
909 _dl_dprintf(_dl_debug_file, "%s:%i: can't map '%s'\n",
910 _dl_progname, __LINE__, LDSO_PRELOAD);
914 /* convert all separators and comments to spaces */
915 for (cp = preload; *cp; /*nada */ ) {
916 if (*cp == ':' || *cp == '\t' || *cp == '\n') {
918 } else if (*cp == '#') {
921 } while (*cp != '\n' && *cp != '\0');
927 /* find start of first library */
928 for (cp = preload; *cp && *cp == ' '; cp++)
932 /* find end of library */
933 for (cp2 = cp; *cp && *cp != ' '; cp++)
938 _dl_if_debug_dprint("\tfile='%s'; needed by '%s'\n", cp2, _dl_progname);
940 tpnt1 = _dl_load_shared_library(0, &rpnt, NULL, cp2, trace_loaded_objects);
942 # ifdef __LDSO_LDD_SUPPORT__
943 if (trace_loaded_objects || _dl_trace_prelink)
944 _dl_dprintf(1, "\t%s => not found\n", cp2);
948 _dl_dprintf(_dl_debug_file, "%s: can't load library '%s'\n", _dl_progname, cp2);
952 tpnt1->rtld_flags = unlazy | RTLD_GLOBAL;
954 _dl_debug_early("Loading: (%x) %s\n", DL_LOADADDR_BASE(tpnt1->loadaddr), tpnt1->libname);
956 # ifdef __LDSO_LDD_SUPPORT__
957 if (trace_loaded_objects && !_dl_trace_prelink &&
958 tpnt1->usage_count == 1) {
959 _dl_dprintf(1, "\t%s => %s (%x)\n",
961 DL_LOADADDR_BASE(tpnt1->loadaddr));
966 /* find start of next library */
968 for ( /*nada */ ; *cp && *cp == ' '; cp++)
972 _dl_munmap(preload, st.st_size + 1);
974 #endif /* __LDSO_PRELOAD_FILE_SUPPORT__ */
977 for (tcurr = _dl_loaded_modules; tcurr; tcurr = tcurr->next) {
978 ElfW(Dyn) *this_dpnt;
981 for (this_dpnt = (ElfW(Dyn) *) tcurr->dynamic_addr; this_dpnt->d_tag; this_dpnt++) {
982 if (this_dpnt->d_tag == DT_NEEDED) {
984 struct init_fini_list *tmp;
986 lpntstr = (char*) (tcurr->dynamic_info[DT_STRTAB] + this_dpnt->d_un.d_val);
987 name = _dl_get_last_path_component(lpntstr);
988 _dl_if_debug_dprint("\tfile='%s'; needed by '%s'\n", lpntstr, _dl_progname);
990 if (_dl_strcmp(name, UCLIBC_LDSO) == 0) {
992 /* Insert the ld.so only once */
993 ldso_tpnt = add_ldso(tpnt, load_addr, auxvt, rpnt);
995 ldso_tpnt->usage_count++;
998 tpnt1 = _dl_load_shared_library(0, &rpnt, tcurr, lpntstr, trace_loaded_objects);
1001 #ifdef __LDSO_LDD_SUPPORT__
1002 if (trace_loaded_objects || _dl_trace_prelink) {
1003 _dl_dprintf(1, "\t%s => not found\n", lpntstr);
1008 _dl_dprintf(_dl_debug_file, "%s: can't load library '%s'\n", _dl_progname, lpntstr);
1013 tmp = alloca(sizeof(struct init_fini_list)); /* Allocates on stack, no need to free this memory */
1015 tmp->next = tcurr->init_fini;
1016 tcurr->init_fini = tmp;
1018 tpnt1->rtld_flags = unlazy | RTLD_GLOBAL;
1020 _dl_debug_early("Loading: (%x) %s\n", DL_LOADADDR_BASE(tpnt1->loadaddr), tpnt1->libname);
1022 #ifdef __LDSO_LDD_SUPPORT__
1023 if (trace_loaded_objects && !_dl_trace_prelink &&
1024 tpnt1->usage_count == 1) {
1025 _dl_dprintf(1, "\t%s => %s (%x)\n",
1026 lpntstr, tpnt1->libname,
1027 DL_LOADADDR_BASE(tpnt1->loadaddr));
1035 /* Keep track of the number of elements in the global scope */
1036 nscope_elem = nlist;
1038 if (_dl_loaded_modules->libtype == elf_executable) {
1039 --nlist; /* Exclude the application. */
1040 tcurr = _dl_loaded_modules->next;
1042 tcurr = _dl_loaded_modules;
1043 init_fini_list = _dl_malloc(nlist * sizeof(struct elf_resolve *));
1045 for (; tcurr; tcurr = tcurr->next)
1046 init_fini_list[i++] = tcurr;
1048 /* Sort the INIT/FINI list in dependency order. */
1049 for (tcurr = _dl_loaded_modules->next; tcurr; tcurr = tcurr->next) {
1052 for (j = 0; init_fini_list[j] != tcurr; ++j)
1054 for (k = j + 1; k < nlist; ++k) {
1055 struct init_fini_list *runp = init_fini_list[k]->init_fini;
1057 for (; runp; runp = runp->next) {
1058 if (runp->tpnt == tcurr) {
1059 struct elf_resolve *here = init_fini_list[k];
1060 _dl_if_debug_dprint("Move %s from pos %d to %d in INIT/FINI list\n", here->libname, k, j);
1061 for (i = (k - j); i; --i)
1062 init_fini_list[i+j] = init_fini_list[i+j-1];
1063 init_fini_list[j] = here;
1070 #ifdef __SUPPORT_LD_DEBUG__
1072 _dl_dprintf(_dl_debug_file, "\nINIT/FINI order and dependencies:\n");
1073 for (i = 0; i < nlist; i++) {
1074 struct init_fini_list *tmp;
1076 _dl_dprintf(_dl_debug_file, "lib: %s has deps:\n",
1077 init_fini_list[i]->libname);
1078 tmp = init_fini_list[i]->init_fini;
1079 for (; tmp; tmp = tmp->next)
1080 _dl_dprintf(_dl_debug_file, " %s ", tmp->tpnt->libname);
1081 _dl_dprintf(_dl_debug_file, "\n");
1087 * If the program interpreter is not in the module chain, add it.
1088 * This will be required for dlopen to be able to access the internal
1089 * functions in the dynamic linker and to relocate the interpreter
1090 * again once all libs are loaded.
1093 tpnt = add_ldso(tpnt, load_addr, auxvt, rpnt);
1094 tpnt->usage_count++;
1099 #ifdef RERELOCATE_LDSO
1100 /* Only rerelocate functions for now. */
1101 tpnt->init_flag = RELOCS_DONE;
1102 lpnt = (unsigned long *) (tpnt->dynamic_info[DT_PLTGOT]);
1103 # ifdef ALLOW_ZERO_PLTGOT
1104 if (tpnt->dynamic_info[DT_PLTGOT])
1106 INIT_GOT(lpnt, tpnt);
1108 tpnt->init_flag = RELOCS_DONE | JMP_RELOCS_DONE;
1113 * Allocate the global scope array.
1115 scope_elem_list = (struct elf_resolve **) _dl_malloc(nscope_elem * sizeof(struct elf_resolve *));
1117 for (i = 0, tcurr = _dl_loaded_modules; tcurr; tcurr = tcurr->next)
1118 scope_elem_list[i++] = tcurr;
1120 _dl_loaded_modules->symbol_scope.r_list = scope_elem_list;
1121 _dl_loaded_modules->symbol_scope.r_nlist = nscope_elem;
1123 * The symbol scope of the application, that is the first entry of the
1124 * _dl_loaded_modules list, is just the global scope to be used for the
1127 global_scope = &_dl_loaded_modules->symbol_scope;
1129 /* Build the local scope for each loaded modules. */
1130 local_scope = _dl_malloc(nscope_elem * sizeof(struct elf_resolve *));
1132 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);
1169 # ifdef __UCLIBC_HAS_SSP_COMPAT__
1170 __guard = stack_chk_guard;
1173 __stack_chk_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, 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, 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, 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, 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, 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, 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"