OSDN Git Service

ldso: fix build with PRELINK enabled and !TLS
[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 static 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 # endif
128 # ifdef __UCLIBC_HAS_SSP_COMPAT__
129 uintptr_t __guard attribute_relro;
130 # endif
131 #endif
132
133 char *_dl_getenv(const char *symbol, char **envp)
134 {
135         char *pnt;
136         const char *pnt1;
137
138         while ((pnt = *envp++)) {
139                 pnt1 = symbol;
140                 while (*pnt && *pnt == *pnt1)
141                         pnt1++, pnt++;
142                 if (!*pnt || *pnt != '=' || *pnt1)
143                         continue;
144                 return pnt + 1;
145         }
146         return 0;
147 }
148
149 void _dl_unsetenv(const char *symbol, char **envp)
150 {
151         char *pnt;
152         const char *pnt1;
153         char **newenvp = envp;
154
155         for (pnt = *envp; pnt; pnt = *++envp) {
156                 pnt1 = symbol;
157                 while (*pnt && *pnt == *pnt1)
158                         pnt1++, pnt++;
159                 if (!*pnt || *pnt != '=' || *pnt1)
160                         *newenvp++ = *envp;
161         }
162         *newenvp++ = *envp;
163         return;
164 }
165
166 static int _dl_suid_ok(void)
167 {
168         __kernel_uid_t uid, euid;
169         __kernel_gid_t gid, egid;
170
171         uid = _dl_getuid();
172         euid = _dl_geteuid();
173         gid = _dl_getgid();
174         egid = _dl_getegid();
175
176         if (uid == euid && gid == egid) {
177                 return 1;
178         }
179         return 0;
180 }
181
182 void *_dl_malloc(size_t size)
183 {
184         void *retval;
185
186 #if 0
187         _dl_debug_early("request for %d bytes\n", size);
188 #endif
189
190         if (_dl_malloc_function)
191                 return (*_dl_malloc_function) (size);
192
193         if (_dl_malloc_addr - _dl_mmap_zero + size > _dl_pagesize) {
194                 size_t rounded_size;
195
196                 /* Since the above assumes we get a full page even if
197                    we request less than that, make sure we request a
198                    full page, since uClinux may give us less than than
199                    a full page.  We might round even
200                    larger-than-a-page sizes, but we end up never
201                    reusing _dl_mmap_zero/_dl_malloc_addr in that case,
202                    so we don't do it.
203
204                    The actual page size doesn't really matter; as long
205                    as we're self-consistent here, we're safe.  */
206                 if (size < _dl_pagesize)
207                         rounded_size = (size + ADDR_ALIGN) & _dl_pagesize;
208                 else
209                         rounded_size = size;
210
211                 _dl_debug_early("mmapping more memory\n");
212                 _dl_mmap_zero = _dl_malloc_addr = _dl_mmap((void *) 0, rounded_size,
213                                 PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_UNINITIALIZE, -1, 0);
214                 if (_dl_mmap_check_error(_dl_mmap_zero)) {
215                         _dl_dprintf(_dl_debug_file, "%s: mmap of a spare page failed!\n", _dl_progname);
216                         _dl_exit(20);
217                 }
218         }
219         retval = _dl_malloc_addr;
220         _dl_malloc_addr += size;
221
222         /*
223          * Align memory to DL_MALLOC_ALIGN byte boundary.  Some
224          * platforms require this, others simply get better
225          * performance.
226          */
227         _dl_malloc_addr = (unsigned char *) (((unsigned long) _dl_malloc_addr + DL_MALLOC_ALIGN - 1) & ~(DL_MALLOC_ALIGN - 1));
228         return retval;
229 }
230
231 static void *_dl_zalloc(size_t size)
232 {
233         void *p = _dl_malloc(size);
234         if (p)
235                 _dl_memset(p, 0, size);
236         return p;
237 }
238
239 void _dl_free(void *p)
240 {
241         if (_dl_free_function)
242                 (*_dl_free_function) (p);
243 }
244
245 #if defined(USE_TLS) && USE_TLS
246 void *_dl_memalign(size_t __boundary, size_t __size)
247 {
248         void *result;
249         int i = 0;
250         size_t delta;
251         size_t rounded = 0;
252
253         if (_dl_memalign_function)
254                 return (*_dl_memalign_function) (__boundary, __size);
255
256         while (rounded < __boundary) {
257                 rounded = (1 << i++);
258         }
259
260         delta = (((size_t) _dl_malloc_addr + __size) & (rounded - 1));
261
262         if ((result = _dl_malloc(rounded - delta)) == NULL)
263                 return result;
264
265         result = _dl_malloc(__size);
266
267         return result;
268 }
269 #endif
270
271 static void __attribute__ ((destructor)) __attribute_used__ _dl_fini(void)
272 {
273         unsigned int i;
274         struct elf_resolve * tpnt;
275
276         for (i = 0; i < nlist; ++i) {
277                 tpnt = init_fini_list[i];
278                 if (tpnt->init_flag & FINI_FUNCS_CALLED)
279                         continue;
280                 tpnt->init_flag |= FINI_FUNCS_CALLED;
281                 _dl_run_fini_array(tpnt);
282                 if (tpnt->dynamic_info[DT_FINI]) {
283                         void (*dl_elf_func) (void);
284
285                         dl_elf_func = (void (*)(void)) (intptr_t) DL_RELOC_ADDR(tpnt->loadaddr, tpnt->dynamic_info[DT_FINI]);
286                         _dl_if_debug_dprint("\ncalling FINI: %s\n\n", tpnt->libname);
287                         DL_CALL_FUNC_AT_ADDR (dl_elf_func, tpnt->loadaddr, (void(*)(void)));
288                 }
289         }
290 }
291
292 #ifdef __LDSO_PRELINK_SUPPORT__
293 static void trace_objects(struct elf_resolve *tpnt, char *str_name)
294 {
295         if (_dl_strcmp(_dl_trace_prelink, tpnt->libname) == 0)
296                 _dl_trace_prelink_map = tpnt;
297         if (tpnt->libtype == elf_executable) {
298 /* Main executeble */
299                 _dl_dprintf(1, "\t%s => %s (%x, %x)", tpnt->libname, tpnt->libname,
300                                         tpnt->mapaddr, DL_LOADADDR_BASE(tpnt->loadaddr));
301         } else {
302 /* Preloaded, Needed or interpreter */
303                 _dl_dprintf(1, "\t%s => %s (%x, %x)", str_name, tpnt->libname,
304                                         tpnt->mapaddr, DL_LOADADDR_BASE(tpnt->loadaddr));
305         }
306
307 #if defined USE_TLS && USE_TLS
308         if ((tpnt->libtype != program_interpreter) && (tpnt->l_tls_modid))
309                 _dl_dprintf (1, " TLS(%x, %x)\n", tpnt->l_tls_modid,
310                                         (size_t) tpnt->l_tls_offset);
311         else
312 #endif
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                 struct stat st;
893
894                 if (_dl_stat(LDSO_PRELOAD, &st) || st.st_size == 0) {
895                         break;
896                 }
897
898                 if ((fd = _dl_open(LDSO_PRELOAD, O_RDONLY, 0)) < 0) {
899                         _dl_dprintf(_dl_debug_file, "%s: can't open file '%s'\n",
900                                     _dl_progname, LDSO_PRELOAD);
901                         break;
902                 }
903
904                 preload = (caddr_t) _dl_mmap(0, st.st_size + 1,
905                                              PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
906                 _dl_close(fd);
907                 if (preload == (caddr_t) -1) {
908                         _dl_dprintf(_dl_debug_file, "%s:%i: can't map '%s'\n",
909                                     _dl_progname, __LINE__, LDSO_PRELOAD);
910                         break;
911                 }
912
913                 /* convert all separators and comments to spaces */
914                 for (cp = preload; *cp; /*nada */ ) {
915                         if (*cp == ':' || *cp == '\t' || *cp == '\n') {
916                                 *cp++ = ' ';
917                         } else if (*cp == '#') {
918                                 do {
919                                         *cp++ = ' ';
920                                 } while (*cp != '\n' && *cp != '\0');
921                         } else {
922                                 cp++;
923                         }
924                 }
925
926                 /* find start of first library */
927                 for (cp = preload; *cp && *cp == ' '; cp++)
928                         /*nada */ ;
929
930                 while (*cp) {
931                         /* find end of library */
932                         for (cp2 = cp; *cp && *cp != ' '; cp++)
933                                 /*nada */ ;
934                         c = *cp;
935                         *cp = '\0';
936
937                         _dl_if_debug_dprint("\tfile='%s';  needed by '%s'\n", cp2, _dl_progname);
938
939                         tpnt1 = _dl_load_shared_library(0, &rpnt, NULL, cp2, trace_loaded_objects);
940                         if (!tpnt1) {
941 # ifdef __LDSO_LDD_SUPPORT__
942                                 if (trace_loaded_objects || _dl_trace_prelink)
943                                         _dl_dprintf(1, "\t%s => not found\n", cp2);
944                                 else
945 # endif
946                                 {
947                                         _dl_dprintf(_dl_debug_file, "%s: can't load library '%s'\n", _dl_progname, cp2);
948                                         _dl_exit(15);
949                                 }
950                         } else {
951                                 tpnt1->rtld_flags = unlazy | RTLD_GLOBAL;
952
953                                 _dl_debug_early("Loading: (%x) %s\n", DL_LOADADDR_BASE(tpnt1->loadaddr), tpnt1->libname);
954
955 # ifdef __LDSO_LDD_SUPPORT__
956                                 if (trace_loaded_objects && !_dl_trace_prelink &&
957                                     tpnt1->usage_count == 1) {
958                                         _dl_dprintf(1, "\t%s => %s (%x)\n",
959                                                     cp2, tpnt1->libname,
960                                                     DL_LOADADDR_BASE(tpnt1->loadaddr));
961                                 }
962 # endif
963                         }
964
965                         /* find start of next library */
966                         *cp = c;
967                         for ( /*nada */ ; *cp && *cp == ' '; cp++)
968                                 /*nada */ ;
969                 }
970
971                 _dl_munmap(preload, st.st_size + 1);
972         } while (0);
973 #endif /* __LDSO_PRELOAD_FILE_SUPPORT__ */
974
975         nlist = 0;
976         for (tcurr = _dl_loaded_modules; tcurr; tcurr = tcurr->next) {
977                 ElfW(Dyn) *this_dpnt;
978
979                 nlist++;
980                 for (this_dpnt = (ElfW(Dyn) *) tcurr->dynamic_addr; this_dpnt->d_tag; this_dpnt++) {
981                         if (this_dpnt->d_tag == DT_NEEDED) {
982                                 char *name;
983                                 struct init_fini_list *tmp;
984
985                                 lpntstr = (char*) (tcurr->dynamic_info[DT_STRTAB] + this_dpnt->d_un.d_val);
986                                 name = _dl_get_last_path_component(lpntstr);
987                                 _dl_if_debug_dprint("\tfile='%s';  needed by '%s'\n", lpntstr, _dl_progname);
988
989                                 if (_dl_strcmp(name, UCLIBC_LDSO) == 0) {
990                                                 if (!ldso_tpnt) {
991                                                         /* Insert the ld.so only once */
992                                                         ldso_tpnt = add_ldso(tpnt, load_addr, auxvt, rpnt);
993                                                 }
994                                                 ldso_tpnt->usage_count++;
995                                                 tpnt1 = ldso_tpnt;
996                                 } else
997                                         tpnt1 = _dl_load_shared_library(0, &rpnt, tcurr, lpntstr, trace_loaded_objects);
998
999                                 if (!tpnt1) {
1000 #ifdef __LDSO_LDD_SUPPORT__
1001                                         if (trace_loaded_objects || _dl_trace_prelink) {
1002                                                 _dl_dprintf(1, "\t%s => not found\n", lpntstr);
1003                                                 continue;
1004                                         } else
1005 #endif
1006                                         {
1007                                                 _dl_dprintf(_dl_debug_file, "%s: can't load library '%s'\n", _dl_progname, lpntstr);
1008                                                 _dl_exit(16);
1009                                         }
1010                                 }
1011
1012                                 tmp = alloca(sizeof(struct init_fini_list)); /* Allocates on stack, no need to free this memory */
1013                                 tmp->tpnt = tpnt1;
1014                                 tmp->next = tcurr->init_fini;
1015                                 tcurr->init_fini = tmp;
1016
1017                                 tpnt1->rtld_flags = unlazy | RTLD_GLOBAL;
1018
1019                                 _dl_debug_early("Loading: (%x) %s\n", DL_LOADADDR_BASE(tpnt1->loadaddr), tpnt1->libname);
1020
1021 #ifdef __LDSO_LDD_SUPPORT__
1022                                 if (trace_loaded_objects && !_dl_trace_prelink &&
1023                                     tpnt1->usage_count == 1) {
1024                                         _dl_dprintf(1, "\t%s => %s (%x)\n",
1025                                                     lpntstr, tpnt1->libname,
1026                                                     DL_LOADADDR_BASE(tpnt1->loadaddr));
1027                                 }
1028 #endif
1029                         }
1030                 }
1031         }
1032         _dl_unmap_cache();
1033
1034         /* Keep track of the number of elements in the global scope */
1035         nscope_elem = nlist;
1036
1037         if (_dl_loaded_modules->libtype == elf_executable) {
1038                 --nlist; /* Exclude the application. */
1039                 tcurr = _dl_loaded_modules->next;
1040         } else
1041                 tcurr = _dl_loaded_modules;
1042         init_fini_list = _dl_malloc(nlist * sizeof(struct elf_resolve *));
1043         i = 0;
1044         for (; tcurr; tcurr = tcurr->next)
1045                 init_fini_list[i++] = tcurr;
1046
1047         /* Sort the INIT/FINI list in dependency order. */
1048         for (tcurr = _dl_loaded_modules->next; tcurr; tcurr = tcurr->next) {
1049                 unsigned int j, k;
1050
1051                 for (j = 0; init_fini_list[j] != tcurr; ++j)
1052                         /* Empty */;
1053                 for (k = j + 1; k < nlist; ++k) {
1054                         struct init_fini_list *runp = init_fini_list[k]->init_fini;
1055
1056                         for (; runp; runp = runp->next) {
1057                                 if (runp->tpnt == tcurr) {
1058                                         struct elf_resolve *here = init_fini_list[k];
1059                                         _dl_if_debug_dprint("Move %s from pos %d to %d in INIT/FINI list\n", here->libname, k, j);
1060                                         for (i = (k - j); i; --i)
1061                                                 init_fini_list[i+j] = init_fini_list[i+j-1];
1062                                         init_fini_list[j] = here;
1063                                         ++j;
1064                                         break;
1065                                 }
1066                         }
1067                 }
1068         }
1069 #ifdef __SUPPORT_LD_DEBUG__
1070         if (_dl_debug) {
1071                 _dl_dprintf(_dl_debug_file, "\nINIT/FINI order and dependencies:\n");
1072                 for (i = 0; i < nlist; i++) {
1073                         struct init_fini_list *tmp;
1074
1075                         _dl_dprintf(_dl_debug_file, "lib: %s has deps:\n",
1076                                     init_fini_list[i]->libname);
1077                         tmp = init_fini_list[i]->init_fini;
1078                         for (; tmp; tmp = tmp->next)
1079                                 _dl_dprintf(_dl_debug_file, " %s ", tmp->tpnt->libname);
1080                         _dl_dprintf(_dl_debug_file, "\n");
1081                 }
1082         }
1083 #endif
1084
1085         /*
1086          * If the program interpreter is not in the module chain, add it.
1087          * This will be required for dlopen to be able to access the internal
1088          * functions in the dynamic linker and to relocate the interpreter
1089          * again once all libs are loaded.
1090          */
1091         if (!ldso_tpnt) {
1092                 tpnt = add_ldso(tpnt, load_addr, auxvt, rpnt);
1093                 tpnt->usage_count++;
1094                 nscope_elem++;
1095         } else
1096                 tpnt = ldso_tpnt;
1097
1098 #ifdef RERELOCATE_LDSO
1099                 /* Only rerelocate functions for now. */
1100                 tpnt->init_flag = RELOCS_DONE;
1101                 lpnt = (unsigned long *) (tpnt->dynamic_info[DT_PLTGOT]);
1102 # ifdef ALLOW_ZERO_PLTGOT
1103                 if (tpnt->dynamic_info[DT_PLTGOT])
1104 # endif
1105                         INIT_GOT(lpnt, tpnt);
1106 #else
1107                 tpnt->init_flag = RELOCS_DONE | JMP_RELOCS_DONE;
1108 #endif
1109                 tpnt = NULL;
1110
1111         /*
1112          * Allocate the global scope array.
1113          */
1114         scope_elem_list = (struct elf_resolve **) _dl_malloc(nscope_elem * sizeof(struct elf_resolve *));
1115
1116         for (i = 0, tcurr = _dl_loaded_modules; tcurr; tcurr = tcurr->next)
1117                 scope_elem_list[i++] = tcurr;
1118
1119         _dl_loaded_modules->symbol_scope.r_list = scope_elem_list;
1120         _dl_loaded_modules->symbol_scope.r_nlist = nscope_elem;
1121         /*
1122          * The symbol scope of the application, that is the first entry of the
1123          * _dl_loaded_modules list, is just the global scope to be used for the
1124          * symbol lookup.
1125          */
1126         global_scope = &_dl_loaded_modules->symbol_scope;
1127
1128         /* Build the local scope for each loaded modules. */
1129         local_scope = _dl_malloc(nscope_elem * sizeof(struct elf_resolve *));
1130         i = 1;
1131         for (tcurr = _dl_loaded_modules->next; tcurr; tcurr = tcurr->next) {
1132                 unsigned int k;
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 # else
1170         __stack_chk_guard = stack_chk_guard;
1171 # endif
1172 # ifdef __UCLIBC_HAS_SSP_COMPAT__
1173         __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, 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, 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, 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, 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, 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, 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"