OSDN Git Service

ldso/: tls support for dynamic linker
[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 #if USE_TLS
223 void * _dl_memalign (size_t __boundary, size_t __size)
224 {
225         void *result;
226         int i = 0;
227         size_t delta;
228         size_t rounded = 0;
229
230         if (_dl_memalign_function)
231                 return (*_dl_memalign_function) (__boundary, __size);
232
233         while (rounded < __boundary) {
234                 rounded = (1 << i++);
235         }
236
237         delta = (((size_t) _dl_malloc_addr + __size) & (rounded - 1));
238
239         if ((result = _dl_malloc(rounded - delta)) == NULL)
240                 return result;
241
242         result = _dl_malloc(__size);
243
244         return result;
245 }
246 #endif
247
248 static void __attribute__ ((destructor)) __attribute_used__ _dl_fini(void)
249 {
250         unsigned int i;
251         struct elf_resolve * tpnt;
252
253         for (i = 0; i < nlist; ++i) {
254                 tpnt = init_fini_list[i];
255                 if (tpnt->init_flag & FINI_FUNCS_CALLED)
256                         continue;
257                 tpnt->init_flag |= FINI_FUNCS_CALLED;
258                 _dl_run_fini_array(tpnt);
259                 if (tpnt->dynamic_info[DT_FINI]) {
260                         void (*dl_elf_func) (void);
261
262                         dl_elf_func = (void (*)(void)) (intptr_t) DL_RELOC_ADDR(tpnt->loadaddr, tpnt->dynamic_info[DT_FINI]);
263                         _dl_if_debug_dprint("\ncalling FINI: %s\n\n", tpnt->libname);
264                         DL_CALL_FUNC_AT_ADDR (dl_elf_func, tpnt->loadaddr, (void(*)(void)));
265                 }
266         }
267 }
268
269 void _dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr,
270                           ElfW(auxv_t) auxvt[AT_EGID + 1], char **envp,
271                           char **argv
272                           DL_GET_READY_TO_RUN_EXTRA_PARMS)
273 {
274         ElfW(Addr) app_mapaddr = 0;
275         ElfW(Phdr) *ppnt;
276         ElfW(Dyn) *dpnt;
277         char *lpntstr;
278         unsigned int i;
279         int unlazy = 0, trace_loaded_objects = 0;
280         struct dyn_elf *rpnt;
281         struct elf_resolve *tcurr;
282         struct elf_resolve *tpnt1;
283         struct elf_resolve app_tpnt_tmp;
284         struct elf_resolve *app_tpnt = &app_tpnt_tmp;
285         struct r_debug *debug_addr;
286         unsigned long *lpnt;
287         unsigned long *_dl_envp;                /* The environment address */
288         ElfW(Addr) relro_addr = 0;
289         size_t relro_size = 0;
290         struct stat st;
291 #if USE_TLS
292         void *tcbp = NULL;
293 #endif
294         
295
296         /* Wahoo!!! We managed to make a function call!  Get malloc
297          * setup so we can use _dl_dprintf() to print debug noise
298          * instead of the SEND_STDERR macros used in dl-startup.c */
299
300         _dl_memset(app_tpnt, 0, sizeof(*app_tpnt));
301
302         /* Store the page size for later use */
303         _dl_pagesize = (auxvt[AT_PAGESZ].a_un.a_val) ? (size_t) auxvt[AT_PAGESZ].a_un.a_val : PAGE_SIZE;
304         /* Make it so _dl_malloc can use the page of memory we have already
305          * allocated.  We shouldn't need to grab any more memory.  This must
306          * be first since things like _dl_dprintf() use _dl_malloc()...
307          */
308         _dl_malloc_addr = (unsigned char *)_dl_pagesize;
309         _dl_mmap_zero = 0;
310
311         /* Wahoo!!! */
312         _dl_debug_early("Cool, ldso survived making function calls\n");
313
314         /* Now we have done the mandatory linking of some things.  We are now
315          * free to start using global variables, since these things have all
316          * been fixed up by now.  Still no function calls outside of this
317          * library, since the dynamic resolver is not yet ready.
318          */
319         if (argv[0]) {
320                 _dl_progname = argv[0];
321         }
322
323         if (_start == (void *) auxvt[AT_ENTRY].a_un.a_val) {
324                 _dl_dprintf(_dl_debug_file, "Standalone execution is not supported yet\n");
325                 _dl_exit(1);
326         }
327
328         /* Start to build the tables of the modules that are required for
329          * this beast to run.  We start with the basic executable, and then
330          * go from there.  Eventually we will run across ourself, and we
331          * will need to properly deal with that as well.
332          */
333         rpnt = NULL;
334         if (_dl_getenv("LD_BIND_NOW", envp))
335                 unlazy = RTLD_NOW;
336
337         /* Now we need to figure out what kind of options are selected.
338          * Note that for SUID programs we ignore the settings in
339          * LD_LIBRARY_PATH.
340          */
341         if ((auxvt[AT_UID].a_un.a_val == (size_t)-1 && _dl_suid_ok()) ||
342             (auxvt[AT_UID].a_un.a_val != (size_t)-1 &&
343              auxvt[AT_UID].a_un.a_val == auxvt[AT_EUID].a_un.a_val &&
344              auxvt[AT_GID].a_un.a_val == auxvt[AT_EGID].a_un.a_val)) {
345                 _dl_secure = 0;
346                 _dl_preload = _dl_getenv("LD_PRELOAD", envp);
347                 _dl_library_path = _dl_getenv("LD_LIBRARY_PATH", envp);
348         } else {
349                 static const char unsecure_envvars[] =
350 #ifdef EXTRA_UNSECURE_ENVVARS
351                         EXTRA_UNSECURE_ENVVARS
352 #endif
353                         UNSECURE_ENVVARS;
354                 const char *nextp;
355                 _dl_secure = 1;
356
357                 nextp = unsecure_envvars;
358                 do {
359                         _dl_unsetenv (nextp, envp);
360                         /* We could use rawmemchr but this need not be fast.  */
361                         nextp = _dl_strchr(nextp, '\0') + 1;
362                 } while (*nextp != '\0');
363                 _dl_preload = NULL;
364                 _dl_library_path = NULL;
365                 /* SUID binaries can be exploited if they do LAZY relocation. */
366                 unlazy = RTLD_NOW;
367         }
368
369 #if USE_TLS
370         _dl_error_catch_tsd = &_dl_initial_error_catch_tsd;
371         _dl_init_static_tls = &_dl_nothread_init_static_tls;
372 #endif
373
374 #ifdef __UCLIBC_HAS_SSP__
375         /* Set up the stack checker's canary.  */
376         stack_chk_guard = _dl_setup_stack_chk_guard ();
377 # ifdef THREAD_SET_STACK_GUARD
378         THREAD_SET_STACK_GUARD (stack_chk_guard);
379 #  ifdef __UCLIBC_HAS_SSP_COMPAT__
380         __guard = stack_chk_guard;
381 #  endif
382 # else
383         __stack_chk_guard = stack_chk_guard;
384 # endif
385 #endif
386
387         /* At this point we are now free to examine the user application,
388          * and figure out which libraries are supposed to be called.  Until
389          * we have this list, we will not be completely ready for dynamic
390          * linking.
391          */
392
393         /* Find the runtime load address of the main executable.  This may be
394          * different from what the ELF header says for ET_DYN/PIE executables.
395          */
396         {
397                 unsigned int idx;
398                 ElfW(Phdr) *phdr = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_val;
399
400                 for (idx = 0; idx < auxvt[AT_PHNUM].a_un.a_val; idx++, phdr++)
401                         if (phdr->p_type == PT_PHDR) {
402                                 DL_INIT_LOADADDR_PROG(app_tpnt->loadaddr, auxvt[AT_PHDR].a_un.a_val - phdr->p_vaddr);
403                                 break;
404                         }
405
406                 if (DL_LOADADDR_BASE(app_tpnt->loadaddr))
407                         _dl_debug_early("Position Independent Executable: "
408                                         "app_tpnt->loadaddr=%x\n", DL_LOADADDR_BASE(app_tpnt->loadaddr));
409         }
410
411         /*
412          * This is used by gdb to locate the chain of shared libraries that are
413          * currently loaded.
414          */
415         debug_addr = _dl_zalloc(sizeof(struct r_debug));
416
417         ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_val;
418         for (i = 0; i < auxvt[AT_PHNUM].a_un.a_val; i++, ppnt++) {
419                 if (ppnt->p_type == PT_GNU_RELRO) {
420                         relro_addr = ppnt->p_vaddr;
421                         relro_size = ppnt->p_memsz;
422                 }
423                 if (!app_mapaddr && (ppnt->p_type == PT_LOAD)) {
424                         app_mapaddr = DL_RELOC_ADDR (app_tpnt->loadaddr, ppnt->p_vaddr);
425                 }
426                 if (ppnt->p_type == PT_DYNAMIC) {
427                         dpnt = (ElfW(Dyn) *) DL_RELOC_ADDR(app_tpnt->loadaddr, ppnt->p_vaddr);
428                         _dl_parse_dynamic_info(dpnt, app_tpnt->dynamic_info, debug_addr, app_tpnt->loadaddr);
429 #ifndef __FORCE_SHAREABLE_TEXT_SEGMENTS__
430                         /* Ugly, ugly.  We need to call mprotect to change the
431                          * protection of the text pages so that we can do the
432                          * dynamic linking.  We can set the protection back
433                          * again once we are done.
434                          */
435                         _dl_debug_early("calling mprotect on the application program\n");
436                         /* Now cover the application program. */
437                         if (app_tpnt->dynamic_info[DT_TEXTREL]) {
438                                 ElfW(Phdr) *ppnt_outer = ppnt;
439                                 ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_val;
440                                 for (i = 0; i < auxvt[AT_PHNUM].a_un.a_val; i++, ppnt++) {
441                                         if (ppnt->p_type == PT_LOAD && !(ppnt->p_flags & PF_W))
442                                                 _dl_mprotect((void *) (DL_RELOC_ADDR(app_tpnt->loadaddr, ppnt->p_vaddr) & PAGE_ALIGN),
443                                                              (DL_RELOC_ADDR(app_tpnt->loadaddr, ppnt->p_vaddr) & ADDR_ALIGN) +
444                                                              (unsigned long) ppnt->p_filesz,
445                                                              PROT_READ | PROT_WRITE | PROT_EXEC);
446                                 }
447                                 ppnt = ppnt_outer;
448                         }
449 #else
450                         if (app_tpnt->dynamic_info[DT_TEXTREL]) {
451                                 _dl_dprintf(_dl_debug_file, "Can't modify application's text section; use the GCC option -fPIE for position-independent executables.\n");
452                                 _dl_exit(1);
453                         }
454 #endif
455
456 #ifndef ALLOW_ZERO_PLTGOT
457                         /* make sure it's really there. */
458                         if (app_tpnt->dynamic_info[DT_PLTGOT] == 0)
459                                 continue;
460 #endif
461                         /* OK, we have what we need - slip this one into the list. */
462                         app_tpnt = _dl_add_elf_hash_table(_dl_progname, app_tpnt->loadaddr,
463                                         app_tpnt->dynamic_info,
464                                         (unsigned long) DL_RELOC_ADDR(app_tpnt->loadaddr, ppnt->p_vaddr),
465                                         ppnt->p_filesz);
466                         _dl_loaded_modules->libtype = elf_executable;
467                         _dl_loaded_modules->ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_val;
468                         _dl_loaded_modules->n_phent = auxvt[AT_PHNUM].a_un.a_val;
469                         _dl_symbol_tables = rpnt = _dl_zalloc(sizeof(struct dyn_elf));
470                         rpnt->dyn = _dl_loaded_modules;
471                         app_tpnt->mapaddr = app_mapaddr;
472                         app_tpnt->rtld_flags = unlazy | RTLD_GLOBAL;
473                         app_tpnt->usage_count++;
474                         app_tpnt->symbol_scope = _dl_symbol_tables;
475                         lpnt = (unsigned long *) (app_tpnt->dynamic_info[DT_PLTGOT]);
476 #ifdef ALLOW_ZERO_PLTGOT
477                         if (lpnt)
478 #endif
479                                 INIT_GOT(lpnt, _dl_loaded_modules);
480                 }
481
482                 /* OK, fill this in - we did not have this before */
483                 if (ppnt->p_type == PT_INTERP) {
484                         char *ptmp;
485
486                         tpnt->libname = (char *) DL_RELOC_ADDR(app_tpnt->loadaddr, ppnt->p_vaddr);
487
488                         /* Store the path where the shared lib loader was found
489                          * for later use
490                          */
491                         _dl_ldsopath = _dl_strdup(tpnt->libname);
492                         ptmp = _dl_strrchr(_dl_ldsopath, '/');
493                         if (ptmp != _dl_ldsopath)
494                                 *ptmp = '\0';
495
496                         _dl_debug_early("Lib Loader: (%x) %s\n", (unsigned) DL_LOADADDR_BASE(tpnt->loadaddr), tpnt->libname);
497                 }
498
499                 /* Discover any TLS sections if the target supports them. */
500                 if (ppnt->p_type == PT_TLS) {
501 #if USE_TLS
502                         if (ppnt->p_memsz > 0) {
503                                 app_tpnt->l_tls_blocksize = ppnt->p_memsz;
504                                 app_tpnt->l_tls_align = ppnt->p_align;
505                                 if (ppnt->p_align == 0)
506                                         app_tpnt->l_tls_firstbyte_offset = 0;
507                                 else
508                                         app_tpnt->l_tls_firstbyte_offset =
509                                                 (ppnt->p_vaddr & (ppnt->p_align - 1));
510                                 app_tpnt->l_tls_initimage_size = ppnt->p_filesz;
511                                 app_tpnt->l_tls_initimage = (void *) ppnt->p_vaddr;
512
513                                 /* This image gets the ID one.  */
514                                 _dl_tls_max_dtv_idx = app_tpnt->l_tls_modid = 1;
515
516                         }
517                         _dl_debug_early("Found TLS header for appplication program\n");
518                         break;
519 #else
520                         _dl_dprintf(_dl_debug_file, "Program uses unsupported TLS data!\n");
521                         _dl_exit(1);
522 #endif
523                 }
524         }
525         app_tpnt->relro_addr = relro_addr;
526         app_tpnt->relro_size = relro_size;
527
528 #if USE_TLS
529         /*
530          * Adjust the address of the TLS initialization image in
531          * case the executable is actually an ET_DYN object.
532          */
533         if (app_tpnt->l_tls_initimage != NULL)
534         {
535 #ifdef __SUPPORT_LD_DEBUG_EARLY__
536                 unsigned int tmp = (unsigned int) app_tpnt->l_tls_initimage;
537 #endif
538                 app_tpnt->l_tls_initimage =
539                         (char *) app_tpnt->l_tls_initimage + app_tpnt->loadaddr;
540                 _dl_debug_early("Relocated TLS initial image from %x to %x (size = %x)\n", tmp, app_tpnt->l_tls_initimage, app_tpnt->l_tls_initimage_size);
541
542         }
543 #endif
544
545 #ifdef __SUPPORT_LD_DEBUG__
546         _dl_debug = _dl_getenv("LD_DEBUG", envp);
547         if (_dl_debug) {
548                 if (_dl_strstr(_dl_debug, "all")) {
549                         _dl_debug_detail = _dl_debug_move = _dl_debug_symbols
550                                 = _dl_debug_reloc = _dl_debug_bindings = _dl_debug_nofixups = (void*)1;
551                 } else {
552                         _dl_debug_detail   = _dl_strstr(_dl_debug, "detail");
553                         _dl_debug_move     = _dl_strstr(_dl_debug, "move");
554                         _dl_debug_symbols  = _dl_strstr(_dl_debug, "sym");
555                         _dl_debug_reloc    = _dl_strstr(_dl_debug, "reloc");
556                         _dl_debug_nofixups = _dl_strstr(_dl_debug, "nofix");
557                         _dl_debug_bindings = _dl_strstr(_dl_debug, "bind");
558                 }
559         }
560
561         {
562                 const char *dl_debug_output;
563
564                 dl_debug_output = _dl_getenv("LD_DEBUG_OUTPUT", envp);
565
566                 if (dl_debug_output) {
567                         char tmp[22], *tmp1, *filename;
568                         int len1, len2;
569
570                         _dl_memset(tmp, 0, sizeof(tmp));
571                         tmp1 = _dl_simple_ltoa( tmp, (unsigned long)_dl_getpid());
572
573                         len1 = _dl_strlen(dl_debug_output);
574                         len2 = _dl_strlen(tmp1);
575
576                         filename = _dl_malloc(len1 + len2 + 2);
577
578                         if (filename) {
579                                 _dl_strcpy (filename, dl_debug_output);
580                                 filename[len1] = '.';
581                                 _dl_strcpy (&filename[len1+1], tmp1);
582
583                                 _dl_debug_file = _dl_open(filename, O_WRONLY|O_CREAT, 0644);
584                                 if (_dl_debug_file < 0) {
585                                         _dl_debug_file = 2;
586                                         _dl_dprintf(_dl_debug_file, "can't open file: '%s'\n",filename);
587                                 }
588                         }
589                 }
590         }
591 #endif
592
593         if (_dl_getenv("LD_TRACE_LOADED_OBJECTS", envp) != NULL) {
594                 trace_loaded_objects++;
595         }
596
597 #ifndef __LDSO_LDD_SUPPORT__
598         if (trace_loaded_objects) {
599                 _dl_dprintf(_dl_debug_file, "Use the ldd provided by uClibc\n");
600                 _dl_exit(1);
601         }
602 #endif
603
604         /*
605          * OK, fix one more thing - set up debug_addr so it will point
606          * to our chain.  Later we may need to fill in more fields, but this
607          * should be enough for now.
608          */
609         debug_addr->r_map = (struct link_map *) _dl_loaded_modules;
610         debug_addr->r_version = 1;
611         debug_addr->r_ldbase = (ElfW(Addr)) DL_LOADADDR_BASE(load_addr);
612         debug_addr->r_brk = (unsigned long) &_dl_debug_state;
613         _dl_debug_addr = debug_addr;
614
615         /* Do not notify the debugger until the interpreter is in the list */
616
617         /* OK, we now have the application in the list, and we have some
618          * basic stuff in place.  Now search through the list for other shared
619          * libraries that should be loaded, and insert them on the list in the
620          * correct order.
621          */
622
623         _dl_map_cache();
624
625         if (_dl_preload) {
626                 char c, *str, *str2;
627
628                 str = _dl_preload;
629                 while (*str == ':' || *str == ' ' || *str == '\t')
630                         str++;
631
632                 while (*str) {
633                         str2 = str;
634                         while (*str2 && *str2 != ':' && *str2 != ' ' && *str2 != '\t')
635                                 str2++;
636                         c = *str2;
637                         *str2 = '\0';
638
639                         if (!_dl_secure || _dl_strchr(str, '/') == NULL) {
640                                 _dl_if_debug_dprint("\tfile='%s';  needed by '%s'\n", str, _dl_progname);
641
642                                 tpnt1 = _dl_load_shared_library(_dl_secure, &rpnt, NULL, str, trace_loaded_objects);
643                                 if (!tpnt1) {
644 #ifdef __LDSO_LDD_SUPPORT__
645                                         if (trace_loaded_objects)
646                                                 _dl_dprintf(1, "\t%s => not found\n", str);
647                                         else
648 #endif
649                                         {
650                                                 _dl_dprintf(_dl_debug_file, "%s: can't load " "library '%s'\n", _dl_progname, str);
651                                                 _dl_exit(15);
652                                         }
653                                 } else {
654                                         tpnt1->rtld_flags = unlazy | RTLD_GLOBAL;
655
656                                         _dl_debug_early("Loading: (%x) %s\n", DL_LOADADDR_BASE(tpnt1->loadaddr), tpnt1->libname);
657
658 #ifdef __LDSO_LDD_SUPPORT__
659                                         if (trace_loaded_objects &&
660                                             tpnt1->usage_count == 1) {
661                                                 /* This is a real hack to make
662                                                  * ldd not print the library
663                                                  * itself when run on a
664                                                  * library.
665                                                  */
666                                                 if (_dl_strcmp(_dl_progname, str) != 0)
667                                                         _dl_dprintf(1, "\t%s => %s (%x)\n", str, tpnt1->libname,
668                                                                     DL_LOADADDR_BASE(tpnt1->loadaddr));
669                                         }
670 #endif
671                                 }
672                         }
673
674                         *str2 = c;
675                         str = str2;
676                         while (*str == ':' || *str == ' ' || *str == '\t')
677                                 str++;
678                 }
679         }
680
681 #ifdef __LDSO_PRELOAD_FILE_SUPPORT__
682         do {
683                 struct stat st;
684                 char *preload;
685                 int fd;
686                 char c, *cp, *cp2;
687
688                 if (_dl_stat(LDSO_PRELOAD, &st) || st.st_size == 0) {
689                         break;
690                 }
691
692                 if ((fd = _dl_open(LDSO_PRELOAD, O_RDONLY, 0)) < 0) {
693                         _dl_dprintf(_dl_debug_file, "%s: can't open file '%s'\n",
694                                     _dl_progname, LDSO_PRELOAD);
695                         break;
696                 }
697
698                 preload = (caddr_t) _dl_mmap(0, st.st_size + 1,
699                                              PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
700                 _dl_close(fd);
701                 if (preload == (caddr_t) -1) {
702                         _dl_dprintf(_dl_debug_file, "%s:%i: can't map '%s'\n",
703                                     _dl_progname, __LINE__, LDSO_PRELOAD);
704                         break;
705                 }
706
707                 /* convert all separators and comments to spaces */
708                 for (cp = preload; *cp; /*nada */ ) {
709                         if (*cp == ':' || *cp == '\t' || *cp == '\n') {
710                                 *cp++ = ' ';
711                         } else if (*cp == '#') {
712                                 do {
713                                         *cp++ = ' ';
714                                 } while (*cp != '\n' && *cp != '\0');
715                         } else {
716                                 cp++;
717                         }
718                 }
719
720                 /* find start of first library */
721                 for (cp = preload; *cp && *cp == ' '; cp++)
722                         /*nada */ ;
723
724                 while (*cp) {
725                         /* find end of library */
726                         for (cp2 = cp; *cp && *cp != ' '; cp++)
727                                 /*nada */ ;
728                         c = *cp;
729                         *cp = '\0';
730
731                         _dl_if_debug_dprint("\tfile='%s';  needed by '%s'\n", cp2, _dl_progname);
732
733                         tpnt1 = _dl_load_shared_library(0, &rpnt, NULL, cp2, trace_loaded_objects);
734                         if (!tpnt1) {
735 #ifdef __LDSO_LDD_SUPPORT__
736                                 if (trace_loaded_objects)
737                                         _dl_dprintf(1, "\t%s => not found\n", cp2);
738                                 else
739 #endif
740                                 {
741                                         _dl_dprintf(_dl_debug_file, "%s: can't load library '%s'\n", _dl_progname, cp2);
742                                         _dl_exit(15);
743                                 }
744                         } else {
745                                 tpnt1->rtld_flags = unlazy | RTLD_GLOBAL;
746
747                                 _dl_debug_early("Loading: (%x) %s\n", DL_LOADADDR_BASE(tpnt1->loadaddr), tpnt1->libname);
748
749 #ifdef __LDSO_LDD_SUPPORT__
750                                 if (trace_loaded_objects &&
751                                     tpnt1->usage_count == 1) {
752                                         _dl_dprintf(1, "\t%s => %s (%x)\n",
753                                                     cp2, tpnt1->libname,
754                                                     DL_LOADADDR_BASE(tpnt1->loadaddr));
755                                 }
756 #endif
757                         }
758
759                         /* find start of next library */
760                         *cp = c;
761                         for ( /*nada */ ; *cp && *cp == ' '; cp++)
762                                 /*nada */ ;
763                 }
764
765                 _dl_munmap(preload, st.st_size + 1);
766         } while (0);
767 #endif /* __LDSO_PRELOAD_FILE_SUPPORT__ */
768
769         nlist = 0;
770         for (tcurr = _dl_loaded_modules; tcurr; tcurr = tcurr->next) {
771                 ElfW(Dyn) *this_dpnt;
772
773                 nlist++;
774                 for (this_dpnt = (ElfW(Dyn) *) tcurr->dynamic_addr; this_dpnt->d_tag; this_dpnt++) {
775                         if (this_dpnt->d_tag == DT_NEEDED) {
776                                 char *name;
777                                 struct init_fini_list *tmp;
778
779                                 lpntstr = (char*) (tcurr->dynamic_info[DT_STRTAB] + this_dpnt->d_un.d_val);
780                                 name = _dl_get_last_path_component(lpntstr);
781                                 if (_dl_strcmp(name, UCLIBC_LDSO) == 0)
782                                         continue;
783
784                                 _dl_if_debug_dprint("\tfile='%s';  needed by '%s'\n", lpntstr, _dl_progname);
785
786                                 if (!(tpnt1 = _dl_load_shared_library(0, &rpnt, tcurr, lpntstr, trace_loaded_objects))) {
787 #ifdef __LDSO_LDD_SUPPORT__
788                                         if (trace_loaded_objects) {
789                                                 _dl_dprintf(1, "\t%s => not found\n", lpntstr);
790                                                 continue;
791                                         } else
792 #endif
793                                         {
794                                                 _dl_dprintf(_dl_debug_file, "%s: can't load library '%s'\n", _dl_progname, lpntstr);
795                                                 _dl_exit(16);
796                                         }
797                                 }
798
799                                 tmp = alloca(sizeof(struct init_fini_list)); /* Allocates on stack, no need to free this memory */
800                                 tmp->tpnt = tpnt1;
801                                 tmp->next = tcurr->init_fini;
802                                 tcurr->init_fini = tmp;
803
804                                 tpnt1->rtld_flags = unlazy | RTLD_GLOBAL;
805
806                                 _dl_debug_early("Loading: (%x) %s\n", DL_LOADADDR_BASE(tpnt1->loadaddr), tpnt1->libname);
807
808 #ifdef __LDSO_LDD_SUPPORT__
809                                 if (trace_loaded_objects &&
810                                     tpnt1->usage_count == 1) {
811                                         _dl_dprintf(1, "\t%s => %s (%x)\n",
812                                                     lpntstr, tpnt1->libname,
813                                                     DL_LOADADDR_BASE(tpnt1->loadaddr));
814                                 }
815 #endif
816                         }
817                 }
818         }
819         _dl_unmap_cache();
820
821         --nlist; /* Exclude the application. */
822         init_fini_list = _dl_malloc(nlist * sizeof(struct elf_resolve *));
823         i = 0;
824         for (tcurr = _dl_loaded_modules->next; tcurr; tcurr = tcurr->next) {
825                 init_fini_list[i++] = tcurr;
826         }
827
828         /* Sort the INIT/FINI list in dependency order. */
829         for (tcurr = _dl_loaded_modules->next; tcurr; tcurr = tcurr->next) {
830                 unsigned int j, k;
831
832                 for (j = 0; init_fini_list[j] != tcurr; ++j)
833                         /* Empty */;
834                 for (k = j + 1; k < nlist; ++k) {
835                         struct init_fini_list *runp = init_fini_list[k]->init_fini;
836
837                         for (; runp; runp = runp->next) {
838                                 if (runp->tpnt == tcurr) {
839                                         struct elf_resolve *here = init_fini_list[k];
840                                         _dl_if_debug_dprint("Move %s from pos %d to %d in INIT/FINI list\n", here->libname, k, j);
841                                         for (i = (k - j); i; --i)
842                                                 init_fini_list[i+j] = init_fini_list[i+j-1];
843                                         init_fini_list[j] = here;
844                                         ++j;
845                                         break;
846                                 }
847                         }
848                 }
849         }
850 #ifdef __SUPPORT_LD_DEBUG__
851         if (_dl_debug) {
852                 _dl_dprintf(_dl_debug_file, "\nINIT/FINI order and dependencies:\n");
853                 for (i = 0; i < nlist; i++) {
854                         struct init_fini_list *tmp;
855
856                         _dl_dprintf(_dl_debug_file, "lib: %s has deps:\n",
857                                     init_fini_list[i]->libname);
858                         tmp = init_fini_list[i]->init_fini;
859                         for (; tmp; tmp = tmp->next)
860                                 _dl_dprintf(_dl_debug_file, " %s ", tmp->tpnt->libname);
861                         _dl_dprintf(_dl_debug_file, "\n");
862                 }
863         }
864 #endif
865
866         /*
867          * If the program interpreter is not in the module chain, add it.
868          * This will be required for dlopen to be able to access the internal
869          * functions in the dynamic linker and to relocate the interpreter
870          * again once all libs are loaded.
871          */
872         if (tpnt) {
873                 ElfW(Ehdr) *epnt = (ElfW(Ehdr) *) auxvt[AT_BASE].a_un.a_val;
874                 ElfW(Phdr) *myppnt = (ElfW(Phdr) *) DL_RELOC_ADDR(load_addr, epnt->e_phoff);
875                 int j;
876
877                 tpnt = _dl_add_elf_hash_table(tpnt->libname, load_addr,
878                                               tpnt->dynamic_info,
879                                               (unsigned long)tpnt->dynamic_addr,
880                                               0);
881
882                 if (_dl_stat(tpnt->libname, &st) >= 0) {
883                         tpnt->st_dev = st.st_dev;
884                         tpnt->st_ino = st.st_ino;
885                 }
886                 tpnt->n_phent = epnt->e_phnum;
887                 tpnt->ppnt = myppnt;
888                 for (j = 0; j < epnt->e_phnum; j++, myppnt++) {
889                         if (myppnt->p_type ==  PT_GNU_RELRO) {
890                                 tpnt->relro_addr = myppnt->p_vaddr;
891                                 tpnt->relro_size = myppnt->p_memsz;
892                                 break;
893                         }
894                 }
895                 tpnt->libtype = program_interpreter;
896                 tpnt->usage_count++;
897                 tpnt->symbol_scope = _dl_symbol_tables;
898                 if (rpnt) {
899                         rpnt->next = _dl_zalloc(sizeof(struct dyn_elf));
900                         rpnt->next->prev = rpnt;
901                         rpnt = rpnt->next;
902                 } else {
903                         rpnt = _dl_zalloc(sizeof(struct dyn_elf));
904                 }
905                 rpnt->dyn = tpnt;
906                 tpnt->rtld_flags = RTLD_NOW | RTLD_GLOBAL; /* Must not be LAZY */
907 #ifdef RERELOCATE_LDSO
908                 /* Only rerelocate functions for now. */
909                 tpnt->init_flag = RELOCS_DONE;
910                 lpnt = (unsigned long *) (tpnt->dynamic_info[DT_PLTGOT]);
911 # ifdef ALLOW_ZERO_PLTGOT
912                 if (tpnt->dynamic_info[DT_PLTGOT])
913 # endif
914                         INIT_GOT(lpnt, tpnt);
915 #else
916                 tpnt->init_flag = RELOCS_DONE | JMP_RELOCS_DONE;
917 #endif
918                 tpnt = NULL;
919         }
920
921 #ifdef __LDSO_LDD_SUPPORT__
922         /* End of the line for ldd.... */
923         if (trace_loaded_objects) {
924                 _dl_dprintf(1, "\t%s => %s (%x)\n",
925                             rpnt->dyn->libname + _dl_strlen(_dl_ldsopath) + 1,
926                             rpnt->dyn->libname, DL_LOADADDR_BASE(rpnt->dyn->loadaddr));
927                 _dl_exit(0);
928         }
929 #endif
930
931 #if USE_TLS
932         /* We do not initialize any of the TLS functionality unless any of the
933          * initial modules uses TLS.  This makes dynamic loading of modules with
934          * TLS impossible, but to support it requires either eagerly doing setup
935          * now or lazily doing it later.  Doing it now makes us incompatible with
936          * an old kernel that can't perform TLS_INIT_TP, even if no TLS is ever
937          * used.  Trying to do it lazily is too hairy to try when there could be
938          * multiple threads (from a non-TLS-using libpthread).  */
939         bool was_tls_init_tp_called = tls_init_tp_called;
940         if (tcbp == NULL)
941         {
942                 _dl_debug_early("Calling init_tls()!\n");
943                 tcbp = init_tls ();
944         }
945 #endif
946
947         _dl_debug_early("Beginning relocation fixups\n");
948
949 #ifdef __mips__
950         /*
951          * Relocation of the GOT entries for MIPS have to be done
952          * after all the libraries have been loaded.
953          */
954         _dl_perform_mips_global_got_relocations(_dl_loaded_modules, !unlazy);
955 #endif
956
957         /*
958          * OK, now all of the kids are tucked into bed in their proper
959          * addresses.  Now we go through and look for REL and RELA records that
960          * indicate fixups to the GOT tables.  We need to do this in reverse
961          * order so that COPY directives work correctly.
962          */
963         if (_dl_symbol_tables)
964                 if (_dl_fixup(_dl_symbol_tables, unlazy))
965                         _dl_exit(-1);
966
967         for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) {
968                 if (tpnt->relro_size)
969                         _dl_protect_relro (tpnt);
970         }
971
972 #if USE_TLS
973         if (!was_tls_init_tp_called && _dl_tls_max_dtv_idx > 0)
974                 ++_dl_tls_generation;
975
976         _dl_debug_early("Calling _dl_allocate_tls_init()!\n");
977
978         /* Now that we have completed relocation, the initializer data
979            for the TLS blocks has its final values and we can copy them
980            into the main thread's TLS area, which we allocated above.  */
981         _dl_allocate_tls_init (tcbp);
982
983         /* And finally install it for the main thread.  If ld.so itself uses
984            TLS we know the thread pointer was initialized earlier.  */
985         if (! tls_init_tp_called)
986         {
987                 const char *lossage = (char *) TLS_INIT_TP (tcbp, USE___THREAD);
988                 if (__builtin_expect (lossage != NULL, 0))
989                 {
990                         _dl_debug_early("cannot set up thread-local storage: %s\n", lossage);
991                         _dl_exit(30);
992                 }
993         }
994 #endif /* USE_TLS */
995
996         /* OK, at this point things are pretty much ready to run.  Now we need
997          * to touch up a few items that are required, and then we can let the
998          * user application have at it.  Note that the dynamic linker itself
999          * is not guaranteed to be fully dynamicly linked if we are using
1000          * ld.so.1, so we have to look up each symbol individually.
1001          */
1002
1003         _dl_envp = (unsigned long *) (intptr_t) _dl_find_hash(__C_SYMBOL_PREFIX__ "__environ", _dl_symbol_tables, NULL, 0, NULL);
1004         if (_dl_envp)
1005                 *_dl_envp = (unsigned long) envp;
1006
1007 #ifndef __FORCE_SHAREABLE_TEXT_SEGMENTS__
1008         {
1009                 unsigned int j;
1010                 ElfW(Phdr) *myppnt;
1011
1012                 /* We had to set the protections of all pages to R/W for
1013                  * dynamic linking.  Set text pages back to R/O.
1014                  */
1015                 for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) {
1016                         for (myppnt = tpnt->ppnt, j = 0; j < tpnt->n_phent; j++, myppnt++) {
1017                                 if (myppnt->p_type == PT_LOAD && !(myppnt->p_flags & PF_W) && tpnt->dynamic_info[DT_TEXTREL]) {
1018                                         _dl_mprotect((void *) (DL_RELOC_ADDR(tpnt->loadaddr, myppnt->p_vaddr) & PAGE_ALIGN),
1019                                                         (myppnt->p_vaddr & ADDR_ALIGN) + (unsigned long) myppnt->p_filesz, LXFLAGS(myppnt->p_flags));
1020                                 }
1021                         }
1022                 }
1023
1024         }
1025 #endif
1026         /* Notify the debugger we have added some objects. */
1027         _dl_debug_addr->r_state = RT_ADD;
1028         _dl_debug_state();
1029
1030         /* Run pre-initialization functions for the executable.  */
1031         _dl_run_array_forward(_dl_loaded_modules->dynamic_info[DT_PREINIT_ARRAY],
1032                               _dl_loaded_modules->dynamic_info[DT_PREINIT_ARRAYSZ],
1033                               _dl_loaded_modules->loadaddr);
1034
1035         /* Run initialization functions for loaded objects.  For the
1036            main executable, they will be run from __uClibc_main.  */
1037         for (i = nlist; i; --i) {
1038                 tpnt = init_fini_list[i-1];
1039                 tpnt->init_fini = NULL; /* Clear, since alloca was used */
1040                 if (tpnt->init_flag & INIT_FUNCS_CALLED)
1041                         continue;
1042                 tpnt->init_flag |= INIT_FUNCS_CALLED;
1043
1044                 if (tpnt->dynamic_info[DT_INIT]) {
1045                         void (*dl_elf_func) (void);
1046
1047                         dl_elf_func = (void (*)(void)) DL_RELOC_ADDR(tpnt->loadaddr, tpnt->dynamic_info[DT_INIT]);
1048
1049                         _dl_if_debug_dprint("calling INIT: %s\n\n", tpnt->libname);
1050
1051                         DL_CALL_FUNC_AT_ADDR (dl_elf_func, tpnt->loadaddr, (void(*)(void)));
1052                 }
1053
1054                 _dl_run_init_array(tpnt);
1055         }
1056
1057         /* Find the real malloc function and make ldso functions use that from now on */
1058         _dl_malloc_function = (void* (*)(size_t)) (intptr_t) _dl_find_hash(__C_SYMBOL_PREFIX__ "malloc",
1059                         _dl_symbol_tables, NULL, ELF_RTYPE_CLASS_PLT, NULL);
1060
1061 #if USE_TLS
1062         /* Find the real functions and make ldso functions use them from now on */
1063         _dl_calloc_function = (void* (*)(size_t, size_t)) (intptr_t)
1064                 _dl_find_hash(__C_SYMBOL_PREFIX__ "calloc", _dl_symbol_tables, NULL, ELF_RTYPE_CLASS_PLT, NULL);
1065                                         
1066         _dl_realloc_function = (void* (*)(void *, size_t)) (intptr_t)
1067                 _dl_find_hash(__C_SYMBOL_PREFIX__ "realloc", _dl_symbol_tables, NULL, ELF_RTYPE_CLASS_PLT, NULL);
1068                                                                                 
1069         _dl_free_function = (void (*)(void *)) (intptr_t)
1070                 _dl_find_hash(__C_SYMBOL_PREFIX__ "free", _dl_symbol_tables, NULL, ELF_RTYPE_CLASS_PLT, NULL);
1071                                         
1072         _dl_memalign_function = (void* (*)(size_t, size_t)) (intptr_t)
1073                 _dl_find_hash(__C_SYMBOL_PREFIX__ "memalign", _dl_symbol_tables, NULL, ELF_RTYPE_CLASS_PLT, NULL);
1074                         
1075 #endif
1076
1077         /* Notify the debugger that all objects are now mapped in.  */
1078         _dl_debug_addr->r_state = RT_CONSISTENT;
1079         _dl_debug_state();
1080 }
1081
1082 #include "dl-hash.c"
1083 #include "dl-elf.c"