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 */
65 static int _dl_secure = 1; /* Are we dealing with setuid stuff? */
67 #ifdef __SUPPORT_LD_DEBUG__
68 char *_dl_debug = NULL;
69 char *_dl_debug_symbols = NULL;
70 char *_dl_debug_move = NULL;
71 char *_dl_debug_reloc = NULL;
72 char *_dl_debug_detail = NULL;
73 char *_dl_debug_nofixups = NULL;
74 char *_dl_debug_bindings = NULL;
75 int _dl_debug_file = 2;
78 #if defined (__LDSO_STANDALONE_SUPPORT__) && defined (__sh__)
79 /* Not hidden, needed for standalone execution. */
81 * FIXME: align dl_start for SH to other archs so that we can keep this symbol
82 * hidden and we don't need to handle in __uClibc_main
85 unsigned long _dl_skip_args = 0;
87 unsigned long attribute_hidden _dl_skip_args = 0;
90 const char *_dl_progname = UCLIBC_LDSO; /* The name of the executable being run */
91 #include "dl-startup.c"
92 #include "dl-symbols.c"
96 * This stub function is used by some debuggers. The idea is that they
97 * can set an internal breakpoint on it, so that we are notified when the
98 * address mapping is changed in some way.
100 void _dl_debug_state(void);
101 rtld_hidden_proto(_dl_debug_state, noinline);
102 void _dl_debug_state(void)
104 /* Make sure GCC doesn't recognize this function as pure, to avoid
105 * having the calls optimized away.
109 rtld_hidden_def(_dl_debug_state);
111 static unsigned char *_dl_malloc_addr = NULL; /* Lets _dl_malloc use the already allocated memory page */
112 static unsigned char *_dl_mmap_zero = NULL; /* Also used by _dl_malloc */
114 static struct elf_resolve **init_fini_list;
115 static struct elf_resolve **scope_elem_list;
116 static unsigned int nlist; /* # items in init_fini_list */
117 extern void _start(void);
119 #ifdef __UCLIBC_HAS_SSP__
120 # include <dl-osinfo.h>
121 uintptr_t stack_chk_guard;
122 # ifndef THREAD_SET_STACK_GUARD
123 /* Only exported for architectures that don't store the stack guard canary
124 * in local thread area. */
125 uintptr_t __stack_chk_guard attribute_relro;
126 # ifdef __UCLIBC_HAS_SSP_COMPAT__
127 strong_alias(__stack_chk_guard,__guard)
129 # elif __UCLIBC_HAS_SSP_COMPAT__
130 uintptr_t __guard attribute_relro;
134 char *_dl_getenv(const char *symbol, char **envp)
139 while ((pnt = *envp++)) {
141 while (*pnt && *pnt == *pnt1)
143 if (!*pnt || *pnt != '=' || *pnt1)
150 void _dl_unsetenv(const char *symbol, char **envp)
154 char **newenvp = envp;
156 for (pnt = *envp; pnt; pnt = *++envp) {
158 while (*pnt && *pnt == *pnt1)
160 if (!*pnt || *pnt != '=' || *pnt1)
167 static int _dl_suid_ok(void)
169 __kernel_uid_t uid, euid;
170 __kernel_gid_t gid, egid;
173 euid = _dl_geteuid();
175 egid = _dl_getegid();
177 if (uid == euid && gid == egid) {
183 void *_dl_malloc(size_t size)
188 _dl_debug_early("request for %d bytes\n", size);
191 if (_dl_malloc_function)
192 return (*_dl_malloc_function) (size);
194 if (_dl_malloc_addr - _dl_mmap_zero + size > _dl_pagesize) {
197 /* Since the above assumes we get a full page even if
198 we request less than that, make sure we request a
199 full page, since uClinux may give us less than than
200 a full page. We might round even
201 larger-than-a-page sizes, but we end up never
202 reusing _dl_mmap_zero/_dl_malloc_addr in that case,
205 The actual page size doesn't really matter; as long
206 as we're self-consistent here, we're safe. */
207 if (size < _dl_pagesize)
208 rounded_size = (size + ADDR_ALIGN) & _dl_pagesize;
212 _dl_debug_early("mmapping more memory\n");
213 _dl_mmap_zero = _dl_malloc_addr = _dl_mmap((void *) 0, rounded_size,
214 PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_UNINITIALIZE, -1, 0);
215 if (_dl_mmap_check_error(_dl_mmap_zero)) {
216 _dl_dprintf(_dl_debug_file, "%s: mmap of a spare page failed!\n", _dl_progname);
220 retval = _dl_malloc_addr;
221 _dl_malloc_addr += size;
224 * Align memory to DL_MALLOC_ALIGN byte boundary. Some
225 * platforms require this, others simply get better
228 _dl_malloc_addr = (unsigned char *) (((unsigned long) _dl_malloc_addr + DL_MALLOC_ALIGN - 1) & ~(DL_MALLOC_ALIGN - 1));
232 static void *_dl_zalloc(size_t size)
234 void *p = _dl_malloc(size);
236 _dl_memset(p, 0, size);
240 void _dl_free(void *p)
242 if (_dl_free_function)
243 (*_dl_free_function) (p);
246 #if defined(USE_TLS) && USE_TLS
247 void *_dl_memalign(size_t __boundary, size_t __size)
254 if (_dl_memalign_function)
255 return (*_dl_memalign_function) (__boundary, __size);
257 while (rounded < __boundary) {
258 rounded = (1 << i++);
261 delta = (((size_t) _dl_malloc_addr + __size) & (rounded - 1));
263 if ((result = _dl_malloc(rounded - delta)) == NULL)
266 result = _dl_malloc(__size);
272 static void __attribute__ ((destructor)) __attribute_used__ _dl_fini(void)
275 struct elf_resolve * tpnt;
277 for (i = 0; i < nlist; ++i) {
278 tpnt = init_fini_list[i];
279 if (tpnt->init_flag & FINI_FUNCS_CALLED)
281 tpnt->init_flag |= FINI_FUNCS_CALLED;
282 _dl_run_fini_array(tpnt);
283 if (tpnt->dynamic_info[DT_FINI]) {
284 void (*dl_elf_func) (void);
286 dl_elf_func = (void (*)(void)) (intptr_t) DL_RELOC_ADDR(tpnt->loadaddr, tpnt->dynamic_info[DT_FINI]);
287 _dl_if_debug_dprint("\ncalling FINI: %s\n\n", tpnt->libname);
288 DL_CALL_FUNC_AT_ADDR (dl_elf_func, tpnt->loadaddr, (void(*)(void)));
293 #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");
318 static ptrdiff_t _dl_build_local_scope (struct elf_resolve **list,
319 struct elf_resolve *map)
321 struct elf_resolve **p = list;
322 struct init_fini_list *q;
325 map->init_flag |= DL_RESERVED;
327 for (q = map->init_fini; q; q = q->next)
328 if (! (q->tpnt->init_flag & DL_RESERVED))
329 p += _dl_build_local_scope (p, q->tpnt);
333 void *_dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr,
334 ElfW(auxv_t) auxvt[AT_EGID + 1], char **envp, char **argv
335 DL_GET_READY_TO_RUN_EXTRA_PARMS)
337 ElfW(Addr) app_mapaddr = 0;
341 unsigned int i, cnt, k, nscope_elem;
342 int unlazy = 0, trace_loaded_objects = 0;
343 struct dyn_elf *rpnt;
344 struct elf_resolve *tcurr;
345 struct elf_resolve *tpnt1;
346 struct elf_resolve app_tpnt_tmp;
347 struct elf_resolve *app_tpnt = &app_tpnt_tmp;
348 struct r_debug *debug_addr;
350 unsigned long *_dl_envp; /* The environment address */
351 ElfW(Addr) relro_addr = 0;
352 size_t relro_size = 0;
353 struct r_scope_elem *global_scope;
354 struct elf_resolve **local_scope;
357 #if defined(USE_TLS) && USE_TLS
361 /* Wahoo!!! We managed to make a function call! Get malloc
362 * setup so we can use _dl_dprintf() to print debug noise
363 * instead of the SEND_STDERR macros used in dl-startup.c */
365 _dl_memset(app_tpnt, 0, sizeof(*app_tpnt));
367 /* Store the page size for later use */
368 _dl_pagesize = (auxvt[AT_PAGESZ].a_un.a_val) ? (size_t) auxvt[AT_PAGESZ].a_un.a_val : PAGE_SIZE;
369 /* Make it so _dl_malloc can use the page of memory we have already
370 * allocated. We shouldn't need to grab any more memory. This must
371 * be first since things like _dl_dprintf() use _dl_malloc()...
373 _dl_malloc_addr = (unsigned char *)_dl_pagesize;
377 _dl_debug_early("Cool, ldso survived making function calls\n");
379 /* Now we have done the mandatory linking of some things. We are now
380 * free to start using global variables, since these things have all
381 * been fixed up by now. Still no function calls outside of this
382 * library, since the dynamic resolver is not yet ready.
385 _dl_progname = argv[0];
388 #ifndef __LDSO_STANDALONE_SUPPORT__
389 if (_start == (void *) auxvt[AT_ENTRY].a_un.a_val) {
390 _dl_dprintf(_dl_debug_file, "Standalone execution is not enabled\n");
395 /* Start to build the tables of the modules that are required for
396 * this beast to run. We start with the basic executable, and then
397 * go from there. Eventually we will run across ourself, and we
398 * will need to properly deal with that as well.
401 if (_dl_getenv("LD_BIND_NOW", envp))
404 /* Now we need to figure out what kind of options are selected.
405 * Note that for SUID programs we ignore the settings in
408 if ((auxvt[AT_UID].a_un.a_val == (size_t)-1 && _dl_suid_ok()) ||
409 (auxvt[AT_UID].a_un.a_val != (size_t)-1 &&
410 auxvt[AT_UID].a_un.a_val == auxvt[AT_EUID].a_un.a_val &&
411 auxvt[AT_GID].a_un.a_val == auxvt[AT_EGID].a_un.a_val)) {
413 #ifdef __LDSO_PRELOAD_ENV_SUPPORT__
414 _dl_preload = _dl_getenv("LD_PRELOAD", envp);
416 _dl_library_path = _dl_getenv("LD_LIBRARY_PATH", envp);
418 static const char unsecure_envvars[] =
419 #ifdef EXTRA_UNSECURE_ENVVARS
420 EXTRA_UNSECURE_ENVVARS
426 nextp = unsecure_envvars;
428 _dl_unsetenv (nextp, envp);
429 /* We could use rawmemchr but this need not be fast. */
430 nextp = _dl_strchr(nextp, '\0') + 1;
431 } while (*nextp != '\0');
432 #ifdef __LDSO_PRELOAD_ENV_SUPPORT__
435 _dl_library_path = NULL;
436 /* SUID binaries can be exploited if they do LAZY relocation. */
440 #if defined(USE_TLS) && USE_TLS
441 _dl_error_catch_tsd = &_dl_initial_error_catch_tsd;
442 _dl_init_static_tls = &_dl_nothread_init_static_tls;
445 #ifdef __LDSO_STANDALONE_SUPPORT__
446 if (_start == (void *) auxvt[AT_ENTRY].a_un.a_val) {
448 unsigned int *aux_dat = (unsigned int *) argv;
449 int argc = aux_dat[-1];
451 tpnt->libname = argv[0];
453 if (! _dl_strcmp (argv[1], "--library-path") && argc > 2) {
454 _dl_library_path = argv[2];
462 * If we have no further argument the program was called incorrectly.
463 * Grant the user some education.
468 Usage: ld.so [OPTION]... EXECUTABLE-FILE [ARGS-FOR-PROGRAM...]\n\
469 You have invoked `ld.so', the helper program for shared library executables.\n\
470 This program usually lives in the file `/lib/ld.so', and special directives\n\
471 in executable files using ELF shared libraries tell the system's program\n\
472 loader to load the helper program from this file. This helper program loads\n\
473 the shared libraries needed by the program executable, prepares the program\n\
474 to run, and runs it. You may invoke this helper program directly from the\n\
475 command line to load and run an ELF executable file; this is like executing\n\
476 that file itself, but always uses this helper program from the file you\n\
477 specified, instead of the helper program file specified in the executable\n\
478 file you run. This is mostly of use for maintainers to test new versions\n\
479 of this helper program; chances are you did not intend to run this program.\n\
481 --library-path PATH use given PATH instead of content of the environment\n\
482 variable LD_LIBRARY_PATH\n");
488 _dl_progname = argv[0];
490 _dl_symbol_tables = rpnt = _dl_zalloc(sizeof(struct dyn_elf));
492 * It needs to load the _dl_progname and to map it
493 * Usually it is the main application launched by means of the ld.so
494 * but it could be also a shared object (when ld.so used for tracing)
495 * We keep the misleading app_tpnt name to avoid variable pollution
497 app_tpnt = _dl_load_elf_shared_library(_dl_secure, &rpnt, _dl_progname);
499 _dl_dprintf(_dl_debug_file, "can't load '%s'\n", _dl_progname);
503 * FIXME: it needs to properly handle a PIE executable
504 * Usually for a main application, loadaddr is computed as difference
505 * between auxvt entry points and phdr, so if it is not 0, that it is a
506 * PIE executable. In this case instead we need to set the loadaddr to 0
507 * because we are actually mapping the ELF for the main application by
508 * ourselves. So the PIE case must be checked.
511 app_tpnt->rtld_flags = unlazy | RTLD_GLOBAL;
513 if (app_tpnt->libtype == elf_executable)
514 app_tpnt->loadaddr = 0;
517 * This is used by gdb to locate the chain of shared libraries that are
520 debug_addr = _dl_zalloc(sizeof(struct r_debug));
521 ppnt = (ElfW(Phdr) *)app_tpnt->ppnt;
522 for (i = 0; i < app_tpnt->n_phent; i++, ppnt++) {
523 if (ppnt->p_type == PT_DYNAMIC) {
524 dpnt = (ElfW(Dyn) *) DL_RELOC_ADDR(app_tpnt->loadaddr, ppnt->p_vaddr);
525 _dl_parse_dynamic_info(dpnt, app_tpnt->dynamic_info, debug_addr, app_tpnt->loadaddr);
529 /* Store the path where the shared lib loader was found
532 _dl_ldsopath = _dl_strdup(tpnt->libname);
533 ptmp = _dl_strrchr(_dl_ldsopath, '/');
534 if (ptmp != _dl_ldsopath)
537 _dl_debug_early("Lib Loader: (%x) %s\n", (unsigned) DL_LOADADDR_BASE(tpnt->loadaddr), tpnt->libname);
541 /* At this point we are now free to examine the user application,
542 * and figure out which libraries are supposed to be called. Until
543 * we have this list, we will not be completely ready for dynamic
547 /* Find the runtime load address of the main executable. This may be
548 * different from what the ELF header says for ET_DYN/PIE executables.
552 ElfW(Phdr) *phdr = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_val;
554 for (idx = 0; idx < auxvt[AT_PHNUM].a_un.a_val; idx++, phdr++)
555 if (phdr->p_type == PT_PHDR) {
556 DL_INIT_LOADADDR_PROG(app_tpnt->loadaddr, auxvt[AT_PHDR].a_un.a_val - phdr->p_vaddr);
560 if (DL_LOADADDR_BASE(app_tpnt->loadaddr))
561 _dl_debug_early("Position Independent Executable: "
562 "app_tpnt->loadaddr=%x\n", DL_LOADADDR_BASE(app_tpnt->loadaddr));
566 * This is used by gdb to locate the chain of shared libraries that are
569 debug_addr = _dl_zalloc(sizeof(struct r_debug));
571 ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_val;
572 for (i = 0; i < auxvt[AT_PHNUM].a_un.a_val; i++, ppnt++) {
573 if (ppnt->p_type == PT_GNU_RELRO) {
574 relro_addr = ppnt->p_vaddr;
575 relro_size = ppnt->p_memsz;
577 if (!app_mapaddr && (ppnt->p_type == PT_LOAD)) {
578 app_mapaddr = DL_RELOC_ADDR (app_tpnt->loadaddr, ppnt->p_vaddr);
580 if (ppnt->p_type == PT_DYNAMIC) {
581 dpnt = (ElfW(Dyn) *) DL_RELOC_ADDR(app_tpnt->loadaddr, ppnt->p_vaddr);
582 _dl_parse_dynamic_info(dpnt, app_tpnt->dynamic_info, debug_addr, app_tpnt->loadaddr);
583 #ifndef __FORCE_SHAREABLE_TEXT_SEGMENTS__
584 /* Ugly, ugly. We need to call mprotect to change the
585 * protection of the text pages so that we can do the
586 * dynamic linking. We can set the protection back
587 * again once we are done.
589 _dl_debug_early("calling mprotect on the application program\n");
590 /* Now cover the application program. */
591 if (app_tpnt->dynamic_info[DT_TEXTREL]) {
592 ElfW(Phdr) *ppnt_outer = ppnt;
593 ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_val;
594 for (i = 0; i < auxvt[AT_PHNUM].a_un.a_val; i++, ppnt++) {
595 if (ppnt->p_type == PT_LOAD && !(ppnt->p_flags & PF_W))
596 _dl_mprotect((void *) (DL_RELOC_ADDR(app_tpnt->loadaddr, ppnt->p_vaddr) & PAGE_ALIGN),
597 (DL_RELOC_ADDR(app_tpnt->loadaddr, ppnt->p_vaddr) & ADDR_ALIGN) +
598 (unsigned long) ppnt->p_filesz,
599 PROT_READ | PROT_WRITE | PROT_EXEC);
604 if (app_tpnt->dynamic_info[DT_TEXTREL]) {
605 _dl_dprintf(_dl_debug_file, "Can't modify application's text section; use the GCC option -fPIE for position-independent executables.\n");
610 #ifndef ALLOW_ZERO_PLTGOT
611 /* make sure it's really there. */
612 if (app_tpnt->dynamic_info[DT_PLTGOT] == 0)
615 /* OK, we have what we need - slip this one into the list. */
616 app_tpnt = _dl_add_elf_hash_table(_dl_progname, app_tpnt->loadaddr,
617 app_tpnt->dynamic_info,
618 (unsigned long) DL_RELOC_ADDR(app_tpnt->loadaddr, ppnt->p_vaddr),
620 _dl_loaded_modules->libtype = elf_executable;
621 _dl_loaded_modules->ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_val;
622 _dl_loaded_modules->n_phent = auxvt[AT_PHNUM].a_un.a_val;
623 _dl_symbol_tables = rpnt = _dl_zalloc(sizeof(struct dyn_elf));
624 rpnt->dyn = _dl_loaded_modules;
625 app_tpnt->mapaddr = app_mapaddr;
626 app_tpnt->rtld_flags = unlazy | RTLD_GLOBAL;
627 app_tpnt->usage_count++;
628 lpnt = (unsigned long *) (app_tpnt->dynamic_info[DT_PLTGOT]);
629 #ifdef ALLOW_ZERO_PLTGOT
632 INIT_GOT(lpnt, _dl_loaded_modules);
635 /* OK, fill this in - we did not have this before */
636 if (ppnt->p_type == PT_INTERP) {
637 tpnt->libname = (char *) DL_RELOC_ADDR(app_tpnt->loadaddr, ppnt->p_vaddr);
638 #ifdef __LDSO_SEARCH_INTERP_PATH__
641 /* Store the path where the shared lib loader was found
644 _dl_ldsopath = _dl_strdup(tpnt->libname);
645 ptmp = _dl_strrchr(_dl_ldsopath, '/');
646 if (ptmp != _dl_ldsopath)
649 _dl_debug_early("Lib Loader: (%x) %s\n", (unsigned) DL_LOADADDR_BASE(tpnt->loadaddr), tpnt->libname);
653 /* Discover any TLS sections if the target supports them. */
654 if (ppnt->p_type == PT_TLS) {
655 #if defined(USE_TLS) && USE_TLS
656 if (ppnt->p_memsz > 0) {
657 app_tpnt->l_tls_blocksize = ppnt->p_memsz;
658 app_tpnt->l_tls_align = ppnt->p_align;
659 if (ppnt->p_align == 0)
660 app_tpnt->l_tls_firstbyte_offset = 0;
662 app_tpnt->l_tls_firstbyte_offset =
663 (ppnt->p_vaddr & (ppnt->p_align - 1));
664 app_tpnt->l_tls_initimage_size = ppnt->p_filesz;
665 app_tpnt->l_tls_initimage = (void *) ppnt->p_vaddr;
667 /* This image gets the ID one. */
668 _dl_tls_max_dtv_idx = app_tpnt->l_tls_modid = 1;
671 _dl_debug_early("Found TLS header for appplication program\n");
674 _dl_dprintf(_dl_debug_file, "Program uses unsupported TLS data!\n");
679 app_tpnt->relro_addr = relro_addr;
680 app_tpnt->relro_size = relro_size;
682 #if defined(USE_TLS) && USE_TLS
684 * Adjust the address of the TLS initialization image in
685 * case the executable is actually an ET_DYN object.
687 if (app_tpnt->l_tls_initimage != NULL) {
688 unsigned int tmp = (unsigned int) app_tpnt->l_tls_initimage;
689 app_tpnt->l_tls_initimage =
690 (char *) app_tpnt->l_tls_initimage + app_tpnt->loadaddr;
691 _dl_debug_early("Relocated TLS initial image from %x to %x (size = %x)\n",
692 tmp, app_tpnt->l_tls_initimage, app_tpnt->l_tls_initimage_size);
696 #ifdef __LDSO_STANDALONE_SUPPORT__
697 } /* ! ldso standalone mode */
700 #ifdef __SUPPORT_LD_DEBUG__
701 _dl_debug = _dl_getenv("LD_DEBUG", envp);
703 if (_dl_strstr(_dl_debug, "all")) {
704 _dl_debug_detail = _dl_debug_move = _dl_debug_symbols
705 = _dl_debug_reloc = _dl_debug_bindings = _dl_debug_nofixups = (void*)1;
707 _dl_debug_detail = _dl_strstr(_dl_debug, "detail");
708 _dl_debug_move = _dl_strstr(_dl_debug, "move");
709 _dl_debug_symbols = _dl_strstr(_dl_debug, "sym");
710 _dl_debug_reloc = _dl_strstr(_dl_debug, "reloc");
711 _dl_debug_nofixups = _dl_strstr(_dl_debug, "nofix");
712 _dl_debug_bindings = _dl_strstr(_dl_debug, "bind");
717 const char *dl_debug_output;
719 dl_debug_output = _dl_getenv("LD_DEBUG_OUTPUT", envp);
721 if (dl_debug_output) {
722 char tmp[22], *tmp1, *filename;
725 _dl_memset(tmp, 0, sizeof(tmp));
726 tmp1 = _dl_simple_ltoa( tmp, (unsigned long)_dl_getpid());
728 len1 = _dl_strlen(dl_debug_output);
729 len2 = _dl_strlen(tmp1);
731 filename = _dl_malloc(len1 + len2 + 2);
734 _dl_strcpy (filename, dl_debug_output);
735 filename[len1] = '.';
736 _dl_strcpy (&filename[len1+1], tmp1);
738 _dl_debug_file = _dl_open(filename, O_WRONLY|O_CREAT, 0644);
739 if (_dl_debug_file < 0) {
741 _dl_dprintf(_dl_debug_file, "can't open file: '%s'\n",filename);
748 #ifdef __LDSO_PRELINK_SUPPORT__
750 char *ld_warn = _dl_getenv ("LD_WARN", envp);
752 if (ld_warn && *ld_warn == '\0')
755 _dl_trace_prelink = _dl_getenv("LD_TRACE_PRELINKING", envp);
758 if (_dl_getenv("LD_TRACE_LOADED_OBJECTS", envp) != NULL) {
759 trace_loaded_objects++;
762 #ifndef __LDSO_LDD_SUPPORT__
763 if (trace_loaded_objects) {
764 _dl_dprintf(_dl_debug_file, "Use the ldd provided by uClibc\n");
770 * OK, fix one more thing - set up debug_addr so it will point
771 * to our chain. Later we may need to fill in more fields, but this
772 * should be enough for now.
774 debug_addr->r_map = (struct link_map *) _dl_loaded_modules;
775 debug_addr->r_version = 1;
776 debug_addr->r_ldbase = (ElfW(Addr)) DL_LOADADDR_BASE(load_addr);
777 debug_addr->r_brk = (unsigned long) &_dl_debug_state;
778 _dl_debug_addr = debug_addr;
780 /* Do not notify the debugger until the interpreter is in the list */
782 /* OK, we now have the application in the list, and we have some
783 * basic stuff in place. Now search through the list for other shared
784 * libraries that should be loaded, and insert them on the list in the
790 #ifdef __LDSO_PRELOAD_ENV_SUPPORT__
795 while (*str == ':' || *str == ' ' || *str == '\t')
800 while (*str2 && *str2 != ':' && *str2 != ' ' && *str2 != '\t')
805 if (!_dl_secure || _dl_strchr(str, '/') == NULL) {
806 _dl_if_debug_dprint("\tfile='%s'; needed by '%s'\n", str, _dl_progname);
808 tpnt1 = _dl_load_shared_library(_dl_secure, &rpnt, NULL, str, trace_loaded_objects);
810 #ifdef __LDSO_LDD_SUPPORT__
811 if (trace_loaded_objects || _dl_trace_prelink)
812 _dl_dprintf(1, "\t%s => not found\n", str);
816 _dl_dprintf(_dl_debug_file, "%s: can't load " "library '%s'\n", _dl_progname, str);
820 tpnt1->rtld_flags = unlazy | RTLD_GLOBAL;
822 _dl_debug_early("Loading: (%x) %s\n", DL_LOADADDR_BASE(tpnt1->loadaddr), tpnt1->libname);
824 #ifdef __LDSO_LDD_SUPPORT__
825 if (trace_loaded_objects && !_dl_trace_prelink &&
826 tpnt1->usage_count == 1) {
827 /* This is a real hack to make
828 * ldd not print the library
829 * itself when run on a
832 if (_dl_strcmp(_dl_progname, str) != 0)
833 _dl_dprintf(1, "\t%s => %s (%x)\n", str, tpnt1->libname,
834 DL_LOADADDR_BASE(tpnt1->loadaddr));
842 while (*str == ':' || *str == ' ' || *str == '\t')
846 #endif /* __LDSO_PRELOAD_ENV_SUPPORT__ */
848 #ifdef __LDSO_PRELOAD_FILE_SUPPORT__
854 if (_dl_stat(LDSO_PRELOAD, &st) || st.st_size == 0) {
858 if ((fd = _dl_open(LDSO_PRELOAD, O_RDONLY, 0)) < 0) {
859 _dl_dprintf(_dl_debug_file, "%s: can't open file '%s'\n",
860 _dl_progname, LDSO_PRELOAD);
864 preload = (caddr_t) _dl_mmap(0, st.st_size + 1,
865 PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
867 if (preload == (caddr_t) -1) {
868 _dl_dprintf(_dl_debug_file, "%s:%i: can't map '%s'\n",
869 _dl_progname, __LINE__, LDSO_PRELOAD);
873 /* convert all separators and comments to spaces */
874 for (cp = preload; *cp; /*nada */ ) {
875 if (*cp == ':' || *cp == '\t' || *cp == '\n') {
877 } else if (*cp == '#') {
880 } while (*cp != '\n' && *cp != '\0');
886 /* find start of first library */
887 for (cp = preload; *cp && *cp == ' '; cp++)
891 /* find end of library */
892 for (cp2 = cp; *cp && *cp != ' '; cp++)
897 _dl_if_debug_dprint("\tfile='%s'; needed by '%s'\n", cp2, _dl_progname);
899 tpnt1 = _dl_load_shared_library(0, &rpnt, NULL, cp2, trace_loaded_objects);
901 # ifdef __LDSO_LDD_SUPPORT__
902 if (trace_loaded_objects || _dl_trace_prelink)
903 _dl_dprintf(1, "\t%s => not found\n", cp2);
907 _dl_dprintf(_dl_debug_file, "%s: can't load library '%s'\n", _dl_progname, cp2);
911 tpnt1->rtld_flags = unlazy | RTLD_GLOBAL;
913 _dl_debug_early("Loading: (%x) %s\n", DL_LOADADDR_BASE(tpnt1->loadaddr), tpnt1->libname);
915 # ifdef __LDSO_LDD_SUPPORT__
916 if (trace_loaded_objects && !_dl_trace_prelink &&
917 tpnt1->usage_count == 1) {
918 _dl_dprintf(1, "\t%s => %s (%x)\n",
920 DL_LOADADDR_BASE(tpnt1->loadaddr));
925 /* find start of next library */
927 for ( /*nada */ ; *cp && *cp == ' '; cp++)
931 _dl_munmap(preload, st.st_size + 1);
933 #endif /* __LDSO_PRELOAD_FILE_SUPPORT__ */
936 for (tcurr = _dl_loaded_modules; tcurr; tcurr = tcurr->next) {
937 ElfW(Dyn) *this_dpnt;
940 for (this_dpnt = (ElfW(Dyn) *) tcurr->dynamic_addr; this_dpnt->d_tag; this_dpnt++) {
941 if (this_dpnt->d_tag == DT_NEEDED) {
943 struct init_fini_list *tmp;
945 lpntstr = (char*) (tcurr->dynamic_info[DT_STRTAB] + this_dpnt->d_un.d_val);
946 name = _dl_get_last_path_component(lpntstr);
947 if (_dl_strcmp(name, UCLIBC_LDSO) == 0)
950 _dl_if_debug_dprint("\tfile='%s'; needed by '%s'\n", lpntstr, _dl_progname);
952 if (!(tpnt1 = _dl_load_shared_library(0, &rpnt, tcurr, lpntstr, trace_loaded_objects))) {
953 #ifdef __LDSO_LDD_SUPPORT__
954 if (trace_loaded_objects || _dl_trace_prelink) {
955 _dl_dprintf(1, "\t%s => not found\n", lpntstr);
960 _dl_dprintf(_dl_debug_file, "%s: can't load library '%s'\n", _dl_progname, lpntstr);
965 tmp = alloca(sizeof(struct init_fini_list)); /* Allocates on stack, no need to free this memory */
967 tmp->next = tcurr->init_fini;
968 tcurr->init_fini = tmp;
970 tpnt1->rtld_flags = unlazy | RTLD_GLOBAL;
972 _dl_debug_early("Loading: (%x) %s\n", DL_LOADADDR_BASE(tpnt1->loadaddr), tpnt1->libname);
974 #ifdef __LDSO_LDD_SUPPORT__
975 if (trace_loaded_objects && !_dl_trace_prelink &&
976 tpnt1->usage_count == 1) {
977 _dl_dprintf(1, "\t%s => %s (%x)\n",
978 lpntstr, tpnt1->libname,
979 DL_LOADADDR_BASE(tpnt1->loadaddr));
987 /* Keep track of the number of elements in the global scope */
990 if (_dl_loaded_modules->libtype == elf_executable) {
991 --nlist; /* Exclude the application. */
992 tcurr = _dl_loaded_modules->next;
994 tcurr = _dl_loaded_modules;
995 init_fini_list = _dl_malloc(nlist * sizeof(struct elf_resolve *));
997 for (; tcurr; tcurr = tcurr->next)
998 init_fini_list[i++] = tcurr;
1000 /* Sort the INIT/FINI list in dependency order. */
1001 for (tcurr = _dl_loaded_modules->next; tcurr; tcurr = tcurr->next) {
1004 for (j = 0; init_fini_list[j] != tcurr; ++j)
1006 for (k = j + 1; k < nlist; ++k) {
1007 struct init_fini_list *runp = init_fini_list[k]->init_fini;
1009 for (; runp; runp = runp->next) {
1010 if (runp->tpnt == tcurr) {
1011 struct elf_resolve *here = init_fini_list[k];
1012 _dl_if_debug_dprint("Move %s from pos %d to %d in INIT/FINI list\n", here->libname, k, j);
1013 for (i = (k - j); i; --i)
1014 init_fini_list[i+j] = init_fini_list[i+j-1];
1015 init_fini_list[j] = here;
1022 #ifdef __SUPPORT_LD_DEBUG__
1024 _dl_dprintf(_dl_debug_file, "\nINIT/FINI order and dependencies:\n");
1025 for (i = 0; i < nlist; i++) {
1026 struct init_fini_list *tmp;
1028 _dl_dprintf(_dl_debug_file, "lib: %s has deps:\n",
1029 init_fini_list[i]->libname);
1030 tmp = init_fini_list[i]->init_fini;
1031 for (; tmp; tmp = tmp->next)
1032 _dl_dprintf(_dl_debug_file, " %s ", tmp->tpnt->libname);
1033 _dl_dprintf(_dl_debug_file, "\n");
1039 * If the program interpreter is not in the module chain, add it.
1040 * This will be required for dlopen to be able to access the internal
1041 * functions in the dynamic linker and to relocate the interpreter
1042 * again once all libs are loaded.
1045 ElfW(Ehdr) *epnt = (ElfW(Ehdr) *) auxvt[AT_BASE].a_un.a_val;
1046 ElfW(Phdr) *myppnt = (ElfW(Phdr) *) DL_RELOC_ADDR(load_addr, epnt->e_phoff);
1049 tpnt = _dl_add_elf_hash_table(tpnt->libname, load_addr,
1051 (unsigned long)tpnt->dynamic_addr,
1054 if (_dl_stat(tpnt->libname, &st) >= 0) {
1055 tpnt->st_dev = st.st_dev;
1056 tpnt->st_ino = st.st_ino;
1058 tpnt->n_phent = epnt->e_phnum;
1059 tpnt->ppnt = myppnt;
1060 for (j = 0; j < epnt->e_phnum; j++, myppnt++) {
1061 if (myppnt->p_type == PT_GNU_RELRO) {
1062 tpnt->relro_addr = myppnt->p_vaddr;
1063 tpnt->relro_size = myppnt->p_memsz;
1067 tpnt->libtype = program_interpreter;
1068 tpnt->usage_count++;
1071 rpnt->next = _dl_zalloc(sizeof(struct dyn_elf));
1072 rpnt->next->prev = rpnt;
1075 rpnt = _dl_zalloc(sizeof(struct dyn_elf));
1078 tpnt->rtld_flags = RTLD_NOW | RTLD_GLOBAL; /* Must not be LAZY */
1080 #ifdef RERELOCATE_LDSO
1081 /* Only rerelocate functions for now. */
1082 tpnt->init_flag = RELOCS_DONE;
1083 lpnt = (unsigned long *) (tpnt->dynamic_info[DT_PLTGOT]);
1084 # ifdef ALLOW_ZERO_PLTGOT
1085 if (tpnt->dynamic_info[DT_PLTGOT])
1087 INIT_GOT(lpnt, tpnt);
1089 tpnt->init_flag = RELOCS_DONE | JMP_RELOCS_DONE;
1095 * Allocate the global scope array.
1097 scope_elem_list = (struct elf_resolve **) _dl_malloc(nscope_elem * sizeof(struct elf_resolve *));
1099 for (i = 0, tcurr = _dl_loaded_modules; tcurr; tcurr = tcurr->next)
1100 scope_elem_list[i++] = tcurr;
1102 _dl_loaded_modules->symbol_scope.r_list = scope_elem_list;
1103 _dl_loaded_modules->symbol_scope.r_nlist = nscope_elem;
1105 * The symbol scope of the application, that is the first entry of the
1106 * _dl_loaded_modules list, is just the global scope to be used for the
1109 global_scope = &_dl_loaded_modules->symbol_scope;
1111 /* Build the local scope for each loaded modules. */
1112 local_scope = _dl_malloc(nscope_elem * sizeof(struct elf_resolve *));
1114 for (tcurr = _dl_loaded_modules->next; tcurr; tcurr = tcurr->next) {
1115 cnt = _dl_build_local_scope(local_scope, scope_elem_list[i++]);
1116 tcurr->symbol_scope.r_list = _dl_malloc(cnt * sizeof(struct elf_resolve *));
1117 tcurr->symbol_scope.r_nlist = cnt;
1118 _dl_memcpy (tcurr->symbol_scope.r_list, local_scope, cnt * sizeof (struct elf_resolve *));
1119 /* Restoring the init_flag.*/
1120 for (k = 1; k < nscope_elem; k++)
1121 scope_elem_list[k]->init_flag &= ~DL_RESERVED;
1124 _dl_free(local_scope);
1126 #ifdef __LDSO_LDD_SUPPORT__
1127 /* End of the line for ldd.... */
1128 if (trace_loaded_objects && !_dl_trace_prelink) {
1129 _dl_dprintf(1, "\t%s => %s (%x)\n",
1130 rpnt->dyn->libname + _dl_strlen(_dl_ldsopath) + 1,
1131 rpnt->dyn->libname, DL_LOADADDR_BASE(rpnt->dyn->loadaddr));
1136 #if defined(USE_TLS) && USE_TLS
1137 /* We do not initialize any of the TLS functionality unless any of the
1138 * initial modules uses TLS. This makes dynamic loading of modules with
1139 * TLS impossible, but to support it requires either eagerly doing setup
1140 * now or lazily doing it later. Doing it now makes us incompatible with
1141 * an old kernel that can't perform TLS_INIT_TP, even if no TLS is ever
1142 * used. Trying to do it lazily is too hairy to try when there could be
1143 * multiple threads (from a non-TLS-using libpthread). */
1144 bool was_tls_init_tp_called = tls_init_tp_called;
1146 _dl_debug_early("Calling init_tls()!\n");
1150 #ifdef __UCLIBC_HAS_SSP__
1151 /* Set up the stack checker's canary. */
1152 stack_chk_guard = _dl_setup_stack_chk_guard ();
1153 # ifdef THREAD_SET_STACK_GUARD
1154 THREAD_SET_STACK_GUARD (stack_chk_guard);
1155 # ifdef __UCLIBC_HAS_SSP_COMPAT__
1156 __guard = stack_chk_guard;
1159 __stack_chk_guard = stack_chk_guard;
1164 /* FIXME: The glibc code doesn't trace the ldso when LD_TRACE_OBJECT is set,
1165 * here has been trace to mantain the original one.
1166 * Another difference Vs Glibc is the check to verify if an object is
1167 * "statically linked" (only if LD_TRACE_OBJECT is on).
1170 #ifdef __LDSO_PRELINK_SUPPORT__
1171 if (_dl_trace_prelink) {
1172 for (i = 0; i < nscope_elem; i++)
1173 trace_objects(scope_elem_list[i],
1174 _dl_get_last_path_component(scope_elem_list[i]->libname));
1177 /* Warn about undefined symbols. */
1178 if (_dl_symbol_tables)
1179 if (_dl_fixup(_dl_symbol_tables, global_scope, unlazy))
1185 _dl_debug_early("Beginning relocation fixups\n");
1189 * Relocation of the GOT entries for MIPS have to be done
1190 * after all the libraries have been loaded.
1192 _dl_perform_mips_global_got_relocations(_dl_loaded_modules, !unlazy);
1196 * OK, now all of the kids are tucked into bed in their proper
1197 * addresses. Now we go through and look for REL and RELA records that
1198 * indicate fixups to the GOT tables. We need to do this in reverse
1199 * order so that COPY directives work correctly.
1201 if (_dl_symbol_tables)
1202 if (_dl_fixup(_dl_symbol_tables, global_scope, unlazy))
1205 for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) {
1206 if (tpnt->relro_size)
1207 _dl_protect_relro (tpnt);
1210 #if defined(USE_TLS) && USE_TLS
1211 if (!was_tls_init_tp_called && _dl_tls_max_dtv_idx > 0)
1212 ++_dl_tls_generation;
1214 _dl_debug_early("Calling _dl_allocate_tls_init()!\n");
1216 /* Now that we have completed relocation, the initializer data
1217 for the TLS blocks has its final values and we can copy them
1218 into the main thread's TLS area, which we allocated above. */
1219 _dl_allocate_tls_init (tcbp);
1221 /* And finally install it for the main thread. If ld.so itself uses
1222 TLS we know the thread pointer was initialized earlier. */
1223 if (! tls_init_tp_called) {
1224 const char *lossage = (char *) TLS_INIT_TP (tcbp, USE___THREAD);
1225 if (__builtin_expect (lossage != NULL, 0)) {
1226 _dl_debug_early("cannot set up thread-local storage: %s\n", lossage);
1230 #endif /* USE_TLS */
1232 /* OK, at this point things are pretty much ready to run. Now we need
1233 * to touch up a few items that are required, and then we can let the
1234 * user application have at it. Note that the dynamic linker itself
1235 * is not guaranteed to be fully dynamicly linked if we are using
1236 * ld.so.1, so we have to look up each symbol individually.
1239 _dl_envp = (unsigned long *) (intptr_t) _dl_find_hash(__C_SYMBOL_PREFIX__ "__environ", global_scope, NULL, NULL, 0, NULL);
1241 *_dl_envp = (unsigned long) envp;
1243 #ifndef __FORCE_SHAREABLE_TEXT_SEGMENTS__
1248 /* We had to set the protections of all pages to R/W for
1249 * dynamic linking. Set text pages back to R/O.
1251 for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) {
1252 for (myppnt = tpnt->ppnt, j = 0; j < tpnt->n_phent; j++, myppnt++) {
1253 if (myppnt->p_type == PT_LOAD && !(myppnt->p_flags & PF_W) && tpnt->dynamic_info[DT_TEXTREL]) {
1254 _dl_mprotect((void *) (DL_RELOC_ADDR(tpnt->loadaddr, myppnt->p_vaddr) & PAGE_ALIGN),
1255 (myppnt->p_vaddr & ADDR_ALIGN) + (unsigned long) myppnt->p_filesz, LXFLAGS(myppnt->p_flags));
1262 /* Notify the debugger we have added some objects. */
1263 _dl_debug_addr->r_state = RT_ADD;
1266 /* Run pre-initialization functions for the executable. */
1267 _dl_run_array_forward(_dl_loaded_modules->dynamic_info[DT_PREINIT_ARRAY],
1268 _dl_loaded_modules->dynamic_info[DT_PREINIT_ARRAYSZ],
1269 _dl_loaded_modules->loadaddr);
1271 /* Run initialization functions for loaded objects. For the
1272 main executable, they will be run from __uClibc_main. */
1273 for (i = nlist; i; --i) {
1274 tpnt = init_fini_list[i-1];
1275 tpnt->init_fini = NULL; /* Clear, since alloca was used */
1276 if (tpnt->init_flag & INIT_FUNCS_CALLED)
1278 tpnt->init_flag |= INIT_FUNCS_CALLED;
1280 if (tpnt->dynamic_info[DT_INIT]) {
1281 void (*dl_elf_func) (void);
1283 dl_elf_func = (void (*)(void)) DL_RELOC_ADDR(tpnt->loadaddr, tpnt->dynamic_info[DT_INIT]);
1285 _dl_if_debug_dprint("calling INIT: %s\n\n", tpnt->libname);
1287 DL_CALL_FUNC_AT_ADDR (dl_elf_func, tpnt->loadaddr, (void(*)(void)));
1290 _dl_run_init_array(tpnt);
1293 /* Find the real malloc function and make ldso functions use that from now on */
1294 _dl_malloc_function = (void* (*)(size_t)) (intptr_t) _dl_find_hash(__C_SYMBOL_PREFIX__ "malloc",
1295 global_scope, NULL, NULL, ELF_RTYPE_CLASS_PLT, NULL);
1297 #if defined(USE_TLS) && USE_TLS
1298 /* Find the real functions and make ldso functions use them from now on */
1299 _dl_calloc_function = (void* (*)(size_t, size_t)) (intptr_t)
1300 _dl_find_hash(__C_SYMBOL_PREFIX__ "calloc", global_scope, NULL, NULL, ELF_RTYPE_CLASS_PLT, NULL);
1302 _dl_realloc_function = (void* (*)(void *, size_t)) (intptr_t)
1303 _dl_find_hash(__C_SYMBOL_PREFIX__ "realloc", global_scope, NULL, NULL, ELF_RTYPE_CLASS_PLT, NULL);
1305 _dl_free_function = (void (*)(void *)) (intptr_t)
1306 _dl_find_hash(__C_SYMBOL_PREFIX__ "free", global_scope, NULL, NULL, ELF_RTYPE_CLASS_PLT, NULL);
1308 _dl_memalign_function = (void* (*)(size_t, size_t)) (intptr_t)
1309 _dl_find_hash(__C_SYMBOL_PREFIX__ "memalign", global_scope, NULL, NULL, ELF_RTYPE_CLASS_PLT, NULL);
1313 /* Notify the debugger that all objects are now mapped in. */
1314 _dl_debug_addr->r_state = RT_CONSISTENT;
1317 #ifdef __LDSO_STANDALONE_SUPPORT__
1318 if (_start == (void *) auxvt[AT_ENTRY].a_un.a_val)
1319 return (void *) app_tpnt->l_entry;
1322 return (void *) auxvt[AT_ENTRY].a_un.a_val;
1325 #include "dl-hash.c"