OSDN Git Service

Merge remote-tracking branch 'origin/master' into prelink
[uclinux-h8/uClibc.git] / ldso / ldso / ldso.c
1 /* vi: set sw=4 ts=4: */
2 /*
3  * Program to load an ELF binary on a linux system, and run it
4  * after resolving ELF shared library symbols
5  *
6  * Copyright (C) 2005 by Joakim Tjernlund
7  * Copyright (C) 2000-2006 by Erik Andersen <andersen@codepoet.org>
8  * Copyright (c) 1994-2000 Eric Youngdale, Peter MacDonald,
9  *                              David Engel, Hongjiu Lu and Mitch D'Souza
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. The name of the above contributors may not be
17  *    used to endorse or promote products derived from this software
18  *    without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE
24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31  */
32
33 #include "ldso.h"
34 #include "unsecvars.h"
35
36 /* Pull in common debug code */
37 #include "dl-debug.c"
38
39 #define ALLOW_ZERO_PLTGOT
40
41 #if defined(USE_TLS) && USE_TLS
42 #include "dl-tls.c"
43 #endif
44
45 /* Pull in the value of _dl_progname */
46 #include LDSO_ELFINTERP
47
48 /* Global variables used within the shared library loader */
49 char *_dl_library_path         = NULL;  /* Where we look for libraries */
50 #ifdef __LDSO_PRELOAD_ENV_SUPPORT__
51 char *_dl_preload              = NULL;  /* Things to be loaded before the libs */
52 #endif
53 char *_dl_ldsopath             = NULL;  /* Location of the shared lib loader */
54 int _dl_errno                  = 0;     /* We can't use the real errno in ldso */
55 size_t _dl_pagesize            = 0;     /* Store the page size for use later */
56 struct r_debug *_dl_debug_addr = NULL;  /* Used to communicate with the gdb debugger */
57 void *(*_dl_malloc_function) (size_t size) = NULL;
58 void (*_dl_free_function) (void *p) = NULL;
59
60 #ifdef __LDSO_PRELINK_SUPPORT__
61 char *_dl_trace_prelink                      = NULL;    /* Library for prelinking trace */
62 struct elf_resolve *_dl_trace_prelink_map    = NULL;    /* Library module for prelinking trace */
63 bool _dl_verbose                                = true;                                 /* On by default */
64 bool prelinked                                  = false;
65 #endif
66 static int _dl_secure = 1; /* Are we dealing with setuid stuff? */
67
68 #ifdef __SUPPORT_LD_DEBUG__
69 char *_dl_debug           = NULL;
70 char *_dl_debug_symbols   = NULL;
71 char *_dl_debug_move      = NULL;
72 char *_dl_debug_reloc     = NULL;
73 char *_dl_debug_detail    = NULL;
74 char *_dl_debug_nofixups  = NULL;
75 char *_dl_debug_bindings  = NULL;
76 int   _dl_debug_file      = 2;
77 #endif
78
79 #if defined (__LDSO_STANDALONE_SUPPORT__) && defined (__sh__)
80 /* Not hidden, needed for standalone execution. */
81 /*
82  * FIXME: align dl_start for SH to other archs so that we can keep this symbol
83  *        hidden and we don't need to handle in __uClibc_main
84  */
85
86 unsigned long _dl_skip_args = 0;
87 #else
88 unsigned long attribute_hidden _dl_skip_args = 0;
89 #endif
90
91 const char *_dl_progname = UCLIBC_LDSO;      /* The name of the executable being run */
92 #include "dl-startup.c"
93 #include "dl-symbols.c"
94 #include "dl-array.c"
95
96 /*
97  * This stub function is used by some debuggers.  The idea is that they
98  * can set an internal breakpoint on it, so that we are notified when the
99  * address mapping is changed in some way.
100  */
101 void _dl_debug_state(void);
102 rtld_hidden_proto(_dl_debug_state, noinline);
103 void _dl_debug_state(void)
104 {
105         /* Make sure GCC doesn't recognize this function as pure, to avoid
106          * having the calls optimized away.
107          */
108         __asm__("");
109 }
110 rtld_hidden_def(_dl_debug_state);
111
112 static unsigned char *_dl_malloc_addr = NULL;   /* Lets _dl_malloc use the already allocated memory page */
113 static unsigned char *_dl_mmap_zero   = NULL;   /* Also used by _dl_malloc */
114
115 static struct elf_resolve **init_fini_list;
116 static struct elf_resolve **scope_elem_list;
117 static unsigned int nlist; /* # items in init_fini_list */
118 extern void _start(void);
119
120 #ifdef __UCLIBC_HAS_SSP__
121 # include <dl-osinfo.h>
122 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
891                 if (_dl_stat(LDSO_PRELOAD, &st) || st.st_size == 0) {
892                         break;
893                 }
894
895                 if ((fd = _dl_open(LDSO_PRELOAD, O_RDONLY, 0)) < 0) {
896                         _dl_dprintf(_dl_debug_file, "%s: can't open file '%s'\n",
897                                     _dl_progname, LDSO_PRELOAD);
898                         break;
899                 }
900
901                 preload = (caddr_t) _dl_mmap(0, st.st_size + 1,
902                                              PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
903                 _dl_close(fd);
904                 if (preload == (caddr_t) -1) {
905                         _dl_dprintf(_dl_debug_file, "%s:%i: can't map '%s'\n",
906                                     _dl_progname, __LINE__, LDSO_PRELOAD);
907                         break;
908                 }
909
910                 /* convert all separators and comments to spaces */
911                 for (cp = preload; *cp; /*nada */ ) {
912                         if (*cp == ':' || *cp == '\t' || *cp == '\n') {
913                                 *cp++ = ' ';
914                         } else if (*cp == '#') {
915                                 do {
916                                         *cp++ = ' ';
917                                 } while (*cp != '\n' && *cp != '\0');
918                         } else {
919                                 cp++;
920                         }
921                 }
922
923                 /* find start of first library */
924                 for (cp = preload; *cp && *cp == ' '; cp++)
925                         /*nada */ ;
926
927                 while (*cp) {
928                         /* find end of library */
929                         for (cp2 = cp; *cp && *cp != ' '; cp++)
930                                 /*nada */ ;
931                         c = *cp;
932                         *cp = '\0';
933
934                         _dl_if_debug_dprint("\tfile='%s';  needed by '%s'\n", cp2, _dl_progname);
935
936                         tpnt1 = _dl_load_shared_library(0, &rpnt, NULL, cp2, trace_loaded_objects);
937                         if (!tpnt1) {
938 # ifdef __LDSO_LDD_SUPPORT__
939                                 if (trace_loaded_objects || _dl_trace_prelink)
940                                         _dl_dprintf(1, "\t%s => not found\n", cp2);
941                                 else
942 # endif
943                                 {
944                                         _dl_dprintf(_dl_debug_file, "%s: can't load library '%s'\n", _dl_progname, cp2);
945                                         _dl_exit(15);
946                                 }
947                         } else {
948                                 tpnt1->rtld_flags = unlazy | RTLD_GLOBAL;
949
950                                 _dl_debug_early("Loading: (%x) %s\n", DL_LOADADDR_BASE(tpnt1->loadaddr), tpnt1->libname);
951
952 # ifdef __LDSO_LDD_SUPPORT__
953                                 if (trace_loaded_objects && !_dl_trace_prelink &&
954                                     tpnt1->usage_count == 1) {
955                                         _dl_dprintf(1, "\t%s => %s (%x)\n",
956                                                     cp2, tpnt1->libname,
957                                                     DL_LOADADDR_BASE(tpnt1->loadaddr));
958                                 }
959 # endif
960                         }
961
962                         /* find start of next library */
963                         *cp = c;
964                         for ( /*nada */ ; *cp && *cp == ' '; cp++)
965                                 /*nada */ ;
966                 }
967
968                 _dl_munmap(preload, st.st_size + 1);
969         } while (0);
970 #endif /* __LDSO_PRELOAD_FILE_SUPPORT__ */
971
972         nlist = 0;
973         for (tcurr = _dl_loaded_modules; tcurr; tcurr = tcurr->next) {
974                 ElfW(Dyn) *this_dpnt;
975
976                 nlist++;
977                 for (this_dpnt = (ElfW(Dyn) *) tcurr->dynamic_addr; this_dpnt->d_tag; this_dpnt++) {
978                         if (this_dpnt->d_tag == DT_NEEDED) {
979                                 char *name;
980                                 struct init_fini_list *tmp;
981
982                                 lpntstr = (char*) (tcurr->dynamic_info[DT_STRTAB] + this_dpnt->d_un.d_val);
983                                 name = _dl_get_last_path_component(lpntstr);
984                                 _dl_if_debug_dprint("\tfile='%s';  needed by '%s'\n", lpntstr, _dl_progname);
985
986                                 if (_dl_strcmp(name, UCLIBC_LDSO) == 0) {
987                                                 if (!ldso_tpnt) {
988                                                         /* Insert the ld.so only once */
989                                                         ldso_tpnt = add_ldso(tpnt, load_addr, auxvt, rpnt);
990                                                 }
991                                                 ldso_tpnt->usage_count++;
992                                                 tpnt1 = ldso_tpnt;
993                                 } else
994                                         tpnt1 = _dl_load_shared_library(0, &rpnt, tcurr, lpntstr, trace_loaded_objects);
995
996                                 if (!tpnt1) {
997 #ifdef __LDSO_LDD_SUPPORT__
998                                         if (trace_loaded_objects || _dl_trace_prelink) {
999                                                 _dl_dprintf(1, "\t%s => not found\n", lpntstr);
1000                                                 continue;
1001                                         } else
1002 #endif
1003                                         {
1004                                                 _dl_dprintf(_dl_debug_file, "%s: can't load library '%s'\n", _dl_progname, lpntstr);
1005                                                 _dl_exit(16);
1006                                         }
1007                                 }
1008
1009                                 tmp = alloca(sizeof(struct init_fini_list)); /* Allocates on stack, no need to free this memory */
1010                                 tmp->tpnt = tpnt1;
1011                                 tmp->next = tcurr->init_fini;
1012                                 tcurr->init_fini = tmp;
1013
1014                                 tpnt1->rtld_flags = unlazy | RTLD_GLOBAL;
1015
1016                                 _dl_debug_early("Loading: (%x) %s\n", DL_LOADADDR_BASE(tpnt1->loadaddr), tpnt1->libname);
1017
1018 #ifdef __LDSO_LDD_SUPPORT__
1019                                 if (trace_loaded_objects && !_dl_trace_prelink &&
1020                                     tpnt1->usage_count == 1) {
1021                                         _dl_dprintf(1, "\t%s => %s (%x)\n",
1022                                                     lpntstr, tpnt1->libname,
1023                                                     DL_LOADADDR_BASE(tpnt1->loadaddr));
1024                                 }
1025 #endif
1026                         }
1027                 }
1028         }
1029         _dl_unmap_cache();
1030
1031         /* Keep track of the number of elements in the global scope */
1032         nscope_elem = nlist;
1033
1034         if (_dl_loaded_modules->libtype == elf_executable) {
1035                 --nlist; /* Exclude the application. */
1036                 tcurr = _dl_loaded_modules->next;
1037         } else
1038                 tcurr = _dl_loaded_modules;
1039         init_fini_list = _dl_malloc(nlist * sizeof(struct elf_resolve *));
1040         i = 0;
1041         for (; tcurr; tcurr = tcurr->next)
1042                 init_fini_list[i++] = tcurr;
1043
1044         /* Sort the INIT/FINI list in dependency order. */
1045         for (tcurr = _dl_loaded_modules->next; tcurr; tcurr = tcurr->next) {
1046                 unsigned int j, k;
1047
1048                 for (j = 0; init_fini_list[j] != tcurr; ++j)
1049                         /* Empty */;
1050                 for (k = j + 1; k < nlist; ++k) {
1051                         struct init_fini_list *runp = init_fini_list[k]->init_fini;
1052
1053                         for (; runp; runp = runp->next) {
1054                                 if (runp->tpnt == tcurr) {
1055                                         struct elf_resolve *here = init_fini_list[k];
1056                                         _dl_if_debug_dprint("Move %s from pos %d to %d in INIT/FINI list\n", here->libname, k, j);
1057                                         for (i = (k - j); i; --i)
1058                                                 init_fini_list[i+j] = init_fini_list[i+j-1];
1059                                         init_fini_list[j] = here;
1060                                         ++j;
1061                                         break;
1062                                 }
1063                         }
1064                 }
1065         }
1066 #ifdef __SUPPORT_LD_DEBUG__
1067         if (_dl_debug) {
1068                 _dl_dprintf(_dl_debug_file, "\nINIT/FINI order and dependencies:\n");
1069                 for (i = 0; i < nlist; i++) {
1070                         struct init_fini_list *tmp;
1071
1072                         _dl_dprintf(_dl_debug_file, "lib: %s has deps:\n",
1073                                     init_fini_list[i]->libname);
1074                         tmp = init_fini_list[i]->init_fini;
1075                         for (; tmp; tmp = tmp->next)
1076                                 _dl_dprintf(_dl_debug_file, " %s ", tmp->tpnt->libname);
1077                         _dl_dprintf(_dl_debug_file, "\n");
1078                 }
1079         }
1080 #endif
1081
1082         /*
1083          * If the program interpreter is not in the module chain, add it.
1084          * This will be required for dlopen to be able to access the internal
1085          * functions in the dynamic linker and to relocate the interpreter
1086          * again once all libs are loaded.
1087          */
1088         if (!ldso_tpnt) {
1089                 tpnt = add_ldso(tpnt, load_addr, auxvt, rpnt);
1090                 tpnt->usage_count++;
1091                 nscope_elem++;
1092         } else
1093                 tpnt = ldso_tpnt;
1094
1095 #ifdef RERELOCATE_LDSO
1096                 /* Only rerelocate functions for now. */
1097                 tpnt->init_flag = RELOCS_DONE;
1098                 lpnt = (unsigned long *) (tpnt->dynamic_info[DT_PLTGOT]);
1099 # ifdef ALLOW_ZERO_PLTGOT
1100                 if (tpnt->dynamic_info[DT_PLTGOT])
1101 # endif
1102                         INIT_GOT(lpnt, tpnt);
1103 #else
1104                 tpnt->init_flag = RELOCS_DONE | JMP_RELOCS_DONE;
1105 #endif
1106                 tpnt = NULL;
1107
1108         /*
1109          * Allocate the global scope array.
1110          */
1111         scope_elem_list = (struct elf_resolve **) _dl_malloc(nscope_elem * sizeof(struct elf_resolve *));
1112
1113         for (i = 0, tcurr = _dl_loaded_modules; tcurr; tcurr = tcurr->next)
1114                 scope_elem_list[i++] = tcurr;
1115
1116         _dl_loaded_modules->symbol_scope.r_list = scope_elem_list;
1117         _dl_loaded_modules->symbol_scope.r_nlist = nscope_elem;
1118         /*
1119          * The symbol scope of the application, that is the first entry of the
1120          * _dl_loaded_modules list, is just the global scope to be used for the
1121          * symbol lookup.
1122          */
1123         global_scope = &_dl_loaded_modules->symbol_scope;
1124
1125         /* Build the local scope for each loaded modules. */
1126         local_scope = _dl_malloc(nscope_elem * sizeof(struct elf_resolve *));
1127         i = 1;
1128         for (tcurr = _dl_loaded_modules->next; tcurr; tcurr = tcurr->next) {
1129                 unsigned int k;
1130                 cnt = _dl_build_local_scope(local_scope, scope_elem_list[i++]);
1131                 tcurr->symbol_scope.r_list = _dl_malloc(cnt * sizeof(struct elf_resolve *));
1132                 tcurr->symbol_scope.r_nlist = cnt;
1133                 _dl_memcpy (tcurr->symbol_scope.r_list, local_scope, cnt * sizeof (struct elf_resolve *));
1134                 /* Restoring the init_flag.*/
1135                 for (k = 1; k < nscope_elem; k++)
1136                         scope_elem_list[k]->init_flag &= ~DL_RESERVED;
1137         }
1138
1139         _dl_free(local_scope);
1140
1141 #ifdef __LDSO_LDD_SUPPORT__
1142         /* Exit if LD_TRACE_LOADED_OBJECTS is on. */
1143         if (trace_loaded_objects && !_dl_trace_prelink)
1144                 _dl_exit(0);
1145 #endif
1146
1147 #if defined(USE_TLS) && USE_TLS
1148         /* We do not initialize any of the TLS functionality unless any of the
1149          * initial modules uses TLS.  This makes dynamic loading of modules with
1150          * TLS impossible, but to support it requires either eagerly doing setup
1151          * now or lazily doing it later.  Doing it now makes us incompatible with
1152          * an old kernel that can't perform TLS_INIT_TP, even if no TLS is ever
1153          * used.  Trying to do it lazily is too hairy to try when there could be
1154          * multiple threads (from a non-TLS-using libpthread).  */
1155         bool was_tls_init_tp_called = tls_init_tp_called;
1156         if (tcbp == NULL) {
1157                 _dl_debug_early("Calling init_tls()!\n");
1158                 tcbp = init_tls ();
1159         }
1160 #endif
1161 #ifdef __UCLIBC_HAS_SSP__
1162         /* Set up the stack checker's canary.  */
1163         stack_chk_guard = _dl_setup_stack_chk_guard ();
1164 # ifdef THREAD_SET_STACK_GUARD
1165         THREAD_SET_STACK_GUARD (stack_chk_guard);
1166 # else
1167         __stack_chk_guard = stack_chk_guard;
1168 # endif
1169 # ifdef __UCLIBC_HAS_SSP_COMPAT__
1170         __guard = stack_chk_guard;
1171 # endif
1172 #endif
1173
1174 #ifdef __LDSO_PRELINK_SUPPORT__
1175         if (_dl_trace_prelink) {
1176
1177                 unsigned int nscope_trace = ldso_tpnt ? nscope_elem : (nscope_elem - 1);
1178
1179                 for (i = 0; i < nscope_trace; i++)
1180                         trace_objects(scope_elem_list[i],
1181                                 _dl_get_last_path_component(scope_elem_list[i]->libname));
1182
1183                 if (_dl_verbose)
1184                         /* Warn about undefined symbols. */
1185                         if (_dl_symbol_tables)
1186                                 if (_dl_fixup(_dl_symbol_tables, global_scope, unlazy))
1187                                         _dl_exit(-1);
1188                 _dl_exit(0);
1189         }
1190
1191         if (_dl_loaded_modules->dynamic_info[DT_GNU_LIBLIST_IDX]) {
1192                 ElfW(Lib) *liblist, *liblistend;
1193                 struct elf_resolve **r_list, **r_listend, *l;
1194                 const char *strtab = (const char *)_dl_loaded_modules->dynamic_info[DT_STRTAB];
1195
1196                 _dl_assert (_dl_loaded_modules->dynamic_info[DT_GNU_LIBLISTSZ_IDX] != 0);
1197                 liblist = (ElfW(Lib) *) _dl_loaded_modules->dynamic_info[DT_GNU_LIBLIST_IDX];
1198                 liblistend = (ElfW(Lib) *)
1199                 ((char *) liblist + _dl_loaded_modules->dynamic_info[DT_GNU_LIBLISTSZ_IDX]);
1200                 r_list = _dl_loaded_modules->symbol_scope.r_list;
1201                 r_listend = r_list + nscope_elem;
1202
1203                 for (; r_list < r_listend && liblist < liblistend; r_list++) {
1204                         l = *r_list;
1205
1206                         if (l == _dl_loaded_modules)
1207                                 continue;
1208
1209                         /* If the library is not mapped where it should, fail.  */
1210                         if (l->loadaddr)
1211                                 break;
1212
1213                         /* Next, check if checksum matches.  */
1214                         if (l->dynamic_info[DT_CHECKSUM_IDX] == 0 ||
1215                                 l->dynamic_info[DT_CHECKSUM_IDX] != liblist->l_checksum)
1216                                 break;
1217
1218                         if (l->dynamic_info[DT_GNU_PRELINKED_IDX] == 0 ||
1219                                 (l->dynamic_info[DT_GNU_PRELINKED_IDX] != liblist->l_time_stamp))
1220                                 break;
1221
1222                         if (_dl_strcmp(strtab + liblist->l_name, _dl_get_last_path_component(l->libname)) != 0)
1223                                 break;
1224
1225                         ++liblist;
1226                 }
1227
1228
1229                 if (r_list == r_listend && liblist == liblistend)
1230                         prelinked = true;
1231
1232         }
1233
1234         _dl_debug_early ("\nprelink checking: %s\n", prelinked ? "ok" : "failed");
1235
1236         if (prelinked) {
1237                 if (_dl_loaded_modules->dynamic_info[DT_GNU_CONFLICT_IDX]) {
1238                         ELF_RELOC *conflict;
1239                         unsigned long conflict_size;
1240
1241                         _dl_assert (_dl_loaded_modules->dynamic_info[DT_GNU_CONFLICTSZ_IDX] != 0);
1242                         conflict = (ELF_RELOC *) _dl_loaded_modules->dynamic_info[DT_GNU_CONFLICT_IDX];
1243                         conflict_size = _dl_loaded_modules->dynamic_info[DT_GNU_CONFLICTSZ_IDX];
1244                         _dl_parse_relocation_information(_dl_symbol_tables, global_scope,
1245                                 (unsigned long) conflict, conflict_size);
1246                 }
1247
1248                 /* Mark all the objects so we know they have been already relocated.  */
1249                 for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) {
1250                         tpnt->init_flag |= RELOCS_DONE;
1251                         if (tpnt->relro_size)
1252                                 _dl_protect_relro (tpnt);
1253                 }
1254         } else
1255 #endif
1256
1257         {
1258
1259         _dl_debug_early("Beginning relocation fixups\n");
1260
1261 #ifdef __mips__
1262         /*
1263          * Relocation of the GOT entries for MIPS have to be done
1264          * after all the libraries have been loaded.
1265          */
1266         _dl_perform_mips_global_got_relocations(_dl_loaded_modules, !unlazy);
1267 #endif
1268
1269         /*
1270          * OK, now all of the kids are tucked into bed in their proper
1271          * addresses.  Now we go through and look for REL and RELA records that
1272          * indicate fixups to the GOT tables.  We need to do this in reverse
1273          * order so that COPY directives work correctly.
1274          */
1275         if (_dl_symbol_tables)
1276                 if (_dl_fixup(_dl_symbol_tables, global_scope, unlazy))
1277                         _dl_exit(-1);
1278
1279         for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) {
1280                 if (tpnt->relro_size)
1281                         _dl_protect_relro (tpnt);
1282         }
1283         } /* not prelinked */
1284
1285 #if defined(USE_TLS) && USE_TLS
1286         if (!was_tls_init_tp_called && _dl_tls_max_dtv_idx > 0)
1287                 ++_dl_tls_generation;
1288
1289         _dl_debug_early("Calling _dl_allocate_tls_init()!\n");
1290
1291         /* Now that we have completed relocation, the initializer data
1292            for the TLS blocks has its final values and we can copy them
1293            into the main thread's TLS area, which we allocated above.  */
1294         _dl_allocate_tls_init (tcbp);
1295
1296         /* And finally install it for the main thread.  If ld.so itself uses
1297            TLS we know the thread pointer was initialized earlier.  */
1298         if (! tls_init_tp_called) {
1299                 const char *lossage = (char *) TLS_INIT_TP (tcbp, USE___THREAD);
1300                 if (__builtin_expect (lossage != NULL, 0)) {
1301                         _dl_debug_early("cannot set up thread-local storage: %s\n", lossage);
1302                         _dl_exit(30);
1303                 }
1304         }
1305 #endif /* USE_TLS */
1306
1307         /* OK, at this point things are pretty much ready to run.  Now we need
1308          * to touch up a few items that are required, and then we can let the
1309          * user application have at it.  Note that the dynamic linker itself
1310          * is not guaranteed to be fully dynamicly linked if we are using
1311          * ld.so.1, so we have to look up each symbol individually.
1312          */
1313
1314         _dl_envp = (unsigned long *) (intptr_t) _dl_find_hash(__C_SYMBOL_PREFIX__ "__environ", global_scope, NULL, 0, NULL);
1315         if (_dl_envp)
1316                 *_dl_envp = (unsigned long) envp;
1317
1318 #ifndef __FORCE_SHAREABLE_TEXT_SEGMENTS__
1319         {
1320                 unsigned int j;
1321                 ElfW(Phdr) *myppnt;
1322
1323                 /* We had to set the protections of all pages to R/W for
1324                  * dynamic linking.  Set text pages back to R/O.
1325                  */
1326                 for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) {
1327                         for (myppnt = tpnt->ppnt, j = 0; j < tpnt->n_phent; j++, myppnt++) {
1328                                 if (myppnt->p_type == PT_LOAD && !(myppnt->p_flags & PF_W) && tpnt->dynamic_info[DT_TEXTREL]) {
1329                                         _dl_mprotect((void *) (DL_RELOC_ADDR(tpnt->loadaddr, myppnt->p_vaddr) & PAGE_ALIGN),
1330                                                         (myppnt->p_vaddr & ADDR_ALIGN) + (unsigned long) myppnt->p_filesz, LXFLAGS(myppnt->p_flags));
1331                                 }
1332                         }
1333                 }
1334
1335         }
1336 #endif
1337         /* Notify the debugger we have added some objects. */
1338         _dl_debug_addr->r_state = RT_ADD;
1339         _dl_debug_state();
1340
1341         /* Run pre-initialization functions for the executable.  */
1342         _dl_run_array_forward(_dl_loaded_modules->dynamic_info[DT_PREINIT_ARRAY],
1343                               _dl_loaded_modules->dynamic_info[DT_PREINIT_ARRAYSZ],
1344                               _dl_loaded_modules->loadaddr);
1345
1346         /* Run initialization functions for loaded objects.  For the
1347            main executable, they will be run from __uClibc_main.  */
1348         for (i = nlist; i; --i) {
1349                 tpnt = init_fini_list[i-1];
1350                 tpnt->init_fini = NULL; /* Clear, since alloca was used */
1351                 if (tpnt->init_flag & INIT_FUNCS_CALLED)
1352                         continue;
1353                 tpnt->init_flag |= INIT_FUNCS_CALLED;
1354
1355                 if (tpnt->dynamic_info[DT_INIT]) {
1356                         void (*dl_elf_func) (void);
1357
1358                         dl_elf_func = (void (*)(void)) DL_RELOC_ADDR(tpnt->loadaddr, tpnt->dynamic_info[DT_INIT]);
1359
1360                         _dl_if_debug_dprint("calling INIT: %s\n\n", tpnt->libname);
1361
1362                         DL_CALL_FUNC_AT_ADDR (dl_elf_func, tpnt->loadaddr, (void(*)(void)));
1363                 }
1364
1365                 _dl_run_init_array(tpnt);
1366         }
1367
1368         /* Find the real malloc function and make ldso functions use that from now on */
1369         _dl_malloc_function = (void* (*)(size_t)) (intptr_t) _dl_find_hash(__C_SYMBOL_PREFIX__ "malloc",
1370                         global_scope, NULL, ELF_RTYPE_CLASS_PLT, NULL);
1371
1372 #if defined(USE_TLS) && USE_TLS
1373         /* Find the real functions and make ldso functions use them from now on */
1374         _dl_calloc_function = (void* (*)(size_t, size_t)) (intptr_t)
1375                 _dl_find_hash(__C_SYMBOL_PREFIX__ "calloc", global_scope, NULL, ELF_RTYPE_CLASS_PLT, NULL);
1376
1377         _dl_realloc_function = (void* (*)(void *, size_t)) (intptr_t)
1378                 _dl_find_hash(__C_SYMBOL_PREFIX__ "realloc", global_scope, NULL, ELF_RTYPE_CLASS_PLT, NULL);
1379
1380         _dl_free_function = (void (*)(void *)) (intptr_t)
1381                 _dl_find_hash(__C_SYMBOL_PREFIX__ "free", global_scope, NULL, ELF_RTYPE_CLASS_PLT, NULL);
1382
1383         _dl_memalign_function = (void* (*)(size_t, size_t)) (intptr_t)
1384                 _dl_find_hash(__C_SYMBOL_PREFIX__ "memalign", global_scope, NULL, ELF_RTYPE_CLASS_PLT, NULL);
1385
1386 #endif
1387
1388         /* Notify the debugger that all objects are now mapped in.  */
1389         _dl_debug_addr->r_state = RT_CONSISTENT;
1390         _dl_debug_state();
1391
1392 #ifdef __LDSO_STANDALONE_SUPPORT__
1393         if (_start == (void *) auxvt[AT_ENTRY].a_un.a_val)
1394                 return (void *) app_tpnt->l_entry;
1395         else
1396 #endif
1397                 return (void *) auxvt[AT_ENTRY].a_un.a_val;
1398 }
1399
1400 #include "dl-hash.c"
1401 #include "dl-elf.c"