X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fuserprog%2Faddrspace.c;h=65c09e41e8be3f38885b2aeffd6fd93d2c28a094;hb=993c1d9f4452e2edd851f3175dfdf317f18bdb9f;hp=2574c31d7d91737c7f57194ed2571544bd21a039;hpb=fff78daad97b593a531b54103e3fc335bd3239db;p=pintos-anon diff --git a/src/userprog/addrspace.c b/src/userprog/addrspace.c index 2574c31..65c09e4 100644 --- a/src/userprog/addrspace.c +++ b/src/userprog/addrspace.c @@ -1,15 +1,17 @@ -#include "addrspace.h" +#include "userprog/addrspace.h" +#include #include -#include "debug.h" -#include "file.h" -#include "filesys.h" -#include "init.h" -#include "lib.h" -#include "mmu.h" -#include "paging.h" -#include "palloc.h" -#include "thread.h" -#include "tss.h" +#include +#include +#include +#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" /* We load ELF binaries. The following definitions are taken from the ELF specification, [ELF1], more-or-less verbatim. */ @@ -18,7 +20,7 @@ typedef uint32_t Elf32_Word, Elf32_Addr, Elf32_Off; typedef uint16_t Elf32_Half; -/* For use with ELF types in printk(). */ +/* For use with ELF types in printf(). */ #define PE32Wx PRIx32 /* Print Elf32_Word in hexadecimal. */ #define PE32Ax PRIx32 /* Print Elf32_Addr in hexadecimal. */ #define PE32Ox PRIx32 /* Print Elf32_Off in hexadecimal. */ @@ -81,9 +83,9 @@ static bool setup_stack (struct thread *); /* Aborts loading an executable, with an error message. */ #define LOAD_ERROR(MSG) \ do { \ - printk ("addrspace_load: %s: ", filename); \ - printk MSG; \ - printk ("\n"); \ + printf ("addrspace_load: %s: ", filename); \ + printf MSG; \ + printf ("\n"); \ goto done; \ } while (0) @@ -94,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; @@ -106,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")); @@ -133,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) @@ -152,10 +153,10 @@ addrspace_load (struct thread *t, const char *filename, void (**start) (void)) LOAD_ERROR (("unsupported ELF segment type %d\n", phdr.p_type)); break; default: - printk ("unknown ELF segment type %08x\n", phdr.p_type); + 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; } @@ -173,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; @@ -221,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); @@ -230,7 +236,7 @@ load_segment (struct thread *t, struct file *file, modulo PGSIZE. */ if (phdr->p_offset % PGSIZE != phdr->p_vaddr % PGSIZE) { - printk ("%#08"PE32Ox" and %#08"PE32Ax" not congruent modulo %#x\n", + printf ("%#08"PE32Ox" and %#08"PE32Ax" not congruent modulo %#x\n", phdr->p_offset, phdr->p_vaddr, (unsigned) PGSIZE); return false; } @@ -239,7 +245,7 @@ load_segment (struct thread *t, struct file *file, p_filesz. */ if (phdr->p_memsz < phdr->p_filesz) { - printk ("p_memsz (%08"PE32Wx") < p_filesz (%08"PE32Wx")\n", + printf ("p_memsz (%08"PE32Wx") < p_filesz (%08"PE32Wx")\n", phdr->p_memsz, phdr->p_filesz); return false; } @@ -252,7 +258,7 @@ load_segment (struct thread *t, struct file *file, end = pg_round_up ((void *) (phdr->p_vaddr + phdr->p_memsz)); if (start >= PHYS_BASE || end >= PHYS_BASE || end < start) { - printk ("bad virtual region %08lx...%08lx\n", + printf ("bad virtual region %08lx...%08lx\n", (unsigned long) start, (unsigned long) end); return false; } @@ -266,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; @@ -298,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); @@ -306,7 +312,7 @@ setup_stack (struct thread *t) palloc_free (kpage); } else - printk ("failed to allocate process stack\n"); + printf ("failed to allocate process stack\n"); return success; }