X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fuserprog%2Faddrspace.c;h=1170f16ab92a7f61f1a93ad381ea49ff38208e63;hb=a051c001c942a1f9cce57b1beec79794f9c7089f;hp=eb0de496851a5a340270e8d1cdd38074d677d88e;hpb=b9d1a06a2bcc6de5251e12be91ad687d3b291244;p=pintos-anon diff --git a/src/userprog/addrspace.c b/src/userprog/addrspace.c index eb0de49..1170f16 100644 --- a/src/userprog/addrspace.c +++ b/src/userprog/addrspace.c @@ -3,11 +3,13 @@ #include "debug.h" #include "file.h" #include "filesys.h" +#include "init.h" #include "lib.h" #include "mmu.h" -#include "malloc.h" #include "paging.h" #include "palloc.h" +#include "thread.h" +#include "tss.h" /* We load ELF binaries. The following definitions are taken from the ELF specification more-or-less verbatim. */ @@ -79,12 +81,12 @@ struct Elf32_Phdr } while (0) static bool -install_page (struct addrspace *as, void *upage, void *kpage) +install_page (struct thread *t, void *upage, void *kpage) { /* Verify that there's not already a page at that virtual address, then map our page there. */ - if (pagedir_get_page (as->pagedir, upage) == NULL - && pagedir_set_page (as->pagedir, upage, kpage, true)) + if (pagedir_get_page (t->pagedir, upage) == NULL + && pagedir_set_page (t->pagedir, upage, kpage, true)) return true; else { @@ -94,14 +96,14 @@ install_page (struct addrspace *as, void *upage, void *kpage) } static bool -load_segment (struct addrspace *as, struct file *file, +load_segment (struct thread *t, struct file *file, const struct Elf32_Phdr *phdr) { void *start, *end; uint8_t *upage; off_t filesz_left; - ASSERT (as != NULL); + ASSERT (t != NULL); ASSERT (file != NULL); ASSERT (phdr != NULL); ASSERT (phdr->p_type == PT_LOAD); @@ -147,7 +149,7 @@ load_segment (struct addrspace *as, struct file *file, memset (kpage + read_bytes, 0, zero_bytes); filesz_left -= read_bytes; - if (!install_page (as, upage, kpage)) + if (!install_page (t, upage, kpage)) return false; } @@ -155,7 +157,7 @@ load_segment (struct addrspace *as, struct file *file, } static bool -setup_stack (struct addrspace *as) +setup_stack (struct thread *t) { uint8_t *kpage = palloc_get (PAL_ZERO); if (kpage == NULL) @@ -164,27 +166,32 @@ setup_stack (struct addrspace *as) return false; } - return install_page (as, ((uint8_t *) PHYS_BASE) - PGSIZE, kpage); + return install_page (t, ((uint8_t *) PHYS_BASE) - PGSIZE, kpage); } bool -addrspace_load (struct addrspace *as, const char *filename, +addrspace_load (struct thread *t, const char *filename, void (**start) (void)) { struct Elf32_Ehdr ehdr; - struct file *file = NULL; + struct file file; + bool file_open = false; off_t file_ofs; bool success = false; int i; - as->pagedir = pagedir_create (); + /* Allocate page directory. */ + t->pagedir = pagedir_create (); + if (t->pagedir == NULL) + LOAD_ERROR (("page directory allocation failed")); - file = filesys_open (filename); - if (file == NULL) + /* Open executable file. */ + file_open = filesys_open (filename, &file); + if (!file_open) 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")); @@ -206,14 +213,9 @@ addrspace_load (struct addrspace *as, const char *filename, { 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")); - printk ("%x: %08x, %08x %08x %08x %05x %05x\n", - file_tell (file), - phdr.p_type, - phdr.p_offset, phdr.p_vaddr, phdr.p_paddr, - phdr.p_filesz, phdr.p_memsz); file_ofs += sizeof phdr; switch (phdr.p_type) { @@ -233,14 +235,14 @@ addrspace_load (struct addrspace *as, const char *filename, printk ("unknown ELF segment type %08x\n", phdr.p_type); break; case PT_LOAD: - if (!load_segment (as, file, &phdr)) + if (!load_segment (t, &file, &phdr)) goto error; break; } } /* Set up stack. */ - if (!setup_stack (as)) + if (!setup_stack (t)) goto error; /* Start address. */ @@ -249,25 +251,29 @@ addrspace_load (struct addrspace *as, const char *filename, success = true; error: - if (file != NULL) - file_close (file); + if (file_open) + file_close (&file); if (!success) - addrspace_destroy (as); + addrspace_destroy (t); return success; } void -addrspace_destroy (struct addrspace *as) +addrspace_destroy (struct thread *t) { - if (as != NULL && as->pagedir != NULL) - pagedir_destroy (as->pagedir); + if (t->pagedir != NULL) + { + pagedir_destroy (t->pagedir); + t->pagedir = NULL; + } } void -addrspace_activate (struct addrspace *as) +addrspace_activate (struct thread *t) { - ASSERT (as != NULL); + ASSERT (t != NULL); - if (as->pagedir != NULL) - pagedir_activate (as->pagedir); + if (t->pagedir != NULL) + pagedir_activate (t->pagedir); + tss_set_esp0 ((uint8_t *) t + PGSIZE); }