exec.c

来自「美国mit操作系统课程所用的一个教学操作系统xv6」· C语言 代码 · 共 116 行

C
116
字号
#include "types.h"#include "param.h"#include "mmu.h"#include "proc.h"#include "defs.h"#include "x86.h"#include "elf.h"intexec(char *path, char **argv){  char *mem, *s, *last;  int i, argc, arglen, len, off;  uint sz, sp, argp;  struct elfhdr elf;  struct inode *ip;  struct proghdr ph;  if((ip = namei(path)) == 0)    return -1;  ilock(ip);  // Compute memory size of new process.  mem = 0;  sz = 0;  // Program segments.  if(readi(ip, (char*)&elf, 0, sizeof(elf)) < sizeof(elf))    goto bad;  if(elf.magic != ELF_MAGIC)    goto bad;  for(i=0, off=elf.phoff; i<elf.phnum; i++, off+=sizeof(ph)){    if(readi(ip, (char*)&ph, off, sizeof(ph)) != sizeof(ph))      goto bad;    if(ph.type != ELF_PROG_LOAD)      continue;    if(ph.memsz < ph.filesz)      goto bad;    sz += ph.memsz;  }    // Arguments.  arglen = 0;  for(argc=0; argv[argc]; argc++)    arglen += strlen(argv[argc]) + 1;  arglen = (arglen+3) & ~3;  sz += arglen + 4*(argc+1);  // Stack.  sz += PAGE;    // Allocate program memory.  sz = (sz+PAGE-1) & ~(PAGE-1);  mem = kalloc(sz);  if(mem == 0)    goto bad;  memset(mem, 0, sz);  // Load program into memory.  for(i=0, off=elf.phoff; i<elf.phnum; i++, off+=sizeof(ph)){    if(readi(ip, (char*)&ph, off, sizeof(ph)) != sizeof(ph))      goto bad;    if(ph.type != ELF_PROG_LOAD)      continue;    if(ph.va + ph.memsz > sz)      goto bad;    if(readi(ip, mem + ph.va, ph.offset, ph.filesz) != ph.filesz)      goto bad;    memset(mem + ph.va + ph.filesz, 0, ph.memsz - ph.filesz);  }  iunlockput(ip);    // Initialize stack.  sp = sz;  argp = sz - arglen - 4*(argc+1);  // Copy argv strings and pointers to stack.  *(uint*)(mem+argp + 4*argc) = 0;  // argv[argc]  for(i=argc-1; i>=0; i--){    len = strlen(argv[i]) + 1;    sp -= len;    memmove(mem+sp, argv[i], len);    *(uint*)(mem+argp + 4*i) = sp;  // argv[i]  }  // Stack frame for main(argc, argv), below arguments.  sp = argp;  sp -= 4;  *(uint*)(mem+sp) = argp;  sp -= 4;  *(uint*)(mem+sp) = argc;  sp -= 4;  *(uint*)(mem+sp) = 0xffffffff;   // fake return pc  // Save program name for debugging.  for(last=s=path; *s; s++)    if(*s == '/')      last = s+1;  safestrcpy(cp->name, last, sizeof(cp->name));  // Commit to the new image.  kfree(cp->mem, cp->sz);  cp->mem = mem;  cp->sz = sz;  cp->tf->eip = elf.entry;  // main  cp->tf->esp = sp;  setupsegs(cp);  return 0; bad:  if(mem)    kfree(mem, sz);  iunlockput(ip);  return -1;}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?