diff --git a/userprog/populate_stack.c b/userprog/populate_stack.c index 6a7bb2e4897aa6e05b7cd050e2ebff4e41445525..00092b3a5162f8c83bebe564f56887f96f20a299 100644 --- a/userprog/populate_stack.c +++ b/userprog/populate_stack.c @@ -1,6 +1,46 @@ #include "userprog/argument_parsing.h" -void populate_stack(void* esp, int argc, char** argv) { - #warning "Implement me" +void populate_stack(void* stackPointer, int argc, char** argv) { + *stackPointer = PHYS_BASE; + int i = argc; + + // this array holds reference to differences arguments in the stack + uint32_t * arr[argc]; + + while (--i >= 0) + { + *stackPointer = *stackPointer - (strlen(argv[i]) + 1) * sizeof(char); + + arr[i] = (uint32_t *)*stackPointer; + + memcpy(*stackPointer, argv[i], strlen(argv[i]) + 1); + } + + *stackPointer = move_stack_pointer(*stackPointer, -4); //Moves the stack pointer back 4 + + (*(int *)(*stackPointer)) = 0;//sentinel + i = argc; + + while (--i >= 0) + { + *stackPointer = move_stack_pointer(*stackPointer, -4); //32bit Moves the stack pointer back 4 + + (*(uint32_t **)(*stackPointer)) = arr[i]; + } + + *stackPointer = move_stack_pointer(*stackPointer, -4); + + (*(uintptr_t **)(*stackPointer)) = *stackPointer = move_stack_pointer(*stackPointer, 4); //Moves the stack pointer forwards 4 + *stackPointer = move_stack_pointer(*stackPointer, -4); //Moves the stack pointer back 4 + + *(int *)(*stackPointer) = argc; + *stackPointer = move_stack_pointer(*stackPointer, -4); //Moves the stack pointer back 4 + + (*(int *)(*stackPointer)) = 0; } + +int move_stack_pointer(void* stackPointer, int moveValue) { + *stackPointer = *stackPointer + moveValue; + return *stackPointer; +} \ No newline at end of file diff --git a/userprog/process.c b/userprog/process.c index 7aa158189374917306d5021e01bc54caea8b38fe..d44ae7a436d9bd1deea19aadb0146715e243eb0d 100644 --- a/userprog/process.c +++ b/userprog/process.c @@ -19,7 +19,7 @@ #include "threads/vaddr.h" static thread_func start_process NO_RETURN; -static bool load (const char *cmdline, void (**eip) (void), void **esp); +static bool load (const char *cmdline, void (**eip) (void), void **initialStackPointer); /* Starts a new thread running a user program loaded by parsing COMMAND. The new thread may be scheduled (and may even exit) @@ -68,7 +68,7 @@ start_process (void *file_name_) if_.cs = SEL_UCSEG; if_.eflags = FLAG_IF | FLAG_MBS; - success = load (file_name, &if_.eip, &if_.esp); + success = load (file_name, &if_.eip, &if_.initialStackPointer); /* If load failed, quit. */ palloc_free_page (file_name); @@ -79,9 +79,9 @@ start_process (void *file_name_) interrupt, implemented by intr_exit (in threads/intr-stubs.S). Because intr_exit takes all of its arguments on the stack in the form of a `struct intr_frame', - we just point the stack pointer (%esp) to our stack frame + we just point the stack pointer (%initialStackPointer) to our stack frame and jump to it. */ - asm volatile ("movl %0, %%esp; jmp intr_exit" : : "g" (&if_) : "memory"); + asm volatile ("movl %0, %%initialStackPointer; jmp intr_exit" : : "g" (&if_) : "memory"); NOT_REACHED (); } @@ -212,7 +212,7 @@ struct Elf32_Phdr #define PF_W 2 /* Writable. */ #define PF_R 4 /* Readable. */ -static bool setup_stack (void **esp); +static bool setup_stack(void **initialStackPointer, char **argv, int argc) static bool validate_segment (const struct Elf32_Phdr *, struct file *); static bool load_segment (struct file *file, off_t ofs, uint8_t *upage, uint32_t read_bytes, uint32_t zero_bytes, @@ -220,15 +220,15 @@ static bool load_segment (struct file *file, off_t ofs, uint8_t *upage, /* 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. + and its initial stack pointer into *initialStackPointer. Returns true if successful, false otherwise. */ bool -load (const char *file_name, void (**eip) (void), void **esp) +load (const char *file_name, void (**eip) (void), void **initialStackPointer) { struct thread *t = thread_current (); struct Elf32_Ehdr ehdr; - struct file *file = NULL; - off_t file_ofs; + struct file * = NULL; + off_t file_ofs;file bool success = false; int i; @@ -320,7 +320,7 @@ load (const char *file_name, void (**eip) (void), void **esp) } /* Set up stack. */ - if (!setup_stack (esp)) + if (!setup_stack (initialStackPointer)) goto done; /* Start address. */ @@ -445,7 +445,7 @@ load_segment (struct file *file, off_t ofs, uint8_t *upage, /* Create a minimal stack by mapping a zeroed page at the top of user virtual memory. */ static bool -setup_stack (void **esp) +setup_stack (void **initialStackPointer, char **argv, int argc) { uint8_t *kpage; bool success = false; @@ -455,7 +455,7 @@ setup_stack (void **esp) { success = install_page (((uint8_t *) PHYS_BASE) - PGSIZE, kpage, true); if (success) { - *esp = PHYS_BASE - 12; + *initialStackPointer = PHYS_BASE - 12; } else palloc_free_page (kpage); }