Example #1
0
int
exec(char *path, char **argv)
{
  char *s, *last;
  char newPath[2*INPUT_BUF]={0};
  int i, off;
  uint argc, sz, sp, ustack[3+MAXARG+1];
  struct elfhdr elf;
  struct inode *ip;
  struct proghdr ph;
  pde_t *pgdir, *oldpgdir;

  if((ip = namei(path)) == 0)
  {
    for( i=0;i<place_to_add_path;i++)
    {
      
      if((ip = namei(newstrcat(newPath,pathVariable[i],path))) != 0){
  	   break;
      }
    }
    if(i>=place_to_add_path)
    return -1;
  }
  
  ilock(ip);
  pgdir = 0;

  // Check ELF header
  if(readi(ip, (char*)&elf, 0, sizeof(elf)) < sizeof(elf))
    goto bad;
  if(elf.magic != ELF_MAGIC)
    goto bad;

  if((pgdir = setupkvm(kalloc)) == 0)
    goto bad;

  // Load program into memory.
  sz = 0;
  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;
    if((sz = allocuvm(pgdir, sz, ph.vaddr + ph.memsz)) == 0)
      goto bad;
    if(loaduvm(pgdir, (char*)ph.vaddr, ip, ph.off, ph.filesz) < 0)
      goto bad;
  }
  iunlockput(ip);
  ip = 0;

  // Allocate two pages at the next page boundary.
  // Make the first inaccessible.  Use the second as the user stack.
  sz = PGROUNDUP(sz);
  if((sz = allocuvm(pgdir, sz, sz + 2*PGSIZE)) == 0)
    goto bad;
  clearpteu(pgdir, (char*)(sz - 2*PGSIZE));
  sp = sz;

  // Push argument strings, prepare rest of stack in ustack.
  for(argc = 0; argv[argc]; argc++) {
    if(argc >= MAXARG)
      goto bad;
    sp = (sp - (strlen(argv[argc]) + 1)) & ~3;
    if(copyout(pgdir, sp, argv[argc], strlen(argv[argc]) + 1) < 0)
      goto bad;
    ustack[3+argc] = sp;
  }
  ustack[3+argc] = 0;

  ustack[0] = 0xffffffff;  // fake return PC
  ustack[1] = argc;
  ustack[2] = sp - (argc+1)*4;  // argv pointer

  sp -= (3+argc+1) * 4;
  if(copyout(pgdir, sp, ustack, (3+argc+1)*4) < 0)
    goto bad;

  // Save program name for debugging.
  for(last=s=path; *s; s++)
    if(*s == '/')
      last = s+1;
  safestrcpy(proc->name, last, sizeof(proc->name));

  // Commit to the user image.
  oldpgdir = proc->pgdir;
  proc->pgdir = pgdir;
  proc->sz = sz;
  proc->tf->eip = elf.entry;  // main
  proc->tf->esp = sp;
  switchuvm(proc);
  freevm(oldpgdir);
  return 0;

 bad:
  if(pgdir)
    freevm(pgdir);
  if(ip)
    iunlockput(ip);
  return -1;
}
Example #2
0
File: ldrdf.c Project: aosm/nasm
int main(int argc, char **argv)
{
    char *outname = "aout.rdf";
    int moduleloaded = 0;
    char *respstrings[128] = { 0, };

    options.verbose = 0;
    options.align = 16;
    options.dynalink = 0;
    options.strip = 0;

    error_file = stderr;

    argc--, argv++;
    if (argc == 0)
        usage();
    while (argc && *argv && **argv == '-' && argv[0][1] != 'l') {
        switch (argv[0][1]) {
        case 'r':
            printf("ldrdf (linker for RDF files) version " LDRDF_VERSION
                   "\n");
            printf("RDOFF2 revision %s\n", RDOFF2_REVISION);
            exit(0);
        case 'v':
            if (argv[0][2] == '=') {
                options.verbose = argv[0][3] - '0';
                if (options.verbose < 0 || options.verbose > 9) {
                    fprintf(stderr,
                            "ldrdf: verbosity level must be a number"
                            " between 0 and 9\n");
                    exit(1);
                }
            } else
                options.verbose++;
            break;
        case 'a':
            options.align = atoi(argv[1]);
            if (options.align <= 0) {
                fprintf(stderr,
                        "ldrdf: -a expects a positive number argument\n");
                exit(1);
            }
            argv++, argc--;
            break;
        case 's':
            options.strip = 1;
            break;
        case 'd':
            if (argv[0][2] == 'y')
                options.dynalink = 1;
            break;
        case 'o':
            outname = argv[1];
            argv++, argc--;
            break;
        case 'j':
            if (!objpath) {
                options.objpath = 1;
                objpath = argv[1];
                argv++, argc--;
                break;
            } else {
                fprintf(stderr,
                        "ldrdf: more than one objects search path specified\n");
                exit(1);
            }
        case 'L':
            if (!libpath) {
                options.libpath = 1;
                libpath = argv[1];
                argv++, argc--;
                break;
            } else {
                fprintf(stderr,
                        "ldrdf: more than one libraries search path specified\n");
                exit(1);
            }
        case '@':{
                int i = 0;
                char buf[256];
                FILE *f;

                options.respfile = 1;
                if (argv[1] != NULL)
                    f = fopen(argv[1], "r");
                else {
                    fprintf(stderr,
                            "ldrdf: no response file name specified\n");
                    exit(1);
                }

                if (f == NULL) {
                    fprintf(stderr,
                            "ldrdf: unable to open response file\n");
                    exit(1);
                }

                argv++, argc--;
                while (fgets(buf, sizeof(buf), f) != NULL) {
                    char *p;
                    if (buf[0] == '\n')
                        continue;
                    if ((p = strchr(buf, '\n')) != NULL)
                        *p = '\0';
                    if (i >= 128) {
                        fprintf(stderr, "ldrdf: too many input files\n");
                        exit(1);
                    }
                    *(respstrings + i) = newstr(buf);
                    argc++, i++;
                }
                break;
            }
        case '2':
            options.stderr_redir = 1;
            error_file = stdout;
            break;
        case 'g':
            generic_rec_file = argv[1];
            argv++, argc--;
            break;
        default:
            usage();
        }
        argv++, argc--;
    }

    if (options.verbose > 4) {
        printf("ldrdf invoked with options:\n");
        printf("    section alignment: %d bytes\n", options.align);
        printf("    output name: `%s'\n", outname);
        if (options.strip)
            printf("    strip symbols\n");
        if (options.dynalink)
            printf("    Unix-style dynamic linking\n");
        if (options.objpath)
            printf("    objects search path: %s\n", objpath);
        if (options.libpath)
            printf("    libraries search path: %s\n", libpath);
        printf("\n");
    }

    symtab = symtabNew();
    initsegments();

    if (!symtab) {
        fprintf(stderr, "ldrdf: out of memory\n");
        exit(1);
    }

    while (argc) {
        if (!*argv)
            argv = respstrings;
        if (!*argv)
            break;
        if (!strncmp(*argv, "-l", 2)) {
            if (libpath && (argv[0][2] != '/'))
                add_library(newstrcat(libpath, *argv + 2));
            else
                add_library(*argv + 2);
        } else {
            if (objpath && (argv[0][0] != '/'))
                loadmodule(newstrcat(objpath, *argv));
            else
                loadmodule(*argv);
            moduleloaded = 1;
        }
        argv++, argc--;
    }

    if (!moduleloaded) {
        printf("ldrdf: nothing to do. ldrdf -h for usage\n");
        return 0;
    }

    search_libraries();

    if (options.verbose > 2) {
        printf("symbol table:\n");
        symtabDump(symtab, stdout);
    }

    write_output(outname);

    if (errorcount > 0)
        exit(1);
    return 0;
}