From ff340ae492915a1723450c148641b594326c5fd8 Mon Sep 17 00:00:00 2001 From: Mystery Man Date: Mon, 4 Apr 2005 19:00:13 +0000 Subject: This commit was manufactured by cvs2svn to create tag 'V10_2_19mdk'. --- mdk-stage1/dietlibc/libdl/_dl_load.c | 401 ----------------------------------- 1 file changed, 401 deletions(-) delete mode 100644 mdk-stage1/dietlibc/libdl/_dl_load.c (limited to 'mdk-stage1/dietlibc/libdl/_dl_load.c') diff --git a/mdk-stage1/dietlibc/libdl/_dl_load.c b/mdk-stage1/dietlibc/libdl/_dl_load.c deleted file mode 100644 index 49e8db0be..000000000 --- a/mdk-stage1/dietlibc/libdl/_dl_load.c +++ /dev/null @@ -1,401 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#include "_dl_int.h" - -#define _ELF_DWN_ROUND(ps,n) ((n)&(~((ps)-1))) -#define _ELF_UP_ROUND(ps,n) ((((n)&((ps)-1))?(ps):0)+ _ELF_DWN_ROUND((ps),(n))) -#define _ELF_RST_ROUND(ps,n) ((n)&((ps)-1)) - -/* this is an arch specific "return jump" for the relocation */ -void _dl_jump(); - -/* - * this file is a Q. & D. hack ... don't think this is bug free or meaningfull - */ - -static inline int map_flags(int flags) -{ - int perm = 0; - if (flags & PF_X) perm|=PROT_EXEC; - if (flags & PF_R) perm|=PROT_READ; - if (flags & PF_W) perm|=PROT_WRITE; - return perm; -} - -static inline void *do_map_in(void *base, unsigned long length, int flags, int fd, unsigned long offset) -{ - register int op = MAP_PRIVATE; - if (base) op|=MAP_FIXED; - return mmap(base, length, map_flags(flags), op, fd, offset); -} - -static struct _dl_handle *_dl_map_lib(const char*fn, const char*pathname, int fd, int flags) -{ - struct _dl_handle* ret=0; - int ps=getpagesize(); - int i; - unsigned char buf[1024]; - char *m=0,*d=0; - - unsigned long l; - struct stat st; - - Elf_Ehdr *eh; - Elf_Phdr *ph; - - int ld_nr=0; - Elf_Phdr **ld=0; - Elf_Phdr *dyn=0; - - if (fd==-1) return 0; - -#ifdef DEBUG - pf(__func__": "); pf(pathname); pf("\n"); -#endif - - if (fstat(fd,&st)<0) { - close(fd); - _dl_error=2; - return 0; - } - else { - // use st_dev and st_ino for identification - } - - if (read(fd, buf, 1024)<128) { - close(fd); - _dl_error=2; - return 0; - } - - eh=(Elf_Ehdr*)buf; - ph=(Elf_Phdr*)&buf[eh->e_phoff]; - - for (i=0; ie_phnum; i++) { - if (ph[i].p_type==PT_LOAD) ++ld_nr; - } - ld=alloca(ld_nr*sizeof(Elf_Phdr)); - - for (ld_nr=i=0; ie_phnum; i++) { - if (ph[i].p_type==PT_LOAD) { - ld[ld_nr++]=ph+i; - } - if (ph[i].p_type==PT_DYNAMIC) { - dyn=ph+i; - } - } - - if (ld_nr==1) { - unsigned long offset = _ELF_DWN_ROUND(ps,ld[0]->p_offset); - unsigned long off = _ELF_RST_ROUND(ps,ld[0]->p_offset); - unsigned long length = _ELF_UP_ROUND(ps,ld[0]->p_memsz+off); - ret = _dl_get_handle(); - - m = (char*)do_map_in(0, length, ld[0]->p_flags, fd, offset); - if (m==MAP_FAILED) { _dl_free_handle(ret); close(fd); return 0; } - - /* zero pad bss */ - l = ld[0]->p_offset+ld[0]->p_filesz; - memset(m+l,0,length-l); - - ret->mem_base=m; - ret->mem_size=length; - } - else if (ld_nr==2) { /* aem... yes Quick & Really Dirty / for the avarage 99% */ -// unsigned long text_addr = _ELF_DWN_ROUND(ps,ld[0]->p_vaddr); /* do we need this ? */ - unsigned long text_offset = _ELF_DWN_ROUND(ps,ld[0]->p_offset); - unsigned long text_off = _ELF_RST_ROUND(ps,ld[0]->p_offset); - unsigned long text_size = _ELF_UP_ROUND(ps,ld[0]->p_memsz+text_off); - - unsigned long data_addr = _ELF_DWN_ROUND(ps,ld[1]->p_vaddr); - unsigned long data_offset = _ELF_DWN_ROUND(ps,ld[1]->p_offset); - unsigned long data_off = _ELF_RST_ROUND(ps,ld[1]->p_offset); - unsigned long data_size = _ELF_UP_ROUND(ps,ld[1]->p_memsz+data_off); - unsigned long data_fsize = _ELF_UP_ROUND(ps,ld[1]->p_filesz+data_off); - - ret = _dl_get_handle(); - /* mmap all mem_blocks for *.so */ - m = (char*) do_map_in(0,text_size+data_size,ld[0]->p_flags,fd,text_offset); - if (m==MAP_FAILED) { _dl_free_handle(ret); close(fd); return 0; } - - /* release data,bss part */ - mprotect(m+data_addr, data_size, PROT_NONE); - - /* mmap data,bss part */ - d = (char*) do_map_in(m+data_addr,data_fsize,ld[1]->p_flags,fd,data_offset); - - /* zero pad bss */ - l = data_off+ld[1]->p_filesz; - memset(d+l,0,data_fsize-l); - - /* more bss ? */ - if (data_size>data_fsize) { - l = data_size-data_fsize; - mmap(d+data_fsize, l, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0); - } - - ret->mem_base=m; - ret->mem_size=text_size+data_size; - } - - if (ret) { - ret->lnk_count=1; - ret->name=strdup(fn); - ret->dyn_str_tab=(char*)m+dyn->p_vaddr; /* missuse of field */ - } - - close(fd); - return ret; -} - -/* local alias */ -static struct _dl_handle* __dl_dyn_scan(struct _dl_handle* dh, void* dyn_addr, int flags) -__attribute__ ((alias("_dl_dyn_scan"))); - -struct _dl_handle* _dl_dyn_scan(struct _dl_handle* dh, void* dyn_addr, int flags) -{ - Elf_Dyn* dyn_tab = dyn_addr; - - void (*init)()=0; - unsigned long* got=0; - void* jmprel=0; - int pltreltype=0; - int pltrelsize=0; - unsigned long rel=0; - int relent=0; - int relsize=0; - - int i; - -#ifdef DEBUG - pf(__func__": pre dynamic scan "); ph((unsigned long)dh); pf("\n"); -#endif - dh->dyn_str_tab=0; - dh->flags=flags; - - for(i=0;dyn_tab[i].d_tag;i++) { -// DEBUG(printf("_dl_load dyn %d, %08lx\n",dyn_tab[i].d_tag, dyn_tab[i].d_un.d_val);) - if (dyn_tab[i].d_tag==DT_HASH) { - dh->hash_tab = (unsigned long*)(dh->mem_base+dyn_tab[i].d_un.d_ptr); -#ifdef DEBUG - pf(__func__": have hash @ "); ph((long)dh->hash_tab); pf("\n"); -#endif - } - else if (dyn_tab[i].d_tag==DT_SYMTAB) { - dh->dyn_sym_tab = (Elf_Sym*)(dh->mem_base+dyn_tab[i].d_un.d_ptr); -#ifdef DEBUG - pf(__func__": have dyn_sym_tab @ "); ph((long)dh->dyn_sym_tab); pf("\n"); -#endif - } - else if (dyn_tab[i].d_tag==DT_STRTAB) { - dh->dyn_str_tab = (char*)(dh->mem_base+dyn_tab[i].d_un.d_ptr); -#ifdef DEBUG - pf(__func__": have dyn_str_tab @ "); ph((long)dh->dyn_str_tab); pf("\n"); -#endif - } - - /* INIT / FINI */ - else if (dyn_tab[i].d_tag==DT_FINI) { - dh->fini = (void(*)(void))(dh->mem_base+dyn_tab[i].d_un.d_val); -#ifdef DEBUG - pf(__func__": have fini @ "); ph((long)dh->fini); pf("\n"); -#endif - } - else if (dyn_tab[i].d_tag==DT_INIT) { - init = (void(*)(void))(dh->mem_base+dyn_tab[i].d_un.d_val); -#ifdef DEBUG - pf(__func__": have init @ "); ph((long)init); pf("\n"); -#endif - } - - /* PLT / Relocation entries for PLT in GOT */ - else if (dyn_tab[i].d_tag==DT_PLTGOT) { - got=(unsigned long*)(dh->mem_base+dyn_tab[i].d_un.d_val); - dh->pltgot=got; -#ifdef DEBUG - pf(__func__": have plt got @ "); ph((long)dh->pltgot); pf("\n"); -#endif - } - else if (dyn_tab[i].d_tag==DT_PLTREL) { - pltreltype=dyn_tab[i].d_un.d_val; -#ifdef DEBUG - pf(__func__": have pltreltype @ "); ph((long)pltreltype); pf("\n"); -#endif - } - else if (dyn_tab[i].d_tag==DT_PLTRELSZ) { - pltrelsize=dyn_tab[i].d_un.d_val; -#ifdef DEBUG - pf(__func__": have pltrelsize @ "); ph((long)pltrelsize); pf("\n"); -#endif - } - else if (dyn_tab[i].d_tag==DT_JMPREL) { - jmprel=(dh->mem_base+dyn_tab[i].d_un.d_val); - dh->plt_rel=jmprel; -#ifdef DEBUG - pf(__func__": have jmprel @ "); ph((long)jmprel); pf("\n"); -#endif - } - - /* Relocation */ - else if (dyn_tab[i].d_tag==DT_REL) { - rel=(unsigned long)(dh->mem_base+dyn_tab[i].d_un.d_val); -#ifdef DEBUG - pf(__func__": have rel @ "); ph((long)rel); pf("\n"); -#endif - } - else if (dyn_tab[i].d_tag==DT_RELENT) { - relent=dyn_tab[i].d_un.d_val; -#ifdef DEBUG - pf(__func__": have relent @ "); ph((long)relent); pf("\n"); -#endif - } - else if (dyn_tab[i].d_tag==DT_RELSZ) { - relsize=dyn_tab[i].d_un.d_val; -#ifdef DEBUG - pf(__func__": have relsize @ "); ph((long)relsize); pf("\n"); -#endif - } - - else if (dyn_tab[i].d_tag==DT_TEXTREL) { - _dl_free_handle(dh); - _dl_error = 3; - return 0; - } - } - /* extra scan for rpath (if program) ... */ - if (dh->name==0) { - for(i=0;dyn_tab[i].d_tag;i++) { - if (dyn_tab[i].d_tag==DT_RPATH) { - char *rpath=dh->dyn_str_tab+dyn_tab[i].d_un.d_val; - _dl_set_rpath(rpath); -#ifdef DEBUG - pf(__func__": have runpath: "); pf(rpath); pf("\n"); -#endif - } - } - } - -#ifdef DEBUG - pf(__func__": post dynamic scan "); ph((unsigned long)dh); pf("\n"); -#endif - - if ((got=_dlsym(dh,"_GLOBAL_OFFSET_TABLE_"))) { -#ifdef DEBUG - pf(__func__": found a GOT @ "); ph((unsigned long)got); pf("\n"); -#endif - /* GOT */ - got[0]+=(unsigned long)dh->mem_base; /* reloc dynamic pointer */ - got[1] =(unsigned long)dh; - got[2] =(unsigned long)(_dl_jump); /* sysdep jump to _dl_rel */ - /* */ - } - else { - if (dh) { - munmap(dh->mem_base,dh->mem_size); - _dl_free_handle(dh); - } - _dl_error = 3; - return 0; - } - - /* load other libs */ - for(i=0;dyn_tab[i].d_tag;i++) { - if (dyn_tab[i].d_tag==DT_NEEDED) { - char *lib_name=dh->dyn_str_tab+dyn_tab[i].d_un.d_val; -#ifdef DEBUG - pf(__func__": needed for this lib: "); pf(lib_name); pf("\n"); -#endif - _dl_queue_lib(lib_name,flags); - } - } - - if (_dl_open_dep()) { - _dl_error = 1; - return 0; - } - - /* relocate */ - if (rel) { -#ifdef DEBUG - pf(__func__": try to relocate some values\n"); -#endif - if (_dl_relocate(dh,(Elf_Rel*)rel,relsize/relent)) { - munmap(dh->mem_base,dh->mem_size); - _dl_free_handle(dh); - return 0; - } - } - - /* do PTL / GOT relocation */ - if (pltreltype == DT_REL) { - Elf_Rel *tmp = jmprel; -#ifdef DEBUG - pf(__func__": rel got\n"); -#endif - for (;(char*)tmp<(((char*)jmprel)+pltrelsize);(char*)tmp=((char*)tmp)+sizeof(Elf_Rel)) { - if ((flags&RTLD_NOW)) { - unsigned long sym=(unsigned long)_dl_sym(dh,ELF_R_SYM(tmp->r_info)); - if (sym) *((unsigned long*)(dh->mem_base+tmp->r_offset))=sym; - else { - _dl_free_handle(dh); - _dl_error = 4; - return 0; - } - } - else - *((unsigned long*)(dh->mem_base+tmp->r_offset))+=(unsigned long)dh->mem_base; -#if 0 - DEBUG("_dl_load rel @ %08lx with type %d -> %d\n",(long)dh->mem_base+tmp->r_offset,ELF_R_TYPE(tmp->r_info),ELF_R_SYM(tmp->r_info)); - DEBUG("_dl_load -> %08lx\n",*((unsigned long*)(dh->mem_base+tmp->r_offset))); -#endif - } - } - if (pltreltype == DT_RELA) { - Elf_Rela *tmp = jmprel; -#ifdef DEBUG - pf(__func__": rela got\n"); -#endif - for (;(char*)tmp<(((char*)jmprel)+pltrelsize);(char*)tmp=((char*)tmp)+sizeof(Elf_Rela)) { - if ((flags&RTLD_NOW)) { - unsigned long sym=(unsigned long)_dl_sym(dh,ELF_R_SYM(tmp->r_info)); - if (sym) *((unsigned long*)(dh->mem_base+tmp->r_offset))=sym; - else { - _dl_free_handle(dh); - _dl_error = 4; - return 0; - } - } - else - *((unsigned long*)(dh->mem_base+tmp->r_offset))=(unsigned long)(dh->mem_base+tmp->r_addend); -#if 0 - DEBUG("_dl_load rela @ %08lx with type %d -> %d\n",(long)dh->mem_base+tmp->r_offset,ELF_R_TYPE(tmp->r_info),ELF_R_SYM(tmp->r_info)); - DEBUG("_dl_load -> %08lx\n",*((unsigned long*)(dh->mem_base+tmp->r_offset))); -#endif - } - } - - /* _dl_load depending libs ... */ -#ifdef DEBUG - pf(__func__": post resolve, pre init\n"); -#endif - if (init) init(); -#ifdef DEBUG - pf(__func__": post init\n"); -#endif - - return dh; -} - -void *_dl_load(const char*fn, const char*pathname, int fd, int flags) -{ - struct _dl_handle* ret=0; - if ((ret=_dl_map_lib(fn,pathname,fd,flags))) { - ret=__dl_dyn_scan(ret,(void*)(ret->dyn_str_tab),flags); - } - return ret; -} -- cgit v1.2.1