OSDN Git Service

b056f8af277bf568d6e4bb2b97cae5eb6ec04b4a
[uclinux-h8/uClibc.git] / ldso / ldso / ldso.c
1 /* vi: set sw=4 ts=4: */
2 /*
3  * Program to load an ELF binary on a linux system, and run it
4  * after resolving ELF shared library symbols
5  *
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
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
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.
19  *
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
30  * SUCH DAMAGE.
31  */
32
33 #include "ldso.h"
34 #include "unsecvars.h"
35
36 /* Pull in common debug code */
37 #include "dl-debug.c"
38
39 #define ALLOW_ZERO_PLTGOT
40
41 #if defined(USE_TLS) && USE_TLS
42 #include "dl-tls.c"
43 #endif
44
45 /* Pull in the value of _dl_progname */
46 #include LDSO_ELFINTERP
47
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 */
52 #endif
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;
59
60 #ifdef __LDSO_PRELINK_SUPPORT__
61 char *_dl_trace_prelink                      = NULL;    /* Library for prelinking trace */
62 struct elf_resolve *_dl_trace_prelink_map    = NULL;    /* Library module for prelinking trace */
63 bool _dl_verbose                                = true;                                 /* On by default */
64 bool prelinked                                  = false;
65 #endif
66 static int _dl_secure = 1; /* Are we dealing with setuid stuff? */
67
68 #ifdef __SUPPORT_LD_DEBUG__
69 char *_dl_debug           = NULL;
70 char *_dl_debug_symbols   = NULL;
71 char *_dl_debug_move      = NULL;
72 char *_dl_debug_reloc     = NULL;
73 char *_dl_debug_detail    = NULL;
74 char *_dl_debug_nofixups  = NULL;
75 char *_dl_debug_bindings  = NULL;
76 int   _dl_debug_file      = 2;
77 #endif
78
79 #if defined (__LDSO_STANDALONE_SUPPORT__) && defined (__sh__)
80 /* Not hidden, needed for standalone execution. */
81 /*
82  * FIXME: align dl_start for SH to other archs so that we can keep this symbol
83  *        hidden and we don't need to handle in __uClibc_main
84  */
85
86 unsigned long _dl_skip_args = 0;
87 #else
88 unsigned long attribute_hidden _dl_skip_args = 0;
89 #endif
90
91 const char *_dl_progname = UCLIBC_LDSO;      /* The name of the executable being run */
92 #include "dl-startup.c"
93 #include "dl-symbols.c"
94 #include "dl-array.c"
95
96 /*
97  * This stub function is used by some debuggers.  The idea is that they
98  * can set an internal breakpoint on it, so that we are notified when the
99  * address mapping is changed in some way.
100  */
101 void _dl_debug_state(void);
102 rtld_hidden_proto(_dl_debug_state, noinline);
103 void _dl_debug_state(void)
104 {
105         /* Make sure GCC doesn't recognize this function as pure, to avoid
106          * having the calls optimized away.
107          */
108         __asm__("");
109 }
110 rtld_hidden_def(_dl_debug_state);
111
112 static unsigned char *_dl_malloc_addr = NULL;   /* Lets _dl_malloc use the already allocated memory page */
113 static unsigned char *_dl_mmap_zero   = NULL;   /* Also used by _dl_malloc */
114
115 static struct elf_resolve **init_fini_list;
116 static struct elf_resolve **scope_elem_list;
117 static unsigned int nlist; /* # items in init_fini_list */
118 extern void _start(void);
119
120 #ifdef __UCLIBC_HAS_SSP__
121 # include <dl-osinfo.h>
122 uintptr_t stack_chk_guard;
123 # ifndef THREAD_SET_STACK_GUARD
124 /* Only exported for architectures that don't store the stack guard canary
125  * in local thread area.  */
126 uintptr_t __stack_chk_guard attribute_relro;
127 #  ifdef __UCLIBC_HAS_SSP_COMPAT__
128 strong_alias(__stack_chk_guard,__guard)
129 #  endif
130 # elif __UCLIBC_HAS_SSP_COMPAT__
131 uintptr_t __guard attribute_relro;
132 # endif
133 #endif
134
135 char *_dl_getenv(const char *symbol, char **envp)
136 {
137         char *pnt;
138         const char *pnt1;
139
140         while ((pnt = *envp++)) {
141                 pnt1 = symbol;
142                 while (*pnt && *pnt == *pnt1)
143                         pnt1++, pnt++;
144                 if (!*pnt || *pnt != '=' || *pnt1)
145                         continue;
146                 return pnt + 1;
147         }
148         return 0;
149 }
150
151 void _dl_unsetenv(const char *symbol, char **envp)
152 {
153         char *pnt;
154         const char *pnt1;
155         char **newenvp = envp;
156
157         for (pnt = *envp; pnt; pnt = *++envp) {
158                 pnt1 = symbol;
159                 while (*pnt && *pnt == *pnt1)
160                         pnt1++, pnt++;
161                 if (!*pnt || *pnt != '=' || *pnt1)
162                         *newenvp++ = *envp;
163         }
164         *newenvp++ = *envp;
165         return;
166 }
167
168 static int _dl_suid_ok(void)
169 {
170         __kernel_uid_t uid, euid;
171         __kernel_gid_t gid, egid;
172
173         uid = _dl_getuid();
174         euid = _dl_geteuid();
175         gid = _dl_getgid();
176         egid = _dl_getegid();
177
178         if (uid == euid && gid == egid) {
179                 return 1;
180         }
181         return 0;
182 }
183
184 void *_dl_malloc(size_t size)
185 {
186         void *retval;
187
188 #if 0
189         _dl_debug_early("request for %d bytes\n", size);
190 #endif
191
192         if (_dl_malloc_function)
193                 return (*_dl_malloc_function) (size);
194
195         if (_dl_malloc_addr - _dl_mmap_zero + size > _dl_pagesize) {
196                 size_t rounded_size;
197
198                 /* Since the above assumes we get a full page even if
199                    we request less than that, make sure we request a
200                    full page, since uClinux may give us less than than
201                    a full page.  We might round even
202                    larger-than-a-page sizes, but we end up never
203                    reusing _dl_mmap_zero/_dl_malloc_addr in that case,
204                    so we don't do it.
205
206                    The actual page size doesn't really matter; as long
207                    as we're self-consistent here, we're safe.  */
208                 if (size < _dl_pagesize)
209                         rounded_size = (size + ADDR_ALIGN) & _dl_pagesize;
210                 else
211                         rounded_size = size;
212
213                 _dl_debug_early("mmapping more memory\n");
214                 _dl_mmap_zero = _dl_malloc_addr = _dl_mmap((void *) 0, rounded_size,
215                                 PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_UNINITIALIZE, -1, 0);
216                 if (_dl_mmap_check_error(_dl_mmap_zero)) {
217                         _dl_dprintf(_dl_debug_file, "%s: mmap of a spare page failed!\n", _dl_progname);
218                         _dl_exit(20);
219                 }
220         }
221         retval = _dl_malloc_addr;
222         _dl_malloc_addr += size;
223
224         /*
225          * Align memory to DL_MALLOC_ALIGN byte boundary.  Some
226          * platforms require this, others simply get better
227          * performance.
228          */
229         _dl_malloc_addr = (unsigned char *) (((unsigned long) _dl_malloc_addr + DL_MALLOC_ALIGN - 1) & ~(DL_MALLOC_ALIGN - 1));
230         return retval;
231 }
232
233 static void *_dl_zalloc(size_t size)
234 {
235         void *p = _dl_malloc(size);
236         if (p)
237                 _dl_memset(p, 0, size);
238         return p;
239 }
240
241 void _dl_free(void *p)
242 {
243         if (_dl_free_function)
244                 (*_dl_free_function) (p);
245 }
246
247 #if defined(USE_TLS) && USE_TLS
248 void *_dl_memalign(size_t __boundary, size_t __size)
249 {
250         void *result;
251         int i = 0;
252         size_t delta;
253         size_t rounded = 0;
254
255         if (_dl_memalign_function)
256                 return (*_dl_memalign_function) (__boundary, __size);
257
258         while (rounded < __boundary) {
259                 rounded = (1 << i++);
260         }
261
262         delta = (((size_t) _dl_malloc_addr + __size) & (rounded - 1));
263
264         if ((result = _dl_malloc(rounded - delta)) == NULL)
265                 return result;
266
267         result = _dl_malloc(__size);
268
269         return result;
270 }
271 #endif
272
273 static void __attribute__ ((destructor)) __attribute_used__ _dl_fini(void)
274 {
275         unsigned int i;
276         struct elf_resolve * tpnt;
277
278         for (i = 0; i < nlist; ++i) {
279                 tpnt = init_fini_list[i];
280                 if (tpnt->init_flag & FINI_FUNCS_CALLED)
281                         continue;
282                 tpnt->init_flag |= FINI_FUNCS_CALLED;
283                 _dl_run_fini_array(tpnt);
284                 if (tpnt->dynamic_info[DT_FINI]) {
285                         void (*dl_elf_func) (void);
286
287                         dl_elf_func = (void (*)(void)) (intptr_t) DL_RELOC_ADDR(tpnt->loadaddr, tpnt->dynamic_info[DT_FINI]);
288                         _dl_if_debug_dprint("\ncalling FINI: %s\n\n", tpnt->libname);
289                         DL_CALL_FUNC_AT_ADDR (dl_elf_func, tpnt->loadaddr, (void(*)(void)));
290                 }
291         }
292 }
293
294 #ifdef __LDSO_PRELINK_SUPPORT__
295 static void trace_objects(struct elf_resolve *tpnt, char *str_name)
296 {
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));
303         } else {
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));
307         }
308
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);
312         else
313                 _dl_dprintf (1, "\n");
314 }
315 #endif
316
317 static struct elf_resolve * add_ldso(struct elf_resolve *tpnt,
318                                                                          DL_LOADADDR_TYPE load_addr,
319                                                                          ElfW(auxv_t) auxvt[AT_EGID + 1],
320                                                                          struct dyn_elf *rpnt)
321 {
322                 ElfW(Ehdr) *epnt = (ElfW(Ehdr) *) auxvt[AT_BASE].a_un.a_val;
323                 ElfW(Phdr) *myppnt = (ElfW(Phdr) *)
324                                                                 DL_RELOC_ADDR(load_addr, epnt->e_phoff);
325                 int j;
326                 struct stat st;
327
328                 tpnt = _dl_add_elf_hash_table(tpnt->libname, tpnt->loadaddr,
329                                               tpnt->dynamic_info, (unsigned long)tpnt->dynamic_addr,
330                                               0);
331
332                 if (_dl_stat(tpnt->libname, &st) >= 0) {
333                         tpnt->st_dev = st.st_dev;
334                         tpnt->st_ino = st.st_ino;
335                 }
336                 tpnt->n_phent = epnt->e_phnum;
337                 tpnt->ppnt = myppnt;
338                 for (j = 0; j < epnt->e_phnum; j++, myppnt++) {
339                         if (myppnt->p_type ==  PT_GNU_RELRO) {
340                                 tpnt->relro_addr = myppnt->p_vaddr;
341                                 tpnt->relro_size = myppnt->p_memsz;
342                                 break;
343                         }
344                 }
345                 tpnt->libtype = program_interpreter;
346                 if (rpnt) {
347                         rpnt->next = _dl_zalloc(sizeof(struct dyn_elf));
348                         rpnt->next->prev = rpnt;
349                         rpnt = rpnt->next;
350                 } else {
351                         rpnt = _dl_zalloc(sizeof(struct dyn_elf));
352                 }
353                 rpnt->dyn = tpnt;
354                 tpnt->rtld_flags = RTLD_NOW | RTLD_GLOBAL; /* Must not be LAZY */
355
356         return tpnt;
357 }
358
359 static ptrdiff_t _dl_build_local_scope (struct elf_resolve **list,
360                                                                                 struct elf_resolve *map)
361 {
362         struct elf_resolve **p = list;
363         struct init_fini_list *q;
364
365         *p++ = map;
366         map->init_flag |= DL_RESERVED;
367         if (map->init_fini)
368                 for (q = map->init_fini; q; q = q->next)
369                         if (! (q->tpnt->init_flag & DL_RESERVED))
370                                 p += _dl_build_local_scope (p, q->tpnt);
371         return p - list;
372 }
373
374 void *_dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr,
375                           ElfW(auxv_t) auxvt[AT_EGID + 1], char **envp, char **argv
376                           DL_GET_READY_TO_RUN_EXTRA_PARMS)
377 {
378         ElfW(Addr) app_mapaddr = 0;
379         ElfW(Phdr) *ppnt;
380         ElfW(Dyn) *dpnt;
381         char *lpntstr;
382         unsigned int i, cnt, k, nscope_elem;
383         int unlazy = 0, trace_loaded_objects = 0;
384         struct dyn_elf *rpnt;
385         struct elf_resolve *tcurr;
386         struct elf_resolve *tpnt1;
387         struct elf_resolve *ldso_tpnt = NULL;
388         struct elf_resolve app_tpnt_tmp;
389         struct elf_resolve *app_tpnt = &app_tpnt_tmp;
390         struct r_debug *debug_addr;
391         unsigned long *lpnt;
392         unsigned long *_dl_envp;                /* The environment address */
393         ElfW(Addr) relro_addr = 0;
394         size_t relro_size = 0;
395         struct r_scope_elem *global_scope;
396         struct elf_resolve **local_scope;
397
398 #if defined(USE_TLS) && USE_TLS
399         void *tcbp = NULL;
400 #endif
401
402         /* Wahoo!!! We managed to make a function call!  Get malloc
403          * setup so we can use _dl_dprintf() to print debug noise
404          * instead of the SEND_STDERR macros used in dl-startup.c */
405
406         _dl_memset(app_tpnt, 0, sizeof(*app_tpnt));
407
408         /* Store the page size for later use */
409         _dl_pagesize = (auxvt[AT_PAGESZ].a_un.a_val) ? (size_t) auxvt[AT_PAGESZ].a_un.a_val : PAGE_SIZE;
410         /* Make it so _dl_malloc can use the page of memory we have already
411          * allocated.  We shouldn't need to grab any more memory.  This must
412          * be first since things like _dl_dprintf() use _dl_malloc()...
413          */
414         _dl_malloc_addr = (unsigned char *)_dl_pagesize;
415         _dl_mmap_zero = 0;
416
417         /* Wahoo!!! */
418         _dl_debug_early("Cool, ldso survived making function calls\n");
419
420         /* Now we have done the mandatory linking of some things.  We are now
421          * free to start using global variables, since these things have all
422          * been fixed up by now.  Still no function calls outside of this
423          * library, since the dynamic resolver is not yet ready.
424          */
425         if (argv[0]) {
426                 _dl_progname = argv[0];
427         }
428
429 #ifndef __LDSO_STANDALONE_SUPPORT__
430         if (_start == (void *) auxvt[AT_ENTRY].a_un.a_val) {
431                 _dl_dprintf(_dl_debug_file, "Standalone execution is not enabled\n");
432                 _dl_exit(1);
433         }
434 #endif
435
436         /* Start to build the tables of the modules that are required for
437          * this beast to run.  We start with the basic executable, and then
438          * go from there.  Eventually we will run across ourself, and we
439          * will need to properly deal with that as well.
440          */
441         rpnt = NULL;
442         if (_dl_getenv("LD_BIND_NOW", envp))
443                 unlazy = RTLD_NOW;
444
445         /* Now we need to figure out what kind of options are selected.
446          * Note that for SUID programs we ignore the settings in
447          * LD_LIBRARY_PATH.
448          */
449         if ((auxvt[AT_UID].a_un.a_val == (size_t)-1 && _dl_suid_ok()) ||
450             (auxvt[AT_UID].a_un.a_val != (size_t)-1 &&
451              auxvt[AT_UID].a_un.a_val == auxvt[AT_EUID].a_un.a_val &&
452              auxvt[AT_GID].a_un.a_val == auxvt[AT_EGID].a_un.a_val)) {
453                 _dl_secure = 0;
454 #ifdef __LDSO_PRELOAD_ENV_SUPPORT__
455                 _dl_preload = _dl_getenv("LD_PRELOAD", envp);
456 #endif
457                 _dl_library_path = _dl_getenv("LD_LIBRARY_PATH", envp);
458         } else {
459                 static const char unsecure_envvars[] =
460 #ifdef EXTRA_UNSECURE_ENVVARS
461                         EXTRA_UNSECURE_ENVVARS
462 #endif
463                         UNSECURE_ENVVARS;
464                 const char *nextp;
465                 _dl_secure = 1;
466
467                 nextp = unsecure_envvars;
468                 do {
469                         _dl_unsetenv (nextp, envp);
470                         /* We could use rawmemchr but this need not be fast.  */
471                         nextp = _dl_strchr(nextp, '\0') + 1;
472                 } while (*nextp != '\0');
473 #ifdef __LDSO_PRELOAD_ENV_SUPPORT__
474                 _dl_preload = NULL;
475 #endif
476                 _dl_library_path = NULL;
477                 /* SUID binaries can be exploited if they do LAZY relocation. */
478                 unlazy = RTLD_NOW;
479         }
480
481 #if defined(USE_TLS) && USE_TLS
482         _dl_error_catch_tsd = &_dl_initial_error_catch_tsd;
483         _dl_init_static_tls = &_dl_nothread_init_static_tls;
484 #endif
485
486 #ifdef __LDSO_STANDALONE_SUPPORT__
487         if (_start == (void *) auxvt[AT_ENTRY].a_un.a_val) {
488                 char *ptmp;
489                 unsigned int *aux_dat = (unsigned int *) argv;
490                 int argc = aux_dat[-1];
491
492                 tpnt->libname = argv[0];
493                 while (argc > 1)
494                         if (! _dl_strcmp (argv[1], "--library-path") && argc > 2) {
495                                 _dl_library_path = argv[2];
496                                 _dl_skip_args += 2;
497                                 argc -= 2;
498                                 argv += 2;
499                         } else
500                                 break;
501
502         /*
503          * If we have no further argument the program was called incorrectly.
504          * Grant the user some education.
505          */
506
507                 if (argc < 2) {
508                         _dl_dprintf(1, "\
509 Usage: ld.so [OPTION]... EXECUTABLE-FILE [ARGS-FOR-PROGRAM...]\n\
510 You have invoked `ld.so', the helper program for shared library executables.\n\
511 This program usually lives in the file `/lib/ld.so', and special directives\n\
512 in executable files using ELF shared libraries tell the system's program\n\
513 loader to load the helper program from this file.  This helper program loads\n\
514 the shared libraries needed by the program executable, prepares the program\n\
515 to run, and runs it.  You may invoke this helper program directly from the\n\
516 command line to load and run an ELF executable file; this is like executing\n\
517 that file itself, but always uses this helper program from the file you\n\
518 specified, instead of the helper program file specified in the executable\n\
519 file you run.  This is mostly of use for maintainers to test new versions\n\
520 of this helper program; chances are you did not intend to run this program.\n\
521 \n\
522   --library-path PATH   use given PATH instead of content of the environment\n\
523                         variable LD_LIBRARY_PATH\n");
524                         _dl_exit(1);
525                 }
526
527                 ++_dl_skip_args;
528                 ++argv;
529                 _dl_progname = argv[0];
530
531                 _dl_symbol_tables = rpnt = _dl_zalloc(sizeof(struct dyn_elf));
532                 /*
533                  * It needs to load the _dl_progname and to map it
534                  * Usually it is the main application launched by means of the ld.so
535                  * but it could be also a shared object (when ld.so used for tracing)
536                  * We keep the misleading app_tpnt name to avoid variable pollution
537                  */
538                 app_tpnt = _dl_load_elf_shared_library(_dl_secure, &rpnt, _dl_progname);
539                 if (!app_tpnt) {
540                         _dl_dprintf(_dl_debug_file, "can't load '%s'\n", _dl_progname);
541                         _dl_exit(16);
542                 }
543                 /*
544                  * FIXME: it needs to properly handle a PIE executable
545                  * Usually for a main application, loadaddr is computed as difference
546                  * between auxvt entry points and phdr, so if it is not 0, that it is a
547                  * PIE executable. In this case instead we need to set the loadaddr to 0
548                  * because we are actually mapping the ELF for the main application by
549                  * ourselves. So the PIE case must be checked.
550                  */
551
552                 app_tpnt->rtld_flags = unlazy | RTLD_GLOBAL;
553
554                 if (app_tpnt->libtype == elf_executable)
555                         app_tpnt->loadaddr = 0;
556
557                 /*
558                  * This is used by gdb to locate the chain of shared libraries that are
559                  * currently loaded.
560                  */
561                 debug_addr = _dl_zalloc(sizeof(struct r_debug));
562                 ppnt = (ElfW(Phdr) *)app_tpnt->ppnt;
563                 for (i = 0; i < app_tpnt->n_phent; i++, ppnt++) {
564                         if (ppnt->p_type == PT_DYNAMIC) {
565                                 dpnt = (ElfW(Dyn) *) DL_RELOC_ADDR(app_tpnt->loadaddr, ppnt->p_vaddr);
566                                 _dl_parse_dynamic_info(dpnt, app_tpnt->dynamic_info, debug_addr, app_tpnt->loadaddr);
567                         }
568                 }
569
570                 /* Store the path where the shared lib loader was found
571                  * for later use
572                  */
573                 _dl_ldsopath = _dl_strdup(tpnt->libname);
574                 ptmp = _dl_strrchr(_dl_ldsopath, '/');
575                 if (ptmp != _dl_ldsopath)
576                         *ptmp = '\0';
577
578                 _dl_debug_early("Lib Loader: (%x) %s\n", (unsigned) DL_LOADADDR_BASE(tpnt->loadaddr), tpnt->libname);
579         } else {
580 #endif
581
582         /* At this point we are now free to examine the user application,
583          * and figure out which libraries are supposed to be called.  Until
584          * we have this list, we will not be completely ready for dynamic
585          * linking.
586          */
587
588         /* Find the runtime load address of the main executable.  This may be
589          * different from what the ELF header says for ET_DYN/PIE executables.
590          */
591         {
592                 unsigned int idx;
593                 ElfW(Phdr) *phdr = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_val;
594
595                 for (idx = 0; idx < auxvt[AT_PHNUM].a_un.a_val; idx++, phdr++)
596                         if (phdr->p_type == PT_PHDR) {
597                                 DL_INIT_LOADADDR_PROG(app_tpnt->loadaddr, auxvt[AT_PHDR].a_un.a_val - phdr->p_vaddr);
598                                 break;
599                         }
600
601                 if (DL_LOADADDR_BASE(app_tpnt->loadaddr))
602                         _dl_debug_early("Position Independent Executable: "
603                                         "app_tpnt->loadaddr=%x\n", DL_LOADADDR_BASE(app_tpnt->loadaddr));
604         }
605
606         /*
607          * This is used by gdb to locate the chain of shared libraries that are
608          * currently loaded.
609          */
610         debug_addr = _dl_zalloc(sizeof(struct r_debug));
611
612         ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_val;
613         for (i = 0; i < auxvt[AT_PHNUM].a_un.a_val; i++, ppnt++) {
614                 if (ppnt->p_type == PT_GNU_RELRO) {
615                         relro_addr = ppnt->p_vaddr;
616                         relro_size = ppnt->p_memsz;
617                 }
618                 if (!app_mapaddr && (ppnt->p_type == PT_LOAD)) {
619                         app_mapaddr = DL_RELOC_ADDR (app_tpnt->loadaddr, ppnt->p_vaddr);
620                 }
621                 if (ppnt->p_type == PT_DYNAMIC) {
622                         dpnt = (ElfW(Dyn) *) DL_RELOC_ADDR(app_tpnt->loadaddr, ppnt->p_vaddr);
623                         _dl_parse_dynamic_info(dpnt, app_tpnt->dynamic_info, debug_addr, app_tpnt->loadaddr);
624 #ifndef __FORCE_SHAREABLE_TEXT_SEGMENTS__
625                         /* Ugly, ugly.  We need to call mprotect to change the
626                          * protection of the text pages so that we can do the
627                          * dynamic linking.  We can set the protection back
628                          * again once we are done.
629                          */
630                         _dl_debug_early("calling mprotect on the application program\n");
631                         /* Now cover the application program. */
632                         if (app_tpnt->dynamic_info[DT_TEXTREL]) {
633                                 ElfW(Phdr) *ppnt_outer = ppnt;
634                                 ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_val;
635                                 for (i = 0; i < auxvt[AT_PHNUM].a_un.a_val; i++, ppnt++) {
636                                         if (ppnt->p_type == PT_LOAD && !(ppnt->p_flags & PF_W))
637                                                 _dl_mprotect((void *) (DL_RELOC_ADDR(app_tpnt->loadaddr, ppnt->p_vaddr) & PAGE_ALIGN),
638                                                              (DL_RELOC_ADDR(app_tpnt->loadaddr, ppnt->p_vaddr) & ADDR_ALIGN) +
639                                                              (unsigned long) ppnt->p_filesz,
640                                                              PROT_READ | PROT_WRITE | PROT_EXEC);
641                                 }
642                                 ppnt = ppnt_outer;
643                         }
644 #else
645                         if (app_tpnt->dynamic_info[DT_TEXTREL]) {
646                                 _dl_dprintf(_dl_debug_file, "Can't modify application's text section; use the GCC option -fPIE for position-independent executables.\n");
647                                 _dl_exit(1);
648                         }
649 #endif
650
651 #ifndef ALLOW_ZERO_PLTGOT
652                         /* make sure it's really there. */
653                         if (app_tpnt->dynamic_info[DT_PLTGOT] == 0)
654                                 continue;
655 #endif
656                         /* OK, we have what we need - slip this one into the list. */
657                         app_tpnt = _dl_add_elf_hash_table(_dl_progname, app_tpnt->loadaddr,
658                                         app_tpnt->dynamic_info,
659                                         (unsigned long) DL_RELOC_ADDR(app_tpnt->loadaddr, ppnt->p_vaddr),
660                                         ppnt->p_filesz);
661                         _dl_loaded_modules->libtype = elf_executable;
662                         _dl_loaded_modules->ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_val;
663                         _dl_loaded_modules->n_phent = auxvt[AT_PHNUM].a_un.a_val;
664                         _dl_symbol_tables = rpnt = _dl_zalloc(sizeof(struct dyn_elf));
665                         rpnt->dyn = _dl_loaded_modules;
666                         app_tpnt->mapaddr = app_mapaddr;
667                         app_tpnt->rtld_flags = unlazy | RTLD_GLOBAL;
668                         app_tpnt->usage_count++;
669                         lpnt = (unsigned long *) (app_tpnt->dynamic_info[DT_PLTGOT]);
670 #ifdef ALLOW_ZERO_PLTGOT
671                         if (lpnt)
672 #endif
673                                 INIT_GOT(lpnt, _dl_loaded_modules);
674                 }
675
676                 /* OK, fill this in - we did not have this before */
677                 if (ppnt->p_type == PT_INTERP) {
678                         tpnt->libname = (char *) DL_RELOC_ADDR(app_tpnt->loadaddr, ppnt->p_vaddr);
679 #ifdef __LDSO_SEARCH_INTERP_PATH__
680                         {
681                                 char *ptmp;
682                                 /* Store the path where the shared lib loader was found
683                                  * for later use
684                                  */
685                                 _dl_ldsopath = _dl_strdup(tpnt->libname);
686                                 ptmp = _dl_strrchr(_dl_ldsopath, '/');
687                                 if (ptmp != _dl_ldsopath)
688                                         *ptmp = '\0';
689                         }
690                         _dl_debug_early("Lib Loader: (%x) %s\n", (unsigned) DL_LOADADDR_BASE(tpnt->loadaddr), tpnt->libname);
691 #endif
692                 }
693
694                 /* Discover any TLS sections if the target supports them. */
695                 if (ppnt->p_type == PT_TLS) {
696 #if defined(USE_TLS) && USE_TLS
697                         if (ppnt->p_memsz > 0) {
698                                 app_tpnt->l_tls_blocksize = ppnt->p_memsz;
699                                 app_tpnt->l_tls_align = ppnt->p_align;
700                                 if (ppnt->p_align == 0)
701                                         app_tpnt->l_tls_firstbyte_offset = 0;
702                                 else
703                                         app_tpnt->l_tls_firstbyte_offset =
704                                                 (ppnt->p_vaddr & (ppnt->p_align - 1));
705                                 app_tpnt->l_tls_initimage_size = ppnt->p_filesz;
706                                 app_tpnt->l_tls_initimage = (void *) ppnt->p_vaddr;
707
708                                 /* This image gets the ID one.  */
709                                 _dl_tls_max_dtv_idx = app_tpnt->l_tls_modid = 1;
710
711                         }
712                         _dl_debug_early("Found TLS header for appplication program\n");
713                         break;
714 #else
715                         _dl_dprintf(_dl_debug_file, "Program uses unsupported TLS data!\n");
716                         _dl_exit(1);
717 #endif
718                 }
719         }
720         app_tpnt->relro_addr = relro_addr;
721         app_tpnt->relro_size = relro_size;
722
723 #if defined(USE_TLS) && USE_TLS
724         /*
725          * Adjust the address of the TLS initialization image in
726          * case the executable is actually an ET_DYN object.
727          */
728         if (app_tpnt->l_tls_initimage != NULL) {
729                 unsigned int tmp = (unsigned int) app_tpnt->l_tls_initimage;
730                 app_tpnt->l_tls_initimage =
731                         (char *) app_tpnt->l_tls_initimage + app_tpnt->loadaddr;
732                 _dl_debug_early("Relocated TLS initial image from %x to %x (size = %x)\n",
733                         tmp, app_tpnt->l_tls_initimage, app_tpnt->l_tls_initimage_size);
734         }
735 #endif
736
737 #ifdef __LDSO_STANDALONE_SUPPORT__
738         } /* ! ldso standalone mode */
739 #endif
740
741 #ifdef __SUPPORT_LD_DEBUG__
742         _dl_debug = _dl_getenv("LD_DEBUG", envp);
743         if (_dl_debug) {
744                 if (_dl_strstr(_dl_debug, "all")) {
745                         _dl_debug_detail = _dl_debug_move = _dl_debug_symbols
746                                 = _dl_debug_reloc = _dl_debug_bindings = _dl_debug_nofixups = (void*)1;
747                 } else {
748                         _dl_debug_detail   = _dl_strstr(_dl_debug, "detail");
749                         _dl_debug_move     = _dl_strstr(_dl_debug, "move");
750                         _dl_debug_symbols  = _dl_strstr(_dl_debug, "sym");
751                         _dl_debug_reloc    = _dl_strstr(_dl_debug, "reloc");
752                         _dl_debug_nofixups = _dl_strstr(_dl_debug, "nofix");
753                         _dl_debug_bindings = _dl_strstr(_dl_debug, "bind");
754                 }
755         }
756
757         {
758                 const char *dl_debug_output;
759
760                 dl_debug_output = _dl_getenv("LD_DEBUG_OUTPUT", envp);
761
762                 if (dl_debug_output) {
763                         char tmp[22], *tmp1, *filename;
764                         int len1, len2;
765
766                         _dl_memset(tmp, 0, sizeof(tmp));
767                         tmp1 = _dl_simple_ltoa( tmp, (unsigned long)_dl_getpid());
768
769                         len1 = _dl_strlen(dl_debug_output);
770                         len2 = _dl_strlen(tmp1);
771
772                         filename = _dl_malloc(len1 + len2 + 2);
773
774                         if (filename) {
775                                 _dl_strcpy (filename, dl_debug_output);
776                                 filename[len1] = '.';
777                                 _dl_strcpy (&filename[len1+1], tmp1);
778
779                                 _dl_debug_file = _dl_open(filename, O_WRONLY|O_CREAT, 0644);
780                                 if (_dl_debug_file < 0) {
781                                         _dl_debug_file = 2;
782                                         _dl_dprintf(_dl_debug_file, "can't open file: '%s'\n",filename);
783                                 }
784                         }
785                 }
786         }
787 #endif
788
789 #ifdef __LDSO_PRELINK_SUPPORT__
790 {
791         char *ld_warn = _dl_getenv ("LD_WARN", envp);
792
793         if (ld_warn && *ld_warn == '\0')
794                 _dl_verbose = false;
795 }
796         _dl_trace_prelink = _dl_getenv("LD_TRACE_PRELINKING", envp);
797 #endif
798
799         if (_dl_getenv("LD_TRACE_LOADED_OBJECTS", envp) != NULL) {
800                 trace_loaded_objects++;
801         }
802
803 #ifndef __LDSO_LDD_SUPPORT__
804         if (trace_loaded_objects) {
805                 _dl_dprintf(_dl_debug_file, "Use the ldd provided by uClibc\n");
806                 _dl_exit(1);
807         }
808 #endif
809
810         /*
811          * OK, fix one more thing - set up debug_addr so it will point
812          * to our chain.  Later we may need to fill in more fields, but this
813          * should be enough for now.
814          */
815         debug_addr->r_map = (struct link_map *) _dl_loaded_modules;
816         debug_addr->r_version = 1;
817         debug_addr->r_ldbase = (ElfW(Addr)) DL_LOADADDR_BASE(load_addr);
818         debug_addr->r_brk = (unsigned long) &_dl_debug_state;
819         _dl_debug_addr = debug_addr;
820
821         /* Do not notify the debugger until the interpreter is in the list */
822
823         /* OK, we now have the application in the list, and we have some
824          * basic stuff in place.  Now search through the list for other shared
825          * libraries that should be loaded, and insert them on the list in the
826          * correct order.
827          */
828
829         _dl_map_cache();
830
831 #ifdef __LDSO_PRELOAD_ENV_SUPPORT__
832         if (_dl_preload) {
833                 char c, *str, *str2;
834
835                 str = _dl_preload;
836                 while (*str == ':' || *str == ' ' || *str == '\t')
837                         str++;
838
839                 while (*str) {
840                         str2 = str;
841                         while (*str2 && *str2 != ':' && *str2 != ' ' && *str2 != '\t')
842                                 str2++;
843                         c = *str2;
844                         *str2 = '\0';
845
846                         if (!_dl_secure || _dl_strchr(str, '/') == NULL) {
847                                 _dl_if_debug_dprint("\tfile='%s';  needed by '%s'\n", str, _dl_progname);
848
849                                 tpnt1 = _dl_load_shared_library(_dl_secure, &rpnt, NULL, str, trace_loaded_objects);
850                                 if (!tpnt1) {
851 #ifdef __LDSO_LDD_SUPPORT__
852                                         if (trace_loaded_objects || _dl_trace_prelink)
853                                                 _dl_dprintf(1, "\t%s => not found\n", str);
854                                         else
855 #endif
856                                         {
857                                                 _dl_dprintf(_dl_debug_file, "%s: can't load " "library '%s'\n", _dl_progname, str);
858                                                 _dl_exit(15);
859                                         }
860                                 } else {
861                                         tpnt1->rtld_flags = unlazy | RTLD_GLOBAL;
862
863                                         _dl_debug_early("Loading: (%x) %s\n", DL_LOADADDR_BASE(tpnt1->loadaddr), tpnt1->libname);
864
865 #ifdef __LDSO_LDD_SUPPORT__
866                                         if (trace_loaded_objects && !_dl_trace_prelink &&
867                                             tpnt1->usage_count == 1) {
868                                                 /* This is a real hack to make
869                                                  * ldd not print the library
870                                                  * itself when run on a
871                                                  * library.
872                                                  */
873                                                 if (_dl_strcmp(_dl_progname, str) != 0)
874                                                         _dl_dprintf(1, "\t%s => %s (%x)\n", str, tpnt1->libname,
875                                                                     DL_LOADADDR_BASE(tpnt1->loadaddr));
876                                         }
877 #endif
878                                 }
879                         }
880
881                         *str2 = c;
882                         str = str2;
883                         while (*str == ':' || *str == ' ' || *str == '\t')
884                                 str++;
885                 }
886         }
887 #endif /* __LDSO_PRELOAD_ENV_SUPPORT__ */
888
889 #ifdef __LDSO_PRELOAD_FILE_SUPPORT__
890         do {
891                 char *preload;
892                 int fd;
893                 char c, *cp, *cp2;
894
895                 if (_dl_stat(LDSO_PRELOAD, &st) || st.st_size == 0) {
896                         break;
897                 }
898
899                 if ((fd = _dl_open(LDSO_PRELOAD, O_RDONLY, 0)) < 0) {
900                         _dl_dprintf(_dl_debug_file, "%s: can't open file '%s'\n",
901                                     _dl_progname, LDSO_PRELOAD);
902                         break;
903                 }
904
905                 preload = (caddr_t) _dl_mmap(0, st.st_size + 1,
906                                              PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
907                 _dl_close(fd);
908                 if (preload == (caddr_t) -1) {
909                         _dl_dprintf(_dl_debug_file, "%s:%i: can't map '%s'\n",
910                                     _dl_progname, __LINE__, LDSO_PRELOAD);
911                         break;
912                 }
913
914                 /* convert all separators and comments to spaces */
915                 for (cp = preload; *cp; /*nada */ ) {
916                         if (*cp == ':' || *cp == '\t' || *cp == '\n') {
917                                 *cp++ = ' ';
918                         } else if (*cp == '#') {
919                                 do {
920                                         *cp++ = ' ';
921                                 } while (*cp != '\n' && *cp != '\0');
922                         } else {
923                                 cp++;
924                         }
925                 }
926
927                 /* find start of first library */
928                 for (cp = preload; *cp && *cp == ' '; cp++)
929                         /*nada */ ;
930
931                 while (*cp) {
932                         /* find end of library */
933                         for (cp2 = cp; *cp && *cp != ' '; cp++)
934                                 /*nada */ ;
935                         c = *cp;
936                         *cp = '\0';
937
938                         _dl_if_debug_dprint("\tfile='%s';  needed by '%s'\n", cp2, _dl_progname);
939
940                         tpnt1 = _dl_load_shared_library(0, &rpnt, NULL, cp2, trace_loaded_objects);
941                         if (!tpnt1) {
942 # ifdef __LDSO_LDD_SUPPORT__
943                                 if (trace_loaded_objects || _dl_trace_prelink)
944                                         _dl_dprintf(1, "\t%s => not found\n", cp2);
945                                 else
946 # endif
947                                 {
948                                         _dl_dprintf(_dl_debug_file, "%s: can't load library '%s'\n", _dl_progname, cp2);
949                                         _dl_exit(15);
950                                 }
951                         } else {
952                                 tpnt1->rtld_flags = unlazy | RTLD_GLOBAL;
953
954                                 _dl_debug_early("Loading: (%x) %s\n", DL_LOADADDR_BASE(tpnt1->loadaddr), tpnt1->libname);
955
956 # ifdef __LDSO_LDD_SUPPORT__
957                                 if (trace_loaded_objects && !_dl_trace_prelink &&
958                                     tpnt1->usage_count == 1) {
959                                         _dl_dprintf(1, "\t%s => %s (%x)\n",
960                                                     cp2, tpnt1->libname,
961                                                     DL_LOADADDR_BASE(tpnt1->loadaddr));
962                                 }
963 # endif
964                         }
965
966                         /* find start of next library */
967                         *cp = c;
968                         for ( /*nada */ ; *cp && *cp == ' '; cp++)
969                                 /*nada */ ;
970                 }
971
972                 _dl_munmap(preload, st.st_size + 1);
973         } while (0);
974 #endif /* __LDSO_PRELOAD_FILE_SUPPORT__ */
975
976         nlist = 0;
977         for (tcurr = _dl_loaded_modules; tcurr; tcurr = tcurr->next) {
978                 ElfW(Dyn) *this_dpnt;
979
980                 nlist++;
981                 for (this_dpnt = (ElfW(Dyn) *) tcurr->dynamic_addr; this_dpnt->d_tag; this_dpnt++) {
982                         if (this_dpnt->d_tag == DT_NEEDED) {
983                                 char *name;
984                                 struct init_fini_list *tmp;
985
986                                 lpntstr = (char*) (tcurr->dynamic_info[DT_STRTAB] + this_dpnt->d_un.d_val);
987                                 name = _dl_get_last_path_component(lpntstr);
988                                 _dl_if_debug_dprint("\tfile='%s';  needed by '%s'\n", lpntstr, _dl_progname);
989
990                                 if (_dl_strcmp(name, UCLIBC_LDSO) == 0) {
991                                                 if (!ldso_tpnt) {
992                                                         /* Insert the ld.so only once */
993                                                         ldso_tpnt = add_ldso(tpnt, load_addr, auxvt, rpnt);
994                                                 }
995                                                 ldso_tpnt->usage_count++;
996                                                 tpnt1 = ldso_tpnt;
997                                 } else
998                                         tpnt1 = _dl_load_shared_library(0, &rpnt, tcurr, lpntstr, trace_loaded_objects);
999
1000                                 if (!tpnt1) {
1001 #ifdef __LDSO_LDD_SUPPORT__
1002                                         if (trace_loaded_objects || _dl_trace_prelink) {
1003                                                 _dl_dprintf(1, "\t%s => not found\n", lpntstr);
1004                                                 continue;
1005                                         } else
1006 #endif
1007                                         {
1008                                                 _dl_dprintf(_dl_debug_file, "%s: can't load library '%s'\n", _dl_progname, lpntstr);
1009                                                 _dl_exit(16);
1010                                         }
1011                                 }
1012
1013                                 tmp = alloca(sizeof(struct init_fini_list)); /* Allocates on stack, no need to free this memory */
1014                                 tmp->tpnt = tpnt1;
1015                                 tmp->next = tcurr->init_fini;
1016                                 tcurr->init_fini = tmp;
1017
1018                                 tpnt1->rtld_flags = unlazy | RTLD_GLOBAL;
1019
1020                                 _dl_debug_early("Loading: (%x) %s\n", DL_LOADADDR_BASE(tpnt1->loadaddr), tpnt1->libname);
1021
1022 #ifdef __LDSO_LDD_SUPPORT__
1023                                 if (trace_loaded_objects && !_dl_trace_prelink &&
1024                                     tpnt1->usage_count == 1) {
1025                                         _dl_dprintf(1, "\t%s => %s (%x)\n",
1026                                                     lpntstr, tpnt1->libname,
1027                                                     DL_LOADADDR_BASE(tpnt1->loadaddr));
1028                                 }
1029 #endif
1030                         }
1031                 }
1032         }
1033         _dl_unmap_cache();
1034
1035         /* Keep track of the number of elements in the global scope */
1036         nscope_elem = nlist;
1037
1038         if (_dl_loaded_modules->libtype == elf_executable) {
1039                 --nlist; /* Exclude the application. */
1040                 tcurr = _dl_loaded_modules->next;
1041         } else
1042                 tcurr = _dl_loaded_modules;
1043         init_fini_list = _dl_malloc(nlist * sizeof(struct elf_resolve *));
1044         i = 0;
1045         for (; tcurr; tcurr = tcurr->next)
1046                 init_fini_list[i++] = tcurr;
1047
1048         /* Sort the INIT/FINI list in dependency order. */
1049         for (tcurr = _dl_loaded_modules->next; tcurr; tcurr = tcurr->next) {
1050                 unsigned int j, k;
1051
1052                 for (j = 0; init_fini_list[j] != tcurr; ++j)
1053                         /* Empty */;
1054                 for (k = j + 1; k < nlist; ++k) {
1055                         struct init_fini_list *runp = init_fini_list[k]->init_fini;
1056
1057                         for (; runp; runp = runp->next) {
1058                                 if (runp->tpnt == tcurr) {
1059                                         struct elf_resolve *here = init_fini_list[k];
1060                                         _dl_if_debug_dprint("Move %s from pos %d to %d in INIT/FINI list\n", here->libname, k, j);
1061                                         for (i = (k - j); i; --i)
1062                                                 init_fini_list[i+j] = init_fini_list[i+j-1];
1063                                         init_fini_list[j] = here;
1064                                         ++j;
1065                                         break;
1066                                 }
1067                         }
1068                 }
1069         }
1070 #ifdef __SUPPORT_LD_DEBUG__
1071         if (_dl_debug) {
1072                 _dl_dprintf(_dl_debug_file, "\nINIT/FINI order and dependencies:\n");
1073                 for (i = 0; i < nlist; i++) {
1074                         struct init_fini_list *tmp;
1075
1076                         _dl_dprintf(_dl_debug_file, "lib: %s has deps:\n",
1077                                     init_fini_list[i]->libname);
1078                         tmp = init_fini_list[i]->init_fini;
1079                         for (; tmp; tmp = tmp->next)
1080                                 _dl_dprintf(_dl_debug_file, " %s ", tmp->tpnt->libname);
1081                         _dl_dprintf(_dl_debug_file, "\n");
1082                 }
1083         }
1084 #endif
1085
1086         /*
1087          * If the program interpreter is not in the module chain, add it.
1088          * This will be required for dlopen to be able to access the internal
1089          * functions in the dynamic linker and to relocate the interpreter
1090          * again once all libs are loaded.
1091          */
1092         if (!ldso_tpnt) {
1093                 tpnt = add_ldso(tpnt, load_addr, auxvt, rpnt);
1094                 tpnt->usage_count++;
1095                 nscope_elem++;
1096         } else
1097                 tpnt = ldso_tpnt;
1098
1099 #ifdef RERELOCATE_LDSO
1100                 /* Only rerelocate functions for now. */
1101                 tpnt->init_flag = RELOCS_DONE;
1102                 lpnt = (unsigned long *) (tpnt->dynamic_info[DT_PLTGOT]);
1103 # ifdef ALLOW_ZERO_PLTGOT
1104                 if (tpnt->dynamic_info[DT_PLTGOT])
1105 # endif
1106                         INIT_GOT(lpnt, tpnt);
1107 #else
1108                 tpnt->init_flag = RELOCS_DONE | JMP_RELOCS_DONE;
1109 #endif
1110                 tpnt = NULL;
1111
1112         /*
1113          * Allocate the global scope array.
1114          */
1115         scope_elem_list = (struct elf_resolve **) _dl_malloc(nscope_elem * sizeof(struct elf_resolve *));
1116
1117         for (i = 0, tcurr = _dl_loaded_modules; tcurr; tcurr = tcurr->next)
1118                 scope_elem_list[i++] = tcurr;
1119
1120         _dl_loaded_modules->symbol_scope.r_list = scope_elem_list;
1121         _dl_loaded_modules->symbol_scope.r_nlist = nscope_elem;
1122         /*
1123          * The symbol scope of the application, that is the first entry of the
1124          * _dl_loaded_modules list, is just the global scope to be used for the
1125          * symbol lookup.
1126          */
1127         global_scope = &_dl_loaded_modules->symbol_scope;
1128
1129         /* Build the local scope for each loaded modules. */
1130         local_scope = _dl_malloc(nscope_elem * sizeof(struct elf_resolve *));
1131         i = 1;
1132         for (tcurr = _dl_loaded_modules->next; tcurr; tcurr = tcurr->next) {
1133                 cnt = _dl_build_local_scope(local_scope, scope_elem_list[i++]);
1134                 tcurr->symbol_scope.r_list = _dl_malloc(cnt * sizeof(struct elf_resolve *));
1135                 tcurr->symbol_scope.r_nlist = cnt;
1136                 _dl_memcpy (tcurr->symbol_scope.r_list, local_scope, cnt * sizeof (struct elf_resolve *));
1137                 /* Restoring the init_flag.*/
1138                 for (k = 1; k < nscope_elem; k++)
1139                         scope_elem_list[k]->init_flag &= ~DL_RESERVED;
1140         }
1141
1142         _dl_free(local_scope);
1143
1144 #ifdef __LDSO_LDD_SUPPORT__
1145         /* Exit if LD_TRACE_LOADED_OBJECTS is on. */
1146         if (trace_loaded_objects && !_dl_trace_prelink)
1147                 _dl_exit(0);
1148 #endif
1149
1150 #if defined(USE_TLS) && USE_TLS
1151         /* We do not initialize any of the TLS functionality unless any of the
1152          * initial modules uses TLS.  This makes dynamic loading of modules with
1153          * TLS impossible, but to support it requires either eagerly doing setup
1154          * now or lazily doing it later.  Doing it now makes us incompatible with
1155          * an old kernel that can't perform TLS_INIT_TP, even if no TLS is ever
1156          * used.  Trying to do it lazily is too hairy to try when there could be
1157          * multiple threads (from a non-TLS-using libpthread).  */
1158         bool was_tls_init_tp_called = tls_init_tp_called;
1159         if (tcbp == NULL) {
1160                 _dl_debug_early("Calling init_tls()!\n");
1161                 tcbp = init_tls ();
1162         }
1163 #endif
1164 #ifdef __UCLIBC_HAS_SSP__
1165         /* Set up the stack checker's canary.  */
1166         stack_chk_guard = _dl_setup_stack_chk_guard ();
1167 # ifdef THREAD_SET_STACK_GUARD
1168         THREAD_SET_STACK_GUARD (stack_chk_guard);
1169 #  ifdef __UCLIBC_HAS_SSP_COMPAT__
1170         __guard = stack_chk_guard;
1171 #  endif
1172 # else
1173         __stack_chk_guard = stack_chk_guard;
1174 # endif
1175 #endif
1176
1177 #ifdef __LDSO_PRELINK_SUPPORT__
1178         if (_dl_trace_prelink) {
1179
1180                 unsigned int nscope_trace = ldso_tpnt ? nscope_elem : (nscope_elem - 1);
1181
1182                 for (i = 0; i < nscope_trace; i++)
1183                         trace_objects(scope_elem_list[i],
1184                                 _dl_get_last_path_component(scope_elem_list[i]->libname));
1185
1186                 if (_dl_verbose)
1187                         /* Warn about undefined symbols. */
1188                         if (_dl_symbol_tables)
1189                                 if (_dl_fixup(_dl_symbol_tables, global_scope, unlazy))
1190                                         _dl_exit(-1);
1191                 _dl_exit(0);
1192         }
1193
1194         if (_dl_loaded_modules->dynamic_info[DT_GNU_LIBLIST_IDX]) {
1195                 ElfW(Lib) *liblist, *liblistend;
1196                 struct elf_resolve **r_list, **r_listend, *l;
1197                 const char *strtab = (const char *)_dl_loaded_modules->dynamic_info[DT_STRTAB];
1198
1199                 _dl_assert (_dl_loaded_modules->dynamic_info[DT_GNU_LIBLISTSZ_IDX] != 0);
1200                 liblist = (ElfW(Lib) *) _dl_loaded_modules->dynamic_info[DT_GNU_LIBLIST_IDX];
1201                 liblistend = (ElfW(Lib) *)
1202                 ((char *) liblist + _dl_loaded_modules->dynamic_info[DT_GNU_LIBLISTSZ_IDX]);
1203                 r_list = _dl_loaded_modules->symbol_scope.r_list;
1204                 r_listend = r_list + nscope_elem;
1205
1206                 for (; r_list < r_listend && liblist < liblistend; r_list++) {
1207                         l = *r_list;
1208
1209                         if (l == _dl_loaded_modules)
1210                                 continue;
1211
1212                         /* If the library is not mapped where it should, fail.  */
1213                         if (l->loadaddr)
1214                                 break;
1215
1216                         /* Next, check if checksum matches.  */
1217                         if (l->dynamic_info[DT_CHECKSUM_IDX] == 0 ||
1218                                 l->dynamic_info[DT_CHECKSUM_IDX] != liblist->l_checksum)
1219                                 break;
1220
1221                         if (l->dynamic_info[DT_GNU_PRELINKED_IDX] == 0 ||
1222                                 (l->dynamic_info[DT_GNU_PRELINKED_IDX] != liblist->l_time_stamp))
1223                                 break;
1224
1225                         if (_dl_strcmp(strtab + liblist->l_name, _dl_get_last_path_component(l->libname)) != 0)
1226                                 break;
1227
1228                         ++liblist;
1229                 }
1230
1231
1232                 if (r_list == r_listend && liblist == liblistend)
1233                         prelinked = true;
1234
1235         }
1236
1237         _dl_debug_early ("\nprelink checking: %s\n", prelinked ? "ok" : "failed");
1238
1239         if (prelinked) {
1240                 if (_dl_loaded_modules->dynamic_info[DT_GNU_CONFLICT_IDX]) {
1241                         ELF_RELOC *conflict;
1242                         unsigned long conflict_size;
1243
1244                         _dl_assert (_dl_loaded_modules->dynamic_info[DT_GNU_CONFLICTSZ_IDX] != 0);
1245                         conflict = (ELF_RELOC *) _dl_loaded_modules->dynamic_info[DT_GNU_CONFLICT_IDX];
1246                         conflict_size = _dl_loaded_modules->dynamic_info[DT_GNU_CONFLICTSZ_IDX];
1247                         _dl_parse_relocation_information(_dl_symbol_tables, global_scope,
1248                                 (unsigned long) conflict, conflict_size);
1249                 }
1250
1251                 /* Mark all the objects so we know they have been already relocated.  */
1252                 for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) {
1253                         tpnt->init_flag |= RELOCS_DONE;
1254                         if (tpnt->relro_size)
1255                                 _dl_protect_relro (tpnt);
1256                 }
1257         } else
1258 #endif
1259
1260         {
1261
1262         _dl_debug_early("Beginning relocation fixups\n");
1263
1264 #ifdef __mips__
1265         /*
1266          * Relocation of the GOT entries for MIPS have to be done
1267          * after all the libraries have been loaded.
1268          */
1269         _dl_perform_mips_global_got_relocations(_dl_loaded_modules, !unlazy);
1270 #endif
1271
1272         /*
1273          * OK, now all of the kids are tucked into bed in their proper
1274          * addresses.  Now we go through and look for REL and RELA records that
1275          * indicate fixups to the GOT tables.  We need to do this in reverse
1276          * order so that COPY directives work correctly.
1277          */
1278         if (_dl_symbol_tables)
1279                 if (_dl_fixup(_dl_symbol_tables, global_scope, unlazy))
1280                         _dl_exit(-1);
1281
1282         for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) {
1283                 if (tpnt->relro_size)
1284                         _dl_protect_relro (tpnt);
1285         }
1286         } /* not prelinked */
1287
1288 #if defined(USE_TLS) && USE_TLS
1289         if (!was_tls_init_tp_called && _dl_tls_max_dtv_idx > 0)
1290                 ++_dl_tls_generation;
1291
1292         _dl_debug_early("Calling _dl_allocate_tls_init()!\n");
1293
1294         /* Now that we have completed relocation, the initializer data
1295            for the TLS blocks has its final values and we can copy them
1296            into the main thread's TLS area, which we allocated above.  */
1297         _dl_allocate_tls_init (tcbp);
1298
1299         /* And finally install it for the main thread.  If ld.so itself uses
1300            TLS we know the thread pointer was initialized earlier.  */
1301         if (! tls_init_tp_called) {
1302                 const char *lossage = (char *) TLS_INIT_TP (tcbp, USE___THREAD);
1303                 if (__builtin_expect (lossage != NULL, 0)) {
1304                         _dl_debug_early("cannot set up thread-local storage: %s\n", lossage);
1305                         _dl_exit(30);
1306                 }
1307         }
1308 #endif /* USE_TLS */
1309
1310         /* OK, at this point things are pretty much ready to run.  Now we need
1311          * to touch up a few items that are required, and then we can let the
1312          * user application have at it.  Note that the dynamic linker itself
1313          * is not guaranteed to be fully dynamicly linked if we are using
1314          * ld.so.1, so we have to look up each symbol individually.
1315          */
1316
1317         _dl_envp = (unsigned long *) (intptr_t) _dl_find_hash(__C_SYMBOL_PREFIX__ "__environ", global_scope, NULL, NULL, 0, NULL);
1318         if (_dl_envp)
1319                 *_dl_envp = (unsigned long) envp;
1320
1321 #ifndef __FORCE_SHAREABLE_TEXT_SEGMENTS__
1322         {
1323                 unsigned int j;
1324                 ElfW(Phdr) *myppnt;
1325
1326                 /* We had to set the protections of all pages to R/W for
1327                  * dynamic linking.  Set text pages back to R/O.
1328                  */
1329                 for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) {
1330                         for (myppnt = tpnt->ppnt, j = 0; j < tpnt->n_phent; j++, myppnt++) {
1331                                 if (myppnt->p_type == PT_LOAD && !(myppnt->p_flags & PF_W) && tpnt->dynamic_info[DT_TEXTREL]) {
1332                                         _dl_mprotect((void *) (DL_RELOC_ADDR(tpnt->loadaddr, myppnt->p_vaddr) & PAGE_ALIGN),
1333                                                         (myppnt->p_vaddr & ADDR_ALIGN) + (unsigned long) myppnt->p_filesz, LXFLAGS(myppnt->p_flags));
1334                                 }
1335                         }
1336                 }
1337
1338         }
1339 #endif
1340         /* Notify the debugger we have added some objects. */
1341         _dl_debug_addr->r_state = RT_ADD;
1342         _dl_debug_state();
1343
1344         /* Run pre-initialization functions for the executable.  */
1345         _dl_run_array_forward(_dl_loaded_modules->dynamic_info[DT_PREINIT_ARRAY],
1346                               _dl_loaded_modules->dynamic_info[DT_PREINIT_ARRAYSZ],
1347                               _dl_loaded_modules->loadaddr);
1348
1349         /* Run initialization functions for loaded objects.  For the
1350            main executable, they will be run from __uClibc_main.  */
1351         for (i = nlist; i; --i) {
1352                 tpnt = init_fini_list[i-1];
1353                 tpnt->init_fini = NULL; /* Clear, since alloca was used */
1354                 if (tpnt->init_flag & INIT_FUNCS_CALLED)
1355                         continue;
1356                 tpnt->init_flag |= INIT_FUNCS_CALLED;
1357
1358                 if (tpnt->dynamic_info[DT_INIT]) {
1359                         void (*dl_elf_func) (void);
1360
1361                         dl_elf_func = (void (*)(void)) DL_RELOC_ADDR(tpnt->loadaddr, tpnt->dynamic_info[DT_INIT]);
1362
1363                         _dl_if_debug_dprint("calling INIT: %s\n\n", tpnt->libname);
1364
1365                         DL_CALL_FUNC_AT_ADDR (dl_elf_func, tpnt->loadaddr, (void(*)(void)));
1366                 }
1367
1368                 _dl_run_init_array(tpnt);
1369         }
1370
1371         /* Find the real malloc function and make ldso functions use that from now on */
1372         _dl_malloc_function = (void* (*)(size_t)) (intptr_t) _dl_find_hash(__C_SYMBOL_PREFIX__ "malloc",
1373                         global_scope, NULL, NULL, ELF_RTYPE_CLASS_PLT, NULL);
1374
1375 #if defined(USE_TLS) && USE_TLS
1376         /* Find the real functions and make ldso functions use them from now on */
1377         _dl_calloc_function = (void* (*)(size_t, size_t)) (intptr_t)
1378                 _dl_find_hash(__C_SYMBOL_PREFIX__ "calloc", global_scope, NULL, NULL, ELF_RTYPE_CLASS_PLT, NULL);
1379
1380         _dl_realloc_function = (void* (*)(void *, size_t)) (intptr_t)
1381                 _dl_find_hash(__C_SYMBOL_PREFIX__ "realloc", global_scope, NULL, NULL, ELF_RTYPE_CLASS_PLT, NULL);
1382
1383         _dl_free_function = (void (*)(void *)) (intptr_t)
1384                 _dl_find_hash(__C_SYMBOL_PREFIX__ "free", global_scope, NULL, NULL, ELF_RTYPE_CLASS_PLT, NULL);
1385
1386         _dl_memalign_function = (void* (*)(size_t, size_t)) (intptr_t)
1387                 _dl_find_hash(__C_SYMBOL_PREFIX__ "memalign", global_scope, NULL, NULL, ELF_RTYPE_CLASS_PLT, NULL);
1388
1389 #endif
1390
1391         /* Notify the debugger that all objects are now mapped in.  */
1392         _dl_debug_addr->r_state = RT_CONSISTENT;
1393         _dl_debug_state();
1394
1395 #ifdef __LDSO_STANDALONE_SUPPORT__
1396         if (_start == (void *) auxvt[AT_ENTRY].a_un.a_val)
1397                 return (void *) app_tpnt->l_entry;
1398         else
1399 #endif
1400                 return (void *) auxvt[AT_ENTRY].a_un.a_val;
1401 }
1402
1403 #include "dl-hash.c"
1404 #include "dl-elf.c"