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