OSDN Git Service

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