OSDN Git Service

Step one, begin shuffling things around a bit
[uclinux-h8/uClibc.git] / ldso / ldso / ldso.c
1 /* vi: set sw=4 ts=4: */
2 /* Program to load an ELF binary on a linux system, and run it
3  * after resolving ELF shared library symbols
4  *
5  * Copyright (c) 1994-2000 Eric Youngdale, Peter MacDonald, 
6  *                              David Engel, Hongjiu Lu and Mitch D'Souza
7  * Copyright (C) 2001-2002, Erik Andersen
8  *
9  * All rights reserved.
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 // Support a list of library preloads in /etc/ld.so.preload
34 //#define SUPPORT_LDSO_PRELOAD_FILE
35
36
37 /* Disclaimer:  I have never seen any AT&T source code for SVr4, nor have
38    I ever taken any courses on internals.  This program was developed using
39    information available through the book "UNIX SYSTEM V RELEASE 4,
40    Programmers guide: Ansi C and Programming Support Tools", which did
41    a more than adequate job of explaining everything required to get this
42    working. */
43
44 /*
45  * The main trick with this program is that initially, we ourselves are
46  * not dynamicly linked.  This means that we cannot access any global
47  * variables or call any functions.  No globals initially, since the
48  * Global Offset Table (GOT) is initialized by the linker assuming a
49  * virtual address of 0, and no function calls initially since the
50  * Procedure Linkage Table (PLT) is not yet initialized.
51  *
52  * There are additional initial restrictions - we cannot use large
53  * switch statements, since the compiler generates tables of addresses
54  * and jumps through them.  We can use inline functions, because these
55  * do not transfer control to a new address, but they must be static so
56  * that they are not exported from the modules.  We cannot use normal
57  * syscall stubs, because these all reference the errno global variable
58  * which is not yet initialized.  We can use all of the local stack
59  * variables that we want.
60  *
61  * Life is further complicated by the fact that initially we do not
62  * want to do a complete dynamic linking.  We want to allow the user to
63  * supply new functions to override symbols (i.e. weak symbols and/or
64  * LD_PRELOAD).  So initially, we only perform relocations for
65  * variables that start with "_dl_" since ANSI specifies that the user
66  * is not supposed to redefine any of these variables.
67  *
68  * Fortunately, the linker itself leaves a few clues lying around, and
69  * when the kernel starts the image, there are a few further clues.
70  * First of all, there is Auxiliary Vector Table information sitting on
71  * which is provided to us by the kernel, and which includes
72  * information about the load address that the program interpreter was
73  * loaded at, the number of sections, the address the application was
74  * loaded at and so forth.  Here this information is stored in the
75  * array auxvt.  For details see linux/fs/binfmt_elf.c where it calls
76  * NEW_AUX_ENT() a bunch of time....
77  *
78  * Next, we need to find the GOT.  On most arches there is a register
79  * pointing to the GOT, but just in case (and for new ports) I've added
80  * some (slow) C code to locate the GOT for you. 
81  *
82  * This code was originally written for SVr4, and there the kernel
83  * would load all text pages R/O, so they needed to call mprotect a
84  * zillion times to mark all text pages as writable so dynamic linking
85  * would succeed.  Then when they were done, they would change the
86  * protections for all the pages back again.  Well, under Linux
87  * everything is loaded writable (since Linux does copy on write
88  * anyways) so all the mprotect stuff has been disabled.
89  *
90  * Initially, we do not have access to _dl_malloc since we can't yet
91  * make function calls, so we mmap one page to use as scratch space.
92  * Later on, when we can call _dl_malloc we reuse this this memory.
93  * This is also beneficial, since we do not want to use the same memory
94  * pool as malloc anyway - esp if the user redefines malloc to do
95  * something funky.
96  *
97  * Our first task is to perform a minimal linking so that we can call
98  * other portions of the dynamic linker.  Once we have done this, we
99  * then build the list of modules that the application requires, using
100  * LD_LIBRARY_PATH if this is not a suid program (/usr/lib otherwise).
101  * Once this is done, we can do the dynamic linking as required, and we
102  * must omit the things we did to get the dynamic linker up and running
103  * in the first place.  After we have done this, we just have a few
104  * housekeeping chores and we can transfer control to the user's
105  * application.
106  */
107
108 #include "ldso.h"
109
110
111 #define ALLOW_ZERO_PLTGOT
112
113 /*  Some arches may need to override this in boot1_arch.h */
114 #define     ELFMAGIC    ELFMAG
115
116 /* This is a poor man's malloc, used prior to resolving our internal poor man's malloc */
117 #define LD_MALLOC(SIZE) ((void *) (malloc_buffer += SIZE, malloc_buffer - SIZE)) ;  REALIGN();
118 /*
119  * Make sure that the malloc buffer is aligned on 4 byte boundary.  For 64 bit
120  * platforms we may need to increase this to 8, but this is good enough for
121  * now.  This is typically called after LD_MALLOC.
122  */
123 #define REALIGN() malloc_buffer = (unsigned char *) (((unsigned long) malloc_buffer + 3) & ~(3))
124
125 char *_dl_library_path = 0;             /* Where we look for libraries */
126 char *_dl_preload = 0;                  /* Things to be loaded before the libs. */
127 char *_dl_ldsopath = 0;
128 #ifdef __SUPPORT_LD_DEBUG__
129 char *_dl_debug  = 0;
130 char *_dl_debug_symbols = 0;
131 char *_dl_debug_move    = 0;
132 char *_dl_debug_reloc   = 0;
133 char *_dl_debug_detail  = 0;
134 char *_dl_debug_nofixups  = 0;
135 char *_dl_debug_bindings  = 0;
136 int   _dl_debug_file = 2;
137 #else
138 #define _dl_debug_file 2
139 #endif
140 static unsigned char *_dl_malloc_addr, *_dl_mmap_zero;
141
142 static int _dl_secure = 0;
143 static int (*_dl_elf_main) (int, char **, char **);
144 struct r_debug *_dl_debug_addr = NULL;
145 unsigned long *_dl_brkp;
146 unsigned long *_dl_envp;
147 int _dl_fixup(struct dyn_elf *rpnt, int flag);
148 void _dl_debug_state(void);
149 char *_dl_get_last_path_component(char *path);
150
151 #include "boot1_arch.h"
152 #include "_dl_progname.h"                               /* Pull in the value of _dl_progname */
153
154 /* When we enter this piece of code, the program stack looks like this:
155         argc            argument counter (integer)
156         argv[0]         program name (pointer)
157         argv[1...N]     program args (pointers)
158         argv[argc-1]    end of args (integer)
159                 NULL
160         env[0...N]      environment variables (pointers)
161         NULL
162                 auxvt[0...N]   Auxiliary Vector Table elements (mixed types)
163 */
164
165 LD_BOOT(unsigned long args) __attribute__ ((unused));
166 LD_BOOT(unsigned long args)
167 {
168         unsigned int argc;
169         char **argv, **envp;
170         unsigned long load_addr;
171         unsigned long *got;
172         unsigned long *aux_dat;
173         int goof = 0;
174         ElfW(Ehdr) *header;
175         struct elf_resolve *tpnt;
176         struct elf_resolve *app_tpnt;
177         Elf32_auxv_t auxvt[AT_EGID + 1];
178         unsigned char *malloc_buffer, *mmap_zero;
179         Elf32_Dyn *dpnt;
180         unsigned long *hash_addr;
181         struct r_debug *debug_addr = NULL;
182         int indx;
183         int status;
184
185
186         /* WARNING! -- we cannot make _any_ funtion calls until we have
187          * taken care of fixing up our own relocations.  Making static
188          * inline calls is ok, but _no_ function calls.  Not yet
189          * anyways. */
190
191         /* First obtain the information on the stack that tells us more about
192            what binary is loaded, where it is loaded, etc, etc */
193         GET_ARGV(aux_dat, args);
194 #if defined (__arm__) || defined (__mips__) || defined (__cris__)
195         aux_dat += 1;
196 #endif
197         argc = *(aux_dat - 1);
198         argv = (char **) aux_dat;
199         aux_dat += argc;                        /* Skip over the argv pointers */
200         aux_dat++;                                      /* Skip over NULL at end of argv */
201         envp = (char **) aux_dat;
202         while (*aux_dat)
203                 aux_dat++;                              /* Skip over the envp pointers */
204         aux_dat++;                                      /* Skip over NULL at end of envp */
205
206         /* Place -1 here as a checkpoint.  We later check if it was changed
207          * when we read in the auxvt */
208         auxvt[AT_UID].a_type = -1;
209
210         /* The junk on the stack immediately following the environment is  
211          * the Auxiliary Vector Table.  Read out the elements of the auxvt,
212          * sort and store them in auxvt for later use. */
213         while (*aux_dat) {
214                 Elf32_auxv_t *auxv_entry = (Elf32_auxv_t *) aux_dat;
215
216                 if (auxv_entry->a_type <= AT_EGID) {
217                         _dl_memcpy(&(auxvt[auxv_entry->a_type]), auxv_entry, sizeof(Elf32_auxv_t));
218                 }
219                 aux_dat += 2;
220         }
221
222         /* locate the ELF header.   We need this done as soon as possible 
223          * (esp since SEND_STDERR() needs this on some platforms... */
224         load_addr = auxvt[AT_BASE].a_un.a_val;
225         header = (ElfW(Ehdr) *) auxvt[AT_BASE].a_un.a_ptr;
226
227         /* Check the ELF header to make sure everything looks ok.  */
228         if (!header || header->e_ident[EI_CLASS] != ELFCLASS32 ||
229                 header->e_ident[EI_VERSION] != EV_CURRENT
230 #if !defined(__powerpc__) && !defined(__mips__) && !defined(__sh__)
231                 || _dl_strncmp((void *) header, ELFMAGIC, SELFMAG) != 0
232 #else
233                 || header->e_ident[EI_MAG0] != ELFMAG0
234                 || header->e_ident[EI_MAG1] != ELFMAG1
235                 || header->e_ident[EI_MAG2] != ELFMAG2
236                 || header->e_ident[EI_MAG3] != ELFMAG3
237 #endif
238                 ) {
239                 SEND_STDERR("Invalid ELF header\n");
240                 _dl_exit(0);
241         }
242 #ifdef __SUPPORT_LD_DEBUG_EARLY__
243         SEND_STDERR("ELF header=");
244         SEND_ADDRESS_STDERR(load_addr, 1);
245 #endif
246
247
248         /* Locate the global offset table.  Since this code must be PIC  
249          * we can take advantage of the magic offset register, if we
250          * happen to know what that is for this architecture.  If not,
251          * we can always read stuff out of the ELF file to find it... */
252 #if defined(__i386__)
253   __asm__("\tmovl %%ebx,%0\n\t":"=a"(got));
254 #elif defined(__m68k__)
255   __asm__("movel %%a5,%0":"=g"(got));
256 #elif defined(__sparc__)
257   __asm__("\tmov %%l7,%0\n\t":"=r"(got));
258 #elif defined(__arm__)
259   __asm__("\tmov %0, r10\n\t":"=r"(got));
260 #elif defined(__powerpc__)
261   __asm__("\tbl _GLOBAL_OFFSET_TABLE_-4@local\n\t":"=l"(got));
262 #elif defined(__mips__)
263   __asm__("\tmove %0, $28\n\tsubu %0,%0,0x7ff0\n\t":"=r"(got));
264 #elif defined(__sh__) && !defined(__SH5__)
265   __asm__(
266 "       mov.l    1f, %0\n"
267 "       mova     1f, r0\n"
268 "       bra      2f\n"
269 "       add r0,  %0\n"
270 "       .balign  4\n"
271 "1:     .long    _GLOBAL_OFFSET_TABLE_\n"
272 "2:" : "=r" (got) : : "r0");
273 #elif defined(__cris__)
274   __asm__("\tmove.d $pc,%0\n\tsub.d .:GOTOFF,%0\n\t":"=r"(got));
275 #else
276         /* Do things the slow way in C */
277         {
278                 unsigned long tx_reloc;
279                 Elf32_Dyn *dynamic = NULL;
280                 Elf32_Shdr *shdr;
281                 Elf32_Phdr *pt_load;
282
283 #ifdef __SUPPORT_LD_DEBUG_EARLY__
284                 SEND_STDERR("Finding the GOT using C code to read the ELF file\n");
285 #endif
286                 /* Find where the dynamic linking information section is hiding */
287                 shdr = (Elf32_Shdr *) (header->e_shoff + (char *) header);
288                 for (indx = header->e_shnum; --indx >= 0; ++shdr) {
289                         if (shdr->sh_type == SHT_DYNAMIC) {
290                                 goto found_dynamic;
291                         }
292                 }
293                 SEND_STDERR("missing dynamic linking information section \n");
294                 _dl_exit(0);
295
296           found_dynamic:
297                 dynamic = (Elf32_Dyn *) (shdr->sh_offset + (char *) header);
298
299                 /* Find where PT_LOAD is hiding */
300                 pt_load = (Elf32_Phdr *) (header->e_phoff + (char *) header);
301                 for (indx = header->e_phnum; --indx >= 0; ++pt_load) {
302                         if (pt_load->p_type == PT_LOAD) {
303                                 goto found_pt_load;
304                         }
305                 }
306                 SEND_STDERR("missing loadable program segment\n");
307                 _dl_exit(0);
308
309           found_pt_load:
310                 /* Now (finally) find where DT_PLTGOT is hiding */
311                 tx_reloc = pt_load->p_vaddr - pt_load->p_offset;
312                 for (; DT_NULL != dynamic->d_tag; ++dynamic) {
313                         if (dynamic->d_tag == DT_PLTGOT) {
314                                 goto found_got;
315                         }
316                 }
317                 SEND_STDERR("missing global offset table\n");
318                 _dl_exit(0);
319
320           found_got:
321                 got = (unsigned long *) (dynamic->d_un.d_val - tx_reloc +
322                                 (char *) header);
323         }
324 #endif
325
326         /* Now, finally, fix up the location of the dynamic stuff */
327         dpnt = (Elf32_Dyn *) (*got + load_addr);
328 #ifdef __SUPPORT_LD_DEBUG_EARLY__
329         SEND_STDERR("First Dynamic section entry=");
330         SEND_ADDRESS_STDERR(dpnt, 1);
331 #endif
332
333
334         /* Call mmap to get a page of writable memory that can be used 
335          * for _dl_malloc throughout the shared lib loader. */
336         mmap_zero = malloc_buffer = _dl_mmap((void *) 0, PAGE_SIZE, 
337                         PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
338         if (_dl_mmap_check_error(mmap_zero)) {
339                 SEND_STDERR("dl_boot: mmap of a spare page failed!\n");
340                 _dl_exit(13);
341         }
342
343         tpnt = LD_MALLOC(sizeof(struct elf_resolve));
344         _dl_memset(tpnt, 0, sizeof(struct elf_resolve));
345         app_tpnt = LD_MALLOC(sizeof(struct elf_resolve));
346         _dl_memset(app_tpnt, 0, sizeof(struct elf_resolve));
347
348 #ifdef __UCLIBC_PIE_SUPPORT__
349         /* Find the runtime load address of the main executable, this may be
350          * different from what the ELF header says for ET_DYN/PIE executables.
351          */
352         {
353                 ElfW(Phdr) *ppnt;
354                 int i;
355
356                 ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_ptr;
357                 for (i = 0; i < auxvt[AT_PHNUM].a_un.a_val; i++, ppnt++)
358                         if (ppnt->p_type == PT_PHDR) {
359                                 app_tpnt->loadaddr = (ElfW(Addr)) (auxvt[AT_PHDR].a_un.a_val - ppnt->p_vaddr);
360                                 break;
361                         }
362         }
363
364 #ifdef __SUPPORT_LD_DEBUG_EARLY__
365         SEND_STDERR("app_tpnt->loadaddr=");
366         SEND_ADDRESS_STDERR(app_tpnt->loadaddr, 1);
367 #endif
368 #endif
369
370         /*
371          * This is used by gdb to locate the chain of shared libraries that are currently loaded.
372          */
373         debug_addr = LD_MALLOC(sizeof(struct r_debug));
374         _dl_memset(debug_addr, 0, sizeof(struct r_debug));
375
376         /* OK, that was easy.  Next scan the DYNAMIC section of the image.
377            We are only doing ourself right now - we will have to do the rest later */
378 #ifdef __SUPPORT_LD_DEBUG_EARLY__
379         SEND_STDERR("scanning DYNAMIC section\n");
380 #endif
381         while (dpnt->d_tag) {
382 #if defined(__mips__)
383                 if (dpnt->d_tag == DT_MIPS_GOTSYM)
384                         tpnt->mips_gotsym = (unsigned long) dpnt->d_un.d_val;
385                 if (dpnt->d_tag == DT_MIPS_LOCAL_GOTNO)
386                         tpnt->mips_local_gotno = (unsigned long) dpnt->d_un.d_val;
387                 if (dpnt->d_tag == DT_MIPS_SYMTABNO)
388                         tpnt->mips_symtabno = (unsigned long) dpnt->d_un.d_val;
389 #endif
390                 if (dpnt->d_tag < 24) {
391                         tpnt->dynamic_info[dpnt->d_tag] = dpnt->d_un.d_val;
392                         if (dpnt->d_tag == DT_TEXTREL) {
393                                 tpnt->dynamic_info[DT_TEXTREL] = 1;
394                         }
395                 }
396                 dpnt++;
397         }
398
399         {
400                 ElfW(Phdr) *ppnt;
401                 int i;
402
403                 ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_ptr;
404                 for (i = 0; i < auxvt[AT_PHNUM].a_un.a_val; i++, ppnt++)
405                         if (ppnt->p_type == PT_DYNAMIC) {
406 #ifndef __UCLIBC_PIE_SUPPORT__
407                                 dpnt = (Elf32_Dyn *) ppnt->p_vaddr;
408 #else
409                                 dpnt = (Elf32_Dyn *) (ppnt->p_vaddr + app_tpnt->loadaddr);
410 #endif
411                                 while (dpnt->d_tag) {
412 #if defined(__mips__)
413                                         if (dpnt->d_tag == DT_MIPS_GOTSYM)
414                                                 app_tpnt->mips_gotsym =
415                                                         (unsigned long) dpnt->d_un.d_val;
416                                         if (dpnt->d_tag == DT_MIPS_LOCAL_GOTNO)
417                                                 app_tpnt->mips_local_gotno =
418                                                         (unsigned long) dpnt->d_un.d_val;
419                                         if (dpnt->d_tag == DT_MIPS_SYMTABNO)
420                                                 app_tpnt->mips_symtabno =
421                                                         (unsigned long) dpnt->d_un.d_val;
422                                         if (dpnt->d_tag > DT_JMPREL) {
423                                                 dpnt++;
424                                                 continue;
425                                         }
426                                         app_tpnt->dynamic_info[dpnt->d_tag] = dpnt->d_un.d_val;
427
428 #warning "Debugging threads on mips won't work till someone fixes this..."
429 #if 0
430                                         if (dpnt->d_tag == DT_DEBUG) {
431                                                 dpnt->d_un.d_val = (unsigned long) debug_addr;
432                                         }
433 #endif
434
435 #else
436                                         if (dpnt->d_tag > DT_JMPREL) {
437                                                 dpnt++;
438                                                 continue;
439                                         }
440                                         app_tpnt->dynamic_info[dpnt->d_tag] = dpnt->d_un.d_val;
441                                         if (dpnt->d_tag == DT_DEBUG) {
442                                                 dpnt->d_un.d_val = (unsigned long) debug_addr;
443                                         }
444 #endif
445                                         if (dpnt->d_tag == DT_TEXTREL)
446                                                 app_tpnt->dynamic_info[DT_TEXTREL] = 1;
447                                         dpnt++;
448                                 }
449                         }
450         }
451
452 #ifdef __SUPPORT_LD_DEBUG_EARLY__
453         SEND_STDERR("done scanning DYNAMIC section\n");
454 #endif
455
456         /* Get some more of the information that we will need to dynamicly link
457            this module to itself */
458
459         hash_addr = (unsigned long *) (tpnt->dynamic_info[DT_HASH] + load_addr);
460         tpnt->nbucket = *hash_addr++;
461         tpnt->nchain = *hash_addr++;
462         tpnt->elf_buckets = hash_addr;
463         hash_addr += tpnt->nbucket;
464
465 #ifdef __SUPPORT_LD_DEBUG_EARLY__
466         SEND_STDERR("done grabbing link information\n");
467 #endif
468
469 #ifndef FORCE_SHAREABLE_TEXT_SEGMENTS
470         /* Ugly, ugly.  We need to call mprotect to change the protection of
471            the text pages so that we can do the dynamic linking.  We can set the
472            protection back again once we are done */
473
474         {
475                 ElfW(Phdr) *ppnt;
476                 int i;
477
478 #ifdef __SUPPORT_LD_DEBUG_EARLY__
479                 SEND_STDERR("calling mprotect on the shared library/dynamic linker\n");
480 #endif
481
482                 /* First cover the shared library/dynamic linker. */
483                 if (tpnt->dynamic_info[DT_TEXTREL]) {
484                         header = (ElfW(Ehdr) *) auxvt[AT_BASE].a_un.a_ptr;
485                         ppnt = (ElfW(Phdr) *) ((int)auxvt[AT_BASE].a_un.a_ptr + 
486                                         header->e_phoff);
487                         for (i = 0; i < header->e_phnum; i++, ppnt++) {
488                                 if (ppnt->p_type == PT_LOAD && !(ppnt->p_flags & PF_W)) {
489                                         _dl_mprotect((void *) (load_addr + (ppnt->p_vaddr & PAGE_ALIGN)), 
490                                                         (ppnt->p_vaddr & ADDR_ALIGN) + (unsigned long) ppnt->p_filesz, 
491                                                         PROT_READ | PROT_WRITE | PROT_EXEC);
492                                 }
493                         }
494                 }
495
496 #ifdef __SUPPORT_LD_DEBUG_EARLY__
497                 SEND_STDERR("calling mprotect on the application program\n");
498 #endif
499                 /* Now cover the application program. */
500                 if (app_tpnt->dynamic_info[DT_TEXTREL]) {
501                         ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_ptr;
502                         for (i = 0; i < auxvt[AT_PHNUM].a_un.a_val; i++, ppnt++) {
503                                 if (ppnt->p_type == PT_LOAD && !(ppnt->p_flags & PF_W))
504 #ifndef __UCLIBC_PIE_SUPPORT__
505                                         _dl_mprotect((void *) (ppnt->p_vaddr & PAGE_ALIGN),
506                                                                  (ppnt->p_vaddr & ADDR_ALIGN) +
507 #else
508                                         _dl_mprotect((void *) ((ppnt->p_vaddr + app_tpnt->loadaddr) & PAGE_ALIGN),
509                                                                  ((ppnt->p_vaddr + app_tpnt->loadaddr) & ADDR_ALIGN) +
510 #endif
511                                                                  (unsigned long) ppnt->p_filesz,
512                                                                  PROT_READ | PROT_WRITE | PROT_EXEC);
513                         }
514                 }
515         }
516 #endif
517         
518 #if defined(__mips__)
519 #ifdef __SUPPORT_LD_DEBUG_EARLY__
520         SEND_STDERR("About to do MIPS specific GOT bootstrap\n");
521 #endif
522         /* For MIPS we have to do stuff to the GOT before we do relocations.  */
523         PERFORM_BOOTSTRAP_GOT(got);
524 #endif
525
526         /* OK, now do the relocations.  We do not do a lazy binding here, so
527            that once we are done, we have considerably more flexibility. */
528 #ifdef __SUPPORT_LD_DEBUG_EARLY__
529         SEND_STDERR("About to do library loader relocations\n");
530 #endif
531
532         goof = 0;
533         for (indx = 0; indx < 2; indx++) {
534                 unsigned int i;
535                 ELF_RELOC *rpnt;
536                 unsigned long *reloc_addr;
537                 unsigned long symbol_addr;
538                 int symtab_index;
539                 unsigned long rel_addr, rel_size;
540
541
542                 rel_addr = (indx ? tpnt->dynamic_info[DT_JMPREL] : tpnt->
543                          dynamic_info[DT_RELOC_TABLE_ADDR]);
544                 rel_size = (indx ? tpnt->dynamic_info[DT_PLTRELSZ] : tpnt->
545                          dynamic_info[DT_RELOC_TABLE_SIZE]);
546
547                 if (!rel_addr)
548                         continue;
549
550                 /* Now parse the relocation information */
551                 rpnt = (ELF_RELOC *) (rel_addr + load_addr);
552                 for (i = 0; i < rel_size; i += sizeof(ELF_RELOC), rpnt++) {
553                         reloc_addr = (unsigned long *) (load_addr + (unsigned long) rpnt->r_offset);
554                         symtab_index = ELF32_R_SYM(rpnt->r_info);
555                         symbol_addr = 0;
556                         if (symtab_index) {
557                                 char *strtab;
558                                 Elf32_Sym *symtab;
559
560                                 symtab = (Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB] + load_addr);
561                                 strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + load_addr);
562
563                                 /* We only do a partial dynamic linking right now.  The user
564                                    is not supposed to redefine any symbols that start with
565                                    a '_', so we can do this with confidence. */
566                                 if (!_dl_symbol(strtab + symtab[symtab_index].st_name))
567                                         continue;
568                                 symbol_addr = load_addr + symtab[symtab_index].st_value;
569
570                                 if (!symbol_addr) {
571                                         /* This will segfault - you cannot call a function until
572                                          * we have finished the relocations.
573                                          */
574                                         SEND_STDERR("ELF dynamic loader - unable to self-bootstrap - symbol ");
575                                         SEND_STDERR(strtab + symtab[symtab_index].st_name);
576                                         SEND_STDERR(" undefined.\n");
577                                         goof++;
578                                 }
579 #ifdef __SUPPORT_LD_DEBUG_EARLY__
580                                 SEND_STDERR("About to fixup symbol: ");
581                                 SEND_STDERR(strtab + symtab[symtab_index].st_name);
582                                 SEND_STDERR("\n");
583 #endif  
584                                 PERFORM_BOOTSTRAP_RELOC(rpnt, reloc_addr, symbol_addr, load_addr, &symtab[symtab_index]);
585                         } else {
586                                 /*
587                                  * Use this machine-specific macro to perform the actual relocation.
588                                  */
589                                 PERFORM_BOOTSTRAP_RELOC(rpnt, reloc_addr, symbol_addr, load_addr, NULL);
590                         }
591                 }
592         }
593
594         if (goof) {
595                 _dl_exit(14);
596         }
597 #ifdef __SUPPORT_LD_DEBUG_EARLY__
598         /* Wahoo!!! */
599         _dl_dprintf(_dl_debug_file, "Done relocating library loader, so we can now\n\tuse globals and make function calls!\n");
600 #endif
601
602         if (argv[0]) {
603                 _dl_progname = argv[0];
604         }
605
606         /* Start to build the tables of the modules that are required for
607          * this beast to run.  We start with the basic executable, and then
608          * go from there.  Eventually we will run across ourself, and we
609          * will need to properly deal with that as well. */
610
611         /* Make it so _dl_malloc can use the page of memory we have already
612          * allocated, so we shouldn't need to grab any more memory */
613         _dl_malloc_addr = malloc_buffer;
614         _dl_mmap_zero = mmap_zero;
615
616
617
618         /* Now we have done the mandatory linking of some things.  We are now
619            free to start using global variables, since these things have all been
620            fixed up by now.  Still no function calls outside of this library ,
621            since the dynamic resolver is not yet ready. */
622         _dl_get_ready_to_run(tpnt, app_tpnt, load_addr, hash_addr,
623                         auxvt, envp, debug_addr, malloc_buffer, mmap_zero, argv);
624
625
626         /* Transfer control to the application.  */
627         status = 0;                                     /* Used on x86, but not on other arches */
628 #if defined (__SUPPORT_LD_DEBUG__)
629         if(_dl_debug) _dl_dprintf(_dl_debug_file,"\ntransfering control: %s\n\n", _dl_progname);        
630 #endif    
631         _dl_elf_main = (int (*)(int, char **, char **)) auxvt[AT_ENTRY].a_un.a_fcn;
632         START();
633 }
634
635 #if defined (__SUPPORT_LD_DEBUG__)
636 static void debug_fini (int status, void *arg)
637 {
638         (void)status;
639         _dl_dprintf(_dl_debug_file,"\ncalling fini: %s\n\n", (const char*)arg);
640 }
641 #endif    
642
643 void _dl_get_ready_to_run(struct elf_resolve *tpnt, struct elf_resolve *app_tpnt,
644                 unsigned long load_addr, unsigned long *hash_addr,
645                 Elf32_auxv_t auxvt[AT_EGID + 1], char **envp, struct r_debug *debug_addr,
646                 unsigned char *malloc_buffer, unsigned char *mmap_zero, char **argv)
647
648 {
649         ElfW(Phdr) *ppnt;
650         char *lpntstr;
651         int i, goof = 0, be_lazy = RTLD_LAZY, trace_loaded_objects = 0;
652         struct dyn_elf *rpnt;
653         struct elf_resolve *tcurr;
654         struct elf_resolve *tpnt1;
655         unsigned long brk_addr, *lpnt;
656         int (*_dl_atexit) (void *);
657 #if defined (__SUPPORT_LD_DEBUG__)
658         int (*_dl_on_exit) (void (*FUNCTION)(int STATUS, void *ARG),void*);
659 #endif
660
661 #ifdef __SUPPORT_LD_DEBUG_EARLY__
662     /* Wahoo!!! */
663     SEND_STDERR("Cool, we managed to make a function call.\n");
664 #endif
665
666         /* Make it so _dl_malloc can use the page of memory we have already
667          * allocated.  We shouldn't need to grab any more memory.  This must
668          * be first since things like _dl_dprintf() use _dl_malloc().... */
669         _dl_malloc_addr = malloc_buffer;
670         _dl_mmap_zero = mmap_zero;
671
672         /* Now we have done the mandatory linking of some things.  We are now
673          * free to start using global variables, since these things have all been
674          * fixed up by now.  Still no function calls outside of this library ,
675          * since the dynamic resolver is not yet ready. */
676
677         if (argv[0]) {
678                 _dl_progname = argv[0];
679         }
680
681         /* Start to build the tables of the modules that are required for
682          * this beast to run.  We start with the basic executable, and then
683          * go from there.  Eventually we will run across ourself, and we
684          * will need to properly deal with that as well. */
685         lpnt = (unsigned long *) (tpnt->dynamic_info[DT_PLTGOT] + load_addr);
686
687         tpnt->chains = hash_addr;
688         tpnt->next = 0;
689         tpnt->libname = 0;
690         tpnt->libtype = program_interpreter;
691         tpnt->loadaddr = (ElfW(Addr)) load_addr;
692
693 #ifdef ALLOW_ZERO_PLTGOT
694         if (tpnt->dynamic_info[DT_PLTGOT])
695 #endif
696         {
697                 INIT_GOT(lpnt, tpnt);
698 #ifdef __SUPPORT_LD_DEBUG_EARLY__
699                 _dl_dprintf(_dl_debug_file, "GOT found at %x\n", lpnt);
700 #endif
701         }
702
703         /* OK, this was a big step, now we need to scan all of the user images
704            and load them properly. */
705
706         {
707                 ElfW(Ehdr) *epnt;
708                 ElfW(Phdr) *myppnt;
709                 int j;
710
711                 epnt = (ElfW(Ehdr) *) auxvt[AT_BASE].a_un.a_ptr;
712                 tpnt->n_phent = epnt->e_phnum;
713                 tpnt->ppnt = myppnt = (ElfW(Phdr) *) (load_addr + epnt->e_phoff);
714                 for (j = 0; j < epnt->e_phnum; j++, myppnt++) {
715                         if (myppnt->p_type == PT_DYNAMIC) {
716                                 tpnt->dynamic_addr = (ElfW(Dyn) *)myppnt->p_vaddr + load_addr;
717                                 tpnt->dynamic_size = myppnt->p_filesz;
718                         }
719                 }
720         }
721
722         brk_addr = 0;
723         rpnt = NULL;
724
725         /* At this point we are now free to examine the user application,
726            and figure out which libraries are supposed to be called.  Until
727            we have this list, we will not be completely ready for dynamic linking */
728
729         ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_ptr;
730         for (i = 0; i < auxvt[AT_PHNUM].a_un.a_val; i++, ppnt++) {
731                 if (ppnt->p_type == PT_LOAD) {
732 #ifndef __UCLIBC_PIE_SUPPORT__
733                         if (ppnt->p_vaddr + ppnt->p_memsz > brk_addr)
734                                 brk_addr = ppnt->p_vaddr + ppnt->p_memsz;
735 #else
736                         if (ppnt->p_vaddr + app_tpnt->loadaddr + ppnt->p_memsz > brk_addr)
737                                 brk_addr = ppnt->p_vaddr + app_tpnt->loadaddr + ppnt->p_memsz;
738 #endif
739                 }
740                 if (ppnt->p_type == PT_DYNAMIC) {
741 #ifndef ALLOW_ZERO_PLTGOT
742                         /* make sure it's really there. */
743                         if (app_tpnt->dynamic_info[DT_PLTGOT] == 0)
744                                 continue;
745 #endif
746                         /* OK, we have what we need - slip this one into the list. */
747 #ifndef __UCLIBC_PIE_SUPPORT__
748                         app_tpnt = _dl_add_elf_hash_table("", 0, 
749                                         app_tpnt->dynamic_info, ppnt->p_vaddr, ppnt->p_filesz);
750 #else
751                         app_tpnt = _dl_add_elf_hash_table("", (char *)app_tpnt->loadaddr,
752                                         app_tpnt->dynamic_info, ppnt->p_vaddr + app_tpnt->loadaddr, ppnt->p_filesz);
753 #endif
754                         _dl_loaded_modules->libtype = elf_executable;
755                         _dl_loaded_modules->ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_ptr;
756                         _dl_loaded_modules->n_phent = auxvt[AT_PHNUM].a_un.a_val;
757                         _dl_symbol_tables = rpnt = (struct dyn_elf *) _dl_malloc(sizeof(struct dyn_elf));
758                         _dl_memset(rpnt, 0, sizeof(struct dyn_elf));
759                         rpnt->dyn = _dl_loaded_modules;
760                         app_tpnt->usage_count++;
761                         app_tpnt->symbol_scope = _dl_symbol_tables;
762 #ifndef __UCLIBC_PIE_SUPPORT__
763                         lpnt = (unsigned long *) (app_tpnt->dynamic_info[DT_PLTGOT]);
764 #else
765                         lpnt = (unsigned long *) (app_tpnt->dynamic_info[DT_PLTGOT] + app_tpnt->loadaddr);
766 #endif
767 #ifdef ALLOW_ZERO_PLTGOT
768                         if (lpnt)
769 #endif
770                                 INIT_GOT(lpnt, _dl_loaded_modules);
771                 }
772
773                 /* OK, fill this in - we did not have this before */
774                 if (ppnt->p_type == PT_INTERP) {        
775                         int readsize = 0;
776                         char *pnt, *pnt1, buf[1024];
777                         tpnt->libname = _dl_strdup((char *) ppnt->p_offset +
778                                         (auxvt[AT_PHDR].a_un.a_val & PAGE_ALIGN));
779                         
780                         /* Determine if the shared lib loader is a symlink */
781                         _dl_memset(buf, 0, sizeof(buf));
782                         readsize = _dl_readlink(tpnt->libname, buf, sizeof(buf));
783                         if (readsize > 0 && readsize < (int)(sizeof(buf)-1)) {
784                                 pnt1 = _dl_strrchr(buf, '/');
785                                 if (pnt1 && buf != pnt1) {
786 #ifdef __SUPPORT_LD_DEBUG_EARLY__
787                                         _dl_dprintf(_dl_debug_file, "changing tpnt->libname from '%s' to '%s'\n", tpnt->libname, buf);
788 #endif
789                                         tpnt->libname = _dl_strdup(buf);
790                                 }
791                         }
792
793                         /* Store the path where the shared lib loader was found for 
794                          * later use */
795                         pnt = _dl_strdup(tpnt->libname);
796                         pnt1 = _dl_strrchr(pnt, '/');
797                         if (pnt != pnt1) {
798                                 *pnt1 = '\0';
799                                 _dl_ldsopath = pnt;
800                         } else {
801                                 _dl_ldsopath = tpnt->libname;
802                         }
803 #ifdef __SUPPORT_LD_DEBUG_EARLY__
804                         _dl_dprintf(_dl_debug_file, "Lib Loader:\t(%x) %s\n", tpnt->loadaddr, tpnt->libname);
805 #endif
806                 }
807         }
808
809
810         /* Now we need to figure out what kind of options are selected.
811            Note that for SUID programs we ignore the settings in LD_LIBRARY_PATH */
812         {
813                 if (_dl_getenv("LD_BIND_NOW", envp))
814                         be_lazy = 0;
815
816                 if ((auxvt[AT_UID].a_un.a_val == -1 && _dl_suid_ok()) ||
817                                 (auxvt[AT_UID].a_un.a_val != -1 && 
818                                  auxvt[AT_UID].a_un.a_val == auxvt[AT_EUID].a_un.a_val
819                                  && auxvt[AT_GID].a_un.a_val== auxvt[AT_EGID].a_un.a_val)) {
820                         _dl_secure = 0;
821                         _dl_preload = _dl_getenv("LD_PRELOAD", envp);
822                         _dl_library_path = _dl_getenv("LD_LIBRARY_PATH", envp);
823                 } else {
824                         _dl_secure = 1;
825                         _dl_preload = _dl_getenv("LD_PRELOAD", envp);
826                         _dl_unsetenv("LD_AOUT_PRELOAD", envp);
827                         _dl_unsetenv("LD_LIBRARY_PATH", envp);
828                         _dl_unsetenv("LD_AOUT_LIBRARY_PATH", envp);
829                         _dl_library_path = NULL;
830                 }
831         }
832
833 #ifdef __SUPPORT_LD_DEBUG__
834         _dl_debug    = _dl_getenv("LD_DEBUG", envp);
835         if (_dl_debug)
836         {
837           if (_dl_strstr(_dl_debug, "all")) {
838                 _dl_debug_detail = _dl_debug_move = _dl_debug_symbols
839                         = _dl_debug_reloc = _dl_debug_bindings = _dl_debug_nofixups = _dl_strstr(_dl_debug, "all");
840           }
841           else {
842                 _dl_debug_detail   = _dl_strstr(_dl_debug, "detail");
843                 _dl_debug_move     = _dl_strstr(_dl_debug, "move");
844                 _dl_debug_symbols  = _dl_strstr(_dl_debug, "sym");
845                 _dl_debug_reloc    = _dl_strstr(_dl_debug, "reloc");
846                 _dl_debug_nofixups = _dl_strstr(_dl_debug, "nofix");
847                 _dl_debug_bindings = _dl_strstr(_dl_debug, "bind");
848           }
849         }
850         {
851           const char *dl_debug_output;
852           
853           dl_debug_output = _dl_getenv("LD_DEBUG_OUTPUT", envp);
854
855           if (dl_debug_output)
856           {
857             char tmp[22], *tmp1, *filename;
858             int len1, len2;
859             
860             _dl_memset(tmp, 0, sizeof(tmp));
861             tmp1=_dl_simple_ltoa( tmp, (unsigned long)_dl_getpid());
862
863             len1 = _dl_strlen(dl_debug_output);
864             len2 = _dl_strlen(tmp1);
865
866             filename = _dl_malloc(len1+len2+2);
867
868             if (filename)
869             {
870               _dl_strcpy (filename, dl_debug_output);
871               filename[len1] = '.';
872               _dl_strcpy (&filename[len1+1], tmp1);
873
874               _dl_debug_file= _dl_open (filename, O_WRONLY|O_CREAT);
875               if (_dl_debug_file<0)
876               {
877                 _dl_debug_file = 2;
878                 _dl_dprintf (2, "can't open file: '%s'\n",filename);
879               }
880             }
881           }
882         }
883         
884         
885 #endif  
886         if (_dl_getenv("LD_TRACE_LOADED_OBJECTS", envp) != NULL) {
887                 trace_loaded_objects++;
888         }
889 #ifndef __LDSO_LDD_SUPPORT__
890         if (trace_loaded_objects) {
891                 _dl_dprintf(_dl_debug_file, "Use the ldd provided by uClibc\n");
892                 _dl_exit(1);
893         }
894 #endif
895
896         /*
897          * OK, fix one more thing - set up debug_addr so it will point
898          * to our chain.  Later we may need to fill in more fields, but this
899          * should be enough for now.
900          */
901         debug_addr->r_map = (struct link_map *) _dl_loaded_modules;
902         debug_addr->r_version = 1;
903         debug_addr->r_ldbase = load_addr;
904         debug_addr->r_brk = (unsigned long) &_dl_debug_state;
905         _dl_debug_addr = debug_addr;
906
907         /* Notify the debugger we are in a consistant state */
908         _dl_debug_addr->r_state = RT_CONSISTENT;
909         _dl_debug_state();
910
911         /* OK, we now have the application in the list, and we have some
912            basic stuff in place.  Now search through the list for other shared
913            libraries that should be loaded, and insert them on the list in the
914            correct order. */
915
916         _dl_map_cache();
917
918
919         if (_dl_preload) 
920         {
921                 char c, *str, *str2;
922
923                 str = _dl_preload;
924                 while (*str == ':' || *str == ' ' || *str == '\t')
925                         str++;
926                 while (*str) 
927                 {
928                         str2 = str;
929                         while (*str2 && *str2 != ':' && *str2 != ' ' && *str2 != '\t')
930                                 str2++;
931                         c = *str2;
932                         *str2 = '\0';
933                         if (!_dl_secure || _dl_strchr(str, '/') == NULL) 
934                         {
935                                 if ((tpnt1 = _dl_check_if_named_library_is_loaded(str, trace_loaded_objects))) 
936                                 {
937                                         continue;
938                                 }
939 #if defined (__SUPPORT_LD_DEBUG__)
940                                 if(_dl_debug) _dl_dprintf(_dl_debug_file, "\tfile='%s';  needed by '%s'\n", 
941                                                 str, _dl_progname);
942 #endif
943                                 tpnt1 = _dl_load_shared_library(_dl_secure, &rpnt, NULL, str, trace_loaded_objects);
944                                 if (!tpnt1) {
945 #ifdef __LDSO_LDD_SUPPORT__
946                                         if (trace_loaded_objects)
947                                                 _dl_dprintf(1, "\t%s => not found\n", str);
948                                         else 
949 #endif
950                                         {
951                                                 _dl_dprintf(2, "%s: can't load " "library '%s'\n", _dl_progname, str);
952                                                 _dl_exit(15);
953                                         }
954                                 } else {
955 #ifdef __SUPPORT_LD_DEBUG_EARLY__
956                                         _dl_dprintf(_dl_debug_file, "Loading:\t(%x) %s\n", tpnt1->loadaddr, tpnt1->libname);
957 #endif
958 #ifdef __LDSO_LDD_SUPPORT__
959                                         if (trace_loaded_objects && tpnt1->usage_count==1) {
960                                                 /* this is a real hack to make ldd not print 
961                                                  * the library itself when run on a library. */
962                                                 if (_dl_strcmp(_dl_progname, str) != 0)
963                                                         _dl_dprintf(1, "\t%s => %s (%x)\n", str, tpnt1->libname, 
964                                                                         (unsigned) tpnt1->loadaddr);
965                                         }
966 #endif
967                                 }
968                         }
969                         *str2 = c;
970                         str = str2;
971                         while (*str == ':' || *str == ' ' || *str == '\t')
972                                 str++;
973                 }
974         }
975
976 #ifdef SUPPORT_LDSO_PRELOAD_FILE
977         {
978                 int fd;
979                 struct stat st;
980                 char *preload;
981                 if (!_dl_stat(LDSO_PRELOAD, &st) && st.st_size > 0) {
982                         if ((fd = _dl_open(LDSO_PRELOAD, O_RDONLY)) < 0) {
983                                 _dl_dprintf(2, "%s: can't open file '%s'\n", 
984                                                 _dl_progname, LDSO_PRELOAD);
985                         } else {
986                                 preload = (caddr_t) _dl_mmap(0, st.st_size + 1, 
987                                                 PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
988                                 _dl_close(fd);
989                                 if (preload == (caddr_t) - 1) {
990                                         _dl_dprintf(2, "%s: can't map file '%s'\n", 
991                                                         _dl_progname, LDSO_PRELOAD);
992                                 } else {
993                                         char c, *cp, *cp2;
994
995                                         /* convert all separators and comments to spaces */
996                                         for (cp = preload; *cp; /*nada */ ) {
997                                                 if (*cp == ':' || *cp == '\t' || *cp == '\n') {
998                                                         *cp++ = ' ';
999                                                 } else if (*cp == '#') {
1000                                                         do
1001                                                                 *cp++ = ' ';
1002                                                         while (*cp != '\n' && *cp != '\0');
1003                                                 } else {
1004                                                         cp++;
1005                                                 }
1006                                         }
1007
1008                                         /* find start of first library */
1009                                         for (cp = preload; *cp && *cp == ' '; cp++)
1010                                                 /*nada */ ;
1011
1012                                         while (*cp) {
1013                                                 /* find end of library */
1014                                                 for (cp2 = cp; *cp && *cp != ' '; cp++)
1015                                                         /*nada */ ;
1016                                                 c = *cp;
1017                                                 *cp = '\0';
1018
1019                                                 if ((tpnt1 = _dl_check_if_named_library_is_loaded(cp2, trace_loaded_objects))) 
1020                                                 {
1021                                                         continue;
1022                                                 }
1023 #if defined (__SUPPORT_LD_DEBUG__)
1024                                                 if(_dl_debug) _dl_dprintf(_dl_debug_file, "\tfile='%s';  needed by '%s'\n", 
1025                                                                 cp2, _dl_progname);
1026 #endif
1027                                                 tpnt1 = _dl_load_shared_library(0, &rpnt, NULL, cp2, trace_loaded_objects);
1028                                                 if (!tpnt1) {
1029 #ifdef __LDSO_LDD_SUPPORT__
1030                                                         if (trace_loaded_objects)
1031                                                                 _dl_dprintf(1, "\t%s => not found\n", cp2);
1032                                                         else 
1033 #endif
1034                                                         {
1035                                                                 _dl_dprintf(2, "%s: can't load library '%s'\n", _dl_progname, cp2);
1036                                                                 _dl_exit(15);
1037                                                         }
1038                                                 } else {
1039 #ifdef __SUPPORT_LD_DEBUG_EARLY__
1040                                                         _dl_dprintf(_dl_debug_file, "Loading:\t(%x) %s\n", tpnt1->loadaddr, tpnt1->libname);
1041 #endif
1042 #ifdef __LDSO_LDD_SUPPORT__
1043                                                         if (trace_loaded_objects && tpnt1->usage_count==1) {
1044                                                                 _dl_dprintf(1, "\t%s => %s (%x)\n", cp2, 
1045                                                                                 tpnt1->libname, (unsigned) tpnt1->loadaddr);
1046                                                         }
1047 #endif
1048                                                 }
1049
1050                                                 /* find start of next library */
1051                                                 *cp = c;
1052                                                 for ( /*nada */ ; *cp && *cp == ' '; cp++)
1053                                                         /*nada */ ;
1054                                         }
1055
1056                                         _dl_munmap(preload, st.st_size + 1);
1057                                 }
1058                         }
1059                 }
1060         }
1061 #endif
1062
1063         for (tcurr = _dl_loaded_modules; tcurr; tcurr = tcurr->next) 
1064         {
1065                 Elf32_Dyn *dpnt;
1066                 for (dpnt = (Elf32_Dyn *) tcurr->dynamic_addr; dpnt->d_tag; dpnt++) 
1067                 {
1068                         if (dpnt->d_tag == DT_NEEDED) 
1069                         {
1070                                 char *name;
1071                                 lpntstr = (char*) (tcurr->loadaddr + tcurr->dynamic_info[DT_STRTAB] + dpnt->d_un.d_val);
1072                                 name = _dl_get_last_path_component(lpntstr);
1073
1074                                 if ((tpnt1 = _dl_check_if_named_library_is_loaded(name, trace_loaded_objects))) 
1075                                 {
1076                                         continue;
1077                                 }
1078 #if defined (__SUPPORT_LD_DEBUG__)
1079                                 if(_dl_debug) _dl_dprintf(_dl_debug_file, "\tfile='%s';  needed by '%s'\n", 
1080                                                 lpntstr, _dl_progname);
1081 #endif
1082                                 if (!(tpnt1 = _dl_load_shared_library(0, &rpnt, tcurr, lpntstr, trace_loaded_objects)))
1083                                 {
1084 #ifdef __LDSO_LDD_SUPPORT__
1085                                         if (trace_loaded_objects) {
1086                                                 _dl_dprintf(1, "\t%s => not found\n", lpntstr);
1087                                                 continue;
1088                                         } else 
1089 #endif
1090                                         {
1091                                                 _dl_dprintf(2, "%s: can't load library '%s'\n", _dl_progname, lpntstr);
1092                                                 _dl_exit(16);
1093                                         }
1094                                 } else {
1095 #ifdef __SUPPORT_LD_DEBUG_EARLY__
1096                                         _dl_dprintf(_dl_debug_file, "Loading:\t(%x) %s\n", tpnt1->loadaddr, tpnt1->libname);
1097 #endif
1098 #ifdef __LDSO_LDD_SUPPORT__
1099                                         if (trace_loaded_objects && tpnt1->usage_count==1) {
1100                                                 _dl_dprintf(1, "\t%s => %s (%x)\n", lpntstr, tpnt1->libname, 
1101                                                                 (unsigned) tpnt1->loadaddr);
1102                                         }
1103 #endif
1104                                 }
1105                         }
1106                 }
1107         }
1108
1109
1110         _dl_unmap_cache();
1111
1112         /*
1113          * If the program interpreter is not in the module chain, add it.  This will
1114          * be required for dlopen to be able to access the internal functions in the 
1115          * dynamic linker.
1116          */
1117         if (tpnt) {
1118                 tcurr = _dl_loaded_modules;
1119                 if (tcurr)
1120                         while (tcurr->next)
1121                                 tcurr = tcurr->next;
1122                 tpnt->next = NULL;
1123                 tpnt->usage_count++;
1124
1125                 if (tcurr) {
1126                         tcurr->next = tpnt;
1127                         tpnt->prev = tcurr;
1128                 } else {
1129                         _dl_loaded_modules = tpnt;
1130                         tpnt->prev = NULL;
1131                 }
1132                 if (rpnt) {
1133                         rpnt->next = (struct dyn_elf *) _dl_malloc(sizeof(struct dyn_elf));
1134                         _dl_memset(rpnt->next, 0, sizeof(struct dyn_elf));
1135                         rpnt->next->prev = rpnt;
1136                         rpnt = rpnt->next;
1137                 } else {
1138                         rpnt = (struct dyn_elf *) _dl_malloc(sizeof(struct dyn_elf));
1139                         _dl_memset(rpnt, 0, sizeof(struct dyn_elf));
1140                 }
1141                 rpnt->dyn = tpnt;
1142                 tpnt = NULL;
1143         }
1144
1145 #ifdef __LDSO_LDD_SUPPORT__
1146         /* End of the line for ldd.... */
1147         if (trace_loaded_objects) {
1148                 _dl_dprintf(1, "\t%s => %s (%x)\n", rpnt->dyn->libname + (_dl_strlen(_dl_ldsopath)) + 1, 
1149                                 rpnt->dyn->libname, rpnt->dyn->loadaddr);  
1150                 _dl_exit(0);
1151         }
1152 #endif
1153
1154
1155 #ifdef __mips__
1156         /*
1157          * Relocation of the GOT entries for MIPS have to be done
1158          * after all the libraries have been loaded.
1159          */
1160         _dl_perform_mips_global_got_relocations(_dl_loaded_modules);
1161 #endif
1162
1163 #ifdef __SUPPORT_LD_DEBUG_EARLY__
1164         _dl_dprintf(_dl_debug_file, "Beginning relocation fixups\n");
1165 #endif
1166         /*
1167          * OK, now all of the kids are tucked into bed in their proper addresses.
1168          * Now we go through and look for REL and RELA records that indicate fixups
1169          * to the GOT tables.  We need to do this in reverse order so that COPY
1170          * directives work correctly */
1171         if (_dl_symbol_tables)
1172                 goof += _dl_fixup(_dl_symbol_tables, be_lazy);
1173
1174
1175         /* OK, at this point things are pretty much ready to run.  Now we
1176            need to touch up a few items that are required, and then
1177            we can let the user application have at it.  Note that
1178            the dynamic linker itself is not guaranteed to be fully
1179            dynamicly linked if we are using ld.so.1, so we have to look
1180            up each symbol individually. */
1181
1182
1183         _dl_brkp = (unsigned long *) (intptr_t) _dl_find_hash("___brk_addr", NULL, NULL, symbolrel);
1184         
1185         if (_dl_brkp) {
1186                 *_dl_brkp = brk_addr;
1187         }
1188         _dl_envp = (unsigned long *) (intptr_t) _dl_find_hash("__environ", NULL, NULL, symbolrel);
1189
1190         if (_dl_envp) {
1191                 *_dl_envp = (unsigned long) envp;
1192         }
1193
1194 #ifndef FORCE_SHAREABLE_TEXT_SEGMENTS
1195         {
1196                 unsigned int j;
1197                 ElfW(Phdr) *myppnt;
1198
1199                 /* We had to set the protections of all pages to R/W for dynamic linking.
1200                    Set text pages back to R/O */
1201                 for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) {
1202                         for (myppnt = tpnt->ppnt, j = 0; j < tpnt->n_phent; j++, myppnt++) {
1203                                 if (myppnt->p_type == PT_LOAD && !(myppnt->p_flags & PF_W) && tpnt->dynamic_info[DT_TEXTREL]) {
1204                                         _dl_mprotect((void *) (tpnt->loadaddr + (myppnt->p_vaddr & PAGE_ALIGN)), 
1205                                                         (myppnt->p_vaddr & ADDR_ALIGN) + (unsigned long) myppnt->p_filesz, LXFLAGS(myppnt->p_flags));
1206                                 }
1207                         }
1208                 }
1209
1210         }
1211 #endif
1212         _dl_atexit = (int (*)(void *)) (intptr_t) _dl_find_hash("atexit", NULL, NULL, symbolrel);
1213 #if defined (__SUPPORT_LD_DEBUG__)
1214         _dl_on_exit = (int (*)(void (*)(int, void *),void*)) 
1215                 (intptr_t) _dl_find_hash("on_exit", NULL, NULL, symbolrel);
1216 #endif
1217
1218         /* Notify the debugger we have added some objects. */
1219         _dl_debug_addr->r_state = RT_ADD;
1220         _dl_debug_state();
1221
1222         for (rpnt = _dl_symbol_tables; rpnt!=NULL&& rpnt->next!=NULL; rpnt=rpnt->next)
1223           ;
1224           
1225         for (;rpnt!=NULL; rpnt=rpnt->prev)
1226         {
1227                 tpnt = rpnt->dyn;
1228
1229                 if (tpnt->libtype == program_interpreter)
1230                         continue;
1231
1232                 /* Apparently crt0/1 for the application is responsible for handling this.
1233                  * We only need to run the init/fini for shared libraries
1234                  */
1235                 if (tpnt->libtype == elf_executable)
1236                         break;      /* at this point all shared libs are initialized !! */
1237
1238                 if (tpnt->init_flag & INIT_FUNCS_CALLED)
1239                         continue;
1240                 tpnt->init_flag |= INIT_FUNCS_CALLED;
1241
1242                 if (tpnt->dynamic_info[DT_INIT]) {
1243                         void (*dl_elf_func) (void);
1244                         dl_elf_func = (void (*)(void)) (intptr_t) (tpnt->loadaddr + tpnt->dynamic_info[DT_INIT]);
1245 #if defined (__SUPPORT_LD_DEBUG__)
1246                         if(_dl_debug) _dl_dprintf(_dl_debug_file,"\ncalling init: %s\n\n", tpnt->libname);      
1247 #endif    
1248                         (*dl_elf_func) ();
1249                 }
1250                 if (_dl_atexit && tpnt->dynamic_info[DT_FINI]) {
1251                         void (*dl_elf_func) (void);
1252                         dl_elf_func = (void (*)(void)) (intptr_t) (tpnt->loadaddr + tpnt->dynamic_info[DT_FINI]);
1253                         (*_dl_atexit) (dl_elf_func);
1254 #if defined (__SUPPORT_LD_DEBUG__)
1255                         if(_dl_debug && _dl_on_exit)
1256                         {
1257                                 (*_dl_on_exit)(debug_fini, tpnt->libname);
1258                         }
1259 #endif
1260                 }
1261 #if defined (__SUPPORT_LD_DEBUG__)
1262                 else {
1263                         if (!_dl_atexit)
1264                                 _dl_dprintf(_dl_debug_file, "%s: The address of atexit () is 0x0.\n", tpnt->libname);
1265 #if 0
1266                         if (!tpnt->dynamic_info[DT_FINI])
1267                                 _dl_dprintf(_dl_debug_file, "%s: Invalid .fini section.\n", tpnt->libname);
1268 #endif
1269                 }
1270 #endif
1271         }
1272
1273         /* Notify the debugger that all objects are now mapped in.  */
1274         _dl_debug_addr->r_state = RT_CONSISTENT;
1275         _dl_debug_state();
1276 }
1277
1278 /*
1279  * This stub function is used by some debuggers.  The idea is that they
1280  * can set an internal breakpoint on it, so that we are notified when the
1281  * address mapping is changed in some way.
1282  */
1283 void _dl_debug_state(void)
1284 {
1285 }
1286
1287 char *_dl_getenv(const char *symbol, char **envp)
1288 {
1289         char *pnt;
1290         const char *pnt1;
1291
1292         while ((pnt = *envp++)) {
1293                 pnt1 = symbol;
1294                 while (*pnt && *pnt == *pnt1)
1295                         pnt1++, pnt++;
1296                 if (!*pnt || *pnt != '=' || *pnt1)
1297                         continue;
1298                 return pnt + 1;
1299         }
1300         return 0;
1301 }
1302
1303 void _dl_unsetenv(const char *symbol, char **envp)
1304 {
1305         char *pnt;
1306         const char *pnt1;
1307         char **newenvp = envp;
1308
1309         for (pnt = *envp; pnt; pnt = *++envp) {
1310                 pnt1 = symbol;
1311                 while (*pnt && *pnt == *pnt1)
1312                         pnt1++, pnt++;
1313                 if (!*pnt || *pnt != '=' || *pnt1)
1314                         *newenvp++ = *envp;
1315         }
1316         *newenvp++ = *envp;
1317         return;
1318 }
1319
1320 #include "hash.c"
1321 #include "readelflib1.c"