Advertisement
Guest User

exec.c

a guest
Aug 29th, 2015
78
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 2.35 KB | None | 0 0
  1. #include "types.h"
  2. #include "param.h"
  3. #include "memlayout.h"
  4. #include "mmu.h"
  5. #include "proc.h"
  6. #include "defs.h"
  7. #include "x86.h"
  8. #include "elf.h"
  9.  
  10. int
  11. exec(char *path, char **argv)
  12. {
  13.   char *s, *last;
  14.   int i, off;
  15.   uint argc, sz, sp, ustack[3+MAXARG+1];
  16.   struct elfhdr elf;
  17.   struct inode *ip;
  18.   struct proghdr ph;
  19.   pde_t *pgdir, *oldpgdir;
  20.  
  21.   if((ip = namei(path)) == 0)
  22.     return -1;
  23.   ilock(ip);
  24.   pgdir = 0;
  25.  
  26.   // Check ELF header
  27.   if(readi(ip, (char*)&elf, 0, sizeof(elf)) < sizeof(elf))
  28.     goto bad;
  29.   if(elf.magic != ELF_MAGIC)
  30.     goto bad;
  31.  
  32.   if((pgdir = setupkvm()) == 0)
  33.     goto bad;
  34.  
  35.   // Load program into memory.
  36.   sz = 0;
  37.   for(i=0, off=elf.phoff; i<elf.phnum; i++, off+=sizeof(ph)){
  38.     if(readi(ip, (char*)&ph, off, sizeof(ph)) != sizeof(ph))
  39.       goto bad;
  40.     if(ph.type != ELF_PROG_LOAD)
  41.       continue;
  42.     if(ph.memsz < ph.filesz)
  43.       goto bad;
  44.     if((sz = allocuvm(pgdir, sz, ph.vaddr + ph.memsz)) == 0)
  45.       goto bad;
  46.     if(loaduvm(pgdir, (char*)ph.vaddr, ip, ph.off, ph.filesz) < 0)
  47.       goto bad;
  48.   }
  49.   iunlockput(ip);
  50.   ip = 0;
  51.  
  52.   // Allocate two pages at the next page boundary.
  53.   // Make the first inaccessible.  Use the second as the user stack.
  54.   sz = PGROUNDUP(sz);
  55.   if((sz = allocuvm(pgdir, sz, sz + 2*PGSIZE)) == 0)
  56.     goto bad;
  57.   clearpteu(pgdir, (char*)(sz - 2*PGSIZE));
  58.   sp = sz;
  59.  
  60.   // Push argument strings, prepare rest of stack in ustack.
  61.   for(argc = 0; argv[argc]; argc++) {
  62.     if(argc >= MAXARG)
  63.       goto bad;
  64.     sp = (sp - (strlen(argv[argc]) + 1)) & ~3;
  65.     if(copyout(pgdir, sp, argv[argc], strlen(argv[argc]) + 1) < 0)
  66.       goto bad;
  67.     ustack[3+argc] = sp;
  68.   }
  69.   ustack[3+argc] = 0;
  70.  
  71.   ustack[0] = 0xffffffff;  // fake return PC
  72.   ustack[1] = argc;
  73.   ustack[2] = sp - (argc+1)*4;  // argv pointer
  74.  
  75.   sp -= (3+argc+1) * 4;
  76.   if(copyout(pgdir, sp, ustack, (3+argc+1)*4) < 0)
  77.     goto bad;
  78.  
  79.   // Save program name for debugging.
  80.   for(last=s=path; *s; s++)
  81.     if(*s == '/')
  82.       last = s+1;
  83.   safestrcpy(proc->name, last, sizeof(proc->name));
  84.  
  85.   // Commit to the user image.
  86.   oldpgdir = proc->pgdir;
  87.   proc->pgdir = pgdir;
  88.   proc->sz = sz;
  89.   proc->tf->eip = elf.entry;  // main
  90.   proc->tf->esp = sp;
  91.   switchuvm(proc);
  92.   freevm(oldpgdir);
  93.   return 0;
  94.  
  95.  bad:
  96.   if(pgdir)
  97.     freevm(pgdir);
  98.   if(ip)
  99.     iunlockput(ip);
  100.   return -1;
  101. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement