diff options
author | Eric Andersen <andersen@codepoet.org> | 2001-05-01 14:20:45 +0000 |
---|---|---|
committer | Eric Andersen <andersen@codepoet.org> | 2001-05-01 14:20:45 +0000 |
commit | b7bc129184a23d4c9c70774362f4eeaa5e0b44c8 (patch) | |
tree | f42053a86d7e4f8c156663b4c9c791deef7e2ef5 /ldso | |
parent | 22a9e5bbdf43e1086d80341480d0601ee9c6f898 (diff) |
Yet another major rework. This time around, rework it to no longer
use linux kernel header files.
-Erik
Diffstat (limited to 'ldso')
-rw-r--r-- | ldso/ldso/boot1.c | 1579 | ||||
-rw-r--r-- | ldso/ldso/dl-elf.c | 990 | ||||
-rw-r--r-- | ldso/ldso/dl-hash.c | 400 | ||||
-rw-r--r-- | ldso/ldso/hash.c | 400 | ||||
-rw-r--r-- | ldso/ldso/hash.h | 2 | ||||
-rw-r--r-- | ldso/ldso/i386/dl-syscalls.h | 1 | ||||
-rw-r--r-- | ldso/ldso/i386/elfinterp.c | 475 | ||||
-rw-r--r-- | ldso/ldso/i386/ld_syscalls.h | 1 | ||||
-rw-r--r-- | ldso/ldso/i386/syscalls.h | 1 | ||||
-rw-r--r-- | ldso/ldso/ld-uClibc.c | 1579 | ||||
-rw-r--r-- | ldso/ldso/ld_hash.h | 2 | ||||
-rw-r--r-- | ldso/ldso/ld_string.h | 2 | ||||
-rw-r--r-- | ldso/ldso/ld_syscall.h | 2 | ||||
-rw-r--r-- | ldso/ldso/ldso.c | 1579 | ||||
-rw-r--r-- | ldso/ldso/linuxelf.h | 200 | ||||
-rw-r--r-- | ldso/ldso/m68k/dl-syscalls.h | 1 | ||||
-rw-r--r-- | ldso/ldso/m68k/elfinterp.c | 54 | ||||
-rw-r--r-- | ldso/ldso/m68k/ld_syscalls.h | 1 | ||||
-rw-r--r-- | ldso/ldso/m68k/syscalls.h | 1 | ||||
-rw-r--r-- | ldso/ldso/readelflib1.c | 990 | ||||
-rw-r--r-- | ldso/ldso/sparc/dl-syscalls.h | 1 | ||||
-rw-r--r-- | ldso/ldso/sparc/elfinterp.c | 58 | ||||
-rw-r--r-- | ldso/ldso/sparc/ld_syscalls.h | 1 | ||||
-rw-r--r-- | ldso/ldso/sparc/syscalls.h | 1 | ||||
-rw-r--r-- | ldso/ldso/string.h | 2 | ||||
-rw-r--r-- | ldso/ldso/syscall.h | 2 | ||||
-rw-r--r-- | ldso/ldso/vsprintf.c | 1 |
27 files changed, 4165 insertions, 4161 deletions
diff --git a/ldso/ldso/boot1.c b/ldso/ldso/boot1.c index 3b613fb87..948a6e159 100644 --- a/ldso/ldso/boot1.c +++ b/ldso/ldso/boot1.c @@ -92,17 +92,12 @@ * 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" @@ -110,24 +105,24 @@ #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++ = ' '; < |