OSDN Git Service

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