OSDN Git Service

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