group/pintos/src/userprog/process.c
/* Loads an ELF executable from FILE_NAME into the current thread.
   Stores the executable's entry point into *EIP
   and its initial stack pointer into *ESP.
   Returns true if successful, false otherwise. */
Loads an ELF executable from FILE_NAME into the current thread.
Stores the executable's entry point into *EIP
and its initial stack pointer into *ESP.
Returns true if successful, false otherwise.
Loads an ELF executable from FILE_NAME into the current thread . Stores the executable ' s entry point into * EIP and its initial stack pointer into * ESP . Returns true if successful false otherwise .
bool
load (const char *cmd, void (**eip) (void), void **esp)
{
  struct thread *t = thread_current ();
  struct Elf32_Ehdr ehdr;
  struct file *file = NULL;
  off_t file_ofs;
  bool success = false;
  int i;
  char fname[NAME_MAX];
  char *ppath = malloc(sizeof(char) * PATH_MAX);
  get_ppath(cmd, ppath);
  path_basename(ppath, fname);
  t->pagedir = pagedir_create ();
  if (t->pagedir == NULL)
    goto done;
  process_activate ();
  file = filesys_open (ppath);
  if (file == NULL)
    {
      printf ("load: %s: open failed\n", fname);
      goto done;
    }
  if (file_read (file, &ehdr, sizeof ehdr) != sizeof ehdr
      || memcmp (ehdr.e_ident, "\177ELF\1\1\1", 7)
      || ehdr.e_type != 2
      || ehdr.e_machine != 3
      || ehdr.e_version != 1
      || ehdr.e_phentsize != sizeof (struct Elf32_Phdr)
      || ehdr.e_phnum > 1024)
    {
      printf ("load: %s: error loading executable\n", ppath);
      goto done;
    }
  file_ofs = ehdr.e_phoff;
  for (i = 0; i < ehdr.e_phnum; i++)
    {
      struct Elf32_Phdr phdr;
      if (file_ofs < 0 || file_ofs > file_length (file))
        goto done;
      file_seek (file, file_ofs);
      if (file_read (file, &phdr, sizeof phdr) != sizeof phdr)
        goto done;
      file_ofs += sizeof phdr;
      switch (phdr.p_type)
        {
        case PT_NULL:
        case PT_NOTE:
        case PT_PHDR:
        case PT_STACK:
        default:
          break;
        case PT_DYNAMIC:
        case PT_INTERP:
        case PT_SHLIB:
          goto done;
        case PT_LOAD:
          if (validate_segment (&phdr, file))
            {
              bool writable = (phdr.p_flags & PF_W) != 0;
              uint32_t file_page = phdr.p_offset & ~PGMASK;
              uint32_t mem_page = phdr.p_vaddr & ~PGMASK;
              uint32_t page_offset = phdr.p_vaddr & PGMASK;
              uint32_t read_bytes, zero_bytes;
              if (phdr.p_filesz > 0)
                {
                  read_bytes = page_offset + phdr.p_filesz;
                  zero_bytes = (ROUND_UP (page_offset + phdr.p_memsz, PGSIZE)
                                - read_bytes);
                }
              else
                {
                  read_bytes = 0;
                  zero_bytes = ROUND_UP (page_offset + phdr.p_memsz, PGSIZE);
                }
              if (!load_segment (file, file_page, (void *) mem_page,
                                 read_bytes, zero_bytes, writable))
                goto done;
            }
          else
            goto done;
          break;
        }
    }
  if (!setup_stack (esp)) {
    goto done;
  }
  void* sp = *esp;
  int argc = 0;
  char *args[64];
  int inword;
  i = 0;
  inword = 0;
  while(*(cmd + i) != '\0')
      i++;
  i--;
  while(i >= 0) {
    if (*(cmd + i) == ' ') {
        if (inword) {
            args[argc] = (char*)sp;
            argc++;
        }
        inword = 0;
    }
    else {
        if (!inword)
            *(char*)(--sp) = '\0';
        inword = 1;
        *(char*)(--sp) = *(cmd + i);
    }
    i--;
  }
  if (inword) {
      args[argc] = (char*)sp;
      argc++;
  }
  *(uint8_t*)(--sp) = 0;
  sp -= 4;
  *(char**)sp = NULL;
  for (i = 0 ; i < argc ; i ++) {
      sp -= 4;
      *(char**)sp = args[i];
  }
  sp -= 4;
  *(char***) sp = (char**)(sp + 4);
  sp -= 4;
  *(int*) sp = argc;
  sp -= 4;
  *(void**) sp = NULL;
  *(void**) esp = sp;
  *eip = (void (*) (void)) ehdr.e_entry;
  success = true;
  update_open_cnt(ppath);
 done:
  free(ppath);
  return success;
}
bool load ( const char * cmd , void ( * * eip ) ( void ) , void * * esp ) { struct thread * t = thread_current ( ) ; struct Elf32_Ehdr ehdr ; struct file * file = NULL ; off_t file_ofs ; bool success = false ; int i ; char fname [ NAME_MAX ] ; char * ppath = malloc ( sizeof ( char ) * PATH_MAX ) ; get_ppath ( cmd , ppath ) ; path_basename ( ppath , fname ) ; t -> pagedir = pagedir_create ( ) ; if ( t -> pagedir == NULL ) goto done ; process_activate ( ) ; file = filesys_open ( ppath ) ; if ( file == NULL ) { printf ( " \n " , fname ) ; goto done ; } if ( file_read ( file , & ehdr , sizeof ehdr ) != sizeof ehdr || memcmp ( ehdr . e_ident , " \177 \1 \1 \1 " , 7 ) || ehdr . e_type != 2 || ehdr . e_machine != 3 || ehdr . e_version != 1 || ehdr . e_phentsize != sizeof ( struct Elf32_Phdr ) || ehdr . e_phnum > 1024 ) { printf ( " \n " , ppath ) ; goto done ; } file_ofs = ehdr . e_phoff ; for ( i = 0 ; i < ehdr . e_phnum ; i ++ ) { struct Elf32_Phdr phdr ; if ( file_ofs < 0 || file_ofs > file_length ( file ) ) goto done ; file_seek ( file , file_ofs ) ; if ( file_read ( file , & phdr , sizeof phdr ) != sizeof phdr ) goto done ; file_ofs += sizeof phdr ; switch ( phdr . p_type ) { case PT_NULL : case PT_NOTE : case PT_PHDR : case PT_STACK : default : break ; case PT_DYNAMIC : case PT_INTERP : case PT_SHLIB : goto done ; case PT_LOAD : if ( validate_segment ( & phdr , file ) ) { bool writable = ( phdr . p_flags & PF_W ) != 0 ; uint32_t file_page = phdr . p_offset & ~ PGMASK ; uint32_t mem_page = phdr . p_vaddr & ~ PGMASK ; uint32_t page_offset = phdr . p_vaddr & PGMASK ; uint32_t read_bytes , zero_bytes ; if ( phdr . p_filesz > 0 ) { read_bytes = page_offset + phdr . p_filesz ; zero_bytes = ( ROUND_UP ( page_offset + phdr . p_memsz , PGSIZE ) - read_bytes ) ; } else { read_bytes = 0 ; zero_bytes = ROUND_UP ( page_offset + phdr . p_memsz , PGSIZE ) ; } if ( ! load_segment ( file , file_page , ( void * ) mem_page , read_bytes , zero_bytes , writable ) ) goto done ; } else goto done ; break ; } } if ( ! setup_stack ( esp ) ) { goto done ; } void * sp = * esp ; int argc = 0 ; char * args [ 64 ] ; int inword ; i = 0 ; inword = 0 ; while ( * ( cmd + i ) != ' \0 ' ) i ++ ; i -- ; while ( i >= 0 ) { if ( * ( cmd + i ) == ' ' ) { if ( inword ) { args [ argc ] = ( char * ) sp ; argc ++ ; } inword = 0 ; } else { if ( ! inword ) * ( char * ) ( -- sp ) = ' \0 ' ; inword = 1 ; * ( char * ) ( -- sp ) = * ( cmd + i ) ; } i -- ; } if ( inword ) { args [ argc ] = ( char * ) sp ; argc ++ ; } * ( uint8_t * ) ( -- sp ) = 0 ; sp -= 4 ; * ( char * * ) sp = NULL ; for ( i = 0 ; i < argc ; i ++ ) { sp -= 4 ; * ( char * * ) sp = args [ i ] ; } sp -= 4 ; * ( char * * * ) sp = ( char * * ) ( sp + 4 ) ; sp -= 4 ; * ( int * ) sp = argc ; sp -= 4 ; * ( void * * ) sp = NULL ; * ( void * * ) esp = sp ; * eip = ( void ( * ) ( void ) ) ehdr . e_entry ; success = true ; update_open_cnt ( ppath ) ; done : free ( ppath ) ; return success ; }
Loads an ELF executable from FILE_NAME into the current thread.
Loads an ELF executable from FILE_NAME into the current thread .
/* Allocate and activate page directory. */ /* Open executable file. */ /* Read and verify executable header. */ /* Read program headers. */ /* Ignore this segment. */ /* Normal segment.
                     Read initial part from disk and zero the rest. */ /* Entirely zero.
                     Don't read anything from disk. */ /* Set up stack. */ // set up args /* Start address. */ /* We arrive here whether the load is successful or not. */ // file_close (file);