X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fuserprog%2Faddrspace.c;h=f535badd1bac08e4fb07fee17ca49e3a05fddd5d;hb=04c55108f55f8a6f4a31a5085151bb729635ff8e;hp=6112484f25162a37cb6c38801297fbd0b9c29644;hpb=f2f8875638593bd5365cfd6a5ba7c9578e52322f;p=pintos-anon diff --git a/src/userprog/addrspace.c b/src/userprog/addrspace.c index 6112484..f535bad 100644 --- a/src/userprog/addrspace.c +++ b/src/userprog/addrspace.c @@ -4,12 +4,12 @@ #include #include #include +#include "userprog/pagedir.h" #include "userprog/tss.h" #include "filesys/file.h" #include "filesys/filesys.h" #include "threads/init.h" #include "threads/mmu.h" -#include "threads/paging.h" #include "threads/palloc.h" #include "threads/thread.h" @@ -96,8 +96,7 @@ bool addrspace_load (struct thread *t, const char *filename, void (**start) (void)) { struct Elf32_Ehdr ehdr; - struct file file; - bool file_open = false; + struct file *file = NULL; off_t file_ofs; bool success = false; int i; @@ -108,12 +107,12 @@ addrspace_load (struct thread *t, const char *filename, void (**start) (void)) LOAD_ERROR (("page directory allocation failed")); /* Open executable file. */ - file_open = filesys_open (filename, &file); - if (!file_open) + file = filesys_open (filename); + if (file == NULL) LOAD_ERROR (("open failed")); /* Read and verify executable header. */ - if (file_read (&file, &ehdr, sizeof ehdr) != sizeof ehdr) + if (file_read (file, &ehdr, sizeof ehdr) != sizeof ehdr) LOAD_ERROR (("error reading executable header")); if (memcmp (ehdr.e_ident, "\177ELF\1\1\1", 7) != 0) LOAD_ERROR (("file is not ELF")); @@ -135,8 +134,8 @@ addrspace_load (struct thread *t, const char *filename, void (**start) (void)) { struct Elf32_Phdr phdr; - file_seek (&file, file_ofs); - if (file_read (&file, &phdr, sizeof phdr) != sizeof phdr) + file_seek (file, file_ofs); + if (file_read (file, &phdr, sizeof phdr) != sizeof phdr) LOAD_ERROR (("error reading program header")); file_ofs += sizeof phdr; switch (phdr.p_type) @@ -157,7 +156,7 @@ addrspace_load (struct thread *t, const char *filename, void (**start) (void)) printf ("unknown ELF segment type %08x\n", phdr.p_type); break; case PT_LOAD: - if (!load_segment (t, &file, &phdr)) + if (!load_segment (t, file, &phdr)) goto done; break; } @@ -175,8 +174,7 @@ addrspace_load (struct thread *t, const char *filename, void (**start) (void)) done: /* We arrive here whether the load is successful or not. We can distinguish based on `success'. */ - if (file_open) - file_close (&file); + file_close (file); if (!success) addrspace_destroy (t); return success; @@ -223,6 +221,12 @@ load_segment (struct thread *t, struct file *file, off_t filesz_left; /* Bytes left of file data (as opposed to zero-initialized bytes). */ + /* Is this a read-only segment? Not currently used, so it's + commented out. You'll want to use it when implementing VM + to decide whether to page the segment from its executable or + from swap. */ + //bool read_only = (phdr->p_flags & PF_W) == 0; + ASSERT (t != NULL); ASSERT (file != NULL); ASSERT (phdr != NULL); @@ -268,7 +272,7 @@ load_segment (struct thread *t, struct file *file, file into the page and zero the rest. */ size_t read_bytes = filesz_left >= PGSIZE ? PGSIZE : filesz_left; size_t zero_bytes = PGSIZE - read_bytes; - uint8_t *kpage = palloc_get (0); + uint8_t *kpage = palloc_get (PAL_USER); if (kpage == NULL) return false; @@ -300,7 +304,7 @@ setup_stack (struct thread *t) uint8_t *kpage; bool success = false; - kpage = palloc_get (PAL_ZERO); + kpage = palloc_get (PAL_USER | PAL_ZERO); if (kpage != NULL) { success = install_page (t, ((uint8_t *) PHYS_BASE) - PGSIZE, kpage);