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