OSDN Git Service

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