Added arch framework for handling page faults
[akaros.git] / kern / src / elf.c
index ee0e48f..8cfe5e2 100644 (file)
@@ -1,4 +1,6 @@
 #include <mm.h>
+#include <frontend.h>
+#include <string.h>
 #include <ros/mman.h>
 #include <kmalloc.h>
 #include <syscall.h>
 struct elf_info
 {
        long entry;
+       long highest_addr;
        long phdr;
        int phnum;
        int dynamic;
        char interp[256];
 };
 
-int load_one_elf(struct proc* p, int fd, struct elf_info* ei)
+int load_one_elf(struct proc* p, int fd, int pgoffset, struct elf_info* ei)
 {
        int ret = -1;
        ei->phdr = -1;
        ei->dynamic = 0;
+       ei->highest_addr = 0;
 
        char* elf = (char*)kmalloc(PGSIZE,0);
        if(!elf || read_page(p,fd,PADDR(elf),0) == -1)
@@ -63,24 +67,27 @@ int load_one_elf(struct proc* p, int fd, struct elf_info* ei)
                        uintptr_t memstart = ROUNDDOWN(ph->p_va,PGSIZE);
                        uintptr_t memend = ROUNDUP(ph->p_va + ph->p_memsz,PGSIZE);
                        uintptr_t memsz = memend-memstart;
+                       if(memend > ei->highest_addr)
+                               ei->highest_addr = memend;
 
                        // mmap will zero the rest of the page if filesz % PGSIZE != 0
                        if(filesz)
-                               if(mmap(p, memstart, filesz,
+                               // TODO: waterman, figure out proper permissions
+                               if(mmap(p, memstart+pgoffset*PGSIZE, filesz,
                                        PROT_READ|PROT_WRITE|PROT_EXEC, MAP_FIXED,
                                        fd, filestart/PGSIZE) == MAP_FAILED)
                                        goto fail;
 
                        filesz = ROUNDUP(filesz,PGSIZE);
                        if(filesz < memsz)
-                               if(mmap(p, memstart+filesz, memsz-filesz,
+                               if(mmap(p, memstart+filesz+pgoffset*PGSIZE, memsz-filesz,
                                        PROT_READ|PROT_WRITE|PROT_EXEC, MAP_FIXED|MAP_ANON,
                                        -1, 0) == MAP_FAILED)
                                        goto fail;
                }
        }
 
-       ei->entry = elfhdr->e_entry;
+       ei->entry = elfhdr->e_entry + pgoffset*PGSIZE;
        ei->phnum = elfhdr->e_phnum;
 
        ret = 0;
@@ -93,14 +100,21 @@ int load_elf(struct proc* p, const char* fn)
 {
        struct elf_info ei,interp_ei;
        int fd = open_file(p,fn,0,0);
-       if(fd == -1 || load_one_elf(p,fd,&ei))
+       if(fd == -1 || load_one_elf(p,fd,0,&ei))
                return -1;
        close_file(p,fd);
 
        if(ei.dynamic)
        {
-               int fd2 = open_file(p,ei.interp,0,0);
-               if(fd2 == -1 || load_one_elf(p,fd2,&interp_ei))
+               // plzplzplz let us use the stack and PADDR()
+               char* str = kmalloc(sizeof(ei.interp),0);
+               if(!str)
+                       return -1;
+               memcpy(str,ei.interp,sizeof(ei.interp));
+               int fd2 = open_file(p,str,0,0);
+               kfree(str);
+
+               if(fd2 == -1 || load_one_elf(p,fd2,1,&interp_ei))
                        return -1;
                close_file(p,fd2);
 
@@ -123,41 +137,19 @@ int load_elf(struct proc* p, const char* fn)
                memcpy(p->env_procinfo->argp+auxp_pos,auxp,sizeof(auxp));
        }
 
-       p->env_entry = ei.dynamic ? interp_ei.entry : ei.entry;
-       proc_set_program_counter(&p->env_tf,p->env_entry);
+       uintptr_t core0_entry = ei.dynamic ? interp_ei.entry : ei.entry;
+       proc_init_trapframe(&p->env_tf,0,core0_entry,USTACKTOP);
+       p->env_entry = ei.entry;
 
        uintptr_t stacksz = USTACK_NUM_PAGES*PGSIZE;
        if(mmap(p,USTACKTOP-stacksz,stacksz,PROT_READ|PROT_WRITE,
                MAP_FIXED|MAP_ANON,-1,0) == MAP_FAILED)
                return -1;
 
-       return 0;
-}
-
-intreg_t sys_exec(struct proc* p, const char fn[MAX_PATH_LEN], procinfo_t* pi)
-{
-       if(p->state != PROC_RUNNING_S)
-               return -1;
-
-       char kfn[PGSIZE];
-       if(memcpy_from_user(p,kfn,fn,PGSIZE))
-               return -1;
-
-       if(memcpy_from_user(p,p->env_procinfo,pi,sizeof(procinfo_t)))
-       {
-               proc_destroy(p);
-               return -1;
-       }
-       proc_init_procinfo(p);
-
-       env_segment_free(p,0,USTACKTOP);
-       proc_init_trapframe(current_tf,0);
-
-       if(load_elf(p,kfn))
-       {
-               proc_destroy(p);
-               return -1;
-       }
+       // Set the heap bottom and top to just past where the text 
+       // region has been loaded
+       p->heap_bottom = (void*)ei.highest_addr;
+       p->heap_top = p->heap_bottom;
 
        return 0;
 }