1 /* vi: set sw=4 ts=4: */
3 * Program to load an ELF binary on a linux system, and run it
4 * after resolving ELF shared library symbols
6 * Copyright (C) 2005 by Joakim Tjernlund
7 * Copyright (C) 2000-2006 by Erik Andersen <andersen@codepoet.org>
8 * Copyright (c) 1994-2000 Eric Youngdale, Peter MacDonald,
9 * David Engel, Hongjiu Lu and Mitch D'Souza
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. The name of the above contributors may not be
17 * used to endorse or promote products derived from this software
18 * without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 #include "unsecvars.h"
36 /* Pull in common debug code */
39 #define ALLOW_ZERO_PLTGOT
41 #if defined(USE_TLS) && USE_TLS
45 /* Pull in the value of _dl_progname */
46 #include LDSO_ELFINTERP
48 /* Global variables used within the shared library loader */
49 #ifdef __LDSO_LD_LIBRARY_PATH__
50 char *_dl_library_path = NULL; /* Where we look for libraries */
52 #ifdef __LDSO_PRELOAD_ENV_SUPPORT__
53 char *_dl_preload = NULL; /* Things to be loaded before the libs */
55 #ifdef __LDSO_SEARCH_INTERP_PATH__
56 char *_dl_ldsopath = NULL; /* Location of the shared lib loader */
58 int _dl_errno = 0; /* We can't use the real errno in ldso */
59 size_t _dl_pagesize = 0; /* Store the page size for use later */
60 struct r_debug *_dl_debug_addr = NULL; /* Used to communicate with the gdb debugger */
61 void *(*_dl_malloc_function) (size_t size) = NULL;
62 void (*_dl_free_function) (void *p) = NULL;
64 #ifdef __LDSO_PRELINK_SUPPORT__
65 char *_dl_trace_prelink = NULL; /* Library for prelinking trace */
66 struct elf_resolve *_dl_trace_prelink_map = NULL; /* Library module for prelinking trace */
67 bool _dl_verbose = true; /* On by default */
68 bool prelinked = false;
70 static int _dl_secure = 1; /* Are we dealing with setuid stuff? */
72 #ifdef __SUPPORT_LD_DEBUG__
73 char *_dl_debug = NULL;
74 char *_dl_debug_symbols = NULL;
75 char *_dl_debug_move = NULL;
76 char *_dl_debug_reloc = NULL;
77 char *_dl_debug_detail = NULL;
78 char *_dl_debug_nofixups = NULL;
79 char *_dl_debug_bindings = NULL;
80 int _dl_debug_file = 2;
83 #if defined (__LDSO_STANDALONE_SUPPORT__) && defined (__sh__)
84 /* Not hidden, needed for standalone execution. */
86 * FIXME: align dl_start for SH to other archs so that we can keep this symbol
87 * hidden and we don't need to handle in __uClibc_main
90 unsigned long _dl_skip_args = 0;
92 unsigned long attribute_hidden _dl_skip_args = 0;
95 const char *_dl_progname = UCLIBC_LDSO; /* The name of the executable being run */
96 #include "dl-startup.c"
97 #include "dl-symbols.c"
101 * This stub function is used by some debuggers. The idea is that they
102 * can set an internal breakpoint on it, so that we are notified when the
103 * address mapping is changed in some way.
105 void _dl_debug_state(void);
106 rtld_hidden_proto(_dl_debug_state, noinline);
107 void _dl_debug_state(void)
109 /* Make sure GCC doesn't recognize this function as pure, to avoid
110 * having the calls optimized away.
114 rtld_hidden_def(_dl_debug_state);
116 static unsigned char *_dl_malloc_addr = NULL; /* Lets _dl_malloc use the already allocated memory page */
117 static unsigned char *_dl_mmap_zero = NULL; /* Also used by _dl_malloc */
119 static struct elf_resolve **init_fini_list;
120 static struct elf_resolve **scope_elem_list;
121 static unsigned int nlist; /* # items in init_fini_list */
122 extern void _start(void);
124 #ifdef __UCLIBC_HAS_SSP__
125 # include <dl-osinfo.h>
126 static uintptr_t stack_chk_guard;
127 # ifndef THREAD_SET_STACK_GUARD
128 /* Only exported for architectures that don't store the stack guard canary
129 * in local thread area. */
130 uintptr_t __stack_chk_guard attribute_relro;
132 # ifdef __UCLIBC_HAS_SSP_COMPAT__
133 uintptr_t __guard attribute_relro;
137 char *_dl_getenv(const char *symbol, char **envp)
142 while ((pnt = *envp++)) {
144 while (*pnt && *pnt == *pnt1)
146 if (!*pnt || *pnt != '=' || *pnt1)
153 void _dl_unsetenv(const char *symbol, char **envp)
157 char **newenvp = envp;
159 for (pnt = *envp; pnt; pnt = *++envp) {
161 while (*pnt && *pnt == *pnt1)
163 if (!*pnt || *pnt != '=' || *pnt1)
170 static int _dl_suid_ok(void)
172 __kernel_uid_t uid, euid;
173 __kernel_gid_t gid, egid;
176 euid = _dl_geteuid();
178 egid = _dl_getegid();
180 if (uid == euid && gid == egid) {
186 void *_dl_malloc(size_t size)
191 _dl_debug_early("request for %d bytes\n", size);
194 if (_dl_malloc_function)
195 return (*_dl_malloc_function) (size);
197 if (_dl_malloc_addr - _dl_mmap_zero + size > _dl_pagesize) {
200 /* Since the above assumes we get a full page even if
201 we request less than that, make sure we request a
202 full page, since uClinux may give us less than than
203 a full page. We might round even
204 larger-than-a-page sizes, but we end up never
205 reusing _dl_mmap_zero/_dl_malloc_addr in that case,
208 The actual page size doesn't really matter; as long
209 as we're self-consistent here, we're safe. */
210 if (size < _dl_pagesize)
211 rounded_size = (size + ADDR_ALIGN) & _dl_pagesize;
215 _dl_debug_early("mmapping more memory\n");
216 _dl_mmap_zero = _dl_malloc_addr = _dl_mmap((void *) 0, rounded_size,
217 PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_UNINITIALIZE, -1, 0);
218 if (_dl_mmap_check_error(_dl_mmap_zero)) {
219 _dl_dprintf(_dl_debug_file, "%s: mmap of a spare page failed!\n", _dl_progname);
223 retval = _dl_malloc_addr;
224 _dl_malloc_addr += size;
227 * Align memory to DL_MALLOC_ALIGN byte boundary. Some
228 * platforms require this, others simply get better
231 _dl_malloc_addr = (unsigned char *) (((unsigned long) _dl_malloc_addr + DL_MALLOC_ALIGN - 1) & ~(DL_MALLOC_ALIGN - 1));
235 static void *_dl_zalloc(size_t size)
237 void *p = _dl_malloc(size);
239 _dl_memset(p, 0, size);
243 void _dl_free(void *p)
245 if (_dl_free_function)
246 (*_dl_free_function) (p);
249 #if defined(USE_TLS) && USE_TLS
250 void *_dl_memalign(size_t __boundary, size_t __size)
257 if (_dl_memalign_function)
258 return (*_dl_memalign_function) (__boundary, __size);
260 while (rounded < __boundary) {
261 rounded = (1 << i++);
264 delta = (((size_t) _dl_malloc_addr + __size) & (rounded - 1));
266 if ((result = _dl_malloc(rounded - delta)) == NULL)
269 result = _dl_malloc(__size);
275 static void __attribute__ ((destructor)) __attribute_used__ _dl_fini(void)
278 struct elf_resolve * tpnt;
280 for (i = 0; i < nlist; ++i) {
281 tpnt = init_fini_list[i];
282 if (tpnt->init_flag & FINI_FUNCS_CALLED)
284 tpnt->init_flag |= FINI_FUNCS_CALLED;
285 _dl_run_fini_array(tpnt);
286 if (tpnt->dynamic_info[DT_FINI]) {
287 void (*dl_elf_func) (void);
289 dl_elf_func = (void (*)(void)) (intptr_t) DL_RELOC_ADDR(tpnt->loadaddr, tpnt->dynamic_info[DT_FINI]);
290 _dl_if_debug_dprint("\ncalling FINI: %s\n\n", tpnt->libname);
291 DL_CALL_FUNC_AT_ADDR (dl_elf_func, tpnt->loadaddr, (void(*)(void)));
296 #ifdef __LDSO_PRELINK_SUPPORT__
297 static void trace_objects(struct elf_resolve *tpnt, char *str_name)
299 if (_dl_strcmp(_dl_trace_prelink, tpnt->libname) == 0)
300 _dl_trace_prelink_map = tpnt;
301 if (tpnt->libtype == elf_executable) {
302 /* Main executeble */
303 _dl_dprintf(1, "\t%s => %s (%x, %x)", tpnt->libname, tpnt->libname,
304 tpnt->mapaddr, DL_LOADADDR_BASE(tpnt->loadaddr));
306 /* Preloaded, Needed or interpreter */
307 _dl_dprintf(1, "\t%s => %s (%x, %x)", str_name, tpnt->libname,
308 tpnt->mapaddr, DL_LOADADDR_BASE(tpnt->loadaddr));
311 #if defined USE_TLS && USE_TLS
312 if ((tpnt->libtype != program_interpreter) && (tpnt->l_tls_modid))
313 _dl_dprintf (1, " TLS(%x, %x)\n", tpnt->l_tls_modid,
314 (size_t) tpnt->l_tls_offset);
317 _dl_dprintf (1, "\n");
321 static struct elf_resolve * add_ldso(struct elf_resolve *tpnt,
322 DL_LOADADDR_TYPE load_addr,
323 ElfW(auxv_t) auxvt[AT_EGID + 1],
324 struct dyn_elf *rpnt)
326 ElfW(Ehdr) *epnt = (ElfW(Ehdr) *) auxvt[AT_BASE].a_un.a_val;
327 ElfW(Phdr) *myppnt = (ElfW(Phdr) *)
328 DL_RELOC_ADDR(load_addr, epnt->e_phoff);
332 tpnt = _dl_add_elf_hash_table(tpnt->libname, tpnt->loadaddr,
333 tpnt->dynamic_info, (unsigned long)tpnt->dynamic_addr,
336 tpnt->mapaddr = load_addr;
337 if (_dl_stat(tpnt->libname, &st) >= 0) {
338 tpnt->st_dev = st.st_dev;
339 tpnt->st_ino = st.st_ino;
341 tpnt->n_phent = epnt->e_phnum;
343 for (j = 0; j < epnt->e_phnum; j++, myppnt++) {
344 if (myppnt->p_type == PT_GNU_RELRO) {
345 tpnt->relro_addr = myppnt->p_vaddr;
346 tpnt->relro_size = myppnt->p_memsz;
350 tpnt->libtype = program_interpreter;
352 rpnt->next = _dl_zalloc(sizeof(struct dyn_elf));
353 rpnt->next->prev = rpnt;
356 rpnt = _dl_zalloc(sizeof(struct dyn_elf));
359 tpnt->rtld_flags = RTLD_NOW | RTLD_GLOBAL; /* Must not be LAZY */
364 static ptrdiff_t _dl_build_local_scope (struct elf_resolve **list,
365 struct elf_resolve *map)
367 struct elf_resolve **p = list;
368 struct init_fini_list *q;
371 map->init_flag |= DL_RESERVED;
373 for (q = map->init_fini; q; q = q->next)
374 if (! (q->tpnt->init_flag & DL_RESERVED))
375 p += _dl_build_local_scope (p, q->tpnt);
379 void *_dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr,
380 ElfW(auxv_t) auxvt[AT_EGID + 1], char **envp, char **argv
381 DL_GET_READY_TO_RUN_EXTRA_PARMS)
383 ElfW(Addr) app_mapaddr = 0;
387 unsigned int i, cnt, nscope_elem;
388 int unlazy = 0, trace_loaded_objects = 0;
389 struct dyn_elf *rpnt;
390 struct elf_resolve *tcurr;
391 struct elf_resolve *tpnt1;
392 struct elf_resolve *ldso_tpnt = NULL;
393 struct elf_resolve app_tpnt_tmp;
394 struct elf_resolve *app_tpnt = &app_tpnt_tmp;
395 struct r_debug *debug_addr;
397 unsigned long *_dl_envp; /* The environment address */
398 ElfW(Addr) relro_addr = 0;
399 size_t relro_size = 0;
400 struct r_scope_elem *global_scope;
401 struct elf_resolve **local_scope;
403 #if defined(USE_TLS) && USE_TLS
407 /* Wahoo!!! We managed to make a function call! Get malloc
408 * setup so we can use _dl_dprintf() to print debug noise
409 * instead of the SEND_STDERR macros used in dl-startup.c */
411 _dl_memset(app_tpnt, 0, sizeof(*app_tpnt));
413 /* Store the page size for later use */
414 _dl_pagesize = (auxvt[AT_PAGESZ].a_un.a_val) ? (size_t) auxvt[AT_PAGESZ].a_un.a_val : PAGE_SIZE;
415 /* Make it so _dl_malloc can use the page of memory we have already
416 * allocated. We shouldn't need to grab any more memory. This must
417 * be first since things like _dl_dprintf() use _dl_malloc()...
419 _dl_malloc_addr = (unsigned char *)_dl_pagesize;
423 _dl_debug_early("Cool, ldso survived making function calls\n");
425 /* Now we have done the mandatory linking of some things. We are now
426 * free to start using global variables, since these things have all
427 * been fixed up by now. Still no function calls outside of this
428 * library, since the dynamic resolver is not yet ready.
431 _dl_progname = argv[0];
434 #ifndef __LDSO_STANDALONE_SUPPORT__
435 if (_start == (void *) auxvt[AT_ENTRY].a_un.a_val) {
436 _dl_dprintf(_dl_debug_file, "Standalone execution is not enabled\n");
441 /* Start to build the tables of the modules that are required for
442 * this beast to run. We start with the basic executable, and then
443 * go from there. Eventually we will run across ourself, and we
444 * will need to properly deal with that as well.
447 if (_dl_getenv("LD_BIND_NOW", envp))
450 /* Now we need to figure out what kind of options are selected.
451 * Note that for SUID programs we ignore the settings in
454 if ((auxvt[AT_UID].a_un.a_val == (size_t)-1 && _dl_suid_ok()) ||
455 (auxvt[AT_UID].a_un.a_val != (size_t)-1 &&
456 auxvt[AT_UID].a_un.a_val == auxvt[AT_EUID].a_un.a_val &&
457 auxvt[AT_GID].a_un.a_val == auxvt[AT_EGID].a_un.a_val)) {
459 #ifdef __LDSO_PRELOAD_ENV_SUPPORT__
460 _dl_preload = _dl_getenv("LD_PRELOAD", envp);
462 #ifdef __LDSO_LD_LIBRARY_PATH__
463 _dl_library_path = _dl_getenv("LD_LIBRARY_PATH", envp);
466 static const char unsecure_envvars[] =
467 #ifdef EXTRA_UNSECURE_ENVVARS
468 EXTRA_UNSECURE_ENVVARS
474 nextp = unsecure_envvars;
476 _dl_unsetenv (nextp, envp);
477 /* We could use rawmemchr but this need not be fast. */
478 nextp = _dl_strchr(nextp, '\0') + 1;
479 } while (*nextp != '\0');
480 #ifdef __LDSO_PRELOAD_ENV_SUPPORT__
483 #ifdef __LDSO_LD_LIBRARY_PATH__
484 _dl_library_path = NULL;
486 /* SUID binaries can be exploited if they do LAZY relocation. */
490 #if defined(USE_TLS) && USE_TLS
491 _dl_error_catch_tsd = &_dl_initial_error_catch_tsd;
492 _dl_init_static_tls = &_dl_nothread_init_static_tls;
495 #ifdef __LDSO_STANDALONE_SUPPORT__
496 if (_start == (void *) auxvt[AT_ENTRY].a_un.a_val) {
497 unsigned int *aux_dat = (unsigned int *) argv;
498 int argc = aux_dat[-1];
500 tpnt->libname = argv[0];
502 if (! _dl_strcmp (argv[1], "--library-path") && argc > 2) {
503 #ifdef __LDSO_LD_LIBRARY_PATH__
504 _dl_library_path = argv[2];
513 * If we have no further argument the program was called incorrectly.
514 * Grant the user some education.
519 Usage: ld.so [OPTION]... EXECUTABLE-FILE [ARGS-FOR-PROGRAM...]\n\
520 You have invoked `ld.so', the helper program for shared library executables.\n\
521 This program usually lives in the file `/lib/ld.so', and special directives\n\
522 in executable files using ELF shared libraries tell the system's program\n\
523 loader to load the helper program from this file. This helper program loads\n\
524 the shared libraries needed by the program executable, prepares the program\n\
525 to run, and runs it. You may invoke this helper program directly from the\n\
526 command line to load and run an ELF executable file; this is like executing\n\
527 that file itself, but always uses this helper program from the file you\n\
528 specified, instead of the helper program file specified in the executable\n\
529 file you run. This is mostly of use for maintainers to test new versions\n\
530 of this helper program; chances are you did not intend to run this program.\n\
532 --library-path PATH use given PATH instead of content of the environment\n\
533 variable LD_LIBRARY_PATH\n");
539 _dl_progname = argv[0];
541 _dl_symbol_tables = rpnt = _dl_zalloc(sizeof(struct dyn_elf));
543 * It needs to load the _dl_progname and to map it
544 * Usually it is the main application launched by means of the ld.so
545 * but it could be also a shared object (when ld.so used for tracing)
546 * We keep the misleading app_tpnt name to avoid variable pollution
548 app_tpnt = _dl_load_elf_shared_library(_dl_secure, &rpnt, _dl_progname);
550 _dl_dprintf(_dl_debug_file, "can't load '%s'\n", _dl_progname);
554 * FIXME: it needs to properly handle a PIE executable
555 * Usually for a main application, loadaddr is computed as difference
556 * between auxvt entry points and phdr, so if it is not 0, that it is a
557 * PIE executable. In this case instead we need to set the loadaddr to 0
558 * because we are actually mapping the ELF for the main application by
559 * ourselves. So the PIE case must be checked.
562 app_tpnt->rtld_flags = unlazy | RTLD_GLOBAL;
565 * This is used by gdb to locate the chain of shared libraries that are
568 debug_addr = _dl_zalloc(sizeof(struct r_debug));
569 ppnt = (ElfW(Phdr) *)app_tpnt->ppnt;
570 for (i = 0; i < app_tpnt->n_phent; i++, ppnt++) {
571 if (ppnt->p_type == PT_DYNAMIC) {
572 dpnt = (ElfW(Dyn) *) DL_RELOC_ADDR(app_tpnt->loadaddr, ppnt->p_vaddr);
573 _dl_parse_dynamic_info(dpnt, app_tpnt->dynamic_info, debug_addr, app_tpnt->loadaddr);
577 #ifdef __LDSO_SEARCH_INTERP_PATH__
580 /* Store the path where the shared lib loader was found
583 _dl_ldsopath = _dl_strdup(tpnt->libname);
584 ptmp = _dl_strrchr(_dl_ldsopath, '/');
585 if (ptmp != _dl_ldsopath)
588 _dl_debug_early("Lib Loader: (%x) %s\n", (unsigned) DL_LOADADDR_BASE(tpnt->loadaddr), tpnt->libname);
594 /* At this point we are now free to examine the user application,
595 * and figure out which libraries are supposed to be called. Until
596 * we have this list, we will not be completely ready for dynamic
600 /* Find the runtime load address of the main executable. This may be
601 * different from what the ELF header says for ET_DYN/PIE executables.
605 ElfW(Phdr) *phdr = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_val;
607 for (idx = 0; idx < auxvt[AT_PHNUM].a_un.a_val; idx++, phdr++)
608 if (phdr->p_type == PT_PHDR) {
609 DL_INIT_LOADADDR_PROG(app_tpnt->loadaddr, auxvt[AT_PHDR].a_un.a_val - phdr->p_vaddr);
613 if (DL_LOADADDR_BASE(app_tpnt->loadaddr))
614 _dl_debug_early("Position Independent Executable: "
615 "app_tpnt->loadaddr=%x\n", DL_LOADADDR_BASE(app_tpnt->loadaddr));
619 * This is used by gdb to locate the chain of shared libraries that are
622 debug_addr = _dl_zalloc(sizeof(struct r_debug));
624 ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_val;
625 for (i = 0; i < auxvt[AT_PHNUM].a_un.a_val; i++, ppnt++) {
626 if (ppnt->p_type == PT_GNU_RELRO) {
627 relro_addr = ppnt->p_vaddr;
628 relro_size = ppnt->p_memsz;
630 if (!app_mapaddr && (ppnt->p_type == PT_LOAD)) {
631 app_mapaddr = DL_RELOC_ADDR (app_tpnt->loadaddr, ppnt->p_vaddr);
633 if (ppnt->p_type == PT_DYNAMIC) {
634 dpnt = (ElfW(Dyn) *) DL_RELOC_ADDR(app_tpnt->loadaddr, ppnt->p_vaddr);
635 _dl_parse_dynamic_info(dpnt, app_tpnt->dynamic_info, debug_addr, app_tpnt->loadaddr);
636 #ifndef __FORCE_SHAREABLE_TEXT_SEGMENTS__
637 /* Ugly, ugly. We need to call mprotect to change the
638 * protection of the text pages so that we can do the
639 * dynamic linking. We can set the protection back
640 * again once we are done.
642 _dl_debug_early("calling mprotect on the application program\n");
643 /* Now cover the application program. */
644 if (app_tpnt->dynamic_info[DT_TEXTREL]) {
645 ElfW(Phdr) *ppnt_outer = ppnt;
646 ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_val;
647 for (i = 0; i < auxvt[AT_PHNUM].a_un.a_val; i++, ppnt++) {
648 if (ppnt->p_type == PT_LOAD && !(ppnt->p_flags & PF_W))
649 _dl_mprotect((void *) (DL_RELOC_ADDR(app_tpnt->loadaddr, ppnt->p_vaddr) & PAGE_ALIGN),
650 (DL_RELOC_ADDR(app_tpnt->loadaddr, ppnt->p_vaddr) & ADDR_ALIGN) +
651 (unsigned long) ppnt->p_filesz,
652 PROT_READ | PROT_WRITE | PROT_EXEC);
657 if (app_tpnt->dynamic_info[DT_TEXTREL]) {
658 _dl_dprintf(_dl_debug_file, "Can't modify application's text section; use the GCC option -fPIE for position-independent executables.\n");
663 #ifndef ALLOW_ZERO_PLTGOT
664 /* make sure it's really there. */
665 if (app_tpnt->dynamic_info[DT_PLTGOT] == 0)
668 /* OK, we have what we need - slip this one into the list. */
669 app_tpnt = _dl_add_elf_hash_table(_dl_progname, app_tpnt->loadaddr,
670 app_tpnt->dynamic_info,
671 (unsigned long) DL_RELOC_ADDR(app_tpnt->loadaddr, ppnt->p_vaddr),
673 _dl_loaded_modules->libtype = elf_executable;
674 _dl_loaded_modules->ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_val;
675 _dl_loaded_modules->n_phent = auxvt[AT_PHNUM].a_un.a_val;
676 _dl_symbol_tables = rpnt = _dl_zalloc(sizeof(struct dyn_elf));
677 rpnt->dyn = _dl_loaded_modules;
678 app_tpnt->mapaddr = app_mapaddr;
679 app_tpnt->rtld_flags = unlazy | RTLD_GLOBAL;
680 app_tpnt->usage_count++;
681 lpnt = (unsigned long *) (app_tpnt->dynamic_info[DT_PLTGOT]);
682 #ifdef ALLOW_ZERO_PLTGOT
685 INIT_GOT(lpnt, _dl_loaded_modules);
688 /* OK, fill this in - we did not have this before */
689 if (ppnt->p_type == PT_INTERP) {
690 tpnt->libname = (char *) DL_RELOC_ADDR(app_tpnt->loadaddr, ppnt->p_vaddr);
691 #ifdef __LDSO_SEARCH_INTERP_PATH__
694 /* Store the path where the shared lib loader was found
697 _dl_ldsopath = _dl_strdup(tpnt->libname);
698 ptmp = _dl_strrchr(_dl_ldsopath, '/');
699 if (ptmp != _dl_ldsopath)
702 _dl_debug_early("Lib Loader: (%x) %s\n", (unsigned) DL_LOADADDR_BASE(tpnt->loadaddr), tpnt->libname);
706 /* Discover any TLS sections if the target supports them. */
707 if (ppnt->p_type == PT_TLS) {
708 #if defined(USE_TLS) && USE_TLS
709 if (ppnt->p_memsz > 0) {
710 app_tpnt->l_tls_blocksize = ppnt->p_memsz;
711 app_tpnt->l_tls_align = ppnt->p_align;
712 if (ppnt->p_align == 0)
713 app_tpnt->l_tls_firstbyte_offset = 0;
715 app_tpnt->l_tls_firstbyte_offset =
716 (ppnt->p_vaddr & (ppnt->p_align - 1));
717 app_tpnt->l_tls_initimage_size = ppnt->p_filesz;
718 app_tpnt->l_tls_initimage = (void *) ppnt->p_vaddr;
720 /* This image gets the ID one. */
721 _dl_tls_max_dtv_idx = app_tpnt->l_tls_modid = 1;
724 _dl_debug_early("Found TLS header for appplication program\n");
727 _dl_dprintf(_dl_debug_file, "Program uses unsupported TLS data!\n");
732 app_tpnt->relro_addr = relro_addr;
733 app_tpnt->relro_size = relro_size;
735 #if defined(USE_TLS) && USE_TLS
737 * Adjust the address of the TLS initialization image in
738 * case the executable is actually an ET_DYN object.
740 if (app_tpnt->l_tls_initimage != NULL) {
741 unsigned int tmp = (unsigned int) app_tpnt->l_tls_initimage;
742 app_tpnt->l_tls_initimage =
743 (char *) app_tpnt->l_tls_initimage + app_tpnt->loadaddr;
744 _dl_debug_early("Relocated TLS initial image from %x to %x (size = %x)\n",
745 tmp, app_tpnt->l_tls_initimage, app_tpnt->l_tls_initimage_size);
749 #ifdef __LDSO_STANDALONE_SUPPORT__
750 } /* ! ldso standalone mode */
753 #ifdef __SUPPORT_LD_DEBUG__
754 _dl_debug = _dl_getenv("LD_DEBUG", envp);
756 if (_dl_strstr(_dl_debug, "all")) {
757 _dl_debug_detail = _dl_debug_move = _dl_debug_symbols
758 = _dl_debug_reloc = _dl_debug_bindings = _dl_debug_nofixups = (void*)1;
760 _dl_debug_detail = _dl_strstr(_dl_debug, "detail");
761 _dl_debug_move = _dl_strstr(_dl_debug, "move");
762 _dl_debug_symbols = _dl_strstr(_dl_debug, "sym");
763 _dl_debug_reloc = _dl_strstr(_dl_debug, "reloc");
764 _dl_debug_nofixups = _dl_strstr(_dl_debug, "nofix");
765 _dl_debug_bindings = _dl_strstr(_dl_debug, "bind");
770 const char *dl_debug_output;
772 dl_debug_output = _dl_getenv("LD_DEBUG_OUTPUT", envp);
774 if (dl_debug_output) {
775 char tmp[22], *tmp1, *filename;
778 _dl_memset(tmp, 0, sizeof(tmp));
779 tmp1 = _dl_simple_ltoa( tmp, (unsigned long)_dl_getpid());
781 len1 = _dl_strlen(dl_debug_output);
782 len2 = _dl_strlen(tmp1);
784 filename = _dl_malloc(len1 + len2 + 2);
787 _dl_strcpy (filename, dl_debug_output);
788 filename[len1] = '.';
789 _dl_strcpy (&filename[len1+1], tmp1);
791 _dl_debug_file = _dl_open(filename, O_WRONLY|O_CREAT, 0644);
792 if (_dl_debug_file < 0) {
794 _dl_dprintf(_dl_debug_file, "can't open file: '%s'\n",filename);
801 #ifdef __LDSO_PRELINK_SUPPORT__
803 char *ld_warn = _dl_getenv ("LD_WARN", envp);
805 if (ld_warn && *ld_warn == '\0')
808 _dl_trace_prelink = _dl_getenv("LD_TRACE_PRELINKING", envp);
811 if (_dl_getenv("LD_TRACE_LOADED_OBJECTS", envp) != NULL) {
812 trace_loaded_objects++;
815 #ifndef __LDSO_LDD_SUPPORT__
816 if (trace_loaded_objects) {
817 _dl_dprintf(_dl_debug_file, "Use the ldd provided by uClibc\n");
823 * OK, fix one more thing - set up debug_addr so it will point
824 * to our chain. Later we may need to fill in more fields, but this
825 * should be enough for now.
827 debug_addr->r_map = (struct link_map *) _dl_loaded_modules;
828 debug_addr->r_version = 1;
829 debug_addr->r_ldbase = (ElfW(Addr)) DL_LOADADDR_BASE(load_addr);
830 debug_addr->r_brk = (unsigned long) &_dl_debug_state;
831 _dl_debug_addr = debug_addr;
833 /* Do not notify the debugger until the interpreter is in the list */
835 /* OK, we now have the application in the list, and we have some
836 * basic stuff in place. Now search through the list for other shared
837 * libraries that should be loaded, and insert them on the list in the
843 #ifdef __LDSO_PRELOAD_ENV_SUPPORT__
848 while (*str == ':' || *str == ' ' || *str == '\t')
853 while (*str2 && *str2 != ':' && *str2 != ' ' && *str2 != '\t')
858 if (!_dl_secure || _dl_strchr(str, '/') == NULL) {
859 _dl_if_debug_dprint("\tfile='%s'; needed by '%s'\n", str, _dl_progname);
861 tpnt1 = _dl_load_shared_library(
862 _dl_secure ? DL_RESOLVE_SECURE : 0,
863 &rpnt, NULL, str, trace_loaded_objects);
865 #ifdef __LDSO_LDD_SUPPORT__
866 if (trace_loaded_objects || _dl_trace_prelink)
867 _dl_dprintf(1, "\t%s => not found\n", str);
871 _dl_dprintf(_dl_debug_file, "%s: can't load " "library '%s'\n", _dl_progname, str);
875 tpnt1->rtld_flags = unlazy | RTLD_GLOBAL;
877 _dl_debug_early("Loading: (%x) %s\n", DL_LOADADDR_BASE(tpnt1->loadaddr), tpnt1->libname);
879 #ifdef __LDSO_LDD_SUPPORT__
880 if (trace_loaded_objects && !_dl_trace_prelink &&
881 tpnt1->usage_count == 1) {
882 /* This is a real hack to make
883 * ldd not print the library
884 * itself when run on a
887 if (_dl_strcmp(_dl_progname, str) != 0)
888 _dl_dprintf(1, "\t%s => %s (%x)\n", str, tpnt1->libname,
889 DL_LOADADDR_BASE(tpnt1->loadaddr));
897 while (*str == ':' || *str == ' ' || *str == '\t')
901 #endif /* __LDSO_PRELOAD_ENV_SUPPORT__ */
903 #ifdef __LDSO_PRELOAD_FILE_SUPPORT__
910 if (_dl_stat(LDSO_PRELOAD, &st) || st.st_size == 0) {
914 if ((fd = _dl_open(LDSO_PRELOAD, O_RDONLY, 0)) < 0) {
915 _dl_dprintf(_dl_debug_file, "%s: can't open file '%s'\n",
916 _dl_progname, LDSO_PRELOAD);
920 preload = (caddr_t) _dl_mmap(0, st.st_size + 1,
921 PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
923 if (preload == (caddr_t) -1) {
924 _dl_dprintf(_dl_debug_file, "%s:%i: can't map '%s'\n",
925 _dl_progname, __LINE__, LDSO_PRELOAD);
929 /* convert all separators and comments to spaces */
930 for (cp = preload; *cp; /*nada */ ) {
931 if (*cp == ':' || *cp == '\t' || *cp == '\n') {
933 } else if (*cp == '#') {
936 } while (*cp != '\n' && *cp != '\0');
942 /* find start of first library */
943 for (cp = preload; *cp && *cp == ' '; cp++)
947 /* find end of library */
948 for (cp2 = cp; *cp && *cp != ' '; cp++)
953 _dl_if_debug_dprint("\tfile='%s'; needed by '%s'\n", cp2, _dl_progname);
955 tpnt1 = _dl_load_shared_library(0, &rpnt, NULL, cp2, trace_loaded_objects);
957 # ifdef __LDSO_LDD_SUPPORT__
958 if (trace_loaded_objects || _dl_trace_prelink)
959 _dl_dprintf(1, "\t%s => not found\n", cp2);
963 _dl_dprintf(_dl_debug_file, "%s: can't load library '%s'\n", _dl_progname, cp2);
967 tpnt1->rtld_flags = unlazy | RTLD_GLOBAL;
969 _dl_debug_early("Loading: (%x) %s\n", DL_LOADADDR_BASE(tpnt1->loadaddr), tpnt1->libname);
971 # ifdef __LDSO_LDD_SUPPORT__
972 if (trace_loaded_objects && !_dl_trace_prelink &&
973 tpnt1->usage_count == 1) {
974 _dl_dprintf(1, "\t%s => %s (%x)\n",
976 DL_LOADADDR_BASE(tpnt1->loadaddr));
981 /* find start of next library */
983 for ( /*nada */ ; *cp && *cp == ' '; cp++)
987 _dl_munmap(preload, st.st_size + 1);
989 #endif /* __LDSO_PRELOAD_FILE_SUPPORT__ */
992 for (tcurr = _dl_loaded_modules; tcurr; tcurr = tcurr->next) {
993 ElfW(Dyn) *this_dpnt;
996 for (this_dpnt = (ElfW(Dyn) *) tcurr->dynamic_addr; this_dpnt->d_tag; this_dpnt++) {
997 if (this_dpnt->d_tag == DT_NEEDED) {
999 struct init_fini_list *tmp;
1001 lpntstr = (char*) (tcurr->dynamic_info[DT_STRTAB] + this_dpnt->d_un.d_val);
1002 name = _dl_get_last_path_component(lpntstr);
1003 _dl_if_debug_dprint("\tfile='%s'; needed by '%s'\n", lpntstr, _dl_progname);
1005 if (_dl_strcmp(name, UCLIBC_LDSO) == 0) {
1007 /* Insert the ld.so only once */
1008 ldso_tpnt = add_ldso(tpnt, load_addr, auxvt, rpnt);
1010 ldso_tpnt->usage_count++;
1013 tpnt1 = _dl_load_shared_library(0, &rpnt, tcurr, lpntstr, trace_loaded_objects);
1016 #ifdef __LDSO_LDD_SUPPORT__
1017 if (trace_loaded_objects || _dl_trace_prelink) {
1018 _dl_dprintf(1, "\t%s => not found\n", lpntstr);
1023 _dl_dprintf(_dl_debug_file, "%s: can't load library '%s'\n", _dl_progname, lpntstr);
1028 tmp = alloca(sizeof(struct init_fini_list)); /* Allocates on stack, no need to free this memory */
1030 tmp->next = tcurr->init_fini;
1031 tcurr->init_fini = tmp;
1033 tpnt1->rtld_flags = unlazy | RTLD_GLOBAL;
1035 _dl_debug_early("Loading: (%x) %s\n", DL_LOADADDR_BASE(tpnt1->loadaddr), tpnt1->libname);
1037 #ifdef __LDSO_LDD_SUPPORT__
1038 if (trace_loaded_objects && !_dl_trace_prelink &&
1039 tpnt1->usage_count == 1) {
1040 _dl_dprintf(1, "\t%s => %s (%x)\n",
1041 lpntstr, tpnt1->libname,
1042 DL_LOADADDR_BASE(tpnt1->loadaddr));
1050 /* Keep track of the number of elements in the global scope */
1051 nscope_elem = nlist;
1053 if (_dl_loaded_modules->libtype == elf_executable) {
1054 --nlist; /* Exclude the application. */
1055 tcurr = _dl_loaded_modules->next;
1057 tcurr = _dl_loaded_modules;
1058 init_fini_list = _dl_malloc(nlist * sizeof(struct elf_resolve *));
1060 for (; tcurr; tcurr = tcurr->next)
1061 init_fini_list[i++] = tcurr;
1063 /* Sort the INIT/FINI list in dependency order. */
1064 for (tcurr = _dl_loaded_modules->next; tcurr; tcurr = tcurr->next) {
1067 for (j = 0; init_fini_list[j] != tcurr; ++j)
1069 for (k = j + 1; k < nlist; ++k) {
1070 struct init_fini_list *runp = init_fini_list[k]->init_fini;
1072 for (; runp; runp = runp->next) {
1073 if (runp->tpnt == tcurr) {
1074 struct elf_resolve *here = init_fini_list[k];
1075 _dl_if_debug_dprint("Move %s from pos %d to %d in INIT/FINI list\n", here->libname, k, j);
1076 for (i = (k - j); i; --i)
1077 init_fini_list[i+j] = init_fini_list[i+j-1];
1078 init_fini_list[j] = here;
1085 #ifdef __SUPPORT_LD_DEBUG__
1087 _dl_dprintf(_dl_debug_file, "\nINIT/FINI order and dependencies:\n");
1088 for (i = 0; i < nlist; i++) {
1089 struct init_fini_list *tmp;
1091 _dl_dprintf(_dl_debug_file, "lib: %s has deps:\n",
1092 init_fini_list[i]->libname);
1093 tmp = init_fini_list[i]->init_fini;
1094 for (; tmp; tmp = tmp->next)
1095 _dl_dprintf(_dl_debug_file, " %s ", tmp->tpnt->libname);
1096 _dl_dprintf(_dl_debug_file, "\n");
1102 * If the program interpreter is not in the module chain, add it.
1103 * This will be required for dlopen to be able to access the internal
1104 * functions in the dynamic linker and to relocate the interpreter
1105 * again once all libs are loaded.
1108 tpnt = add_ldso(tpnt, load_addr, auxvt, rpnt);
1109 tpnt->usage_count++;
1114 #ifdef RERELOCATE_LDSO
1115 /* Only rerelocate functions for now. */
1116 tpnt->init_flag = RELOCS_DONE;
1117 lpnt = (unsigned long *) (tpnt->dynamic_info[DT_PLTGOT]);
1118 # ifdef ALLOW_ZERO_PLTGOT
1119 if (tpnt->dynamic_info[DT_PLTGOT])
1121 INIT_GOT(lpnt, tpnt);
1123 tpnt->init_flag = RELOCS_DONE | JMP_RELOCS_DONE;
1128 * Allocate the global scope array.
1130 scope_elem_list = (struct elf_resolve **) _dl_malloc(nscope_elem * sizeof(struct elf_resolve *));
1132 for (i = 0, tcurr = _dl_loaded_modules; tcurr; tcurr = tcurr->next)
1133 scope_elem_list[i++] = tcurr;
1135 _dl_loaded_modules->symbol_scope.r_list = scope_elem_list;
1136 _dl_loaded_modules->symbol_scope.r_nlist = nscope_elem;
1138 * The symbol scope of the application, that is the first entry of the
1139 * _dl_loaded_modules list, is just the global scope to be used for the
1142 global_scope = &_dl_loaded_modules->symbol_scope;
1144 /* Build the local scope for each loaded modules. */
1145 local_scope = _dl_malloc(nscope_elem * sizeof(struct elf_resolve *));
1147 for (tcurr = _dl_loaded_modules->next; tcurr; tcurr = tcurr->next) {
1149 cnt = _dl_build_local_scope(local_scope, scope_elem_list[i++]);
1150 tcurr->symbol_scope.r_list = _dl_malloc(cnt * sizeof(struct elf_resolve *));
1151 tcurr->symbol_scope.r_nlist = cnt;
1152 _dl_memcpy (tcurr->symbol_scope.r_list, local_scope, cnt * sizeof (struct elf_resolve *));
1153 /* Restoring the init_flag.*/
1154 for (k = 1; k < nscope_elem; k++)
1155 scope_elem_list[k]->init_flag &= ~DL_RESERVED;
1158 _dl_free(local_scope);
1160 #ifdef __LDSO_LDD_SUPPORT__
1161 /* Exit if LD_TRACE_LOADED_OBJECTS is on. */
1162 if (trace_loaded_objects && !_dl_trace_prelink)
1166 #if defined(USE_TLS) && USE_TLS
1167 /* We do not initialize any of the TLS functionality unless any of the
1168 * initial modules uses TLS. This makes dynamic loading of modules with
1169 * TLS impossible, but to support it requires either eagerly doing setup
1170 * now or lazily doing it later. Doing it now makes us incompatible with
1171 * an old kernel that can't perform TLS_INIT_TP, even if no TLS is ever
1172 * used. Trying to do it lazily is too hairy to try when there could be
1173 * multiple threads (from a non-TLS-using libpthread). */
1174 bool was_tls_init_tp_called = tls_init_tp_called;
1176 _dl_debug_early("Calling init_tls()!\n");
1180 #ifdef __UCLIBC_HAS_SSP__
1181 /* Set up the stack checker's canary. */
1182 stack_chk_guard = _dl_setup_stack_chk_guard ();
1183 # ifdef THREAD_SET_STACK_GUARD
1184 THREAD_SET_STACK_GUARD (stack_chk_guard);
1186 __stack_chk_guard = stack_chk_guard;
1188 # ifdef __UCLIBC_HAS_SSP_COMPAT__
1189 __guard = stack_chk_guard;
1193 #ifdef __LDSO_PRELINK_SUPPORT__
1194 if (_dl_trace_prelink) {
1196 unsigned int nscope_trace = ldso_tpnt ? nscope_elem : (nscope_elem - 1);
1198 for (i = 0; i < nscope_trace; i++)
1199 trace_objects(scope_elem_list[i],
1200 _dl_get_last_path_component(scope_elem_list[i]->libname));
1203 /* Warn about undefined symbols. */
1204 if (_dl_symbol_tables)
1205 if (_dl_fixup(_dl_symbol_tables, global_scope, unlazy))
1210 if (_dl_loaded_modules->dynamic_info[DT_GNU_LIBLIST_IDX]) {
1211 ElfW(Lib) *liblist, *liblistend;
1212 struct elf_resolve **r_list, **r_listend, *l;
1213 const char *strtab = (const char *)_dl_loaded_modules->dynamic_info[DT_STRTAB];
1215 _dl_assert (_dl_loaded_modules->dynamic_info[DT_GNU_LIBLISTSZ_IDX] != 0);
1216 liblist = (ElfW(Lib) *) _dl_loaded_modules->dynamic_info[DT_GNU_LIBLIST_IDX];
1217 liblistend = (ElfW(Lib) *)
1218 ((char *) liblist + _dl_loaded_modules->dynamic_info[DT_GNU_LIBLISTSZ_IDX]);
1219 r_list = _dl_loaded_modules->symbol_scope.r_list;
1220 r_listend = r_list + nscope_elem;
1222 for (; r_list < r_listend && liblist < liblistend; r_list++) {
1225 if (l == _dl_loaded_modules)
1228 /* If the library is not mapped where it should, fail. */
1232 /* Next, check if checksum matches. */
1233 if (l->dynamic_info[DT_CHECKSUM_IDX] == 0 ||
1234 l->dynamic_info[DT_CHECKSUM_IDX] != liblist->l_checksum)
1237 if (l->dynamic_info[DT_GNU_PRELINKED_IDX] == 0 ||
1238 (l->dynamic_info[DT_GNU_PRELINKED_IDX] != liblist->l_time_stamp))
1241 if (_dl_strcmp(strtab + liblist->l_name, _dl_get_last_path_component(l->libname)) != 0)
1248 if (r_list == r_listend && liblist == liblistend)
1253 _dl_debug_early ("\nprelink checking: %s\n", prelinked ? "ok" : "failed");
1256 if (_dl_loaded_modules->dynamic_info[DT_GNU_CONFLICT_IDX]) {
1257 ELF_RELOC *conflict;
1258 unsigned long conflict_size;
1260 _dl_assert (_dl_loaded_modules->dynamic_info[DT_GNU_CONFLICTSZ_IDX] != 0);
1261 conflict = (ELF_RELOC *) _dl_loaded_modules->dynamic_info[DT_GNU_CONFLICT_IDX];
1262 conflict_size = _dl_loaded_modules->dynamic_info[DT_GNU_CONFLICTSZ_IDX];
1263 _dl_parse_relocation_information(_dl_symbol_tables, global_scope,
1264 (unsigned long) conflict, conflict_size);
1267 /* Mark all the objects so we know they have been already relocated. */
1268 for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) {
1269 tpnt->init_flag |= RELOCS_DONE;
1270 if (tpnt->relro_size)
1271 _dl_protect_relro (tpnt);
1278 _dl_debug_early("Beginning relocation fixups\n");
1282 * Relocation of the GOT entries for MIPS have to be done
1283 * after all the libraries have been loaded.
1285 _dl_perform_mips_global_got_relocations(_dl_loaded_modules, !unlazy);
1289 * OK, now all of the kids are tucked into bed in their proper
1290 * addresses. Now we go through and look for REL and RELA records that
1291 * indicate fixups to the GOT tables. We need to do this in reverse
1292 * order so that COPY directives work correctly.
1294 if (_dl_symbol_tables)
1295 if (_dl_fixup(_dl_symbol_tables, global_scope, unlazy))
1298 for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) {
1299 if (tpnt->relro_size)
1300 _dl_protect_relro (tpnt);
1302 } /* not prelinked */
1304 #if defined(USE_TLS) && USE_TLS
1305 if (!was_tls_init_tp_called && _dl_tls_max_dtv_idx > 0)
1306 ++_dl_tls_generation;
1308 _dl_debug_early("Calling _dl_allocate_tls_init()!\n");
1310 /* Now that we have completed relocation, the initializer data
1311 for the TLS blocks has its final values and we can copy them
1312 into the main thread's TLS area, which we allocated above. */
1313 _dl_allocate_tls_init (tcbp);
1315 /* And finally install it for the main thread. If ld.so itself uses
1316 TLS we know the thread pointer was initialized earlier. */
1317 if (! tls_init_tp_called) {
1318 const char *lossage = (char *) TLS_INIT_TP (tcbp, USE___THREAD);
1319 if (__builtin_expect (lossage != NULL, 0)) {
1320 _dl_debug_early("cannot set up thread-local storage: %s\n", lossage);
1324 #endif /* USE_TLS */
1326 /* OK, at this point things are pretty much ready to run. Now we need
1327 * to touch up a few items that are required, and then we can let the
1328 * user application have at it. Note that the dynamic linker itself
1329 * is not guaranteed to be fully dynamicly linked if we are using
1330 * ld.so.1, so we have to look up each symbol individually.
1333 _dl_envp = (unsigned long *) (intptr_t) _dl_find_hash(__C_SYMBOL_PREFIX__ "__environ", global_scope, NULL, 0, NULL);
1335 *_dl_envp = (unsigned long) envp;
1337 #ifndef __FORCE_SHAREABLE_TEXT_SEGMENTS__
1342 /* We had to set the protections of all pages to R/W for
1343 * dynamic linking. Set text pages back to R/O.
1345 for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) {
1346 for (myppnt = tpnt->ppnt, j = 0; j < tpnt->n_phent; j++, myppnt++) {
1347 if (myppnt->p_type == PT_LOAD && !(myppnt->p_flags & PF_W) && tpnt->dynamic_info[DT_TEXTREL]) {
1348 _dl_mprotect((void *) (DL_RELOC_ADDR(tpnt->loadaddr, myppnt->p_vaddr) & PAGE_ALIGN),
1349 (myppnt->p_vaddr & ADDR_ALIGN) + (unsigned long) myppnt->p_filesz, LXFLAGS(myppnt->p_flags));
1356 /* Notify the debugger we have added some objects. */
1357 _dl_debug_addr->r_state = RT_ADD;
1360 /* Run pre-initialization functions for the executable. */
1361 _dl_run_array_forward(_dl_loaded_modules->dynamic_info[DT_PREINIT_ARRAY],
1362 _dl_loaded_modules->dynamic_info[DT_PREINIT_ARRAYSZ],
1363 _dl_loaded_modules->loadaddr);
1365 /* Run initialization functions for loaded objects. For the
1366 main executable, they will be run from __uClibc_main. */
1367 for (i = nlist; i; --i) {
1368 tpnt = init_fini_list[i-1];
1369 tpnt->init_fini = NULL; /* Clear, since alloca was used */
1370 if (tpnt->init_flag & INIT_FUNCS_CALLED)
1372 tpnt->init_flag |= INIT_FUNCS_CALLED;
1374 if (tpnt->dynamic_info[DT_INIT]) {
1375 void (*dl_elf_func) (void);
1377 dl_elf_func = (void (*)(void)) DL_RELOC_ADDR(tpnt->loadaddr, tpnt->dynamic_info[DT_INIT]);
1379 _dl_if_debug_dprint("calling INIT: %s\n\n", tpnt->libname);
1381 DL_CALL_FUNC_AT_ADDR (dl_elf_func, tpnt->loadaddr, (void(*)(void)));
1384 _dl_run_init_array(tpnt);
1387 /* Find the real malloc function and make ldso functions use that from now on */
1388 _dl_malloc_function = (void* (*)(size_t)) (intptr_t) _dl_find_hash(__C_SYMBOL_PREFIX__ "malloc",
1389 global_scope, NULL, ELF_RTYPE_CLASS_PLT, NULL);
1391 #if defined(USE_TLS) && USE_TLS
1392 /* Find the real functions and make ldso functions use them from now on */
1393 _dl_calloc_function = (void* (*)(size_t, size_t)) (intptr_t)
1394 _dl_find_hash(__C_SYMBOL_PREFIX__ "calloc", global_scope, NULL, ELF_RTYPE_CLASS_PLT, NULL);
1396 _dl_realloc_function = (void* (*)(void *, size_t)) (intptr_t)
1397 _dl_find_hash(__C_SYMBOL_PREFIX__ "realloc", global_scope, NULL, ELF_RTYPE_CLASS_PLT, NULL);
1399 _dl_free_function = (void (*)(void *)) (intptr_t)
1400 _dl_find_hash(__C_SYMBOL_PREFIX__ "free", global_scope, NULL, ELF_RTYPE_CLASS_PLT, NULL);
1402 _dl_memalign_function = (void* (*)(size_t, size_t)) (intptr_t)
1403 _dl_find_hash(__C_SYMBOL_PREFIX__ "memalign", global_scope, NULL, ELF_RTYPE_CLASS_PLT, NULL);
1407 /* Notify the debugger that all objects are now mapped in. */
1408 _dl_debug_addr->r_state = RT_CONSISTENT;
1411 #ifdef __LDSO_STANDALONE_SUPPORT__
1412 if (_start == (void *) auxvt[AT_ENTRY].a_un.a_val)
1413 return (void *) app_tpnt->l_entry;
1416 return (void *) auxvt[AT_ENTRY].a_un.a_val;
1419 #include "dl-hash.c"