OSDN Git Service

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