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 static int _dl_secure = 1; /* Are we dealing with setuid stuff? */
62 #ifdef __SUPPORT_LD_DEBUG__
63 char *_dl_debug = NULL;
64 char *_dl_debug_symbols = NULL;
65 char *_dl_debug_move = NULL;
66 char *_dl_debug_reloc = NULL;
67 char *_dl_debug_detail = NULL;
68 char *_dl_debug_nofixups = NULL;
69 char *_dl_debug_bindings = NULL;
70 int _dl_debug_file = 2;
73 /* Needed for standalone execution. */
74 unsigned long attribute_hidden _dl_skip_args = 0;
75 const char *_dl_progname = UCLIBC_LDSO; /* The name of the executable being run */
76 #include "dl-startup.c"
77 #include "dl-symbols.c"
81 * This stub function is used by some debuggers. The idea is that they
82 * can set an internal breakpoint on it, so that we are notified when the
83 * address mapping is changed in some way.
85 void _dl_debug_state(void);
86 rtld_hidden_proto(_dl_debug_state, noinline);
87 void _dl_debug_state(void)
89 /* Make sure GCC doesn't recognize this function as pure, to avoid
90 * having the calls optimized away.
94 rtld_hidden_def(_dl_debug_state);
96 static unsigned char *_dl_malloc_addr = NULL; /* Lets _dl_malloc use the already allocated memory page */
97 static unsigned char *_dl_mmap_zero = NULL; /* Also used by _dl_malloc */
99 static struct elf_resolve **init_fini_list;
100 static unsigned int nlist; /* # items in init_fini_list */
101 extern void _start(void);
103 #ifdef __UCLIBC_HAS_SSP__
104 # include <dl-osinfo.h>
105 static uintptr_t stack_chk_guard;
106 # ifndef THREAD_SET_STACK_GUARD
107 /* Only exported for architectures that don't store the stack guard canary
108 * in local thread area. */
109 uintptr_t __stack_chk_guard attribute_relro;
111 # ifdef __UCLIBC_HAS_SSP_COMPAT__
112 uintptr_t __guard attribute_relro;
116 char *_dl_getenv(const char *symbol, char **envp)
121 while ((pnt = *envp++)) {
123 while (*pnt && *pnt == *pnt1)
125 if (!*pnt || *pnt != '=' || *pnt1)
132 void _dl_unsetenv(const char *symbol, char **envp)
136 char **newenvp = envp;
138 for (pnt = *envp; pnt; pnt = *++envp) {
140 while (*pnt && *pnt == *pnt1)
142 if (!*pnt || *pnt != '=' || *pnt1)
149 static int _dl_suid_ok(void)
151 __kernel_uid_t uid, euid;
152 __kernel_gid_t gid, egid;
155 euid = _dl_geteuid();
157 egid = _dl_getegid();
159 if (uid == euid && gid == egid) {
165 void *_dl_malloc(size_t size)
170 _dl_debug_early("request for %d bytes\n", size);
173 if (_dl_malloc_function)
174 return (*_dl_malloc_function) (size);
176 if (_dl_malloc_addr - _dl_mmap_zero + size > _dl_pagesize) {
179 /* Since the above assumes we get a full page even if
180 we request less than that, make sure we request a
181 full page, since uClinux may give us less than than
182 a full page. We might round even
183 larger-than-a-page sizes, but we end up never
184 reusing _dl_mmap_zero/_dl_malloc_addr in that case,
187 The actual page size doesn't really matter; as long
188 as we're self-consistent here, we're safe. */
189 if (size < _dl_pagesize)
190 rounded_size = (size + ADDR_ALIGN) & _dl_pagesize;
194 _dl_debug_early("mmapping more memory\n");
195 _dl_mmap_zero = _dl_malloc_addr = _dl_mmap((void *) 0, rounded_size,
196 PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_UNINITIALIZE, -1, 0);
197 if (_dl_mmap_check_error(_dl_mmap_zero)) {
198 _dl_dprintf(_dl_debug_file, "%s: mmap of a spare page failed!\n", _dl_progname);
202 retval = _dl_malloc_addr;
203 _dl_malloc_addr += size;
206 * Align memory to DL_MALLOC_ALIGN byte boundary. Some
207 * platforms require this, others simply get better
210 _dl_malloc_addr = (unsigned char *) (((unsigned long) _dl_malloc_addr + DL_MALLOC_ALIGN - 1) & ~(DL_MALLOC_ALIGN - 1));
214 static void *_dl_zalloc(size_t size)
216 void *p = _dl_malloc(size);
218 _dl_memset(p, 0, size);
222 void _dl_free(void *p)
224 if (_dl_free_function)
225 (*_dl_free_function) (p);
228 #if defined(USE_TLS) && USE_TLS
229 void *_dl_memalign(size_t __boundary, size_t __size)
236 if (_dl_memalign_function)
237 return (*_dl_memalign_function) (__boundary, __size);
239 while (rounded < __boundary) {
240 rounded = (1 << i++);
243 delta = (((size_t) _dl_malloc_addr + __size) & (rounded - 1));
245 if ((result = _dl_malloc(rounded - delta)) == NULL)
248 result = _dl_malloc(__size);
254 static void __attribute__ ((destructor)) __attribute_used__ _dl_fini(void)
257 struct elf_resolve * tpnt;
259 for (i = 0; i < nlist; ++i) {
260 tpnt = init_fini_list[i];
261 if (tpnt->init_flag & FINI_FUNCS_CALLED)
263 tpnt->init_flag |= FINI_FUNCS_CALLED;
264 _dl_run_fini_array(tpnt);
265 if (tpnt->dynamic_info[DT_FINI]) {
266 void (*dl_elf_func) (void);
268 dl_elf_func = (void (*)(void)) (intptr_t) DL_RELOC_ADDR(tpnt->loadaddr, tpnt->dynamic_info[DT_FINI]);
269 _dl_if_debug_dprint("\ncalling FINI: %s\n\n", tpnt->libname);
270 DL_CALL_FUNC_AT_ADDR (dl_elf_func, tpnt->loadaddr, (void(*)(void)));
275 void _dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr,
276 ElfW(auxv_t) auxvt[AT_EGID + 1], char **envp,
278 DL_GET_READY_TO_RUN_EXTRA_PARMS)
280 ElfW(Addr) app_mapaddr = 0;
285 int unlazy = 0, trace_loaded_objects = 0;
286 struct dyn_elf *rpnt;
287 struct elf_resolve *tcurr;
288 struct elf_resolve *tpnt1;
289 struct elf_resolve app_tpnt_tmp;
290 struct elf_resolve *app_tpnt = &app_tpnt_tmp;
291 struct r_debug *debug_addr;
293 unsigned long *_dl_envp; /* The environment address */
294 ElfW(Addr) relro_addr = 0;
295 size_t relro_size = 0;
297 #if defined(USE_TLS) && USE_TLS
301 /* Wahoo!!! We managed to make a function call! Get malloc
302 * setup so we can use _dl_dprintf() to print debug noise
303 * instead of the SEND_STDERR macros used in dl-startup.c */
305 _dl_memset(app_tpnt, 0, sizeof(*app_tpnt));
307 /* Store the page size for later use */
308 _dl_pagesize = (auxvt[AT_PAGESZ].a_un.a_val) ? (size_t) auxvt[AT_PAGESZ].a_un.a_val : PAGE_SIZE;
309 /* Make it so _dl_malloc can use the page of memory we have already
310 * allocated. We shouldn't need to grab any more memory. This must
311 * be first since things like _dl_dprintf() use _dl_malloc()...
313 _dl_malloc_addr = (unsigned char *)_dl_pagesize;
317 _dl_debug_early("Cool, ldso survived making function calls\n");
319 /* Now we have done the mandatory linking of some things. We are now
320 * free to start using global variables, since these things have all
321 * been fixed up by now. Still no function calls outside of this
322 * library, since the dynamic resolver is not yet ready.
325 _dl_progname = argv[0];
328 if (_start == (void *) auxvt[AT_ENTRY].a_un.a_val) {
329 _dl_dprintf(_dl_debug_file, "Standalone execution is not supported yet\n");
333 /* Start to build the tables of the modules that are required for
334 * this beast to run. We start with the basic executable, and then
335 * go from there. Eventually we will run across ourself, and we
336 * will need to properly deal with that as well.
339 if (_dl_getenv("LD_BIND_NOW", envp))
342 /* Now we need to figure out what kind of options are selected.
343 * Note that for SUID programs we ignore the settings in
346 if ((auxvt[AT_UID].a_un.a_val == (size_t)-1 && _dl_suid_ok()) ||
347 (auxvt[AT_UID].a_un.a_val != (size_t)-1 &&
348 auxvt[AT_UID].a_un.a_val == auxvt[AT_EUID].a_un.a_val &&
349 auxvt[AT_GID].a_un.a_val == auxvt[AT_EGID].a_un.a_val)) {
351 #ifdef __LDSO_PRELOAD_ENV_SUPPORT__
352 _dl_preload = _dl_getenv("LD_PRELOAD", envp);
354 _dl_library_path = _dl_getenv("LD_LIBRARY_PATH", envp);
356 static const char unsecure_envvars[] =
357 #ifdef EXTRA_UNSECURE_ENVVARS
358 EXTRA_UNSECURE_ENVVARS
364 nextp = unsecure_envvars;
366 _dl_unsetenv (nextp, envp);
367 /* We could use rawmemchr but this need not be fast. */
368 nextp = _dl_strchr(nextp, '\0') + 1;
369 } while (*nextp != '\0');
370 #ifdef __LDSO_PRELOAD_ENV_SUPPORT__
373 _dl_library_path = NULL;
374 /* SUID binaries can be exploited if they do LAZY relocation. */
378 #if defined(USE_TLS) && USE_TLS
379 _dl_error_catch_tsd = &_dl_initial_error_catch_tsd;
380 _dl_init_static_tls = &_dl_nothread_init_static_tls;
383 /* At this point we are now free to examine the user application,
384 * and figure out which libraries are supposed to be called. Until
385 * we have this list, we will not be completely ready for dynamic
389 /* Find the runtime load address of the main executable. This may be
390 * different from what the ELF header says for ET_DYN/PIE executables.
394 ElfW(Phdr) *phdr = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_val;
396 for (idx = 0; idx < auxvt[AT_PHNUM].a_un.a_val; idx++, phdr++)
397 if (phdr->p_type == PT_PHDR) {
398 DL_INIT_LOADADDR_PROG(app_tpnt->loadaddr, auxvt[AT_PHDR].a_un.a_val - phdr->p_vaddr);
402 if (DL_LOADADDR_BASE(app_tpnt->loadaddr))
403 _dl_debug_early("Position Independent Executable: "
404 "app_tpnt->loadaddr=%x\n", DL_LOADADDR_BASE(app_tpnt->loadaddr));
408 * This is used by gdb to locate the chain of shared libraries that are
411 debug_addr = _dl_zalloc(sizeof(struct r_debug));
413 ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_val;
414 for (i = 0; i < auxvt[AT_PHNUM].a_un.a_val; i++, ppnt++) {
415 if (ppnt->p_type == PT_GNU_RELRO) {
416 relro_addr = ppnt->p_vaddr;
417 relro_size = ppnt->p_memsz;
419 if (!app_mapaddr && (ppnt->p_type == PT_LOAD)) {
420 app_mapaddr = DL_RELOC_ADDR (app_tpnt->loadaddr, ppnt->p_vaddr);
422 if (ppnt->p_type == PT_DYNAMIC) {
423 dpnt = (ElfW(Dyn) *) DL_RELOC_ADDR(app_tpnt->loadaddr, ppnt->p_vaddr);
424 _dl_parse_dynamic_info(dpnt, app_tpnt->dynamic_info, debug_addr, app_tpnt->loadaddr);
425 #ifndef __FORCE_SHAREABLE_TEXT_SEGMENTS__
426 /* Ugly, ugly. We need to call mprotect to change the
427 * protection of the text pages so that we can do the
428 * dynamic linking. We can set the protection back
429 * again once we are done.
431 _dl_debug_early("calling mprotect on the application program\n");
432 /* Now cover the application program. */
433 if (app_tpnt->dynamic_info[DT_TEXTREL]) {
434 ElfW(Phdr) *ppnt_outer = ppnt;
435 ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_val;
436 for (i = 0; i < auxvt[AT_PHNUM].a_un.a_val; i++, ppnt++) {
437 if (ppnt->p_type == PT_LOAD && !(ppnt->p_flags & PF_W))
438 _dl_mprotect((void *) (DL_RELOC_ADDR(app_tpnt->loadaddr, ppnt->p_vaddr) & PAGE_ALIGN),
439 (DL_RELOC_ADDR(app_tpnt->loadaddr, ppnt->p_vaddr) & ADDR_ALIGN) +
440 (unsigned long) ppnt->p_filesz,
441 PROT_READ | PROT_WRITE | PROT_EXEC);
446 if (app_tpnt->dynamic_info[DT_TEXTREL]) {
447 _dl_dprintf(_dl_debug_file, "Can't modify application's text section; use the GCC option -fPIE for position-independent executables.\n");
452 #ifndef ALLOW_ZERO_PLTGOT
453 /* make sure it's really there. */
454 if (app_tpnt->dynamic_info[DT_PLTGOT] == 0)
457 /* OK, we have what we need - slip this one into the list. */
458 app_tpnt = _dl_add_elf_hash_table(_dl_progname, app_tpnt->loadaddr,
459 app_tpnt->dynamic_info,
460 (unsigned long) DL_RELOC_ADDR(app_tpnt->loadaddr, ppnt->p_vaddr),
462 _dl_loaded_modules->libtype = elf_executable;
463 _dl_loaded_modules->ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_val;
464 _dl_loaded_modules->n_phent = auxvt[AT_PHNUM].a_un.a_val;
465 _dl_symbol_tables = rpnt = _dl_zalloc(sizeof(struct dyn_elf));
466 rpnt->dyn = _dl_loaded_modules;
467 app_tpnt->mapaddr = app_mapaddr;
468 app_tpnt->rtld_flags = unlazy | RTLD_GLOBAL;
469 app_tpnt->usage_count++;
470 app_tpnt->symbol_scope = _dl_symbol_tables;
471 lpnt = (unsigned long *) (app_tpnt->dynamic_info[DT_PLTGOT]);
472 #ifdef ALLOW_ZERO_PLTGOT
475 INIT_GOT(lpnt, _dl_loaded_modules);
478 /* OK, fill this in - we did not have this before */
479 if (ppnt->p_type == PT_INTERP) {
480 tpnt->libname = (char *) DL_RELOC_ADDR(app_tpnt->loadaddr, ppnt->p_vaddr);
481 #ifdef __LDSO_SEARCH_INTERP_PATH__
484 /* Store the path where the shared lib loader was found
487 _dl_ldsopath = _dl_strdup(tpnt->libname);
488 ptmp = _dl_strrchr(_dl_ldsopath, '/');
489 if (ptmp != _dl_ldsopath)
492 _dl_debug_early("Lib Loader: (%x) %s\n", (unsigned) DL_LOADADDR_BASE(tpnt->loadaddr), tpnt->libname);
496 /* Discover any TLS sections if the target supports them. */
497 if (ppnt->p_type == PT_TLS) {
498 #if defined(USE_TLS) && USE_TLS
499 if (ppnt->p_memsz > 0) {
500 app_tpnt->l_tls_blocksize = ppnt->p_memsz;
501 app_tpnt->l_tls_align = ppnt->p_align;
502 if (ppnt->p_align == 0)
503 app_tpnt->l_tls_firstbyte_offset = 0;
505 app_tpnt->l_tls_firstbyte_offset =
506 (ppnt->p_vaddr & (ppnt->p_align - 1));
507 app_tpnt->l_tls_initimage_size = ppnt->p_filesz;
508 app_tpnt->l_tls_initimage = (void *) ppnt->p_vaddr;
510 /* This image gets the ID one. */
511 _dl_tls_max_dtv_idx = app_tpnt->l_tls_modid = 1;
514 _dl_debug_early("Found TLS header for appplication program\n");
517 _dl_dprintf(_dl_debug_file, "Program uses unsupported TLS data!\n");
522 app_tpnt->relro_addr = relro_addr;
523 app_tpnt->relro_size = relro_size;
525 #if defined(USE_TLS) && USE_TLS
527 * Adjust the address of the TLS initialization image in
528 * case the executable is actually an ET_DYN object.
530 if (app_tpnt->l_tls_initimage != NULL) {
531 app_tpnt->l_tls_initimage =
532 (char *) app_tpnt->l_tls_initimage + app_tpnt->loadaddr;
533 _dl_debug_early("Relocated TLS initial image from %x to %x (size = %x)\n",
534 (unsigned int)app_tpnt->l_tls_initimage,
535 app_tpnt->l_tls_initimage, app_tpnt->l_tls_initimage_size);
539 #ifdef __SUPPORT_LD_DEBUG__
540 _dl_debug = _dl_getenv("LD_DEBUG", envp);
542 if (_dl_strstr(_dl_debug, "all")) {
543 _dl_debug_detail = _dl_debug_move = _dl_debug_symbols
544 = _dl_debug_reloc = _dl_debug_bindings = _dl_debug_nofixups = (void*)1;
546 _dl_debug_detail = _dl_strstr(_dl_debug, "detail");
547 _dl_debug_move = _dl_strstr(_dl_debug, "move");
548 _dl_debug_symbols = _dl_strstr(_dl_debug, "sym");
549 _dl_debug_reloc = _dl_strstr(_dl_debug, "reloc");
550 _dl_debug_nofixups = _dl_strstr(_dl_debug, "nofix");
551 _dl_debug_bindings = _dl_strstr(_dl_debug, "bind");
556 const char *dl_debug_output;
558 dl_debug_output = _dl_getenv("LD_DEBUG_OUTPUT", envp);
560 if (dl_debug_output) {
561 char tmp[22], *tmp1, *filename;
564 _dl_memset(tmp, 0, sizeof(tmp));
565 tmp1 = _dl_simple_ltoa( tmp, (unsigned long)_dl_getpid());
567 len1 = _dl_strlen(dl_debug_output);
568 len2 = _dl_strlen(tmp1);
570 filename = _dl_malloc(len1 + len2 + 2);
573 _dl_strcpy (filename, dl_debug_output);
574 filename[len1] = '.';
575 _dl_strcpy (&filename[len1+1], tmp1);
577 _dl_debug_file = _dl_open(filename, O_WRONLY|O_CREAT, 0644);
578 if (_dl_debug_file < 0) {
580 _dl_dprintf(_dl_debug_file, "can't open file: '%s'\n",filename);
587 if (_dl_getenv("LD_TRACE_LOADED_OBJECTS", envp) != NULL) {
588 trace_loaded_objects++;
591 #ifndef __LDSO_LDD_SUPPORT__
592 if (trace_loaded_objects) {
593 _dl_dprintf(_dl_debug_file, "Use the ldd provided by uClibc\n");
599 * OK, fix one more thing - set up debug_addr so it will point
600 * to our chain. Later we may need to fill in more fields, but this
601 * should be enough for now.
603 debug_addr->r_map = (struct link_map *) _dl_loaded_modules;
604 debug_addr->r_version = 1;
605 debug_addr->r_ldbase = (ElfW(Addr)) DL_LOADADDR_BASE(load_addr);
606 debug_addr->r_brk = (unsigned long) &_dl_debug_state;
607 _dl_debug_addr = debug_addr;
609 /* Do not notify the debugger until the interpreter is in the list */
611 /* OK, we now have the application in the list, and we have some
612 * basic stuff in place. Now search through the list for other shared
613 * libraries that should be loaded, and insert them on the list in the
619 #ifdef __LDSO_PRELOAD_ENV_SUPPORT__
624 while (*str == ':' || *str == ' ' || *str == '\t')
629 while (*str2 && *str2 != ':' && *str2 != ' ' && *str2 != '\t')
634 if (!_dl_secure || _dl_strchr(str, '/') == NULL) {
635 _dl_if_debug_dprint("\tfile='%s'; needed by '%s'\n", str, _dl_progname);
637 tpnt1 = _dl_load_shared_library(_dl_secure, &rpnt, NULL, str, trace_loaded_objects);
639 #ifdef __LDSO_LDD_SUPPORT__
640 if (trace_loaded_objects)
641 _dl_dprintf(1, "\t%s => not found\n", str);
645 _dl_dprintf(_dl_debug_file, "%s: can't load " "library '%s'\n", _dl_progname, str);
649 tpnt1->rtld_flags = unlazy | RTLD_GLOBAL;
651 _dl_debug_early("Loading: (%x) %s\n", DL_LOADADDR_BASE(tpnt1->loadaddr), tpnt1->libname);
653 #ifdef __LDSO_LDD_SUPPORT__
654 if (trace_loaded_objects &&
655 tpnt1->usage_count == 1) {
656 /* This is a real hack to make
657 * ldd not print the library
658 * itself when run on a
661 if (_dl_strcmp(_dl_progname, str) != 0)
662 _dl_dprintf(1, "\t%s => %s (%x)\n", str, tpnt1->libname,
663 DL_LOADADDR_BASE(tpnt1->loadaddr));
671 while (*str == ':' || *str == ' ' || *str == '\t')
675 #endif /* __LDSO_PRELOAD_ENV_SUPPORT__ */
677 #ifdef __LDSO_PRELOAD_FILE_SUPPORT__
683 if (_dl_stat(LDSO_PRELOAD, &st) || st.st_size == 0) {
687 if ((fd = _dl_open(LDSO_PRELOAD, O_RDONLY, 0)) < 0) {
688 _dl_dprintf(_dl_debug_file, "%s: can't open file '%s'\n",
689 _dl_progname, LDSO_PRELOAD);
693 preload = (caddr_t) _dl_mmap(0, st.st_size + 1,
694 PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
696 if (preload == (caddr_t) -1) {
697 _dl_dprintf(_dl_debug_file, "%s:%i: can't map '%s'\n",
698 _dl_progname, __LINE__, LDSO_PRELOAD);
702 /* convert all separators and comments to spaces */
703 for (cp = preload; *cp; /*nada */ ) {
704 if (*cp == ':' || *cp == '\t' || *cp == '\n') {
706 } else if (*cp == '#') {
709 } while (*cp != '\n' && *cp != '\0');
715 /* find start of first library */
716 for (cp = preload; *cp && *cp == ' '; cp++)
720 /* find end of library */
721 for (cp2 = cp; *cp && *cp != ' '; cp++)
726 _dl_if_debug_dprint("\tfile='%s'; needed by '%s'\n", cp2, _dl_progname);
728 tpnt1 = _dl_load_shared_library(0, &rpnt, NULL, cp2, trace_loaded_objects);
730 # ifdef __LDSO_LDD_SUPPORT__
731 if (trace_loaded_objects)
732 _dl_dprintf(1, "\t%s => not found\n", cp2);
736 _dl_dprintf(_dl_debug_file, "%s: can't load library '%s'\n", _dl_progname, cp2);
740 tpnt1->rtld_flags = unlazy | RTLD_GLOBAL;
742 _dl_debug_early("Loading: (%x) %s\n", DL_LOADADDR_BASE(tpnt1->loadaddr), tpnt1->libname);
744 # ifdef __LDSO_LDD_SUPPORT__
745 if (trace_loaded_objects &&
746 tpnt1->usage_count == 1) {
747 _dl_dprintf(1, "\t%s => %s (%x)\n",
749 DL_LOADADDR_BASE(tpnt1->loadaddr));
754 /* find start of next library */
756 for ( /*nada */ ; *cp && *cp == ' '; cp++)
760 _dl_munmap(preload, st.st_size + 1);
762 #endif /* __LDSO_PRELOAD_FILE_SUPPORT__ */
765 for (tcurr = _dl_loaded_modules; tcurr; tcurr = tcurr->next) {
766 ElfW(Dyn) *this_dpnt;
769 for (this_dpnt = (ElfW(Dyn) *) tcurr->dynamic_addr; this_dpnt->d_tag; this_dpnt++) {
770 if (this_dpnt->d_tag == DT_NEEDED) {
772 struct init_fini_list *tmp;
774 lpntstr = (char*) (tcurr->dynamic_info[DT_STRTAB] + this_dpnt->d_un.d_val);
775 name = _dl_get_last_path_component(lpntstr);
776 if (_dl_strcmp(name, UCLIBC_LDSO) == 0)
779 _dl_if_debug_dprint("\tfile='%s'; needed by '%s'\n", lpntstr, _dl_progname);
781 if (!(tpnt1 = _dl_load_shared_library(0, &rpnt, tcurr, lpntstr, trace_loaded_objects))) {
782 #ifdef __LDSO_LDD_SUPPORT__
783 if (trace_loaded_objects) {
784 _dl_dprintf(1, "\t%s => not found\n", lpntstr);
789 _dl_dprintf(_dl_debug_file, "%s: can't load library '%s'\n", _dl_progname, lpntstr);
794 tmp = alloca(sizeof(struct init_fini_list)); /* Allocates on stack, no need to free this memory */
796 tmp->next = tcurr->init_fini;
797 tcurr->init_fini = tmp;
799 tpnt1->rtld_flags = unlazy | RTLD_GLOBAL;
801 _dl_debug_early("Loading: (%x) %s\n", DL_LOADADDR_BASE(tpnt1->loadaddr), tpnt1->libname);
803 #ifdef __LDSO_LDD_SUPPORT__
804 if (trace_loaded_objects &&
805 tpnt1->usage_count == 1) {
806 _dl_dprintf(1, "\t%s => %s (%x)\n",
807 lpntstr, tpnt1->libname,
808 DL_LOADADDR_BASE(tpnt1->loadaddr));
816 --nlist; /* Exclude the application. */
817 init_fini_list = _dl_malloc(nlist * sizeof(struct elf_resolve *));
819 for (tcurr = _dl_loaded_modules->next; tcurr; tcurr = tcurr->next) {
820 init_fini_list[i++] = tcurr;
823 /* Sort the INIT/FINI list in dependency order. */
824 for (tcurr = _dl_loaded_modules->next; tcurr; tcurr = tcurr->next) {
827 for (j = 0; init_fini_list[j] != tcurr; ++j)
829 for (k = j + 1; k < nlist; ++k) {
830 struct init_fini_list *runp = init_fini_list[k]->init_fini;
832 for (; runp; runp = runp->next) {
833 if (runp->tpnt == tcurr) {
834 struct elf_resolve *here = init_fini_list[k];
835 _dl_if_debug_dprint("Move %s from pos %d to %d in INIT/FINI list\n", here->libname, k, j);
836 for (i = (k - j); i; --i)
837 init_fini_list[i+j] = init_fini_list[i+j-1];
838 init_fini_list[j] = here;
845 #ifdef __SUPPORT_LD_DEBUG__
847 _dl_dprintf(_dl_debug_file, "\nINIT/FINI order and dependencies:\n");
848 for (i = 0; i < nlist; i++) {
849 struct init_fini_list *tmp;
851 _dl_dprintf(_dl_debug_file, "lib: %s has deps:\n",
852 init_fini_list[i]->libname);
853 tmp = init_fini_list[i]->init_fini;
854 for (; tmp; tmp = tmp->next)
855 _dl_dprintf(_dl_debug_file, " %s ", tmp->tpnt->libname);
856 _dl_dprintf(_dl_debug_file, "\n");
862 * If the program interpreter is not in the module chain, add it.
863 * This will be required for dlopen to be able to access the internal
864 * functions in the dynamic linker and to relocate the interpreter
865 * again once all libs are loaded.
868 ElfW(Ehdr) *epnt = (ElfW(Ehdr) *) auxvt[AT_BASE].a_un.a_val;
869 ElfW(Phdr) *myppnt = (ElfW(Phdr) *) DL_RELOC_ADDR(load_addr, epnt->e_phoff);
872 tpnt = _dl_add_elf_hash_table(tpnt->libname, load_addr,
874 (unsigned long)tpnt->dynamic_addr,
877 if (_dl_stat(tpnt->libname, &st) >= 0) {
878 tpnt->st_dev = st.st_dev;
879 tpnt->st_ino = st.st_ino;
881 tpnt->n_phent = epnt->e_phnum;
883 for (j = 0; j < epnt->e_phnum; j++, myppnt++) {
884 if (myppnt->p_type == PT_GNU_RELRO) {
885 tpnt->relro_addr = myppnt->p_vaddr;
886 tpnt->relro_size = myppnt->p_memsz;
890 tpnt->libtype = program_interpreter;
892 tpnt->symbol_scope = _dl_symbol_tables;
894 rpnt->next = _dl_zalloc(sizeof(struct dyn_elf));
895 rpnt->next->prev = rpnt;
898 rpnt = _dl_zalloc(sizeof(struct dyn_elf));
901 tpnt->rtld_flags = RTLD_NOW | RTLD_GLOBAL; /* Must not be LAZY */
902 #ifdef RERELOCATE_LDSO
903 /* Only rerelocate functions for now. */
904 tpnt->init_flag = RELOCS_DONE;
905 lpnt = (unsigned long *) (tpnt->dynamic_info[DT_PLTGOT]);
906 # ifdef ALLOW_ZERO_PLTGOT
907 if (tpnt->dynamic_info[DT_PLTGOT])
909 INIT_GOT(lpnt, tpnt);
911 tpnt->init_flag = RELOCS_DONE | JMP_RELOCS_DONE;
916 #ifdef __LDSO_LDD_SUPPORT__
917 /* End of the line for ldd.... */
918 if (trace_loaded_objects) {
919 _dl_dprintf(1, "\t%s => %s (%x)\n",
920 rpnt->dyn->libname + _dl_strlen(_dl_ldsopath) + 1,
921 rpnt->dyn->libname, DL_LOADADDR_BASE(rpnt->dyn->loadaddr));
926 #if defined(USE_TLS) && USE_TLS
927 /* We do not initialize any of the TLS functionality unless any of the
928 * initial modules uses TLS. This makes dynamic loading of modules with
929 * TLS impossible, but to support it requires either eagerly doing setup
930 * now or lazily doing it later. Doing it now makes us incompatible with
931 * an old kernel that can't perform TLS_INIT_TP, even if no TLS is ever
932 * used. Trying to do it lazily is too hairy to try when there could be
933 * multiple threads (from a non-TLS-using libpthread). */
934 bool was_tls_init_tp_called = tls_init_tp_called;
936 _dl_debug_early("Calling init_tls()!\n");
940 #ifdef __UCLIBC_HAS_SSP__
941 /* Set up the stack checker's canary. */
942 stack_chk_guard = _dl_setup_stack_chk_guard ();
943 # ifdef THREAD_SET_STACK_GUARD
944 THREAD_SET_STACK_GUARD (stack_chk_guard);
946 __stack_chk_guard = stack_chk_guard;
948 # ifdef __UCLIBC_HAS_SSP_COMPAT__
949 __guard = stack_chk_guard;
954 _dl_debug_early("Beginning relocation fixups\n");
958 * Relocation of the GOT entries for MIPS have to be done
959 * after all the libraries have been loaded.
961 _dl_perform_mips_global_got_relocations(_dl_loaded_modules, !unlazy);
965 * OK, now all of the kids are tucked into bed in their proper
966 * addresses. Now we go through and look for REL and RELA records that
967 * indicate fixups to the GOT tables. We need to do this in reverse
968 * order so that COPY directives work correctly.
970 if (_dl_symbol_tables)
971 if (_dl_fixup(_dl_symbol_tables, unlazy))
974 for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) {
975 if (tpnt->relro_size)
976 _dl_protect_relro (tpnt);
979 #if defined(USE_TLS) && USE_TLS
980 if (!was_tls_init_tp_called && _dl_tls_max_dtv_idx > 0)
981 ++_dl_tls_generation;
983 _dl_debug_early("Calling _dl_allocate_tls_init()!\n");
985 /* Now that we have completed relocation, the initializer data
986 for the TLS blocks has its final values and we can copy them
987 into the main thread's TLS area, which we allocated above. */
988 _dl_allocate_tls_init (tcbp);
990 /* And finally install it for the main thread. If ld.so itself uses
991 TLS we know the thread pointer was initialized earlier. */
992 if (! tls_init_tp_called) {
993 const char *lossage = (char *) TLS_INIT_TP (tcbp, USE___THREAD);
994 if (__builtin_expect (lossage != NULL, 0)) {
995 _dl_debug_early("cannot set up thread-local storage: %s\n", lossage);
1001 /* OK, at this point things are pretty much ready to run. Now we need
1002 * to touch up a few items that are required, and then we can let the
1003 * user application have at it. Note that the dynamic linker itself
1004 * is not guaranteed to be fully dynamicly linked if we are using
1005 * ld.so.1, so we have to look up each symbol individually.
1008 _dl_envp = (unsigned long *) (intptr_t) _dl_find_hash(__C_SYMBOL_PREFIX__ "__environ", _dl_symbol_tables, NULL, 0, NULL);
1010 *_dl_envp = (unsigned long) envp;
1012 #ifndef __FORCE_SHAREABLE_TEXT_SEGMENTS__
1017 /* We had to set the protections of all pages to R/W for
1018 * dynamic linking. Set text pages back to R/O.
1020 for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) {
1021 for (myppnt = tpnt->ppnt, j = 0; j < tpnt->n_phent; j++, myppnt++) {
1022 if (myppnt->p_type == PT_LOAD && !(myppnt->p_flags & PF_W) && tpnt->dynamic_info[DT_TEXTREL]) {
1023 _dl_mprotect((void *) (DL_RELOC_ADDR(tpnt->loadaddr, myppnt->p_vaddr) & PAGE_ALIGN),
1024 (myppnt->p_vaddr & ADDR_ALIGN) + (unsigned long) myppnt->p_filesz, LXFLAGS(myppnt->p_flags));
1031 /* Notify the debugger we have added some objects. */
1032 _dl_debug_addr->r_state = RT_ADD;
1035 /* Run pre-initialization functions for the executable. */
1036 _dl_run_array_forward(_dl_loaded_modules->dynamic_info[DT_PREINIT_ARRAY],
1037 _dl_loaded_modules->dynamic_info[DT_PREINIT_ARRAYSZ],
1038 _dl_loaded_modules->loadaddr);
1040 /* Run initialization functions for loaded objects. For the
1041 main executable, they will be run from __uClibc_main. */
1042 for (i = nlist; i; --i) {
1043 tpnt = init_fini_list[i-1];
1044 tpnt->init_fini = NULL; /* Clear, since alloca was used */
1045 if (tpnt->init_flag & INIT_FUNCS_CALLED)
1047 tpnt->init_flag |= INIT_FUNCS_CALLED;
1049 if (tpnt->dynamic_info[DT_INIT]) {
1050 void (*dl_elf_func) (void);
1052 dl_elf_func = (void (*)(void)) DL_RELOC_ADDR(tpnt->loadaddr, tpnt->dynamic_info[DT_INIT]);
1054 _dl_if_debug_dprint("calling INIT: %s\n\n", tpnt->libname);
1056 DL_CALL_FUNC_AT_ADDR (dl_elf_func, tpnt->loadaddr, (void(*)(void)));
1059 _dl_run_init_array(tpnt);
1062 /* Find the real malloc function and make ldso functions use that from now on */
1063 _dl_malloc_function = (void* (*)(size_t)) (intptr_t) _dl_find_hash(__C_SYMBOL_PREFIX__ "malloc",
1064 _dl_symbol_tables, NULL, ELF_RTYPE_CLASS_PLT, NULL);
1066 #if defined(USE_TLS) && USE_TLS
1067 /* Find the real functions and make ldso functions use them from now on */
1068 _dl_calloc_function = (void* (*)(size_t, size_t)) (intptr_t)
1069 _dl_find_hash(__C_SYMBOL_PREFIX__ "calloc", _dl_symbol_tables, NULL, ELF_RTYPE_CLASS_PLT, NULL);
1071 _dl_realloc_function = (void* (*)(void *, size_t)) (intptr_t)
1072 _dl_find_hash(__C_SYMBOL_PREFIX__ "realloc", _dl_symbol_tables, NULL, ELF_RTYPE_CLASS_PLT, NULL);
1074 _dl_free_function = (void (*)(void *)) (intptr_t)
1075 _dl_find_hash(__C_SYMBOL_PREFIX__ "free", _dl_symbol_tables, NULL, ELF_RTYPE_CLASS_PLT, NULL);
1077 _dl_memalign_function = (void* (*)(size_t, size_t)) (intptr_t)
1078 _dl_find_hash(__C_SYMBOL_PREFIX__ "memalign", _dl_symbol_tables, NULL, ELF_RTYPE_CLASS_PLT, NULL);
1082 /* Notify the debugger that all objects are now mapped in. */
1083 _dl_debug_addr->r_state = RT_CONSISTENT;
1087 #include "dl-hash.c"