OSDN Git Service

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