OSDN Git Service

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