OSDN Git Service

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