OSDN Git Service

Yet another major rework. This time around, rework it to no longer
authorEric Andersen <andersen@codepoet.org>
Tue, 1 May 2001 14:20:45 +0000 (14:20 -0000)
committerEric Andersen <andersen@codepoet.org>
Tue, 1 May 2001 14:20:45 +0000 (14:20 -0000)
use linux kernel header files.
 -Erik

27 files changed:
ldso/ldso/boot1.c
ldso/ldso/dl-elf.c
ldso/ldso/dl-hash.c
ldso/ldso/hash.c
ldso/ldso/hash.h
ldso/ldso/i386/dl-syscalls.h
ldso/ldso/i386/elfinterp.c
ldso/ldso/i386/ld_syscalls.h
ldso/ldso/i386/syscalls.h
ldso/ldso/ld-uClibc.c
ldso/ldso/ld_hash.h
ldso/ldso/ld_string.h
ldso/ldso/ld_syscall.h
ldso/ldso/ldso.c
ldso/ldso/linuxelf.h
ldso/ldso/m68k/dl-syscalls.h
ldso/ldso/m68k/elfinterp.c
ldso/ldso/m68k/ld_syscalls.h
ldso/ldso/m68k/syscalls.h
ldso/ldso/readelflib1.c
ldso/ldso/sparc/dl-syscalls.h
ldso/ldso/sparc/elfinterp.c
ldso/ldso/sparc/ld_syscalls.h
ldso/ldso/sparc/syscalls.h
ldso/ldso/string.h
ldso/ldso/syscall.h
ldso/ldso/vsprintf.c

index 3b613fb..948a6e1 100644 (file)
  * can transfer control to the user's application.
  */
 
+#include <sys/mman.h>                  // For MAP_ANONYMOUS -- differs between platforms
 #include <stdarg.h>
-#include <linux/types.h>
-#include <linux/fcntl.h>
-#include <linux/unistd.h>
-#include <linux/elf.h>
-#include <linux/mman.h>
+#include "elf.h"
 #include "link.h"
-
 #include "sysdep.h"
 #include "hash.h"
-#include "linuxelf.h"
 #include "syscall.h"
 #include "string.h"
 
 
 #define ALLOW_ZERO_PLTGOT
 
-static char * _dl_malloc_addr, *_dl_mmap_zero;
-char * _dl_library_path = 0; /* Where we look for libraries */
-char *_dl_preload = 0; /* Things to be loaded before the libs. */
+static char *_dl_malloc_addr, *_dl_mmap_zero;
+char *_dl_library_path = 0;            /* Where we look for libraries */
+char *_dl_preload = 0;                 /* Things to be loaded before the libs. */
 char *_dl_progname = "/lib/ld-linux-uclibc.so.1";
-static char * _dl_not_lazy = 0;
-static char * _dl_warn = 0; /* Used by ldd */
-static char * _dl_trace_loaded_objects = 0;
-static int (*_dl_elf_main)(int, char **, char**);
+static char *_dl_not_lazy = 0;
+static char *_dl_warn = 0;             /* Used by ldd */
+static char *_dl_trace_loaded_objects = 0;
+static int (*_dl_elf_main) (int, char **, char **);
 
-static int (*_dl_elf_init)(void);
+static int (*_dl_elf_init) (void);
 
-void * (*_dl_malloc_function)(int size) = NULL;
+void *(*_dl_malloc_function) (int size) = NULL;
 
-struct r_debug * _dl_debug_addr = NULL;
+struct r_debug *_dl_debug_addr = NULL;
 
-unsigned int * _dl_brkp; 
+unsigned int *_dl_brkp;
 
-unsigned int * _dl_envp;
+unsigned int *_dl_envp;
 
 #define DL_MALLOC(SIZE) ((void *) (malloc_buffer += SIZE, malloc_buffer - SIZE))
 /*
@@ -151,19 +146,10 @@ unsigned int * _dl_envp;
   RESULT = hash; \
 }
 extern int _dl_linux_resolve(void);
-extern char * _dl_strdup(const char *);
-extern char * _dl_getenv(char * symbol, char ** envp);
-extern void _dl_unsetenv(char * symbol, char ** envp);
-extern int _dl_fixup(struct elf_resolve * tpnt);
-
-/*
- * Datatype of a relocation on this platform
- */
-#ifdef ELF_USES_RELOCA
-typedef struct elf32_rela ELF_RELOC;
-#else
-typedef struct elf32_rel ELF_RELOC;
-#endif
+extern char *_dl_strdup(const char *);
+extern char *_dl_getenv(char *symbol, char **envp);
+extern void _dl_unsetenv(char *symbol, char **envp);
+extern int _dl_fixup(struct elf_resolve *tpnt);
 
 /*
  * This stub function is used by some debuggers.  The idea is that they
@@ -172,71 +158,72 @@ typedef struct elf32_rel ELF_RELOC;
  */
 void _dl_debug_state()
 {
-  return;
+       return;
 }
 
 void _dl_boot(int args);
 
-void _dl_boot(int args){
-  unsigned int argc;
-  char ** argv, ** envp;
-  int status;
-
-  unsigned int load_addr;
-  unsigned int * got;
-  unsigned int * aux_dat;
-  int goof = 0;
-  struct elfhdr * header;
-  struct elf_resolve * tpnt;
-  struct dyn_elf * rpnt;
-  struct elf_resolve * app_tpnt;
-  unsigned int brk_addr;
-  unsigned int dl_data[AT_EGID+1];
-  unsigned char * malloc_buffer, *mmap_zero;
-  int (*_dl_atexit)(void *);
-  int * lpnt;
-  struct dynamic * dpnt;
-  unsigned int *hash_addr;
-  struct r_debug * debug_addr;
-  unsigned int *chains;
-  int indx;
-  int _dl_secure;
-
-  /* First obtain the information on the stack that tells us more about
-     what binary is loaded, where it is loaded, etc, etc */
-
-  GET_ARGV(aux_dat, args);
-  argc = *(aux_dat - 1);
-  argv = (char **) aux_dat;
-  aux_dat += argc;  /* Skip over the argv pointers */
-  aux_dat++;  /* Skip over NULL at end of argv */
-  envp = (char **) aux_dat;
-  while(*aux_dat) aux_dat++;  /* Skip over the envp pointers */
-  aux_dat++;  /* Skip over NULL at end of envp */
-  dl_data[AT_UID] = -1; /* check later to see if it is changed */
-  while(*aux_dat)
-    {
-      unsigned int * ad1;
-      ad1 = aux_dat + 1;
-      if( *aux_dat <= AT_EGID ) dl_data[*aux_dat] = *ad1;
-      aux_dat += 2;
-    }
-
-  /* Next, locate the GOT */
-
-  load_addr = dl_data[AT_BASE];
-
-  GET_GOT(got);
-  dpnt = (struct dynamic *) (*got + load_addr);
-  /* OK, time for another hack.  Now call mmap to get a page of writable
-     memory that can be used for a temporary malloc.  We do not know brk
-     yet, so we cannot use real malloc. */
-
-  {
-    /* This hack is to work around a suspected asm bug in gcc-2.7.0 */
-    //int zfileno;
-//#define ZFILENO ((-1 & (~zfileno)) | zfileno)
+void _dl_boot(int args)
+{
+       unsigned int argc;
+       char **argv, **envp;
+       int status;
+
+       unsigned int load_addr;
+       unsigned int *got;
+       unsigned int *aux_dat;
+       int goof = 0;
+       elfhdr *header;
+       struct elf_resolve *tpnt;
+       struct dyn_elf *rpnt;
+       struct elf_resolve *app_tpnt;
+       unsigned int brk_addr;
+       unsigned int dl_data[AT_EGID + 1];
+       unsigned char *malloc_buffer, *mmap_zero;
+       int (*_dl_atexit) (void *);
+       int *lpnt;
+       Elf32_Dyn *dpnt;
+       unsigned int *hash_addr;
+       struct r_debug *debug_addr;
+       unsigned int *chains;
+       int indx;
+       int _dl_secure;
+
+       /* First obtain the information on the stack that tells us more about
+          what binary is loaded, where it is loaded, etc, etc */
+
+       GET_ARGV(aux_dat, args);
+       argc = *(aux_dat - 1);
+       argv = (char **) aux_dat;
+       aux_dat += argc;                        /* Skip over the argv pointers */
+       aux_dat++;                              /* Skip over NULL at end of argv */
+       envp = (char **) aux_dat;
+       while (*aux_dat)
+               aux_dat++;                      /* Skip over the envp pointers */
+       aux_dat++;                              /* Skip over NULL at end of envp */
+       dl_data[AT_UID] = -1;                   /* check later to see if it is changed */
+       while (*aux_dat) 
+       {
+               unsigned int *ad1;
+
+               ad1 = aux_dat + 1;
+               if (*aux_dat <= AT_EGID)
+                       dl_data[*aux_dat] = *ad1;
+               aux_dat += 2;
+       }
+
+       /* Next, locate the GOT */
+
+       load_addr = dl_data[AT_BASE];
+
+       GET_GOT(got);
+       dpnt = (Elf32_Dyn *) (*got + load_addr);
+
+       /* OK, time for another hack.  Now call mmap to get a page of writable
+          memory that can be used for a temporary malloc.  We do not know brk
+          yet, so we cannot use real malloc. */
+
+       {
 #define ZFILENO -1
 
 #ifndef MAP_ANONYMOUS
@@ -247,178 +234,195 @@ void _dl_boot(int args){
 #endif
 #endif
 
-    /* See if we need to relocate this address */
-    mmap_zero = malloc_buffer = (unsigned char *) _dl_mmap((void*) 0, 4096,
-                            PROT_READ | PROT_WRITE, 
-                            MAP_PRIVATE | MAP_ANONYMOUS, ZFILENO, 0);
-    if(_dl_mmap_check_error(mmap_zero)) {
-       SEND_STDERR("dl_boot: mmap of /dev/zero failed!\n");
-       _dl_exit(13);
-    }
-  }
-
-  tpnt = DL_MALLOC(sizeof(struct elf_resolve));
-  REALIGN();
-  _dl_memset (tpnt, 0, sizeof (*tpnt));
-  app_tpnt = DL_MALLOC(sizeof(struct elf_resolve));
-  REALIGN();
-  _dl_memset (app_tpnt, 0, sizeof (*app_tpnt));
-
-  /*
-   * This is used by gdb to locate the chain of shared libraries that are currently loaded.
-   */
-  debug_addr = DL_MALLOC(sizeof(struct r_debug));
-  REALIGN();
-  _dl_memset (debug_addr, 0, sizeof (*debug_addr));
-
-  /* OK, that was easy.  Next scan the DYNAMIC section of the image.
-     We are only doing ourself right now - we will have to do the rest later */
-
-  while(dpnt->d_tag)
-    {
-      tpnt->dynamic_info[dpnt->d_tag] = dpnt->d_un.d_val;
-      if(dpnt->d_tag == DT_TEXTREL ||
-        SVR4_BUGCOMPAT) tpnt->dynamic_info[DT_TEXTREL] = 1;
-      dpnt++;
-    }
-
-  {
-    struct elf_phdr * ppnt;
-    int i;
-    
-    ppnt = (struct elf_phdr *) dl_data[AT_PHDR];
-    for(i=0; i<dl_data[AT_PHNUM]; i++, ppnt++)
-      if(ppnt->p_type == PT_DYNAMIC) {
-       dpnt = (struct dynamic *) ppnt->p_vaddr;
-       while(dpnt->d_tag)
-         {
-           if(dpnt->d_tag > DT_JMPREL) {dpnt++; continue; }
-           app_tpnt->dynamic_info[dpnt->d_tag] = dpnt->d_un.d_val;
-           if(dpnt->d_tag == DT_DEBUG) dpnt->d_un.d_val = (int) debug_addr;
-           if(dpnt->d_tag == DT_TEXTREL ||
-              SVR4_BUGCOMPAT) app_tpnt->dynamic_info[DT_TEXTREL] = 1;
-           dpnt++;
-         }
-      }
-  }
-
-  /* Get some more of the information that we will need to dynamicly link
-     this module to itself */
-
-  hash_addr = (unsigned int *) (tpnt->dynamic_info[DT_HASH]+load_addr);
-  tpnt->nbucket = *hash_addr++;
-  tpnt->nchain = *hash_addr++;
-  tpnt->elf_buckets = hash_addr;
-  hash_addr += tpnt->nbucket;
-  chains = hash_addr;
-
-  /* Ugly, ugly.  We need to call mprotect to change the protection of
-     the text pages so that we can do the dynamic linking.  We can set the
-     protection back again once we are done */
-
-  {
-    struct elf_phdr * ppnt;
-    int i;
-
-    /* First cover the shared library/dynamic linker. */
-    if(tpnt->dynamic_info[DT_TEXTREL]) {
-      header = (struct elfhdr *) dl_data[AT_BASE];         
-      ppnt = (struct elf_phdr *) (dl_data[AT_BASE] + header->e_phoff);
-      for(i=0; i<header->e_phnum ; i++, ppnt++) {
-       if(ppnt->p_type == PT_LOAD && !(ppnt->p_flags & PF_W))
-               _dl_mprotect((void *) (load_addr + (ppnt->p_vaddr & 0xfffff000)),
-                             (ppnt->p_vaddr & 0xfff) + (unsigned int) ppnt->p_filesz,
-                             PROT_READ | PROT_WRITE | PROT_EXEC);
-      }
-    }
-    
-    /* Now cover the application program. */
-    if(app_tpnt->dynamic_info[DT_TEXTREL]) {
-      ppnt = (struct elf_phdr *) dl_data[AT_PHDR];
-      for(i=0; i<dl_data[AT_PHNUM]; i++, ppnt++) {
-       if(ppnt->p_type == PT_LOAD && !(ppnt->p_flags & PF_W))
-         _dl_mprotect((void *) (ppnt->p_vaddr & 0xfffff000),
-                      (ppnt->p_vaddr & 0xfff) + (unsigned int) ppnt->p_filesz,
-                      PROT_READ | PROT_WRITE | PROT_EXEC);
-      }
-    }
-  }
-
-  /* OK, now do the relocations.  We do not do a lazy binding here, so
-   that once we are done, we have considerably more flexibility. */
-
-  goof = 0;
-  for(indx=0; indx < 2; indx++)
-    {
-      int i;
-      ELF_RELOC * rpnt;
-      unsigned int * reloc_addr;
-      unsigned int symbol_addr;
-      int symtab_index;
-      unsigned int rel_addr, rel_size;
-
-  
-#ifdef ELF_USES_RELOCA
-      rel_addr = (indx ? tpnt->dynamic_info[DT_JMPREL] : tpnt->dynamic_info[DT_RELA]);
-      rel_size = (indx ? tpnt->dynamic_info[DT_PLTRELSZ] : tpnt->dynamic_info[DT_RELASZ]);
-#else
-      rel_addr = (indx ? tpnt->dynamic_info[DT_JMPREL] : tpnt->dynamic_info[DT_REL]);
-      rel_size = (indx ? tpnt->dynamic_info[DT_PLTRELSZ] : tpnt->dynamic_info[DT_RELSZ]);
-#endif
+               /* See if we need to relocate this address */
+               mmap_zero = malloc_buffer = (unsigned char *) _dl_mmap((void *) 0, 4096, 
+                       PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, ZFILENO, 0);
+               if (_dl_mmap_check_error(mmap_zero)) {
+                       SEND_STDERR("dl_boot: mmap of /dev/zero failed!\n");
+                       _dl_exit(13);
+               }
+       }
 
+       tpnt = DL_MALLOC(sizeof(struct elf_resolve));
+       REALIGN();
+       _dl_memset(tpnt, 0, sizeof(*tpnt));
+       app_tpnt = DL_MALLOC(sizeof(struct elf_resolve));
+       REALIGN();
+       _dl_memset(app_tpnt, 0, sizeof(*app_tpnt));
 
-      if(!rel_addr) continue;
+       /*
+        * This is used by gdb to locate the chain of shared libraries that are currently loaded.
+        */
+       debug_addr = DL_MALLOC(sizeof(struct r_debug));
+       REALIGN();
+       _dl_memset(debug_addr, 0, sizeof(*debug_addr));
+
+       /* OK, that was easy.  Next scan the DYNAMIC section of the image.
+          We are only doing ourself right now - we will have to do the rest later */
+
+       while (dpnt->d_tag) {
+               tpnt->dynamic_info[dpnt->d_tag] = dpnt->d_un.d_val;
+               if (dpnt->d_tag == DT_TEXTREL || SVR4_BUGCOMPAT)
+                       tpnt->dynamic_info[DT_TEXTREL] = 1;
+               dpnt++;
+       }
 
-      /* Now parse the relocation information */
-      rpnt = (ELF_RELOC *) (rel_addr + load_addr);
-      for(i=0; i< rel_size; i+=sizeof(ELF_RELOC), rpnt++){
-       reloc_addr = (int *) (load_addr + (int)rpnt->r_offset);
-       symtab_index = ELF32_R_SYM(rpnt->r_info);
-       symbol_addr = 0;
-       if(symtab_index) {
-         char * strtab;
-         struct elf32_sym * symtab;
+       {
+               elf_phdr *ppnt;
+               int i;
+
+               ppnt = (elf_phdr *) dl_data[AT_PHDR];
+               for (i = 0; i < dl_data[AT_PHNUM]; i++, ppnt++)
+                       if (ppnt->p_type == PT_DYNAMIC) {
+                               dpnt = (Elf32_Dyn *) ppnt->p_vaddr;
+                               while (dpnt->d_tag) {
+                                       if (dpnt->d_tag > DT_JMPREL) {
+                                               dpnt++;
+                                               continue;
+                                       }
+                                       app_tpnt->dynamic_info[dpnt->d_tag] = dpnt->d_un.d_val;
+                                       if (dpnt->d_tag == DT_DEBUG)
+                                               dpnt->d_un.d_val = (int) debug_addr;
+                                       if (dpnt->d_tag == DT_TEXTREL || SVR4_BUGCOMPAT)
+                                               app_tpnt->dynamic_info[DT_TEXTREL] = 1;
+                                       dpnt++;
+                               }
+                       }
+       }
 
-         symtab = (struct elf32_sym *) (tpnt->dynamic_info[DT_SYMTAB]+load_addr);
-         strtab = (char *) (tpnt->dynamic_info[DT_STRTAB]+load_addr);
+       /* Get some more of the information that we will need to dynamicly link
+          this module to itself */
 
-         /* We only do a partial dynamic linking right now.  The user
-            is not supposed to redefine any symbols that start with
-            a '_', so we can do this with confidence. */
+       hash_addr = (unsigned int *) (tpnt->dynamic_info[DT_HASH] + load_addr);
+       tpnt->nbucket = *hash_addr++;
+       tpnt->nchain = *hash_addr++;
+       tpnt->elf_buckets = hash_addr;
+       hash_addr += tpnt->nbucket;
+       chains = hash_addr;
 
-         if (!_dl_symbol(strtab + symtab[symtab_index].st_name)) continue;
+       /* Ugly, ugly.  We need to call mprotect to change the protection of
+          the text pages so that we can do the dynamic linking.  We can set the
+          protection back again once we are done */
 
-         symbol_addr = load_addr + symtab[symtab_index].st_value;
+       {
+               elf_phdr *ppnt;
+               int i;
+
+               /* First cover the shared library/dynamic linker. */
+               if (tpnt->dynamic_info[DT_TEXTREL]) {
+                       header = (elfhdr *) dl_data[AT_BASE];
+                       ppnt = (elf_phdr *) (dl_data[AT_BASE] + header->e_phoff);
+                       for (i = 0; i < header->e_phnum; i++, ppnt++) {
+                               if (ppnt->p_type == PT_LOAD && !(ppnt->p_flags & PF_W))
+                                       _dl_mprotect((void *) (load_addr + 
+                                               (ppnt->p_vaddr & 0xfffff000)), 
+                                               (ppnt->p_vaddr & 0xfff) + 
+                                               (unsigned int) ppnt->p_filesz, 
+                                               PROT_READ | PROT_WRITE | PROT_EXEC);
+                       }
+               }
 
-         if(!symbol_addr) {
-           /*
-            * This will segfault - you cannot call a function until
-            * we have finished the relocations.
-            */
-           SEND_STDERR("ELF dynamic loader - unable to self-bootstrap - symbol ");
-           SEND_STDERR(strtab + symtab[symtab_index].st_name);
-           SEND_STDERR(" undefined.\n");
-           goof++;
-         }
+               /* Now cover the application program. */
+               if (app_tpnt->dynamic_info[DT_TEXTREL]) {
+                       ppnt = (elf_phdr *) dl_data[AT_PHDR];
+                       for (i = 0; i < dl_data[AT_PHNUM]; i++, ppnt++) {
+                               if (ppnt->p_type == PT_LOAD && !(ppnt->p_flags & PF_W))
+                                       _dl_mprotect((void *) (ppnt->p_vaddr & 0xfffff000), 
+                                               (ppnt->p_vaddr & 0xfff) + 
+                                               (unsigned int) ppnt->p_filesz, 
+                                               PROT_READ | PROT_WRITE | PROT_EXEC);
+                       }
+               }
        }
-       /*
-        * Use this machine-specific macro to perform the actual relocation.
-        */
-       PERFORM_BOOTSTRAP_RELOC(rpnt, reloc_addr, symbol_addr, load_addr);
-      }
-    }
 
-  if (goof)    _dl_exit(14);
+       /* OK, now do the relocations.  We do not do a lazy binding here, so
+          that once we are done, we have considerably more flexibility. */
+
+       goof = 0;
+       for (indx = 0; indx < 2; indx++) {
+               int i;
+               ELF_RELOC *rpnt;
+               unsigned int *reloc_addr;
+               unsigned int symbol_addr;
+               int symtab_index;
+               unsigned int rel_addr, rel_size;
+
+
+#ifdef ELF_USES_RELOCA
+               rel_addr =
+                       (indx ? tpnt->dynamic_info[DT_JMPREL] : tpnt->
+                        dynamic_info[DT_RELA]);
+               rel_size =
+                       (indx ? tpnt->dynamic_info[DT_PLTRELSZ] : tpnt->
+                        dynamic_info[DT_RELASZ]);
+#else
+               rel_addr =
+                       (indx ? tpnt->dynamic_info[DT_JMPREL] : tpnt->
+                        dynamic_info[DT_REL]);
+               rel_size =
+                       (indx ? tpnt->dynamic_info[DT_PLTRELSZ] : tpnt->
+                        dynamic_info[DT_RELSZ]);
+#endif
+
 
-  /* OK, at this point we have a crude malloc capability.  Start to build
-     the tables of the modules that are required for this beast to run.
-     We start with the basic executable, and then go from there.  Eventually
-     we will run across ourself, and we will need to properly deal with that
-     as well. */
+               if (!rel_addr)
+                       continue;
+
+               /* Now parse the relocation information */
+               rpnt = (ELF_RELOC *) (rel_addr + load_addr);
+               for (i = 0; i < rel_size; i += sizeof(ELF_RELOC), rpnt++) {
+                       reloc_addr = (int *) (load_addr + (int) rpnt->r_offset);
+                       symtab_index = ELF32_R_SYM(rpnt->r_info);
+                       symbol_addr = 0;
+                       if (symtab_index) {
+                               char *strtab;
+                               Elf32_Sym *symtab;
+
+                               symtab = (Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB] +
+                                                                  load_addr);
+                               strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + load_addr);
+
+                               /* We only do a partial dynamic linking right now.  The user
+                                  is not supposed to redefine any symbols that start with
+                                  a '_', so we can do this with confidence. */
+
+                               if (!_dl_symbol(strtab + symtab[symtab_index].st_name))
+                                       continue;
+
+                               symbol_addr = load_addr + symtab[symtab_index].st_value;
+
+                               if (!symbol_addr) {
+                                       /*
+                                        * This will segfault - you cannot call a function until
+                                        * we have finished the relocations.
+                                        */
+                                       SEND_STDERR("ELF dynamic loader - unable to "
+                                               "self-bootstrap - symbol ");
+                                       SEND_STDERR(strtab + symtab[symtab_index].st_name);
+                                       SEND_STDERR(" undefined.\n");
+                                       goof++;
+                               }
+                       }
+                       /*
+                        * Use this machine-specific macro to perform the actual relocation.
+                        */
+                       PERFORM_BOOTSTRAP_RELOC(rpnt, reloc_addr, symbol_addr, load_addr);
+               }
+       }
+
+       if (goof) {
+               _dl_exit(14);
+       }
 
-  _dl_malloc_addr = malloc_buffer;
+       /* OK, at this point we have a crude malloc capability.  Start to build
+          the tables of the modules that are required for this beast to run.
+          We start with the basic executable, and then go from there.  Eventually
+          we will run across ourself, and we will need to properly deal with that
+          as well. */
 
-  _dl_mmap_zero = mmap_zero;
+       _dl_malloc_addr = malloc_buffer;
+
+       _dl_mmap_zero = mmap_zero;
 /*  tpnt = _dl_malloc(sizeof(struct elf_resolve)); */
 
 /* Now we have done the mandatory linking of some things.  We are now
@@ -426,573 +430,594 @@ void _dl_boot(int args){
    fixed up by now.  Still no function calls outside of this library ,
    since the dynamic resolver is not yet ready. */
 
-  lpnt = (int *) (tpnt->dynamic_info[DT_PLTGOT] + load_addr);
-  INIT_GOT(lpnt, tpnt);
-
-  /* OK, this was a big step, now we need to scan all of the user images
-     and load them properly. */
-
-  tpnt->next = 0;
-  tpnt->libname = 0;
-  tpnt->libtype = program_interpreter;
-
-  { struct elfhdr * epnt;
-    struct elf_phdr * ppnt;
-    int i;
-
-    epnt = (struct elfhdr *) dl_data[AT_BASE];
-    tpnt->n_phent = epnt->e_phnum;
-    tpnt->ppnt = ppnt = (struct elf_phdr *) (load_addr + epnt->e_phoff);
-    for(i=0;i < epnt->e_phnum; i++, ppnt++){
-      if(ppnt->p_type == PT_DYNAMIC) {
-       tpnt->dynamic_addr = ppnt->p_vaddr + load_addr;
-       tpnt->dynamic_size = ppnt->p_filesz;
-      }
-    }
-  }
-
-  tpnt->chains = chains;
-  tpnt->loadaddr = (char *) load_addr;
-
-  brk_addr = 0;
-  rpnt = NULL;
-
-  /* At this point we are now free to examine the user application,
-     and figure out which libraries are supposed to be called.  Until
-     we have this list, we will not be completely ready for dynamic linking */
-
-  {
-    struct elf_phdr * ppnt;
-    int i;
-
-    ppnt = (struct elf_phdr *) dl_data[AT_PHDR];
-    for(i=0; i<dl_data[AT_PHNUM]; i++, ppnt++) {
-      if(ppnt->p_type == PT_LOAD) {
-       if(ppnt->p_vaddr + ppnt->p_memsz > brk_addr) 
-         brk_addr = ppnt->p_vaddr + ppnt->p_memsz;
-      }
-      if(ppnt->p_type == PT_DYNAMIC) {
+       lpnt = (int *) (tpnt->dynamic_info[DT_PLTGOT] + load_addr);
+       INIT_GOT(lpnt, tpnt);
+
+       /* OK, this was a big step, now we need to scan all of the user images
+          and load them properly. */
+
+       tpnt->next = 0;
+       tpnt->libname = 0;
+       tpnt->libtype = program_interpreter;
+
+       {
+               elfhdr *epnt;
+               elf_phdr *ppnt;
+               int i;
+
+               epnt = (elfhdr *) dl_data[AT_BASE];
+               tpnt->n_phent = epnt->e_phnum;
+               tpnt->ppnt = ppnt = (elf_phdr *) (load_addr + epnt->e_phoff);
+               for (i = 0; i < epnt->e_phnum; i++, ppnt++) {
+                       if (ppnt->p_type == PT_DYNAMIC) {
+                               tpnt->dynamic_addr = ppnt->p_vaddr + load_addr;
+                               tpnt->dynamic_size = ppnt->p_filesz;
+                       }
+               }
+       }
+
+       tpnt->chains = chains;
+       tpnt->loadaddr = (char *) load_addr;
+
+       brk_addr = 0;
+       rpnt = NULL;
+
+       /* At this point we are now free to examine the user application,
+          and figure out which libraries are supposed to be called.  Until
+          we have this list, we will not be completely ready for dynamic linking */
+
+       {
+               elf_phdr *ppnt;
+               int i;
+
+               ppnt = (elf_phdr *) dl_data[AT_PHDR];
+               for (i = 0; i < dl_data[AT_PHNUM]; i++, ppnt++) {
+                       if (ppnt->p_type == PT_LOAD) {
+                               if (ppnt->p_vaddr + ppnt->p_memsz > brk_addr)
+                                       brk_addr = ppnt->p_vaddr + ppnt->p_memsz;
+                       }
+                       if (ppnt->p_type == PT_DYNAMIC) {
 #ifndef ALLOW_ZERO_PLTGOT
-       /* make sure it's really there. */
-       if (app_tpnt->dynamic_info[DT_PLTGOT] == 0) continue;
+                               /* make sure it's really there. */
+                               if (app_tpnt->dynamic_info[DT_PLTGOT] == 0)
+                                       continue;
 #endif
-       /* OK, we have what we need - slip this one into the list. */
-       app_tpnt = _dl_add_elf_hash_table("", 0, 
-                           app_tpnt->dynamic_info, ppnt->p_vaddr, ppnt->p_filesz);
-       _dl_loaded_modules->libtype = elf_executable;
-       _dl_loaded_modules->ppnt = (struct elf_phdr *) dl_data[AT_PHDR];
-       _dl_loaded_modules->n_phent = dl_data[AT_PHNUM];
-       _dl_symbol_tables = rpnt = 
-          (struct dyn_elf *) _dl_malloc(sizeof(struct dyn_elf));
-       _dl_memset (rpnt, 0, sizeof (*rpnt));
-       rpnt->dyn = _dl_loaded_modules;
-       app_tpnt->usage_count++;
-       app_tpnt->symbol_scope = _dl_symbol_tables;
-       lpnt = (int *) (app_tpnt->dynamic_info[DT_PLTGOT]);
+                               /* OK, we have what we need - slip this one into the list. */
+                               app_tpnt = _dl_add_elf_hash_table("", 0, 
+                                       app_tpnt->dynamic_info, ppnt->p_vaddr, ppnt->p_filesz);
+                               _dl_loaded_modules->libtype = elf_executable;
+                               _dl_loaded_modules->ppnt = (elf_phdr *) dl_data[AT_PHDR];
+                               _dl_loaded_modules->n_phent = dl_data[AT_PHNUM];
+                               _dl_symbol_tables = rpnt =
+                                       (struct dyn_elf *) _dl_malloc(sizeof(struct dyn_elf));
+                               _dl_memset(rpnt, 0, sizeof(*rpnt));
+                               rpnt->dyn = _dl_loaded_modules;
+                               app_tpnt->usage_count++;
+                               app_tpnt->symbol_scope = _dl_symbol_tables;
+                               lpnt = (int *) (app_tpnt->dynamic_info[DT_PLTGOT]);
 #ifdef ALLOW_ZERO_PLTGOT
-       if (lpnt)
+                               if (lpnt)
 #endif
-         INIT_GOT(lpnt, _dl_loaded_modules);
-      }
-      if(ppnt->p_type == PT_INTERP) { /* OK, fill this in - we did not have
-                                        this before */
-       tpnt->libname =  _dl_strdup((char *) ppnt->p_offset +(dl_data[AT_PHDR] & 0xfffff000));
-      }
-    }
-  }
-
-  if (argv[0])
-    _dl_progname = argv[0];
-
-  /* Now we need to figure out what kind of options are selected.
-   Note that for SUID programs we ignore the settings in LD_LIBRARY_PATH */
-  {
-    _dl_not_lazy = _dl_getenv("LD_BIND_NOW",envp);
-
-    if ( (dl_data[AT_UID] == -1 && _dl_suid_ok()) ||
-        (dl_data[AT_UID] != -1 && dl_data[AT_UID] == dl_data[AT_EUID] &&
-         dl_data[AT_GID] == dl_data[AT_EGID]))
-    {
-      _dl_secure = 0;
-      _dl_preload = _dl_getenv("LD_PRELOAD", envp);
-      _dl_library_path = _dl_getenv("LD_LIBRARY_PATH",envp);
-    }
-    else
-    {
-      _dl_secure = 1;
-      _dl_preload = _dl_getenv("LD_PRELOAD", envp);
-      _dl_unsetenv("LD_AOUT_PRELOAD", envp);
-      _dl_unsetenv("LD_LIBRARY_PATH", envp);
-      _dl_unsetenv("LD_AOUT_LIBRARY_PATH", envp);
-      _dl_library_path = NULL;
-    }
-  }
-
-  _dl_trace_loaded_objects = _dl_getenv("LD_TRACE_LOADED_OBJECTS", envp);
-
-  /* OK, we now have the application in the list, and we have some
-     basic stuff in place.  Now search through the list for other shared
-     libraries that should be loaded, and insert them on the list in the
-     correct order. */
+                                       INIT_GOT(lpnt, _dl_loaded_modules);
+                       }
+                       if (ppnt->p_type == PT_INTERP) {        /* OK, fill this in - we did not 
+                                                                  have this before */
+                               tpnt->libname = _dl_strdup((char *) ppnt->p_offset +
+                                                          (dl_data[AT_PHDR] & 0xfffff000));
+                       }
+               }
+       }
+
+       if (argv[0]) {
+               _dl_progname = argv[0];
+       }
+
+       /* Now we need to figure out what kind of options are selected.
+          Note that for SUID programs we ignore the settings in LD_LIBRARY_PATH */
+       {
+               _dl_not_lazy = _dl_getenv("LD_BIND_NOW", envp);
+
+               if ((dl_data[AT_UID] == -1 && _dl_suid_ok()) ||
+                       (dl_data[AT_UID] != -1 && dl_data[AT_UID] == dl_data[AT_EUID]
+                        && dl_data[AT_GID] == dl_data[AT_EGID])) {
+                       _dl_secure = 0;
+                       _dl_preload = _dl_getenv("LD_PRELOAD", envp);
+                       _dl_library_path = _dl_getenv("LD_LIBRARY_PATH", envp);
+               } else {
+                       _dl_secure = 1;
+                       _dl_preload = _dl_getenv("LD_PRELOAD", envp);
+                       _dl_unsetenv("LD_AOUT_PRELOAD", envp);
+                       _dl_unsetenv("LD_LIBRARY_PATH", envp);
+                       _dl_unsetenv("LD_AOUT_LIBRARY_PATH", envp);
+                       _dl_library_path = NULL;
+               }
+       }
+
+       _dl_trace_loaded_objects = _dl_getenv("LD_TRACE_LOADED_OBJECTS", envp);
+
+       /* OK, we now have the application in the list, and we have some
+          basic stuff in place.  Now search through the list for other shared
+          libraries that should be loaded, and insert them on the list in the
+          correct order. */
+
+#ifdef USE_CACHE
+       _dl_map_cache();
+#endif
+
+       {
+               struct elf_resolve *tcurr;
+               struct elf_resolve *tpnt1;
+               char *lpnt;
+
+               if (_dl_preload) 
+               {
+                       char c, *str, *str2;
+
+                       str = _dl_preload;
+                       while (*str == ':' || *str == ' ' || *str == '\t')
+                               str++;
+                       while (*str) 
+                       {
+                               str2 = str;
+                               while (*str2 && *str2 != ':' && *str2 != ' ' && *str2 != '\t')
+                                       str2++;
+                               c = *str2;
+                               *str2 = '\0';
+                               if (!_dl_secure || _dl_strchr(str, '/') == NULL) 
+                               {
+                                       tpnt1 = _dl_load_shared_library(_dl_secure, NULL, str);
+                                       if (!tpnt1) {
+                                               if (_dl_trace_loaded_objects)
+                                                       _dl_fdprintf(1, "\t%s => not found\n", str);
+                                               else {
+                                                       _dl_fdprintf(2, "%s: can't load "
+                                                               "library '%s'\n", _dl_progname, str);
+                                                       _dl_exit(15);
+                                               }
+                                       } else {
+                                               if (_dl_trace_loaded_objects
+                                                       && !tpnt1->usage_count) {
+                                                       /* this is a real hack to make ldd not print 
+                                                        * the library itself when run on a library. */
+                                                       if (_dl_strcmp(_dl_progname, str) != 0)
+                                                               _dl_fdprintf(1, "\t%s => %s (0x%x)\n", 
+                                                                       str, tpnt1->libname, 
+                                                                       (unsigned) tpnt1->loadaddr);
+                                               }
+                                               rpnt->next = (struct dyn_elf *)
+                                                       _dl_malloc(sizeof(struct dyn_elf));
+                                               _dl_memset(rpnt->next, 0, sizeof(*(rpnt->next)));
+                                               rpnt = rpnt->next;
+                                               tpnt1->usage_count++;
+                                               tpnt1->symbol_scope = _dl_symbol_tables;
+                                               tpnt1->libtype = elf_lib;
+                                               rpnt->dyn = tpnt1;
+                                       }
+                               }
+                               *str2 = c;
+                               str = str2;
+                               while (*str == ':' || *str == ' ' || *str == '\t')
+                                       str++;
+                       }
+               }
+
+               {
+                       int fd;
+                       struct kernel_stat st;
+                       char *preload;
+
+                       if (!_dl_stat(LDSO_PRELOAD, &st)) {
+                               if ((fd = _dl_open(LDSO_PRELOAD, O_RDONLY)) < 0) {
+                                       _dl_fdprintf(2, "%s: can't open file '%s'\n", 
+                                               _dl_progname, LDSO_PRELOAD);
+                               } else {
+                                       preload = (caddr_t) _dl_mmap(0, st.st_size + 1, 
+                                               PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
+                                       _dl_close(fd);
+                                       if (preload == (caddr_t) - 1) {
+                                               _dl_fdprintf(2, "%s: can't map file '%s'\n", 
+                                                       _dl_progname, LDSO_PRELOAD);
+                                       } else {
+                                               char c, *cp, *cp2;
+
+                                               /* convert all separators and comments to spaces */
+                                               for (cp = preload; *cp; /*nada */ ) {
+                                                       if (*cp == ':' || *cp == '\t' || *cp == '\n') {
+                                                               *cp++ = ' ';
+                                                       } else if (*cp == '#') {
+                                                               do
+                                                                       *cp++ = ' ';
+                                                               while (*cp != '\n' && *cp != '\0');
+                                                       } else {
+                                                               cp++;
+                                                       }
+                                               }
+
+                                               /* find start of first library */
+                                               for (cp = preload; *cp && *cp == ' '; cp++)
+                                                       /*nada */ ;
+
+                                               while (*cp) {
+                                                       /* find end of library */
+                                                       for (cp2 = cp; *cp && *cp != ' '; cp++)
+                                                               /*nada */ ;
+                                                       c = *cp;
+                                                       *cp = '\0';
+
+                                                       tpnt1 = _dl_load_shared_library(0, NULL, cp2);
+                                                       if (!tpnt1) {
+                                                               if (_dl_trace_loaded_objects)
+                                                                       _dl_fdprintf(1, "\t%s => not "
+                                                                               "found\n", cp2);
+                                                               else {
+                                                                       _dl_fdprintf(2, "%s: can't "
+                                                                               "load library '%s'\n", 
+                                                                               _dl_progname, cp2);
+                                                                       _dl_exit(15);
+                                                               }
+                                                       } else {
+                                                               if (_dl_trace_loaded_objects
+                                                                       && !tpnt1->usage_count) {
+                                                                       _dl_fdprintf(1, "\t%s => %s "
+                                                                               "(0x%x)\n", cp2, 
+                                                                               tpnt1->libname, 
+                                                                               (unsigned) tpnt1->loadaddr);
+                                                               }
+                                                               rpnt->next = (struct dyn_elf *)
+                                                                       _dl_malloc(sizeof(struct dyn_elf));
+                                                               _dl_memset(rpnt->next, 0, 
+                                                                       sizeof(*(rpnt->next)));
+                                                               rpnt = rpnt->next;
+                                                               tpnt1->usage_count++;
+                                                               tpnt1->symbol_scope = _dl_symbol_tables;
+                                                               tpnt1->libtype = elf_lib;
+                                                               rpnt->dyn = tpnt1;
+                                                       }
+
+                                                       /* find start of next library */
+                                                       *cp = c;
+                                                       for ( /*nada */ ; *cp && *cp == ' '; cp++)
+                                                               /*nada */ ;
+                                               }
+
+                                               _dl_munmap(preload, st.st_size + 1);
+                                       }
+                               }
+                       }
+               }
+
+               for (tcurr = _dl_loaded_modules; tcurr; tcurr = tcurr->next) {
+                       for (dpnt = (Elf32_Dyn *) tcurr->dynamic_addr; dpnt->d_tag;
+                                dpnt++) {
+                               if (dpnt->d_tag == DT_NEEDED) {
+                                       lpnt = tcurr->loadaddr + tcurr->dynamic_info[DT_STRTAB] +
+                                               dpnt->d_un.d_val;
+                                       if (tpnt && _dl_strcmp(lpnt, tpnt->libname) == 0) {
+                                               struct elf_resolve *ttmp;
+
+                                               ttmp = _dl_loaded_modules;
+                                               while (ttmp->next)
+                                                       ttmp = ttmp->next;
+                                               ttmp->next = tpnt;
+                                               tpnt->prev = ttmp;
+                                               tpnt->next = NULL;
+                                               rpnt->next = (struct dyn_elf *)
+                                                       _dl_malloc(sizeof(struct dyn_elf));
+                                               _dl_memset(rpnt->next, 0, sizeof(*(rpnt->next)));
+                                               rpnt = rpnt->next;
+                                               rpnt->dyn = tpnt;
+                                               tpnt->usage_count++;
+                                               tpnt->symbol_scope = _dl_symbol_tables;
+                                               tpnt = NULL;
+                                               continue;
+                                       }
+                                       if (!(tpnt1 = _dl_load_shared_library(0, tcurr, lpnt))) {
+                                               if (_dl_trace_loaded_objects)
+                                                       _dl_fdprintf(1, "\t%s => not found\n", lpnt);
+                                               else {
+                                                       _dl_fdprintf(2, "%s: can't load library '%s'\n", 
+                                                               _dl_progname, lpnt);
+                                                       _dl_exit(16);
+                                               }
+                                       } else {
+                                               if (_dl_trace_loaded_objects
+                                                       && !tpnt1->usage_count)
+                                                       _dl_fdprintf(1, "\t%s => %s (0x%x)\n", lpnt, 
+                                                               tpnt1->libname, (unsigned) tpnt1->loadaddr);
+                                               rpnt->next = (struct dyn_elf *)
+                                                       _dl_malloc(sizeof(struct dyn_elf));
+                                               _dl_memset(rpnt->next, 0, sizeof(*(rpnt->next)));
+                                               rpnt = rpnt->next;
+                                               tpnt1->usage_count++;
+                                               tpnt1->symbol_scope = _dl_symbol_tables;
+                                               tpnt1->libtype = elf_lib;
+                                               rpnt->dyn = tpnt1;
+                                       }
+                               }
+                       }
+               }
+       }
 
 #ifdef USE_CACHE
-  _dl_map_cache();
+       _dl_unmap_cache();
 #endif
 
-  {
-    struct elf_resolve *tcurr;
-    struct elf_resolve *tpnt1;
-    char *lpnt;
-
-    if (_dl_preload) {
-      char c, *str, *str2;
-
-      str = _dl_preload;
-      while (*str == ':' || *str == ' ' || *str == '\t')
-       str++;
-      while (*str) {
-       str2 = str;
-       while (*str2 && *str2 != ':' && *str2 != ' ' && *str2 != '\t')
-         str2++;
-       c = *str2;
-       *str2 = '\0';
-       if (!_dl_secure || _dl_strchr(str, '/') == NULL) {
-         tpnt1 = _dl_load_shared_library(_dl_secure, NULL, str);
-         if (!tpnt1) {
-           if (_dl_trace_loaded_objects)
-             _dl_fdprintf(1, "\t%s => not found\n", str);
-           else {
-             _dl_fdprintf(2, "%s: can't load library '%s'\n",
-                          _dl_progname, str);
-             _dl_exit(15);
-           }
-         } else {
-           if (_dl_trace_loaded_objects && !tpnt1->usage_count) {
-             /* this is a real hack to make ldd not print the
-                library itself when run on a library. */
-             if (_dl_strcmp(_dl_progname, str) != 0)
-               _dl_fdprintf(1, "\t%s => %s (0x%x)\n", str, tpnt1->libname,
-                            (unsigned)tpnt1->loadaddr);
-           }
-           rpnt->next = 
-             (struct dyn_elf *) _dl_malloc(sizeof(struct dyn_elf));
-           _dl_memset (rpnt->next, 0, sizeof (*(rpnt->next)));
-           rpnt = rpnt->next;
-           tpnt1->usage_count++;
-           tpnt1->symbol_scope = _dl_symbol_tables;
-           tpnt1->libtype = elf_lib;
-           rpnt->dyn = tpnt1;
-         }
+       /* ldd uses uses this.  I am not sure how you pick up the other flags */
+       if (_dl_trace_loaded_objects) {
+               _dl_warn = _dl_getenv("LD_WARN", envp);
+               if (!_dl_warn)
+                       _dl_exit(0);
        }
-       *str2 = c;
-       str = str2;
-       while (*str == ':' || *str == ' ' || *str == '\t')
-         str++;
-      }
-    }
-
-    {
-      int fd;
-      struct kernel_stat st;
-      char *preload;
-
-      if (!_dl_stat(LDSO_PRELOAD, &st)) {
-       if ((fd = _dl_open(LDSO_PRELOAD, O_RDONLY)) < 0) {
-         _dl_fdprintf(2, "%s: can't open file '%s'\n", _dl_progname, 
-                      LDSO_PRELOAD);
-       } else {
-         preload = (caddr_t)_dl_mmap(0, st.st_size+1, PROT_READ|PROT_WRITE, 
-                                     MAP_PRIVATE, fd, 0);
-         _dl_close (fd);
-         if (preload == (caddr_t)-1) {
-           _dl_fdprintf(2, "%s: can't map file '%s'\n", _dl_progname, 
-                        LDSO_PRELOAD);
-         } else {
-           char c, *cp, *cp2;
-
-           /* convert all separators and comments to spaces */
-           for (cp = preload; *cp; /*nada*/) {
-             if (*cp == ':' || *cp == '\t' || *cp == '\n') {
-               *cp++ = ' ';
-             } else if (*cp == '#') {
-               do
-                 *cp++ = ' ';
-               while (*cp != '\n' && *cp != '\0');
-             } else {
-               cp++;
-             }
-           }
-
-           /* find start of first library */
-           for (cp = preload; *cp && *cp == ' '; cp++)
-             /*nada*/;
-
-           while (*cp) {
-             /* find end of library */
-             for (cp2 = cp; *cp && *cp != ' '; cp++)
-               /*nada*/;
-             c = *cp;
-             *cp = '\0';
-
-             tpnt1 = _dl_load_shared_library(0, NULL, cp2);
-             if (!tpnt1) {
-               if (_dl_trace_loaded_objects)
-                 _dl_fdprintf(1, "\t%s => not found\n", cp2);
-               else {
-                 _dl_fdprintf(2, "%s: can't load library '%s'\n",
-                              _dl_progname, cp2);
-                 _dl_exit(15);
+
+       /*
+        * If the program interpreter is not in the module chain, add it.  This will
+        * be required for dlopen to be able to access the internal functions in the 
+        * dynamic linker.
+        */
+       if (tpnt) {
+               struct elf_resolve *tcurr;
+
+               tcurr = _dl_loaded_modules;
+               if (tcurr)
+                       while (tcurr->next)
+                               tcurr = tcurr->next;
+               tpnt->next = NULL;
+               tpnt->usage_count++;
+
+               if (tcurr) {
+                       tcurr->next = tpnt;
+                       tpnt->prev = tcurr;
+               } else {
+                       _dl_loaded_modules = tpnt;
+                       tpnt->prev = NULL;
                }
-             } else {
-               if (_dl_trace_loaded_objects && !tpnt1->usage_count)
-                 _dl_fdprintf(1, "\t%s => %s (0x%x)\n", cp2, tpnt1->libname,
-                              (unsigned)tpnt1->loadaddr);
-                rpnt->next = 
-                 (struct dyn_elf *) _dl_malloc(sizeof(struct dyn_elf));
-               _dl_memset (rpnt->next, 0, sizeof (*(rpnt->next)));
-               rpnt = rpnt->next;
-               tpnt1->usage_count++;
-               tpnt1->symbol_scope = _dl_symbol_tables;
-               tpnt1->libtype = elf_lib;
-               rpnt->dyn = tpnt1;
-             }
-
-             /* find start of next library */
-             *cp = c;
-             for (/*nada*/; *cp && *cp == ' '; cp++)
-               /*nada*/;
-           }
-
-           _dl_munmap(preload, st.st_size+1);
-         }
+               if (rpnt) {
+                       rpnt->next = (struct dyn_elf *) _dl_malloc(sizeof(struct dyn_elf));
+                       _dl_memset(rpnt->next, 0, sizeof(*(rpnt->next)));
+                       rpnt = rpnt->next;
+               } else {
+                       rpnt = (struct dyn_elf *) _dl_malloc(sizeof(struct dyn_elf));
+                       _dl_memset(rpnt, 0, sizeof(*(rpnt->next)));
+               }
+               rpnt->dyn = tpnt;
+               tpnt = NULL;
        }
-      }
-    }
-
-    for (tcurr = _dl_loaded_modules; tcurr; tcurr = tcurr->next)
-    {
-      for (dpnt = (struct dynamic *)tcurr->dynamic_addr; dpnt->d_tag; dpnt++)
-      {
-       if(dpnt->d_tag == DT_NEEDED)
+
+       /*
+        * OK, now all of the kids are tucked into bed in their proper addresses.
+        * Now we go through and look for REL and RELA records that indicate fixups
+        * to the GOT tables.  We need to do this in reverse order so that COPY
+        * directives work correctly */
+
+
+       goof = _dl_loaded_modules ? _dl_fixup(_dl_loaded_modules) : 0;
+
+
+       /* Some flavors of SVr4 do not generate the R_*_COPY directive,
+          and we have to manually search for entries that require fixups. 
+          Solaris gets this one right, from what I understand.  */
+
+
+       if (_dl_symbol_tables)
+               goof += _dl_copy_fixups(_dl_symbol_tables);
+
+       if (goof || _dl_trace_loaded_objects)
+               _dl_exit(0);
+
+       /* OK, at this point things are pretty much ready to run.  Now we
+          need to touch up a few items that are required, and then
+          we can let the user application have at it.  Note that
+          the dynamic linker itself is not guaranteed to be fully
+          dynamicly linked if we are using ld.so.1, so we have to look
+          up each symbol individually. */
+
+
+       _dl_brkp = (unsigned int *) _dl_find_hash("___brk_addr", NULL, 1, NULL, 0);
+       if (_dl_brkp)
+               *_dl_brkp = brk_addr;
+       _dl_envp =
+               (unsigned int *) _dl_find_hash("__environ", NULL, 1, NULL, 0);
+
+       if (_dl_envp)
+               *_dl_envp = (unsigned int) envp;
+
        {
-         lpnt = tcurr->loadaddr + tcurr->dynamic_info[DT_STRTAB] + 
-           dpnt->d_un.d_val;
-         if (tpnt && _dl_strcmp(lpnt, tpnt->libname) == 0)
-         {
-           struct elf_resolve * ttmp;
-           ttmp = _dl_loaded_modules;
-           while (ttmp->next) 
-             ttmp = ttmp->next;
-           ttmp->next = tpnt;
-           tpnt->prev = ttmp;
-           tpnt->next = NULL;
-           rpnt->next = 
-             (struct dyn_elf *) _dl_malloc(sizeof(struct dyn_elf));
-           _dl_memset (rpnt->next, 0, sizeof (*(rpnt->next)));
-           rpnt = rpnt->next;
-           rpnt->dyn = tpnt;
-           tpnt->usage_count++;
-           tpnt->symbol_scope = _dl_symbol_tables;
-           tpnt = NULL;
-           continue;
-         }
-         if (!(tpnt1 = _dl_load_shared_library(0, tcurr, lpnt)))
-         {
-           if (_dl_trace_loaded_objects)
-             _dl_fdprintf(1, "\t%s => not found\n", lpnt);
-           else
-           {
-             _dl_fdprintf(2, "%s: can't load library '%s'\n",
-                          _dl_progname, lpnt);
-             _dl_exit(16);
-           }
-         }
-         else
-         {
-           if (_dl_trace_loaded_objects && !tpnt1->usage_count)
-             _dl_fdprintf(1, "\t%s => %s (0x%x)\n", lpnt, tpnt1->libname,
-                          (unsigned)tpnt1->loadaddr);
-           rpnt->next = 
-             (struct dyn_elf *) _dl_malloc(sizeof(struct dyn_elf));
-           _dl_memset (rpnt->next, 0, sizeof (*(rpnt->next)));
-           rpnt = rpnt->next;
-           tpnt1->usage_count++;
-           tpnt1->symbol_scope = _dl_symbol_tables;
-           tpnt1->libtype = elf_lib;
-           rpnt->dyn = tpnt1;
-         }
+               int i;
+               elf_phdr *ppnt;
+
+               /* We had to set the protections of all pages to R/W for dynamic linking.
+                  Set text pages back to R/O */
+               for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next)
+                       for (ppnt = tpnt->ppnt, i = 0; i < tpnt->n_phent; i++, ppnt++)
+                               if (ppnt->p_type == PT_LOAD && !(ppnt->p_flags & PF_W) &&
+                                       tpnt->dynamic_info[DT_TEXTREL])
+                                       _dl_mprotect((void *) (tpnt->loadaddr + 
+                                                   (ppnt->p_vaddr & 0xfffff000)), 
+                                               (ppnt->p_vaddr & 0xfff) + 
+                                               (unsigned int) ppnt->p_filesz, 
+                                               LXFLAGS(ppnt->p_flags));
+
        }
-      }
-    }
-  }
 
-#ifdef USE_CACHE
-  _dl_unmap_cache();
-#endif
+       _dl_atexit = (int (*)(void *)) _dl_find_hash("atexit", NULL, 1, NULL, 0);
 
-    /* ldd uses uses this.  I am not sure how you pick up the other flags */ 
-  if(_dl_trace_loaded_objects)
-    {
-      _dl_warn = _dl_getenv("LD_WARN", envp);
-      if (!_dl_warn) _dl_exit(0);
-    }
-
-  /*
-   * If the program interpreter is not in the module chain, add it.  This will
-   * be required for dlopen to be able to access the internal functions in the 
-   * dynamic linker.
-   */
-  if(tpnt) {
-    struct elf_resolve * tcurr;
-
-    tcurr = _dl_loaded_modules;
-    if (tcurr)
-      while(tcurr->next) tcurr = tcurr->next;
-    tpnt->next = NULL;
-    tpnt->usage_count++;
-
-    if (tcurr) {
-      tcurr->next = tpnt;
-      tpnt->prev = tcurr;
-    }
-    else {
-      _dl_loaded_modules = tpnt;
-      tpnt->prev = NULL;
-    }
-    if (rpnt) {
-      rpnt->next = 
-       (struct dyn_elf *) _dl_malloc(sizeof(struct dyn_elf));
-      _dl_memset (rpnt->next, 0, sizeof (*(rpnt->next)));
-      rpnt = rpnt->next;
-    } else {
-      rpnt =   (struct dyn_elf *) _dl_malloc(sizeof(struct dyn_elf));
-      _dl_memset (rpnt, 0, sizeof (*(rpnt->next)));
-    }
-    rpnt->dyn = tpnt;
-    tpnt = NULL;
-  }
-
-  /*
-   * OK, now all of the kids are tucked into bed in their proper addresses.
-   * Now we go through and look for REL and RELA records that indicate fixups
-   * to the GOT tables.  We need to do this in reverse order so that COPY
-   * directives work correctly */
-
-
-  goof = _dl_loaded_modules ? _dl_fixup(_dl_loaded_modules) : 0;
-
-
-  /* Some flavors of SVr4 do not generate the R_*_COPY directive,
-   and we have to manually search for entries that require fixups. 
-   Solaris gets this one right, from what I understand.  */
-
-
-  if (_dl_symbol_tables)
-    goof += _dl_copy_fixups(_dl_symbol_tables);
-
-  if(goof || _dl_trace_loaded_objects) _dl_exit(0);
-
-  /* OK, at this point things are pretty much ready to run.  Now we
-     need to touch up a few items that are required, and then
-     we can let the user application have at it.  Note that
-     the dynamic linker itself is not guaranteed to be fully
-     dynamicly linked if we are using ld.so.1, so we have to look
-     up each symbol individually. */
-
-
-  _dl_brkp = (unsigned int *) _dl_find_hash("___brk_addr", NULL, 1, NULL, 0);
-  if (_dl_brkp) *_dl_brkp = brk_addr;
-  _dl_envp = (unsigned int *) _dl_find_hash("__environ", NULL, 1, NULL, 0);
-
-  if (_dl_envp) *_dl_envp = (unsigned int) envp;
-
-  {
-    int i;
-    struct elf_phdr * ppnt;
-
-  /* We had to set the protections of all pages to R/W for dynamic linking.
-     Set text pages back to R/O */
-  for(tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next)
-    for(ppnt = tpnt->ppnt, i=0; i < tpnt->n_phent; i++, ppnt++)
-      if(ppnt->p_type == PT_LOAD && !(ppnt->p_flags & PF_W) &&
-        tpnt->dynamic_info[DT_TEXTREL])
-       _dl_mprotect((void *) (tpnt->loadaddr + (ppnt->p_vaddr & 0xfffff000)),
-                    (ppnt->p_vaddr & 0xfff) + (unsigned int) ppnt->p_filesz,
-                    LXFLAGS(ppnt->p_flags));
-
-  }
-
-  _dl_atexit = (int (*)(void *)) _dl_find_hash("atexit", NULL, 1, NULL, 0);
-
-  /*
-   * OK, fix one more thing - set up the debug_addr structure to point
-   * to our chain.  Later we may need to fill in more fields, but this
-   * should be enough for now.
-   */
-  debug_addr->r_map = (struct link_map *) _dl_loaded_modules;
-  debug_addr->r_version = 1;
-  debug_addr->r_ldbase = load_addr;
-  debug_addr->r_brk = (unsigned long) &_dl_debug_state;
-  _dl_debug_addr = debug_addr;
-  debug_addr->r_state = RT_CONSISTENT;
-  /* This is written in this funny way to keep gcc from inlining the
-     function call. */
-  ((void (*)(void))debug_addr->r_brk)();
-
-  for(tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next)
-    {
-      /* Apparently crt1 for the application is responsible for handling this.
-       * We only need to run the init/fini for shared libraries
-       */
-      if (tpnt->libtype == program_interpreter ||
-       tpnt->libtype == elf_executable) continue;
-      if (tpnt->init_flag & INIT_FUNCS_CALLED) continue;
-      tpnt->init_flag |= INIT_FUNCS_CALLED;
-      
-      if(tpnt->dynamic_info[DT_INIT]) {
-       _dl_elf_init = (int (*)(void)) (tpnt->loadaddr + 
-                                   tpnt->dynamic_info[DT_INIT]);
-       (*_dl_elf_init)();
-      }
-      if(_dl_atexit && tpnt->dynamic_info[DT_FINI])
-      {
-        (*_dl_atexit)(tpnt->loadaddr + tpnt->dynamic_info[DT_FINI]);
-      }
+       /*
+        * OK, fix one more thing - set up the debug_addr structure to point
+        * to our chain.  Later we may need to fill in more fields, but this
+        * should be enough for now.
+        */
+       debug_addr->r_map = (struct link_map *) _dl_loaded_modules;
+       debug_addr->r_version = 1;
+       debug_addr->r_ldbase = load_addr;
+       debug_addr->r_brk = (unsigned long) &_dl_debug_state;
+       _dl_debug_addr = debug_addr;
+       debug_addr->r_state = RT_CONSISTENT;
+       /* This is written in this funny way to keep gcc from inlining the
+          function call. */
+       ((void (*)(void)) debug_addr->r_brk) ();
+
+       for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) {
+               /* Apparently crt1 for the application is responsible for handling this.
+                * We only need to run the init/fini for shared libraries
+                */
+               if (tpnt->libtype == program_interpreter ||
+                       tpnt->libtype == elf_executable)
+                       continue;
+               if (tpnt->init_flag & INIT_FUNCS_CALLED)
+                       continue;
+               tpnt->init_flag |= INIT_FUNCS_CALLED;
+
+               if (tpnt->dynamic_info[DT_INIT]) {
+                       _dl_elf_init = (int (*)(void)) (tpnt->loadaddr + 
+                               tpnt->dynamic_info[DT_INIT]);
+                       (*_dl_elf_init) ();
+               }
+               if (_dl_atexit && tpnt->dynamic_info[DT_FINI]) {
+                       (*_dl_atexit) (tpnt->loadaddr + tpnt->dynamic_info[DT_FINI]);
+               }
 #undef DL_DEBUG
 #ifdef DL_DEBUG
-      else
-      {
-       _dl_fdprintf(2, tpnt->libname);
-       _dl_fdprintf(2, ": ");
-       if (!_dl_atexit)
-         _dl_fdprintf(2, "The address is atexit () is 0x0.");
-       if (!tpnt->dynamic_info[DT_FINI])
-         _dl_fdprintf(2, "Invalid .fini section.");
-       _dl_fdprintf(2, "\n");
-      }
+               else {
+                       _dl_fdprintf(2, tpnt->libname);
+                       _dl_fdprintf(2, ": ");
+                       if (!_dl_atexit)
+                               _dl_fdprintf(2, "The address is atexit () is 0x0.");
+                       if (!tpnt->dynamic_info[DT_FINI])
+                               _dl_fdprintf(2, "Invalid .fini section.");
+                       _dl_fdprintf(2, "\n");
+               }
 #endif
 #undef DL_DEBUG
-   }
+       }
 
-  /* OK we are done here.  Turn out the lights, and lock up. */
-  _dl_elf_main = (int (*)(int, char**, char**)) dl_data[AT_ENTRY];
+       /* OK we are done here.  Turn out the lights, and lock up. */
+       _dl_elf_main = (int (*)(int, char **, char **)) dl_data[AT_ENTRY];
 
 
-  /*
-   * Transfer control to the application.
-   */
-  START();
+       /*
+        * Transfer control to the application.
+        */
+       START();
 }
 
-int _dl_fixup(struct elf_resolve * tpnt)
+int _dl_fixup(struct elf_resolve *tpnt)
 {
-  int goof = 0;
-  if(tpnt->next) goof += _dl_fixup(tpnt->next);
+       int goof = 0;
+
+       if (tpnt->next)
+               goof += _dl_fixup(tpnt->next);
 
-  if(tpnt->dynamic_info[DT_REL]) {
+       if (tpnt->dynamic_info[DT_REL]) {
 #ifdef ELF_USES_RELOCA
-    _dl_fdprintf(2, "%s: can't handle REL relocation records\n", _dl_progname);
-    _dl_exit(17);
+               _dl_fdprintf(2, "%s: can't handle REL relocation records\n", 
+                       _dl_progname);
+               _dl_exit(17);
 #else
-    if (tpnt->init_flag & RELOCS_DONE) return goof;
-    tpnt->init_flag |= RELOCS_DONE;
-   
-    goof += _dl_parse_relocation_information(tpnt, tpnt->dynamic_info[DT_REL],
-                                            tpnt->dynamic_info[DT_RELSZ], 0);
+               if (tpnt->init_flag & RELOCS_DONE)
+                       return goof;
+               tpnt->init_flag |= RELOCS_DONE;
+
+               goof += _dl_parse_relocation_information(tpnt, 
+                       tpnt->dynamic_info[DT_REL], tpnt->dynamic_info[DT_RELSZ], 0);
 #endif
-  }
-  if(tpnt->dynamic_info[DT_RELA]) {
+       }
+       if (tpnt->dynamic_info[DT_RELA]) {
 #ifdef ELF_USES_RELOCA
-    if (tpnt->init_flag & RELOCS_DONE) return goof;
-    tpnt->init_flag |= RELOCS_DONE;
-   
-    goof += _dl_parse_relocation_information(tpnt, tpnt->dynamic_info[DT_RELA],
-                                            tpnt->dynamic_info[DT_RELASZ], 0);
+               if (tpnt->init_flag & RELOCS_DONE)
+                       return goof;
+               tpnt->init_flag |= RELOCS_DONE;
+
+               goof += _dl_parse_relocation_information(tpnt, 
+                       tpnt->dynamic_info[DT_RELA], tpnt->dynamic_info[DT_RELASZ], 0);
 #else
-    _dl_fdprintf(2, "%s: can't handle RELA relocation records\n", _dl_progname);
-    _dl_exit(18);
+               _dl_fdprintf(2, "%s: can't handle RELA relocation records\n", 
+                       _dl_progname);
+               _dl_exit(18);
 #endif
-  }
-  if(tpnt->dynamic_info[DT_JMPREL])
-    {
-      if (tpnt->init_flag & JMP_RELOCS_DONE) return goof;
-      tpnt->init_flag |= JMP_RELOCS_DONE;
-      
-      if(! _dl_not_lazy || *_dl_not_lazy == 0)
-       _dl_parse_lazy_relocation_information(tpnt, tpnt->dynamic_info[DT_JMPREL],
-                                             tpnt->dynamic_info[DT_PLTRELSZ], 0);
-      else
-       goof +=  _dl_parse_relocation_information(tpnt,
-                                                 tpnt->dynamic_info[DT_JMPREL],
-                                                 tpnt->dynamic_info[DT_PLTRELSZ], 0);
-    }
-  return goof;
+       }
+       if (tpnt->dynamic_info[DT_JMPREL]) {
+               if (tpnt->init_flag & JMP_RELOCS_DONE)
+                       return goof;
+               tpnt->init_flag |= JMP_RELOCS_DONE;
+
+               if (!_dl_not_lazy || *_dl_not_lazy == 0)
+                       _dl_parse_lazy_relocation_information(tpnt, 
+                               tpnt->dynamic_info[DT_JMPREL], tpnt->dynamic_info[DT_PLTRELSZ], 0);
+               else
+                       goof += _dl_parse_relocation_information(tpnt, 
+                               tpnt->dynamic_info[DT_JMPREL], tpnt->dynamic_info[DT_PLTRELSZ], 0);
+       }
+       return goof;
 }
 
-void * _dl_malloc(int size) {
-  void * retval;
-
-  if(_dl_malloc_function)
-       return (*_dl_malloc_function)(size);
-
-  if(_dl_malloc_addr-_dl_mmap_zero+size>4096) {
-       _dl_mmap_zero = _dl_malloc_addr = (unsigned char *) _dl_mmap((void*) 0, size,
-                               PROT_READ | PROT_WRITE, 
-                               MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
-       if(_dl_mmap_check_error(_dl_mmap_zero)) {
-           _dl_fdprintf(2, "%s: can't map '/dev/zero'\n", _dl_progname);
-           _dl_exit(20);
-       }
-  }
-  retval = _dl_malloc_addr;
-  _dl_malloc_addr += size;
-
-  /*
-   * Align memory to 4 byte boundary.  Some platforms require this, others
-   * simply get better performance.
-   */
-  _dl_malloc_addr = (char *) (((unsigned int) _dl_malloc_addr + 3) & ~(3));
-  return retval;
+void *_dl_malloc(int size)
+{
+       void *retval;
+
+       if (_dl_malloc_function)
+               return (*_dl_malloc_function) (size);
+
+       if (_dl_malloc_addr - _dl_mmap_zero + size > 4096) {
+               _dl_mmap_zero = _dl_malloc_addr =
+                       (unsigned char *) _dl_mmap((void *) 0, size, 
+                                                  PROT_READ | PROT_WRITE, 
+                                                  MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+               if (_dl_mmap_check_error(_dl_mmap_zero)) {
+                       _dl_fdprintf(2, "%s: can't map '/dev/zero'\n", _dl_progname);
+                       _dl_exit(20);
+               }
+       }
+       retval = _dl_malloc_addr;
+       _dl_malloc_addr += size;
+
+       /*
+        * Align memory to 4 byte boundary.  Some platforms require this, others
+        * simply get better performance.
+        */
+       _dl_malloc_addr = (char *) (((unsigned int) _dl_malloc_addr + 3) & ~(3));
+       return retval;
 }
 
-char * _dl_getenv(char *symbol, char **envp)
+char *_dl_getenv(char *symbol, char **envp)
 {
-  char *pnt;
-  char *pnt1;
-  while ((pnt = *envp++)) {
-    pnt1 = symbol;
-    while (*pnt && *pnt == *pnt1)
-      pnt1++, pnt++;
-    if (!*pnt || *pnt != '=' || *pnt1)
-      continue;
-    return pnt+1;
-  }
-  return 0;
+       char *pnt;
+       char *pnt1;
+
+       while ((pnt = *envp++)) {
+               pnt1 = symbol;
+               while (*pnt && *pnt == *pnt1)
+                       pnt1++, pnt++;
+               if (!*pnt || *pnt != '=' || *pnt1)
+                       continue;
+               return pnt + 1;
+       }
+       return 0;
 }
 
 void _dl_unsetenv(char *symbol, char **envp)
 {
-  char *pnt;
-  char *pnt1;
-  char **newenvp = envp;
-  for (pnt = *envp; pnt; pnt = *++envp) {
-    pnt1 = symbol;
-    while (*pnt && *pnt == *pnt1)
-      pnt1++, pnt++;
-    if(!*pnt || *pnt != '=' || *pnt1)
-      *newenvp++ = *envp;
-  }
-  *newenvp++ = *envp;
-  return;
+       char *pnt;
+       char *pnt1;
+       char **newenvp = envp;
+
+       for (pnt = *envp; pnt; pnt = *++envp) {
+               pnt1 = symbol;
+               while (*pnt && *pnt == *pnt1)
+                       pnt1++, pnt++;
+               if (!*pnt || *pnt != '=' || *pnt1)
+                       *newenvp++ = *envp;
+       }
+       *newenvp++ = *envp;
+       return;
 }
 
-char * _dl_strdup(const char * string){
-  char * retval;
-  int len;
+char *_dl_strdup(const char *string)
+{
+       char *retval;
+       int len;
 
-  len = _dl_strlen(string);
-  retval = _dl_malloc(len + 1);
-  _dl_strcpy(retval, string);
-  return retval;
+       len = _dl_strlen(string);
+       retval = _dl_malloc(len + 1);
+       _dl_strcpy(retval, string);
+       return retval;
 }
-
index 9d1cd0f..d9b9008 100644 (file)
 /* This file contains the helper routines to load an ELF sharable
    library into memory and add the symbol table info to the chain. */
 
-#include <linux/types.h>
-#include <linux/fcntl.h>
-#include <linux/errno.h>
+#include <asm/mman.h>
+#include "elf.h"
 #include "string.h"
-/*#include <stdlib.h>*/
-#include <linux/mman.h>
-#include <linux/stat.h>
 #include "hash.h"
-#include "linuxelf.h"
 #include "sysdep.h"
-#include <linux/unistd.h>
 #include "syscall.h"
 #ifdef USE_CACHE
 #include "../config.h"
@@ -46,80 +40,79 @@ static size_t _dl_cache_size = 0;
 
 int _dl_map_cache(void)
 {
-  int fd;
-  struct kernel_stat st;
-  header_t *header;
-  libentry_t *libent;
-  int i, strtabsize;
-
-  if (_dl_cache_addr == (caddr_t)-1)
-    return -1;
-  else if (_dl_cache_addr != NULL)
-    return 0;
-
-  if (_dl_stat(LDSO_CACHE, &st) || (fd = _dl_open(LDSO_CACHE, O_RDONLY)) < 0)
-  {
-    _dl_fdprintf(2, "%s: can't open cache '%s'\n", _dl_progname, LDSO_CACHE);
-    _dl_cache_addr = (caddr_t)-1; /* so we won't try again */
-    return -1;
-  }
-
-  _dl_cache_size = st.st_size;
-  _dl_cache_addr = (caddr_t)_dl_mmap(0, _dl_cache_size, PROT_READ,
-                                    MAP_SHARED, fd, 0);
-  _dl_close (fd);
-  if (_dl_cache_addr == (caddr_t)-1)
-  {
-    _dl_fdprintf(2, "%s: can't map cache '%s'\n", _dl_progname, LDSO_CACHE);
-    return -1;
-  }
-
-  header = (header_t *)_dl_cache_addr;
-
-  if (_dl_cache_size < sizeof (header_t) ||
-      _dl_memcmp(header->magic, LDSO_CACHE_MAGIC, LDSO_CACHE_MAGIC_LEN) ||
-      _dl_memcmp(header->version, LDSO_CACHE_VER, LDSO_CACHE_VER_LEN) ||
-      _dl_cache_size < 
-        (sizeof (header_t) + header->nlibs * sizeof (libentry_t)) ||
-      _dl_cache_addr[_dl_cache_size-1] != '\0')
-  {
-    _dl_fdprintf(2, "%s: cache '%s' is corrupt\n", _dl_progname, LDSO_CACHE);
-    goto fail;
-  }
-
-  strtabsize = _dl_cache_size - sizeof (header_t) - 
-    header->nlibs * sizeof (libentry_t);
-  libent = (libentry_t *)&header[1];
-
-  for (i = 0; i < header->nlibs; i++)
-  {
-    if (libent[i].sooffset >= strtabsize ||
-       libent[i].liboffset >= strtabsize)
-    {
-      _dl_fdprintf(2, "%s: cache '%s' is corrupt\n", _dl_progname, LDSO_CACHE);
-      goto fail;
-    }
-  }
-
-  return 0;
-
-fail:
-  _dl_munmap(_dl_cache_addr, _dl_cache_size);
-  _dl_cache_addr = (caddr_t)-1;
-  return -1;
+       int fd;
+       struct kernel_stat st;
+       header_t *header;
+       libentry_t *libent;
+       int i, strtabsize;
+
+       if (_dl_cache_addr == (caddr_t) - 1)
+               return -1;
+       else if (_dl_cache_addr != NULL)
+               return 0;
+
+       if (_dl_stat(LDSO_CACHE, &st)
+               || (fd = _dl_open(LDSO_CACHE, O_RDONLY)) < 0) {
+               _dl_fdprintf(2, "%s: can't open cache '%s'\n", _dl_progname, LDSO_CACHE);
+               _dl_cache_addr = (caddr_t) - 1; /* so we won't try again */
+               return -1;
+       }
+
+       _dl_cache_size = st.st_size;
+       _dl_cache_addr = (caddr_t) _dl_mmap(0, _dl_cache_size, PROT_READ, MAP_SHARED, fd, 0);
+       _dl_close(fd);
+       if (_dl_cache_addr == (caddr_t) - 1) {
+               _dl_fdprintf(2, "%s: can't map cache '%s'\n", 
+                       _dl_progname, LDSO_CACHE);
+               return -1;
+       }
+
+       header = (header_t *) _dl_cache_addr;
+
+       if (_dl_cache_size < sizeof(header_t) ||
+               _dl_memcmp(header->magic, LDSO_CACHE_MAGIC, LDSO_CACHE_MAGIC_LEN)
+               || _dl_memcmp(header->version, LDSO_CACHE_VER, LDSO_CACHE_VER_LEN)
+               || _dl_cache_size <
+               (sizeof(header_t) + header->nlibs * sizeof(libentry_t))
+               || _dl_cache_addr[_dl_cache_size - 1] != '\0') 
+       {
+               _dl_fdprintf(2, "%s: cache '%s' is corrupt\n", _dl_progname, 
+                       LDSO_CACHE);
+               goto fail;
+       }
+
+       strtabsize = _dl_cache_size - sizeof(header_t) -
+               header->nlibs * sizeof(libentry_t);
+       libent = (libentry_t *) & header[1];
+
+       for (i = 0; i < header->nlibs; i++) {
+               if (libent[i].sooffset >= strtabsize || 
+                       libent[i].liboffset >= strtabsize) 
+               {
+                       _dl_fdprintf(2, "%s: cache '%s' is corrupt\n", _dl_progname, LDSO_CACHE);
+                       goto fail;
+               }
+       }
+
+       return 0;
+
+  fail:
+       _dl_munmap(_dl_cache_addr, _dl_cache_size);
+       _dl_cache_addr = (caddr_t) - 1;
+       return -1;
 }
 
 int _dl_unmap_cache(void)
 {
-  if (_dl_cache_addr == NULL || _dl_cache_addr == (caddr_t)-1)
-    return -1;
+       if (_dl_cache_addr == NULL || _dl_cache_addr == (caddr_t) - 1)
+               return -1;
 
 #if 1
-  _dl_munmap (_dl_cache_addr, _dl_cache_size);
-  _dl_cache_addr = NULL;
+       _dl_munmap(_dl_cache_addr, _dl_cache_size);
+       _dl_cache_addr = NULL;
 #endif
 
-  return 0;
+       return 0;
 }
 
 #endif
@@ -131,160 +124,182 @@ int _dl_unmap_cache(void)
 unsigned int _dl_error_number;
 unsigned int _dl_internal_error_number;
 
-struct elf_resolve * _dl_load_shared_library(int secure, 
-       struct elf_resolve * tpnt, char * full_libname) {
-  char * pnt, *pnt1, *pnt2;
-  struct elf_resolve *tpnt1 = NULL;
-  char mylibname[2050];
-  char * libname;
-
-  _dl_internal_error_number = 0;
-
-  /* quick hack to ensure mylibname buffer doesn't overflow.  don't 
-     allow full_libname or any directory to be longer than 1024. */
-  if (_dl_strlen(full_libname) > 1024)
-    goto goof;
-
-  pnt = libname = full_libname;
-  while (*pnt) {
-    if(*pnt == '/') libname = pnt+1;
-    pnt++;
-  }
-
- /* If the filename has any '/', try it straight and leave it at that.
-     For IBCS2 compatibility under linux, we substitute the string 
-     /usr/i486-sysv4/lib for /usr/lib in library names. */
-
-  if (libname != full_libname) {
-    tpnt1 = _dl_load_elf_shared_library(secure, full_libname, 0);
-    if (tpnt1)
-      return tpnt1;
-    goto goof;
-  }
-
-  /*
-   * The ABI specifies that RPATH is searched before LD_*_PATH or
-   * the default path of /usr/lib.
-   * Check in rpath directories 
-   */
-  for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) {
-    if (tpnt->libtype == elf_executable) {
-      pnt1 = (char *)tpnt->dynamic_info[DT_RPATH];
-      if(pnt1) {
-       pnt1 += (unsigned int) tpnt->loadaddr + tpnt->dynamic_info[DT_STRTAB];
-       while(*pnt1){
-         pnt2 = mylibname;
-         while(*pnt1 && *pnt1 != ':') {
-           if (pnt2 - mylibname < 1024)
-             *pnt2++ = *pnt1++;
-           else
-             pnt1++;
-         }
-         if (pnt2 - mylibname >= 1024)
-           break;
-         if(pnt2[-1] != '/') *pnt2++ = '/';
-         pnt = libname;
-         while(*pnt) *pnt2++  = *pnt++;
-         *pnt2++ = 0;
-         tpnt1 = _dl_load_elf_shared_library(secure, mylibname, 0);
-         if(tpnt1) return tpnt1;
-         if(*pnt1 == ':') pnt1++;
+struct elf_resolve *_dl_load_shared_library(int secure, 
+       struct elf_resolve *tpnt, char *full_libname)
+{
+       char *pnt, *pnt1, *pnt2;
+       struct elf_resolve *tpnt1 = NULL;
+       char mylibname[2050];
+       char *libname;
+
+       _dl_internal_error_number = 0;
+
+       /* quick hack to ensure mylibname buffer doesn't overflow.  don't 
+          allow full_libname or any directory to be longer than 1024. */
+       if (_dl_strlen(full_libname) > 1024)
+               goto goof;
+
+       pnt = libname = full_libname;
+       while (*pnt) {
+               if (*pnt == '/')
+                       libname = pnt + 1;
+               pnt++;
        }
-      }
-    }
-  }
-  
-
-  /* Check in LD_{ELF_}LIBRARY_PATH, if specified and allowed */
-  pnt1 = _dl_library_path;
-  if (pnt1 && *pnt1) {
-    while (*pnt1) {
-      pnt2 = mylibname;
-      while(*pnt1 && *pnt1 != ':' && *pnt1 != ';') {
-       if (pnt2 - mylibname < 1024)
-         *pnt2++ = *pnt1++;
-       else
-         pnt1++;
-      }
-      if (pnt2 - mylibname >= 1024)
-       break;
-      if(pnt2[-1] != '/') *pnt2++ = '/';
-      pnt = libname;
-      while(*pnt) *pnt2++  = *pnt++;
-      *pnt2++ = 0;
-      tpnt1 = _dl_load_elf_shared_library(secure, mylibname, 0);
-      if(tpnt1) return tpnt1;
-      if(*pnt1 == ':' || *pnt1 == ';') pnt1++;
-    }
-  }
-
-
-  /*
-   * Where should the cache be searched?  There is no such concept in the
-   * ABI, so we have some flexibility here.  For now, search it before
-   * the default path of /usr/lib.
-   */
+
+       /* If the filename has any '/', try it straight and leave it at that.
+          For IBCS2 compatibility under linux, we substitute the string 
+          /usr/i486-sysv4/lib for /usr/lib in library names. */
+
+       if (libname != full_libname) {
+               tpnt1 = _dl_load_elf_shared_library(secure, full_libname, 0);
+               if (tpnt1)
+                       return tpnt1;
+               goto goof;
+       }
+
+       /*
+        * The ABI specifies that RPATH is searched before LD_*_PATH or
+        * the default path of /usr/lib.
+        * Check in rpath directories 
+        */
+       for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) {
+               if (tpnt->libtype == elf_executable) {
+                       pnt1 = (char *) tpnt->dynamic_info[DT_RPATH];
+                       if (pnt1) {
+                               pnt1 += (unsigned int) tpnt->loadaddr +
+                                       tpnt->dynamic_info[DT_STRTAB];
+                               while (*pnt1) {
+                                       pnt2 = mylibname;
+                                       while (*pnt1 && *pnt1 != ':') {
+                                               if (pnt2 - mylibname < 1024)
+                                                       *pnt2++ = *pnt1++;
+                                               else
+                                                       pnt1++;
+                                       }
+                                       if (pnt2 - mylibname >= 1024)
+                                               break;
+                                       if (pnt2[-1] != '/')
+                                               *pnt2++ = '/';
+                                       pnt = libname;
+                                       while (*pnt)
+                                               *pnt2++ = *pnt++;
+                                       *pnt2++ = 0;
+                                       tpnt1 =
+                                               _dl_load_elf_shared_library(secure, mylibname, 0);
+                                       if (tpnt1)
+                                               return tpnt1;
+                                       if (*pnt1 == ':')
+                                               pnt1++;
+                               }
+                       }
+               }
+       }
+
+
+       /* Check in LD_{ELF_}LIBRARY_PATH, if specified and allowed */
+       pnt1 = _dl_library_path;
+       if (pnt1 && *pnt1) {
+               while (*pnt1) {
+                       pnt2 = mylibname;
+                       while (*pnt1 && *pnt1 != ':' && *pnt1 != ';') {
+                               if (pnt2 - mylibname < 1024)
+                                       *pnt2++ = *pnt1++;
+                               else
+                                       pnt1++;
+                       }
+                       if (pnt2 - mylibname >= 1024)
+                               break;
+                       if (pnt2[-1] != '/')
+                               *pnt2++ = '/';
+                       pnt = libname;
+                       while (*pnt)
+                               *pnt2++ = *pnt++;
+                       *pnt2++ = 0;
+                       tpnt1 = _dl_load_elf_shared_library(secure, mylibname, 0);
+                       if (tpnt1)
+                               return tpnt1;
+                       if (*pnt1 == ':' || *pnt1 == ';')
+                               pnt1++;
+               }
+       }
+
+
+       /*
+        * Where should the cache be searched?  There is no such concept in the
+        * ABI, so we have some flexibility here.  For now, search it before
+        * the default path of /usr/lib.
+        */
 #ifdef USE_CACHE
-  if (_dl_cache_addr != NULL && _dl_cache_addr != (caddr_t)-1)
-  {
-    int i;
-    header_t *header = (header_t *)_dl_cache_addr;
-    libentry_t *libent = (libentry_t *)&header[1];
-    char *strs = (char *)&libent[header->nlibs];
-
-    for (i = 0; i < header->nlibs; i++)
-    {
-      if ((libent[i].flags == LIB_ELF || 
-          libent[i].flags == LIB_ELF_LIBC5) &&
-         _dl_strcmp(libname, strs+libent[i].sooffset) == 0 &&
-         (tpnt1 = _dl_load_elf_shared_library(secure, strs+libent[i].liboffset, 0)))
-       return tpnt1;
-    }
-  }
+       if (_dl_cache_addr != NULL && _dl_cache_addr != (caddr_t) - 1) {
+               int i;
+               header_t *header = (header_t *) _dl_cache_addr;
+               libentry_t *libent = (libentry_t *) & header[1];
+               char *strs = (char *) &libent[header->nlibs];
+
+               for (i = 0; i < header->nlibs; i++) {
+                       if ((libent[i].flags == LIB_ELF ||
+                                libent[i].flags == LIB_ELF_LIBC5) &&
+                               _dl_strcmp(libname, strs + libent[i].sooffset) == 0 &&
+                               (tpnt1 = _dl_load_elf_shared_library(secure, 
+                                    strs + libent[i].liboffset, 0)))
+                               return tpnt1;
+               }
+       }
 #endif
 
 
 #ifdef UCLIBC_DEVEL
 
-  /* Check in /usr/<arch>-linux-uclibc/lib */
-  pnt1 = UCLIBC_INSTALL_DIR"/lib";
-  pnt = mylibname;
-  while(*pnt1) *pnt++ = *pnt1++;
-  pnt1 = libname;
-  while(*pnt1) *pnt++ = *pnt1++;
-  *pnt++ = 0;
-  tpnt1 = _dl_load_elf_shared_library(secure, mylibname, 0);
-  if (tpnt1) return tpnt1;
-  
+       /* Check in /usr/<arch>-linux-uclibc/lib */
+       pnt1 = UCLIBC_INSTALL_DIR "/lib";
+       pnt = mylibname;
+       while (*pnt1)
+               *pnt++ = *pnt1++;
+       pnt1 = libname;
+       while (*pnt1)
+               *pnt++ = *pnt1++;
+       *pnt++ = 0;
+       tpnt1 = _dl_load_elf_shared_library(secure, mylibname, 0);
+       if (tpnt1)
+               return tpnt1;
+
 #else /* UCLIBC_DEVEL */
 
-  /* Check in /usr/lib */
-  pnt1 = "/usr/lib/";
-  pnt = mylibname;
-  while(*pnt1) *pnt++ = *pnt1++;
-  pnt1 = libname;
-  while(*pnt1) *pnt++ = *pnt1++;
-  *pnt++ = 0;
-  tpnt1 = _dl_load_elf_shared_library(secure, mylibname, 0);
-  if (tpnt1) return tpnt1;
-  
-  /* Check in /lib */
-  /* try "/lib/". */
-  pnt1 = "/lib/";
-  pnt = mylibname;
-  while(*pnt1) *pnt++ = *pnt1++;
-  pnt1 = libname;
-  while(*pnt1) *pnt++ = *pnt1++;
-  *pnt++ = 0;
-  tpnt1 = _dl_load_elf_shared_library(secure, mylibname, 0);
-  if (tpnt1) return tpnt1;
+       /* Check in /usr/lib */
+       pnt1 = "/usr/lib/";
+       pnt = mylibname;
+       while (*pnt1)
+               *pnt++ = *pnt1++;
+       pnt1 = libname;
+       while (*pnt1)
+               *pnt++ = *pnt1++;
+       *pnt++ = 0;
+       tpnt1 = _dl_load_elf_shared_library(secure, mylibname, 0);
+       if (tpnt1)
+               return tpnt1;
+
+       /* Check in /lib */
+       /* try "/lib/". */
+       pnt1 = "/lib/";
+       pnt = mylibname;
+       while (*pnt1)
+               *pnt++ = *pnt1++;
+       pnt1 = libname;
+       while (*pnt1)
+               *pnt++ = *pnt1++;
+       *pnt++ = 0;
+       tpnt1 = _dl_load_elf_shared_library(secure, mylibname, 0);
+       if (tpnt1)
+               return tpnt1;
 #endif /* UCLIBC_DEVEL */
 
-goof:
-  /* Well, we shot our wad on that one.  All we can do now is punt */
-  if (_dl_internal_error_number) _dl_error_number = _dl_internal_error_number;
-       else _dl_error_number = DL_ERROR_NOFILE;
-  return NULL;
+  goof:
+       /* Well, we shot our wad on that one.  All we can do now is punt */
+       if (_dl_internal_error_number)
+               _dl_error_number = _dl_internal_error_number;
+       else
+               _dl_error_number = DL_ERROR_NOFILE;
+       return NULL;
 }
 
 /*
@@ -295,264 +310,273 @@ goof:
 
 //extern _elf_rtbndr(void);
 
-struct elf_resolve * _dl_load_elf_shared_library(int secure, 
-        char * libname, int flag) {
-  struct elfhdr * epnt;
-  unsigned int dynamic_addr = 0;
-  unsigned int dynamic_size = 0;
-  struct dynamic * dpnt;
-  struct elf_resolve * tpnt;
-  struct elf_phdr * ppnt;
-  int piclib;
-  char * status;
-  int flags;
-  char header[4096];
-  int dynamic_info[24];
-  int * lpnt;
-  unsigned int libaddr;
-  unsigned int minvma=0xffffffff, maxvma=0;
-  
-  int i;
-  int infile;
-
-  /* If this file is already loaded, skip this step */
-  tpnt = _dl_check_hashed_files(libname);
-  if(tpnt) return tpnt;
-
-  /* If we are in secure mode (i.e. a setu/gid binary using LD_PRELOAD),
-     we don't load the library if it isn't setuid. */
-
-  if (secure) {
-    struct kernel_stat st;
-    if (_dl_stat(libname, &st) || !(st.st_mode & S_ISUID))
-      return NULL;
-  }
-
-  libaddr = 0;
-  infile = _dl_open(libname, O_RDONLY);
-  if(infile < 0)
-  {
+struct elf_resolve *_dl_load_elf_shared_library(int secure, 
+       char *libname, int flag)
+{
+       elfhdr *epnt;
+       unsigned int dynamic_addr = 0;
+       unsigned int dynamic_size = 0;
+       Elf32_Dyn *dpnt;
+       struct elf_resolve *tpnt;
+       elf_phdr *ppnt;
+       int piclib;
+       char *status;
+       int flags;
+       char header[4096];
+       int dynamic_info[24];
+       int *lpnt;
+       unsigned int libaddr;
+       unsigned int minvma = 0xffffffff, maxvma = 0;
+
+       int i;
+       int infile;
+
+       /* If this file is already loaded, skip this step */
+       tpnt = _dl_check_hashed_files(libname);
+       if (tpnt)
+               return tpnt;
+
+       /* If we are in secure mode (i.e. a setu/gid binary using LD_PRELOAD),
+          we don't load the library if it isn't setuid. */
+
+       if (secure) {
+               struct kernel_stat st;
+
+               if (_dl_stat(libname, &st) || !(st.st_mode & S_ISUID))
+                       return NULL;
+       }
+
+       libaddr = 0;
+       infile = _dl_open(libname, O_RDONLY);
+       if (infile < 0) {
 #if 0
-    /*
-     * NO!  When we open shared libraries we may search several paths.
-     * it is inappropriate to generate an error here.
-     */
-    _dl_fdprintf(2, "%s: can't open '%s'\n", _dl_progname, libname);
+               /*
+                * NO!  When we open shared libraries we may search several paths.
+                * it is inappropriate to generate an error here.
+                */
+               _dl_fdprintf(2, "%s: can't open '%s'\n", _dl_progname, libname);
 #endif
-    _dl_internal_error_number = DL_ERROR_NOFILE;
-    return NULL;
-  }
-  _dl_read(infile, header, sizeof(header));
-  epnt = (struct elfhdr *) header;
-  if (epnt->e_ident[0] != 0x7f ||
-      epnt->e_ident[1] != 'E' ||
-      epnt->e_ident[2] != 'L' ||
-      epnt->e_ident[3] != 'F') {
-    _dl_fdprintf(2, "%s: '%s' is not an ELF file\n", _dl_progname, libname);
-    _dl_internal_error_number = DL_ERROR_NOTELF;
-    _dl_close(infile);
-    return NULL;
-  };
-  
-  if((epnt->e_type != ET_DYN) || 
-     (epnt->e_machine != MAGIC1 
+               _dl_internal_error_number = DL_ERROR_NOFILE;
+               return NULL;
+       }
+
+       _dl_read(infile, header, sizeof(header));
+       epnt = (elfhdr *) header;
+       if (epnt->e_ident[0] != 0x7f ||
+               epnt->e_ident[1] != 'E' || 
+               epnt->e_ident[2] != 'L' || 
+               epnt->e_ident[3] != 'F') 
+       {
+               _dl_fdprintf(2, "%s: '%s' is not an ELF file\n", _dl_progname,
+                                        libname);
+               _dl_internal_error_number = DL_ERROR_NOTELF;
+               _dl_close(infile);
+               return NULL;
+       };
+
+       if ((epnt->e_type != ET_DYN) || (epnt->e_machine != MAGIC1 
 #ifdef MAGIC2
-      && epnt->e_machine != MAGIC2
+                   && epnt->e_machine != MAGIC2
 #endif
-      )){
-    _dl_internal_error_number = (epnt->e_type != ET_DYN ? DL_ERROR_NOTDYN : DL_ERROR_NOTMAGIC);
-    _dl_fdprintf(2, "%s: '%s' is not an ELF executable for " ELF_TARGET "\n",
-                _dl_progname, libname);
-    _dl_close(infile);
-    return NULL;
-  };
-
-  ppnt = (struct elf_phdr *) &header[epnt->e_phoff];
-
-  piclib = 1;
-  for(i=0;i < epnt->e_phnum; i++){
-
-    if(ppnt->p_type == PT_DYNAMIC) {
-      if (dynamic_addr)
-       _dl_fdprintf(2, "%s: '%s' has more than one dynamic section\n",
-                    _dl_progname, libname);
-      dynamic_addr = ppnt->p_vaddr;
-      dynamic_size = ppnt->p_filesz;
-    };
-
-    if(ppnt->p_type == PT_LOAD) {
-       /* See if this is a PIC library. */
-       if(i == 0 && ppnt->p_vaddr > 0x1000000) {
-           piclib = 0;
-           minvma=ppnt->p_vaddr;
+               )) 
+       {
+               _dl_internal_error_number = 
+                   (epnt->e_type != ET_DYN ? DL_ERROR_NOTDYN : DL_ERROR_NOTMAGIC);
+               _dl_fdprintf(2, "%s: '%s' is not an ELF executable for " ELF_TARGET 
+                       "\n", _dl_progname, libname);
+               _dl_close(infile);
+               return NULL;
+       };
+
+       ppnt = (elf_phdr *) & header[epnt->e_phoff];
+
+       piclib = 1;
+       for (i = 0; i < epnt->e_phnum; i++) {
+
+               if (ppnt->p_type == PT_DYNAMIC) {
+                       if (dynamic_addr)
+                               _dl_fdprintf(2, "%s: '%s' has more than one dynamic section\n", 
+                                       _dl_progname, libname);
+                       dynamic_addr = ppnt->p_vaddr;
+                       dynamic_size = ppnt->p_filesz;
+               };
+
+               if (ppnt->p_type == PT_LOAD) {
+                       /* See if this is a PIC library. */
+                       if (i == 0 && ppnt->p_vaddr > 0x1000000) {
+                               piclib = 0;
+                               minvma = ppnt->p_vaddr;
+                       }
+                       if (piclib && ppnt->p_vaddr < minvma) {
+                               minvma = ppnt->p_vaddr;
+                       }
+                       if (((unsigned int) ppnt->p_vaddr + ppnt->p_memsz) > maxvma) {
+                               maxvma = ppnt->p_vaddr + ppnt->p_memsz;
+                       }
+               }
+               ppnt++;
+       };
+
+       maxvma = (maxvma + 0xfffU) & ~0xfffU;
+       minvma = minvma & ~0xffffU;
+
+       flags = MAP_PRIVATE /*| MAP_DENYWRITE */ ;
+       if (!piclib)
+               flags |= MAP_FIXED;
+
+       status = (char *) _dl_mmap((char *) (piclib ? 0 : minvma), 
+               maxvma - minvma, PROT_NONE, flags | MAP_ANONYMOUS, -1, 0);
+       if (_dl_mmap_check_error(status)) {
+               _dl_fdprintf(2, "%s: can't map '/dev/zero'\n", _dl_progname);
+               _dl_internal_error_number = DL_ERROR_MMAP_FAILED;
+               _dl_close(infile);
+               return NULL;
+       };
+       libaddr = (unsigned int) status;
+       flags |= MAP_FIXED;
+
+       /* Get the memory to store the library */
+       ppnt = (elf_phdr *) & header[epnt->e_phoff];
+
+       for (i = 0; i < epnt->e_phnum; i++) {
+               if (ppnt->p_type == PT_LOAD) {
+
+                       /* See if this is a PIC library. */
+                       if (i == 0 && ppnt->p_vaddr > 0x1000000) {
+                               piclib = 0;
+                               /* flags |= MAP_FIXED; */
+                       }
+
+
+
+                       if (ppnt->p_flags & PF_W) {
+                               unsigned int map_size;
+                               char *cpnt;
+
+                               status = (char *) _dl_mmap((char *) ((piclib ? libaddr : 0) + 
+                                       (ppnt->p_vaddr & 0xfffff000)), (ppnt->p_vaddr & 0xfff) 
+                                       + ppnt->p_filesz, LXFLAGS(ppnt->p_flags), flags, infile, 
+                                       ppnt->p_offset & 0x7ffff000);
+
+                               if (_dl_mmap_check_error(status)) {
+                                       _dl_fdprintf(2, "%s: can't map '%s'\n", 
+                                               _dl_progname, libname);
+                                       _dl_internal_error_number = DL_ERROR_MMAP_FAILED;
+                                       _dl_munmap((char *) libaddr, maxvma - minvma);
+                                       _dl_close(infile);
+                                       return NULL;
+                               };
+
+                               /* Pad the last page with zeroes. */
+                               cpnt = (char *) (status + (ppnt->p_vaddr & 0xfff) +
+                                                         ppnt->p_filesz);
+                               while (((unsigned int) cpnt) & 0xfff)
+                                       *cpnt++ = 0;
+
+                               /* I am not quite sure if this is completely
+                                * correct to do or not, but the basic way that
+                                * we handle bss segments is that we mmap
+                                * /dev/zero if there are any pages left over
+                                * that are not mapped as part of the file */
+
+                               map_size = (ppnt->p_vaddr + ppnt->p_filesz + 0xfff) & 0xfffff000;
+                               if (map_size < ppnt->p_vaddr + ppnt->p_memsz)
+                                       status = (char *) _dl_mmap((char *) map_size + 
+                                               (piclib ? libaddr : 0), 
+                                               ppnt->p_vaddr + ppnt->p_memsz - map_size, 
+                                               LXFLAGS(ppnt->p_flags), flags | MAP_ANONYMOUS, -1, 0);
+                       } else
+                               status = (char *) _dl_mmap((char *) (ppnt->p_vaddr & 0xfffff000) 
+                                       + (piclib ? libaddr : 0), (ppnt->p_vaddr & 0xfff) + 
+                                       ppnt->p_filesz, LXFLAGS(ppnt->p_flags), flags, 
+                                       infile, ppnt->p_offset & 0x7ffff000);
+                       if (_dl_mmap_check_error(status)) {
+                               _dl_fdprintf(2, "%s: can't map '%s'\n", _dl_progname, libname);
+                               _dl_internal_error_number = DL_ERROR_MMAP_FAILED;
+                               _dl_munmap((char *) libaddr, maxvma - minvma);
+                               _dl_close(infile);
+                               return NULL;
+                       };
+
+                       /* if(libaddr == 0 && piclib) {
+                          libaddr = (unsigned int) status;
+                          flags |= MAP_FIXED;
+                          }; */
+               };
+               ppnt++;
+       };
+       _dl_close(infile);
+
+       /* For a non-PIC library, the addresses are all absolute */
+       if (piclib) {
+               dynamic_addr += (unsigned int) libaddr;
        }
-       if(piclib && ppnt->p_vaddr < minvma) {
-           minvma = ppnt->p_vaddr;
+
+       /* 
+        * OK, the ELF library is now loaded into VM in the correct locations
+        * The next step is to go through and do the dynamic linking (if needed).
+        */
+
+       /* Start by scanning the dynamic section to get all of the pointers */
+
+       if (!dynamic_addr) {
+               _dl_internal_error_number = DL_ERROR_NODYNAMIC;
+               _dl_fdprintf(2, "%s: '%s' is missing a dynamic section\n", 
+                       _dl_progname, libname);
+               return NULL;
        }
-       if(((unsigned int)ppnt->p_vaddr + ppnt->p_memsz) > maxvma) {
-           maxvma = ppnt->p_vaddr + ppnt->p_memsz;
+
+       dpnt = (Elf32_Dyn *) dynamic_addr;
+
+       dynamic_size = dynamic_size / sizeof(Elf32_Dyn);
+       _dl_memset(dynamic_info, 0, sizeof(dynamic_info));
+       for (i = 0; i < dynamic_size; i++) {
+               if (dpnt->d_tag > DT_JMPREL) {
+                       dpnt++;
+                       continue;
+               }
+               dynamic_info[dpnt->d_tag] = dpnt->d_un.d_val;
+               if (dpnt->d_tag == DT_TEXTREL || SVR4_BUGCOMPAT)
+                       dynamic_info[DT_TEXTREL] = 1;
+               dpnt++;
+       };
+
+       /* If the TEXTREL is set, this means that we need to make the pages
+          writable before we perform relocations.  Do this now. They get set back
+          again later. */
+
+       if (dynamic_info[DT_TEXTREL]) {
+               ppnt = (elf_phdr *) & header[epnt->e_phoff];
+               for (i = 0; i < epnt->e_phnum; i++, ppnt++) {
+                       if (ppnt->p_type == PT_LOAD && !(ppnt->p_flags & PF_W))
+                               _dl_mprotect((void *) ((piclib ? libaddr : 0) + 
+                                           (ppnt->p_vaddr & 0xfffff000)), 
+                                       (ppnt->p_vaddr & 0xfff) + (unsigned int) ppnt->p_filesz, 
+                                       PROT_READ | PROT_WRITE | PROT_EXEC);
+               }
        }
-     }
-    ppnt++;
-  };
-
-  maxvma=(maxvma+0xfffU)&~0xfffU;
-  minvma=minvma&~0xffffU;
-  
-  flags = MAP_PRIVATE /*| MAP_DENYWRITE*/;
-  if(!piclib) flags |= MAP_FIXED;
-  
-  status = (char *) _dl_mmap((char *) (piclib?0:minvma),
-                         maxvma-minvma, 
-                         PROT_NONE, 
-                         flags | MAP_ANONYMOUS, -1,
-                         0);
-  if(_dl_mmap_check_error(status)) {
-    _dl_fdprintf(2, "%s: can't map '/dev/zero'\n", _dl_progname);
-    _dl_internal_error_number = DL_ERROR_MMAP_FAILED;
-    _dl_close(infile);
-     return NULL;
-  };
-  libaddr=(unsigned int)status;
-  flags|=MAP_FIXED;
-
-  /* Get the memory to store the library */
-  ppnt = (struct elf_phdr *) &header[epnt->e_phoff];
-  
-  for(i=0;i < epnt->e_phnum; i++){
-    if(ppnt->p_type == PT_LOAD) {
-
-      /* See if this is a PIC library. */
-      if(i == 0 && ppnt->p_vaddr > 0x1000000) {
-       piclib = 0;
-       /* flags |= MAP_FIXED; */
-      }
-
-
-      
-      if(ppnt->p_flags & PF_W) {
-       unsigned int map_size;
-       char * cpnt;
-       
-       status = (char *) _dl_mmap((char *) ((piclib?libaddr:0)  +
-                                            (ppnt->p_vaddr & 0xfffff000)),
-                         (ppnt->p_vaddr & 0xfff) + ppnt->p_filesz, 
-                         LXFLAGS(ppnt->p_flags), 
-                         flags, infile,
-                         ppnt->p_offset & 0x7ffff000);
-       
-       if(_dl_mmap_check_error(status)) {
-           _dl_fdprintf(2, "%s: can't map '%s'\n", _dl_progname, libname);
-           _dl_internal_error_number = DL_ERROR_MMAP_FAILED;
-           _dl_munmap((char *)libaddr, maxvma-minvma);
-           _dl_close(infile);
-           return NULL;
+
+
+       tpnt = _dl_add_elf_hash_table(libname, (char *) libaddr, dynamic_info, 
+               dynamic_addr, dynamic_size);
+
+       tpnt->ppnt = (elf_phdr *) (tpnt->loadaddr + epnt->e_phoff);
+       tpnt->n_phent = epnt->e_phnum;
+
+       /*
+        * OK, the next thing we need to do is to insert the dynamic linker into
+        * the proper entry in the GOT so that the PLT symbols can be properly
+        * resolved. 
+        */
+
+       lpnt = (int *) dynamic_info[DT_PLTGOT];
+
+       if (lpnt) {
+               lpnt = (int *) (dynamic_info[DT_PLTGOT] + ((int) libaddr));
+               INIT_GOT(lpnt, tpnt);
        };
-       
-       /* Pad the last page with zeroes. */
-       cpnt =(char *) (status + (ppnt->p_vaddr & 0xfff) + ppnt->p_filesz);
-       while(((unsigned int) cpnt) & 0xfff) *cpnt++ = 0;
-
-/* I am not quite sure if this is completely correct to do or not, but
-   the basic way that we handle bss segments is that we mmap /dev/zero if
-   there are any pages left over that are not mapped as part of the file */
-
-       map_size = (ppnt->p_vaddr + ppnt->p_filesz + 0xfff) & 0xfffff000;
-       if(map_size < ppnt->p_vaddr + ppnt->p_memsz)
-         status = (char *) _dl_mmap((char *) map_size + (piclib?libaddr:0), 
-                           ppnt->p_vaddr + ppnt->p_memsz - map_size,
-                           LXFLAGS(ppnt->p_flags),
-                           flags | MAP_ANONYMOUS, -1, 0);
-      } else
-       status = (char *) _dl_mmap((char *) (ppnt->p_vaddr & 0xfffff000) + 
-                                  (piclib?libaddr:0), 
-                         (ppnt->p_vaddr & 0xfff) + ppnt->p_filesz, 
-                         LXFLAGS(ppnt->p_flags), 
-                         flags, infile, 
-                         ppnt->p_offset & 0x7ffff000);
-      if(_dl_mmap_check_error(status)) {
-       _dl_fdprintf(2, "%s: can't map '%s'\n", _dl_progname, libname);
-       _dl_internal_error_number = DL_ERROR_MMAP_FAILED;
-       _dl_munmap((char *)libaddr, maxvma-minvma);
-       _dl_close(infile);
-       return NULL;
-      };
 
-      /* if(libaddr == 0 && piclib) {
-       libaddr = (unsigned int) status;
-       flags |= MAP_FIXED;
-      }; */
-    };
-    ppnt++;
-  };
-  _dl_close(infile);
-  
-  /* For a non-PIC library, the addresses are all absolute */
-  if(piclib) {
-    dynamic_addr += (unsigned int) libaddr;
-  }
-
- /* 
-  * OK, the ELF library is now loaded into VM in the correct locations
-  * The next step is to go through and do the dynamic linking (if needed).
-  */
-  
-  /* Start by scanning the dynamic section to get all of the pointers */
-  
-  if(!dynamic_addr) {
-    _dl_internal_error_number = DL_ERROR_NODYNAMIC;
-    _dl_fdprintf(2, "%s: '%s' is missing a dynamic section\n", _dl_progname, libname);
-    return NULL;
-  }
-
-  dpnt = (struct dynamic *) dynamic_addr;
-
-  dynamic_size = dynamic_size / sizeof(struct dynamic);
-  _dl_memset(dynamic_info, 0, sizeof(dynamic_info));
-  for(i=0; i< dynamic_size; i++){
-    if( dpnt->d_tag > DT_JMPREL ) {dpnt++; continue; }
-    dynamic_info[dpnt->d_tag] = dpnt->d_un.d_val;
-    if(dpnt->d_tag == DT_TEXTREL ||
-       SVR4_BUGCOMPAT) dynamic_info[DT_TEXTREL] = 1;
-    dpnt++;
-  };
-
-  /* If the TEXTREL is set, this means that we need to make the pages
-     writable before we perform relocations.  Do this now. They get set back
-     again later. */
-
-  if (dynamic_info[DT_TEXTREL]) {
-  ppnt = (struct elf_phdr *) &header[epnt->e_phoff];
-  for(i=0;i < epnt->e_phnum; i++, ppnt++){
-    if(ppnt->p_type == PT_LOAD && !(ppnt->p_flags & PF_W))
-      _dl_mprotect((void *) ((piclib?libaddr:0) + (ppnt->p_vaddr & 0xfffff000)),
-                  (ppnt->p_vaddr & 0xfff) + (unsigned int) ppnt->p_filesz,
-                  PROT_READ | PROT_WRITE | PROT_EXEC);
-  }
-  }
-
-
-  tpnt = _dl_add_elf_hash_table(libname, (char *) libaddr, dynamic_info, dynamic_addr, 
-                             dynamic_size);
-
-  tpnt->ppnt = (struct elf_phdr *) (tpnt->loadaddr + epnt->e_phoff);
-  tpnt->n_phent = epnt->e_phnum;
-
-  /*
-   * OK, the next thing we need to do is to insert the dynamic linker into
-   * the proper entry in the GOT so that the PLT symbols can be properly
-   * resolved. 
-   */
-  
-  lpnt = (int *) dynamic_info[DT_PLTGOT];
-  
-  if(lpnt) {
-    lpnt = (int *) (dynamic_info[DT_PLTGOT] + ((int) libaddr));
-    INIT_GOT(lpnt, tpnt);
-  };
-  
-  return tpnt;
+       return tpnt;
 }
 
 /* Ugly, ugly.  Some versions of the SVr4 linker fail to generate COPY
@@ -561,28 +585,30 @@ struct elf_resolve * _dl_load_elf_shared_library(int secure,
    are guaranteed to be generated by a trustworthy linker, then this
    step can be skipped. */
 
-int _dl_copy_fixups(struct dyn_elf * rpnt)
+int _dl_copy_fixups(struct dyn_elf *rpnt)
 {
-  int goof = 0;
-  struct elf_resolve * tpnt;
+       int goof = 0;
+       struct elf_resolve *tpnt;
 
-  if(rpnt->next) goof += _dl_copy_fixups(rpnt->next);
-  else return 0;
+       if (rpnt->next)
+               goof += _dl_copy_fixups(rpnt->next);
+       else
+               return 0;
+
+       tpnt = rpnt->dyn;
+
+       if (tpnt->init_flag & COPY_RELOCS_DONE)
+               return goof;
+       tpnt->init_flag |= COPY_RELOCS_DONE;
 
-  tpnt = rpnt->dyn;
-       
-  if (tpnt->init_flag & COPY_RELOCS_DONE) return goof;
-  tpnt->init_flag |= COPY_RELOCS_DONE;
-  
 #ifdef ELF_USES_RELOCA
-  goof += _dl_parse_copy_information(rpnt, tpnt->dynamic_info[DT_RELA],
-                                          tpnt->dynamic_info[DT_RELASZ], 0);
+       goof += _dl_parse_copy_information(rpnt, 
+               tpnt->dynamic_info[DT_RELA], tpnt->dynamic_info[DT_RELASZ], 0);
 
 #else
-  goof += _dl_parse_copy_information(rpnt, tpnt->dynamic_info[DT_REL],
-                                          tpnt->dynamic_info[DT_RELSZ], 0);
+       goof += _dl_parse_copy_information(rpnt, tpnt->dynamic_info[DT_REL], 
+               tpnt->dynamic_info[DT_RELSZ], 0);
 
 #endif
-  return goof;
+       return goof;
 }
-
index 048c277..fa610e0 100644 (file)
 
 /* Various symbol table handling functions, including symbol lookup */
 
-/*#include <stdlib.h>*/
 #include "string.h"
-#include <linux/unistd.h>
-#include <linux/elf.h>
-
 #include "dlfcn.h"
 #include "hash.h"
 #include "linuxelf.h"
  * as well as all of the other good stuff in the binary.
  */
 
-struct elf_resolve * _dl_loaded_modules = NULL;
+struct elf_resolve *_dl_loaded_modules = NULL;
 
 /*
  * This is the list of modules that are loaded when the image is first
  * started.  As we add more via dlopen, they get added into other
  * chains.
  */
-struct dyn_elf * _dl_symbol_tables = NULL;
+struct dyn_elf *_dl_symbol_tables = NULL;
 
 /*
  * This is the list of modules that are loaded via dlopen.  We may need
  * to search these for RTLD_GLOBAL files.
  */
-struct dyn_elf * _dl_handles = NULL;
+struct dyn_elf *_dl_handles = NULL;
 
 
 /*
@@ -60,32 +56,35 @@ struct dyn_elf * _dl_handles = NULL;
  * have.  We need it to decode the hash table.
  */
 
-unsigned long _dl_elf_hash(const char * name){
-  unsigned long hash = 0;
-  unsigned long tmp;
+unsigned long _dl_elf_hash(const char *name)
+{
+       unsigned long hash = 0;
+       unsigned long tmp;
 
-  while (*name){
-    hash = (hash << 4) + *name++;
-    if((tmp = hash & 0xf0000000)) hash ^= tmp >> 24;
-    hash &= ~tmp;
-  };
-  return hash;
+       while (*name) {
+               hash = (hash << 4) + *name++;
+               if ((tmp = hash & 0xf0000000))
+                       hash ^= tmp >> 24;
+               hash &= ~tmp;
+       };
+       return hash;
 }
 
 /*
  * Check to see if a library has already been added to the hash chain.
  */
-struct elf_resolve * _dl_check_hashed_files(char * libname){
-  struct elf_resolve * tpnt;
-  int len = _dl_strlen(libname);
+struct elf_resolve *_dl_check_hashed_files(char *libname)
+{
+       struct elf_resolve *tpnt;
+       int len = _dl_strlen(libname);
 
-  for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) {
-    if (_dl_strncmp(tpnt->libname, libname, len) == 0 &&
-       (tpnt->libname[len] == '\0' || tpnt->libname[len] == '.'))
-      return tpnt;
-  }
+       for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) {
+               if (_dl_strncmp(tpnt->libname, libname, len) == 0 &&
+                       (tpnt->libname[len] == '\0' || tpnt->libname[len] == '.'))
+                       return tpnt;
+       }
 
-  return NULL;
+       return NULL;
 }
 
 /*
@@ -94,48 +93,47 @@ struct elf_resolve * _dl_check_hashed_files(char * libname){
  * externals properly.
  */
 
-struct elf_resolve * _dl_add_elf_hash_table(char * libname,
-                                       char * loadaddr,
-                                       unsigned int * dynamic_info,
-                                       unsigned int dynamic_addr,
-                                       unsigned int dynamic_size){
-  unsigned int *  hash_addr;
-  struct elf_resolve * tpnt;
-  int i;
-
-  if (!_dl_loaded_modules) {
-    tpnt = _dl_loaded_modules = 
-      (struct elf_resolve *) _dl_malloc(sizeof(struct elf_resolve));
-    _dl_memset (tpnt, 0, sizeof (*tpnt));
-  }
-  else {
-    tpnt = _dl_loaded_modules;
-    while(tpnt->next) tpnt = tpnt->next;
-    tpnt->next = (struct elf_resolve *) _dl_malloc(sizeof(struct elf_resolve));
-    _dl_memset (tpnt->next, 0, sizeof (*(tpnt->next)));
-    tpnt->next->prev = tpnt;
-    tpnt = tpnt->next;
-  };
-  
-  tpnt->next = NULL;
-  tpnt->init_flag = 0;
-  tpnt->libname = _dl_strdup(libname);
-  tpnt->dynamic_addr = dynamic_addr;
-  tpnt->dynamic_size = dynamic_size;
-  tpnt->libtype = loaded_file;
-
-  if( dynamic_info[DT_HASH] != 0 )
-  {
-    hash_addr = (unsigned int *) (dynamic_info[DT_HASH] + loadaddr);
-    tpnt->nbucket = *hash_addr++;
-    tpnt->nchain = *hash_addr++;
-    tpnt->elf_buckets = hash_addr;
-    hash_addr += tpnt->nbucket;
-    tpnt->chains = hash_addr;
-  }
-  tpnt->loadaddr = loadaddr;
-  for(i=0; i<24; i++) tpnt->dynamic_info[i] = dynamic_info[i];
-  return tpnt;
+struct elf_resolve *_dl_add_elf_hash_table(char *libname, 
+       char *loadaddr, unsigned int *dynamic_info, unsigned int dynamic_addr, 
+       unsigned int dynamic_size)
+{
+       unsigned int *hash_addr;
+       struct elf_resolve *tpnt;
+       int i;
+
+       if (!_dl_loaded_modules) {
+               tpnt = _dl_loaded_modules = 
+                   (struct elf_resolve *) _dl_malloc(sizeof(struct elf_resolve));
+               _dl_memset(tpnt, 0, sizeof(*tpnt));
+       } else {
+               tpnt = _dl_loaded_modules;
+               while (tpnt->next)
+                       tpnt = tpnt->next;
+               tpnt->next = (struct elf_resolve *) _dl_malloc(sizeof(struct elf_resolve));
+               _dl_memset(tpnt->next, 0, sizeof(*(tpnt->next)));
+               tpnt->next->prev = tpnt;
+               tpnt = tpnt->next;
+       };
+
+       tpnt->next = NULL;
+       tpnt->init_flag = 0;
+       tpnt->libname = _dl_strdup(libname);
+       tpnt->dynamic_addr = dynamic_addr;
+       tpnt->dynamic_size = dynamic_size;
+       tpnt->libtype = loaded_file;
+
+       if (dynamic_info[DT_HASH] != 0) {
+               hash_addr = (unsigned int *) (dynamic_info[DT_HASH] + loadaddr);
+               tpnt->nbucket = *hash_addr++;
+               tpnt->nchain = *hash_addr++;
+               tpnt->elf_buckets = hash_addr;
+               hash_addr += tpnt->nbucket;
+               tpnt->chains = hash_addr;
+       }
+       tpnt->loadaddr = loadaddr;
+       for (i = 0; i < 24; i++)
+               tpnt->dynamic_info[i] = dynamic_info[i];
+       return tpnt;
 }
 
 
@@ -144,141 +142,145 @@ struct elf_resolve * _dl_add_elf_hash_table(char * libname,
  * relocations or when we call an entry in the PLT table for the first time.
  */
 
-char * _dl_find_hash(char * name, struct dyn_elf * rpnt1, 
-                    unsigned int instr_addr, struct elf_resolve * f_tpnt, 
-                    int copyrel){
-  struct elf_resolve * tpnt;
-  int si;
-  char * pnt;
-  int    pass;
-  char * strtab;
-  struct elf32_sym * symtab;
-  unsigned int elf_hash_number, hn;
-  char * weak_result;
-  struct elf_resolve * first_def;
-  struct dyn_elf * rpnt, first;
-  char * data_result = 0;         /* nakao */
-
-  weak_result = 0;
-  elf_hash_number = _dl_elf_hash(name);
-
-  /* A quick little hack to make sure that any symbol in the executable
-  will be preferred to one in a shared library.  This is necessary so
-  that any shared library data symbols referenced in the executable
-  will be seen at the same address by the executable, shared libraries
-  and dynamically loaded code. -Rob Ryan (robr@cmu.edu) */
-  if(!copyrel && rpnt1) {
-      first=(*_dl_symbol_tables);
-      first.next=rpnt1;
-      rpnt1=(&first);
-  }
-  
-  /*
-   * The passes are so that we can first search the regular symbols
-   * for whatever module was specified, and then search anything
-   * loaded with RTLD_GLOBAL.  When pass is 1, it means we are just
-   * starting the first dlopened module, and anything above that
-   * is just the next one in the chain.
-   */
-  for(pass = 0; (1==1); pass++)
-    {
-      
-      /*
-       * If we are just starting to search for RTLD_GLOBAL, setup
-       * the pointer for the start of the search.
-       */
-      if( pass == 1) {
-       rpnt1 = _dl_handles;
-      }
-
-      /*
-       * Anything after this, we need to skip to the next module.
-       */
-      else if( pass >= 2) {
-       rpnt1 = rpnt1->next_handle;
-      }
-
-      /*
-       * Make sure we still have a module, and make sure that this
-       * module was loaded with RTLD_GLOBAL.
-       */
-      if( pass != 0 )
-       {
-         if( rpnt1 == NULL ) break;
-         if( (rpnt1->flags & RTLD_GLOBAL) == 0) continue;
+char *_dl_find_hash(char *name, struct dyn_elf *rpnt1, 
+       unsigned int instr_addr, struct elf_resolve *f_tpnt, int copyrel)
+{
+       struct elf_resolve *tpnt;
+       int si;
+       char *pnt;
+       int pass;
+       char *strtab;
+       Elf32_Sym *symtab;
+       unsigned int elf_hash_number, hn;
+       char *weak_result;
+       struct elf_resolve *first_def;
+       struct dyn_elf *rpnt, first;
+       char *data_result = 0;          /* nakao */
+
+       weak_result = 0;
+       elf_hash_number = _dl_elf_hash(name);
+
+       /* A quick little hack to make sure that any symbol in the executable
+          will be preferred to one in a shared library.  This is necessary so
+          that any shared library data symbols referenced in the executable
+          will be seen at the same address by the executable, shared libraries
+          and dynamically loaded code. -Rob Ryan (robr@cmu.edu) */
+       if (!copyrel && rpnt1) {
+               first = (*_dl_symbol_tables);
+               first.next = rpnt1;
+               rpnt1 = (&first);
        }
 
-      for(rpnt = (rpnt1 ? rpnt1 : _dl_symbol_tables); 
-         rpnt; rpnt = rpnt->next) {
-       tpnt = rpnt->dyn;
-       
-       /*
-        * The idea here is that if we are using dlsym, we want to
-        * first search the entire chain loaded from dlopen, and
-        * return a result from that if we found anything.  If this
-        * fails, then we continue the search into the stuff loaded
-        * when the image was activated.  For normal lookups, we start
-        * with rpnt == NULL, so we should never hit this.  
-        */
-       if( tpnt->libtype == elf_executable
-          && weak_result != 0 )
-         {
-           break;
-         }
-       
-       /*
-        * Avoid calling .urem here.
-        */
-       do_rem(hn, elf_hash_number, tpnt->nbucket);
-       symtab = (struct elf32_sym *) (tpnt->dynamic_info[DT_SYMTAB] + 
-                                      tpnt->loadaddr);
-       strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
        /*
-        * This crap is required because the first instance of a
-        * symbol on the chain will be used for all symbol references.
-        * Thus this instance must be resolved to an address that
-        * contains the actual function, 
+        * The passes are so that we can first search the regular symbols
+        * for whatever module was specified, and then search anything
+        * loaded with RTLD_GLOBAL.  When pass is 1, it means we are just
+        * starting the first dlopened module, and anything above that
+        * is just the next one in the chain.
         */
-       
-       first_def = NULL;
-       
-       for(si = tpnt->elf_buckets[hn]; si; si = tpnt->chains[si]){
-         pnt = strtab + symtab[si].st_name;
-         
-         if(_dl_strcmp(pnt, name) == 0 && 
-            (ELF32_ST_TYPE(symtab[si].st_info) == STT_FUNC ||
-             ELF32_ST_TYPE(symtab[si].st_info) == STT_NOTYPE ||
-             ELF32_ST_TYPE(symtab[si].st_info) == STT_OBJECT) &&
-            symtab[si].st_value != 0) {
-           
-           /* Here we make sure that we find a module where the symbol is
-            * actually defined.
-            */
-           
-           if(f_tpnt) {
-             if(!first_def) first_def = tpnt;
-             if(first_def == f_tpnt && symtab[si].st_shndx == 0)
-               continue;
-           }
-           
-           switch(ELF32_ST_BIND(symtab[si].st_info)){
-           case STB_GLOBAL:
-             if ( tpnt->libtype != elf_executable
-               && ELF32_ST_TYPE(symtab[si].st_info) == STT_NOTYPE) { /* nakao */
-               data_result = tpnt->loadaddr + symtab[si].st_value; /* nakao */
-               break;                                              /* nakao */
-             } else                                                /* nakao */
-               return tpnt->loadaddr + symtab[si].st_value;
-           case STB_WEAK:
-             if (!weak_result) weak_result = tpnt->loadaddr + symtab[si].st_value;
-             break;
-           default:  /* Do local symbols need to be examined? */
-             break;
-           }
-         }
+       for (pass = 0; (1 == 1); pass++) {
+
+               /*
+                * If we are just starting to search for RTLD_GLOBAL, setup
+                * the pointer for the start of the search.
+                */
+               if (pass == 1) {
+                       rpnt1 = _dl_handles;
+               }
+
+               /*
+                * Anything after this, we need to skip to the next module.
+                */
+               else if (pass >= 2) {
+                       rpnt1 = rpnt1->next_handle;
+               }
+
+               /*
+                * Make sure we still have a module, and make sure that this
+                * module was loaded with RTLD_GLOBAL.
+                */
+               if (pass != 0) {
+                       if (rpnt1 == NULL)
+                               break;
+                       if ((rpnt1->flags & RTLD_GLOBAL) == 0)
+                               continue;
+               }
+
+               for (rpnt = (rpnt1 ? rpnt1 : _dl_symbol_tables); rpnt; rpnt = rpnt->next) {
+                       tpnt = rpnt->dyn;
+
+                       /*
+                        * The idea here is that if we are using dlsym, we want to
+                        * first search the entire chain loaded from dlopen, and
+                        * return a result from that if we found anything.  If this
+                        * fails, then we continue the search into the stuff loaded
+                        * when the image was activated.  For normal lookups, we start
+                        * with rpnt == NULL, so we should never hit this.  
+                        */
+                       if (tpnt->libtype == elf_executable && weak_result != 0) {
+                               break;
+                       }
+
+                       /*
+                        * Avoid calling .urem here.
+                        */
+                       do_rem(hn, elf_hash_number, tpnt->nbucket);
+                       symtab = (Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr);
+                       strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
+                       /*
+                        * This crap is required because the first instance of a
+                        * symbol on the chain will be used for all symbol references.
+                        * Thus this instance must be resolved to an address that
+                        * contains the actual function, 
+                        */
+
+                       first_def = NULL;
+
+                       for (si = tpnt->elf_buckets[hn]; si; si = tpnt->chains[si]) {
+                               pnt = strtab + symtab[si].st_name;
+
+                               if (_dl_strcmp(pnt, name) == 0 &&
+                                       (ELF32_ST_TYPE(symtab[si].st_info) == STT_FUNC ||
+                                        ELF32_ST_TYPE(symtab[si].st_info) == STT_NOTYPE ||
+                                        ELF32_ST_TYPE(symtab[si].st_info) == STT_OBJECT) &&
+                                       symtab[si].st_value != 0) {
+
+                                       /* Here we make sure that we find a module where the symbol is
+                                        * actually defined.
+                                        */
+
+                                       if (f_tpnt) {
+                                               if (!first_def)
+                                                       first_def = tpnt;
+                                               if (first_def == f_tpnt
+                                                       && symtab[si].st_shndx == 0)
+                                                       continue;
+                                       }
+
+                                       switch (ELF32_ST_BIND(symtab[si].st_info)) {
+                                       case STB_GLOBAL:
+                                               if (tpnt->libtype != elf_executable && 
+                                                       ELF32_ST_TYPE(symtab[si].st_info) 
+                                                       == STT_NOTYPE) 
+                                               {       /* nakao */
+                                                       data_result = tpnt->loadaddr + 
+                                                           symtab[si].st_value;        /* nakao */
+                                                       break;  /* nakao */
+                                               } else  /* nakao */
+                                                       return tpnt->loadaddr + symtab[si].st_value;
+                                       case STB_WEAK:
+                                               if (!weak_result)
+                                                       weak_result =
+                                                               tpnt->loadaddr + symtab[si].st_value;
+                                               break;
+                                       default:        /* Do local symbols need to be examined? */
+                                               break;
+                                       }
+                               }
+                       }
+               }
        }
-      }
-    }
-  if (data_result) return data_result; /* nakao */
-  return weak_result;
+       if (data_result)
+               return data_result;             /* nakao */
+       return weak_result;
 }
index 048c277..fa610e0 100644 (file)
 
 /* Various symbol table handling functions, including symbol lookup */
 
-/*#include <stdlib.h>*/
 #include "string.h"
-#include <linux/unistd.h>
-#include <linux/elf.h>
-
 #include "dlfcn.h"
 #include "hash.h"
 #include "linuxelf.h"
  * as well as all of the other good stuff in the binary.
  */
 
-struct elf_resolve * _dl_loaded_modules = NULL;
+struct elf_resolve *_dl_loaded_modules = NULL;
 
 /*
  * This is the list of modules that are loaded when the image is first
  * started.  As we add more via dlopen, they get added into other
  * chains.
  */
-struct dyn_elf * _dl_symbol_tables = NULL;
+struct dyn_elf *_dl_symbol_tables = NULL;
 
 /*
  * This is the list of modules that are loaded via dlopen.  We may need
  * to search these for RTLD_GLOBAL files.
  */
-struct dyn_elf * _dl_handles = NULL;
+struct dyn_elf *_dl_handles = NULL;
 
 
 /*
@@ -60,32 +56,35 @@ struct dyn_elf * _dl_handles = NULL;
  * have.  We need it to decode the hash table.
  */
 
-unsigned long _dl_elf_hash(const char * name){
-  unsigned long hash = 0;
-  unsigned long tmp;
+unsigned long _dl_elf_hash(const char *name)
+{
+       unsigned long hash = 0;
+       unsigned long tmp;
 
-  while (*name){
-    hash = (hash << 4) + *name++;
-    if((tmp = hash & 0xf0000000)) hash ^= tmp >> 24;
-    hash &= ~tmp;
-  };
-  return hash;
+       while (*name) {
+               hash = (hash << 4) + *name++;
+               if ((tmp = hash & 0xf0000000))
+                       hash ^= tmp >> 24;
+               hash &= ~tmp;
+       };
+       return hash;
 }
 
 /*
  * Check to see if a library has already been added to the hash chain.
  */
-struct elf_resolve * _dl_check_hashed_files(char * libname){
-  struct elf_resolve * tpnt;
-  int len = _dl_strlen(libname);
+struct elf_resolve *_dl_check_hashed_files(char *libname)
+{
+       struct elf_resolve *tpnt;
+       int len = _dl_strlen(libname);
 
-  for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) {
-    if (_dl_strncmp(tpnt->libname, libname, len) == 0 &&
-       (tpnt->libname[len] == '\0' || tpnt->libname[len] == '.'))
-      return tpnt;
-  }
+       for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) {
+               if (_dl_strncmp(tpnt->libname, libname, len) == 0 &&
+                       (tpnt->libname[len] == '\0' || tpnt->libname[len] == '.'))
+                       return tpnt;
+       }
 
-  return NULL;
+       return NULL;
 }
 
 /*
@@ -94,48 +93,47 @@ struct elf_resolve * _dl_check_hashed_files(char * libname){
  * externals properly.
  */
 
-struct elf_resolve * _dl_add_elf_hash_table(char * libname,
-                                       char * loadaddr,
-                                       unsigned int * dynamic_info,
-                                       unsigned int dynamic_addr,
-                                       unsigned int dynamic_size){
-  unsigned int *  hash_addr;
-  struct elf_resolve * tpnt;
-  int i;
-
-  if (!_dl_loaded_modules) {
-    tpnt = _dl_loaded_modules = 
-      (struct elf_resolve *) _dl_malloc(sizeof(struct elf_resolve));
-    _dl_memset (tpnt, 0, sizeof (*tpnt));
-  }
-  else {
-    tpnt = _dl_loaded_modules;
-    while(tpnt->next) tpnt = tpnt->next;
-    tpnt->next = (struct elf_resolve *) _dl_malloc(sizeof(struct elf_resolve));
-    _dl_memset (tpnt->next, 0, sizeof (*(tpnt->next)));
-    tpnt->next->prev = tpnt;
-    tpnt = tpnt->next;
-  };
-  
-  tpnt->next = NULL;
-  tpnt->init_flag = 0;
-  tpnt->libname = _dl_strdup(libname);
-  tpnt->dynamic_addr = dynamic_addr;
-  tpnt->dynamic_size = dynamic_size;
-  tpnt->libtype = loaded_file;
-
-  if( dynamic_info[DT_HASH] != 0 )
-  {
-    hash_addr = (unsigned int *) (dynamic_info[DT_HASH] + loadaddr);
-    tpnt->nbucket = *hash_addr++;
-    tpnt->nchain = *hash_addr++;
-    tpnt->elf_buckets = hash_addr;
-    hash_addr += tpnt->nbucket;
-    tpnt->chains = hash_addr;
-  }
-  tpnt->loadaddr = loadaddr;
-  for(i=0; i<24; i++) tpnt->dynamic_info[i] = dynamic_info[i];
-  return tpnt;
+struct elf_resolve *_dl_add_elf_hash_table(char *libname, 
+       char *loadaddr, unsigned int *dynamic_info, unsigned int dynamic_addr, 
+       unsigned int dynamic_size)
+{
+       unsigned int *hash_addr;
+       struct elf_resolve *tpnt;
+       int i;
+
+       if (!_dl_loaded_modules) {
+               tpnt = _dl_loaded_modules = 
+                   (struct elf_resolve *) _dl_malloc(sizeof(struct elf_resolve));
+               _dl_memset(tpnt, 0, sizeof(*tpnt));
+       } else {
+               tpnt = _dl_loaded_modules;
+               while (tpnt->next)
+                       tpnt = tpnt->next;
+               tpnt->next = (struct elf_resolve *) _dl_malloc(sizeof(struct elf_resolve));
+               _dl_memset(tpnt->next, 0, sizeof(*(tpnt->next)));
+               tpnt->next->prev = tpnt;
+               tpnt = tpnt->next;
+       };
+
+       tpnt->next = NULL;
+       tpnt->init_flag = 0;
+       tpnt->libname = _dl_strdup(libname);
+       tpnt->dynamic_addr = dynamic_addr;
+       tpnt->dynamic_size = dynamic_size;
+       tpnt->libtype = loaded_file;
+
+       if (dynamic_info[DT_HASH] != 0) {
+               hash_addr = (unsigned int *) (dynamic_info[DT_HASH] + loadaddr);
+               tpnt->nbucket = *hash_addr++;
+               tpnt->nchain = *hash_addr++;
+               tpnt->elf_buckets = hash_addr;
+               hash_addr += tpnt->nbucket;
+               tpnt->chains = hash_addr;
+       }
+       tpnt->loadaddr = loadaddr;
+       for (i = 0; i < 24; i++)
+               tpnt->dynamic_info[i] = dynamic_info[i];
+       return tpnt;
 }
 
 
@@ -144,141 +142,145 @@ struct elf_resolve * _dl_add_elf_hash_table(char * libname,
  * relocations or when we call an entry in the PLT table for the first time.
  */
 
-char * _dl_find_hash(char * name, struct dyn_elf * rpnt1, 
-                    unsigned int instr_addr, struct elf_resolve * f_tpnt, 
-                    int copyrel){
-  struct elf_resolve * tpnt;
-  int si;
-  char * pnt;
-  int    pass;
-  char * strtab;
-  struct elf32_sym * symtab;
-  unsigned int elf_hash_number, hn;
-  char * weak_result;
-  struct elf_resolve * first_def;
-  struct dyn_elf * rpnt, first;
-  char * data_result = 0;         /* nakao */
-
-  weak_result = 0;
-  elf_hash_number = _dl_elf_hash(name);
-
-  /* A quick little hack to make sure that any symbol in the executable
-  will be preferred to one in a shared library.  This is necessary so
-  that any shared library data symbols referenced in the executable
-  will be seen at the same address by the executable, shared libraries
-  and dynamically loaded code. -Rob Ryan (robr@cmu.edu) */
-  if(!copyrel && rpnt1) {
-      first=(*_dl_symbol_tables);
-      first.next=rpnt1;
-      rpnt1=(&first);
-  }
-  
-  /*
-   * The passes are so that we can first search the regular symbols
-   * for whatever module was specified, and then search anything
-   * loaded with RTLD_GLOBAL.  When pass is 1, it means we are just
-   * starting the first dlopened module, and anything above that
-   * is just the next one in the chain.
-   */
-  for(pass = 0; (1==1); pass++)
-    {
-      
-      /*
-       * If we are just starting to search for RTLD_GLOBAL, setup
-       * the pointer for the start of the search.
-       */
-      if( pass == 1) {
-       rpnt1 = _dl_handles;
-      }
-
-      /*
-       * Anything after this, we need to skip to the next module.
-       */
-      else if( pass >= 2) {
-       rpnt1 = rpnt1->next_handle;
-      }
-
-      /*
-       * Make sure we still have a module, and make sure that this
-       * module was loaded with RTLD_GLOBAL.
-       */
-      if( pass != 0 )
-       {
-         if( rpnt1 == NULL ) break;
-         if( (rpnt1->flags & RTLD_GLOBAL) == 0) continue;
+char *_dl_find_hash(char *name, struct dyn_elf *rpnt1, 
+       unsigned int instr_addr, struct elf_resolve *f_tpnt, int copyrel)
+{
+       struct elf_resolve *tpnt;
+       int si;
+       char *pnt;
+       int pass;
+       char *strtab;
+       Elf32_Sym *symtab;
+       unsigned int elf_hash_number, hn;
+       char *weak_result;
+       struct elf_resolve *first_def;
+       struct dyn_elf *rpnt, first;
+       char *data_result = 0;          /* nakao */
+
+       weak_result = 0;
+       elf_hash_number = _dl_elf_hash(name);
+
+       /* A quick little hack to make sure that any symbol in the executable
+          will be preferred to one in a shared library.  This is necessary so
+          that any shared library data symbols referenced in the executable
+          will be seen at the same address by the executable, shared libraries
+          and dynamically loaded code. -Rob Ryan (robr@cmu.edu) */
+       if (!copyrel && rpnt1) {
+               first = (*_dl_symbol_tables);
+               first.next = rpnt1;
+               rpnt1 = (&first);
        }
 
-      for(rpnt = (rpnt1 ? rpnt1 : _dl_symbol_tables); 
-         rpnt; rpnt = rpnt->next) {
-       tpnt = rpnt->dyn;
-       
-       /*
-        * The idea here is that if we are using dlsym, we want to
-        * first search the entire chain loaded from dlopen, and
-        * return a result from that if we found anything.  If this
-        * fails, then we continue the search into the stuff loaded
-        * when the image was activated.  For normal lookups, we start
-        * with rpnt == NULL, so we should never hit this.  
-        */
-       if( tpnt->libtype == elf_executable
-          && weak_result != 0 )
-         {
-           break;
-         }
-       
-       /*
-        * Avoid calling .urem here.
-        */
-       do_rem(hn, elf_hash_number, tpnt->nbucket);
-       symtab = (struct elf32_sym *) (tpnt->dynamic_info[DT_SYMTAB] + 
-                                      tpnt->loadaddr);
-       strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
        /*
-        * This crap is required because the first instance of a
-        * symbol on the chain will be used for all symbol references.
-        * Thus this instance must be resolved to an address that
-        * contains the actual function, 
+        * The passes are so that we can first search the regular symbols
+        * for whatever module was specified, and then search anything
+        * loaded with RTLD_GLOBAL.  When pass is 1, it means we are just
+        * starting the first dlopened module, and anything above that
+        * is just the next one in the chain.
         */
-       
-       first_def = NULL;
-       
-       for(si = tpnt->elf_buckets[hn]; si; si = tpnt->chains[si]){
-         pnt = strtab + symtab[si].st_name;
-         
-         if(_dl_strcmp(pnt, name) == 0 && 
-            (ELF32_ST_TYPE(symtab[si].st_info) == STT_FUNC ||
-             ELF32_ST_TYPE(symtab[si].st_info) == STT_NOTYPE ||
-             ELF32_ST_TYPE(symtab[si].st_info) == STT_OBJECT) &&
-            symtab[si].st_value != 0) {
-           
-           /* Here we make sure that we find a module where the symbol is
-            * actually defined.
-            */
-           
-           if(f_tpnt) {
-             if(!first_def) first_def = tpnt;
-             if(first_def == f_tpnt && symtab[si].st_shndx == 0)
-               continue;
-           }
-           
-           switch(ELF32_ST_BIND(symtab[si].st_info)){
-           case STB_GLOBAL:
-             if ( tpnt->libtype != elf_executable
-               && ELF32_ST_TYPE(symtab[si].st_info) == STT_NOTYPE) { /* nakao */
-               data_result = tpnt->loadaddr + symtab[si].st_value; /* nakao */
-               break;                                              /* nakao */
-             } else                                                /* nakao */
-               return tpnt->loadaddr + symtab[si].st_value;
-           case STB_WEAK:
-             if (!weak_result) weak_result = tpnt->loadaddr + symtab[si].st_value;
-             break;
-           default:  /* Do local symbols need to be examined? */
-             break;
-           }
-         }
+       for (pass = 0; (1 == 1); pass++) {
+
+               /*
+                * If we are just starting to search for RTLD_GLOBAL, setup
+                * the pointer for the start of the search.
+                */
+               if (pass == 1) {
+                       rpnt1 = _dl_handles;
+               }
+
+               /*
+                * Anything after this, we need to skip to the next module.
+                */
+               else if (pass >= 2) {
+                       rpnt1 = rpnt1->next_handle;
+               }
+
+               /*
+                * Make sure we still have a module, and make sure that this
+                * module was loaded with RTLD_GLOBAL.
+                */
+               if (pass != 0) {
+                       if (rpnt1 == NULL)
+                               break;
+                       if ((rpnt1->flags & RTLD_GLOBAL) == 0)
+                               continue;
+               }
+
+               for (rpnt = (rpnt1 ? rpnt1 : _dl_symbol_tables); rpnt; rpnt = rpnt->next) {
+                       tpnt = rpnt->dyn;
+
+                       /*
+                        * The idea here is that if we are using dlsym, we want to
+                        * first search the entire chain loaded from dlopen, and
+                        * return a result from that if we found anything.  If this
+                        * fails, then we continue the search into the stuff loaded
+                        * when the image was activated.  For normal lookups, we start
+                        * with rpnt == NULL, so we should never hit this.  
+                        */
+                       if (tpnt->libtype == elf_executable && weak_result != 0) {
+                               break;
+                       }
+
+                       /*
+                        * Avoid calling .urem here.
+                        */
+                       do_rem(hn, elf_hash_number, tpnt->nbucket);
+                       symtab = (Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr);
+                       strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
+                       /*
+                        * This crap is required because the first instance of a
+                        * symbol on the chain will be used for all symbol references.
+                        * Thus this instance must be resolved to an address that
+                        * contains the actual function, 
+                        */
+
+                       first_def = NULL;
+
+                       for (si = tpnt->elf_buckets[hn]; si; si = tpnt->chains[si]) {
+                               pnt = strtab + symtab[si].st_name;
+
+                               if (_dl_strcmp(pnt, name) == 0 &&
+                                       (ELF32_ST_TYPE(symtab[si].st_info) == STT_FUNC ||
+                                        ELF32_ST_TYPE(symtab[si].st_info) == STT_NOTYPE ||
+                                        ELF32_ST_TYPE(symtab[si].st_info) == STT_OBJECT) &&
+                                       symtab[si].st_value != 0) {
+
+                                       /* Here we make sure that we find a module where the symbol is
+                                        * actually defined.
+                                        */
+
+                                       if (f_tpnt) {
+                                               if (!first_def)
+                                                       first_def = tpnt;
+                                               if (first_def == f_tpnt
+                                                       && symtab[si].st_shndx == 0)
+                                                       continue;
+                                       }
+
+                                       switch (ELF32_ST_BIND(symtab[si].st_info)) {
+                                       case STB_GLOBAL:
+                                               if (tpnt->libtype != elf_executable && 
+                                                       ELF32_ST_TYPE(symtab[si].st_info) 
+                                                       == STT_NOTYPE) 
+                                               {       /* nakao */
+                                                       data_result = tpnt->loadaddr + 
+                                                           symtab[si].st_value;        /* nakao */
+                                                       break;  /* nakao */
+                                               } else  /* nakao */
+                                                       return tpnt->loadaddr + symtab[si].st_value;
+                                       case STB_WEAK:
+                                               if (!weak_result)
+                                                       weak_result =
+                                                               tpnt->loadaddr + symtab[si].st_value;
+                                               break;
+                                       default:        /* Do local symbols need to be examined? */
+                                               break;
+                                       }
+                               }
+                       }
+               }
        }
-      }
-    }
-  if (data_result) return data_result; /* nakao */
-  return weak_result;
+       if (data_result)
+               return data_result;             /* nakao */
+       return weak_result;
 }
index 2eeda2d..f7c6eeb 100644 (file)
@@ -35,7 +35,7 @@ struct elf_resolve{
 
   unsigned int dynamic_size;
   unsigned int n_phent;
-  struct elf_phdr * ppnt;
+  Elf32_Phdr * ppnt;
 };
 
 #if 0
index a9adb23..3054429 100644 (file)
@@ -1,4 +1,3 @@
-#include <linux/types.h>
 #include <asm/unistd.h>
 
 /* Here are the macros which define how this platform makes
index 359018a..e0d3505 100644 (file)
 #define VERBOSE_DLINKER
 #endif
 #ifdef VERBOSE_DLINKER
-static char * _dl_reltypes[] = {"R_386_NONE","R_386_32","R_386_PC32","R_386_GOT32",
-                      "R_386_PLT32","R_386_COPY","R_386_GLOB_DAT",
-                      "R_386_JMP_SLOT","R_386_RELATIVE","R_386_GOTOFF",
-                      "R_386_GOTPC","R_386_NUM"};
+static char *_dl_reltypes[] =
+       { "R_386_NONE", "R_386_32", "R_386_PC32", "R_386_GOT32",
+       "R_386_PLT32", "R_386_COPY", "R_386_GLOB_DAT",
+       "R_386_JMP_SLOT", "R_386_RELATIVE", "R_386_GOTOFF",
+       "R_386_GOTPC", "R_386_NUM"
+};
 #endif
 
 /* Program to load an ELF binary on a linux system, and run it.
-References to symbols in sharable libraries can be resolved by either
-an ELF sharable library or a linux style of shared library. */
+   References to symbols in sharable libraries can be resolved by either
+   an ELF sharable library or a linux style of shared library. */
 
 /* Disclaimer:  I have never seen any AT&T source code for SVr4, nor have
    I ever taken any courses on internals.  This program was developed using
@@ -39,214 +41,219 @@ an ELF sharable library or a linux style of shared library. */
 
 #include <sys/types.h>
 #include <errno.h>
-#include <fcntl.h>
-#include <linux/elf.h>
-
+#include "elf.h"
 #include "hash.h"
-#include "linuxelf.h"
 #include "syscall.h"
-#include "../string.h"
-
-#define SVR4_COMPATIBILITY
+#include "string.h"
+#include "sysdep.h"
 
 extern char *_dl_progname;
 
 extern int _dl_linux_resolve(void);
 
-unsigned int _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_entry)
+unsigned int _dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry)
 {
-  int reloc_type;
-  struct elf32_rel * this_reloc;
-  char * strtab;
-  struct elf32_sym * symtab; 
-  struct elf32_rel * rel_addr;
-  int symtab_index;
-  char * new_addr;
-  char ** got_addr;
-  unsigned int instr_addr;
+       int reloc_type;
+       Elf32_Rel *this_reloc;
+       char *strtab;
+       Elf32_Sym *symtab;
+       Elf32_Rel *rel_addr;
+       int symtab_index;
+       char *new_addr;
+       char **got_addr;
+       unsigned int instr_addr;
 
-  rel_addr = (struct elf32_rel *) (tpnt->dynamic_info[DT_JMPREL] + 
-                                  tpnt->loadaddr);
+       rel_addr = (Elf32_Rel *) (tpnt->dynamic_info[DT_JMPREL] + tpnt->loadaddr);
 
-  this_reloc = rel_addr + (reloc_entry >> 3);
-  reloc_type = ELF32_R_TYPE(this_reloc->r_info);
-  symtab_index = ELF32_R_SYM(this_reloc->r_info);
+       this_reloc = rel_addr + (reloc_entry >> 3);
+       reloc_type = ELF32_R_TYPE(this_reloc->r_info);
+       symtab_index = ELF32_R_SYM(this_reloc->r_info);
 
-  symtab =  (struct elf32_sym *) (tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr);
-  strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
+       symtab = (Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr);
+       strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
 
 
-  if (reloc_type != R_386_JMP_SLOT) {
-    _dl_fdprintf(2, "%s: Incorrect relocation type in jump relocations\n",
-                _dl_progname);
-    _dl_exit(1);
-  };
+       if (reloc_type != R_386_JMP_SLOT) {
+               _dl_fdprintf(2, "%s: Incorrect relocation type in jump relocations\n", 
+                       _dl_progname);
+               _dl_exit(1);
+       };
 
-  /* Address of jump instruction to fix up */
-  instr_addr  = ((int)this_reloc->r_offset  + (int)tpnt->loadaddr);
-  got_addr = (char **) instr_addr;
+       /* Address of jump instruction to fix up */
+       instr_addr = ((int) this_reloc->r_offset + (int) tpnt->loadaddr);
+       got_addr = (char **) instr_addr;
 
 #ifdef DEBUG
-  _dl_fdprintf(2, "Resolving symbol %s\n",
-       strtab + symtab[symtab_index].st_name);
+       _dl_fdprintf(2, "Resolving symbol %s\n", 
+               strtab + symtab[symtab_index].st_name);
 #endif
 
-  /* Get the address of the GOT entry */
-  new_addr = _dl_find_hash(strtab + symtab[symtab_index].st_name, 
-                       tpnt->symbol_scope, (int) got_addr, tpnt, 0);
-  if(!new_addr) {
-    _dl_fdprintf(2, "%s: can't resolve symbol '%s'\n",
-              _dl_progname, strtab + symtab[symtab_index].st_name);
-    _dl_exit(1);
-  };
+       /* Get the address of the GOT entry */
+       new_addr = _dl_find_hash(strtab + symtab[symtab_index].st_name, 
+               tpnt->symbol_scope, (int) got_addr, tpnt, 0);
+       if (!new_addr) {
+               _dl_fdprintf(2, "%s: can't resolve symbol '%s'\n", 
+                       _dl_progname, strtab + symtab[symtab_index].st_name);
+               _dl_exit(1);
+       };
 /* #define DEBUG_LIBRARY */
 #ifdef DEBUG_LIBRARY
-  if((unsigned int) got_addr < 0x40000000) {
-    _dl_fdprintf(2, "Calling library function: %s\n",
-              strtab + symtab[symtab_index].st_name);
-  } else {
-    *got_addr = new_addr;
-  }
+       if ((unsigned int) got_addr < 0x40000000) {
+               _dl_fdprintf(2, "Calling library function: %s\n", 
+                       strtab + symtab[symtab_index].st_name);
+       } else {
+               *got_addr = new_addr;
+       }
 #else
-  *got_addr = new_addr;
+       *got_addr = new_addr;
 #endif
-  return (unsigned int) new_addr;
+       return (unsigned int) new_addr;
 }
 
-void _dl_parse_lazy_relocation_information(struct elf_resolve * tpnt, int rel_addr,
-       int rel_size, int type){
-  int i;
-  char * strtab;
-  int reloc_type;
-  int symtab_index;
-  struct elf32_sym * symtab; 
-  struct elf32_rel * rpnt;
-  unsigned int * reloc_addr;
-
-  /* Now parse the relocation information */
-  rpnt = (struct elf32_rel *) (rel_addr + tpnt->loadaddr);
-  rel_size = rel_size / sizeof(struct elf32_rel);
-
-  symtab =  (struct elf32_sym *) (tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr);
-  strtab = ( char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
-
-  for(i=0; i< rel_size; i++, rpnt++){
-    reloc_addr = (int *) (tpnt->loadaddr + (int)rpnt->r_offset);
-    reloc_type = ELF32_R_TYPE(rpnt->r_info);
-    symtab_index = ELF32_R_SYM(rpnt->r_info);
-
-    /* When the dynamic linker bootstrapped itself, it resolved some symbols.
-       Make sure we do not do them again */
-    if(!symtab_index && tpnt->libtype == program_interpreter) continue;
-    if(symtab_index && tpnt->libtype == program_interpreter &&
-       _dl_symbol(strtab + symtab[symtab_index].st_name))
-      continue;
-
-    switch(reloc_type){
-    case R_386_NONE: break;
-    case R_386_JMP_SLOT:
-      *reloc_addr += (unsigned int) tpnt->loadaddr;
-      break;
-    default:
-      _dl_fdprintf(2, "%s: (LAZY) can't handle reloc type ", _dl_progname);
+void _dl_parse_lazy_relocation_information(struct elf_resolve *tpnt, 
+       int rel_addr, int rel_size, int type)
+{
+       int i;
+       char *strtab;
+       int reloc_type;
+       int symtab_index;
+       Elf32_Sym *symtab;
+       Elf32_Rel *rpnt;
+       unsigned int *reloc_addr;
+
+       /* Now parse the relocation information */
+       rpnt = (Elf32_Rel *) (rel_addr + tpnt->loadaddr);
+       rel_size = rel_size / sizeof(Elf32_Rel);
+
+       symtab =
+               (Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr);
+       strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
+
+       for (i = 0; i < rel_size; i++, rpnt++) {
+               reloc_addr = (int *) (tpnt->loadaddr + (int) rpnt->r_offset);
+               reloc_type = ELF32_R_TYPE(rpnt->r_info);
+               symtab_index = ELF32_R_SYM(rpnt->r_info);
+
+               /* When the dynamic linker bootstrapped itself, it resolved some symbols.
+                  Make sure we do not do them again */
+               if (!symtab_index && tpnt->libtype == program_interpreter)
+                       continue;
+               if (symtab_index && tpnt->libtype == program_interpreter &&
+                       _dl_symbol(strtab + symtab[symtab_index].st_name))
+                       continue;
+
+               switch (reloc_type) {
+               case R_386_NONE:
+                       break;
+               case R_386_JMP_SLOT:
+                       *reloc_addr += (unsigned int) tpnt->loadaddr;
+                       break;
+               default:
+                       _dl_fdprintf(2, "%s: (LAZY) can't handle reloc type ", 
+                               _dl_progname);
 #ifdef VERBOSE_DLINKER
-      _dl_fdprintf(2, "%s ", _dl_reltypes[reloc_type]);
+                       _dl_fdprintf(2, "%s ", _dl_reltypes[reloc_type]);
 #endif
-      if(symtab_index) _dl_fdprintf(2, "'%s'\n",
-                                 strtab + symtab[symtab_index].st_name);
-      _dl_exit(1);
-    };
-  };
+                       if (symtab_index)
+                               _dl_fdprintf(2, "'%s'\n", strtab + symtab[symtab_index].st_name);
+                       _dl_exit(1);
+               };
+       };
 }
 
-int _dl_parse_relocation_information(struct elf_resolve * tpnt, int rel_addr,
-       int rel_size, int type){
-  int i;
-  char * strtab;
-  int reloc_type;
-  int goof = 0;
-  struct elf32_sym * symtab; 
-  struct elf32_rel * rpnt;
-  unsigned int * reloc_addr;
-  unsigned int symbol_addr;
-  int symtab_index;
-  /* Now parse the relocation information */
-
-  rpnt = (struct elf32_rel *) (rel_addr + tpnt->loadaddr);
-  rel_size = rel_size / sizeof(struct elf32_rel);
-
-  symtab =  (struct elf32_sym *) (tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr);
-  strtab = ( char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
-
-  for(i=0; i< rel_size; i++, rpnt++){
-    reloc_addr = (int *) (tpnt->loadaddr + (int)rpnt->r_offset);
-    reloc_type = ELF32_R_TYPE(rpnt->r_info);
-    symtab_index = ELF32_R_SYM(rpnt->r_info);
-    symbol_addr = 0;
-
-    if(!symtab_index && tpnt->libtype == program_interpreter) continue;
-
-    if(symtab_index) {
-
-      if(tpnt->libtype == program_interpreter && 
-        _dl_symbol(strtab + symtab[symtab_index].st_name))
-       continue;
-
-      symbol_addr = (unsigned int) 
-       _dl_find_hash(strtab + symtab[symtab_index].st_name,
-                             tpnt->symbol_scope, (int) reloc_addr, 
-                     (reloc_type == R_386_JMP_SLOT ? tpnt : NULL), 0);
-
-      /*
-       * We want to allow undefined references to weak symbols - this might
-       * have been intentional.  We should not be linking local symbols
-       * here, so all bases should be covered.
-       */
-      if(!symbol_addr && 
-        ELF32_ST_BIND(symtab[symtab_index].st_info) == STB_GLOBAL) {
-       _dl_fdprintf(2, "%s: can't resolve symbol '%s'\n",
-                  _dl_progname, strtab + symtab[symtab_index].st_name);
-       goof++;
-      }
-    }
-    switch(reloc_type){
-    case R_386_NONE:
-      break;
-    case R_386_32:
-      *reloc_addr += symbol_addr;
-      break;
-    case R_386_PC32:
-      *reloc_addr += symbol_addr - (unsigned int) reloc_addr;
-      break;
-    case R_386_GLOB_DAT:
-    case R_386_JMP_SLOT:
-      *reloc_addr = symbol_addr;
-      break;
-    case R_386_RELATIVE:
-      *reloc_addr += (unsigned int) tpnt->loadaddr;
-      break;
-    case R_386_COPY:
-#if 0  /* Do this later */
-      _dl_fdprintf(2, "Doing copy for symbol ");
-      if(symtab_index) _dl_fdprintf(2, strtab + symtab[symtab_index].st_name);
-      _dl_fdprintf(2, "\n");
-      _dl_memcpy((void *) symtab[symtab_index].st_value,
-                (void *) symbol_addr, 
-                symtab[symtab_index].st_size);
+int _dl_parse_relocation_information(struct elf_resolve *tpnt, 
+       int rel_addr, int rel_size, int type)
+{
+       int i;
+       char *strtab;
+       int reloc_type;
+       int goof = 0;
+       Elf32_Sym *symtab;
+       Elf32_Rel *rpnt;
+       unsigned int *reloc_addr;
+       unsigned int symbol_addr;
+       int symtab_index;
+
+       /* Now parse the relocation information */
+
+       rpnt = (Elf32_Rel *) (rel_addr + tpnt->loadaddr);
+       rel_size = rel_size / sizeof(Elf32_Rel);
+
+       symtab =
+               (Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr);
+       strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
+
+       for (i = 0; i < rel_size; i++, rpnt++) {
+               reloc_addr = (int *) (tpnt->loadaddr + (int) rpnt->r_offset);
+               reloc_type = ELF32_R_TYPE(rpnt->r_info);
+               symtab_index = ELF32_R_SYM(rpnt->r_info);
+               symbol_addr = 0;
+
+               if (!symtab_index && tpnt->libtype == program_interpreter)
+                       continue;
+
+               if (symtab_index) {
+
+                       if (tpnt->libtype == program_interpreter &&
+                               _dl_symbol(strtab + symtab[symtab_index].st_name))
+                               continue;
+
+                       symbol_addr = (unsigned int)
+                               _dl_find_hash(strtab + symtab[symtab_index].st_name, 
+                                       tpnt->symbol_scope, (int) reloc_addr, 
+                                       (reloc_type == R_386_JMP_SLOT ? tpnt : NULL), 0);
+
+                       /*
+                        * We want to allow undefined references to weak symbols - this might
+                        * have been intentional.  We should not be linking local symbols
+                        * here, so all bases should be covered.
+                        */
+                       if (!symbol_addr &&
+                               ELF32_ST_BIND(symtab[symtab_index].st_info) ==
+                               STB_GLOBAL) {
+                               _dl_fdprintf(2, "%s: can't resolve symbol '%s'\n", 
+                                       _dl_progname, strtab + symtab[symtab_index].st_name);
+                               goof++;
+                       }
+               }
+               switch (reloc_type) {
+               case R_386_NONE:
+                       break;
+               case R_386_32:
+                       *reloc_addr += symbol_addr;
+                       break;
+               case R_386_PC32:
+                       *reloc_addr += symbol_addr - (unsigned int) reloc_addr;
+                       break;
+               case R_386_GLOB_DAT:
+               case R_386_JMP_SLOT:
+                       *reloc_addr = symbol_addr;
+                       break;
+               case R_386_RELATIVE:
+                       *reloc_addr += (unsigned int) tpnt->loadaddr;
+                       break;
+               case R_386_COPY:
+#if 0                                                  
+                       /* Do this later */
+                       _dl_fdprintf(2, "Doing copy for symbol ");
+                       if (symtab_index) _dl_fdprintf(2, strtab + symtab[symtab_index].st_name);
+                       _dl_fdprintf(2, "\n");
+                       _dl_memcpy((void *) symtab[symtab_index].st_value, 
+                               (void *) symbol_addr, symtab[symtab_index].st_size);
 #endif
-      break;
-    default:
-      _dl_fdprintf(2, "%s: can't handle reloc type ", _dl_progname);
+                       break;
+               default:
+                       _dl_fdprintf(2, "%s: can't handle reloc type ", _dl_progname);
 #ifdef VERBOSE_DLINKER
-      _dl_fdprintf(2, "%s ", _dl_reltypes[reloc_type]);
+                       _dl_fdprintf(2, "%s ", _dl_reltypes[reloc_type]);
 #endif
-      if (symtab_index)
-       _dl_fdprintf(2, "'%s'\n", strtab + symtab[symtab_index].st_name);
-      _dl_exit(1);
-    };
+                       if (symtab_index)
+                               _dl_fdprintf(2, "'%s'\n", strtab + symtab[symtab_index].st_name);
+                       _dl_exit(1);
+               };
 
-  };
-  return goof;
+       };
+       return goof;
 }
 
 
@@ -259,57 +266,57 @@ int _dl_parse_relocation_information(struct elf_resolve * tpnt, int rel_addr,
 /* No, there are cases where the SVr4 linker fails to emit COPY relocs
    at all */
 
-int _dl_parse_copy_information(struct dyn_elf * xpnt, int rel_addr,
-       int rel_size, int type)
+int _dl_parse_copy_information(struct dyn_elf *xpnt, int rel_addr, 
+       int rel_size, int type)
 {
-  int i;
-  char * strtab;
-  int reloc_type;
-  int goof = 0;
-  struct elf32_sym * symtab; 
-  struct elf32_rel * rpnt;
-  unsigned int * reloc_addr;
-  unsigned int symbol_addr;
-  struct elf_resolve *tpnt;
-  int symtab_index;
-  /* Now parse the relocation information */
-
-  tpnt = xpnt->dyn;
-  
-  rpnt = (struct elf32_rel *) (rel_addr + tpnt->loadaddr);
-  rel_size = rel_size / sizeof(struct elf32_rel);
-
-  symtab =  (struct elf32_sym *) (tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr);
-  strtab = ( char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
-
-  for(i=0; i< rel_size; i++, rpnt++){
-    reloc_addr = (int *) (tpnt->loadaddr + (int)rpnt->r_offset);
-    reloc_type = ELF32_R_TYPE(rpnt->r_info);
-    if(reloc_type != R_386_COPY) continue;
-    symtab_index = ELF32_R_SYM(rpnt->r_info);
-    symbol_addr = 0;
-    if(!symtab_index && tpnt->libtype == program_interpreter) continue;
-    if(symtab_index) {
-
-      if(tpnt->libtype == program_interpreter && 
-        _dl_symbol(strtab + symtab[symtab_index].st_name))
-       continue;
-
-      symbol_addr = (unsigned int) 
-       _dl_find_hash(strtab + symtab[symtab_index].st_name,
-                             xpnt->next, (int) reloc_addr, NULL, 1);
-      if(!symbol_addr) {
-       _dl_fdprintf(2, "%s: can't resolve symbol '%s'\n",
-                  _dl_progname, strtab + symtab[symtab_index].st_name);
-       goof++;
-      };
-    };
-    if (!goof)
-      _dl_memcpy((char *) symtab[symtab_index].st_value, 
-                (char *) symbol_addr, 
-                symtab[symtab_index].st_size);
-  };
-  return goof;
+       int i;
+       char *strtab;
+       int reloc_type;
+       int goof = 0;
+       Elf32_Sym *symtab;
+       Elf32_Rel *rpnt;
+       unsigned int *reloc_addr;
+       unsigned int symbol_addr;
+       struct elf_resolve *tpnt;
+       int symtab_index;
+
+       /* Now parse the relocation information */
+
+       tpnt = xpnt->dyn;
+
+       rpnt = (Elf32_Rel *) (rel_addr + tpnt->loadaddr);
+       rel_size = rel_size / sizeof(Elf32_Rel);
+
+       symtab = (Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr);
+       strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
+
+       for (i = 0; i < rel_size; i++, rpnt++) {
+               reloc_addr = (int *) (tpnt->loadaddr + (int) rpnt->r_offset);
+               reloc_type = ELF32_R_TYPE(rpnt->r_info);
+               if (reloc_type != R_386_COPY)
+                       continue;
+               symtab_index = ELF32_R_SYM(rpnt->r_info);
+               symbol_addr = 0;
+               if (!symtab_index && tpnt->libtype == program_interpreter)
+                       continue;
+               if (symtab_index) {
+
+                       if (tpnt->libtype == program_interpreter &&
+                               _dl_symbol(strtab + symtab[symtab_index].st_name))
+                               continue;
+
+                       symbol_addr = (unsigned int) _dl_find_hash(strtab + symtab[symtab_index].st_name, 
+                                       xpnt->next, (int) reloc_addr, NULL, 1);
+                       if (!symbol_addr) {
+                               _dl_fdprintf(2, "%s: can't resolve symbol '%s'\n", 
+                                       _dl_progname, strtab + symtab[symtab_index].st_name);
+                               goof++;
+                       };
+               };
+               if (!goof) {
+                       _dl_memcpy((char *) symtab[symtab_index].st_value, 
+                               (char *) symbol_addr, symtab[symtab_index].st_size);
+               }
+       };
+       return goof;
 }
-
-
index a9adb23..3054429 100644 (file)
@@ -1,4 +1,3 @@
-#include <linux/types.h>
 #include <asm/unistd.h>
 
 /* Here are the macros which define how this platform makes
index a9adb23..3054429 100644 (file)
@@ -1,4 +1,3 @@
-#include <linux/types.h>
 #include <asm/unistd.h>
 
 /* Here are the macros which define how this platform makes
index 3b613fb..948a6e1 100644 (file)
  * can transfer control to the user's application.
  */
 
+#include <sys/mman.h>                  // For MAP_ANONYMOUS -- differs between platforms
 #include <stdarg.h>
-#include <linux/types.h>
-#include <linux/fcntl.h>
-#include <linux/unistd.h>
-#include <linux/elf.h>
-#include <linux/mman.h>
+#include "elf.h"
 #include "link.h"
-
 #include "sysdep.h"
 #include "hash.h"
-#include "linuxelf.h"
 #include "syscall.h"
 #include "string.h"
 
 
 #define ALLOW_ZERO_PLTGOT
 
-static char * _dl_malloc_addr, *_dl_mmap_zero;
-char * _dl_library_path = 0; /* Where we look for libraries */
-char *_dl_preload = 0; /* Things to be loaded before the libs. */
+static char *_dl_malloc_addr, *_dl_mmap_zero;
+char *_dl_library_path = 0;            /* Where we look for libraries */
+char *_dl_preload = 0;                 /* Things to be loaded before the libs. */
 char *_dl_progname = "/lib/ld-linux-uclibc.so.1";
-static char * _dl_not_lazy = 0;
-static char * _dl_warn = 0; /* Used by ldd */
-static char * _dl_trace_loaded_objects = 0;
-static int (*_dl_elf_main)(int, char **, char**);
+static char *_dl_not_lazy = 0;
+static char *_dl_warn = 0;             /* Used by ldd */
+static char *_dl_trace_loaded_objects = 0;
+static int (*_dl_elf_main) (int, char **, char **);
 
-static int (*_dl_elf_init)(void);
+static int (*_dl_elf_init) (void);
 
-void * (*_dl_malloc_function)(int size) = NULL;
+void *(*_dl_malloc_function) (int size) = NULL;
 
-struct r_debug * _dl_debug_addr = NULL;
+struct r_debug *_dl_debug_addr = NULL;
 
-unsigned int * _dl_brkp; 
+unsigned int *_dl_brkp;
 
-unsigned int * _dl_envp;
+unsigned int *_dl_envp;
 
 #define DL_MALLOC(SIZE) ((void *) (malloc_buffer += SIZE, malloc_buffer - SIZE))
 /*
@@ -151,19 +146,10 @@ unsigned int * _dl_envp;
   RESULT = hash; \
 }
 extern int _dl_linux_resolve(void);
-extern char * _dl_strdup(const char *);
-extern char * _dl_getenv(char * symbol, char ** envp);
-extern void _dl_unsetenv(char * symbol, char ** envp);
-extern int _dl_fixup(struct elf_resolve * tpnt);
-
-/*
- * Datatype of a relocation on this platform
- */
-#ifdef ELF_USES_RELOCA
-typedef struct elf32_rela ELF_RELOC;
-#else
-typedef struct elf32_rel ELF_RELOC;
-#endif
+extern char *_dl_strdup(const char *);
+extern char *_dl_getenv(char *symbol, char **envp);
+extern void _dl_unsetenv(char *symbol, char **envp);
+extern int _dl_fixup(struct elf_resolve *tpnt);
 
 /*
  * This stub function is used by some debuggers.  The idea is that they
@@ -172,71 +158,72 @@ typedef struct elf32_rel ELF_RELOC;
  */
 void _dl_debug_state()
 {
-  return;
+       return;
 }
 
 void _dl_boot(int args);
 
-void _dl_boot(int args){
-  unsigned int argc;
-  char ** argv, ** envp;
-  int status;
-
-  unsigned int load_addr;
-  unsigned int * got;
-  unsigned int * aux_dat;
-  int goof = 0;
-  struct elfhdr * header;
-  struct elf_resolve * tpnt;
-  struct dyn_elf * rpnt;
-  struct elf_resolve * app_tpnt;
-  unsigned int brk_addr;
-  unsigned int dl_data[AT_EGID+1];
-  unsigned char * malloc_buffer, *mmap_zero;
-  int (*_dl_atexit)(void *);
-  int * lpnt;
-  struct dynamic * dpnt;
-  unsigned int *hash_addr;
-  struct r_debug * debug_addr;
-  unsigned int *chains;
-  int indx;
-  int _dl_secure;
-
-  /* First obtain the information on the stack that tells us more about
-     what binary is loaded, where it is loaded, etc, etc */
-
-  GET_ARGV(aux_dat, args);
-  argc = *(aux_dat - 1);
-  argv = (char **) aux_dat;
-  aux_dat += argc;  /* Skip over the argv pointers */
-  aux_dat++;  /* Skip over NULL at end of argv */
-  envp = (char **) aux_dat;
-  while(*aux_dat) aux_dat++;  /* Skip over the envp pointers */
-  aux_dat++;  /* Skip over NULL at end of envp */
-  dl_data[AT_UID] = -1; /* check later to see if it is changed */
-  while(*aux_dat)
-    {
-      unsigned int * ad1;
-      ad1 = aux_dat + 1;
-      if( *aux_dat <= AT_EGID ) dl_data[*aux_dat] = *ad1;
-      aux_dat += 2;
-    }
-
-  /* Next, locate the GOT */
-
-  load_addr = dl_data[AT_BASE];
-
-  GET_GOT(got);
-  dpnt = (struct dynamic *) (*got + load_addr);
-  /* OK, time for another hack.  Now call mmap to get a page of writable
-     memory that can be used for a temporary malloc.  We do not know brk
-     yet, so we cannot use real malloc. */
-
-  {
-    /* This hack is to work around a suspected asm bug in gcc-2.7.0 */
-    //int zfileno;
-//#define ZFILENO ((-1 & (~zfileno)) | zfileno)
+void _dl_boot(int args)
+{
+       unsigned int argc;
+       char **argv, **envp;
+       int status;
+
+       unsigned int load_addr;
+       unsigned int *got;
+       unsigned int *aux_dat;
+       int goof = 0;
+       elfhdr *header;
+       struct elf_resolve *tpnt;
+       struct dyn_elf *rpnt;
+       struct elf_resolve *app_tpnt;
+       unsigned int brk_addr;
+       unsigned int dl_data[AT_EGID + 1];
+       unsigned char *malloc_buffer, *mmap_zero;
+       int (*_dl_atexit) (void *);
+       int *lpnt;
+       Elf32_Dyn *dpnt;
+       unsigned int *hash_addr;
+       struct r_debug *debug_addr;
+       unsigned int *chains;
+       int indx;
+       int _dl_secure;
+
+       /* First obtain the information on the stack that tells us more about
+          what binary is loaded, where it is loaded, etc, etc */
+
+       GET_ARGV(aux_dat, args);
+       argc = *(aux_dat - 1);
+       argv = (char **) aux_dat;
+       aux_dat += argc;                        /* Skip over the argv pointers */
+       aux_dat++;                              /* Skip over NULL at end of argv */
+       envp = (char **) aux_dat;
+       while (*aux_dat)
+               aux_dat++;                      /* Skip over the envp pointers */
+       aux_dat++;                              /* Skip over NULL at end of envp */
+       dl_data[AT_UID] = -1;                   /* check later to see if it is changed */
+       while (*aux_dat) 
+       {
+               unsigned int *ad1;
+
+               ad1 = aux_dat + 1;
+               if (*aux_dat <= AT_EGID)
+                       dl_data[*aux_dat] = *ad1;
+               aux_dat += 2;
+       }
+
+       /* Next, locate the GOT */
+
+       load_addr = dl_data[AT_BASE];
+
+       GET_GOT(got);
+       dpnt = (Elf32_Dyn *) (*got + load_addr);
+
+       /* OK, time for another hack.  Now call mmap to get a page of writable
+          memory that can be used for a temporary malloc.  We do not know brk
+          yet, so we cannot use real malloc. */
+
+       {
 #define ZFILENO -1
 
 #ifndef MAP_ANONYMOUS
@@ -247,178 +234,195 @@ void _dl_boot(int args){
 #endif
 #endif
 
-    /* See if we need to relocate this address */
-    mmap_zero = malloc_buffer = (unsigned char *) _dl_mmap((void*) 0, 4096,
-                            PROT_READ | PROT_WRITE, 
-                            MAP_PRIVATE | MAP_ANONYMOUS, ZFILENO, 0);
-    if(_dl_mmap_check_error(mmap_zero)) {
-       SEND_STDERR("dl_boot: mmap of /dev/zero failed!\n");
-       _dl_exit(13);
-    }
-  }
-
-  tpnt = DL_MALLOC(sizeof(struct elf_resolve));
-  REALIGN();
-  _dl_memset (tpnt, 0, sizeof (*tpnt));
-  app_tpnt = DL_MALLOC(sizeof(struct elf_resolve));
-  REALIGN();
-  _dl_memset (app_tpnt, 0, sizeof (*app_tpnt));
-
-  /*
-   * This is used by gdb to locate the chain of shared libraries that are currently loaded.
-   */
-  debug_addr = DL_MALLOC(sizeof(struct r_debug));
-  REALIGN();
-  _dl_memset (debug_addr, 0, sizeof (*debug_addr));
-
-  /* OK, that was easy.  Next scan the DYNAMIC section of the image.
-     We are only doing ourself right now - we will have to do the rest later */
-
-  while(dpnt->d_tag)
-    {
-      tpnt->dynamic_info[dpnt->d_tag] = dpnt->d_un.d_val;
-      if(dpnt->d_tag == DT_TEXTREL ||
-        SVR4_BUGCOMPAT) tpnt->dynamic_info[DT_TEXTREL] = 1;
-      dpnt++;
-    }
-
-  {
-    struct elf_phdr * ppnt;
-    int i;
-    
-    ppnt = (struct elf_phdr *) dl_data[AT_PHDR];
-    for(i=0; i<dl_data[AT_PHNUM]; i++, ppnt++)
-      if(ppnt->p_type == PT_DYNAMIC) {
-       dpnt = (struct dynamic *) ppnt->p_vaddr;
-       while(dpnt->d_tag)
-         {
-           if(dpnt->d_tag > DT_JMPREL) {dpnt++; continue; }
-           app_tpnt->dynamic_info[dpnt->d_tag] = dpnt->d_un.d_val;
-           if(dpnt->d_tag == DT_DEBUG) dpnt->d_un.d_val = (int) debug_addr;
-           if(dpnt->d_tag == DT_TEXTREL ||
-              SVR4_BUGCOMPAT) app_tpnt->dynamic_info[DT_TEXTREL] = 1;
-           dpnt++;
-         }
-      }
-  }
-
-  /* Get some more of the information that we will need to dynamicly link
-     this module to itself */
-
-  hash_addr = (unsigned int *) (tpnt->dynamic_info[DT_HASH]+load_addr);
-  tpnt->nbucket = *hash_addr++;
-  tpnt->nchain = *hash_addr++;
-  tpnt->elf_buckets = hash_addr;
-  hash_addr += tpnt->nbucket;
-  chains = hash_addr;
-
-  /* Ugly, ugly.  We need to call mprotect to change the protection of
-     the text pages so that we can do the dynamic linking.  We can set the
-     protection back again once we are done */
-
-  {
-    struct elf_phdr * ppnt;
-    int i;
-
-    /* First cover the shared library/dynamic linker. */
-    if(tpnt->dynamic_info[DT_TEXTREL]) {
-      header = (struct elfhdr *) dl_data[AT_BASE];         
-      ppnt = (struct elf_phdr *) (dl_data[AT_BASE] + header->e_phoff);
-      for(i=0; i<header->e_phnum ; i++, ppnt++) {
-       if(ppnt->p_type == PT_LOAD && !(ppnt->p_flags & PF_W))
-               _dl_mprotect((void *) (load_addr + (ppnt->p_vaddr & 0xfffff000)),
-                             (ppnt->p_vaddr & 0xfff) + (unsigned int) ppnt->p_filesz,
-                             PROT_READ | PROT_WRITE | PROT_EXEC);
-      }
-    }
-    
-    /* Now cover the application program. */
-    if(app_tpnt->dynamic_info[DT_TEXTREL]) {
-      ppnt = (struct elf_phdr *) dl_data[AT_PHDR];
-      for(i=0; i<dl_data[AT_PHNUM]; i++, ppnt++) {
-       if(ppnt->p_type == PT_LOAD && !(ppnt->p_flags & PF_W))
-         _dl_mprotect((void *) (ppnt->p_vaddr & 0xfffff000),
-                      (ppnt->p_vaddr & 0xfff) + (unsigned int) ppnt->p_filesz,
-                      PROT_READ | PROT_WRITE | PROT_EXEC);
-      }
-    }
-  }
-
-  /* OK, now do the relocations.  We do not do a lazy binding here, so
-   that once we are done, we have considerably more flexibility. */
-
-  goof = 0;
-  for(indx=0; indx < 2; indx++)
-    {
-      int i;
-      ELF_RELOC * rpnt;
-      unsigned int * reloc_addr;
-      unsigned int symbol_addr;
-      int symtab_index;
-      unsigned int rel_addr, rel_size;
-
-  
-#ifdef ELF_USES_RELOCA
-      rel_addr = (indx ? tpnt->dynamic_info[DT_JMPREL] : tpnt->dynamic_info[DT_RELA]);
-      rel_size = (indx ? tpnt->dynamic_info[DT_PLTRELSZ] : tpnt->dynamic_info[DT_RELASZ]);
-#else
-      rel_addr = (indx ? tpnt->dynamic_info[DT_JMPREL] : tpnt->dynamic_info[DT_REL]);
-      rel_size = (indx ? tpnt->dynamic_info[DT_PLTRELSZ] : tpnt->dynamic_info[DT_RELSZ]);
-#endif
+               /* See if we need to relocate this address */
+               mmap_zero = malloc_buffer = (unsigned char *) _dl_mmap((void *) 0, 4096, 
+                       PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, ZFILENO, 0);
+               if (_dl_mmap_check_error(mmap_zero)) {
+                       SEND_STDERR("dl_boot: mmap of /dev/zero failed!\n");
+                       _dl_exit(13);
+               }
+       }
 
+       tpnt = DL_MALLOC(sizeof(struct elf_resolve));
+       REALIGN();
+       _dl_memset(tpnt, 0, sizeof(*tpnt));
+       app_tpnt = DL_MALLOC(sizeof(struct elf_resolve));
+       REALIGN();
+       _dl_memset(app_tpnt, 0, sizeof(*app_tpnt));
 
-      if(!rel_addr) continue;
+       /*
+        * This is used by gdb to locate the chain of shared libraries that are currently loaded.
+        */
+       debug_addr = DL_MALLOC(sizeof(struct r_debug));
+       REALIGN();
+       _dl_memset(debug_addr, 0, sizeof(*debug_addr));
+
+       /* OK, that was easy.  Next scan the DYNAMIC section of the image.
+          We are only doing ourself right now - we will have to do the rest later */
+
+       while (dpnt->d_tag) {
+               tpnt->dynamic_info[dpnt->d_tag] = dpnt->d_un.d_val;
+               if (dpnt->d_tag == DT_TEXTREL || SVR4_BUGCOMPAT)
+                       tpnt->dynamic_info[DT_TEXTREL] = 1;
+               dpnt++;
+       }
 
-      /* Now parse the relocation information */
-      rpnt = (ELF_RELOC *) (rel_addr + load_addr);
-      for(i=0; i< rel_size; i+=sizeof(ELF_RELOC), rpnt++){
-       reloc_addr = (int *) (load_addr + (int)rpnt->r_offset);
-       symtab_index = ELF32_R_SYM(rpnt->r_info);
-       symbol_addr = 0;
-       if(symtab_index) {
-         char * strtab;
-         struct elf32_sym * symtab;
+       {
+               elf_phdr *ppnt;
+               int i;
+
+               ppnt = (elf_phdr *) dl_data[AT_PHDR];
+               for (i = 0; i < dl_data[AT_PHNUM]; i++, ppnt++)
+                       if (ppnt->p_type == PT_DYNAMIC) {
+                               dpnt = (Elf32_Dyn *) ppnt->p_vaddr;
+                               while (dpnt->d_tag) {
+                                       if (dpnt->d_tag > DT_JMPREL) {
+                                               dpnt++;
+                                               continue;
+                                       }
+                                       app_tpnt->dynamic_info[dpnt->d_tag] = dpnt->d_un.d_val;
+                                       if (dpnt->d_tag == DT_DEBUG)
+                                               dpnt->d_un.d_val = (int) debug_addr;
+                                       if (dpnt->d_tag == DT_TEXTREL || SVR4_BUGCOMPAT)
+                                               app_tpnt->dynamic_info[DT_TEXTREL] = 1;
+                                       dpnt++;
+                               }
+                       }
+       }
 
-         symtab = (struct elf32_sym *) (tpnt->dynamic_info[DT_SYMTAB]+load_addr);
-         strtab = (char *) (tpnt->dynamic_info[DT_STRTAB]+load_addr);
+       /* Get some more of the information that we will need to dynamicly link
+          this module to itself */
 
-         /* We only do a partial dynamic linking right now.  The user
-            is not supposed to redefine any symbols that start with
-            a '_', so we can do this with confidence. */
+       hash_addr = (unsigned int *) (tpnt->dynamic_info[DT_HASH] + load_addr);
+       tpnt->nbucket = *hash_addr++;
+       tpnt->nchain = *hash_addr++;
+       tpnt->elf_buckets = hash_addr;
+       hash_addr += tpnt->nbucket;
+       chains = hash_addr;
 
-         if (!_dl_symbol(strtab + symtab[symtab_index].st_name)) continue;
+       /* Ugly, ugly.  We need to call mprotect to change the protection of
+          the text pages so that we can do the dynamic linking.  We can set the
+          protection back again once we are done */
 
-         symbol_addr = load_addr + symtab[symtab_index].st_value;
+       {
+               elf_phdr *ppnt;
+               int i;
+
+               /* First cover the shared library/dynamic linker. */
+               if (tpnt->dynamic_info[DT_TEXTREL]) {
+                       header = (elfhdr *) dl_data[AT_BASE];
+                       ppnt = (elf_phdr *) (dl_data[AT_BASE] + header->e_phoff);
+                       for (i = 0; i < header->e_phnum; i++, ppnt++) {
+                               if (ppnt->p_type == PT_LOAD && !(ppnt->p_flags & PF_W))
+                                       _dl_mprotect((void *) (load_addr + 
+                                               (ppnt->p_vaddr & 0xfffff000)), 
+                                               (ppnt->p_vaddr & 0xfff) + 
+                                               (unsigned int) ppnt->p_filesz, 
+                                               PROT_READ | PROT_WRITE | PROT_EXEC);
+                       }
+               }
 
-         if(!symbol_addr) {
-           /*
-            * This will segfault - you cannot call a function until
-            * we have finished the relocations.
-            */
-           SEND_STDERR("ELF dynamic loader - unable to self-bootstrap - symbol ");
-           SEND_STDERR(strtab + symtab[symtab_index].st_name);
-           SEND_STDERR(" undefined.\n");
-           goof++;
-         }
+               /* Now cover the application program. */
+               if (app_tpnt->dynamic_info[DT_TEXTREL]) {
+                       ppnt = (elf_phdr *) dl_data[AT_PHDR];
+                       for (i = 0; i < dl_data[AT_PHNUM]; i++, ppnt++) {
+                               if (ppnt->p_type == PT_LOAD && !(ppnt->p_flags & PF_W))
+                                       _dl_mprotect((void *) (ppnt->p_vaddr & 0xfffff000), 
+                                               (ppnt->p_vaddr & 0xfff) + 
+                                               (unsigned int) ppnt->p_filesz, 
+                                               PROT_READ | PROT_WRITE | PROT_EXEC);
+                       }
+               }
        }
-       /*
-        * Use this machine-specific macro to perform the actual relocation.
-        */
-       PERFORM_BOOTSTRAP_RELOC(rpnt, reloc_addr, symbol_addr, load_addr);
-      }
-    }
 
-  if (goof)    _dl_exit(14);
+       /* OK, now do the relocations.  We do not do a lazy binding here, so
+          that once we are done, we have considerably more flexibility. */
+
+       goof = 0;
+       for (indx = 0; indx < 2; indx++) {
+               int i;
+               ELF_RELOC *rpnt;
+               unsigned int *reloc_addr;
+               unsigned int symbol_addr;
+               int symtab_index;
+               unsigned int rel_addr, rel_size;
+
+
+#ifdef ELF_USES_RELOCA
+               rel_addr =
+                       (indx ? tpnt->dynamic_info[DT_JMPREL] : tpnt->
+                        dynamic_info[DT_RELA]);
+               rel_size =
+                       (indx ? tpnt->dynamic_info[DT_PLTRELSZ] : tpnt->
+                        dynamic_info[DT_RELASZ]);
+#else
+               rel_addr =
+                       (indx ? tpnt->dynamic_info[DT_JMPREL] : tpnt->
+                        dynamic_info[DT_REL]);
+               rel_size =
+                       (indx ? tpnt->dynamic_info[DT_PLTRELSZ] : tpnt->
+                        dynamic_info[DT_RELSZ]);
+#endif
+
 
-  /* OK, at this point we have a crude malloc capability.  Start to build
-     the tables of the modules that are required for this beast to run.
-     We start with the basic executable, and then go from there.  Eventually
-     we will run across ourself, and we will need to properly deal with that
-     as well. */
+               if (!rel_addr)
+                       continue;
+
+               /* Now parse the relocation information */
+               rpnt = (ELF_RELOC *) (rel_addr + load_addr);
+               for (i = 0; i < rel_size; i += sizeof(ELF_RELOC), rpnt++) {
+                       reloc_addr = (int *) (load_addr + (int) rpnt->r_offset);
+                       symtab_index = ELF32_R_SYM(rpnt->r_info);
+                       symbol_addr = 0;
+                       if (symtab_index) {
+                               char *strtab;
+                               Elf32_Sym *symtab;
+
+                               symtab = (Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB] +
+                                                                  load_addr);
+                               strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + load_addr);
+
+                               /* We only do a partial dynamic linking right now.  The user
+                                  is not supposed to redefine any symbols that start with
+                                  a '_', so we can do this with confidence. */
+
+                               if (!_dl_symbol(strtab + symtab[symtab_index].st_name))
+                                       continue;
+
+                               symbol_addr = load_addr + symtab[symtab_index].st_value;
+
+                               if (!symbol_addr) {
+                                       /*
+                                        * This will segfault - you cannot call a function until
+                                        * we have finished the relocations.
+                                        */
+                                       SEND_STDERR("ELF dynamic loader - unable to "
+                                               "self-bootstrap - symbol ");
+                                       SEND_STDERR(strtab + symtab[symtab_index].st_name);
+                                       SEND_STDERR(" undefined.\n");
+                                       goof++;
+                               }
+                       }
+                       /*
+                        * Use this machine-specific macro to perform the actual relocation.
+                        */
+                       PERFORM_BOOTSTRAP_RELOC(rpnt, reloc_addr, symbol_addr, load_addr);
+               }
+       }
+
+       if (goof) {
+               _dl_exit(14);
+       }
 
-  _dl_malloc_addr = malloc_buffer;
+       /* OK, at this point we have a crude malloc capability.  Start to build
+          the tables of the modules that are required for this beast to run.
+          We start with the basic executable, and then go from there.  Eventually
+          we will run across ourself, and we will need to properly deal with that
+          as well. */
 
-  _dl_mmap_zero = mmap_zero;
+       _dl_malloc_addr = malloc_buffer;
+
+       _dl_mmap_zero = mmap_zero;
 /*  tpnt = _dl_malloc(sizeof(struct elf_resolve)); */
 
 /* Now we have done the mandatory linking of some things.  We are now
@@ -426,573 +430,594 @@ void _dl_boot(int args){
    fixed up by now.  Still no function calls outside of this library ,
    since the dynamic resolver is not yet ready. */
 
-  lpnt = (int *) (tpnt->dynamic_info[DT_PLTGOT] + load_addr);
-  INIT_GOT(lpnt, tpnt);
-
-  /* OK, this was a big step, now we need to scan all of the user images
-     and load them properly. */
-
-  tpnt->next = 0;
-  tpnt->libname = 0;
-  tpnt->libtype = program_interpreter;
-
-  { struct elfhdr * epnt;
-    struct elf_phdr * ppnt;
-    int i;
-
-    epnt = (struct elfhdr *) dl_data[AT_BASE];
-    tpnt->n_phent = epnt->e_phnum;
-    tpnt->ppnt = ppnt = (struct elf_phdr *) (load_addr + epnt->e_phoff);
-    for(i=0;i < epnt->e_phnum; i++, ppnt++){
-      if(ppnt->p_type == PT_DYNAMIC) {
-       tpnt->dynamic_addr = ppnt->p_vaddr + load_addr;
-       tpnt->dynamic_size = ppnt->p_filesz;
-      }
-    }
-  }
-
-  tpnt->chains = chains;
-  tpnt->loadaddr = (char *) load_addr;
-
-  brk_addr = 0;
-  rpnt = NULL;
-
-  /* At this point we are now free to examine the user application,
-     and figure out which libraries are supposed to be called.  Until
-     we have this list, we will not be completely ready for dynamic linking */
-
-  {
-    struct elf_phdr * ppnt;
-    int i;
-
-    ppnt = (struct elf_phdr *) dl_data[AT_PHDR];
-    for(i=0; i<dl_data[AT_PHNUM]; i++, ppnt++) {
-      if(ppnt->p_type == PT_LOAD) {
-       if(ppnt->p_vaddr + ppnt->p_memsz > brk_addr) 
-         brk_addr = ppnt->p_vaddr + ppnt->p_memsz;
-      }
-      if(ppnt->p_type == PT_DYNAMIC) {
+       lpnt = (int *) (tpnt->dynamic_info[DT_PLTGOT] + load_addr);
+       INIT_GOT(lpnt, tpnt);
+
+       /* OK, this was a big step, now we need to scan all of the user images
+          and load them properly. */
+
+       tpnt->next = 0;
+       tpnt->libname = 0;
+       tpnt->libtype = program_interpreter;
+
+       {
+               elfhdr *epnt;
+               elf_phdr *ppnt;
+               int i;
+
+               epnt = (elfhdr *) dl_data[AT_BASE];
+               tpnt->n_phent = epnt->e_phnum;
+               tpnt->ppnt = ppnt = (elf_phdr *) (load_addr + epnt->e_phoff);
+               for (i = 0; i < epnt->e_phnum; i++, ppnt++) {
+                       if (ppnt->p_type == PT_DYNAMIC) {
+                               tpnt->dynamic_addr = ppnt->p_vaddr + load_addr;
+                               tpnt->dynamic_size = ppnt->p_filesz;
+                       }
+               }
+       }
+
+       tpnt->chains = chains;
+       tpnt->loadaddr = (char *) load_addr;
+
+       brk_addr = 0;
+       rpnt = NULL;
+
+       /* At this point we are now free to examine the user application,
+          and figure out which libraries are supposed to be called.  Until
+          we have this list, we will not be completely ready for dynamic linking */
+
+       {
+               elf_phdr *ppnt;
+               int i;
+
+               ppnt = (elf_phdr *) dl_data[AT_PHDR];
+               for (i = 0; i < dl_data[AT_PHNUM]; i++, ppnt++) {
+                       if (ppnt->p_type == PT_LOAD) {
+                               if (ppnt->p_vaddr + ppnt->p_memsz > brk_addr)
+                                       brk_addr = ppnt->p_vaddr + ppnt->p_memsz;
+                       }
+                       if (ppnt->p_type == PT_DYNAMIC) {
 #ifndef ALLOW_ZERO_PLTGOT
-       /* make sure it's really there. */
-       if (app_tpnt->dynamic_info[DT_PLTGOT] == 0) continue;
+                               /* make sure it's really there. */
+                               if (app_tpnt->dynamic_info[DT_PLTGOT] == 0)
+                                       continue;
 #endif
-       /* OK, we have what we need - slip this one into the list. */
-       app_tpnt = _dl_add_elf_hash_table("", 0, 
-                           app_tpnt->dynamic_info, ppnt->p_vaddr, ppnt->p_filesz);
-       _dl_loaded_modules->libtype = elf_executable;
-       _dl_loaded_modules->ppnt = (struct elf_phdr *) dl_data[AT_PHDR];
-       _dl_loaded_modules->n_phent = dl_data[AT_PHNUM];
-       _dl_symbol_tables = rpnt = 
-          (struct dyn_elf *) _dl_malloc(sizeof(struct dyn_elf));
-       _dl_memset (rpnt, 0, sizeof (*rpnt));
-       rpnt->dyn = _dl_loaded_modules;
-       app_tpnt->usage_count++;
-       app_tpnt->symbol_scope = _dl_symbol_tables;
-       lpnt = (int *) (app_tpnt->dynamic_info[DT_PLTGOT]);
+                               /* OK, we have what we need - slip this one into the list. */
+                               app_tpnt = _dl_add_elf_hash_table("", 0, 
+                                       app_tpnt->dynamic_info, ppnt->p_vaddr, ppnt->p_filesz);
+                               _dl_loaded_modules->libtype = elf_executable;
+                               _dl_loaded_modules->ppnt = (elf_phdr *) dl_data[AT_PHDR];
+                               _dl_loaded_modules->n_phent = dl_data[AT_PHNUM];
+                               _dl_symbol_tables = rpnt =
+                                       (struct dyn_elf *) _dl_malloc(sizeof(struct dyn_elf));
+                               _dl_memset(rpnt, 0, sizeof(*rpnt));
+                               rpnt->dyn = _dl_loaded_modules;
+                               app_tpnt->usage_count++;
+                               app_tpnt->symbol_scope = _dl_symbol_tables;
+                               lpnt = (int *) (app_tpnt->dynamic_info[DT_PLTGOT]);
 #ifdef ALLOW_ZERO_PLTGOT
-       if (lpnt)
+                               if (lpnt)
 #endif
-         INIT_GOT(lpnt, _dl_loaded_modules);
-      }
-      if(ppnt->p_type == PT_INTERP) { /* OK, fill this in - we did not have
-                                        this before */
-       tpnt->libname =  _dl_strdup((char *) ppnt->p_offset +(dl_data[AT_PHDR] & 0xfffff000));
-      }
-    }
-  }
-
-  if (argv[0])
-    _dl_progname = argv[0];
-
-  /* Now we need to figure out what kind of options are selected.
-   Note that for SUID programs we ignore the settings in LD_LIBRARY_PATH */
-  {
-    _dl_not_lazy = _dl_getenv("LD_BIND_NOW",envp);
-
-    if ( (dl_data[AT_UID] == -1 && _dl_suid_ok()) ||
-        (dl_data[AT_UID] != -1 && dl_data[AT_UID] == dl_data[AT_EUID] &&
-         dl_data[AT_GID] == dl_data[AT_EGID]))
-    {
-      _dl_secure = 0;
-      _dl_preload = _dl_getenv("LD_PRELOAD", envp);
-      _dl_library_path = _dl_getenv("LD_LIBRARY_PATH",envp);
-    }
-    else
-    {
-      _dl_secure = 1;
-      _dl_preload = _dl_getenv("LD_PRELOAD", envp);
-      _dl_unsetenv("LD_AOUT_PRELOAD", envp);
-      _dl_unsetenv("LD_LIBRARY_PATH", envp);
-      _dl_unsetenv("LD_AOUT_LIBRARY_PATH", envp);
-      _dl_library_path = NULL;
-    }
-  }
-
-  _dl_trace_loaded_objects = _dl_getenv("LD_TRACE_LOADED_OBJECTS", envp);
-
-  /* OK, we now have the application in the list, and we have some
-     basic stuff in place.  Now search through the list for other shared
-     libraries that should be loaded, and insert them on the list in the
-     correct order. */
+                                       INIT_GOT(lpnt, _dl_loaded_modules);
+                       }
+                       if (ppnt->p_type == PT_INTERP) {        /* OK, fill this in - we did not 
+                                                                  have this before */
+                               tpnt->libname = _dl_strdup((char *) ppnt->p_offset +
+                                                          (dl_data[AT_PHDR] & 0xfffff000));
+                       }
+               }
+       }
+
+       if (argv[0]) {
+               _dl_progname = argv[0];
+       }
+
+       /* Now we need to figure out what kind of options are selected.
+          Note that for SUID programs we ignore the settings in LD_LIBRARY_PATH */
+       {
+               _dl_not_lazy = _dl_getenv("LD_BIND_NOW", envp);
+
+               if ((dl_data[AT_UID] == -1 && _dl_suid_ok()) ||
+                       (dl_data[AT_UID] != -1 && dl_data[AT_UID] == dl_data[AT_EUID]
+                        && dl_data[AT_GID] == dl_data[AT_EGID])) {
+                       _dl_secure = 0;
+                       _dl_preload = _dl_getenv("LD_PRELOAD", envp);
+                       _dl_library_path = _dl_getenv("LD_LIBRARY_PATH", envp);
+               } else {
+                       _dl_secure = 1;
+                       _dl_preload = _dl_getenv("LD_PRELOAD", envp);
+                       _dl_unsetenv("LD_AOUT_PRELOAD", envp);
+                       _dl_unsetenv("LD_LIBRARY_PATH", envp);
+                       _dl_unsetenv("LD_AOUT_LIBRARY_PATH", envp);
+                       _dl_library_path = NULL;
+               }
+       }
+
+       _dl_trace_loaded_objects = _dl_getenv("LD_TRACE_LOADED_OBJECTS", envp);
+
+       /* OK, we now have the application in the list, and we have some
+          basic stuff in place.  Now search through the list for other shared
+          libraries that should be loaded, and insert them on the list in the
+          correct order. */
+
+#ifdef USE_CACHE
+       _dl_map_cache();
+#endif
+
+       {
+               struct elf_resolve *tcurr;
+               struct elf_resolve *tpnt1;
+               char *lpnt;
+
+               if (_dl_preload) 
+               {
+                       char c, *str, *str2;
+
+                       str = _dl_preload;
+                       while (*str == ':' || *str == ' ' || *str == '\t')
+                               str++;
+                       while (*str) 
+                       {
+                               str2 = str;
+                               while (*str2 && *str2 != ':' && *str2 != ' ' && *str2 != '\t')
+                                       str2++;
+                               c = *str2;
+                               *str2 = '\0';
+                               if (!_dl_secure || _dl_strchr(str, '/') == NULL) 
+                               {
+                                       tpnt1 = _dl_load_shared_library(_dl_secure, NULL, str);
+                                       if (!tpnt1) {
+                                               if (_dl_trace_loaded_objects)
+                                                       _dl_fdprintf(1, "\t%s => not found\n", str);
+                                               else {
+                                                       _dl_fdprintf(2, "%s: can't load "
+                                                               "library '%s'\n", _dl_progname, str);
+                                                       _dl_exit(15);
+                                               }
+                                       } else {
+                                               if (_dl_trace_loaded_objects
+                                                       && !tpnt1->usage_count) {
+                                                       /* this is a real hack to make ldd not print 
+                                                        * the library itself when run on a library. */
+                                                       if (_dl_strcmp(_dl_progname, str) != 0)
+                                                               _dl_fdprintf(1, "\t%s => %s (0x%x)\n", 
+                                                                       str, tpnt1->libname, 
+                                                                       (unsigned) tpnt1->loadaddr);
+                                               }
+                                               rpnt->next = (struct dyn_elf *)
+                                                       _dl_malloc(sizeof(struct dyn_elf));
+                                               _dl_memset(rpnt->next, 0, sizeof(*(rpnt->next)));
+                                               rpnt = rpnt->next;
+                                               tpnt1->usage_count++;
+                                               tpnt1->symbol_scope = _dl_symbol_tables;
+                                               tpnt1->libtype = elf_lib;
+                                               rpnt->dyn = tpnt1;
+                                       }
+                               }
+                               *str2 = c;
+                               str = str2;
+                               while (*str == ':' || *str == ' ' || *str == '\t')
+                                       str++;
+                       }
+               }
+
+               {
+                       int fd;
+                       struct kernel_stat st;
+                       char *preload;
+
+                       if (!_dl_stat(LDSO_PRELOAD, &st)) {
+                               if ((fd = _dl_open(LDSO_PRELOAD, O_RDONLY)) < 0) {
+                                       _dl_fdprintf(2, "%s: can't open file '%s'\n", 
+                                               _dl_progname, LDSO_PRELOAD);
+                               } else {
+                                       preload = (caddr_t) _dl_mmap(0, st.st_size + 1, 
+                                               PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
+                                       _dl_close(fd);
+                                       if (preload == (caddr_t) - 1) {
+                                               _dl_fdprintf(2, "%s: can't map file '%s'\n", 
+                                                       _dl_progname, LDSO_PRELOAD);
+                                       } else {
+                                               char c, *cp, *cp2;
+
+                                               /* convert all separators and comments to spaces */
+                                               for (cp = preload; *cp; /*nada */ ) {
+                                                       if (*cp == ':' || *cp == '\t' || *cp == '\n') {
+                                                               *cp++ = ' ';
+                                                       } else if (*cp == '#') {
+                                                               do
+                                                                       *cp++ = ' ';
+                                                               while (*cp != '\n' && *cp != '\0');
+                                                       } else {
+                                                               cp++;
+                                                       }
+                                               }
+
+                                               /* find start of first library */
+                                               for (cp = preload; *cp && *cp == ' '; cp++)
+                                                       /*nada */ ;
+
+                                               while (*cp) {
+                                                       /* find end of library */
+                                                       for (cp2 = cp; *cp && *cp != ' '; cp++)
+                                                               /*nada */ ;
+                                                       c = *cp;
+                                                       *cp = '\0';
+
+                                                       tpnt1 = _dl_load_shared_library(0, NULL, cp2);
+                                                       if (!tpnt1) {
+                                                               if (_dl_trace_loaded_objects)
+                                                                       _dl_fdprintf(1, "\t%s => not "
+                                                                               "found\n", cp2);
+                                                               else {
+                                                                       _dl_fdprintf(2, "%s: can't "
+                                                                               "load library '%s'\n", 
+                                                                               _dl_progname, cp2);
+                                                                       _dl_exit(15);
+                                                               }
+                                                       } else {
+                                                               if (_dl_trace_loaded_objects
+                                                                       && !tpnt1->usage_count) {
+                                                                       _dl_fdprintf(1, "\t%s => %s "
+                                                                               "(0x%x)\n", cp2, 
+                                                                               tpnt1->libname, 
+                                                                               (unsigned) tpnt1->loadaddr);
+                                                               }
+                                                               rpnt->next = (struct dyn_elf *)
+                                                                       _dl_malloc(sizeof(struct dyn_elf));
+                                                               _dl_memset(rpnt->next, 0, 
+                                                                       sizeof(*(rpnt->next)));
+                                                               rpnt = rpnt->next;
+                                                               tpnt1->usage_count++;
+                                                               tpnt1->symbol_scope = _dl_symbol_tables;
+                                                               tpnt1->libtype = elf_lib;
+                                                               rpnt->dyn = tpnt1;
+                                                       }
+
+                                                       /* find start of next library */
+                                                       *cp = c;
+                                                       for ( /*nada */ ; *cp && *cp == ' '; cp++)
+                                                               /*nada */ ;
+                                               }
+
+                                               _dl_munmap(preload, st.st_size + 1);
+                                       }
+                               }
+                       }
+               }
+
+               for (tcurr = _dl_loaded_modules; tcurr; tcurr = tcurr->next) {
+                       for (dpnt = (Elf32_Dyn *) tcurr->dynamic_addr; dpnt->d_tag;
+                                dpnt++) {
+                               if (dpnt->d_tag == DT_NEEDED) {
+                                       lpnt = tcurr->loadaddr + tcurr->dynamic_info[DT_STRTAB] +
+                                               dpnt->d_un.d_val;
+                                       if (tpnt && _dl_strcmp(lpnt, tpnt->libname) == 0) {
+                                               struct elf_resolve *ttmp;
+
+                                               ttmp = _dl_loaded_modules;
+                                               while (ttmp->next)
+                                                       ttmp = ttmp->next;
+                                               ttmp->next = tpnt;
+                                               tpnt->prev = ttmp;
+                                               tpnt->next = NULL;
+                                               rpnt->next = (struct dyn_elf *)
+                                                       _dl_malloc(sizeof(struct dyn_elf));
+                                               _dl_memset(rpnt->next, 0, sizeof(*(rpnt->next)));
+                                               rpnt = rpnt->next;
+                                               rpnt->dyn = tpnt;
+                                               tpnt->usage_count++;
+                                               tpnt->symbol_scope = _dl_symbol_tables;
+                                               tpnt = NULL;
+                                               continue;
+                                       }
+                                       if (!(tpnt1 = _dl_load_shared_library(0, tcurr, lpnt))) {
+                                               if (_dl_trace_loaded_objects)
+                                                       _dl_fdprintf(1, "\t%s => not found\n", lpnt);
+                                               else {
+                                                       _dl_fdprintf(2, "%s: can't load library '%s'\n", 
+                                                               _dl_progname, lpnt);
+                                                       _dl_exit(16);
+                                               }
+                                       } else {
+                                               if (_dl_trace_loaded_objects
+                                                       && !tpnt1->usage_count)
+                                                       _dl_fdprintf(1, "\t%s => %s (0x%x)\n", lpnt, 
+                                                               tpnt1->libname, (unsigned) tpnt1->loadaddr);
+                                               rpnt->next = (struct dyn_elf *)
+                                                       _dl_malloc(sizeof(struct dyn_elf));
+                                               _dl_memset(rpnt->next, 0, sizeof(*(rpnt->next)));
+                                               rpnt = rpnt->next;
+                                               tpnt1->usage_count++;
+                                               tpnt1->symbol_scope = _dl_symbol_tables;
+                                               tpnt1->libtype = elf_lib;
+                                               rpnt->dyn = tpnt1;
+                                       }
+                               }
+                       }
+               }
+       }
 
 #ifdef USE_CACHE
-  _dl_map_cache();
+       _dl_unmap_cache();
 #endif
 
-  {
-    struct elf_resolve *tcurr;
-    struct elf_resolve *tpnt1;
-    char *lpnt;
-
-    if (_dl_preload) {
-      char c, *str, *str2;
-
-      str = _dl_preload;
-      while (*str == ':' || *str == ' ' || *str == '\t')
-       str++;
-      while (*str) {
-       str2 = str;
-       while (*str2 && *str2 != ':' && *str2 != ' ' && *str2 != '\t')
-         str2++;
-       c = *str2;
-       *str2 = '\0';
-       if (!_dl_secure || _dl_strchr(str, '/') == NULL) {
-         tpnt1 = _dl_load_shared_library(_dl_secure, NULL, str);
-         if (!tpnt1) {
-           if (_dl_trace_loaded_objects)
-             _dl_fdprintf(1, "\t%s => not found\n", str);
-           else {
-             _dl_fdprintf(2, "%s: can't load library '%s'\n",
-                          _dl_progname, str);
-             _dl_exit(15);
-           }
-         } else {
-           if (_dl_trace_loaded_objects && !tpnt1->usage_count) {
-             /* this is a real hack to make ldd not print the
-                library itself when run on a library. */
-             if (_dl_strcmp(_dl_progname, str) != 0)
-               _dl_fdprintf(1, "\t%s => %s (0x%x)\n", str, tpnt1->libname,
-                            (unsigned)tpnt1->loadaddr);
-           }
-           rpnt->next = 
-             (struct dyn_elf *) _dl_malloc(sizeof(struct dyn_elf));
-           _dl_memset (rpnt->next, 0, sizeof (*(rpnt->next)));
-           rpnt = rpnt->next;
-           tpnt1->usage_count++;
-           tpnt1->symbol_scope = _dl_symbol_tables;
-           tpnt1->libtype = elf_lib;
-           rpnt->dyn = tpnt1;
-         }
+       /* ldd uses uses this.  I am not sure how you pick up the other flags */
+       if (_dl_trace_loaded_objects) {
+               _dl_warn = _dl_getenv("LD_WARN", envp);
+               if (!_dl_warn)
+                       _dl_exit(0);
        }
-       *str2 = c;
-       str = str2;
-       while (*str == ':' || *str == ' ' || *str == '\t')
-         str++;
-      }
-    }
-
-    {
-      int fd;
-      struct kernel_stat st;
-      char *preload;
-
-      if (!_dl_stat(LDSO_PRELOAD, &st)) {
-       if ((fd = _dl_open(LDSO_PRELOAD, O_RDONLY)) < 0) {
-         _dl_fdprintf(2, "%s: can't open file '%s'\n", _dl_progname, 
-                      LDSO_PRELOAD);
-       } else {
-         preload = (caddr_t)_dl_mmap(0, st.st_size+1, PROT_READ|PROT_WRITE, 
-                                     MAP_PRIVATE, fd, 0);
-         _dl_close (fd);
-         if (preload == (caddr_t)-1) {
-           _dl_fdprintf(2, "%s: can't map file '%s'\n", _dl_progname, 
-                        LDSO_PRELOAD);
-         } else {
-           char c, *cp, *cp2;
-
-           /* convert all separators and comments to spaces */
-           for (cp = preload; *cp; /*nada*/) {
-             if (*cp == ':' || *cp == '\t' || *cp == '\n') {
-               *cp++ = ' ';
-             } else if (*cp == '#') {
-               do
-                 *cp++ = ' ';
-               while (*cp != '\n' && *cp != '\0');
-             } else {
-               cp++;
-             }
-           }
-
-           /* find start of first library */
-           for (cp = preload; *cp && *cp == ' '; cp++)
-             /*nada*/;
-
-           while (*cp) {
-             /* find end of library */
-             for (cp2 = cp; *cp && *cp != ' '; cp++)
-               /*nada*/;
-             c = *cp;
-             *cp = '\0';
-
-             tpnt1 = _dl_load_shared_library(0, NULL, cp2);
-             if (!tpnt1) {
-               if (_dl_trace_loaded_objects)
-                 _dl_fdprintf(1, "\t%s => not found\n", cp2);
-               else {
-                 _dl_fdprintf(2, "%s: can't load library '%s'\n",
-                              _dl_progname, cp2);
-                 _dl_exit(15);
+
+       /*
+        * If the program interpreter is not in the module chain, add it.  This will
+        * be required for dlopen to be able to access the internal functions in the 
+        * dynamic linker.
+        */
+       if (tpnt) {
+               struct elf_resolve *tcurr;
+
+               tcurr = _dl_loaded_modules;
+               if (tcurr)
+                       while (tcurr->next)
+                               tcurr = tcurr->next;
+               tpnt->next = NULL;
+               tpnt->usage_count++;
+
+               if (tcurr) {
+                       tcurr->next = tpnt;
+                       tpnt->prev = tcurr;
+               } else {
+                       _dl_loaded_modules = tpnt;
+                       tpnt->prev = NULL;
                }
-             } else {
-               if (_dl_trace_loaded_objects && !tpnt1->usage_count)
-                 _dl_fdprintf(1, "\t%s => %s (0x%x)\n", cp2, tpnt1->libname,
-                              (unsigned)tpnt1->loadaddr);
-                rpnt->next = 
-                 (struct dyn_elf *) _dl_malloc(sizeof(struct dyn_elf));
-               _dl_memset (rpnt->next, 0, sizeof (*(rpnt->next)));
-               rpnt = rpnt->next;
-               tpnt1->usage_count++;
-               tpnt1->symbol_scope = _dl_symbol_tables;
-               tpnt1->libtype = elf_lib;
-               rpnt->dyn = tpnt1;
-             }
-
-             /* find start of next library */
-             *cp = c;
-             for (/*nada*/; *cp && *cp == ' '; cp++)
-               /*nada*/;
-           }
-
-           _dl_munmap(preload, st.st_size+1);
-         }
+               if (rpnt) {
+                       rpnt->next = (struct dyn_elf *) _dl_malloc(sizeof(struct dyn_elf));
+                       _dl_memset(rpnt->next, 0, sizeof(*(rpnt->next)));
+                       rpnt = rpnt->next;
+               } else {
+                       rpnt = (struct dyn_elf *) _dl_malloc(sizeof(struct dyn_elf));
+                       _dl_memset(rpnt, 0, sizeof(*(rpnt->next)));
+               }
+               rpnt->dyn = tpnt;
+               tpnt = NULL;
        }
-      }
-    }
-
-    for (tcurr = _dl_loaded_modules; tcurr; tcurr = tcurr->next)
-    {
-      for (dpnt = (struct dynamic *)tcurr->dynamic_addr; dpnt->d_tag; dpnt++)
-      {
-       if(dpnt->d_tag == DT_NEEDED)
+
+       /*
+        * OK, now all of the kids are tucked into bed in their proper addresses.
+        * Now we go through and look for REL and RELA records that indicate fixups
+        * to the GOT tables.  We need to do this in reverse order so that COPY
+        * directives work correctly */
+
+
+       goof = _dl_loaded_modules ? _dl_fixup(_dl_loaded_modules) : 0;
+
+
+       /* Some flavors of SVr4 do not generate the R_*_COPY directive,
+          and we have to manually search for entries that require fixups. 
+          Solaris gets this one right, from what I understand.  */
+
+
+       if (_dl_symbol_tables)
+               goof += _dl_copy_fixups(_dl_symbol_tables);
+
+       if (goof || _dl_trace_loaded_objects)
+               _dl_exit(0);
+
+       /* OK, at this point things are pretty much ready to run.  Now we
+          need to touch up a few items that are required, and then
+          we can let the user application have at it.  Note that
+          the dynamic linker itself is not guaranteed to be fully
+          dynamicly linked if we are using ld.so.1, so we have to look
+          up each symbol individually. */
+
+
+       _dl_brkp = (unsigned int *) _dl_find_hash("___brk_addr", NULL, 1, NULL, 0);
+       if (_dl_brkp)
+               *_dl_brkp = brk_addr;
+       _dl_envp =
+               (unsigned int *) _dl_find_hash("__environ", NULL, 1, NULL, 0);
+
+       if (_dl_envp)
+               *_dl_envp = (unsigned int) envp;
+
        {
-         lpnt = tcurr->loadaddr + tcurr->dynamic_info[DT_STRTAB] + 
-           dpnt->d_un.d_val;
-         if (tpnt && _dl_strcmp(lpnt, tpnt->libname) == 0)
-         {
-           struct elf_resolve * ttmp;
-           ttmp = _dl_loaded_modules;
-           while (ttmp->next) 
-             ttmp = ttmp->next;
-           ttmp->next = tpnt;
-           tpnt->prev = ttmp;
-           tpnt->next = NULL;
-           rpnt->next = 
-             (struct dyn_elf *) _dl_malloc(sizeof(struct dyn_elf));
-           _dl_memset (rpnt->next, 0, sizeof (*(rpnt->next)));
-           rpnt = rpnt->next;
-           rpnt->dyn = tpnt;
-           tpnt->usage_count++;
-           tpnt->symbol_scope = _dl_symbol_tables;
-           tpnt = NULL;
-           continue;
-         }
-         if (!(tpnt1 = _dl_load_shared_library(0, tcurr, lpnt)))
-         {
-           if (_dl_trace_loaded_objects)
-             _dl_fdprintf(1, "\t%s => not found\n", lpnt);
-           else
-           {
-             _dl_fdprintf(2, "%s: can't load library '%s'\n",
-                          _dl_progname, lpnt);
-             _dl_exit(16);
-           }
-         }
-         else
-         {
-           if (_dl_trace_loaded_objects && !tpnt1->usage_count)
-             _dl_fdprintf(1, "\t%s => %s (0x%x)\n", lpnt, tpnt1->libname,
-                          (unsigned)tpnt1->loadaddr);
-           rpnt->next = 
-             (struct dyn_elf *) _dl_malloc(sizeof(struct dyn_elf));
-           _dl_memset (rpnt->next, 0, sizeof (*(rpnt->next)));
-           rpnt = rpnt->next;
-           tpnt1->usage_count++;
-           tpnt1->symbol_scope = _dl_symbol_tables;
-           tpnt1->libtype = elf_lib;
-           rpnt->dyn = tpnt1;
-         }
+               int i;
+               elf_phdr *ppnt;
+
+               /* We had to set the protections of all pages to R/W for dynamic linking.
+                  Set text pages back to R/O */
+               for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next)
+                       for (ppnt = tpnt->ppnt, i = 0; i < tpnt->n_phent; i++, ppnt++)
+                               if (ppnt->p_type == PT_LOAD && !(ppnt->p_flags & PF_W) &&
+                                       tpnt->dynamic_info[DT_TEXTREL])
+                                       _dl_mprotect((void *) (tpnt->loadaddr + 
+                                                   (ppnt->p_vaddr & 0xfffff000)), 
+                                               (ppnt->p_vaddr & 0xfff) + 
+                                               (unsigned int) ppnt->p_filesz, 
+                                               LXFLAGS(ppnt->p_flags));
+
        }
-      }
-    }
-  }
 
-#ifdef USE_CACHE
-  _dl_unmap_cache();
-#endif
+       _dl_atexit = (int (*)(void *)) _dl_find_hash("atexit", NULL, 1, NULL, 0);
 
-    /* ldd uses uses this.  I am not sure how you pick up the other flags */ 
-  if(_dl_trace_loaded_objects)
-    {
-      _dl_warn = _dl_getenv("LD_WARN", envp);
-      if (!_dl_warn) _dl_exit(0);
-    }
-
-  /*
-   * If the program interpreter is not in the module chain, add it.  This will
-   * be required for dlopen to be able to access the internal functions in the 
-   * dynamic linker.
-   */
-  if(tpnt) {
-    struct elf_resolve * tcurr;
-
-    tcurr = _dl_loaded_modules;
-    if (tcurr)
-      while(tcurr->next) tcurr = tcurr->next;
-    tpnt->next = NULL;
-    tpnt->usage_count++;
-
-    if (tcurr) {
-      tcurr->next = tpnt;
-      tpnt->prev = tcurr;
-    }
-    else {
-      _dl_loaded_modules = tpnt;
-      tpnt->prev = NULL;
-    }
-    if (rpnt) {
-      rpnt->next = 
-       (struct dyn_elf *) _dl_malloc(sizeof(struct dyn_elf));
-      _dl_memset (rpnt->next, 0, sizeof (*(rpnt->next)));
-      rpnt = rpnt->next;
-    } else {
-      rpnt =   (struct dyn_elf *) _dl_malloc(sizeof(struct dyn_elf));
-      _dl_memset (rpnt, 0, sizeof (*(rpnt->next)));
-    }
-    rpnt->dyn = tpnt;
-    tpnt = NULL;
-  }
-
-  /*
-   * OK, now all of the kids are tucked into bed in their proper addresses.
-   * Now we go through and look for REL and RELA records that indicate fixups
-   * to the GOT tables.  We need to do this in reverse order so that COPY
-   * directives work correctly */
-
-
-  goof = _dl_loaded_modules ? _dl_fixup(_dl_loaded_modules) : 0;
-
-
-  /* Some flavors of SVr4 do not generate the R_*_COPY directive,
-   and we have to manually search for entries that require fixups. 
-   Solaris gets this one right, from what I understand.  */
-
-
-  if (_dl_symbol_tables)
-    goof += _dl_copy_fixups(_dl_symbol_tables);
-
-  if(goof || _dl_trace_loaded_objects) _dl_exit(0);
-
-  /* OK, at this point things are pretty much ready to run.  Now we
-     need to touch up a few items that are required, and then
-     we can let the user application have at it.  Note that
-     the dynamic linker itself is not guaranteed to be fully
-     dynamicly linked if we are using ld.so.1, so we have to look
-     up each symbol individually. */
-
-
-  _dl_brkp = (unsigned int *) _dl_find_hash("___brk_addr", NULL, 1, NULL, 0);
-  if (_dl_brkp) *_dl_brkp = brk_addr;
-  _dl_envp = (unsigned int *) _dl_find_hash("__environ", NULL, 1, NULL, 0);
-
-  if (_dl_envp) *_dl_envp = (unsigned int) envp;
-
-  {
-    int i;
-    struct elf_phdr * ppnt;
-
-  /* We had to set the protections of all pages to R/W for dynamic linking.
-     Set text pages back to R/O */
-  for(tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next)
-    for(ppnt = tpnt->ppnt, i=0; i < tpnt->n_phent; i++, ppnt++)
-      if(ppnt->p_type == PT_LOAD && !(ppnt->p_flags & PF_W) &&
-        tpnt->dynamic_info[DT_TEXTREL])
-       _dl_mprotect((void *) (tpnt->loadaddr + (ppnt->p_vaddr & 0xfffff000)),
-                    (ppnt->p_vaddr & 0xfff) + (unsigned int) ppnt->p_filesz,
-                    LXFLAGS(ppnt->p_flags));
-
-  }
-
-  _dl_atexit = (int (*)(void *)) _dl_find_hash("atexit", NULL, 1, NULL, 0);
-
-  /*
-   * OK, fix one more thing - set up the debug_addr structure to point
-   * to our chain.  Later we may need to fill in more fields, but this
-   * should be enough for now.
-   */
-  debug_addr->r_map = (struct link_map *) _dl_loaded_modules;
-  debug_addr->r_version = 1;
-  debug_addr->r_ldbase = load_addr;
-  debug_addr->r_brk = (unsigned long) &_dl_debug_state;
-  _dl_debug_addr = debug_addr;
-  debug_addr->r_state = RT_CONSISTENT;
-  /* This is written in this funny way to keep gcc from inlining the
-     function call. */
-  ((void (*)(void))debug_addr->r_brk)();
-
-  for(tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next)
-    {
-      /* Apparently crt1 for the application is responsible for handling this.
-       * We only need to run the init/fini for shared libraries
-       */
-      if (tpnt->libtype == program_interpreter ||
-       tpnt->libtype == elf_executable) continue;
-      if (tpnt->init_flag & INIT_FUNCS_CALLED) continue;
-      tpnt->init_flag |= INIT_FUNCS_CALLED;
-      
-      if(tpnt->dynamic_info[DT_INIT]) {
-       _dl_elf_init = (int (*)(void)) (tpnt->loadaddr + 
-                                   tpnt->dynamic_info[DT_INIT]);
-       (*_dl_elf_init)();
-      }
-      if(_dl_atexit && tpnt->dynamic_info[DT_FINI])
-      {
-        (*_dl_atexit)(tpnt->loadaddr + tpnt->dynamic_info[DT_FINI]);
-      }
+       /*
+        * OK, fix one more thing - set up the debug_addr structure to point
+        * to our chain.  Later we may need to fill in more fields, but this
+        * should be enough for now.
+        */
+       debug_addr->r_map = (struct link_map *) _dl_loaded_modules;
+       debug_addr->r_version = 1;
+       debug_addr->r_ldbase = load_addr;
+       debug_addr->r_brk = (unsigned long) &_dl_debug_state;
+       _dl_debug_addr = debug_addr;
+       debug_addr->r_state = RT_CONSISTENT;
+       /* This is written in this funny way to keep gcc from inlining the
+          function call. */
+       ((void (*)(void)) debug_addr->r_brk) ();
+
+       for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) {
+               /* Apparently crt1 for the application is responsible for handling this.
+                * We only need to run the init/fini for shared libraries
+                */
+               if (tpnt->libtype == program_interpreter ||
+                       tpnt->libtype == elf_executable)
+                       continue;
+               if (tpnt->init_flag & INIT_FUNCS_CALLED)
+                       continue;
+               tpnt->init_flag |= INIT_FUNCS_CALLED;
+
+               if (tpnt->dynamic_info[DT_INIT]) {
+                       _dl_elf_init = (int (*)(void)) (tpnt->loadaddr + 
+                               tpnt->dynamic_info[DT_INIT]);
+                       (*_dl_elf_init) ();
+               }
+               if (_dl_atexit && tpnt->dynamic_info[DT_FINI]) {
+                       (*_dl_atexit) (tpnt->loadaddr + tpnt->dynamic_info[DT_FINI]);
+               }
 #undef DL_DEBUG
 #ifdef DL_DEBUG
-      else
-      {
-       _dl_fdprintf(2, tpnt->libname);
-       _dl_fdprintf(2, ": ");
-       if (!_dl_atexit)
-         _dl_fdprintf(2, "The address is atexit () is 0x0.");
-       if (!tpnt->dynamic_info[DT_FINI])
-         _dl_fdprintf(2, "Invalid .fini section.");
-       _dl_fdprintf(2, "\n");
-      }
+               else {
+                       _dl_fdprintf(2, tpnt->libname);
+                       _dl_fdprintf(2, ": ");
+                       if (!_dl_atexit)
+                               _dl_fdprintf(2, "The address is atexit () is 0x0.");
+                       if (!tpnt->dynamic_info[DT_FINI])
+                               _dl_fdprintf(2, "Invalid .fini section.");
+                       _dl_fdprintf(2, "\n");
+               }
 #endif
 #undef DL_DEBUG
-   }
+       }
 
-  /* OK we are done here.  Turn out the lights, and lock up. */
-  _dl_elf_main = (int (*)(int, char**, char**)) dl_data[AT_ENTRY];
+       /* OK we are done here.  Turn out the lights, and lock up. */
+       _dl_elf_main = (int (*)(int, char **, char **)) dl_data[AT_ENTRY];
 
 
-  /*
-   * Transfer control to the application.
-   */
-  START();
+       /*
+        * Transfer control to the application.
+        */
+       START();
 }
 
-int _dl_fixup(struct elf_resolve * tpnt)
+int _dl_fixup(struct elf_resolve *tpnt)
 {
-  int goof = 0;
-  if(tpnt->next) goof += _dl_fixup(tpnt->next);
+       int goof = 0;
+
+       if (tpnt->next)
+               goof += _dl_fixup(tpnt->next);
 
-  if(tpnt->dynamic_info[DT_REL]) {
+       if (tpnt->dynamic_info[DT_REL]) {
 #ifdef ELF_USES_RELOCA
-    _dl_fdprintf(2, "%s: can't handle REL relocation records\n", _dl_progname);
-    _dl_exit(17);
+               _dl_fdprintf(2, "%s: can't handle REL relocation records\n", 
+                       _dl_progname);
+               _dl_exit(17);
 #else
-    if (tpnt->init_flag & RELOCS_DONE) return goof;
-    tpnt->init_flag |= RELOCS_DONE;
-   
-    goof += _dl_parse_relocation_information(tpnt, tpnt->dynamic_info[DT_REL],
-                                            tpnt->dynamic_info[DT_RELSZ], 0);
+               if (tpnt->init_flag & RELOCS_DONE)
+                       return goof;
+               tpnt->init_flag |= RELOCS_DONE;
+
+               goof += _dl_parse_relocation_information(tpnt, 
+                       tpnt->dynamic_info[DT_REL], tpnt->dynamic_info[DT_RELSZ], 0);
 #endif
-  }
-  if(tpnt->dynamic_info[DT_RELA]) {
+       }
+       if (tpnt->dynamic_info[DT_RELA]) {
 #ifdef ELF_USES_RELOCA
-    if (tpnt->init_flag & RELOCS_DONE) return goof;
-    tpnt->init_flag |= RELOCS_DONE;
-   
-    goof += _dl_parse_relocation_information(tpnt, tpnt->dynamic_info[DT_RELA],
-                                            tpnt->dynamic_info[DT_RELASZ], 0);
+               if (tpnt->init_flag & RELOCS_DONE)
+                       return goof;
+               tpnt->init_flag |= RELOCS_DONE;
+
+               goof += _dl_parse_relocation_information(tpnt, 
+                       tpnt->dynamic_info[DT_RELA], tpnt->dynamic_info[DT_RELASZ], 0);
 #else
-    _dl_fdprintf(2, "%s: can't handle RELA relocation records\n", _dl_progname);
-    _dl_exit(18);
+               _dl_fdprintf(2, "%s: can't handle RELA relocation records\n", 
+                       _dl_progname);
+               _dl_exit(18);
 #endif
-  }
-  if(tpnt->dynamic_info[DT_JMPREL])
-    {
-      if (tpnt->init_flag & JMP_RELOCS_DONE) return goof;
-      tpnt->init_flag |= JMP_RELOCS_DONE;
-      
-      if(! _dl_not_lazy || *_dl_not_lazy == 0)
-       _dl_parse_lazy_relocation_information(tpnt, tpnt->dynamic_info[DT_JMPREL],
-                                             tpnt->dynamic_info[DT_PLTRELSZ], 0);
-      else
-       goof +=  _dl_parse_relocation_information(tpnt,
-                                                 tpnt->dynamic_info[DT_JMPREL],
-                                                 tpnt->dynamic_info[DT_PLTRELSZ], 0);
-    }
-  return goof;
+       }
+       if (tpnt->dynamic_info[DT_JMPREL]) {
+               if (tpnt->init_flag & JMP_RELOCS_DONE)
+                       return goof;
+               tpnt->init_flag |= JMP_RELOCS_DONE;
+
+               if (!_dl_not_lazy || *_dl_not_lazy == 0)
+                       _dl_parse_lazy_relocation_information(tpnt, 
+                               tpnt->dynamic_info[DT_JMPREL], tpnt->dynamic_info[DT_PLTRELSZ], 0);
+               else
+                       goof += _dl_parse_relocation_information(tpnt, 
+                               tpnt->dynamic_info[DT_JMPREL], tpnt->dynamic_info[DT_PLTRELSZ], 0);
+       }
+       return goof;
 }
 
-void * _dl_malloc(int size) {
-  void * retval;
-
-  if(_dl_malloc_function)
-       return (*_dl_malloc_function)(size);
-
-  if(_dl_malloc_addr-_dl_mmap_zero+size>4096) {
-       _dl_mmap_zero = _dl_malloc_addr = (unsigned char *) _dl_mmap((void*) 0, size,
-                               PROT_READ | PROT_WRITE, 
-                               MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
-       if(_dl_mmap_check_error(_dl_mmap_zero)) {
-           _dl_fdprintf(2, "%s: can't map '/dev/zero'\n", _dl_progname);
-           _dl_exit(20);
-       }
-  }
-  retval = _dl_malloc_addr;
-  _dl_malloc_addr += size;
-
-  /*
-   * Align memory to 4 byte boundary.  Some platforms require this, others
-   * simply get better performance.
-   */
-  _dl_malloc_addr = (char *) (((unsigned int) _dl_malloc_addr + 3) & ~(3));
-  return retval;
+void *_dl_malloc(int size)
+{
+       void *retval;
+
+       if (_dl_malloc_function)
+               return (*_dl_malloc_function) (size);
+
+       if (_dl_malloc_addr - _dl_mmap_zero + size > 4096) {
+               _dl_mmap_zero = _dl_malloc_addr =
+                       (unsigned char *) _dl_mmap((void *) 0, size, 
+                                                  PROT_READ | PROT_WRITE, 
+                                                  MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+               if (_dl_mmap_check_error(_dl_mmap_zero)) {
+                       _dl_fdprintf(2, "%s: can't map '/dev/zero'\n", _dl_progname);
+                       _dl_exit(20);
+               }
+       }
+       retval = _dl_malloc_addr;
+       _dl_malloc_addr += size;
+
+       /*
+        * Align memory to 4 byte boundary.  Some platforms require this, others
+        * simply get better performance.
+        */
+       _dl_malloc_addr = (char *) (((unsigned int) _dl_malloc_addr + 3) & ~(3));
+       return retval;
 }
 
-char * _dl_getenv(char *symbol, char **envp)
+char *_dl_getenv(char *symbol, char **envp)
 {
-  char *pnt;
-  char *pnt1;
-  while ((pnt = *envp++)) {
-    pnt1 = symbol;
-    while (*pnt && *pnt == *pnt1)
-      pnt1++, pnt++;
-    if (!*pnt || *pnt != '=' || *pnt1)
-      continue;
-    return pnt+1;
-  }
-  return 0;
+       char *pnt;
+       char *pnt1;
+
+       while ((pnt = *envp++)) {
+               pnt1 = symbol;
+               while (*pnt && *pnt == *pnt1)
+                       pnt1++, pnt++;
+               if (!*pnt || *pnt != '=' || *pnt1)
+                       continue;
+               return pnt + 1;
+       }
+       return 0;
 }
 
 void _dl_unsetenv(char *symbol, char **envp)
 {
-  char *pnt;
-  char *pnt1;
-  char **newenvp = envp;
-  for (pnt = *envp; pnt; pnt = *++envp) {
-    pnt1 = symbol;
-    while (*pnt && *pnt == *pnt1)
-      pnt1++, pnt++;
-    if(!*pnt || *pnt != '=' || *pnt1)
-      *newenvp++ = *envp;
-  }
-  *newenvp++ = *envp;
-  return;
+       char *pnt;
+       char *pnt1;
+       char **newenvp = envp;
+
+       for (pnt = *envp; pnt; pnt = *++envp) {
+               pnt1 = symbol;
+               while (*pnt && *pnt == *pnt1)
+                       pnt1++, pnt++;
+               if (!*pnt || *pnt != '=' || *pnt1)
+                       *newenvp++ = *envp;
+       }
+       *newenvp++ = *envp;
+       return;
 }
 
-char * _dl_strdup(const char * string){
-  char * retval;
-  int len;
+char *_dl_strdup(const char *string)
+{
+       char *retval;
+       int len;
 
-  len = _dl_strlen(string);
-  retval = _dl_malloc(len + 1);
-  _dl_strcpy(retval, string);
-  return retval;
+       len = _dl_strlen(string);
+       retval = _dl_malloc(len + 1);
+       _dl_strcpy(retval, string);
+       return retval;
 }
-
index 2eeda2d..f7c6eeb 100644 (file)
@@ -35,7 +35,7 @@ struct elf_resolve{
 
   unsigned int dynamic_size;
   unsigned int n_phent;
-  struct elf_phdr * ppnt;
+  Elf32_Phdr * ppnt;
 };
 
 #if 0
index 1ea8fd7..be0de45 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef _LINUX_STRING_H_
 #define _LINUX_STRING_H_
 
-#include <linux/types.h>       /* for size_t */
+#include <sys/types.h> /* for size_t */
 
 #ifndef NULL
 #define NULL ((void *) 0)
index 4e4d4c1..6678e2c 100644 (file)
@@ -41,6 +41,7 @@ static inline void * _dl_mmap(void * addr, unsigned long size, int prot,
 
 
 #define __NR__dl_open __NR_open
+#define O_RDONLY        0x0000
 static inline _syscall2(int, _dl_open, const char *, fn, int, flags);
 
 #define __NR__dl_write __NR_write
@@ -66,6 +67,7 @@ static inline _syscall3(int, _dl_mprotect, const void *, addr, unsigned long, le
 #include <asm/stat.h> 
 #undef new_stat
 #undef stat
+#define S_ISUID       04000   /* Set user ID on execution.  */
 static inline _syscall2(int, _dl_stat, const char *, file_name, struct kernel_stat *, buf);
 
 
index 3b613fb..948a6e1 100644 (file)
  * can transfer control to the user's application.
  */
 
+#include <sys/mman.h>                  // For MAP_ANONYMOUS -- differs between platforms
 #include <stdarg.h>
-#include <linux/types.h>
-#include <linux/fcntl.h>
-#include <linux/unistd.h>
-#include <linux/elf.h>
-#include <linux/mman.h>
+#include "elf.h"
 #include "link.h"
-
 #include "sysdep.h"
 #include "hash.h"
-#include "linuxelf.h"
 #include "syscall.h"
 #include "string.h"
 
 
 #define ALLOW_ZERO_PLTGOT
 
-static char * _dl_malloc_addr, *_dl_mmap_zero;
-char * _dl_library_path = 0; /* Where we look for libraries */
-char *_dl_preload = 0; /* Things to be loaded before the libs. */
+static char *_dl_malloc_addr, *_dl_mmap_zero;
+char *_dl_library_path = 0;            /* Where we look for libraries */
+char *_dl_preload = 0;                 /* Things to be loaded before the libs. */
 char *_dl_progname = "/lib/ld-linux-uclibc.so.1";
-static char * _dl_not_lazy = 0;
-static char * _dl_warn = 0; /* Used by ldd */
-static char * _dl_trace_loaded_objects = 0;
-static int (*_dl_elf_main)(int, char **, char**);
+static char *_dl_not_lazy = 0;
+static char *_dl_warn = 0;             /* Used by ldd */
+static char *_dl_trace_loaded_objects = 0;
+static int (*_dl_elf_main) (int, char **, char **);
 
-static int (*_dl_elf_init)(void);
+static int (*_dl_elf_init) (void);
 
-void * (*_dl_malloc_function)(int size) = NULL;
+void *(*_dl_malloc_function) (int size) = NULL;
 
-struct r_debug * _dl_debug_addr = NULL;
+struct r_debug *_dl_debug_addr = NULL;
 
-unsigned int * _dl_brkp; 
+unsigned int *_dl_brkp;
 
-unsigned int * _dl_envp;
+unsigned int *_dl_envp;
 
 #define DL_MALLOC(SIZE) ((void *) (malloc_buffer += SIZE, malloc_buffer - SIZE))
 /*
@@ -151,19 +146,10 @@ unsigned int * _dl_envp;
   RESULT = hash; \
 }
 extern int _dl_linux_resolve(void);
-extern char * _dl_strdup(const char *);
-extern char * _dl_getenv(char * symbol, char ** envp);
-extern void _dl_unsetenv(char * symbol, char ** envp);
-extern int _dl_fixup(struct elf_resolve * tpnt);
-
-/*
- * Datatype of a relocation on this platform
- */
-#ifdef ELF_USES_RELOCA
-typedef struct elf32_rela ELF_RELOC;
-#else
-typedef struct elf32_rel ELF_RELOC;
-#endif
+extern char *_dl_strdup(const char *);
+extern char *_dl_getenv(char *symbol, char **envp);
+extern void _dl_unsetenv(char *symbol, char **envp);
+extern int _dl_fixup(struct elf_resolve *tpnt);
 
 /*
  * This stub function is used by some debuggers.  The idea is that they
@@ -172,71 +158,72 @@ typedef struct elf32_rel ELF_RELOC;
  */
 void _dl_debug_state()
 {
-  return;
+       return;
 }
 
 void _dl_boot(int args);
 
-void _dl_boot(int args){
-  unsigned int argc;
-  char ** argv, ** envp;
-  int status;
-
-  unsigned int load_addr;
-  unsigned int * got;
-  unsigned int * aux_dat;
-  int goof = 0;
-  struct elfhdr * header;
-  struct elf_resolve * tpnt;
-  struct dyn_elf * rpnt;
-  struct elf_resolve * app_tpnt;
-  unsigned int brk_addr;
-  unsigned int dl_data[AT_EGID+1];
-  unsigned char * malloc_buffer, *mmap_zero;
-  int (*_dl_atexit)(void *);
-  int * lpnt;
-  struct dynamic * dpnt;
-  unsigned int *hash_addr;
-  struct r_debug * debug_addr;
-  unsigned int *chains;
-  int indx;
-  int _dl_secure;
-
-  /* First obtain the information on the stack that tells us more about
-     what binary is loaded, where it is loaded, etc, etc */
-
-  GET_ARGV(aux_dat, args);
-  argc = *(aux_dat - 1);
-  argv = (char **) aux_dat;
-  aux_dat += argc;  /* Skip over the argv pointers */
-  aux_dat++;  /* Skip over NULL at end of argv */
-  envp = (char **) aux_dat;
-  while(*aux_dat) aux_dat++;  /* Skip over the envp pointers */
-  aux_dat++;  /* Skip over NULL at end of envp */
-  dl_data[AT_UID] = -1; /* check later to see if it is changed */
-  while(*aux_dat)
-    {
-      unsigned int * ad1;
-      ad1 = aux_dat + 1;
-      if( *aux_dat <= AT_EGID ) dl_data[*aux_dat] = *ad1;
-      aux_dat += 2;
-    }
-
-  /* Next, locate the GOT */
-
-  load_addr = dl_data[AT_BASE];
-
-  GET_GOT(got);
-  dpnt = (struct dynamic *) (*got + load_addr);
-  /* OK, time for another hack.  Now call mmap to get a page of writable
-     memory that can be used for a temporary malloc.  We do not know brk
-     yet, so we cannot use real malloc. */
-
-  {
-    /* This hack is to work around a suspected asm bug in gcc-2.7.0 */
-    //int zfileno;
-//#define ZFILENO ((-1 & (~zfileno)) | zfileno)
+void _dl_boot(int args)
+{
+       unsigned int argc;
+       char **argv, **envp;
+       int status;
+
+       unsigned int load_addr;
+       unsigned int *got;
+       unsigned int *aux_dat;
+       int goof = 0;
+       elfhdr *header;
+       struct elf_resolve *tpnt;
+       struct dyn_elf *rpnt;
+       struct elf_resolve *app_tpnt;
+       unsigned int brk_addr;
+       unsigned int dl_data[AT_EGID + 1];
+       unsigned char *malloc_buffer, *mmap_zero;
+       int (*_dl_atexit) (void *);
+       int *lpnt;
+       Elf32_Dyn *dpnt;
+       unsigned int *hash_addr;
+       struct r_debug *debug_addr;
+       unsigned int *chains;
+       int indx;
+       int _dl_secure;
+
+       /* First obtain the information on the stack that tells us more about
+          what binary is loaded, where it is loaded, etc, etc */
+
+       GET_ARGV(aux_dat, args);
+       argc = *(aux_dat - 1);
+       argv = (char **) aux_dat;
+       aux_dat += argc;                        /* Skip over the argv pointers */
+       aux_dat++;                              /* Skip over NULL at end of argv */
+       envp = (char **) aux_dat;
+       while (*aux_dat)
+               aux_dat++;                      /* Skip over the envp pointers */
+       aux_dat++;                              /* Skip over NULL at end of envp */
+       dl_data[AT_UID] = -1;                   /* check later to see if it is changed */
+       while (*aux_dat) 
+       {
+               unsigned int *ad1;
+
+               ad1 = aux_dat + 1;
+               if (*aux_dat <= AT_EGID)
+                       dl_data[*aux_dat] = *ad1;
+               aux_dat += 2;
+       }
+
+       /* Next, locate the GOT */
+
+       load_addr = dl_data[AT_BASE];
+
+       GET_GOT(got);
+       dpnt = (Elf32_Dyn *) (*got + load_addr);
+
+       /* OK, time for another hack.  Now call mmap to get a page of writable
+          memory that can be used for a temporary malloc.  We do not know brk
+          yet, so we cannot use real malloc. */
+
+       {
 #define ZFILENO -1
 
 #ifndef MAP_ANONYMOUS
@@ -247,178 +234,195 @@ void _dl_boot(int args){
 #endif
 #endif
 
-    /* See if we need to relocate this address */
-    mmap_zero = malloc_buffer = (unsigned char *) _dl_mmap((void*) 0, 4096,
-                            PROT_READ | PROT_WRITE, 
-                            MAP_PRIVATE | MAP_ANONYMOUS, ZFILENO, 0);
-    if(_dl_mmap_check_error(mmap_zero)) {
-       SEND_STDERR("dl_boot: mmap of /dev/zero failed!\n");
-       _dl_exit(13);
-    }
-  }
-
-  tpnt = DL_MALLOC(sizeof(struct elf_resolve));
-  REALIGN();
-  _dl_memset (tpnt, 0, sizeof (*tpnt));
-  app_tpnt = DL_MALLOC(sizeof(struct elf_resolve));
-  REALIGN();
-  _dl_memset (app_tpnt, 0, sizeof (*app_tpnt));
-
-  /*
-   * This is used by gdb to locate the chain of shared libraries that are currently loaded.
-   */
-  debug_addr = DL_MALLOC(sizeof(struct r_debug));
-  REALIGN();
-  _dl_memset (debug_addr, 0, sizeof (*debug_addr));
-
-  /* OK, that was easy.  Next scan the DYNAMIC section of the image.
-     We are only doing ourself right now - we will have to do the rest later */
-
-  while(dpnt->d_tag)
-    {
-      tpnt->dynamic_info[dpnt->d_tag] = dpnt->d_un.d_val;
-      if(dpnt->d_tag == DT_TEXTREL ||
-        SVR4_BUGCOMPAT) tpnt->dynamic_info[DT_TEXTREL] = 1;
-      dpnt++;
-    }
-
-  {
-    struct elf_phdr * ppnt;
-    int i;
-    
-    ppnt = (struct elf_phdr *) dl_data[AT_PHDR];
-    for(i=0; i<dl_data[AT_PHNUM]; i++, ppnt++)
-      if(ppnt->p_type == PT_DYNAMIC) {
-       dpnt = (struct dynamic *) ppnt->p_vaddr;
-       while(dpnt->d_tag)
-         {
-           if(dpnt->d_tag > DT_JMPREL) {dpnt++; continue; }
-           app_tpnt->dynamic_info[dpnt->d_tag] = dpnt->d_un.d_val;
-           if(dpnt->d_tag == DT_DEBUG) dpnt->d_un.d_val = (int) debug_addr;
-           if(dpnt->d_tag == DT_TEXTREL ||
-              SVR4_BUGCOMPAT) app_tpnt->dynamic_info[DT_TEXTREL] = 1;
-           dpnt++;
-         }
-      }
-  }
-
-  /* Get some more of the information that we will need to dynamicly link
-     this module to itself */
-
-  hash_addr = (unsigned int *) (tpnt->dynamic_info[DT_HASH]+load_addr);
-  tpnt->nbucket = *hash_addr++;
-  tpnt->nchain = *hash_addr++;
-  tpnt->elf_buckets = hash_addr;
-  hash_addr += tpnt->nbucket;
-  chains = hash_addr;
-
-  /* Ugly, ugly.  We need to call mprotect to change the protection of
-     the text pages so that we can do the dynamic linking.  We can set the
-     protection back again once we are done */
-
-  {
-    struct elf_phdr * ppnt;
-    int i;
-
-    /* First cover the shared library/dynamic linker. */
-    if(tpnt->dynamic_info[DT_TEXTREL]) {
-      header = (struct elfhdr *) dl_data[AT_BASE];         
-      ppnt = (struct elf_phdr *) (dl_data[AT_BASE] + header->e_phoff);
-      for(i=0; i<header->e_phnum ; i++, ppnt++) {
-       if(ppnt->p_type == PT_LOAD && !(ppnt->p_flags & PF_W))
-               _dl_mprotect((void *) (load_addr + (ppnt->p_vaddr & 0xfffff000)),
-                             (ppnt->p_vaddr & 0xfff) + (unsigned int) ppnt->p_filesz,
-                             PROT_READ | PROT_WRITE | PROT_EXEC);
-      }
-    }
-    
-    /* Now cover the application program. */
-    if(app_tpnt->dynamic_info[DT_TEXTREL]) {
-      ppnt = (struct elf_phdr *) dl_data[AT_PHDR];
-      for(i=0; i<dl_data[AT_PHNUM]; i++, ppnt++) {
-       if(ppnt->p_type == PT_LOAD && !(ppnt->p_flags & PF_W))
-         _dl_mprotect((void *) (ppnt->p_vaddr & 0xfffff000),
-                      (ppnt->p_vaddr & 0xfff) + (unsigned int) ppnt->p_filesz,
-                      PROT_READ | PROT_WRITE | PROT_EXEC);
-      }
-    }
-  }
-
-  /* OK, now do the relocations.  We do not do a lazy binding here, so
-   that once we are done, we have considerably more flexibility. */
-
-  goof = 0;
-  for(indx=0; indx < 2; indx++)
-    {
-      int i;
-      ELF_RELOC * rpnt;
-      unsigned int * reloc_addr;
-      unsigned int symbol_addr;
-      int symtab_index;
-      unsigned int rel_addr, rel_size;
-
-  
-#ifdef ELF_USES_RELOCA
-      rel_addr = (indx ? tpnt->dynamic_info[DT_JMPREL] : tpnt->dynamic_info[DT_RELA]);
-      rel_size = (indx ? tpnt->dynamic_info[DT_PLTRELSZ] : tpnt->dynamic_info[DT_RELASZ]);
-#else
-      rel_addr = (indx ? tpnt->dynamic_info[DT_JMPREL] : tpnt->dynamic_info[DT_REL]);
-      rel_size = (indx ? tpnt->dynamic_info[DT_PLTRELSZ] : tpnt->dynamic_info[DT_RELSZ]);
-#endif
+               /* See if we need to relocate this address */
+               mmap_zero = malloc_buffer = (unsigned char *) _dl_mmap((void *) 0, 4096, 
+                       PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, ZFILENO, 0);
+               if (_dl_mmap_check_error(mmap_zero)) {
+                       SEND_STDERR("dl_boot: mmap of /dev/zero failed!\n");
+                       _dl_exit(13);
+               }
+       }
 
+       tpnt = DL_MALLOC(sizeof(struct elf_resolve));
+       REALIGN();
+       _dl_memset(tpnt, 0, sizeof(*tpnt));
+       app_tpnt = DL_MALLOC(sizeof(struct elf_resolve));
+       REALIGN();
+       _dl_memset(app_tpnt, 0, sizeof(*app_tpnt));
 
-      if(!rel_addr) continue;
+       /*
+        * This is used by gdb to locate the chain of shared libraries that are currently loaded.
+        */
+       debug_addr = DL_MALLOC(sizeof(struct r_debug));
+       REALIGN();
+       _dl_memset(debug_addr, 0, sizeof(*debug_addr));
+
+       /* OK, that was easy.  Next scan the DYNAMIC section of the image.
+          We are only doing ourself right now - we will have to do the rest later */
+
+       while (dpnt->d_tag) {
+               tpnt->dynamic_info[dpnt->d_tag] = dpnt->d_un.d_val;
+               if (dpnt->d_tag == DT_TEXTREL || SVR4_BUGCOMPAT)
+                       tpnt->dynamic_info[DT_TEXTREL] = 1;
+               dpnt++;
+       }
 
-      /* Now parse the relocation information */
-      rpnt = (ELF_RELOC *) (rel_addr + load_addr);
-      for(i=0; i< rel_size; i+=sizeof(ELF_RELOC), rpnt++){
-       reloc_addr = (int *) (load_addr + (int)rpnt->r_offset);
-       symtab_index = ELF32_R_SYM(rpnt->r_info);
-       symbol_addr = 0;
-       if(symtab_index) {
-         char * strtab;
-         struct elf32_sym * symtab;
+       {
+               elf_phdr *ppnt;
+               int i;
+
+               ppnt = (elf_phdr *) dl_data[AT_PHDR];
+               for (i = 0; i < dl_data[AT_PHNUM]; i++, ppnt++)
+                       if (ppnt->p_type == PT_DYNAMIC) {
+                               dpnt = (Elf32_Dyn *) ppnt->p_vaddr;
+                               while (dpnt->d_tag) {
+                                       if (dpnt->d_tag > DT_JMPREL) {
+                                               dpnt++;
+                                               continue;
+                                       }
+                                       app_tpnt->dynamic_info[dpnt->d_tag] = dpnt->d_un.d_val;
+                                       if (dpnt->d_tag == DT_DEBUG)
+                                               dpnt->d_un.d_val = (int) debug_addr;
+                                       if (dpnt->d_tag == DT_TEXTREL || SVR4_BUGCOMPAT)
+                                               app_tpnt->dynamic_info[DT_TEXTREL] = 1;
+                                       dpnt++;
+                               }
+                       }
+       }
 
-         symtab = (struct elf32_sym *) (tpnt->dynamic_info[DT_SYMTAB]+load_addr);
-         strtab = (char *) (tpnt->dynamic_info[DT_STRTAB]+load_addr);
+       /* Get some more of the information that we will need to dynamicly link
+          this module to itself */
 
-         /* We only do a partial dynamic linking right now.  The user
-            is not supposed to redefine any symbols that start with
-            a '_', so we can do this with confidence. */
+       hash_addr = (unsigned int *) (tpnt->dynamic_info[DT_HASH] + load_addr);
+       tpnt->nbucket = *hash_addr++;
+       tpnt->nchain = *hash_addr++;
+       tpnt->elf_buckets = hash_addr;
+       hash_addr += tpnt->nbucket;
+       chains = hash_addr;
 
-         if (!_dl_symbol(strtab + symtab[symtab_index].st_name)) continue;
+       /* Ugly, ugly.  We need to call mprotect to change the protection of
+          the text pages so that we can do the dynamic linking.  We can set the
+          protection back again once we are done */
 
-         symbol_addr = load_addr + symtab[symtab_index].st_value;
+       {
+               elf_phdr *ppnt;
+               int i;
+
+               /* First cover the shared library/dynamic linker. */
+               if (tpnt->dynamic_info[DT_TEXTREL]) {
+                       header = (elfhdr *) dl_data[AT_BASE];
+                       ppnt = (elf_phdr *) (dl_data[AT_BASE] + header->e_phoff);
+                       for (i = 0; i < header->e_phnum; i++, ppnt++) {
+                               if (ppnt->p_type == PT_LOAD && !(ppnt->p_flags & PF_W))
+                                       _dl_mprotect((void *) (load_addr + 
+                                               (ppnt->p_vaddr & 0xfffff000)), 
+                                               (ppnt->p_vaddr & 0xfff) + 
+                                               (unsigned int) ppnt->p_filesz, 
+                                               PROT_READ | PROT_WRITE | PROT_EXEC);
+                       }
+               }
 
-         if(!symbol_addr) {
-           /*
-            * This will segfault - you cannot call a function until
-            * we have finished the relocations.
-            */
-           SEND_STDERR("ELF dynamic loader - unable to self-bootstrap - symbol ");
-           SEND_STDERR(strtab + symtab[symtab_index].st_name);
-           SEND_STDERR(" undefined.\n");
-           goof++;
-         }
+               /* Now cover the application program. */
+               if (app_tpnt->dynamic_info[DT_TEXTREL]) {
+                       ppnt = (elf_phdr *) dl_data[AT_PHDR];
+                       for (i = 0; i < dl_data[AT_PHNUM]; i++, ppnt++) {
+                               if (ppnt->p_type == PT_LOAD && !(ppnt->p_flags & PF_W))
+                                       _dl_mprotect((void *) (ppnt->p_vaddr & 0xfffff000), 
+                                               (ppnt->p_vaddr & 0xfff) + 
+                                               (unsigned int) ppnt->p_filesz, 
+                                               PROT_READ | PROT_WRITE | PROT_EXEC);
+                       }
+               }
        }
-       /*
-        * Use this machine-specific macro to perform the actual relocation.
-        */
-       PERFORM_BOOTSTRAP_RELOC(rpnt, reloc_addr, symbol_addr, load_addr);
-      }
-    }
 
-  if (goof)    _dl_exit(14);
+       /* OK, now do the relocations.  We do not do a lazy binding here, so
+          that once we are done, we have considerably more flexibility. */
+
+       goof = 0;
+       for (indx = 0; indx < 2; indx++) {
+               int i;
+               ELF_RELOC *rpnt;
+               unsigned int *reloc_addr;
+               unsigned int symbol_addr;
+               int symtab_index;
+               unsigned int rel_addr, rel_size;
+
+
+#ifdef ELF_USES_RELOCA
+               rel_addr =
+                       (indx ? tpnt->dynamic_info[DT_JMPREL] : tpnt->
+                        dynamic_info[DT_RELA]);
+               rel_size =
+                       (indx ? tpnt->dynamic_info[DT_PLTRELSZ] : tpnt->
+                        dynamic_info[DT_RELASZ]);
+#else
+               rel_addr =
+                       (indx ? tpnt->dynamic_info[DT_JMPREL] : tpnt->
+                        dynamic_info[DT_REL]);
+               rel_size =
+                       (indx ? tpnt->dynamic_info[DT_PLTRELSZ] : tpnt->
+                        dynamic_info[DT_RELSZ]);
+#endif
+
 
-  /* OK, at this point we have a crude malloc capability.  Start to build
-     the tables of the modules that are required for this beast to run.
-     We start with the basic executable, and then go from there.  Eventually
-     we will run across ourself, and we will need to properly deal with that
-     as well. */
+               if (!rel_addr)
+                       continue;
+
+               /* Now parse the relocation information */
+               rpnt = (ELF_RELOC *) (rel_addr + load_addr);
+               for (i = 0; i < rel_size; i += sizeof(ELF_RELOC), rpnt++) {
+                       reloc_addr = (int *) (load_addr + (int) rpnt->r_offset);
+                       symtab_index = ELF32_R_SYM(rpnt->r_info);
+                       symbol_addr = 0;
+                       if (symtab_index) {
+                               char *strtab;
+                               Elf32_Sym *symtab;
+
+                               symtab = (Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB] +
+                                                                  load_addr);
+                               strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + load_addr);
+
+                               /* We only do a partial dynamic linking right now.  The user
+                                  is not supposed to redefine any symbols that start with
+                                  a '_', so we can do this with confidence. */
+
+                               if (!_dl_symbol(strtab + symtab[symtab_index].st_name))
+                                       continue;
+
+                               symbol_addr = load_addr + symtab[symtab_index].st_value;
+
+                               if (!symbol_addr) {
+                                       /*
+                                        * This will segfault - you cannot call a function until
+                                        * we have finished the relocations.
+                                        */
+                                       SEND_STDERR("ELF dynamic loader - unable to "
+                                               "self-bootstrap - symbol ");
+                                       SEND_STDERR(strtab + symtab[symtab_index].st_name);
+                                       SEND_STDERR(" undefined.\n");
+                                       goof++;
+                               }
+                       }
+                       /*
+                        * Use this machine-specific macro to perform the actual relocation.
+                        */
+                       PERFORM_BOOTSTRAP_RELOC(rpnt, reloc_addr, symbol_addr, load_addr);
+               }
+       }
+
+       if (goof) {
+               _dl_exit(14);
+       }
 
-  _dl_malloc_addr = malloc_buffer;
+       /* OK, at this point we have a crude malloc capability.  Start to build
+          the tables of the modules that are required for this beast to run.
+          We start with the basic executable, and then go from there.  Eventually
+          we will run across ourself, and we will need to properly deal with that
+          as well. */
 
-  _dl_mmap_zero = mmap_zero;
+       _dl_malloc_addr = malloc_buffer;
+
+       _dl_mmap_zero = mmap_zero;
 /*  tpnt = _dl_malloc(sizeof(struct elf_resolve)); */
 
 /* Now we have done the mandatory linking of some things.  We are now
@@ -426,573 +430,594 @@ void _dl_boot(int args){
    fixed up by now.  Still no function calls outside of this library ,
    since the dynamic resolver is not yet ready. */
 
-  lpnt = (int *) (tpnt->dynamic_info[DT_PLTGOT] + load_addr);
-  INIT_GOT(lpnt, tpnt);
-
-  /* OK, this was a big step, now we need to scan all of the user images
-     and load them properly. */
-
-  tpnt->next = 0;
-  tpnt->libname = 0;
-  tpnt->libtype = program_interpreter;
-
-  { struct elfhdr * epnt;
-    struct elf_phdr * ppnt;
-    int i;
-
-    epnt = (struct elfhdr *) dl_data[AT_BASE];
-    tpnt->n_phent = epnt->e_phnum;
-    tpnt->ppnt = ppnt = (struct elf_phdr *) (load_addr + epnt->e_phoff);
-    for(i=0;i < epnt->e_phnum; i++, ppnt++){
-      if(ppnt->p_type == PT_DYNAMIC) {
-       tpnt->dynamic_addr = ppnt->p_vaddr + load_addr;
-       tpnt->dynamic_size = ppnt->p_filesz;
-      }
-    }
-  }
-
-  tpnt->chains = chains;
-  tpnt->loadaddr = (char *) load_addr;
-
-  brk_addr = 0;
-  rpnt = NULL;
-
-  /* At this point we are now free to examine the user application,
-     and figure out which libraries are supposed to be called.  Until
-     we have this list, we will not be completely ready for dynamic linking */
-
-  {
-    struct elf_phdr * ppnt;
-    int i;
-
-    ppnt = (struct elf_phdr *) dl_data[AT_PHDR];
-    for(i=0; i<dl_data[AT_PHNUM]; i++, ppnt++) {
-      if(ppnt->p_type == PT_LOAD) {
-       if(ppnt->p_vaddr + ppnt->p_memsz > brk_addr) 
-         brk_addr = ppnt->p_vaddr + ppnt->p_memsz;
-      }
-      if(ppnt->p_type == PT_DYNAMIC) {
+       lpnt = (int *) (tpnt->dynamic_info[DT_PLTGOT] + load_addr);
+       INIT_GOT(lpnt, tpnt);
+
+       /* OK, this was a big step, now we need to scan all of the user images
+          and load them properly. */
+
+       tpnt->next = 0;
+       tpnt->libname = 0;
+       tpnt->libtype = program_interpreter;
+
+       {
+               elfhdr *epnt;
+               elf_phdr *ppnt;
+               int i;
+
+               epnt = (elfhdr *) dl_data[AT_BASE];
+               tpnt->n_phent = epnt->e_phnum;
+               tpnt->ppnt = ppnt = (elf_phdr *) (load_addr + epnt->e_phoff);
+               for (i = 0; i < epnt->e_phnum; i++, ppnt++) {
+                       if (ppnt->p_type == PT_DYNAMIC) {
+                               tpnt->dynamic_addr = ppnt->p_vaddr + load_addr;
+                               tpnt->dynamic_size = ppnt->p_filesz;
+                       }
+               }
+       }
+
+       tpnt->chains = chains;
+       tpnt->loadaddr = (char *) load_addr;
+
+       brk_addr = 0;
+       rpnt = NULL;
+
+       /* At this point we are now free to examine the user application,
+          and figure out which libraries are supposed to be called.  Until
+          we have this list, we will not be completely ready for dynamic linking */
+
+       {
+               elf_phdr *ppnt;
+               int i;
+
+               ppnt = (elf_phdr *) dl_data[AT_PHDR];
+               for (i = 0; i < dl_data[AT_PHNUM]; i++, ppnt++) {
+                       if (ppnt->p_type == PT_LOAD) {
+                               if (ppnt->p_vaddr + ppnt->p_memsz > brk_addr)
+                                       brk_addr = ppnt->p_vaddr + ppnt->p_memsz;
+                       }
+                       if (ppnt->p_type == PT_DYNAMIC) {
 #ifndef ALLOW_ZERO_PLTGOT
-       /* make sure it's really there. */
-       if (app_tpnt->dynamic_info[DT_PLTGOT] == 0) continue;
+                               /* make sure it's really there. */
+                               if (app_tpnt->dynamic_info[DT_PLTGOT] == 0)
+                                       continue;
 #endif
-       /* OK, we have what we need - slip this one into the list. */
-       app_tpnt = _dl_add_elf_hash_table("", 0, 
-                           app_tpnt->dynamic_info, ppnt->p_vaddr, ppnt->p_filesz);
-       _dl_loaded_modules->libtype = elf_executable;
-       _dl_loaded_modules->ppnt = (struct elf_phdr *) dl_data[AT_PHDR];
-       _dl_loaded_modules->n_phent = dl_data[AT_PHNUM];
-       _dl_symbol_tables = rpnt = 
-          (struct dyn_elf *) _dl_malloc(sizeof(struct dyn_elf));
-       _dl_memset (rpnt, 0, sizeof (*rpnt));
-       rpnt->dyn = _dl_loaded_modules;
-       app_tpnt->usage_count++;
-       app_tpnt->symbol_scope = _dl_symbol_tables;
-       lpnt = (int *) (app_tpnt->dynamic_info[DT_PLTGOT]);
+                               /* OK, we have what we need - slip this one into the list. */
+                               app_tpnt = _dl_add_elf_hash_table("", 0, 
+                                       app_tpnt->dynamic_info, ppnt->p_vaddr, ppnt->p_filesz);
+                               _dl_loaded_modules->libtype = elf_executable;
+                               _dl_loaded_modules->ppnt = (elf_phdr *) dl_data[AT_PHDR];
+                               _dl_loaded_modules->n_phent = dl_data[AT_PHNUM];
+                               _dl_symbol_tables = rpnt =
+                                       (struct dyn_elf *) _dl_malloc(sizeof(struct dyn_elf));
+                               _dl_memset(rpnt, 0, sizeof(*rpnt));
+                               rpnt->dyn = _dl_loaded_modules;
+                               app_tpnt->usage_count++;
+                               app_tpnt->symbol_scope = _dl_symbol_tables;
+                               lpnt = (int *) (app_tpnt->dynamic_info[DT_PLTGOT]);
 #ifdef ALLOW_ZERO_PLTGOT
-       if (lpnt)
+                               if (lpnt)
 #endif
-         INIT_GOT(lpnt, _dl_loaded_modules);
-      }
-      if(ppnt->p_type == PT_INTERP) { /* OK, fill this in - we did not have
-                                        this before */
-       tpnt->libname =  _dl_strdup((char *) ppnt->p_offset +(dl_data[AT_PHDR] & 0xfffff000));
-      }
-    }
-  }
-
-  if (argv[0])
-    _dl_progname = argv[0];
-
-  /* Now we need to figure out what kind of options are selected.
-   Note that for SUID programs we ignore the settings in LD_LIBRARY_PATH */
-  {
-    _dl_not_lazy = _dl_getenv("LD_BIND_NOW",envp);
-
-    if ( (dl_data[AT_UID] == -1 && _dl_suid_ok()) ||
-        (dl_data[AT_UID] != -1 && dl_data[AT_UID] == dl_data[AT_EUID] &&
-         dl_data[AT_GID] == dl_data[AT_EGID]))
-    {
-      _dl_secure = 0;
-      _dl_preload = _dl_getenv("LD_PRELOAD", envp);
-      _dl_library_path = _dl_getenv("LD_LIBRARY_PATH",envp);
-    }
-    else
-    {
-      _dl_secure = 1;
-      _dl_preload = _dl_getenv("LD_PRELOAD", envp);
-      _dl_unsetenv("LD_AOUT_PRELOAD", envp);
-      _dl_unsetenv("LD_LIBRARY_PATH", envp);
-      _dl_unsetenv("LD_AOUT_LIBRARY_PATH", envp);
-      _dl_library_path = NULL;
-    }
-  }
-
-  _dl_trace_loaded_objects = _dl_getenv("LD_TRACE_LOADED_OBJECTS", envp);
-
-  /* OK, we now have the application in the list, and we have some
-     basic stuff in place.  Now search through the list for other shared
-     libraries that should be loaded, and insert them on the list in the
-     correct order. */
+                                       INIT_GOT(lpnt, _dl_loaded_modules);
+                       }
+                       if (ppnt->p_type == PT_INTERP) {        /* OK, fill this in - we did not 
+                                                                  have this before */
+                               tpnt->libname = _dl_strdup((char *) ppnt->p_offset +
+                                                          (dl_data[AT_PHDR] & 0xfffff000));
+                       }
+               }
+       }
+
+       if (argv[0]) {
+               _dl_progname = argv[0];
+       }
+
+       /* Now we need to figure out what kind of options are selected.
+          Note that for SUID programs we ignore the settings in LD_LIBRARY_PATH */
+       {
+               _dl_not_lazy = _dl_getenv("LD_BIND_NOW", envp);
+
+               if ((dl_data[AT_UID] == -1 && _dl_suid_ok()) ||
+                       (dl_data[AT_UID] != -1 && dl_data[AT_UID] == dl_data[AT_EUID]
+                        && dl_data[AT_GID] == dl_data[AT_EGID])) {
+                       _dl_secure = 0;
+                       _dl_preload = _dl_getenv("LD_PRELOAD", envp);
+                       _dl_library_path = _dl_getenv("LD_LIBRARY_PATH", envp);
+               } else {
+                       _dl_secure = 1;
+                       _dl_preload = _dl_getenv("LD_PRELOAD", envp);
+                       _dl_unsetenv("LD_AOUT_PRELOAD", envp);
+                       _dl_unsetenv("LD_LIBRARY_PATH", envp);
+                       _dl_unsetenv("LD_AOUT_LIBRARY_PATH", envp);
+                       _dl_library_path = NULL;
+               }
+       }
+
+       _dl_trace_loaded_objects = _dl_getenv("LD_TRACE_LOADED_OBJECTS", envp);
+
+       /* OK, we now have the application in the list, and we have some
+          basic stuff in place.  Now search through the list for other shared
+          libraries that should be loaded, and insert them on the list in the
+          correct order. */
+
+#ifdef USE_CACHE
+       _dl_map_cache();
+#endif
+
+       {
+               struct elf_resolve *tcurr;
+               struct elf_resolve *tpnt1;
+               char *lpnt;
+
+               if (_dl_preload) 
+               {
+                       char c, *str, *str2;
+
+                       str = _dl_preload;
+                       while (*str == ':' || *str == ' ' || *str == '\t')
+                               str++;
+                       while (*str) 
+                       {
+                               str2 = str;
+                               while (*str2 && *str2 != ':' && *str2 != ' ' && *str2 != '\t')
+                                       str2++;
+                               c = *str2;
+                               *str2 = '\0';
+                               if (!_dl_secure || _dl_strchr(str, '/') == NULL) 
+                               {
+                                       tpnt1 = _dl_load_shared_library(_dl_secure, NULL, str);
+                                       if (!tpnt1) {
+                                               if (_dl_trace_loaded_objects)
+                                                       _dl_fdprintf(1, "\t%s => not found\n", str);
+                                               else {
+                                                       _dl_fdprintf(2, "%s: can't load "
+                                                               "library '%s'\n", _dl_progname, str);
+                                                       _dl_exit(15);
+                                               }
+                                       } else {
+                                               if (_dl_trace_loaded_objects
+                                                       && !tpnt1->usage_count) {
+                                                       /* this is a real hack to make ldd not print 
+                                                        * the library itself when run on a library. */
+                                                       if (_dl_strcmp(_dl_progname, str) != 0)
+                                                               _dl_fdprintf(1, "\t%s => %s (0x%x)\n", 
+                                                                       str, tpnt1->libname, 
+                                                                       (unsigned) tpnt1->loadaddr);
+                                               }
+                                               rpnt->next = (struct dyn_elf *)
+                                                       _dl_malloc(sizeof(struct dyn_elf));
+                                               _dl_memset(rpnt->next, 0, sizeof(*(rpnt->next)));
+                                               rpnt = rpnt->next;
+                                               tpnt1->usage_count++;
+                                               tpnt1->symbol_scope = _dl_symbol_tables;
+                                               tpnt1->libtype = elf_lib;
+                                               rpnt->dyn = tpnt1;
+                                       }
+                               }
+                               *str2 = c;
+                               str = str2;
+                               while (*str == ':' || *str == ' ' || *str == '\t')
+                                       str++;
+                       }
+               }
+
+               {
+                       int fd;
+                       struct kernel_stat st;
+                       char *preload;
+
+                       if (!_dl_stat(LDSO_PRELOAD, &st)) {
+                               if ((fd = _dl_open(LDSO_PRELOAD, O_RDONLY)) < 0) {
+                                       _dl_fdprintf(2, "%s: can't open file '%s'\n", 
+                                               _dl_progname, LDSO_PRELOAD);
+                               } else {
+                                       preload = (caddr_t) _dl_mmap(0, st.st_size + 1, 
+                                               PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
+                                       _dl_close(fd);
+                                       if (preload == (caddr_t) - 1) {
+                                               _dl_fdprintf(2, "%s: can't map file '%s'\n", 
+                                                       _dl_progname, LDSO_PRELOAD);
+                                       } else {
+                                               char c, *cp, *cp2;
+
+                                               /* convert all separators and comments to spaces */
+                                               for (cp = preload; *cp; /*nada */ ) {
+                                                       if (*cp == ':' || *cp == '\t' || *cp == '\n') {
+                                                               *cp++ = ' ';
+                                                       } else if (*cp == '#') {
+                                                               do
+                                                                       *cp++ = ' ';
+                                                               while (*cp != '\n' && *cp != '\0');
+                                                       } else {
+                                                               cp++;
+                                                       }
+                                               }
+
+                                               /* find start of first library */
+                                               for (cp = preload; *cp && *cp == ' '; cp++)
+                                                       /*nada */ ;
+
+                                               while (*cp) {
+                                                       /* find end of library */
+                                                       for (cp2 = cp; *cp && *cp != ' '; cp++)
+                                                               /*nada */ ;
+                                                       c = *cp;
+                                                       *cp = '\0';
+
+                                                       tpnt1 = _dl_load_shared_library(0, NULL, cp2);
+                                                       if (!tpnt1) {
+                                                               if (_dl_trace_loaded_objects)
+                                                                       _dl_fdprintf(1, "\t%s => not "
+                                                                               "found\n", cp2);
+                                                               else {
+                                                                       _dl_fdprintf(2, "%s: can't "
+                                                                               "load library '%s'\n", 
+                                                                               _dl_progname, cp2);
+                                                                       _dl_exit(15);
+                                                               }
+                                                       } else {
+                                                               if (_dl_trace_loaded_objects
+                                                                       && !tpnt1->usage_count) {
+                                                                       _dl_fdprintf(1, "\t%s => %s "
+                                                                               "(0x%x)\n", cp2, 
+                                                                               tpnt1->libname, 
+                                                                               (unsigned) tpnt1->loadaddr);
+                                                               }
+                                                               rpnt->next = (struct dyn_elf *)
+                                                                       _dl_malloc(sizeof(struct dyn_elf));
+                                                               _dl_memset(rpnt->next, 0, 
+                                                                       sizeof(*(rpnt->next)));
+                                                               rpnt = rpnt->next;
+                                                               tpnt1->usage_count++;
+                                                               tpnt1->symbol_scope = _dl_symbol_tables;
+                                                               tpnt1->libtype = elf_lib;
+                                                               rpnt->dyn = tpnt1;
+                                                       }
+
+                                                       /* find start of next library */
+                                                       *cp = c;
+                                                       for ( /*nada */ ; *cp && *cp == ' '; cp++)
+                                                               /*nada */ ;
+                                               }
+
+                                               _dl_munmap(preload, st.st_size + 1);
+                                       }
+                               }
+                       }
+               }
+
+               for (tcurr = _dl_loaded_modules; tcurr; tcurr = tcurr->next) {
+                       for (dpnt = (Elf32_Dyn *) tcurr->dynamic_addr; dpnt->d_tag;
+                                dpnt++) {
+                               if (dpnt->d_tag == DT_NEEDED) {
+                                       lpnt = tcurr->loadaddr + tcurr->dynamic_info[DT_STRTAB] +
+                                               dpnt->d_un.d_val;
+                                       if (tpnt && _dl_strcmp(lpnt, tpnt->libname) == 0) {
+                                               struct elf_resolve *ttmp;
+
+                                               ttmp = _dl_loaded_modules;
+                                               while (ttmp->next)
+                                                       ttmp = ttmp->next;
+                                               ttmp->next = tpnt;
+                                               tpnt->prev = ttmp;
+                                               tpnt->next = NULL;
+                                               rpnt->next = (struct dyn_elf *)
+                                                       _dl_malloc(sizeof(struct dyn_elf));
+                                               _dl_memset(rpnt->next, 0, sizeof(*(rpnt->next)));
+                                               rpnt = rpnt->next;
+                                               rpnt->dyn = tpnt;
+                                               tpnt->usage_count++;
+                                               tpnt->symbol_scope = _dl_symbol_tables;
+                                               tpnt = NULL;
+                                               continue;
+                                       }
+                                       if (!(tpnt1 = _dl_load_shared_library(0, tcurr, lpnt))) {
+                                               if (_dl_trace_loaded_objects)
+                                                       _dl_fdprintf(1, "\t%s => not found\n", lpnt);
+                                               else {
+                                                       _dl_fdprintf(2, "%s: can't load library '%s'\n", 
+                                                               _dl_progname, lpnt);
+                                                       _dl_exit(16);
+                                               }
+                                       } else {
+                                               if (_dl_trace_loaded_objects
+                                                       && !tpnt1->usage_count)
+                                                       _dl_fdprintf(1, "\t%s => %s (0x%x)\n", lpnt, 
+                                                               tpnt1->libname, (unsigned) tpnt1->loadaddr);
+                                               rpnt->next = (struct dyn_elf *)
+                                                       _dl_malloc(sizeof(struct dyn_elf));
+                                               _dl_memset(rpnt->next, 0, sizeof(*(rpnt->next)));
+                                               rpnt = rpnt->next;
+                                               tpnt1->usage_count++;
+                                               tpnt1->symbol_scope = _dl_symbol_tables;
+                                               tpnt1->libtype = elf_lib;
+                                               rpnt->dyn = tpnt1;
+                                       }
+                               }
+                       }
+               }
+       }
 
 #ifdef USE_CACHE
-  _dl_map_cache();
+       _dl_unmap_cache();
 #endif
 
-  {
-    struct elf_resolve *tcurr;
-    struct elf_resolve *tpnt1;
-    char *lpnt;
-
-    if (_dl_preload) {
-      char c, *str, *str2;
-
-      str = _dl_preload;
-      while (*str == ':' || *str == ' ' || *str == '\t')
-       str++;
-      while (*str) {
-       str2 = str;
-       while (*str2 && *str2 != ':' && *str2 != ' ' && *str2 != '\t')
-         str2++;
-       c = *str2;
-       *str2 = '\0';
-       if (!_dl_secure || _dl_strchr(str, '/') == NULL) {
-         tpnt1 = _dl_load_shared_library(_dl_secure, NULL, str);
-         if (!tpnt1) {
-           if (_dl_trace_loaded_objects)
-             _dl_fdprintf(1, "\t%s => not found\n", str);
-           else {
-             _dl_fdprintf(2, "%s: can't load library '%s'\n",
-                          _dl_progname, str);
-             _dl_exit(15);
-           }
-         } else {
-           if (_dl_trace_loaded_objects && !tpnt1->usage_count) {
-             /* this is a real hack to make ldd not print the
-                library itself when run on a library. */
-             if (_dl_strcmp(_dl_progname, str) != 0)
-               _dl_fdprintf(1, "\t%s => %s (0x%x)\n", str, tpnt1->libname,
-                            (unsigned)tpnt1->loadaddr);
-           }
-           rpnt->next = 
-             (struct dyn_elf *) _dl_malloc(sizeof(struct dyn_elf));
-           _dl_memset (rpnt->next, 0, sizeof (*(rpnt->next)));
-           rpnt = rpnt->next;
-           tpnt1->usage_count++;
-           tpnt1->symbol_scope = _dl_symbol_tables;
-           tpnt1->libtype = elf_lib;
-           rpnt->dyn = tpnt1;
-         }
+       /* ldd uses uses this.  I am not sure how you pick up the other flags */
+       if (_dl_trace_loaded_objects) {
+               _dl_warn = _dl_getenv("LD_WARN", envp);
+               if (!_dl_warn)
+                       _dl_exit(0);
        }
-       *str2 = c;
-       str = str2;
-       while (*str == ':' || *str == ' ' || *str == '\t')
-         str++;
-      }
-    }
-
-    {
-      int fd;
-      struct kernel_stat st;
-      char *preload;
-
-      if (!_dl_stat(LDSO_PRELOAD, &st)) {
-       if ((fd = _dl_open(LDSO_PRELOAD, O_RDONLY)) < 0) {
-         _dl_fdprintf(2, "%s: can't open file '%s'\n", _dl_progname, 
-                      LDSO_PRELOAD);
-       } else {
-         preload = (caddr_t)_dl_mmap(0, st.st_size+1, PROT_READ|PROT_WRITE, 
-                                     MAP_PRIVATE, fd, 0);
-         _dl_close (fd);
-         if (preload == (caddr_t)-1) {
-           _dl_fdprintf(2, "%s: can't map file '%s'\n", _dl_progname, 
-                        LDSO_PRELOAD);
-         } else {
-           char c, *cp, *cp2;
-
-           /* convert all separators and comments to spaces */
-           for (cp = preload; *cp; /*nada*/) {
-             if (*cp == ':' || *cp == '\t' || *cp == '\n') {
-               *cp++ = ' ';
-             } else if (*cp == '#') {
-               do
-                 *cp++ = ' ';
-               while (*cp != '\n' && *cp != '\0');
-             } else {
-               cp++;
-             }
-           }
-
-           /* find start of first library */
-           for (cp = preload; *cp && *cp == ' '; cp++)
-             /*nada*/;
-
-           while (*cp) {
-             /* find end of library */
-             for (cp2 = cp; *cp && *cp != ' '; cp++)
-               /*nada*/;
-             c = *cp;
-             *cp = '\0';
-
-             tpnt1 = _dl_load_shared_library(0, NULL, cp2);
-             if (!tpnt1) {
-               if (_dl_trace_loaded_objects)
-                 _dl_fdprintf(1, "\t%s => not found\n", cp2);
-               else {
-                 _dl_fdprintf(2, "%s: can't load library '%s'\n",
-                              _dl_progname, cp2);
-                 _dl_exit(15);
+
+       /*
+        * If the program interpreter is not in the module chain, add it.  This will
+        * be required for dlopen to be able to access the internal functions in the 
+        * dynamic linker.
+        */
+       if (tpnt) {
+               struct elf_resolve *tcurr;
+
+               tcurr = _dl_loaded_modules;
+               if (tcurr)
+                       while (tcurr->next)
+                               tcurr = tcurr->next;
+               tpnt->next = NULL;
+               tpnt->usage_count++;
+
+               if (tcurr) {
+                       tcurr->next = tpnt;
+                       tpnt->prev = tcurr;
+               } else {
+                       _dl_loaded_modules = tpnt;
+                       tpnt->prev = NULL;
                }
-             } else {
-               if (_dl_trace_loaded_objects && !tpnt1->usage_count)
-                 _dl_fdprintf(1, "\t%s => %s (0x%x)\n", cp2, tpnt1->libname,
-                              (unsigned)tpnt1->loadaddr);
-                rpnt->next = 
-                 (struct dyn_elf *) _dl_malloc(sizeof(struct dyn_elf));
-               _dl_memset (rpnt->next, 0, sizeof (*(rpnt->next)));
-               rpnt = rpnt->next;
-               tpnt1->usage_count++;
-               tpnt1->symbol_scope = _dl_symbol_tables;
-               tpnt1->libtype = elf_lib;
-               rpnt->dyn = tpnt1;
-             }
-
-             /* find start of next library */
-             *cp = c;
-             for (/*nada*/; *cp && *cp == ' '; cp++)
-               /*nada*/;
-           }
-
-           _dl_munmap(preload, st.st_size+1);
-         }
+               if (rpnt) {
+                       rpnt->next = (struct dyn_elf *) _dl_malloc(sizeof(struct dyn_elf));
+                       _dl_memset(rpnt->next, 0, sizeof(*(rpnt->next)));
+                       rpnt = rpnt->next;
+               } else {
+                       rpnt = (struct dyn_elf *) _dl_malloc(sizeof(struct dyn_elf));
+                       _dl_memset(rpnt, 0, sizeof(*(rpnt->next)));
+               }
+               rpnt->dyn = tpnt;
+               tpnt = NULL;
        }
-      }
-    }
-
-    for (tcurr = _dl_loaded_modules; tcurr; tcurr = tcurr->next)
-    {
-      for (dpnt = (struct dynamic *)tcurr->dynamic_addr; dpnt->d_tag; dpnt++)
-      {
-       if(dpnt->d_tag == DT_NEEDED)
+
+       /*
+        * OK, now all of the kids are tucked into bed in their proper addresses.
+        * Now we go through and look for REL and RELA records that indicate fixups
+        * to the GOT tables.  We need to do this in reverse order so that COPY
+        * directives work correctly */
+
+
+       goof = _dl_loaded_modules ? _dl_fixup(_dl_loaded_modules) : 0;
+
+
+       /* Some flavors of SVr4 do not generate the R_*_COPY directive,
+          and we have to manually search for entries that require fixups. 
+          Solaris gets this one right, from what I understand.  */
+
+
+       if (_dl_symbol_tables)
+               goof += _dl_copy_fixups(_dl_symbol_tables);
+
+       if (goof || _dl_trace_loaded_objects)
+               _dl_exit(0);
+
+       /* OK, at this point things are pretty much ready to run.  Now we
+          need to touch up a few items that are required, and then
+          we can let the user application have at it.  Note that
+          the dynamic linker itself is not guaranteed to be fully
+          dynamicly linked if we are using ld.so.1, so we have to look
+          up each symbol individually. */
+
+
+       _dl_brkp = (unsigned int *) _dl_find_hash("___brk_addr", NULL, 1, NULL, 0);
+       if (_dl_brkp)
+               *_dl_brkp = brk_addr;
+       _dl_envp =
+               (unsigned int *) _dl_find_hash("__environ", NULL, 1, NULL, 0);
+
+       if (_dl_envp)
+               *_dl_envp = (unsigned int) envp;
+
        {
-         lpnt = tcurr->loadaddr + tcurr->dynamic_info[DT_STRTAB] + 
-           dpnt->d_un.d_val;
-         if (tpnt && _dl_strcmp(lpnt, tpnt->libname) == 0)
-         {
-           struct elf_resolve * ttmp;
-           ttmp = _dl_loaded_modules;
-           while (ttmp->next) 
-             ttmp = ttmp->next;
-           ttmp->next = tpnt;
-           tpnt->prev = ttmp;
-           tpnt->next = NULL;
-           rpnt->next = 
-             (struct dyn_elf *) _dl_malloc(sizeof(struct dyn_elf));
-           _dl_memset (rpnt->next, 0, sizeof (*(rpnt->next)));
-           rpnt = rpnt->next;
-           rpnt->dyn = tpnt;
-           tpnt->usage_count++;
-           tpnt->symbol_scope = _dl_symbol_tables;
-           tpnt = NULL;
-           continue;
-         }
-         if (!(tpnt1 = _dl_load_shared_library(0, tcurr, lpnt)))
-         {
-           if (_dl_trace_loaded_objects)
-             _dl_fdprintf(1, "\t%s => not found\n", lpnt);
-           else
-           {
-             _dl_fdprintf(2, "%s: can't load library '%s'\n",
-                          _dl_progname, lpnt);
-             _dl_exit(16);
-           }
-         }
-         else
-         {
-           if (_dl_trace_loaded_objects && !tpnt1->usage_count)
-             _dl_fdprintf(1, "\t%s => %s (0x%x)\n", lpnt, tpnt1->libname,
-                          (unsigned)tpnt1->loadaddr);
-           rpnt->next = 
-             (struct dyn_elf *) _dl_malloc(sizeof(struct dyn_elf));
-           _dl_memset (rpnt->next, 0, sizeof (*(rpnt->next)));
-           rpnt = rpnt->next;
-           tpnt1->usage_count++;
-           tpnt1->symbol_scope = _dl_symbol_tables;
-           tpnt1->libtype = elf_lib;
-           rpnt->dyn = tpnt1;
-         }
+               int i;
+               elf_phdr *ppnt;
+
+               /* We had to set the protections of all pages to R/W for dynamic linking.
+                  Set text pages back to R/O */
+               for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next)
+                       for (ppnt = tpnt->ppnt, i = 0; i < tpnt->n_phent; i++, ppnt++)
+                               if (ppnt->p_type == PT_LOAD && !(ppnt->p_flags & PF_W) &&
+                                       tpnt->dynamic_info[DT_TEXTREL])
+                                       _dl_mprotect((void *) (tpnt->loadaddr + 
+                                                   (ppnt->p_vaddr & 0xfffff000)), 
+                                               (ppnt->p_vaddr & 0xfff) + 
+                                               (unsigned int) ppnt->p_filesz, 
+                                               LXFLAGS(ppnt->p_flags));
+
        }
-      }
-    }
-  }
 
-#ifdef USE_CACHE
-  _dl_unmap_cache();
-#endif
+       _dl_atexit = (int (*)(void *)) _dl_find_hash("atexit", NULL, 1, NULL, 0);
 
-    /* ldd uses uses this.  I am not sure how you pick up the other flags */ 
-  if(_dl_trace_loaded_objects)
-    {
-      _dl_warn = _dl_getenv("LD_WARN", envp);
-      if (!_dl_warn) _dl_exit(0);
-    }
-
-  /*
-   * If the program interpreter is not in the module chain, add it.  This will
-   * be required for dlopen to be able to access the internal functions in the 
-   * dynamic linker.
-   */
-  if(tpnt) {
-    struct elf_resolve * tcurr;
-
-    tcurr = _dl_loaded_modules;
-    if (tcurr)
-      while(tcurr->next) tcurr = tcurr->next;
-    tpnt->next = NULL;
-    tpnt->usage_count++;
-
-    if (tcurr) {
-      tcurr->next = tpnt;
-      tpnt->prev = tcurr;
-    }
-    else {
-      _dl_loaded_modules = tpnt;
-      tpnt->prev = NULL;
-    }
-    if (rpnt) {
-      rpnt->next = 
-       (struct dyn_elf *) _dl_malloc(sizeof(struct dyn_elf));
-      _dl_memset (rpnt->next, 0, sizeof (*(rpnt->next)));
-      rpnt = rpnt->next;
-    } else {
-      rpnt =   (struct dyn_elf *) _dl_malloc(sizeof(struct dyn_elf));
-      _dl_memset (rpnt, 0, sizeof (*(rpnt->next)));
-    }
-    rpnt->dyn = tpnt;
-    tpnt = NULL;
-  }
-
-  /*
-   * OK, now all of the kids are tucked into bed in their proper addresses.
-   * Now we go through and look for REL and RELA records that indicate fixups
-   * to the GOT tables.  We need to do this in reverse order so that COPY
-   * directives work correctly */
-
-
-  goof = _dl_loaded_modules ? _dl_fixup(_dl_loaded_modules) : 0;
-
-
-  /* Some flavors of SVr4 do not generate the R_*_COPY directive,
-   and we have to manually search for entries that require fixups. 
-   Solaris gets this one right, from what I understand.  */
-
-
-  if (_dl_symbol_tables)
-    goof += _dl_copy_fixups(_dl_symbol_tables);
-
-  if(goof || _dl_trace_loaded_objects) _dl_exit(0);
-
-  /* OK, at this point things are pretty much ready to run.  Now we
-     need to touch up a few items that are required, and then
-     we can let the user application have at it.  Note that
-     the dynamic linker itself is not guaranteed to be fully
-     dynamicly linked if we are using ld.so.1, so we have to look
-     up each symbol individually. */
-
-
-  _dl_brkp = (unsigned int *) _dl_find_hash("___brk_addr", NULL, 1, NULL, 0);
-  if (_dl_brkp) *_dl_brkp = brk_addr;
-  _dl_envp = (unsigned int *) _dl_find_hash("__environ", NULL, 1, NULL, 0);
-
-  if (_dl_envp) *_dl_envp = (unsigned int) envp;
-
-  {
-    int i;
-    struct elf_phdr * ppnt;
-
-  /* We had to set the protections of all pages to R/W for dynamic linking.
-     Set text pages back to R/O */
-  for(tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next)
-    for(ppnt = tpnt->ppnt, i=0; i < tpnt->n_phent; i++, ppnt++)
-      if(ppnt->p_type == PT_LOAD && !(ppnt->p_flags & PF_W) &&
-        tpnt->dynamic_info[DT_TEXTREL])
-       _dl_mprotect((void *) (tpnt->loadaddr + (ppnt->p_vaddr & 0xfffff000)),
-                    (ppnt->p_vaddr & 0xfff) + (unsigned int) ppnt->p_filesz,
-                    LXFLAGS(ppnt->p_flags));
-
-  }
-
-  _dl_atexit = (int (*)(void *)) _dl_find_hash("atexit", NULL, 1, NULL, 0);
-
-  /*
-   * OK, fix one more thing - set up the debug_addr structure to point
-   * to our chain.  Later we may need to fill in more fields, but this
-   * should be enough for now.
-   */
-  debug_addr->r_map = (struct link_map *) _dl_loaded_modules;
-  debug_addr->r_version = 1;
-  debug_addr->r_ldbase = load_addr;
-  debug_addr->r_brk = (unsigned long) &_dl_debug_state;
-  _dl_debug_addr = debug_addr;
-  debug_addr->r_state = RT_CONSISTENT;
-  /* This is written in this funny way to keep gcc from inlining the
-     function call. */
-  ((void (*)(void))debug_addr->r_brk)();
-
-  for(tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next)
-    {
-      /* Apparently crt1 for the application is responsible for handling this.
-       * We only need to run the init/fini for shared libraries
-       */
-      if (tpnt->libtype == program_interpreter ||
-       tpnt->libtype == elf_executable) continue;
-      if (tpnt->init_flag & INIT_FUNCS_CALLED) continue;
-      tpnt->init_flag |= INIT_FUNCS_CALLED;
-      
-      if(tpnt->dynamic_info[DT_INIT]) {
-       _dl_elf_init = (int (*)(void)) (tpnt->loadaddr + 
-                                   tpnt->dynamic_info[DT_INIT]);
-       (*_dl_elf_init)();
-      }
-      if(_dl_atexit && tpnt->dynamic_info[DT_FINI])
-      {
-        (*_dl_atexit)(tpnt->loadaddr + tpnt->dynamic_info[DT_FINI]);
-      }
+       /*
+        * OK, fix one more thing - set up the debug_addr structure to point
+        * to our chain.  Later we may need to fill in more fields, but this
+        * should be enough for now.
+        */
+       debug_addr->r_map = (struct link_map *) _dl_loaded_modules;
+       debug_addr->r_version = 1;
+       debug_addr->r_ldbase = load_addr;
+       debug_addr->r_brk = (unsigned long) &_dl_debug_state;
+       _dl_debug_addr = debug_addr;
+       debug_addr->r_state = RT_CONSISTENT;
+       /* This is written in this funny way to keep gcc from inlining the
+          function call. */
+       ((void (*)(void)) debug_addr->r_brk) ();
+
+       for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) {
+               /* Apparently crt1 for the application is responsible for handling this.
+                * We only need to run the init/fini for shared libraries
+                */
+               if (tpnt->libtype == program_interpreter ||
+                       tpnt->libtype == elf_executable)
+                       continue;
+               if (tpnt->init_flag & INIT_FUNCS_CALLED)
+                       continue;
+               tpnt->init_flag |= INIT_FUNCS_CALLED;
+
+               if (tpnt->dynamic_info[DT_INIT]) {
+                       _dl_elf_init = (int (*)(void)) (tpnt->loadaddr + 
+                               tpnt->dynamic_info[DT_INIT]);
+                       (*_dl_elf_init) ();
+               }
+               if (_dl_atexit && tpnt->dynamic_info[DT_FINI]) {
+                       (*_dl_atexit) (tpnt->loadaddr + tpnt->dynamic_info[DT_FINI]);
+               }
 #undef DL_DEBUG
 #ifdef DL_DEBUG
-      else
-      {
-       _dl_fdprintf(2, tpnt->libname);
-       _dl_fdprintf(2, ": ");
-       if (!_dl_atexit)
-         _dl_fdprintf(2, "The address is atexit () is 0x0.");
-       if (!tpnt->dynamic_info[DT_FINI])
-         _dl_fdprintf(2, "Invalid .fini section.");
-       _dl_fdprintf(2, "\n");
-      }
+               else {
+                       _dl_fdprintf(2, tpnt->libname);
+                       _dl_fdprintf(2, ": ");
+                       if (!_dl_atexit)
+                               _dl_fdprintf(2, "The address is atexit () is 0x0.");
+                       if (!tpnt->dynamic_info[DT_FINI])
+                               _dl_fdprintf(2, "Invalid .fini section.");
+                       _dl_fdprintf(2, "\n");
+               }
 #endif
 #undef DL_DEBUG
-   }
+       }
 
-  /* OK we are done here.  Turn out the lights, and lock up. */
-  _dl_elf_main = (int (*)(int, char**, char**)) dl_data[AT_ENTRY];
+       /* OK we are done here.  Turn out the lights, and lock up. */
+       _dl_elf_main = (int (*)(int, char **, char **)) dl_data[AT_ENTRY];
 
 
-  /*
-   * Transfer control to the application.
-   */
-  START();
+       /*
+        * Transfer control to the application.
+        */
+       START();
 }
 
-int _dl_fixup(struct elf_resolve * tpnt)
+int _dl_fixup(struct elf_resolve *tpnt)
 {
-  int goof = 0;
-  if(tpnt->next) goof += _dl_fixup(tpnt->next);
+       int goof = 0;
+
+       if (tpnt->next)
+               goof += _dl_fixup(tpnt->next);
 
-  if(tpnt->dynamic_info[DT_REL]) {
+       if (tpnt->dynamic_info[DT_REL]) {
 #ifdef ELF_USES_RELOCA
-    _dl_fdprintf(2, "%s: can't handle REL relocation records\n", _dl_progname);
-    _dl_exit(17);
+               _dl_fdprintf(2, "%s: can't handle REL relocation records\n", 
+                       _dl_progname);
+               _dl_exit(17);
 #else
-    if (tpnt->init_flag & RELOCS_DONE) return goof;
-    tpnt->init_flag |= RELOCS_DONE;
-   
-    goof += _dl_parse_relocation_information(tpnt, tpnt->dynamic_info[DT_REL],
-                                            tpnt->dynamic_info[DT_RELSZ], 0);
+               if (tpnt->init_flag & RELOCS_DONE)
+                       return goof;
+               tpnt->init_flag |= RELOCS_DONE;
+
+               goof += _dl_parse_relocation_information(tpnt, 
+                       tpnt->dynamic_info[DT_REL], tpnt->dynamic_info[DT_RELSZ], 0);
 #endif
-  }
-  if(tpnt->dynamic_info[DT_RELA]) {
+       }
+       if (tpnt->dynamic_info[DT_RELA]) {
 #ifdef ELF_USES_RELOCA
-    if (tpnt->init_flag & RELOCS_DONE) return goof;
-    tpnt->init_flag |= RELOCS_DONE;
-   
-    goof += _dl_parse_relocation_information(tpnt, tpnt->dynamic_info[DT_RELA],
-                                            tpnt->dynamic_info[DT_RELASZ], 0);
+               if (tpnt->init_flag & RELOCS_DONE)
+                       return goof;
+               tpnt->init_flag |= RELOCS_DONE;
+
+               goof += _dl_parse_relocation_information(tpnt, 
+                       tpnt->dynamic_info[DT_RELA], tpnt->dynamic_info[DT_RELASZ], 0);
 #else
-    _dl_fdprintf(2, "%s: can't handle RELA relocation records\n", _dl_progname);
-    _dl_exit(18);
+               _dl_fdprintf(2, "%s: can't handle RELA relocation records\n", 
+                       _dl_progname);
+               _dl_exit(18);
 #endif
-  }
-  if(tpnt->dynamic_info[DT_JMPREL])
-    {
-      if (tpnt->init_flag & JMP_RELOCS_DONE) return goof;
-      tpnt->init_flag |= JMP_RELOCS_DONE;
-      
-      if(! _dl_not_lazy || *_dl_not_lazy == 0)
-       _dl_parse_lazy_relocation_information(tpnt, tpnt->dynamic_info[DT_JMPREL],
-                                             tpnt->dynamic_info[DT_PLTRELSZ], 0);
-      else
-       goof +=  _dl_parse_relocation_information(tpnt,
-                                                 tpnt->dynamic_info[DT_JMPREL],
-                                                 tpnt->dynamic_info[DT_PLTRELSZ], 0);
-    }
-  return goof;
+       }
+       if (tpnt->dynamic_info[DT_JMPREL]) {
+               if (tpnt->init_flag & JMP_RELOCS_DONE)
+                       return goof;
+               tpnt->init_flag |= JMP_RELOCS_DONE;
+
+               if (!_dl_not_lazy || *_dl_not_lazy == 0)
+                       _dl_parse_lazy_relocation_information(tpnt, 
+                               tpnt->dynamic_info[DT_JMPREL], tpnt->dynamic_info[DT_PLTRELSZ], 0);
+               else
+                       goof += _dl_parse_relocation_information(tpnt, 
+                               tpnt->dynamic_info[DT_JMPREL], tpnt->dynamic_info[DT_PLTRELSZ], 0);
+       }
+       return goof;
 }
 
-void * _dl_malloc(int size) {
-  void * retval;
-
-  if(_dl_malloc_function)
-       return (*_dl_malloc_function)(size);
-
-  if(_dl_malloc_addr-_dl_mmap_zero+size>4096) {
-       _dl_mmap_zero = _dl_malloc_addr = (unsigned char *) _dl_mmap((void*) 0, size,
-                               PROT_READ | PROT_WRITE, 
-                               MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
-       if(_dl_mmap_check_error(_dl_mmap_zero)) {
-           _dl_fdprintf(2, "%s: can't map '/dev/zero'\n", _dl_progname);
-           _dl_exit(20);
-       }
-  }
-  retval = _dl_malloc_addr;
-  _dl_malloc_addr += size;
-
-  /*
-   * Align memory to 4 byte boundary.  Some platforms require this, others
-   * simply get better performance.
-   */
-  _dl_malloc_addr = (char *) (((unsigned int) _dl_malloc_addr + 3) & ~(3));
-  return retval;
+void *_dl_malloc(int size)
+{
+       void *retval;
+
+       if (_dl_malloc_function)
+               return (*_dl_malloc_function) (size);
+
+       if (_dl_malloc_addr - _dl_mmap_zero + size > 4096) {
+               _dl_mmap_zero = _dl_malloc_addr =
+                       (unsigned char *) _dl_mmap((void *) 0, size, 
+                                                  PROT_READ | PROT_WRITE, 
+                                                  MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+               if (_dl_mmap_check_error(_dl_mmap_zero)) {
+                       _dl_fdprintf(2, "%s: can't map '/dev/zero'\n", _dl_progname);
+                       _dl_exit(20);
+               }
+       }
+       retval = _dl_malloc_addr;
+       _dl_malloc_addr += size;
+
+       /*
+        * Align memory to 4 byte boundary.  Some platforms require this, others
+        * simply get better performance.
+        */
+       _dl_malloc_addr = (char *) (((unsigned int) _dl_malloc_addr + 3) & ~(3));
+       return retval;
 }
 
-char * _dl_getenv(char *symbol, char **envp)
+char *_dl_getenv(char *symbol, char **envp)
 {
-  char *pnt;
-  char *pnt1;
-  while ((pnt = *envp++)) {
-    pnt1 = symbol;
-    while (*pnt && *pnt == *pnt1)
-      pnt1++, pnt++;
-    if (!*pnt || *pnt != '=' || *pnt1)
-      continue;
-    return pnt+1;
-  }
-  return 0;
+       char *pnt;
+       char *pnt1;
+
+       while ((pnt = *envp++)) {
+               pnt1 = symbol;
+               while (*pnt && *pnt == *pnt1)
+                       pnt1++, pnt++;
+               if (!*pnt || *pnt != '=' || *pnt1)
+                       continue;
+               return pnt + 1;
+       }
+       return 0;
 }
 
 void _dl_unsetenv(char *symbol, char **envp)
 {
-  char *pnt;
-  char *pnt1;
-  char **newenvp = envp;
-  for (pnt = *envp; pnt; pnt = *++envp) {
-    pnt1 = symbol;
-    while (*pnt && *pnt == *pnt1)
-      pnt1++, pnt++;
-    if(!*pnt || *pnt != '=' || *pnt1)
-      *newenvp++ = *envp;
-  }
-  *newenvp++ = *envp;
-  return;
+       char *pnt;
+       char *pnt1;
+       char **newenvp = envp;
+
+       for (pnt = *envp; pnt; pnt = *++envp) {
+               pnt1 = symbol;
+               while (*pnt && *pnt == *pnt1)
+                       pnt1++, pnt++;
+               if (!*pnt || *pnt != '=' || *pnt1)
+                       *newenvp++ = *envp;
+       }
+       *newenvp++ = *envp;
+       return;
 }
 
-char * _dl_strdup(const char * string){
-  char * retval;
-  int len;
+char *_dl_strdup(const char *string)
+{
+       char *retval;
+       int len;
 
-  len = _dl_strlen(string);
-  retval = _dl_malloc(len + 1);
-  _dl_strcpy(retval, string);
-  return retval;
+       len = _dl_strlen(string);
+       retval = _dl_malloc(len + 1);
+       _dl_strcpy(retval, string);
+       return retval;
 }
-
index e90a8c3..bab9cd4 100644 (file)
-/* This should eventually appear in the distribution version of linux/elf.h */
-#ifndef R_SPARC_NONE
-#define R_SPARC_NONE           0
-#define R_SPARC_8              1
-#define R_SPARC_16             2
-#define R_SPARC_32             3
-#define R_SPARC_DISP8          4
-#define R_SPARC_DISP16         5
-#define R_SPARC_DISP32         6
-#define R_SPARC_WDISP30                7
-#define R_SPARC_WDISP22                8
-#define R_SPARC_HI22           9
-#define R_SPARC_22             10
-#define R_SPARC_13             11
-#define R_SPARC_LO10           12
-#define R_SPARC_GOT10          13
-#define R_SPARC_GOT13          14
-#define R_SPARC_GOT22          15
-#define R_SPARC_PC10           16
-#define R_SPARC_PC22           17
-#define R_SPARC_WPLT30         18
-#define R_SPARC_COPY           19
-#define R_SPARC_GLOB_DAT       20
-#define R_SPARC_JMP_SLOT       21
-#define R_SPARC_RELATIVE       22
-#define R_SPARC_UA32           23
-#endif
-
-#ifndef R_68K_NONE
-#define R_68K_NONE     0
-#define R_68K_32       1
-#define R_68K_16       2
-#define R_68K_8                3
-#define R_68K_PC32     4
-#define R_68K_PC16     5
-#define R_68K_PC8      6
-#define R_68K_GOT32    7
-#define R_68K_GOT16    8
-#define R_68K_GOT8     9
-#define R_68K_GOT32O   10
-#define R_68K_GOT16O   11
-#define R_68K_GOT8O    12
-#define R_68K_PLT32    13
-#define R_68K_PLT16    14
-#define R_68K_PLT8     15
-#define R_68K_PLT32O   16
-#define R_68K_PLT16O   17
-#define R_68K_PLT8O    18
-#define R_68K_COPY     19
-#define R_68K_GLOB_DAT 20
-#define R_68K_JMP_SLOT 21
-#define R_68K_RELATIVE 22
-#define R_68K_NUM      23
-#endif
-
-
-/* ARM relocs.  */
-#ifndef R_ARM_NONE
-#define R_ARM_NONE             0       /* No reloc */
-#define R_ARM_PC24             1       /* PC relative 26 bit branch */
-#define R_ARM_ABS32            2       /* Direct 32 bit  */
-#define R_ARM_REL32            3       /* PC relative 32 bit */
-#define R_ARM_PC13             4
-#define R_ARM_ABS16            5       /* Direct 16 bit */
-#define R_ARM_ABS12            6       /* Direct 12 bit */
-#define R_ARM_THM_ABS5         7
-#define R_ARM_ABS8             8       /* Direct 8 bit */
-#define R_ARM_SBREL32          9
-#define R_ARM_THM_PC22         10
-#define R_ARM_THM_PC8          11
-#define R_ARM_AMP_VCALL9       12
-#define R_ARM_SWI24            13
-#define R_ARM_THM_SWI8         14
-#define R_ARM_XPC25            15
-#define R_ARM_THM_XPC22                16
-#define R_ARM_COPY             20      /* Copy symbol at runtime */
-#define R_ARM_GLOB_DAT         21      /* Create GOT entry */
-#define R_ARM_JUMP_SLOT                22      /* Create PLT entry */
-#define R_ARM_RELATIVE         23      /* Adjust by program base */
-#define R_ARM_GOTOFF           24      /* 32 bit offset to GOT */
-#define R_ARM_GOTPC            25      /* 32 bit PC relative offset to GOT */
-#define R_ARM_GOT32            26      /* 32 bit GOT entry */
-#define R_ARM_PLT32            27      /* 32 bit PLT address */
-#define R_ARM_GNU_VTENTRY      100
-#define R_ARM_GNU_VTINHERIT    101
-#define R_ARM_THM_PC11         102     /* thumb unconditional branch */
-#define R_ARM_THM_PC9          103     /* thumb conditional branch */
-#define R_ARM_RXPC25           249
-#define R_ARM_RSBREL32         250
-#define R_ARM_THM_RPC22                251
-#define R_ARM_RREL32           252
-#define R_ARM_RABS22           253
-#define R_ARM_RPC24            254
-#define R_ARM_RBASE            255
-/* Keep this the last entry.  */
-#define R_ARM_NUM              256
-#endif
+#ifndef LINUXELF_H
+#define LINUXELF_H
 
+/* Forward declarations for stuff defined in hash.h */
+struct dyn_elf;
+struct elf_resolve;
 
-/*
- * These constants define the elements of the auxiliary vector used to
- * pass additional information from the kernel to an ELF application.
- */
-
-#ifndef AT_NULL
-typedef struct
-{
-  int  a_type;
-  union{
-    long a_val;
-    void *p_ptr;
-    void (*a_fcn)();
-  } a_un;
-} auxv_t;
 
-/*
- * Values of a_type... These often appear in the file /usr/include/sys/auxv.h
- * on SVr4 systems.
- */
-#define AT_NULL                0
-#define AT_IGNORE      1
-#define AT_EXECFD      2
-#define AT_PHDR                3
-#define AT_PHENT       4
-#define AT_PHNUM       5
-#define AT_PAGESZ      6
-#define AT_BASE                7
-#define AT_FLAGS               8
-#define AT_ENTRY       9
-#endif
-#ifndef AT_NOTELF
-#define AT_NOTELF 10   /* program is not ELF */
-#define AT_UID    11   /* real uid */
-#define AT_EUID   12   /* effective uid */
-#define AT_GID    13   /* real gid */
-#define AT_EGID   14   /* effective gid */
-#endif
-
-extern int _dl_linux_resolve(void);
-extern struct elf_resolve * _dl_load_shared_library(int secure, 
-                               struct elf_resolve *, char * libname);
+/* Some function prototypes */
 extern void * _dl_malloc(int size);
 extern int _dl_map_cache(void);
 extern int _dl_unmap_cache(void);
-
-extern struct elf_resolve * _dl_load_elf_shared_library(int secure, 
-                               char * libname, int);
 int _dl_copy_fixups(struct dyn_elf * tpnt);
-
-extern int linux_run(int argc, char * argv[]);
-
-extern void _dl_parse_lazy_relocation_information(struct elf_resolve * tpnt, int rel_addr,
-       int rel_size, int type);
-
 extern int _dl_parse_relocation_information(struct elf_resolve * tpnt, int rel_addr,
        int rel_size, int type);
+extern void _dl_parse_lazy_relocation_information(struct elf_resolve * tpnt, int rel_addr,
+       int rel_size, int type);
+extern struct elf_resolve * _dl_load_shared_library(int secure, 
+                               struct elf_resolve *, char * libname);
+extern struct elf_resolve * _dl_load_elf_shared_library(int secure, 
+                               char * libname, int);
 extern int _dl_parse_copy_information(struct dyn_elf * rpnt, int rel_addr,
        int rel_size, int type);
+extern int _dl_linux_resolve(void);
+#define ELF_CLASS   ELFCLASS32
 
 
-/* This means that we may be forced to manually search for copy fixups
-   which were omitted by the linker.  We cannot depend upon the DT_TEXTREL
-   to tell us whether there are fixups in a text section or not. */
-
 #ifndef SVR4_BUGCOMPAT
 #define SVR4_BUGCOMPAT 1
 #endif
 
-#ifndef PF_R
-#define PF_R 4
-#define PF_W 2
-#define PF_X 1
+#if ELF_CLASS == ELFCLASS32
+
+#define elfhdr         Elf32_Ehdr
+#define elf_phdr       Elf32_Phdr
+#define elf_note       Elf32_Nhdr
+/*
+ * Datatype of a relocation on this platform
+ */
+#ifdef ELF_USES_RELOCA
+# define ELF_RELOC     Elf32_Rela
+#else
+# define ELF_RELOC     Elf32_Rel
+#endif
+
+#else
+
+#define elfhdr         Elf64_Ehdr
+#define elf_phdr       Elf64_Phdr
+#define elf_note       Elf64_Nhdr
+/*
+ * Datatype of a relocation on this platform
+ */
+#ifdef ELF_USES_RELOCA
+# define ELF_RELOC     Elf64_Rela
+#else
+# define ELF_RELOC     Elf64_Rel
+#endif
+
 #endif
 
+
 /* Convert between the Linux flags for page protections and the
    ones specified in the ELF standard. */
-
 #define LXFLAGS(X) ( (((X) & PF_R) ? PROT_READ : 0) | \
                    (((X) & PF_W) ? PROT_WRITE : 0) | \
                    (((X) & PF_X) ? PROT_EXEC : 0))
 
+#endif /* LINUXELF_H */
index 6b1624b..df7e367 100644 (file)
@@ -1,4 +1,3 @@
-#include <linux/types.h>
 #include <asm/unistd.h>
 
 /* Here are the macros which define how this platform makes
index 9b73efd..b3bfeee 100644 (file)
@@ -48,20 +48,12 @@ static char *_dl_reltypes[] =
    a more than adequate job of explaining everything required to get this
    working. */
 
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/unistd.h>
-/*#include <stdlib.h>*/
-#include "string.h"
-#include <linux/unistd.h>
-#include <linux/fcntl.h>
-#include <linux/elf.h>
-
+#include <sys/types.h>
+#include "elf.h"
 #include "hash.h"
-#include "linuxelf.h"
+#include "syscall.h"
+#include "string.h"
 #include "sysdep.h"
-#include "../syscall.h"
-#include "../string.h"
 
 extern char *_dl_progname;
 
@@ -70,9 +62,9 @@ _dl_linux_resolver (int dummy1, int dummy2,
                    struct elf_resolve *tpnt, int reloc_entry)
 {
   int reloc_type;
-  struct elf32_rela *this_reloc;
+  Elf32_Rela *this_reloc;
   char *strtab;
-  struct elf32_sym *symtab;
+  Elf32_Sym *symtab;
   char *rel_addr;
   int symtab_index;
   char *new_addr;
@@ -80,11 +72,11 @@ _dl_linux_resolver (int dummy1, int dummy2,
   unsigned int instr_addr;
 
   rel_addr = tpnt->loadaddr + tpnt->dynamic_info[DT_JMPREL];
-  this_reloc = (struct elf32_rela *) (rel_addr + reloc_entry);
+  this_reloc = (Elf32_Rela *) (rel_addr + reloc_entry);
   reloc_type = ELF32_R_TYPE (this_reloc->r_info);
   symtab_index = ELF32_R_SYM (this_reloc->r_info);
 
-  symtab = (struct elf32_sym *) (tpnt->dynamic_info[DT_SYMTAB]
+  symtab = (Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB]
                                 + tpnt->loadaddr);
   strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
 
@@ -133,15 +125,15 @@ _dl_parse_lazy_relocation_information (struct elf_resolve *tpnt, int rel_addr,
   char *strtab;
   int reloc_type;
   int symtab_index;
-  struct elf32_sym *symtab;
-  struct elf32_rela *rpnt;
+  Elf32_Sym *symtab;
+  Elf32_Rela *rpnt;
   unsigned int *reloc_addr;
 
   /* Now parse the relocation information.  */
-  rpnt = (struct elf32_rela *) (rel_addr + tpnt->loadaddr);
-  rel_size = rel_size / sizeof (struct elf32_rela);
+  rpnt = (Elf32_Rela *) (rel_addr + tpnt->loadaddr);
+  rel_size = rel_size / sizeof (Elf32_Rela);
 
-  symtab = (struct elf32_sym *) (tpnt->dynamic_info[DT_SYMTAB]
+  symtab = (Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB]
                                 + tpnt->loadaddr);
   strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
 
@@ -186,17 +178,17 @@ _dl_parse_relocation_information (struct elf_resolve *tpnt, int rel_addr,
   char *strtab;
   int reloc_type;
   int goof = 0;
-  struct elf32_sym *symtab;
-  struct elf32_rela *rpnt;
+  Elf32_Sym *symtab;
+  Elf32_Rela *rpnt;
   unsigned int *reloc_addr;
   unsigned int symbol_addr;
   int symtab_index;
   /* Now parse the relocation information */
 
-  rpnt = (struct elf32_rela *) (rel_addr + tpnt->loadaddr);
-  rel_size = rel_size / sizeof (struct elf32_rela);
+  rpnt = (Elf32_Rela *) (rel_addr + tpnt->loadaddr);
+  rel_size = rel_size / sizeof (Elf32_Rela);
 
-  symtab = (struct elf32_sym *) (tpnt->dynamic_info[DT_SYMTAB]
+  symtab = (Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB]
                                 + tpnt->loadaddr);
   strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
 
@@ -309,8 +301,8 @@ _dl_parse_copy_information (struct dyn_elf *xpnt, int rel_addr,
   char *strtab;
   int reloc_type;
   int goof = 0;
-  struct elf32_sym *symtab;
-  struct elf32_rela *rpnt;
+  Elf32_Sym *symtab;
+  Elf32_Rela *rpnt;
   unsigned int *reloc_addr;
   unsigned int symbol_addr;
   struct elf_resolve *tpnt;
@@ -319,10 +311,10 @@ _dl_parse_copy_information (struct dyn_elf *xpnt, int rel_addr,
 
   tpnt = xpnt->dyn;
 
-  rpnt = (struct elf32_rela *) (rel_addr + tpnt->loadaddr);
-  rel_size = rel_size / sizeof (struct elf32_rela);
+  rpnt = (Elf32_Rela *) (rel_addr + tpnt->loadaddr);
+  rel_size = rel_size / sizeof (Elf32_Rela);
 
-  symtab = (struct elf32_sym *) (tpnt->dynamic_info[DT_SYMTAB]
+  symtab = (Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB]
                                 + tpnt->loadaddr);
   strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
 
index 6b1624b..df7e367 100644 (file)
@@ -1,4 +1,3 @@
-#include <linux/types.h>
 #include <asm/unistd.h>
 
 /* Here are the macros which define how this platform makes
index 6b1624b..df7e367 100644 (file)
@@ -1,4 +1,3 @@
-#include <linux/types.h>
 #include <asm/unistd.h>
 
 /* Here are the macros which define how this platform makes
index 9d1cd0f..d9b9008 100644 (file)
 /* This file contains the helper routines to load an ELF sharable
    library into memory and add the symbol table info to the chain. */
 
-#include <linux/types.h>
-#include <linux/fcntl.h>
-#include <linux/errno.h>
+#include <asm/mman.h>
+#include "elf.h"
 #include "string.h"
-/*#include <stdlib.h>*/
-#include <linux/mman.h>
-#include <linux/stat.h>
 #include "hash.h"
-#include "linuxelf.h"
 #include "sysdep.h"
-#include <linux/unistd.h>
 #include "syscall.h"
 #ifdef USE_CACHE
 #include "../config.h"
@@ -46,80 +40,79 @@ static size_t _dl_cache_size = 0;
 
 int _dl_map_cache(void)
 {
-  int fd;
-  struct kernel_stat st;
-  header_t *header;
-  libentry_t *libent;
-  int i, strtabsize;
-
-  if (_dl_cache_addr == (caddr_t)-1)
-    return -1;
-  else if (_dl_cache_addr != NULL)
-    return 0;
-
-  if (_dl_stat(LDSO_CACHE, &st) || (fd = _dl_open(LDSO_CACHE, O_RDONLY)) < 0)
-  {
-    _dl_fdprintf(2, "%s: can't open cache '%s'\n", _dl_progname, LDSO_CACHE);
-    _dl_cache_addr = (caddr_t)-1; /* so we won't try again */
-    return -1;
-  }
-
-  _dl_cache_size = st.st_size;
-  _dl_cache_addr = (caddr_t)_dl_mmap(0, _dl_cache_size, PROT_READ,
-                                    MAP_SHARED, fd, 0);
-  _dl_close (fd);
-  if (_dl_cache_addr == (caddr_t)-1)
-  {
-    _dl_fdprintf(2, "%s: can't map cache '%s'\n", _dl_progname, LDSO_CACHE);
-    return -1;
-  }
-
-  header = (header_t *)_dl_cache_addr;
-
-  if (_dl_cache_size < sizeof (header_t) ||
-      _dl_memcmp(header->magic, LDSO_CACHE_MAGIC, LDSO_CACHE_MAGIC_LEN) ||
-      _dl_memcmp(header->version, LDSO_CACHE_VER, LDSO_CACHE_VER_LEN) ||
-      _dl_cache_size < 
-        (sizeof (header_t) + header->nlibs * sizeof (libentry_t)) ||
-      _dl_cache_addr[_dl_cache_size-1] != '\0')
-  {
-    _dl_fdprintf(2, "%s: cache '%s' is corrupt\n", _dl_progname, LDSO_CACHE);
-    goto fail;
-  }
-
-  strtabsize = _dl_cache_size - sizeof (header_t) - 
-    header->nlibs * sizeof (libentry_t);
-  libent = (libentry_t *)&header[1];
-
-  for (i = 0; i < header->nlibs; i++)
-  {
-    if (libent[i].sooffset >= strtabsize ||
-       libent[i].liboffset >= strtabsize)
-    {
-      _dl_fdprintf(2, "%s: cache '%s' is corrupt\n", _dl_progname, LDSO_CACHE);
-      goto fail;
-    }
-  }
-
-  return 0;
-
-fail:
-  _dl_munmap(_dl_cache_addr, _dl_cache_size);
-  _dl_cache_addr = (caddr_t)-1;
-  return -1;
+       int fd;
+       struct kernel_stat st;
+       header_t *header;
+       libentry_t *libent;
+       int i, strtabsize;
+
+       if (_dl_cache_addr == (caddr_t) - 1)
+               return -1;
+       else if (_dl_cache_addr != NULL)
+               return 0;
+
+       if (_dl_stat(LDSO_CACHE, &st)
+               || (fd = _dl_open(LDSO_CACHE, O_RDONLY)) < 0) {
+               _dl_fdprintf(2, "%s: can't open cache '%s'\n", _dl_progname, LDSO_CACHE);
+               _dl_cache_addr = (caddr_t) - 1; /* so we won't try again */
+               return -1;
+       }
+
+       _dl_cache_size = st.st_size;
+       _dl_cache_addr = (caddr_t) _dl_mmap(0, _dl_cache_size, PROT_READ, MAP_SHARED, fd, 0);
+       _dl_close(fd);
+       if (_dl_cache_addr == (caddr_t) - 1) {
+               _dl_fdprintf(2, "%s: can't map cache '%s'\n", 
+                       _dl_progname, LDSO_CACHE);
+               return -1;
+       }
+
+       header = (header_t *) _dl_cache_addr;
+
+       if (_dl_cache_size < sizeof(header_t) ||
+               _dl_memcmp(header->magic, LDSO_CACHE_MAGIC, LDSO_CACHE_MAGIC_LEN)
+               || _dl_memcmp(header->version, LDSO_CACHE_VER, LDSO_CACHE_VER_LEN)
+               || _dl_cache_size <
+               (sizeof(header_t) + header->nlibs * sizeof(libentry_t))
+               || _dl_cache_addr[_dl_cache_size - 1] != '\0') 
+       {
+               _dl_fdprintf(2, "%s: cache '%s' is corrupt\n", _dl_progname, 
+                       LDSO_CACHE);
+               goto fail;
+       }
+
+       strtabsize = _dl_cache_size - sizeof(header_t) -
+               header->nlibs * sizeof(libentry_t);
+       libent = (libentry_t *) & header[1];
+
+       for (i = 0; i < header->nlibs; i++) {
+               if (libent[i].sooffset >= strtabsize || 
+                       libent[i].liboffset >= strtabsize) 
+               {
+                       _dl_fdprintf(2, "%s: cache '%s' is corrupt\n", _dl_progname, LDSO_CACHE);
+                       goto fail;
+               }
+       }
+
+       return 0;
+
+  fail:
+       _dl_munmap(_dl_cache_addr, _dl_cache_size);
+       _dl_cache_addr = (caddr_t) - 1;
+       return -1;
 }
 
 int _dl_unmap_cache(void)
 {
-  if (_dl_cache_addr == NULL || _dl_cache_addr == (caddr_t)-1)
-    return -1;
+       if (_dl_cache_addr == NULL || _dl_cache_addr == (caddr_t) - 1)
+               return -1;
 
 #if 1
-  _dl_munmap (_dl_cache_addr, _dl_cache_size);
-  _dl_cache_addr = NULL;
+       _dl_munmap(_dl_cache_addr, _dl_cache_size);
+       _dl_cache_addr = NULL;
 #endif
 
-  return 0;
+       return 0;
 }
 
 #endif
@@ -131,160 +124,182 @@ int _dl_unmap_cache(void)
 unsigned int _dl_error_number;
 unsigned int _dl_internal_error_number;
 
-struct elf_resolve * _dl_load_shared_library(int secure, 
-       struct elf_resolve * tpnt, char * full_libname) {
-  char * pnt, *pnt1, *pnt2;
-  struct elf_resolve *tpnt1 = NULL;
-  char mylibname[2050];
-  char * libname;
-
-  _dl_internal_error_number = 0;
-
-  /* quick hack to ensure mylibname buffer doesn't overflow.  don't 
-     allow full_libname or any directory to be longer than 1024. */
-  if (_dl_strlen(full_libname) > 1024)
-    goto goof;
-
-  pnt = libname = full_libname;
-  while (*pnt) {
-    if(*pnt == '/') libname = pnt+1;
-    pnt++;
-  }
-
- /* If the filename has any '/', try it straight and leave it at that.
-     For IBCS2 compatibility under linux, we substitute the string 
-     /usr/i486-sysv4/lib for /usr/lib in library names. */
-
-  if (libname != full_libname) {
-    tpnt1 = _dl_load_elf_shared_library(secure, full_libname, 0);
-    if (tpnt1)
-      return tpnt1;
-    goto goof;
-  }
-
-  /*
-   * The ABI specifies that RPATH is searched before LD_*_PATH or
-   * the default path of /usr/lib.
-   * Check in rpath directories 
-   */
-  for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) {
-    if (tpnt->libtype == elf_executable) {
-      pnt1 = (char *)tpnt->dynamic_info[DT_RPATH];
-      if(pnt1) {
-       pnt1 += (unsigned int) tpnt->loadaddr + tpnt->dynamic_info[DT_STRTAB];
-       while(*pnt1){
-         pnt2 = mylibname;
-         while(*pnt1 && *pnt1 != ':') {
-           if (pnt2 - mylibname < 1024)
-             *pnt2++ = *pnt1++;
-           else
-             pnt1++;
-         }
-         if (pnt2 - mylibname >= 1024)
-           break;
-         if(pnt2[-1] != '/') *pnt2++ = '/';
-         pnt = libname;
-         while(*pnt) *pnt2++  = *pnt++;
-         *pnt2++ = 0;
-         tpnt1 = _dl_load_elf_shared_library(secure, mylibname, 0);
-         if(tpnt1) return tpnt1;
-         if(*pnt1 == ':') pnt1++;
+struct elf_resolve *_dl_load_shared_library(int secure, 
+       struct elf_resolve *tpnt, char *full_libname)
+{
+       char *pnt, *pnt1, *pnt2;
+       struct elf_resolve *tpnt1 = NULL;
+       char mylibname[2050];
+       char *libname;
+
+       _dl_internal_error_number = 0;
+
+       /* quick hack to ensure mylibname buffer doesn't overflow.  don't 
+          allow full_libname or any directory to be longer than 1024. */
+       if (_dl_strlen(full_libname) > 1024)
+               goto goof;
+
+       pnt = libname = full_libname;
+       while (*pnt) {
+               if (*pnt == '/')
+                       libname = pnt + 1;
+               pnt++;
        }
-      }
-    }
-  }
-  
-
-  /* Check in LD_{ELF_}LIBRARY_PATH, if specified and allowed */
-  pnt1 = _dl_library_path;
-  if (pnt1 && *pnt1) {
-    while (*pnt1) {
-      pnt2 = mylibname;
-      while(*pnt1 && *pnt1 != ':' && *pnt1 != ';') {
-       if (pnt2 - mylibname < 1024)
-         *pnt2++ = *pnt1++;
-       else
-         pnt1++;
-      }
-      if (pnt2 - mylibname >= 1024)
-       break;
-      if(pnt2[-1] != '/') *pnt2++ = '/';
-      pnt = libname;
-      while(*pnt) *pnt2++  = *pnt++;
-      *pnt2++ = 0;
-      tpnt1 = _dl_load_elf_shared_library(secure, mylibname, 0);
-      if(tpnt1) return tpnt1;
-      if(*pnt1 == ':' || *pnt1 == ';') pnt1++;
-    }
-  }
-
-
-  /*
-   * Where should the cache be searched?  There is no such concept in the
-   * ABI, so we have some flexibility here.  For now, search it before
-   * the default path of /usr/lib.
-   */
+
+       /* If the filename has any '/', try it straight and leave it at that.
+          For IBCS2 compatibility under linux, we substitute the string 
+          /usr/i486-sysv4/lib for /usr/lib in library names. */
+
+       if (libname != full_libname) {
+               tpnt1 = _dl_load_elf_shared_library(secure, full_libname, 0);
+               if (tpnt1)
+                       return tpnt1;
+               goto goof;
+       }
+
+       /*
+        * The ABI specifies that RPATH is searched before LD_*_PATH or
+        * the default path of /usr/lib.
+        * Check in rpath directories 
+        */
+       for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) {
+               if (tpnt->libtype == elf_executable) {
+                       pnt1 = (char *) tpnt->dynamic_info[DT_RPATH];
+                       if (pnt1) {
+                               pnt1 += (unsigned int) tpnt->loadaddr +
+                                       tpnt->dynamic_info[DT_STRTAB];
+                               while (*pnt1) {
+                                       pnt2 = mylibname;
+                                       while (*pnt1 && *pnt1 != ':') {
+                                               if (pnt2 - mylibname < 1024)
+                                                       *pnt2++ = *pnt1++;
+                                               else
+                                                       pnt1++;
+                                       }
+                                       if (pnt2 - mylibname >= 1024)
+                                               break;
+                                       if (pnt2[-1] != '/')
+                                               *pnt2++ = '/';
+                                       pnt = libname;
+                                       while (*pnt)
+                                               *pnt2++ = *pnt++;
+                                       *pnt2++ = 0;
+                                       tpnt1 =
+                                               _dl_load_elf_shared_library(secure, mylibname, 0);
+                                       if (tpnt1)
+                                               return tpnt1;
+                                       if (*pnt1 == ':')
+                                               pnt1++;
+                               }
+                       }
+               }
+       }
+
+
+       /* Check in LD_{ELF_}LIBRARY_PATH, if specified and allowed */
+       pnt1 = _dl_library_path;
+       if (pnt1 && *pnt1) {
+               while (*pnt1) {
+                       pnt2 = mylibname;
+                       while (*pnt1 && *pnt1 != ':' && *pnt1 != ';') {
+                               if (pnt2 - mylibname < 1024)
+                                       *pnt2++ = *pnt1++;
+                               else
+                                       pnt1++;
+                       }
+                       if (pnt2 - mylibname >= 1024)
+                               break;
+                       if (pnt2[-1] != '/')
+                               *pnt2++ = '/';
+                       pnt = libname;
+                       while (*pnt)
+                               *pnt2++ = *pnt++;
+                       *pnt2++ = 0;
+                       tpnt1 = _dl_load_elf_shared_library(secure, mylibname, 0);
+                       if (tpnt1)
+                               return tpnt1;
+                       if (*pnt1 == ':' || *pnt1 == ';')
+                               pnt1++;
+               }
+       }
+
+
+       /*
+        * Where should the cache be searched?  There is no such concept in the
+        * ABI, so we have some flexibility here.  For now, search it before
+        * the default path of /usr/lib.
+        */
 #ifdef USE_CACHE
-  if (_dl_cache_addr != NULL && _dl_cache_addr != (caddr_t)-1)
-  {
-    int i;
-    header_t *header = (header_t *)_dl_cache_addr;
-    libentry_t *libent = (libentry_t *)&header[1];
-    char *strs = (char *)&libent[header->nlibs];
-
-    for (i = 0; i < header->nlibs; i++)
-    {
-      if ((libent[i].flags == LIB_ELF || 
-          libent[i].flags == LIB_ELF_LIBC5) &&
-         _dl_strcmp(libname, strs+libent[i].sooffset) == 0 &&
-         (tpnt1 = _dl_load_elf_shared_library(secure, strs+libent[i].liboffset, 0)))
-       return tpnt1;
-    }
-  }
+       if (_dl_cache_addr != NULL && _dl_cache_addr != (caddr_t) - 1) {
+               int i;
+               header_t *header = (header_t *) _dl_cache_addr;
+               libentry_t *libent = (libentry_t *) & header[1];
+               char *strs = (char *) &libent[header->nlibs];
+
+               for (i = 0; i < header->nlibs; i++) {
+                       if ((libent[i].flags == LIB_ELF ||
+                                libent[i].flags == LIB_ELF_LIBC5) &&
+                               _dl_strcmp(libname, strs + libent[i].sooffset) == 0 &&
+                               (tpnt1 = _dl_load_elf_shared_library(secure, 
+                                    strs + libent[i].liboffset, 0)))
+                               return tpnt1;
+               }
+       }
 #endif
 
 
 #ifdef UCLIBC_DEVEL
 
-  /* Check in /usr/<arch>-linux-uclibc/lib */
-  pnt1 = UCLIBC_INSTALL_DIR"/lib";
-  pnt = mylibname;
-  while(*pnt1) *pnt++ = *pnt1++;
-  pnt1 = libname;
-  while(*pnt1) *pnt++ = *pnt1++;
-  *pnt++ = 0;
-  tpnt1 = _dl_load_elf_shared_library(secure, mylibname, 0);
-  if (tpnt1) return tpnt1;
-  
+       /* Check in /usr/<arch>-linux-uclibc/lib */
+       pnt1 = UCLIBC_INSTALL_DIR "/lib";
+       pnt = mylibname;
+       while (*pnt1)
+               *pnt++ = *pnt1++;
+       pnt1 = libname;
+       while (*pnt1)
+               *pnt++ = *pnt1++;
+       *pnt++ = 0;
+       tpnt1 = _dl_load_elf_shared_library(secure, mylibname, 0);
+       if (tpnt1)
+               return tpnt1;
+
 #else /* UCLIBC_DEVEL */
 
-  /* Check in /usr/lib */
-  pnt1 = "/usr/lib/";
-  pnt = mylibname;
-  while(*pnt1) *pnt++ = *pnt1++;
-  pnt1 = libname;
-  while(*pnt1) *pnt++ = *pnt1++;
-  *pnt++ = 0;
-  tpnt1 = _dl_load_elf_shared_library(secure, mylibname, 0);
-  if (tpnt1) return tpnt1;
-  
-  /* Check in /lib */
-  /* try "/lib/". */
-  pnt1 = "/lib/";
-  pnt = mylibname;
-  while(*pnt1) *pnt++ = *pnt1++;
-  pnt1 = libname;
-  while(*pnt1) *pnt++ = *pnt1++;
-  *pnt++ = 0;
-  tpnt1 = _dl_load_elf_shared_library(secure, mylibname, 0);
-  if (tpnt1) return tpnt1;
+       /* Check in /usr/lib */
+       pnt1 = "/usr/lib/";
+       pnt = mylibname;
+       while (*pnt1)
+               *pnt++ = *pnt1++;
+       pnt1 = libname;
+       while (*pnt1)
+               *pnt++ = *pnt1++;
+       *pnt++ = 0;
+       tpnt1 = _dl_load_elf_shared_library(secure, mylibname, 0);
+       if (tpnt1)
+               return tpnt1;
+
+       /* Check in /lib */
+       /* try "/lib/". */
+       pnt1 = "/lib/";
+       pnt = mylibname;
+       while (*pnt1)
+               *pnt++ = *pnt1++;
+       pnt1 = libname;
+       while (*pnt1)
+               *pnt++ = *pnt1++;
+       *pnt++ = 0;
+       tpnt1 = _dl_load_elf_shared_library(secure, mylibname, 0);
+       if (tpnt1)
+               return tpnt1;
 #endif /* UCLIBC_DEVEL */
 
-goof:
-  /* Well, we shot our wad on that one.  All we can do now is punt */
-  if (_dl_internal_error_number) _dl_error_number = _dl_internal_error_number;
-       else _dl_error_number = DL_ERROR_NOFILE;
-  return NULL;
+  goof:
+       /* Well, we shot our wad on that one.  All we can do now is punt */
+       if (_dl_internal_error_number)
+               _dl_error_number = _dl_internal_error_number;
+       else
+               _dl_error_number = DL_ERROR_NOFILE;
+       return NULL;
 }
 
 /*
@@ -295,264 +310,273 @@ goof:
 
 //extern _elf_rtbndr(void);
 
-struct elf_resolve * _dl_load_elf_shared_library(int secure, 
-        char * libname, int flag) {
-  struct elfhdr * epnt;
-  unsigned int dynamic_addr = 0;
-  unsigned int dynamic_size = 0;
-  struct dynamic * dpnt;
-  struct elf_resolve * tpnt;
-  struct elf_phdr * ppnt;
-  int piclib;
-  char * status;
-  int flags;
-  char header[4096];
-  int dynamic_info[24];
-  int * lpnt;
-  unsigned int libaddr;
-  unsigned int minvma=0xffffffff, maxvma=0;
-  
-  int i;
-  int infile;
-
-  /* If this file is already loaded, skip this step */
-  tpnt = _dl_check_hashed_files(libname);
-  if(tpnt) return tpnt;
-
-  /* If we are in secure mode (i.e. a setu/gid binary using LD_PRELOAD),
-     we don't load the library if it isn't setuid. */
-
-  if (secure) {
-    struct kernel_stat st;
-    if (_dl_stat(libname, &st) || !(st.st_mode & S_ISUID))
-      return NULL;
-  }
-
-  libaddr = 0;
-  infile = _dl_open(libname, O_RDONLY);
-  if(infile < 0)
-  {
+struct elf_resolve *_dl_load_elf_shared_library(int secure, 
+       char *libname, int flag)
+{
+       elfhdr *epnt;
+       unsigned int dynamic_addr = 0;
+       unsigned int dynamic_size = 0;
+       Elf32_Dyn *dpnt;
+       struct elf_resolve *tpnt;
+       elf_phdr *ppnt;
+       int piclib;
+       char *status;
+       int flags;
+       char header[4096];
+       int dynamic_info[24];
+       int *lpnt;
+       unsigned int libaddr;
+       unsigned int minvma = 0xffffffff, maxvma = 0;
+
+       int i;
+       int infile;
+
+       /* If this file is already loaded, skip this step */
+       tpnt = _dl_check_hashed_files(libname);
+       if (tpnt)
+               return tpnt;
+
+       /* If we are in secure mode (i.e. a setu/gid binary using LD_PRELOAD),
+          we don't load the library if it isn't setuid. */
+
+       if (secure) {
+               struct kernel_stat st;
+
+               if (_dl_stat(libname, &st) || !(st.st_mode & S_ISUID))
+                       return NULL;
+       }
+
+       libaddr = 0;
+       infile = _dl_open(libname, O_RDONLY);
+       if (infile < 0) {
 #if 0
-    /*
-     * NO!  When we open shared libraries we may search several paths.
-     * it is inappropriate to generate an error here.
-     */
-    _dl_fdprintf(2, "%s: can't open '%s'\n", _dl_progname, libname);
+               /*
+                * NO!  When we open shared libraries we may search several paths.
+                * it is inappropriate to generate an error here.
+                */
+               _dl_fdprintf(2, "%s: can't open '%s'\n", _dl_progname, libname);
 #endif
-    _dl_internal_error_number = DL_ERROR_NOFILE;
-    return NULL;
-  }
-  _dl_read(infile, header, sizeof(header));
-  epnt = (struct elfhdr *) header;
-  if (epnt->e_ident[0] != 0x7f ||
-      epnt->e_ident[1] != 'E' ||
-      epnt->e_ident[2] != 'L' ||
-      epnt->e_ident[3] != 'F') {
-    _dl_fdprintf(2, "%s: '%s' is not an ELF file\n", _dl_progname, libname);
-    _dl_internal_error_number = DL_ERROR_NOTELF;
-    _dl_close(infile);
-    return NULL;
-  };
-  
-  if((epnt->e_type != ET_DYN) || 
-     (epnt->e_machine != MAGIC1 
+               _dl_internal_error_number = DL_ERROR_NOFILE;
+               return NULL;
+       }
+
+       _dl_read(infile, header, sizeof(header));
+       epnt = (elfhdr *) header;
+       if (epnt->e_ident[0] != 0x7f ||
+               epnt->e_ident[1] != 'E' || 
+               epnt->e_ident[2] != 'L' || 
+               epnt->e_ident[3] != 'F') 
+       {
+               _dl_fdprintf(2, "%s: '%s' is not an ELF file\n", _dl_progname,
+                                        libname);
+               _dl_internal_error_number = DL_ERROR_NOTELF;
+               _dl_close(infile);
+               return NULL;
+       };
+
+       if ((epnt->e_type != ET_DYN) || (epnt->e_machine != MAGIC1 
 #ifdef MAGIC2
-      && epnt->e_machine != MAGIC2
+                   && epnt->e_machine != MAGIC2
 #endif
-      )){
-    _dl_internal_error_number = (epnt->e_type != ET_DYN ? DL_ERROR_NOTDYN : DL_ERROR_NOTMAGIC);
-    _dl_fdprintf(2, "%s: '%s' is not an ELF executable for " ELF_TARGET "\n",
-                _dl_progname, libname);
-    _dl_close(infile);
-    return NULL;
-  };
-
-  ppnt = (struct elf_phdr *) &header[epnt->e_phoff];
-
-  piclib = 1;
-  for(i=0;i < epnt->e_phnum; i++){
-
-    if(ppnt->p_type == PT_DYNAMIC) {
-      if (dynamic_addr)
-       _dl_fdprintf(2, "%s: '%s' has more than one dynamic section\n",
-                    _dl_progname, libname);
-      dynamic_addr = ppnt->p_vaddr;
-      dynamic_size = ppnt->p_filesz;
-    };
-
-    if(ppnt->p_type == PT_LOAD) {
-       /* See if this is a PIC library. */
-       if(i == 0 && ppnt->p_vaddr > 0x1000000) {
-           piclib = 0;
-           minvma=ppnt->p_vaddr;
+               )) 
+       {
+               _dl_internal_error_number = 
+                   (epnt->e_type != ET_DYN ? DL_ERROR_NOTDYN : DL_ERROR_NOTMAGIC);
+               _dl_fdprintf(2, "%s: '%s' is not an ELF executable for " ELF_TARGET 
+                       "\n", _dl_progname, libname);
+               _dl_close(infile);
+               return NULL;
+       };
+
+       ppnt = (elf_phdr *) & header[epnt->e_phoff];
+
+       piclib = 1;
+       for (i = 0; i < epnt->e_phnum; i++) {
+
+               if (ppnt->p_type == PT_DYNAMIC) {
+                       if (dynamic_addr)
+                               _dl_fdprintf(2, "%s: '%s' has more than one dynamic section\n", 
+                                       _dl_progname, libname);
+                       dynamic_addr = ppnt->p_vaddr;
+                       dynamic_size = ppnt->p_filesz;
+               };
+
+               if (ppnt->p_type == PT_LOAD) {
+                       /* See if this is a PIC library. */
+                       if (i == 0 && ppnt->p_vaddr > 0x1000000) {
+                               piclib = 0;
+                               minvma = ppnt->p_vaddr;
+                       }
+                       if (piclib && ppnt->p_vaddr < minvma) {
+                               minvma = ppnt->p_vaddr;
+                       }
+                       if (((unsigned int) ppnt->p_vaddr + ppnt->p_memsz) > maxvma) {
+                               maxvma = ppnt->p_vaddr + ppnt->p_memsz;
+                       }
+               }
+               ppnt++;
+       };
+
+       maxvma = (maxvma + 0xfffU) & ~0xfffU;
+       minvma = minvma & ~0xffffU;
+
+       flags = MAP_PRIVATE /*| MAP_DENYWRITE */ ;
+       if (!piclib)
+               flags |= MAP_FIXED;
+
+       status = (char *) _dl_mmap((char *) (piclib ? 0 : minvma), 
+               maxvma - minvma, PROT_NONE, flags | MAP_ANONYMOUS, -1, 0);
+       if (_dl_mmap_check_error(status)) {
+               _dl_fdprintf(2, "%s: can't map '/dev/zero'\n", _dl_progname);
+               _dl_internal_error_number = DL_ERROR_MMAP_FAILED;
+               _dl_close(infile);
+               return NULL;
+       };
+       libaddr = (unsigned int) status;
+       flags |= MAP_FIXED;
+
+       /* Get the memory to store the library */
+       ppnt = (elf_phdr *) & header[epnt->e_phoff];
+
+       for (i = 0; i < epnt->e_phnum; i++) {
+               if (ppnt->p_type == PT_LOAD) {
+
+                       /* See if this is a PIC library. */
+                       if (i == 0 && ppnt->p_vaddr > 0x1000000) {
+                               piclib = 0;
+                               /* flags |= MAP_FIXED; */
+                       }
+
+
+
+                       if (ppnt->p_flags & PF_W) {
+                               unsigned int map_size;
+                               char *cpnt;
+
+                               status = (char *) _dl_mmap((char *) ((piclib ? libaddr : 0) + 
+                                       (ppnt->p_vaddr & 0xfffff000)), (ppnt->p_vaddr & 0xfff) 
+                                       + ppnt->p_filesz, LXFLAGS(ppnt->p_flags), flags, infile, 
+                                       ppnt->p_offset & 0x7ffff000);
+
+                               if (_dl_mmap_check_error(status)) {
+                                       _dl_fdprintf(2, "%s: can't map '%s'\n", 
+                                               _dl_progname, libname);
+                                       _dl_internal_error_number = DL_ERROR_MMAP_FAILED;
+                                       _dl_munmap((char *) libaddr, maxvma - minvma);
+                                       _dl_close(infile);
+                                       return NULL;
+                               };
+
+                               /* Pad the last page with zeroes. */
+                               cpnt = (char *) (status + (ppnt->p_vaddr & 0xfff) +
+                                                         ppnt->p_filesz);
+                               while (((unsigned int) cpnt) & 0xfff)
+                                       *cpnt++ = 0;
+
+                               /* I am not quite sure if this is completely
+                                * correct to do or not, but the basic way that
+                                * we handle bss segments is that we mmap
+                                * /dev/zero if there are any pages left over
+                                * that are not mapped as part of the file */
+
+                               map_size = (ppnt->p_vaddr + ppnt->p_filesz + 0xfff) & 0xfffff000;
+                               if (map_size < ppnt->p_vaddr + ppnt->p_memsz)
+                                       status = (char *) _dl_mmap((char *) map_size + 
+                                               (piclib ? libaddr : 0), 
+                                               ppnt->p_vaddr + ppnt->p_memsz - map_size, 
+                                               LXFLAGS(ppnt->p_flags), flags | MAP_ANONYMOUS, -1, 0);
+                       } else
+                               status = (char *) _dl_mmap((char *) (ppnt->p_vaddr & 0xfffff000) 
+                                       + (piclib ? libaddr : 0), (ppnt->p_vaddr & 0xfff) + 
+                                       ppnt->p_filesz, LXFLAGS(ppnt->p_flags), flags, 
+                                       infile, ppnt->p_offset & 0x7ffff000);
+                       if (_dl_mmap_check_error(status)) {
+                               _dl_fdprintf(2, "%s: can't map '%s'\n", _dl_progname, libname);
+                               _dl_internal_error_number = DL_ERROR_MMAP_FAILED;
+                               _dl_munmap((char *) libaddr, maxvma - minvma);
+                               _dl_close(infile);
+                               return NULL;
+                       };
+
+                       /* if(libaddr == 0 && piclib) {
+                          libaddr = (unsigned int) status;
+                          flags |= MAP_FIXED;
+                          }; */
+               };
+               ppnt++;
+       };
+       _dl_close(infile);
+
+       /* For a non-PIC library, the addresses are all absolute */
+       if (piclib) {
+               dynamic_addr += (unsigned int) libaddr;
        }
-       if(piclib && ppnt->p_vaddr < minvma) {
-           minvma = ppnt->p_vaddr;
+
+       /* 
+        * OK, the ELF library is now loaded into VM in the correct locations
+        * The next step is to go through and do the dynamic linking (if needed).
+        */
+
+       /* Start by scanning the dynamic section to get all of the pointers */
+
+       if (!dynamic_addr) {
+               _dl_internal_error_number = DL_ERROR_NODYNAMIC;
+               _dl_fdprintf(2, "%s: '%s' is missing a dynamic section\n", 
+                       _dl_progname, libname);
+               return NULL;
        }
-       if(((unsigned int)ppnt->p_vaddr + ppnt->p_memsz) > maxvma) {
-           maxvma = ppnt->p_vaddr + ppnt->p_memsz;
+
+       dpnt = (Elf32_Dyn *) dynamic_addr;
+
+       dynamic_size = dynamic_size / sizeof(Elf32_Dyn);
+       _dl_memset(dynamic_info, 0, sizeof(dynamic_info));
+       for (i = 0; i < dynamic_size; i++) {
+               if (dpnt->d_tag > DT_JMPREL) {
+                       dpnt++;
+                       continue;
+               }
+               dynamic_info[dpnt->d_tag] = dpnt->d_un.d_val;
+               if (dpnt->d_tag == DT_TEXTREL || SVR4_BUGCOMPAT)
+                       dynamic_info[DT_TEXTREL] = 1;
+               dpnt++;
+       };
+
+       /* If the TEXTREL is set, this means that we need to make the pages
+          writable before we perform relocations.  Do this now. They get set back
+          again later. */
+
+       if (dynamic_info[DT_TEXTREL]) {
+               ppnt = (elf_phdr *) & header[epnt->e_phoff];
+               for (i = 0; i < epnt->e_phnum; i++, ppnt++) {
+                       if (ppnt->p_type == PT_LOAD && !(ppnt->p_flags & PF_W))
+                               _dl_mprotect((void *) ((piclib ? libaddr : 0) + 
+                                           (ppnt->p_vaddr & 0xfffff000)), 
+                                       (ppnt->p_vaddr & 0xfff) + (unsigned int) ppnt->p_filesz, 
+                                       PROT_READ | PROT_WRITE | PROT_EXEC);
+               }
        }
-     }
-    ppnt++;
-  };
-
-  maxvma=(maxvma+0xfffU)&~0xfffU;
-  minvma=minvma&~0xffffU;
-  
-  flags = MAP_PRIVATE /*| MAP_DENYWRITE*/;
-  if(!piclib) flags |= MAP_FIXED;
-  
-  status = (char *) _dl_mmap((char *) (piclib?0:minvma),
-                         maxvma-minvma, 
-                         PROT_NONE, 
-                         flags | MAP_ANONYMOUS, -1,
-                         0);
-  if(_dl_mmap_check_error(status)) {
-    _dl_fdprintf(2, "%s: can't map '/dev/zero'\n", _dl_progname);
-    _dl_internal_error_number = DL_ERROR_MMAP_FAILED;
-    _dl_close(infile);
-     return NULL;
-  };
-  libaddr=(unsigned int)status;
-  flags|=MAP_FIXED;
-
-  /* Get the memory to store the library */
-  ppnt = (struct elf_phdr *) &header[epnt->e_phoff];
-  
-  for(i=0;i < epnt->e_phnum; i++){
-    if(ppnt->p_type == PT_LOAD) {
-
-      /* See if this is a PIC library. */
-      if(i == 0 && ppnt->p_vaddr > 0x1000000) {
-       piclib = 0;
-       /* flags |= MAP_FIXED; */
-      }
-
-
-      
-      if(ppnt->p_flags & PF_W) {
-       unsigned int map_size;
-       char * cpnt;
-       
-       status = (char *) _dl_mmap((char *) ((piclib?libaddr:0)  +
-                                            (ppnt->p_vaddr & 0xfffff000)),
-                         (ppnt->p_vaddr & 0xfff) + ppnt->p_filesz, 
-                         LXFLAGS(ppnt->p_flags), 
-                         flags, infile,
-                         ppnt->p_offset & 0x7ffff000);
-       
-       if(_dl_mmap_check_error(status)) {
-           _dl_fdprintf(2, "%s: can't map '%s'\n", _dl_progname, libname);
-           _dl_internal_error_number = DL_ERROR_MMAP_FAILED;
-           _dl_munmap((char *)libaddr, maxvma-minvma);
-           _dl_close(infile);
-           return NULL;
+
+
+       tpnt = _dl_add_elf_hash_table(libname, (char *) libaddr, dynamic_info, 
+               dynamic_addr, dynamic_size);
+
+       tpnt->ppnt = (elf_phdr *) (tpnt->loadaddr + epnt->e_phoff);
+       tpnt->n_phent = epnt->e_phnum;
+
+       /*
+        * OK, the next thing we need to do is to insert the dynamic linker into
+        * the proper entry in the GOT so that the PLT symbols can be properly
+        * resolved. 
+        */
+
+       lpnt = (int *) dynamic_info[DT_PLTGOT];
+
+       if (lpnt) {
+               lpnt = (int *) (dynamic_info[DT_PLTGOT] + ((int) libaddr));
+               INIT_GOT(lpnt, tpnt);
        };
-       
-       /* Pad the last page with zeroes. */
-       cpnt =(char *) (status + (ppnt->p_vaddr & 0xfff) + ppnt->p_filesz);
-       while(((unsigned int) cpnt) & 0xfff) *cpnt++ = 0;
-
-/* I am not quite sure if this is completely correct to do or not, but
-   the basic way that we handle bss segments is that we mmap /dev/zero if
-   there are any pages left over that are not mapped as part of the file */
-
-       map_size = (ppnt->p_vaddr + ppnt->p_filesz + 0xfff) & 0xfffff000;
-       if(map_size < ppnt->p_vaddr + ppnt->p_memsz)
-         status = (char *) _dl_mmap((char *) map_size + (piclib?libaddr:0), 
-                           ppnt->p_vaddr + ppnt->p_memsz - map_size,
-                           LXFLAGS(ppnt->p_flags),
-                           flags | MAP_ANONYMOUS, -1, 0);
-      } else
-       status = (char *) _dl_mmap((char *) (ppnt->p_vaddr & 0xfffff000) + 
-                                  (piclib?libaddr:0), 
-                         (ppnt->p_vaddr & 0xfff) + ppnt->p_filesz, 
-                         LXFLAGS(ppnt->p_flags), 
-                         flags, infile, 
-                         ppnt->p_offset & 0x7ffff000);
-      if(_dl_mmap_check_error(status)) {
-       _dl_fdprintf(2, "%s: can't map '%s'\n", _dl_progname, libname);
-       _dl_internal_error_number = DL_ERROR_MMAP_FAILED;
-       _dl_munmap((char *)libaddr, maxvma-minvma);
-       _dl_close(infile);
-       return NULL;
-      };
 
-      /* if(libaddr == 0 && piclib) {
-       libaddr = (unsigned int) status;
-       flags |= MAP_FIXED;
-      }; */
-    };
-    ppnt++;
-  };
-  _dl_close(infile);
-  
-  /* For a non-PIC library, the addresses are all absolute */
-  if(piclib) {
-    dynamic_addr += (unsigned int) libaddr;
-  }
-
- /* 
-  * OK, the ELF library is now loaded into VM in the correct locations
-  * The next step is to go through and do the dynamic linking (if needed).
-  */
-  
-  /* Start by scanning the dynamic section to get all of the pointers */
-  
-  if(!dynamic_addr) {
-    _dl_internal_error_number = DL_ERROR_NODYNAMIC;
-    _dl_fdprintf(2, "%s: '%s' is missing a dynamic section\n", _dl_progname, libname);
-    return NULL;
-  }
-
-  dpnt = (struct dynamic *) dynamic_addr;
-
-  dynamic_size = dynamic_size / sizeof(struct dynamic);
-  _dl_memset(dynamic_info, 0, sizeof(dynamic_info));
-  for(i=0; i< dynamic_size; i++){
-    if( dpnt->d_tag > DT_JMPREL ) {dpnt++; continue; }
-    dynamic_info[dpnt->d_tag] = dpnt->d_un.d_val;
-    if(dpnt->d_tag == DT_TEXTREL ||
-       SVR4_BUGCOMPAT) dynamic_info[DT_TEXTREL] = 1;
-    dpnt++;
-  };
-
-  /* If the TEXTREL is set, this means that we need to make the pages
-     writable before we perform relocations.  Do this now. They get set back
-     again later. */
-
-  if (dynamic_info[DT_TEXTREL]) {
-  ppnt = (struct elf_phdr *) &header[epnt->e_phoff];
-  for(i=0;i < epnt->e_phnum; i++, ppnt++){
-    if(ppnt->p_type == PT_LOAD && !(ppnt->p_flags & PF_W))
-      _dl_mprotect((void *) ((piclib?libaddr:0) + (ppnt->p_vaddr & 0xfffff000)),
-                  (ppnt->p_vaddr & 0xfff) + (unsigned int) ppnt->p_filesz,
-                  PROT_READ | PROT_WRITE | PROT_EXEC);
-  }
-  }
-
-
-  tpnt = _dl_add_elf_hash_table(libname, (char *) libaddr, dynamic_info, dynamic_addr, 
-                             dynamic_size);
-
-  tpnt->ppnt = (struct elf_phdr *) (tpnt->loadaddr + epnt->e_phoff);
-  tpnt->n_phent = epnt->e_phnum;
-
-  /*
-   * OK, the next thing we need to do is to insert the dynamic linker into
-   * the proper entry in the GOT so that the PLT symbols can be properly
-   * resolved. 
-   */
-  
-  lpnt = (int *) dynamic_info[DT_PLTGOT];
-  
-  if(lpnt) {
-    lpnt = (int *) (dynamic_info[DT_PLTGOT] + ((int) libaddr));
-    INIT_GOT(lpnt, tpnt);
-  };
-  
-  return tpnt;
+       return tpnt;
 }
 
 /* Ugly, ugly.  Some versions of the SVr4 linker fail to generate COPY
@@ -561,28 +585,30 @@ struct elf_resolve * _dl_load_elf_shared_library(int secure,
    are guaranteed to be generated by a trustworthy linker, then this
    step can be skipped. */
 
-int _dl_copy_fixups(struct dyn_elf * rpnt)
+int _dl_copy_fixups(struct dyn_elf *rpnt)
 {
-  int goof = 0;
-  struct elf_resolve * tpnt;
+       int goof = 0;
+       struct elf_resolve *tpnt;
 
-  if(rpnt->next) goof += _dl_copy_fixups(rpnt->next);
-  else return 0;
+       if (rpnt->next)
+               goof += _dl_copy_fixups(rpnt->next);
+       else
+               return 0;
+
+       tpnt = rpnt->dyn;
+
+       if (tpnt->init_flag & COPY_RELOCS_DONE)
+               return goof;
+       tpnt->init_flag |= COPY_RELOCS_DONE;
 
-  tpnt = rpnt->dyn;
-       
-  if (tpnt->init_flag & COPY_RELOCS_DONE) return goof;
-  tpnt->init_flag |= COPY_RELOCS_DONE;
-  
 #ifdef ELF_USES_RELOCA
-  goof += _dl_parse_copy_information(rpnt, tpnt->dynamic_info[DT_RELA],
-                                          tpnt->dynamic_info[DT_RELASZ], 0);
+       goof += _dl_parse_copy_information(rpnt, 
+               tpnt->dynamic_info[DT_RELA], tpnt->dynamic_info[DT_RELASZ], 0);
 
 #else
-  goof += _dl_parse_copy_information(rpnt, tpnt->dynamic_info[DT_REL],
-                                          tpnt->dynamic_info[DT_RELSZ], 0);
+       goof += _dl_parse_copy_information(rpnt, tpnt->dynamic_info[DT_REL], 
+               tpnt->dynamic_info[DT_RELSZ], 0);
 
 #endif
-  return goof;
+       return goof;
 }
-
index f62e641..0fe4318 100644 (file)
@@ -1,4 +1,3 @@
-#include <linux/types.h>
 #include <asm/unistd.h>
 
 /* Here are the macros which define how this platform makes
index 6f0d9f8..c69ef86 100644 (file)
@@ -41,20 +41,12 @@ an ELF sharable library or a linux style of shared library. */
    a more than adequate job of explaining everything required to get this
    working. */
 
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/unistd.h>
-/*#include <stdlib.h>*/
-#include "string.h"
-#include <linux/unistd.h>
-#include <linux/fcntl.h>
+#include <sys/types.h>
+#include "elf.h"
 #include "hash.h"
-#include "linuxelf.h"
+#include "syscall.h"
+#include "string.h"
 #include "sysdep.h"
-#include "../syscall.h"
-#include "../string.h"
-
-#define SVR4_COMPATIBILITY
 
 extern char *_dl_progname;
 
@@ -63,10 +55,10 @@ extern _dl_linux_resolve(void);
 unsigned int _dl_linux_resolver(unsigned int reloc_entry, unsigned int * plt)
 {
   int reloc_type;
-  struct elf32_rela * this_reloc;
+  Elf32_Rela * this_reloc;
   char * strtab;
-  struct elf32_sym * symtab; 
-  struct elf32_rela * rel_addr;
+  Elf32_Sym * symtab; 
+  Elf32_Rela * rel_addr;
   struct elf_resolve * tpnt;
   int symtab_index;
   char * new_addr;
@@ -74,7 +66,7 @@ unsigned int _dl_linux_resolver(unsigned int reloc_entry, unsigned int * plt)
   unsigned int instr_addr;
   tpnt = (struct elf_resolve *) plt[2];
 
-  rel_addr = (struct elf32_rela *) (tpnt->dynamic_info[DT_JMPREL] + 
+  rel_addr = (Elf32_Rela *) (tpnt->dynamic_info[DT_JMPREL] + 
                                   tpnt->loadaddr);
 
   /*
@@ -82,12 +74,12 @@ unsigned int _dl_linux_resolver(unsigned int reloc_entry, unsigned int * plt)
    */
   reloc_entry = (reloc_entry >> 12) - 0xc;
 
-  this_reloc = (struct elf32_rela *) ((char *) rel_addr + reloc_entry);
+  this_reloc = (Elf32_Rela *) ((char *) rel_addr + reloc_entry);
 
   reloc_type = ELF32_R_TYPE(this_reloc->r_info);
   symtab_index = ELF32_R_SYM(this_reloc->r_info);
 
-  symtab =  (struct elf32_sym *) (tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr);
+  symtab =  (Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr);
   strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
 
   _dl_fdprintf(2, "tpnt = %x\n", tpnt);
@@ -146,17 +138,17 @@ void _dl_parse_lazy_relocation_information(struct elf_resolve * tpnt, int rel_ad
   char * strtab;
   int reloc_type;
   int symtab_index;
-  struct elf32_sym * symtab; 
-  struct elf32_rela * rpnt;
+  Elf32_Sym * symtab; 
+  Elf32_Rela * rpnt;
   unsigned int * reloc_addr;
 
   /* Now parse the relocation information */
-  rpnt = (struct elf32_rela *) (rel_addr + tpnt->loadaddr);
+  rpnt = (Elf32_Rela *) (rel_addr + tpnt->loadaddr);
 
-  symtab =  (struct elf32_sym *) (tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr);
+  symtab =  (Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr);
   strtab = ( char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
 
-  for(i=0; i< rel_size; i += sizeof(struct elf32_rela), rpnt++){
+  for(i=0; i< rel_size; i += sizeof(Elf32_Rela), rpnt++){
     reloc_addr = (int *) (tpnt->loadaddr + (int)rpnt->r_offset);
     reloc_type = ELF32_R_TYPE(rpnt->r_info);
     symtab_index = ELF32_R_SYM(rpnt->r_info);
@@ -191,19 +183,19 @@ int _dl_parse_relocation_information(struct elf_resolve * tpnt, int rel_addr,
   char * strtab;
   int reloc_type;
   int goof = 0;
-  struct elf32_sym * symtab; 
-  struct elf32_rela * rpnt;
+  Elf32_Sym * symtab; 
+  Elf32_Rela * rpnt;
   unsigned int * reloc_addr;
   unsigned int symbol_addr;
   int symtab_index;
   /* Now parse the relocation information */
 
-  rpnt = (struct elf32_rela *) (rel_addr + tpnt->loadaddr);
+  rpnt = (Elf32_Rela *) (rel_addr + tpnt->loadaddr);
 
-  symtab =  (struct elf32_sym *) (tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr);
+  symtab =  (Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr);
   strtab = ( char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
 
-  for(i=0; i< rel_size; i+= sizeof(struct elf32_rela), rpnt++){
+  for(i=0; i< rel_size; i+= sizeof(Elf32_Rela), rpnt++){
     reloc_addr = (int *) (tpnt->loadaddr + (int)rpnt->r_offset);
     reloc_type = ELF32_R_TYPE(rpnt->r_info);
     symtab_index = ELF32_R_SYM(rpnt->r_info);
@@ -307,8 +299,8 @@ int _dl_parse_copy_information(struct dyn_elf * xpnt, int rel_addr,
   char * strtab;
   int reloc_type;
   int goof = 0;
-  struct elf32_sym * symtab; 
-  struct elf32_rela * rpnt;
+  Elf32_Sym * symtab; 
+  Elf32_Rela * rpnt;
   unsigned int * reloc_addr;
   unsigned int symbol_addr;
   struct elf_resolve *tpnt;
@@ -317,12 +309,12 @@ int _dl_parse_copy_information(struct dyn_elf * xpnt, int rel_addr,
 
   tpnt = xpnt->dyn;
   
-  rpnt = (struct elf32_rela *) (rel_addr + tpnt->loadaddr);
+  rpnt = (Elf32_Rela *) (rel_addr + tpnt->loadaddr);
 
-  symtab =  (struct elf32_sym *) (tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr);
+  symtab =  (Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr);
   strtab = ( char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);
 
-  for(i=0; i< rel_size; i+= sizeof(struct elf32_rela), rpnt++){
+  for(i=0; i< rel_size; i+= sizeof(Elf32_Rela), rpnt++){
     reloc_addr = (int *) (tpnt->loadaddr + (int)rpnt->r_offset);
     reloc_type = ELF32_R_TYPE(rpnt->r_info);
     if(reloc_type != R_SPARC_COPY) continue;
index f62e641..0fe4318 100644 (file)
@@ -1,4 +1,3 @@
-#include <linux/types.h>
 #include <asm/unistd.h>
 
 /* Here are the macros which define how this platform makes
index f62e641..0fe4318 100644 (file)
@@ -1,4 +1,3 @@
-#include <linux/types.h>
 #include <asm/unistd.h>
 
 /* Here are the macros which define how this platform makes
index 1ea8fd7..be0de45 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef _LINUX_STRING_H_
 #define _LINUX_STRING_H_
 
-#include <linux/types.h>       /* for size_t */
+#include <sys/types.h> /* for size_t */
 
 #ifndef NULL
 #define NULL ((void *) 0)
index 4e4d4c1..6678e2c 100644 (file)
@@ -41,6 +41,7 @@ static inline void * _dl_mmap(void * addr, unsigned long size, int prot,
 
 
 #define __NR__dl_open __NR_open
+#define O_RDONLY        0x0000
 static inline _syscall2(int, _dl_open, const char *, fn, int, flags);
 
 #define __NR__dl_write __NR_write
@@ -66,6 +67,7 @@ static inline _syscall3(int, _dl_mprotect, const void *, addr, unsigned long, le
 #include <asm/stat.h> 
 #undef new_stat
 #undef stat
+#define S_ISUID       04000   /* Set user ID on execution.  */
 static inline _syscall2(int, _dl_stat, const char *, file_name, struct kernel_stat *, buf);
 
 
index 48c44e3..4ca1acf 100644 (file)
@@ -12,7 +12,6 @@
 #include <stdarg.h>
 #include "string.h"
 #include "hash.h"
-#include <linux/unistd.h>
 #include "syscall.h"
 
 /* we use this so that we can do without the ctype library */