summaryrefslogtreecommitdiffstats
path: root/mdk-stage1/dietlibc/libdl/_dl_open.c
diff options
context:
space:
mode:
Diffstat (limited to 'mdk-stage1/dietlibc/libdl/_dl_open.c')
-rw-r--r--mdk-stage1/dietlibc/libdl/_dl_open.c228
1 files changed, 28 insertions, 200 deletions
diff --git a/mdk-stage1/dietlibc/libdl/_dl_open.c b/mdk-stage1/dietlibc/libdl/_dl_open.c
index 1f907db21..f7bd0af95 100644
--- a/mdk-stage1/dietlibc/libdl/_dl_open.c
+++ b/mdk-stage1/dietlibc/libdl/_dl_open.c
@@ -1,207 +1,35 @@
-#include <stdio.h>
-#include <unistd.h>
-#include <sys/mman.h>
+#include <fcntl.h>
#include <dlfcn.h>
-#include <linux/elf.h>
+#include <limits.h>
+#ifndef __DIET_LD_SO__
+#include <string.h>
+#endif
#include "_dl_int.h"
-struct _dl_handle dl_test;
-
-#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))
-
-void _dl_jump();
-
-/*
- * this file is a Q. & D. hack ... don't think this is bug free or meaningfull
- */
-
-static void *do_map_in(void *base, unsigned long length, int flags, int fd, unsigned long offset)
-{
- 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 mmap(base, length, perm, MAP_PRIVATE|((base)?MAP_FIXED:0), fd, offset);
-}
-
-unsigned long do_rel(struct _dl_handle * tmp_dl, unsigned long off)
-{
-// struct _dl_handle * tmp_dl = ((void*)*((&off)-1));
- Elf32_Rel *tmp = ((void*)tmp_dl->plt_rel)+off;
- int sym=ELF32_R_SYM(tmp->r_info);
- register unsigned long sym_val;
-
- printf("do_rel %08x %08x\n",tmp_dl,off);
-
- printf ("do_rel %08x+%x\n",tmp_dl->plt_rel,off);
- printf("do_rel @ %08x with type %d -> %d\n",tmp->r_offset,ELF32_R_TYPE(tmp->r_info),sym);
-
- printf("do_rel sym %08x\n",tmp_dl->dyn_sym_tab[sym].st_value);
-
- /* modify GOT for REAL symbol */
- sym_val=((unsigned long)(tmp_dl->mem_base+tmp_dl->dyn_sym_tab[sym].st_value));
- *((unsigned long*)(tmp_dl->mem_base+tmp->r_offset))=sym_val;
-
- printf("do_rel sym %08x\n",sym_val);
- /* HOWTO JUMP ?!? */
- return sym_val;
-}
-
-void *_dl_open(const char*pathname, int fd, int flag)
-{
- int ps=getpagesize();
- int i;
- unsigned char buf[1024];
- char *m=0,*d;
- struct _dl_handle *ret=0;
-
- unsigned long l;
-
- Elf32_Ehdr *eh;
- Elf32_Phdr *ph;
-
- int ld_nr=0;
- Elf32_Phdr *ld[4]={0,0,0,0};
- Elf32_Phdr *dyn=0;
-
- if (fd==-1) return 0;
-
- printf("_dl_open: %s\n",pathname);
-
- read(fd, buf, 1024);
- eh=(Elf32_Ehdr*)buf;
- ph=(Elf32_Phdr*)&buf[eh->e_phoff];
-
- for (i=0; i<eh->e_phnum; i++) {
- if (ph[i].p_type==PT_LOAD) {
- ld[ld_nr++]=ph+i;
- }
- if (ph[i].p_type==PT_DYNAMIC) {
- dyn=ph+i;
- }
+#ifdef __DIET_LD_SO__
+static
+#endif
+void*_dl_open(const char*filename,int flags) {
+ int fd;
+ char buf[PATH_MAX];
+ const char*p=0;
+
+ for (fd=0;filename[fd] && (p==0);++fd) if (filename[fd]=='/') p=filename;
+ if (p) {
+#ifdef __DIET_LD_SO__
+ if ((fd=_dl_sys_open(p,O_RDONLY,0))<0) fd=-1;
+#else
+ fd=open(p,O_RDONLY);
+#endif
+ } else {
+ p=buf;
+ fd=_dl_search(buf,sizeof(buf)-1,filename);
}
-
- 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);
- m = (char*)do_map_in(0, length, ld[0]->p_flags, fd, offset);
-
- /* zero pad bss */
- l = ld[0]->p_offset+ld[0]->p_filesz;
- memset(m+l,0,length-l);
-
- dl_test.mem_base=m;
- dl_test.mem_size=length;
- dl_test.lnk_count=0;
-
- ret = &dl_test;
- }
- 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);
- 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);
-
- /* mmap all mem_blocks for *.so */
- l = text_size+data_size;
-
- dl_test.mem_size=l;
-
- m = (char*) do_map_in(0,l,ld[0]->p_flags,fd,text_offset);
-
- /* 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_size-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);
- }
-
- dl_test.mem_base=m;
- dl_test.lnk_count=0;
- ret = &dl_test;
- }
-
- printf("_dl_open pre resolv\n");
- if (ret) {
- Elf32_Dyn* dyn_tab = (void*)m+dyn->p_vaddr;
- void (*init)();
- unsigned long* got=0;
- void* jmprel=0;
- int pltreltype=0;
- int pltrelsize=0;
-
- printf("_dl_open IN resolv\n");
- for(i=0;dyn_tab[i].d_tag;i++) {
- if (dyn_tab[i].d_tag==DT_HASH) {
- ret->hash_tab = (unsigned long*)(m+dyn_tab[i].d_un.d_ptr);
- }
- if (dyn_tab[i].d_tag==DT_SYMTAB) {
- ret->dyn_sym_tab = (Elf32_Sym*)(m+dyn_tab[i].d_un.d_ptr);
- }
- if (dyn_tab[i].d_tag==DT_STRTAB) {
- ret->dyn_str_tab = (char*)(m+dyn_tab[i].d_un.d_ptr);
- }
- if (dyn_tab[i].d_tag==DT_FINI) {
- ret->fini = (void(*)(void))(m+dyn_tab[i].d_un.d_val);
- }
- if (dyn_tab[i].d_tag==DT_INIT) {
- init = (void(*)(void))(m+dyn_tab[i].d_un.d_val);
- printf("init @ %08x\n",init);
- }
- if (dyn_tab[i].d_tag==DT_PLTGOT) {
- got=(unsigned long*)(m+dyn_tab[i].d_un.d_val);
- }
- if (dyn_tab[i].d_tag==DT_PLTREL) {
- pltreltype=dyn_tab[i].d_un.d_val;
- }
- if (dyn_tab[i].d_tag==DT_PLTRELSZ) {
- pltrelsize=dyn_tab[i].d_un.d_val;
- }
- if (dyn_tab[i].d_tag==DT_JMPREL) {
- jmprel=(m+dyn_tab[i].d_un.d_val);
- dl_test.plt_rel=jmprel;
- }
- }
- /* GOT */
- got[0]+=(unsigned long)m;
- got[1]=(unsigned long)&dl_test;
-// got[2]=(unsigned long)do_rel;
- got[2]=(unsigned long)(_dl_jump);
- /* */
-
- if (pltreltype == DT_REL) {
- Elf32_Rel *tmp = jmprel;
- for (;(char*)tmp<(((char*)jmprel)+pltrelsize);(char*)tmp=((char*)tmp)+sizeof(Elf32_Rel)) {
- *((unsigned long*)(m+tmp->r_offset))+=(unsigned long)m;
-// *((unsigned long*)(m+tmp->r_offset))+=(unsigned long)do_rel;
- printf("rel @ %08x with type %d -> %d\n",tmp->r_offset,ELF32_R_TYPE(tmp->r_info),ELF32_R_SYM(tmp->r_info));
- }
- }
-
- printf("_dl_open post resolv, pre init\n");
- init();
+ if (fd==-1) {
+ _dl_error_data=filename;
+ _dl_error=1;
+ return 0;
}
- printf("_dl_open post resolv, init\n");
-
- close(fd);
- return ret;
+ return _dl_load(filename,p,fd,flags);
}