OSDN Git Service

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