OSDN Git Service

ldso: Add config option for controlling LD_PRELOAD
[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 #ifdef __UCLIBC_HAS_SSP__
386         /* Set up the stack checker's canary.  */
387         stack_chk_guard = _dl_setup_stack_chk_guard ();
388 # ifdef THREAD_SET_STACK_GUARD
389         THREAD_SET_STACK_GUARD (stack_chk_guard);
390 #  ifdef __UCLIBC_HAS_SSP_COMPAT__
391         __guard = stack_chk_guard;
392 #  endif
393 # else
394         __stack_chk_guard = stack_chk_guard;
395 # endif
396 #endif
397
398         /* At this point we are now free to examine the user application,
399          * and figure out which libraries are supposed to be called.  Until
400          * we have this list, we will not be completely ready for dynamic
401          * linking.
402          */
403
404         /* Find the runtime load address of the main executable.  This may be
405          * different from what the ELF header says for ET_DYN/PIE executables.
406          */
407         {
408                 unsigned int idx;
409                 ElfW(Phdr) *phdr = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_val;
410
411                 for (idx = 0; idx < auxvt[AT_PHNUM].a_un.a_val; idx++, phdr++)
412                         if (phdr->p_type == PT_PHDR) {
413                                 DL_INIT_LOADADDR_PROG(app_tpnt->loadaddr, auxvt[AT_PHDR].a_un.a_val - phdr->p_vaddr);
414                                 break;
415                         }
416
417                 if (DL_LOADADDR_BASE(app_tpnt->loadaddr))
418                         _dl_debug_early("Position Independent Executable: "
419                                         "app_tpnt->loadaddr=%x\n", DL_LOADADDR_BASE(app_tpnt->loadaddr));
420         }
421
422         /*
423          * This is used by gdb to locate the chain of shared libraries that are
424          * currently loaded.
425          */
426         debug_addr = _dl_zalloc(sizeof(struct r_debug));
427
428         ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_val;
429         for (i = 0; i < auxvt[AT_PHNUM].a_un.a_val; i++, ppnt++) {
430                 if (ppnt->p_type == PT_GNU_RELRO) {
431                         relro_addr = ppnt->p_vaddr;
432                         relro_size = ppnt->p_memsz;
433                 }
434                 if (!app_mapaddr && (ppnt->p_type == PT_LOAD)) {
435                         app_mapaddr = DL_RELOC_ADDR (app_tpnt->loadaddr, ppnt->p_vaddr);
436                 }
437                 if (ppnt->p_type == PT_DYNAMIC) {
438                         dpnt = (ElfW(Dyn) *) DL_RELOC_ADDR(app_tpnt->loadaddr, ppnt->p_vaddr);
439                         _dl_parse_dynamic_info(dpnt, app_tpnt->dynamic_info, debug_addr, app_tpnt->loadaddr);
440 #ifndef __FORCE_SHAREABLE_TEXT_SEGMENTS__
441                         /* Ugly, ugly.  We need to call mprotect to change the
442                          * protection of the text pages so that we can do the
443                          * dynamic linking.  We can set the protection back
444                          * again once we are done.
445                          */
446                         _dl_debug_early("calling mprotect on the application program\n");
447                         /* Now cover the application program. */
448                         if (app_tpnt->dynamic_info[DT_TEXTREL]) {
449                                 ElfW(Phdr) *ppnt_outer = ppnt;
450                                 ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_val;
451                                 for (i = 0; i < auxvt[AT_PHNUM].a_un.a_val; i++, ppnt++) {
452                                         if (ppnt->p_type == PT_LOAD && !(ppnt->p_flags & PF_W))
453                                                 _dl_mprotect((void *) (DL_RELOC_ADDR(app_tpnt->loadaddr, ppnt->p_vaddr) & PAGE_ALIGN),
454                                                              (DL_RELOC_ADDR(app_tpnt->loadaddr, ppnt->p_vaddr) & ADDR_ALIGN) +
455                                                              (unsigned long) ppnt->p_filesz,
456                                                              PROT_READ | PROT_WRITE | PROT_EXEC);
457                                 }
458                                 ppnt = ppnt_outer;
459                         }
460 #else
461                         if (app_tpnt->dynamic_info[DT_TEXTREL]) {
462                                 _dl_dprintf(_dl_debug_file, "Can't modify application's text section; use the GCC option -fPIE for position-independent executables.\n");
463                                 _dl_exit(1);
464                         }
465 #endif
466
467 #ifndef ALLOW_ZERO_PLTGOT
468                         /* make sure it's really there. */
469                         if (app_tpnt->dynamic_info[DT_PLTGOT] == 0)
470                                 continue;
471 #endif
472                         /* OK, we have what we need - slip this one into the list. */
473                         app_tpnt = _dl_add_elf_hash_table(_dl_progname, app_tpnt->loadaddr,
474                                         app_tpnt->dynamic_info,
475                                         (unsigned long) DL_RELOC_ADDR(app_tpnt->loadaddr, ppnt->p_vaddr),
476                                         ppnt->p_filesz);
477                         _dl_loaded_modules->libtype = elf_executable;
478                         _dl_loaded_modules->ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_val;
479                         _dl_loaded_modules->n_phent = auxvt[AT_PHNUM].a_un.a_val;
480                         _dl_symbol_tables = rpnt = _dl_zalloc(sizeof(struct dyn_elf));
481                         rpnt->dyn = _dl_loaded_modules;
482                         app_tpnt->mapaddr = app_mapaddr;
483                         app_tpnt->rtld_flags = unlazy | RTLD_GLOBAL;
484                         app_tpnt->usage_count++;
485                         app_tpnt->symbol_scope = _dl_symbol_tables;
486                         lpnt = (unsigned long *) (app_tpnt->dynamic_info[DT_PLTGOT]);
487 #ifdef ALLOW_ZERO_PLTGOT
488                         if (lpnt)
489 #endif
490                                 INIT_GOT(lpnt, _dl_loaded_modules);
491                 }
492
493                 /* OK, fill this in - we did not have this before */
494                 if (ppnt->p_type == PT_INTERP) {
495                         tpnt->libname = (char *) DL_RELOC_ADDR(app_tpnt->loadaddr, ppnt->p_vaddr);
496 #ifdef __LDSO_SEARCH_INTERP_PATH__
497                         {
498                                 char *ptmp;
499                                 /* Store the path where the shared lib loader was found
500                                  * for later use
501                                  */
502                                 _dl_ldsopath = _dl_strdup(tpnt->libname);
503                                 ptmp = _dl_strrchr(_dl_ldsopath, '/');
504                                 if (ptmp != _dl_ldsopath)
505                                         *ptmp = '\0';
506                         }
507                         _dl_debug_early("Lib Loader: (%x) %s\n", (unsigned) DL_LOADADDR_BASE(tpnt->loadaddr), tpnt->libname);
508 #endif
509                 }
510
511                 /* Discover any TLS sections if the target supports them. */
512                 if (ppnt->p_type == PT_TLS) {
513 #if defined(USE_TLS) && USE_TLS
514                         if (ppnt->p_memsz > 0) {
515                                 app_tpnt->l_tls_blocksize = ppnt->p_memsz;
516                                 app_tpnt->l_tls_align = ppnt->p_align;
517                                 if (ppnt->p_align == 0)
518                                         app_tpnt->l_tls_firstbyte_offset = 0;
519                                 else
520                                         app_tpnt->l_tls_firstbyte_offset =
521                                                 (ppnt->p_vaddr & (ppnt->p_align - 1));
522                                 app_tpnt->l_tls_initimage_size = ppnt->p_filesz;
523                                 app_tpnt->l_tls_initimage = (void *) ppnt->p_vaddr;
524
525                                 /* This image gets the ID one.  */
526                                 _dl_tls_max_dtv_idx = app_tpnt->l_tls_modid = 1;
527
528                         }
529                         _dl_debug_early("Found TLS header for appplication program\n");
530                         break;
531 #else
532                         _dl_dprintf(_dl_debug_file, "Program uses unsupported TLS data!\n");
533                         _dl_exit(1);
534 #endif
535                 }
536         }
537         app_tpnt->relro_addr = relro_addr;
538         app_tpnt->relro_size = relro_size;
539
540 #if defined(USE_TLS) && USE_TLS
541         /*
542          * Adjust the address of the TLS initialization image in
543          * case the executable is actually an ET_DYN object.
544          */
545         if (app_tpnt->l_tls_initimage != NULL) {
546                 app_tpnt->l_tls_initimage =
547                         (char *) app_tpnt->l_tls_initimage + app_tpnt->loadaddr;
548                 _dl_debug_early("Relocated TLS initial image from %x to %x (size = %x)\n",
549                         (unsigned int)app_tpnt->l_tls_initimage,
550                         app_tpnt->l_tls_initimage, app_tpnt->l_tls_initimage_size);
551         }
552 #endif
553
554 #ifdef __SUPPORT_LD_DEBUG__
555         _dl_debug = _dl_getenv("LD_DEBUG", envp);
556         if (_dl_debug) {
557                 if (_dl_strstr(_dl_debug, "all")) {
558                         _dl_debug_detail = _dl_debug_move = _dl_debug_symbols
559                                 = _dl_debug_reloc = _dl_debug_bindings = _dl_debug_nofixups = (void*)1;
560                 } else {
561                         _dl_debug_detail   = _dl_strstr(_dl_debug, "detail");
562                         _dl_debug_move     = _dl_strstr(_dl_debug, "move");
563                         _dl_debug_symbols  = _dl_strstr(_dl_debug, "sym");
564                         _dl_debug_reloc    = _dl_strstr(_dl_debug, "reloc");
565                         _dl_debug_nofixups = _dl_strstr(_dl_debug, "nofix");
566                         _dl_debug_bindings = _dl_strstr(_dl_debug, "bind");
567                 }
568         }
569
570         {
571                 const char *dl_debug_output;
572
573                 dl_debug_output = _dl_getenv("LD_DEBUG_OUTPUT", envp);
574
575                 if (dl_debug_output) {
576                         char tmp[22], *tmp1, *filename;
577                         int len1, len2;
578
579                         _dl_memset(tmp, 0, sizeof(tmp));
580                         tmp1 = _dl_simple_ltoa( tmp, (unsigned long)_dl_getpid());
581
582                         len1 = _dl_strlen(dl_debug_output);
583                         len2 = _dl_strlen(tmp1);
584
585                         filename = _dl_malloc(len1 + len2 + 2);
586
587                         if (filename) {
588                                 _dl_strcpy (filename, dl_debug_output);
589                                 filename[len1] = '.';
590                                 _dl_strcpy (&filename[len1+1], tmp1);
591
592                                 _dl_debug_file = _dl_open(filename, O_WRONLY|O_CREAT, 0644);
593                                 if (_dl_debug_file < 0) {
594                                         _dl_debug_file = 2;
595                                         _dl_dprintf(_dl_debug_file, "can't open file: '%s'\n",filename);
596                                 }
597                         }
598                 }
599         }
600 #endif
601
602         if (_dl_getenv("LD_TRACE_LOADED_OBJECTS", envp) != NULL) {
603                 trace_loaded_objects++;
604         }
605
606 #ifndef __LDSO_LDD_SUPPORT__
607         if (trace_loaded_objects) {
608                 _dl_dprintf(_dl_debug_file, "Use the ldd provided by uClibc\n");
609                 _dl_exit(1);
610         }
611 #endif
612
613         /*
614          * OK, fix one more thing - set up debug_addr so it will point
615          * to our chain.  Later we may need to fill in more fields, but this
616          * should be enough for now.
617          */
618         debug_addr->r_map = (struct link_map *) _dl_loaded_modules;
619         debug_addr->r_version = 1;
620         debug_addr->r_ldbase = (ElfW(Addr)) DL_LOADADDR_BASE(load_addr);
621         debug_addr->r_brk = (unsigned long) &_dl_debug_state;
622         _dl_debug_addr = debug_addr;
623
624         /* Do not notify the debugger until the interpreter is in the list */
625
626         /* OK, we now have the application in the list, and we have some
627          * basic stuff in place.  Now search through the list for other shared
628          * libraries that should be loaded, and insert them on the list in the
629          * correct order.
630          */
631
632         _dl_map_cache();
633
634 #ifdef __LDSO_PRELOAD_ENV_SUPPORT__
635         if (_dl_preload) {
636                 char c, *str, *str2;
637
638                 str = _dl_preload;
639                 while (*str == ':' || *str == ' ' || *str == '\t')
640                         str++;
641
642                 while (*str) {
643                         str2 = str;
644                         while (*str2 && *str2 != ':' && *str2 != ' ' && *str2 != '\t')
645                                 str2++;
646                         c = *str2;
647                         *str2 = '\0';
648
649                         if (!_dl_secure || _dl_strchr(str, '/') == NULL) {
650                                 _dl_if_debug_dprint("\tfile='%s';  needed by '%s'\n", str, _dl_progname);
651
652                                 tpnt1 = _dl_load_shared_library(_dl_secure, &rpnt, NULL, str, trace_loaded_objects);
653                                 if (!tpnt1) {
654 #ifdef __LDSO_LDD_SUPPORT__
655                                         if (trace_loaded_objects)
656                                                 _dl_dprintf(1, "\t%s => not found\n", str);
657                                         else
658 #endif
659                                         {
660                                                 _dl_dprintf(_dl_debug_file, "%s: can't load " "library '%s'\n", _dl_progname, str);
661                                                 _dl_exit(15);
662                                         }
663                                 } else {
664                                         tpnt1->rtld_flags = unlazy | RTLD_GLOBAL;
665
666                                         _dl_debug_early("Loading: (%x) %s\n", DL_LOADADDR_BASE(tpnt1->loadaddr), tpnt1->libname);
667
668 #ifdef __LDSO_LDD_SUPPORT__
669                                         if (trace_loaded_objects &&
670                                             tpnt1->usage_count == 1) {
671                                                 /* This is a real hack to make
672                                                  * ldd not print the library
673                                                  * itself when run on a
674                                                  * library.
675                                                  */
676                                                 if (_dl_strcmp(_dl_progname, str) != 0)
677                                                         _dl_dprintf(1, "\t%s => %s (%x)\n", str, tpnt1->libname,
678                                                                     DL_LOADADDR_BASE(tpnt1->loadaddr));
679                                         }
680 #endif
681                                 }
682                         }
683
684                         *str2 = c;
685                         str = str2;
686                         while (*str == ':' || *str == ' ' || *str == '\t')
687                                 str++;
688                 }
689         }
690 #endif /* __LDSO_PRELOAD_ENV_SUPPORT__ */
691
692 #ifdef __LDSO_PRELOAD_FILE_SUPPORT__
693         do {
694                 char *preload;
695                 int fd;
696                 char c, *cp, *cp2;
697
698                 if (_dl_stat(LDSO_PRELOAD, &st) || st.st_size == 0) {
699                         break;
700                 }
701
702                 if ((fd = _dl_open(LDSO_PRELOAD, O_RDONLY, 0)) < 0) {
703                         _dl_dprintf(_dl_debug_file, "%s: can't open file '%s'\n",
704                                     _dl_progname, LDSO_PRELOAD);
705                         break;
706                 }
707
708                 preload = (caddr_t) _dl_mmap(0, st.st_size + 1,
709                                              PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
710                 _dl_close(fd);
711                 if (preload == (caddr_t) -1) {
712                         _dl_dprintf(_dl_debug_file, "%s:%i: can't map '%s'\n",
713                                     _dl_progname, __LINE__, LDSO_PRELOAD);
714                         break;
715                 }
716
717                 /* convert all separators and comments to spaces */
718                 for (cp = preload; *cp; /*nada */ ) {
719                         if (*cp == ':' || *cp == '\t' || *cp == '\n') {
720                                 *cp++ = ' ';
721                         } else if (*cp == '#') {
722                                 do {
723                                         *cp++ = ' ';
724                                 } while (*cp != '\n' && *cp != '\0');
725                         } else {
726                                 cp++;
727                         }
728                 }
729
730                 /* find start of first library */
731                 for (cp = preload; *cp && *cp == ' '; cp++)
732                         /*nada */ ;
733
734                 while (*cp) {
735                         /* find end of library */
736                         for (cp2 = cp; *cp && *cp != ' '; cp++)
737                                 /*nada */ ;
738                         c = *cp;
739                         *cp = '\0';
740
741                         _dl_if_debug_dprint("\tfile='%s';  needed by '%s'\n", cp2, _dl_progname);
742
743                         tpnt1 = _dl_load_shared_library(0, &rpnt, NULL, cp2, trace_loaded_objects);
744                         if (!tpnt1) {
745 # ifdef __LDSO_LDD_SUPPORT__
746                                 if (trace_loaded_objects)
747                                         _dl_dprintf(1, "\t%s => not found\n", cp2);
748                                 else
749 # endif
750                                 {
751                                         _dl_dprintf(_dl_debug_file, "%s: can't load library '%s'\n", _dl_progname, cp2);
752                                         _dl_exit(15);
753                                 }
754                         } else {
755                                 tpnt1->rtld_flags = unlazy | RTLD_GLOBAL;
756
757                                 _dl_debug_early("Loading: (%x) %s\n", DL_LOADADDR_BASE(tpnt1->loadaddr), tpnt1->libname);
758
759 # ifdef __LDSO_LDD_SUPPORT__
760                                 if (trace_loaded_objects &&
761                                     tpnt1->usage_count == 1) {
762                                         _dl_dprintf(1, "\t%s => %s (%x)\n",
763                                                     cp2, tpnt1->libname,
764                                                     DL_LOADADDR_BASE(tpnt1->loadaddr));
765                                 }
766 # endif
767                         }
768
769                         /* find start of next library */
770                         *cp = c;
771                         for ( /*nada */ ; *cp && *cp == ' '; cp++)
772                                 /*nada */ ;
773                 }
774
775                 _dl_munmap(preload, st.st_size + 1);
776         } while (0);
777 #endif /* __LDSO_PRELOAD_FILE_SUPPORT__ */
778
779         nlist = 0;
780         for (tcurr = _dl_loaded_modules; tcurr; tcurr = tcurr->next) {
781                 ElfW(Dyn) *this_dpnt;
782
783                 nlist++;
784                 for (this_dpnt = (ElfW(Dyn) *) tcurr->dynamic_addr; this_dpnt->d_tag; this_dpnt++) {
785                         if (this_dpnt->d_tag == DT_NEEDED) {
786                                 char *name;
787                                 struct init_fini_list *tmp;
788
789                                 lpntstr = (char*) (tcurr->dynamic_info[DT_STRTAB] + this_dpnt->d_un.d_val);
790                                 name = _dl_get_last_path_component(lpntstr);
791                                 if (_dl_strcmp(name, UCLIBC_LDSO) == 0)
792                                         continue;
793
794                                 _dl_if_debug_dprint("\tfile='%s';  needed by '%s'\n", lpntstr, _dl_progname);
795
796                                 if (!(tpnt1 = _dl_load_shared_library(0, &rpnt, tcurr, lpntstr, trace_loaded_objects))) {
797 #ifdef __LDSO_LDD_SUPPORT__
798                                         if (trace_loaded_objects) {
799                                                 _dl_dprintf(1, "\t%s => not found\n", lpntstr);
800                                                 continue;
801                                         } else
802 #endif
803                                         {
804                                                 _dl_dprintf(_dl_debug_file, "%s: can't load library '%s'\n", _dl_progname, lpntstr);
805                                                 _dl_exit(16);
806                                         }
807                                 }
808
809                                 tmp = alloca(sizeof(struct init_fini_list)); /* Allocates on stack, no need to free this memory */
810                                 tmp->tpnt = tpnt1;
811                                 tmp->next = tcurr->init_fini;
812                                 tcurr->init_fini = tmp;
813
814                                 tpnt1->rtld_flags = unlazy | RTLD_GLOBAL;
815
816                                 _dl_debug_early("Loading: (%x) %s\n", DL_LOADADDR_BASE(tpnt1->loadaddr), tpnt1->libname);
817
818 #ifdef __LDSO_LDD_SUPPORT__
819                                 if (trace_loaded_objects &&
820                                     tpnt1->usage_count == 1) {
821                                         _dl_dprintf(1, "\t%s => %s (%x)\n",
822                                                     lpntstr, tpnt1->libname,
823                                                     DL_LOADADDR_BASE(tpnt1->loadaddr));
824                                 }
825 #endif
826                         }
827                 }
828         }
829         _dl_unmap_cache();
830
831         --nlist; /* Exclude the application. */
832         init_fini_list = _dl_malloc(nlist * sizeof(struct elf_resolve *));
833         i = 0;
834         for (tcurr = _dl_loaded_modules->next; tcurr; tcurr = tcurr->next) {
835                 init_fini_list[i++] = tcurr;
836         }
837
838         /* Sort the INIT/FINI list in dependency order. */
839         for (tcurr = _dl_loaded_modules->next; tcurr; tcurr = tcurr->next) {
840                 unsigned int j, k;
841
842                 for (j = 0; init_fini_list[j] != tcurr; ++j)
843                         /* Empty */;
844                 for (k = j + 1; k < nlist; ++k) {
845                         struct init_fini_list *runp = init_fini_list[k]->init_fini;
846
847                         for (; runp; runp = runp->next) {
848                                 if (runp->tpnt == tcurr) {
849                                         struct elf_resolve *here = init_fini_list[k];
850                                         _dl_if_debug_dprint("Move %s from pos %d to %d in INIT/FINI list\n", here->libname, k, j);
851                                         for (i = (k - j); i; --i)
852                                                 init_fini_list[i+j] = init_fini_list[i+j-1];
853                                         init_fini_list[j] = here;
854                                         ++j;
855                                         break;
856                                 }
857                         }
858                 }
859         }
860 #ifdef __SUPPORT_LD_DEBUG__
861         if (_dl_debug) {
862                 _dl_dprintf(_dl_debug_file, "\nINIT/FINI order and dependencies:\n");
863                 for (i = 0; i < nlist; i++) {
864                         struct init_fini_list *tmp;
865
866                         _dl_dprintf(_dl_debug_file, "lib: %s has deps:\n",
867                                     init_fini_list[i]->libname);
868                         tmp = init_fini_list[i]->init_fini;
869                         for (; tmp; tmp = tmp->next)
870                                 _dl_dprintf(_dl_debug_file, " %s ", tmp->tpnt->libname);
871                         _dl_dprintf(_dl_debug_file, "\n");
872                 }
873         }
874 #endif
875
876         /*
877          * If the program interpreter is not in the module chain, add it.
878          * This will be required for dlopen to be able to access the internal
879          * functions in the dynamic linker and to relocate the interpreter
880          * again once all libs are loaded.
881          */
882         if (tpnt) {
883                 ElfW(Ehdr) *epnt = (ElfW(Ehdr) *) auxvt[AT_BASE].a_un.a_val;
884                 ElfW(Phdr) *myppnt = (ElfW(Phdr) *) DL_RELOC_ADDR(load_addr, epnt->e_phoff);
885                 int j;
886
887                 tpnt = _dl_add_elf_hash_table(tpnt->libname, load_addr,
888                                               tpnt->dynamic_info,
889                                               (unsigned long)tpnt->dynamic_addr,
890                                               0);
891
892                 if (_dl_stat(tpnt->libname, &st) >= 0) {
893                         tpnt->st_dev = st.st_dev;
894                         tpnt->st_ino = st.st_ino;
895                 }
896                 tpnt->n_phent = epnt->e_phnum;
897                 tpnt->ppnt = myppnt;
898                 for (j = 0; j < epnt->e_phnum; j++, myppnt++) {
899                         if (myppnt->p_type ==  PT_GNU_RELRO) {
900                                 tpnt->relro_addr = myppnt->p_vaddr;
901                                 tpnt->relro_size = myppnt->p_memsz;
902                                 break;
903                         }
904                 }
905                 tpnt->libtype = program_interpreter;
906                 tpnt->usage_count++;
907                 tpnt->symbol_scope = _dl_symbol_tables;
908                 if (rpnt) {
909                         rpnt->next = _dl_zalloc(sizeof(struct dyn_elf));
910                         rpnt->next->prev = rpnt;
911                         rpnt = rpnt->next;
912                 } else {
913                         rpnt = _dl_zalloc(sizeof(struct dyn_elf));
914                 }
915                 rpnt->dyn = tpnt;
916                 tpnt->rtld_flags = RTLD_NOW | RTLD_GLOBAL; /* Must not be LAZY */
917 #ifdef RERELOCATE_LDSO
918                 /* Only rerelocate functions for now. */
919                 tpnt->init_flag = RELOCS_DONE;
920                 lpnt = (unsigned long *) (tpnt->dynamic_info[DT_PLTGOT]);
921 # ifdef ALLOW_ZERO_PLTGOT
922                 if (tpnt->dynamic_info[DT_PLTGOT])
923 # endif
924                         INIT_GOT(lpnt, tpnt);
925 #else
926                 tpnt->init_flag = RELOCS_DONE | JMP_RELOCS_DONE;
927 #endif
928                 tpnt = NULL;
929         }
930
931 #ifdef __LDSO_LDD_SUPPORT__
932         /* End of the line for ldd.... */
933         if (trace_loaded_objects) {
934                 _dl_dprintf(1, "\t%s => %s (%x)\n",
935                             rpnt->dyn->libname + _dl_strlen(_dl_ldsopath) + 1,
936                             rpnt->dyn->libname, DL_LOADADDR_BASE(rpnt->dyn->loadaddr));
937                 _dl_exit(0);
938         }
939 #endif
940
941 #if defined(USE_TLS) && USE_TLS
942         /* We do not initialize any of the TLS functionality unless any of the
943          * initial modules uses TLS.  This makes dynamic loading of modules with
944          * TLS impossible, but to support it requires either eagerly doing setup
945          * now or lazily doing it later.  Doing it now makes us incompatible with
946          * an old kernel that can't perform TLS_INIT_TP, even if no TLS is ever
947          * used.  Trying to do it lazily is too hairy to try when there could be
948          * multiple threads (from a non-TLS-using libpthread).  */
949         bool was_tls_init_tp_called = tls_init_tp_called;
950         if (tcbp == NULL) {
951                 _dl_debug_early("Calling init_tls()!\n");
952                 tcbp = init_tls ();
953         }
954 #endif
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"