Guts load_icode and proc_create() takes a path
[akaros.git] / kern / src / env.c
index e7a9a0f..02bf991 100644 (file)
@@ -128,135 +128,6 @@ env_setup_vm_error_i:
        return -ENOMEM;
 }
 
-// this helper function handles all cases of copying to/from user/kernel
-// or between two users.
-static error_t load_icode_memcpy(struct proc *dest_p, struct proc *src_p,
-                                 void* dest, const void* src, size_t len)
-{
-       if(src < (void*)UTOP)
-       {
-               if(src_p == NULL)
-                       return -EFAULT;
-
-               if(dest_p == NULL)
-                       return memcpy_from_user(src_p, dest, src, len);
-               else
-               {
-                       // TODO: do something more elegant & faster here.
-                       // e.g. a memcpy_from_user_to_user
-                       uint8_t kbuf[1024];
-                       while(len > 0)
-                       {
-                               size_t thislen = MIN(len,sizeof(kbuf));
-                               if (memcpy_from_user(src_p, kbuf, src, thislen))
-                                       return -EFAULT;
-                               if (memcpy_to_user(dest_p, dest, kbuf, thislen))
-                                       panic("destination env isn't mapped!");
-                               len -= thislen;
-                               src += thislen;
-                               dest += thislen;
-                       }
-                       return ESUCCESS;
-               }
-
-       }
-       else
-       {
-               if(src_p != NULL)
-                       return -EFAULT;
-
-               if(dest_p == NULL)
-                       memcpy(dest, src, len);
-               else if(memcpy_to_user(dest_p, dest, src, len))
-                       panic("destination env isn't mapped!");
-
-               return ESUCCESS;
-       }
-}
-
-//
-// Set up the initial program binary, stack, and processor flags
-// for a user process.
-//
-// This function loads all loadable segments from the ELF binary image
-// into the environment's user memory, starting at the appropriate
-// virtual addresses indicated in the ELF program header.
-// At the same time it clears to zero any portions of these segments
-// that are marked in the program header as being mapped
-// but not actually present in the ELF file - i.e., the program's bss section.
-//
-// Finally, this function maps one page for the program's initial stack.
-static void* load_icode(env_t *SAFE e, env_t* binary_env,
-                        uint8_t *COUNT(size) binary, size_t size)
-{
-       // asw: copy the headers because they might not be aligned.
-       elf_t elfhdr;
-       proghdr_t phdr;
-       void* _end = 0;
-
-       assert(load_icode_memcpy(NULL,binary_env,&elfhdr, binary,
-                                sizeof(elfhdr)) == ESUCCESS);
-
-       int i, r;
-
-       // is this an elf?
-       assert(elfhdr.e_magic == ELF_MAGIC);
-       // make sure we have proghdrs to load
-       assert(elfhdr.e_phnum);
-
-       // TODO: how do we do a runtime COUNT?
-       {TRUSTEDBLOCK // zra: TRUSTEDBLOCK until validation is done.
-       for (i = 0; i < elfhdr.e_phnum; i++) {
-               // copy phdr to kernel mem
-               assert(load_icode_memcpy(NULL,binary_env,&phdr, binary + elfhdr.e_phoff + i*sizeof(phdr), sizeof(phdr)) == ESUCCESS);
-
-               if (phdr.p_type != ELF_PROG_LOAD)
-                       continue;
-               // TODO: validate elf header fields!
-               // seg alloc creates PTE_U|PTE_W pages.  if you ever want to change
-               // this, there will be issues with overlapping sections
-               _end = MAX(_end, (void*)(phdr.p_va + phdr.p_memsz));
-
-               // use mmap to allocate memory.  don't clobber other sections.
-               // this is ugly but will go away once we stop using load_icode
-               uintptr_t pgstart = ROUNDDOWN((uintptr_t)phdr.p_va,PGSIZE);
-               uintptr_t pgend = ROUNDUP((uintptr_t)phdr.p_va+phdr.p_memsz,PGSIZE);
-               for(uintptr_t addr = pgstart; addr < pgend; addr += PGSIZE)
-               {
-                       pte_t* pte = pgdir_walk(e->env_pgdir, (void*)addr, 0);
-                       if(!pte || PAGE_UNMAPPED(*pte))
-                               assert(do_mmap(e,addr,PGSIZE,PROT_READ|PROT_WRITE|PROT_EXEC,
-                                          MAP_ANONYMOUS|MAP_FIXED,NULL,0) != MAP_FAILED);
-               }
-
-               // copy section to user mem
-               assert(load_icode_memcpy(e,binary_env,(void*)phdr.p_va, binary + phdr.p_offset, phdr.p_filesz) == ESUCCESS);
-
-               //no need to memclr the remaining p_memsz-p_filesz bytes
-               //because upage_alloc'd pages are zeroed
-       }}
-
-       proc_init_trapframe(&e->env_tf, 0, elfhdr.e_entry, USTACKTOP);
-       e->env_entry = elfhdr.e_entry;
-
-       // Now map USTACK_NUM_PAGES pages for the program's initial stack
-       // starting at virtual address USTACKTOP - USTACK_NUM_PAGES*PGSIZE.
-       uintptr_t stacksz = USTACK_NUM_PAGES*PGSIZE;
-       assert(do_mmap(e, USTACKTOP-stacksz, stacksz, PROT_READ | PROT_WRITE,
-                      MAP_FIXED | MAP_ANONYMOUS | MAP_POPULATE, NULL, 0)
-              != MAP_FAILED);
-       
-       return _end;
-}
-
-void env_load_icode(env_t* e, env_t* binary_env, uint8_t* binary, size_t size)
-{
-       /* Load the binary and set the current locations of the elf segments.
-        * All end-of-segment pointers are page aligned (invariant) */
-       e->heap_top = load_icode(e, binary_env, binary, size);
-       e->procinfo->heap_bottom = e->heap_top;
-}
-
 #define PER_CPU_THING(type,name)\
 type SLOCKED(name##_lock) * RWPROTECT name;\
 type SLOCKED(name##_lock) *\