OSDN Git Service

ldso: clean up breakage in tls merge
[uclinux-h8/uClibc.git] / ldso / ldso / ldso.c
1 /* vi: set sw=4 ts=4: */
2 /*
3  * Program to load an ELF binary on a linux system, and run it
4  * after resolving ELF shared library symbols
5  *
6  * Copyright (C) 2005 by Joakim Tjernlund
7  * Copyright (C) 2000-2006 by Erik Andersen <andersen@codepoet.org>
8  * Copyright (c) 1994-2000 Eric Youngdale, Peter MacDonald,
9  *                              David Engel, Hongjiu Lu and Mitch D'Souza
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. The name of the above contributors may not be
17  *    used to endorse or promote products derived from this software
18  *    without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE
24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31  */
32
33 #include "ldso.h"
34 #include "unsecvars.h"
35
36 /* Pull in common debug code */
37 #include "dl-debug.c"
38
39 #define ALLOW_ZERO_PLTGOT
40
41 #if USE_TLS
42 #include "dl-tls.c"
43 #endif
44
45 /* Pull in the value of _dl_progname */
46 #include LDSO_ELFINTERP
47
48 /* Global variables used within the shared library loader */
49 char *_dl_library_path         = NULL;  /* Where we look for libraries */
50 char *_dl_preload              = NULL;  /* Things to be loaded before the libs */
51 char *_dl_ldsopath             = NULL;  /* Location of the shared lib loader */
52 int _dl_errno                  = 0;     /* We can't use the real errno in ldso */
53 size_t _dl_pagesize            = 0;     /* Store the page size for use later */
54 struct r_debug *_dl_debug_addr = NULL;  /* Used to communicate with the gdb debugger */
55 void *(*_dl_malloc_function) (size_t size) = NULL;
56 void (*_dl_free_function) (void *p) = NULL;
57
58 static int _dl_secure = 1; /* Are we dealing with setuid stuff? */
59
60 #ifdef __SUPPORT_LD_DEBUG__
61 char *_dl_debug           = NULL;
62 char *_dl_debug_symbols   = NULL;
63 char *_dl_debug_move      = NULL;
64 char *_dl_debug_reloc     = NULL;
65 char *_dl_debug_detail    = NULL;
66 char *_dl_debug_nofixups  = NULL;
67 char *_dl_debug_bindings  = NULL;
68 int   _dl_debug_file      = 2;
69 #endif
70
71 /* Needed for standalone execution. */
72 unsigned long attribute_hidden _dl_skip_args = 0;
73 const char *_dl_progname = UCLIBC_LDSO;      /* The name of the executable being run */
74 #include "dl-startup.c"
75 #include "dl-symbols.c"
76 #include "dl-array.c"
77
78 /*
79  * This stub function is used by some debuggers.  The idea is that they
80  * can set an internal breakpoint on it, so that we are notified when the
81  * address mapping is changed in some way.
82  */
83 void _dl_debug_state(void);
84 rtld_hidden_proto(_dl_debug_state, noinline);
85 void _dl_debug_state(void)
86 {
87         /* Make sure GCC doesn't recognize this function as pure, to avoid
88          * having the calls optimized away.
89          */
90         __asm__("");
91 }
92 rtld_hidden_def(_dl_debug_state);
93
94 static unsigned char *_dl_malloc_addr = NULL;   /* Lets _dl_malloc use the already allocated memory page */
95 static unsigned char *_dl_mmap_zero   = NULL;   /* Also used by _dl_malloc */
96
97 static struct elf_resolve **init_fini_list;
98 static unsigned int nlist; /* # items in init_fini_list */
99 extern void _start(void);
100
101 #ifdef __UCLIBC_HAS_SSP__
102 # include <dl-osinfo.h>
103 uintptr_t stack_chk_guard;
104 # ifndef THREAD_SET_STACK_GUARD
105 /* Only exported for architectures that don't store the stack guard canary
106  * in local thread area.  */
107 uintptr_t __stack_chk_guard attribute_relro;
108 #  ifdef __UCLIBC_HAS_SSP_COMPAT__
109 strong_alias(__stack_chk_guard,__guard)
110 #  endif
111 # elif __UCLIBC_HAS_SSP_COMPAT__
112 uintptr_t __guard attribute_relro;
113 # endif
114 #endif
115
116 char *_dl_getenv(const char *symbol, char **envp)
117 {
118         char *pnt;
119         const char *pnt1;
120
121         while ((pnt = *envp++)) {
122                 pnt1 = symbol;
123                 while (*pnt && *pnt == *pnt1)
124                         pnt1++, pnt++;
125                 if (!*pnt || *pnt != '=' || *pnt1)
126                         continue;
127                 return pnt + 1;
128         }
129         return 0;
130 }
131
132 void _dl_unsetenv(const char *symbol, char **envp)
133 {
134         char *pnt;
135         const char *pnt1;
136         char **newenvp = envp;
137
138         for (pnt = *envp; pnt; pnt = *++envp) {
139                 pnt1 = symbol;
140                 while (*pnt && *pnt == *pnt1)
141                         pnt1++, pnt++;
142                 if (!*pnt || *pnt != '=' || *pnt1)
143                         *newenvp++ = *envp;
144         }
145         *newenvp++ = *envp;
146         return;
147 }
148
149 static int _dl_suid_ok(void)
150 {
151         __kernel_uid_t uid, euid;
152         __kernel_gid_t gid, egid;
153
154         uid = _dl_getuid();
155         euid = _dl_geteuid();
156         gid = _dl_getgid();
157         egid = _dl_getegid();
158
159         if (uid == euid && gid == egid) {
160                 return 1;
161         }
162         return 0;
163 }
164
165 void *_dl_malloc(size_t size)
166 {
167         void *retval;
168
169 #if 0
170         _dl_debug_early("request for %d bytes\n", size);
171 #endif
172
173         if (_dl_malloc_function)
174                 return (*_dl_malloc_function) (size);
175
176         if (_dl_malloc_addr - _dl_mmap_zero + size > _dl_pagesize) {
177                 size_t rounded_size;
178
179                 /* Since the above assumes we get a full page even if
180                    we request less than that, make sure we request a
181                    full page, since uClinux may give us less than than
182                    a full page.  We might round even
183                    larger-than-a-page sizes, but we end up never
184                    reusing _dl_mmap_zero/_dl_malloc_addr in that case,
185                    so we don't do it.
186
187                    The actual page size doesn't really matter; as long
188                    as we're self-consistent here, we're safe.  */
189                 if (size < _dl_pagesize)
190                         rounded_size = (size + ADDR_ALIGN) & _dl_pagesize;
191                 else
192                         rounded_size = size;
193
194                 _dl_debug_early("mmapping more memory\n");
195                 _dl_mmap_zero = _dl_malloc_addr = _dl_mmap((void *) 0, rounded_size,
196                                 PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
197                 if (_dl_mmap_check_error(_dl_mmap_zero)) {
198                         _dl_dprintf(_dl_debug_file, "%s: mmap of a spare page failed!\n", _dl_progname);
199                         _dl_exit(20);
200                 }
201         }
202         retval = _dl_malloc_addr;
203         _dl_malloc_addr += size;
204
205         /*
206          * Align memory to DL_MALLOC_ALIGN byte boundary.  Some
207          * platforms require this, others simply get better
208          * performance.
209          */
210         _dl_malloc_addr = (unsigned char *) (((unsigned long) _dl_malloc_addr + DL_MALLOC_ALIGN - 1) & ~(DL_MALLOC_ALIGN - 1));
211         return retval;
212 }
213
214 static void *_dl_zalloc(size_t size)
215 {
216         void *p = _dl_malloc(size);
217         if (p)
218                 _dl_memset(p, 0, size);
219         return p;
220 }
221
222 void _dl_free(void *p)
223 {
224         if (_dl_free_function)
225                 (*_dl_free_function) (p);
226 }
227
228 #if USE_TLS
229 void *_dl_memalign(size_t __boundary, size_t __size)
230 {
231         void *result;
232         int i = 0;
233         size_t delta;
234         size_t rounded = 0;
235
236         if (_dl_memalign_function)
237                 return (*_dl_memalign_function) (__boundary, __size);
238
239         while (rounded < __boundary) {
240                 rounded = (1 << i++);
241         }
242
243         delta = (((size_t) _dl_malloc_addr + __size) & (rounded - 1));
244
245         if ((result = _dl_malloc(rounded - delta)) == NULL)
246                 return result;
247
248         result = _dl_malloc(__size);
249
250         return result;
251 }
252 #endif
253
254 static void __attribute__ ((destructor)) __attribute_used__ _dl_fini(void)
255 {
256         unsigned int i;
257         struct elf_resolve * tpnt;
258
259         for (i = 0; i < nlist; ++i) {
260                 tpnt = init_fini_list[i];
261                 if (tpnt->init_flag & FINI_FUNCS_CALLED)
262                         continue;
263                 tpnt->init_flag |= FINI_FUNCS_CALLED;
264                 _dl_run_fini_array(tpnt);
265                 if (tpnt->dynamic_info[DT_FINI]) {
266                         void (*dl_elf_func) (void);
267
268                         dl_elf_func = (void (*)(void)) (intptr_t) DL_RELOC_ADDR(tpnt->loadaddr, tpnt->dynamic_info[DT_FINI]);
269                         _dl_if_debug_dprint("\ncalling FINI: %s\n\n", tpnt->libname);
270                         DL_CALL_FUNC_AT_ADDR (dl_elf_func, tpnt->loadaddr, (void(*)(void)));
271                 }
272         }
273 }
274
275 void _dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr,
276                           ElfW(auxv_t) auxvt[AT_EGID + 1], char **envp,
277                           char **argv
278                           DL_GET_READY_TO_RUN_EXTRA_PARMS)
279 {
280         ElfW(Addr) app_mapaddr = 0;
281         ElfW(Phdr) *ppnt;
282         ElfW(Dyn) *dpnt;
283         char *lpntstr;
284         unsigned int i;
285         int unlazy = 0, trace_loaded_objects = 0;
286         struct dyn_elf *rpnt;
287         struct elf_resolve *tcurr;
288         struct elf_resolve *tpnt1;
289         struct elf_resolve app_tpnt_tmp;
290         struct elf_resolve *app_tpnt = &app_tpnt_tmp;
291         struct r_debug *debug_addr;
292         unsigned long *lpnt;
293         unsigned long *_dl_envp;                /* The environment address */
294         ElfW(Addr) relro_addr = 0;
295         size_t relro_size = 0;
296         struct stat st;
297 #if USE_TLS
298         void *tcbp = NULL;
299 #endif
300
301         /* Wahoo!!! We managed to make a function call!  Get malloc
302          * setup so we can use _dl_dprintf() to print debug noise
303          * instead of the SEND_STDERR macros used in dl-startup.c */
304
305         _dl_memset(app_tpnt, 0, sizeof(*app_tpnt));
306
307         /* Store the page size for later use */
308         _dl_pagesize = (auxvt[AT_PAGESZ].a_un.a_val) ? (size_t) auxvt[AT_PAGESZ].a_un.a_val : PAGE_SIZE;
309         /* Make it so _dl_malloc can use the page of memory we have already
310          * allocated.  We shouldn't need to grab any more memory.  This must
311          * be first since things like _dl_dprintf() use _dl_malloc()...
312          */
313         _dl_malloc_addr = (unsigned char *)_dl_pagesize;
314         _dl_mmap_zero = 0;
315
316         /* Wahoo!!! */
317         _dl_debug_early("Cool, ldso survived making function calls\n");
318
319         /* Now we have done the mandatory linking of some things.  We are now
320          * free to start using global variables, since these things have all
321          * been fixed up by now.  Still no function calls outside of this
322          * library, since the dynamic resolver is not yet ready.
323          */
324         if (argv[0]) {
325                 _dl_progname = argv[0];
326         }
327
328         if (_start == (void *) auxvt[AT_ENTRY].a_un.a_val) {
329                 _dl_dprintf(_dl_debug_file, "Standalone execution is not supported yet\n");
330                 _dl_exit(1);
331         }
332
333         /* Start to build the tables of the modules that are required for
334          * this beast to run.  We start with the basic executable, and then
335          * go from there.  Eventually we will run across ourself, and we
336          * will need to properly deal with that as well.
337          */
338         rpnt = NULL;
339         if (_dl_getenv("LD_BIND_NOW", envp))
340                 unlazy = RTLD_NOW;
341
342         /* Now we need to figure out what kind of options are selected.
343          * Note that for SUID programs we ignore the settings in
344          * LD_LIBRARY_PATH.
345          */
346         if ((auxvt[AT_UID].a_un.a_val == (size_t)-1 && _dl_suid_ok()) ||
347             (auxvt[AT_UID].a_un.a_val != (size_t)-1 &&
348              auxvt[AT_UID].a_un.a_val == auxvt[AT_EUID].a_un.a_val &&
349              auxvt[AT_GID].a_un.a_val == auxvt[AT_EGID].a_un.a_val)) {
350                 _dl_secure = 0;
351                 _dl_preload = _dl_getenv("LD_PRELOAD", envp);
352                 _dl_library_path = _dl_getenv("LD_LIBRARY_PATH", envp);
353         } else {
354                 static const char unsecure_envvars[] =
355 #ifdef EXTRA_UNSECURE_ENVVARS
356                         EXTRA_UNSECURE_ENVVARS
357 #endif
358                         UNSECURE_ENVVARS;
359                 const char *nextp;
360                 _dl_secure = 1;
361
362                 nextp = unsecure_envvars;
363                 do {
364                         _dl_unsetenv (nextp, envp);
365                         /* We could use rawmemchr but this need not be fast.  */
366                         nextp = _dl_strchr(nextp, '\0') + 1;
367                 } while (*nextp != '\0');
368                 _dl_preload = NULL;
369                 _dl_library_path = NULL;
370                 /* SUID binaries can be exploited if they do LAZY relocation. */
371                 unlazy = RTLD_NOW;
372         }
373
374 #if USE_TLS
375         _dl_error_catch_tsd = &_dl_initial_error_catch_tsd;
376         _dl_init_static_tls = &_dl_nothread_init_static_tls;
377 #endif
378
379 #ifdef __UCLIBC_HAS_SSP__
380         /* Set up the stack checker's canary.  */
381         stack_chk_guard = _dl_setup_stack_chk_guard ();
382 # ifdef THREAD_SET_STACK_GUARD
383         THREAD_SET_STACK_GUARD (stack_chk_guard);
384 #  ifdef __UCLIBC_HAS_SSP_COMPAT__
385         __guard = stack_chk_guard;
386 #  endif
387 # else
388         __stack_chk_guard = stack_chk_guard;
389 # endif
390 #endif
391
392         /* At this point we are now free to examine the user application,
393          * and figure out which libraries are supposed to be called.  Until
394          * we have this list, we will not be completely ready for dynamic
395          * linking.
396          */
397
398         /* Find the runtime load address of the main executable.  This may be
399          * different from what the ELF header says for ET_DYN/PIE executables.
400          */
401         {
402                 unsigned int idx;
403                 ElfW(Phdr) *phdr = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_val;
404
405                 for (idx = 0; idx < auxvt[AT_PHNUM].a_un.a_val; idx++, phdr++)
406                         if (phdr->p_type == PT_PHDR) {
407                                 DL_INIT_LOADADDR_PROG(app_tpnt->loadaddr, auxvt[AT_PHDR].a_un.a_val - phdr->p_vaddr);
408                                 break;
409                         }
410
411                 if (DL_LOADADDR_BASE(app_tpnt->loadaddr))
412                         _dl_debug_early("Position Independent Executable: "
413                                         "app_tpnt->loadaddr=%x\n", DL_LOADADDR_BASE(app_tpnt->loadaddr));
414         }
415
416         /*
417          * This is used by gdb to locate the chain of shared libraries that are
418          * currently loaded.
419          */
420         debug_addr = _dl_zalloc(sizeof(struct r_debug));
421
422         ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_val;
423         for (i = 0; i < auxvt[AT_PHNUM].a_un.a_val; i++, ppnt++) {
424                 if (ppnt->p_type == PT_GNU_RELRO) {
425                         relro_addr = ppnt->p_vaddr;
426                         relro_size = ppnt->p_memsz;
427                 }
428                 if (!app_mapaddr && (ppnt->p_type == PT_LOAD)) {
429                         app_mapaddr = DL_RELOC_ADDR (app_tpnt->loadaddr, ppnt->p_vaddr);
430                 }
431                 if (ppnt->p_type == PT_DYNAMIC) {
432                         dpnt = (ElfW(Dyn) *) DL_RELOC_ADDR(app_tpnt->loadaddr, ppnt->p_vaddr);
433                         _dl_parse_dynamic_info(dpnt, app_tpnt->dynamic_info, debug_addr, app_tpnt->loadaddr);
434 #ifndef __FORCE_SHAREABLE_TEXT_SEGMENTS__
435                         /* Ugly, ugly.  We need to call mprotect to change the
436                          * protection of the text pages so that we can do the
437                          * dynamic linking.  We can set the protection back
438                          * again once we are done.
439                          */
440                         _dl_debug_early("calling mprotect on the application program\n");
441                         /* Now cover the application program. */
442                         if (app_tpnt->dynamic_info[DT_TEXTREL]) {
443                                 ElfW(Phdr) *ppnt_outer = ppnt;
444                                 ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_val;
445                                 for (i = 0; i < auxvt[AT_PHNUM].a_un.a_val; i++, ppnt++) {
446                                         if (ppnt->p_type == PT_LOAD && !(ppnt->p_flags & PF_W))
447                                                 _dl_mprotect((void *) (DL_RELOC_ADDR(app_tpnt->loadaddr, ppnt->p_vaddr) & PAGE_ALIGN),
448                                                              (DL_RELOC_ADDR(app_tpnt->loadaddr, ppnt->p_vaddr) & ADDR_ALIGN) +
449                                                              (unsigned long) ppnt->p_filesz,
450                                                              PROT_READ | PROT_WRITE | PROT_EXEC);
451                                 }
452                                 ppnt = ppnt_outer;
453                         }
454 #else
455                         if (app_tpnt->dynamic_info[DT_TEXTREL]) {
456                                 _dl_dprintf(_dl_debug_file, "Can't modify application's text section; use the GCC option -fPIE for position-independent executables.\n");
457                                 _dl_exit(1);
458                         }
459 #endif
460
461 #ifndef ALLOW_ZERO_PLTGOT
462                         /* make sure it's really there. */
463                         if (app_tpnt->dynamic_info[DT_PLTGOT] == 0)
464                                 continue;
465 #endif
466                         /* OK, we have what we need - slip this one into the list. */
467                         app_tpnt = _dl_add_elf_hash_table(_dl_progname, app_tpnt->loadaddr,
468                                         app_tpnt->dynamic_info,
469                                         (unsigned long) DL_RELOC_ADDR(app_tpnt->loadaddr, ppnt->p_vaddr),
470                                         ppnt->p_filesz);
471                         _dl_loaded_modules->libtype = elf_executable;
472                         _dl_loaded_modules->ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_val;
473                         _dl_loaded_modules->n_phent = auxvt[AT_PHNUM].a_un.a_val;
474                         _dl_symbol_tables = rpnt = _dl_zalloc(sizeof(struct dyn_elf));
475                         rpnt->dyn = _dl_loaded_modules;
476                         app_tpnt->mapaddr = app_mapaddr;
477                         app_tpnt->rtld_flags = unlazy | RTLD_GLOBAL;
478                         app_tpnt->usage_count++;
479                         app_tpnt->symbol_scope = _dl_symbol_tables;
480                         lpnt = (unsigned long *) (app_tpnt->dynamic_info[DT_PLTGOT]);
481 #ifdef ALLOW_ZERO_PLTGOT
482                         if (lpnt)
483 #endif
484                                 INIT_GOT(lpnt, _dl_loaded_modules);
485                 }
486
487                 /* OK, fill this in - we did not have this before */
488                 if (ppnt->p_type == PT_INTERP) {
489                         char *ptmp;
490
491                         tpnt->libname = (char *) DL_RELOC_ADDR(app_tpnt->loadaddr, ppnt->p_vaddr);
492
493                         /* Store the path where the shared lib loader was found
494                          * for later use
495                          */
496                         _dl_ldsopath = _dl_strdup(tpnt->libname);
497                         ptmp = _dl_strrchr(_dl_ldsopath, '/');
498                         if (ptmp != _dl_ldsopath)
499                                 *ptmp = '\0';
500
501                         _dl_debug_early("Lib Loader: (%x) %s\n", (unsigned) DL_LOADADDR_BASE(tpnt->loadaddr), tpnt->libname);
502                 }
503
504                 /* Discover any TLS sections if the target supports them. */
505                 if (ppnt->p_type == PT_TLS) {
506 #if USE_TLS
507                         if (ppnt->p_memsz > 0) {
508                                 app_tpnt->l_tls_blocksize = ppnt->p_memsz;
509                                 app_tpnt->l_tls_align = ppnt->p_align;
510                                 if (ppnt->p_align == 0)
511                                         app_tpnt->l_tls_firstbyte_offset = 0;
512                                 else
513                                         app_tpnt->l_tls_firstbyte_offset =
514                                                 (ppnt->p_vaddr & (ppnt->p_align - 1));
515                                 app_tpnt->l_tls_initimage_size = ppnt->p_filesz;
516                                 app_tpnt->l_tls_initimage = (void *) ppnt->p_vaddr;
517
518                                 /* This image gets the ID one.  */
519                                 _dl_tls_max_dtv_idx = app_tpnt->l_tls_modid = 1;
520
521                         }
522                         _dl_debug_early("Found TLS header for appplication program\n");
523                         break;
524 #else
525                         _dl_dprintf(_dl_debug_file, "Program uses unsupported TLS data!\n");
526                         _dl_exit(1);
527 #endif
528                 }
529         }
530         app_tpnt->relro_addr = relro_addr;
531         app_tpnt->relro_size = relro_size;
532
533 #if USE_TLS
534         /*
535          * Adjust the address of the TLS initialization image in
536          * case the executable is actually an ET_DYN object.
537          */
538         if (app_tpnt->l_tls_initimage != NULL) {
539                 app_tpnt->l_tls_initimage =
540                         (char *) app_tpnt->l_tls_initimage + app_tpnt->loadaddr;
541                 _dl_debug_early("Relocated TLS initial image from %x to %x (size = %x)\n",
542                         (unsigned int)app_tpnt->l_tls_initimage,
543                         app_tpnt->l_tls_initimage, app_tpnt->l_tls_initimage_size);
544         }
545 #endif
546
547 #ifdef __SUPPORT_LD_DEBUG__
548         _dl_debug = _dl_getenv("LD_DEBUG", envp);
549         if (_dl_debug) {
550                 if (_dl_strstr(_dl_debug, "all")) {
551                         _dl_debug_detail = _dl_debug_move = _dl_debug_symbols
552                                 = _dl_debug_reloc = _dl_debug_bindings = _dl_debug_nofixups = (void*)1;
553                 } else {
554                         _dl_debug_detail   = _dl_strstr(_dl_debug, "detail");
555                         _dl_debug_move     = _dl_strstr(_dl_debug, "move");
556                         _dl_debug_symbols  = _dl_strstr(_dl_debug, "sym");
557                         _dl_debug_reloc    = _dl_strstr(_dl_debug, "reloc");
558                         _dl_debug_nofixups = _dl_strstr(_dl_debug, "nofix");
559                         _dl_debug_bindings = _dl_strstr(_dl_debug, "bind");
560                 }
561         }
562
563         {
564                 const char *dl_debug_output;
565
566                 dl_debug_output = _dl_getenv("LD_DEBUG_OUTPUT", envp);
567
568                 if (dl_debug_output) {
569                         char tmp[22], *tmp1, *filename;
570                         int len1, len2;
571
572                         _dl_memset(tmp, 0, sizeof(tmp));
573                         tmp1 = _dl_simple_ltoa( tmp, (unsigned long)_dl_getpid());
574
575                         len1 = _dl_strlen(dl_debug_output);
576                         len2 = _dl_strlen(tmp1);
577
578                         filename = _dl_malloc(len1 + len2 + 2);
579
580                         if (filename) {
581                                 _dl_strcpy (filename, dl_debug_output);
582                                 filename[len1] = '.';
583                                 _dl_strcpy (&filename[len1+1], tmp1);
584
585                                 _dl_debug_file = _dl_open(filename, O_WRONLY|O_CREAT, 0644);
586                                 if (_dl_debug_file < 0) {
587                                         _dl_debug_file = 2;
588                                         _dl_dprintf(_dl_debug_file, "can't open file: '%s'\n",filename);
589                                 }
590                         }
591                 }
592         }
593 #endif
594
595         if (_dl_getenv("LD_TRACE_LOADED_OBJECTS", envp) != NULL) {
596                 trace_loaded_objects++;
597         }
598
599 #ifndef __LDSO_LDD_SUPPORT__
600         if (trace_loaded_objects) {
601                 _dl_dprintf(_dl_debug_file, "Use the ldd provided by uClibc\n");
602                 _dl_exit(1);
603         }
604 #endif
605
606         /*
607          * OK, fix one more thing - set up debug_addr so it will point
608          * to our chain.  Later we may need to fill in more fields, but this
609          * should be enough for now.
610          */
611         debug_addr->r_map = (struct link_map *) _dl_loaded_modules;
612         debug_addr->r_version = 1;
613         debug_addr->r_ldbase = (ElfW(Addr)) DL_LOADADDR_BASE(load_addr);
614         debug_addr->r_brk = (unsigned long) &_dl_debug_state;
615         _dl_debug_addr = debug_addr;
616
617         /* Do not notify the debugger until the interpreter is in the list */
618
619         /* OK, we now have the application in the list, and we have some
620          * basic stuff in place.  Now search through the list for other shared
621          * libraries that should be loaded, and insert them on the list in the
622          * correct order.
623          */
624
625         _dl_map_cache();
626
627         if (_dl_preload) {
628                 char c, *str, *str2;
629
630                 str = _dl_preload;
631                 while (*str == ':' || *str == ' ' || *str == '\t')
632                         str++;
633
634                 while (*str) {
635                         str2 = str;
636                         while (*str2 && *str2 != ':' && *str2 != ' ' && *str2 != '\t')
637                                 str2++;
638                         c = *str2;
639                         *str2 = '\0';
640
641                         if (!_dl_secure || _dl_strchr(str, '/') == NULL) {
642                                 _dl_if_debug_dprint("\tfile='%s';  needed by '%s'\n", str, _dl_progname);
643
644                                 tpnt1 = _dl_load_shared_library(_dl_secure, &rpnt, NULL, str, trace_loaded_objects);
645                                 if (!tpnt1) {
646 #ifdef __LDSO_LDD_SUPPORT__
647                                         if (trace_loaded_objects)
648                                                 _dl_dprintf(1, "\t%s => not found\n", str);
649                                         else
650 #endif
651                                         {
652                                                 _dl_dprintf(_dl_debug_file, "%s: can't load " "library '%s'\n", _dl_progname, str);
653                                                 _dl_exit(15);
654                                         }
655                                 } else {
656                                         tpnt1->rtld_flags = unlazy | RTLD_GLOBAL;
657
658                                         _dl_debug_early("Loading: (%x) %s\n", DL_LOADADDR_BASE(tpnt1->loadaddr), tpnt1->libname);
659
660 #ifdef __LDSO_LDD_SUPPORT__
661                                         if (trace_loaded_objects &&
662                                             tpnt1->usage_count == 1) {
663                                                 /* This is a real hack to make
664                                                  * ldd not print the library
665                                                  * itself when run on a
666                                                  * library.
667                                                  */
668                                                 if (_dl_strcmp(_dl_progname, str) != 0)
669                                                         _dl_dprintf(1, "\t%s => %s (%x)\n", str, tpnt1->libname,
670                                                                     DL_LOADADDR_BASE(tpnt1->loadaddr));
671                                         }
672 #endif
673                                 }
674                         }
675
676                         *str2 = c;
677                         str = str2;
678                         while (*str == ':' || *str == ' ' || *str == '\t')
679                                 str++;
680                 }
681         }
682
683 #ifdef __LDSO_PRELOAD_FILE_SUPPORT__
684         do {
685                 struct stat st;
686                 char *preload;
687                 int fd;
688                 char c, *cp, *cp2;
689
690                 if (_dl_stat(LDSO_PRELOAD, &st) || st.st_size == 0) {
691                         break;
692                 }
693
694                 if ((fd = _dl_open(LDSO_PRELOAD, O_RDONLY, 0)) < 0) {
695                         _dl_dprintf(_dl_debug_file, "%s: can't open file '%s'\n",
696                                     _dl_progname, LDSO_PRELOAD);
697                         break;
698                 }
699
700                 preload = (caddr_t) _dl_mmap(0, st.st_size + 1,
701                                              PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
702                 _dl_close(fd);
703                 if (preload == (caddr_t) -1) {
704                         _dl_dprintf(_dl_debug_file, "%s:%i: can't map '%s'\n",
705                                     _dl_progname, __LINE__, LDSO_PRELOAD);
706                         break;
707                 }
708
709                 /* convert all separators and comments to spaces */
710                 for (cp = preload; *cp; /*nada */ ) {
711                         if (*cp == ':' || *cp == '\t' || *cp == '\n') {
712                                 *cp++ = ' ';
713                         } else if (*cp == '#') {
714                                 do {
715                                         *cp++ = ' ';
716                                 } while (*cp != '\n' && *cp != '\0');
717                         } else {
718                                 cp++;
719                         }
720                 }
721
722                 /* find start of first library */
723                 for (cp = preload; *cp && *cp == ' '; cp++)
724                         /*nada */ ;
725
726                 while (*cp) {
727                         /* find end of library */
728                         for (cp2 = cp; *cp && *cp != ' '; cp++)
729                                 /*nada */ ;
730                         c = *cp;
731                         *cp = '\0';
732
733                         _dl_if_debug_dprint("\tfile='%s';  needed by '%s'\n", cp2, _dl_progname);
734
735                         tpnt1 = _dl_load_shared_library(0, &rpnt, NULL, cp2, trace_loaded_objects);
736                         if (!tpnt1) {
737 #ifdef __LDSO_LDD_SUPPORT__
738                                 if (trace_loaded_objects)
739                                         _dl_dprintf(1, "\t%s => not found\n", cp2);
740                                 else
741 #endif
742                                 {
743                                         _dl_dprintf(_dl_debug_file, "%s: can't load library '%s'\n", _dl_progname, cp2);
744                                         _dl_exit(15);
745                                 }
746                         } else {
747                                 tpnt1->rtld_flags = unlazy | RTLD_GLOBAL;
748
749                                 _dl_debug_early("Loading: (%x) %s\n", DL_LOADADDR_BASE(tpnt1->loadaddr), tpnt1->libname);
750
751 #ifdef __LDSO_LDD_SUPPORT__
752                                 if (trace_loaded_objects &&
753                                     tpnt1->usage_count == 1) {
754                                         _dl_dprintf(1, "\t%s => %s (%x)\n",
755                                                     cp2, tpnt1->libname,
756                                                     DL_LOADADDR_BASE(tpnt1->loadaddr));
757                                 }
758 #endif
759                         }
760
761                         /* find start of next library */
762                         *cp = c;
763                         for ( /*nada */ ; *cp && *cp == ' '; cp++)
764                                 /*nada */ ;
765                 }
766
767                 _dl_munmap(preload, st.st_size + 1);
768         } while (0);
769 #endif /* __LDSO_PRELOAD_FILE_SUPPORT__ */
770
771         nlist = 0;
772         for (tcurr = _dl_loaded_modules; tcurr; tcurr = tcurr->next) {
773                 ElfW(Dyn) *this_dpnt;
774
775                 nlist++;
776                 for (this_dpnt = (ElfW(Dyn) *) tcurr->dynamic_addr; this_dpnt->d_tag; this_dpnt++) {
777                         if (this_dpnt->d_tag == DT_NEEDED) {
778                                 char *name;
779                                 struct init_fini_list *tmp;
780
781                                 lpntstr = (char*) (tcurr->dynamic_info[DT_STRTAB] + this_dpnt->d_un.d_val);
782                                 name = _dl_get_last_path_component(lpntstr);
783                                 if (_dl_strcmp(name, UCLIBC_LDSO) == 0)
784                                         continue;
785
786                                 _dl_if_debug_dprint("\tfile='%s';  needed by '%s'\n", lpntstr, _dl_progname);
787
788                                 if (!(tpnt1 = _dl_load_shared_library(0, &rpnt, tcurr, lpntstr, trace_loaded_objects))) {
789 #ifdef __LDSO_LDD_SUPPORT__
790                                         if (trace_loaded_objects) {
791                                                 _dl_dprintf(1, "\t%s => not found\n", lpntstr);
792                                                 continue;
793                                         } else
794 #endif
795                                         {
796                                                 _dl_dprintf(_dl_debug_file, "%s: can't load library '%s'\n", _dl_progname, lpntstr);
797                                                 _dl_exit(16);
798                                         }
799                                 }
800
801                                 tmp = alloca(sizeof(struct init_fini_list)); /* Allocates on stack, no need to free this memory */
802                                 tmp->tpnt = tpnt1;
803                                 tmp->next = tcurr->init_fini;
804                                 tcurr->init_fini = tmp;
805
806                                 tpnt1->rtld_flags = unlazy | RTLD_GLOBAL;
807
808                                 _dl_debug_early("Loading: (%x) %s\n", DL_LOADADDR_BASE(tpnt1->loadaddr), tpnt1->libname);
809
810 #ifdef __LDSO_LDD_SUPPORT__
811                                 if (trace_loaded_objects &&
812                                     tpnt1->usage_count == 1) {
813                                         _dl_dprintf(1, "\t%s => %s (%x)\n",
814                                                     lpntstr, tpnt1->libname,
815                                                     DL_LOADADDR_BASE(tpnt1->loadaddr));
816                                 }
817 #endif
818                         }
819                 }
820         }
821         _dl_unmap_cache();
822
823         --nlist; /* Exclude the application. */
824         init_fini_list = _dl_malloc(nlist * sizeof(struct elf_resolve *));
825         i = 0;
826         for (tcurr = _dl_loaded_modules->next; tcurr; tcurr = tcurr->next) {
827                 init_fini_list[i++] = tcurr;
828         }
829
830         /* Sort the INIT/FINI list in dependency order. */
831         for (tcurr = _dl_loaded_modules->next; tcurr; tcurr = tcurr->next) {
832                 unsigned int j, k;
833
834                 for (j = 0; init_fini_list[j] != tcurr; ++j)
835                         /* Empty */;
836                 for (k = j + 1; k < nlist; ++k) {
837                         struct init_fini_list *runp = init_fini_list[k]->init_fini;
838
839                         for (; runp; runp = runp->next) {
840                                 if (runp->tpnt == tcurr) {
841                                         struct elf_resolve *here = init_fini_list[k];
842                                         _dl_if_debug_dprint("Move %s from pos %d to %d in INIT/FINI list\n", here->libname, k, j);
843                                         for (i = (k - j); i; --i)
844                                                 init_fini_list[i+j] = init_fini_list[i+j-1];
845                                         init_fini_list[j] = here;
846                                         ++j;
847                                         break;
848                                 }
849                         }
850                 }
851         }
852 #ifdef __SUPPORT_LD_DEBUG__
853         if (_dl_debug) {
854                 _dl_dprintf(_dl_debug_file, "\nINIT/FINI order and dependencies:\n");
855                 for (i = 0; i < nlist; i++) {
856                         struct init_fini_list *tmp;
857
858                         _dl_dprintf(_dl_debug_file, "lib: %s has deps:\n",
859                                     init_fini_list[i]->libname);
860                         tmp = init_fini_list[i]->init_fini;
861                         for (; tmp; tmp = tmp->next)
862                                 _dl_dprintf(_dl_debug_file, " %s ", tmp->tpnt->libname);
863                         _dl_dprintf(_dl_debug_file, "\n");
864                 }
865         }
866 #endif
867
868         /*
869          * If the program interpreter is not in the module chain, add it.
870          * This will be required for dlopen to be able to access the internal
871          * functions in the dynamic linker and to relocate the interpreter
872          * again once all libs are loaded.
873          */
874         if (tpnt) {
875                 ElfW(Ehdr) *epnt = (ElfW(Ehdr) *) auxvt[AT_BASE].a_un.a_val;
876                 ElfW(Phdr) *myppnt = (ElfW(Phdr) *) DL_RELOC_ADDR(load_addr, epnt->e_phoff);
877                 int j;
878
879                 tpnt = _dl_add_elf_hash_table(tpnt->libname, load_addr,
880                                               tpnt->dynamic_info,
881                                               (unsigned long)tpnt->dynamic_addr,
882                                               0);
883
884                 if (_dl_stat(tpnt->libname, &st) >= 0) {
885                         tpnt->st_dev = st.st_dev;
886                         tpnt->st_ino = st.st_ino;
887                 }
888                 tpnt->n_phent = epnt->e_phnum;
889                 tpnt->ppnt = myppnt;
890                 for (j = 0; j < epnt->e_phnum; j++, myppnt++) {
891                         if (myppnt->p_type ==  PT_GNU_RELRO) {
892                                 tpnt->relro_addr = myppnt->p_vaddr;
893                                 tpnt->relro_size = myppnt->p_memsz;
894                                 break;
895                         }
896                 }
897                 tpnt->libtype = program_interpreter;
898                 tpnt->usage_count++;
899                 tpnt->symbol_scope = _dl_symbol_tables;
900                 if (rpnt) {
901                         rpnt->next = _dl_zalloc(sizeof(struct dyn_elf));
902                         rpnt->next->prev = rpnt;
903                         rpnt = rpnt->next;
904                 } else {
905                         rpnt = _dl_zalloc(sizeof(struct dyn_elf));
906                 }
907                 rpnt->dyn = tpnt;
908                 tpnt->rtld_flags = RTLD_NOW | RTLD_GLOBAL; /* Must not be LAZY */
909 #ifdef RERELOCATE_LDSO
910                 /* Only rerelocate functions for now. */
911                 tpnt->init_flag = RELOCS_DONE;
912                 lpnt = (unsigned long *) (tpnt->dynamic_info[DT_PLTGOT]);
913 # ifdef ALLOW_ZERO_PLTGOT
914                 if (tpnt->dynamic_info[DT_PLTGOT])
915 # endif
916                         INIT_GOT(lpnt, tpnt);
917 #else
918                 tpnt->init_flag = RELOCS_DONE | JMP_RELOCS_DONE;
919 #endif
920                 tpnt = NULL;
921         }
922
923 #ifdef __LDSO_LDD_SUPPORT__
924         /* End of the line for ldd.... */
925         if (trace_loaded_objects) {
926                 _dl_dprintf(1, "\t%s => %s (%x)\n",
927                             rpnt->dyn->libname + _dl_strlen(_dl_ldsopath) + 1,
928                             rpnt->dyn->libname, DL_LOADADDR_BASE(rpnt->dyn->loadaddr));
929                 _dl_exit(0);
930         }
931 #endif
932
933 #if USE_TLS
934         /* We do not initialize any of the TLS functionality unless any of the
935          * initial modules uses TLS.  This makes dynamic loading of modules with
936          * TLS impossible, but to support it requires either eagerly doing setup
937          * now or lazily doing it later.  Doing it now makes us incompatible with
938          * an old kernel that can't perform TLS_INIT_TP, even if no TLS is ever
939          * used.  Trying to do it lazily is too hairy to try when there could be
940          * multiple threads (from a non-TLS-using libpthread).  */
941         bool was_tls_init_tp_called = tls_init_tp_called;
942         if (tcbp == NULL) {
943                 _dl_debug_early("Calling init_tls()!\n");
944                 tcbp = init_tls ();
945         }
946 #endif
947
948         _dl_debug_early("Beginning relocation fixups\n");
949
950 #ifdef __mips__
951         /*
952          * Relocation of the GOT entries for MIPS have to be done
953          * after all the libraries have been loaded.
954          */
955         _dl_perform_mips_global_got_relocations(_dl_loaded_modules, !unlazy);
956 #endif
957
958         /*
959          * OK, now all of the kids are tucked into bed in their proper
960          * addresses.  Now we go through and look for REL and RELA records that
961          * indicate fixups to the GOT tables.  We need to do this in reverse
962          * order so that COPY directives work correctly.
963          */
964         if (_dl_symbol_tables)
965                 if (_dl_fixup(_dl_symbol_tables, unlazy))
966                         _dl_exit(-1);
967
968         for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) {
969                 if (tpnt->relro_size)
970                         _dl_protect_relro (tpnt);
971         }
972
973 #if USE_TLS
974         if (!was_tls_init_tp_called && _dl_tls_max_dtv_idx > 0)
975                 ++_dl_tls_generation;
976
977         _dl_debug_early("Calling _dl_allocate_tls_init()!\n");
978
979         /* Now that we have completed relocation, the initializer data
980            for the TLS blocks has its final values and we can copy them
981            into the main thread's TLS area, which we allocated above.  */
982         _dl_allocate_tls_init (tcbp);
983
984         /* And finally install it for the main thread.  If ld.so itself uses
985            TLS we know the thread pointer was initialized earlier.  */
986         if (! tls_init_tp_called) {
987                 const char *lossage = (char *) TLS_INIT_TP (tcbp, USE___THREAD);
988                 if (__builtin_expect (lossage != NULL, 0)) {
989                         _dl_debug_early("cannot set up thread-local storage: %s\n", lossage);
990                         _dl_exit(30);
991                 }
992         }
993 #endif /* USE_TLS */
994
995         /* OK, at this point things are pretty much ready to run.  Now we need
996          * to touch up a few items that are required, and then we can let the
997          * user application have at it.  Note that the dynamic linker itself
998          * is not guaranteed to be fully dynamicly linked if we are using
999          * ld.so.1, so we have to look up each symbol individually.
1000          */
1001
1002         _dl_envp = (unsigned long *) (intptr_t) _dl_find_hash(__C_SYMBOL_PREFIX__ "__environ", _dl_symbol_tables, NULL, 0, NULL);
1003         if (_dl_envp)
1004                 *_dl_envp = (unsigned long) envp;
1005
1006 #ifndef __FORCE_SHAREABLE_TEXT_SEGMENTS__
1007         {
1008                 unsigned int j;
1009                 ElfW(Phdr) *myppnt;
1010
1011                 /* We had to set the protections of all pages to R/W for
1012                  * dynamic linking.  Set text pages back to R/O.
1013                  */
1014                 for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) {
1015                         for (myppnt = tpnt->ppnt, j = 0; j < tpnt->n_phent; j++, myppnt++) {
1016                                 if (myppnt->p_type == PT_LOAD && !(myppnt->p_flags & PF_W) && tpnt->dynamic_info[DT_TEXTREL]) {
1017                                         _dl_mprotect((void *) (DL_RELOC_ADDR(tpnt->loadaddr, myppnt->p_vaddr) & PAGE_ALIGN),
1018                                                         (myppnt->p_vaddr & ADDR_ALIGN) + (unsigned long) myppnt->p_filesz, LXFLAGS(myppnt->p_flags));
1019                                 }
1020                         }
1021                 }
1022
1023         }
1024 #endif
1025         /* Notify the debugger we have added some objects. */
1026         _dl_debug_addr->r_state = RT_ADD;
1027         _dl_debug_state();
1028
1029         /* Run pre-initialization functions for the executable.  */
1030         _dl_run_array_forward(_dl_loaded_modules->dynamic_info[DT_PREINIT_ARRAY],
1031                               _dl_loaded_modules->dynamic_info[DT_PREINIT_ARRAYSZ],
1032                               _dl_loaded_modules->loadaddr);
1033
1034         /* Run initialization functions for loaded objects.  For the
1035            main executable, they will be run from __uClibc_main.  */
1036         for (i = nlist; i; --i) {
1037                 tpnt = init_fini_list[i-1];
1038                 tpnt->init_fini = NULL; /* Clear, since alloca was used */
1039                 if (tpnt->init_flag & INIT_FUNCS_CALLED)
1040                         continue;
1041                 tpnt->init_flag |= INIT_FUNCS_CALLED;
1042
1043                 if (tpnt->dynamic_info[DT_INIT]) {
1044                         void (*dl_elf_func) (void);
1045
1046                         dl_elf_func = (void (*)(void)) DL_RELOC_ADDR(tpnt->loadaddr, tpnt->dynamic_info[DT_INIT]);
1047
1048                         _dl_if_debug_dprint("calling INIT: %s\n\n", tpnt->libname);
1049
1050                         DL_CALL_FUNC_AT_ADDR (dl_elf_func, tpnt->loadaddr, (void(*)(void)));
1051                 }
1052
1053                 _dl_run_init_array(tpnt);
1054         }
1055
1056         /* Find the real malloc function and make ldso functions use that from now on */
1057         _dl_malloc_function = (void* (*)(size_t)) (intptr_t) _dl_find_hash(__C_SYMBOL_PREFIX__ "malloc",
1058                         _dl_symbol_tables, NULL, ELF_RTYPE_CLASS_PLT, NULL);
1059
1060 #if USE_TLS
1061         /* Find the real functions and make ldso functions use them from now on */
1062         _dl_calloc_function = (void* (*)(size_t, size_t)) (intptr_t)
1063                 _dl_find_hash(__C_SYMBOL_PREFIX__ "calloc", _dl_symbol_tables, NULL, ELF_RTYPE_CLASS_PLT, NULL);
1064
1065         _dl_realloc_function = (void* (*)(void *, size_t)) (intptr_t)
1066                 _dl_find_hash(__C_SYMBOL_PREFIX__ "realloc", _dl_symbol_tables, NULL, ELF_RTYPE_CLASS_PLT, NULL);
1067
1068         _dl_free_function = (void (*)(void *)) (intptr_t)
1069                 _dl_find_hash(__C_SYMBOL_PREFIX__ "free", _dl_symbol_tables, NULL, ELF_RTYPE_CLASS_PLT, NULL);
1070
1071         _dl_memalign_function = (void* (*)(size_t, size_t)) (intptr_t)
1072                 _dl_find_hash(__C_SYMBOL_PREFIX__ "memalign", _dl_symbol_tables, NULL, ELF_RTYPE_CLASS_PLT, NULL);
1073
1074 #endif
1075
1076         /* Notify the debugger that all objects are now mapped in.  */
1077         _dl_debug_addr->r_state = RT_CONSISTENT;
1078         _dl_debug_state();
1079 }
1080
1081 #include "dl-hash.c"
1082 #include "dl-elf.c"