X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fuserprog%2Faddrspace.c;h=c136ae55d0bef505985e312e6a82b07d8ed0b9f7;hb=44d0fa6a2b24a84e5eb0d54959ed91c1d4f15343;hp=28e89f7884ec2d5245ded6c056bddfe3b9fa885d;hpb=76a72158378a6447bb3dbce5bae41db48da0d64f;p=pintos-anon diff --git a/src/userprog/addrspace.c b/src/userprog/addrspace.c index 28e89f7..c136ae5 100644 --- a/src/userprog/addrspace.c +++ b/src/userprog/addrspace.c @@ -3,6 +3,7 @@ #include "debug.h" #include "file.h" #include "filesys.h" +#include "init.h" #include "lib.h" #include "mmu.h" #include "malloc.h" @@ -78,6 +79,21 @@ struct Elf32_Phdr goto error; \ } while (0) +static bool +install_page (struct addrspace *as, 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)) + return true; + else + { + palloc_free (kpage); + return false; + } +} + static bool load_segment (struct addrspace *as, struct file *file, const struct Elf32_Phdr *phdr) @@ -132,19 +148,29 @@ load_segment (struct addrspace *as, struct file *file, memset (kpage + read_bytes, 0, zero_bytes); filesz_left -= read_bytes; - if (pagedir_get_page (as->pagedir, upage)) - { - palloc_free (kpage); - return false; - } - pagedir_set_page (as->pagedir, upage, kpage, true); + if (!install_page (as, upage, kpage)) + return false; } return true; } +static bool +setup_stack (struct addrspace *as) +{ + uint8_t *kpage = palloc_get (PAL_ZERO); + if (kpage == NULL) + { + printk ("failed to allocate process stack\n"); + return false; + } + + return install_page (as, ((uint8_t *) PHYS_BASE) - PGSIZE, kpage); +} + bool -addrspace_load (struct addrspace *as, const char *filename) +addrspace_load (struct addrspace *as, const char *filename, + void (**start) (void)) { struct Elf32_Ehdr ehdr; struct file *file = NULL; @@ -177,7 +203,6 @@ addrspace_load (struct addrspace *as, const char *filename) /* Read program headers. */ file_ofs = ehdr.e_phoff; - printk ("e_phnum=%d\n", ehdr.e_phnum); for (i = 0; i < ehdr.e_phnum; i++) { struct Elf32_Phdr phdr; @@ -185,18 +210,13 @@ addrspace_load (struct addrspace *as, const char *filename) 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) { case PT_NULL: case PT_NOTE: case PT_PHDR: - case PT_STACK: /* Stack segment. */ + case PT_STACK: /* Ignore this segment. */ break; case PT_DYNAMIC: @@ -214,6 +234,14 @@ addrspace_load (struct addrspace *as, const char *filename) break; } } + + /* Set up stack. */ + if (!setup_stack (as)) + goto error; + + /* Start address. */ + *start = (void (*) (void)) ehdr.e_entry; + success = true; error: @@ -238,4 +266,5 @@ addrspace_activate (struct addrspace *as) if (as->pagedir != NULL) pagedir_activate (as->pagedir); + tss->esp0 = (uint32_t) pg_round_down (as) + PGSIZE; }