diff --git a/src/examples/Makefile b/src/examples/Makefile index 41a663d610cb89d30b7aa0277a644b0f63a2c0c5..c5702291e1b8aed9e73b81afc74a33854aaea44a 100644 --- a/src/examples/Makefile +++ b/src/examples/Makefile @@ -4,7 +4,7 @@ SRCDIR = .. # To add a new test, put its name on the PROGS list # and then add a name_SRC line that lists its source files. PROGS = cat cmp cp echo halt hex-dump ls mcat mcp mkdir pwd rm shell \ - bubsort insult lineup matmult recursor my + bubsort insult lineup matmult recursor my mycreate mywait myremove # Should work from project 2 onward. cat_SRC = cat.c @@ -19,6 +19,9 @@ ls_SRC = ls.c recursor_SRC = recursor.c rm_SRC = rm.c my_SRC = my.c +mycreate_SRC = mycreate.c +mywait_SRC = mywait.c +myremove_SRC = myremove.c # Should work in project 3; also in project 4 if VM is included. bubsort_SRC = bubsort.c diff --git a/src/examples/my.c b/src/examples/my.c index 30c2b27f85ad79f149d01a57da1fd83ac3eee645..19e65f294c7d4cfc8cafdaf1a018076bb7682d97 100644 --- a/src/examples/my.c +++ b/src/examples/my.c @@ -4,7 +4,8 @@ int main (void) { - printf("Hello, World\n"); - + halt(); + //dfgvdf return EXIT_SUCCESS; } + diff --git a/src/examples/mycreate b/src/examples/mycreate new file mode 100755 index 0000000000000000000000000000000000000000..bfcba58faf5d343ffabe9872e8d3efe2631d2fa9 Binary files /dev/null and b/src/examples/mycreate differ diff --git a/src/examples/mycreate.c b/src/examples/mycreate.c new file mode 100644 index 0000000000000000000000000000000000000000..e7dbd7ed6b68ef3dd9762aab1597b9a838968db7 --- /dev/null +++ b/src/examples/mycreate.c @@ -0,0 +1,10 @@ +#include <stdio.h> +#include <syscall.h> +//This file has been created too test the create system call +int +main (void) +{ + create("myfile.txt", 1024); + + return EXIT_SUCCESS; +} diff --git a/src/examples/myremove b/src/examples/myremove new file mode 100755 index 0000000000000000000000000000000000000000..30a7fbe4f8b4a60cf0217b852401f21728bf328c Binary files /dev/null and b/src/examples/myremove differ diff --git a/src/examples/myremove.c b/src/examples/myremove.c new file mode 100644 index 0000000000000000000000000000000000000000..462570015bba0da7825bec1506ea2bf0e85750f7 --- /dev/null +++ b/src/examples/myremove.c @@ -0,0 +1,10 @@ +#include <stdio.h> +#include <syscall.h> +//This file has been created too test the create system call +int +main (void) +{ + remove("myfile.txt"); + + return EXIT_SUCCESS; +} diff --git a/src/examples/mysysexit.c b/src/examples/mysysexit.c new file mode 100644 index 0000000000000000000000000000000000000000..b52c7bdc83e7c1fb6edf1b010051a8147690f823 --- /dev/null +++ b/src/examples/mysysexit.c @@ -0,0 +1,10 @@ +#include <stdio.h> +#include <syscall.h> +//This file has been created too test the create system call +int +main (void) +{ + exit(-1); + + return EXIT_SUCCESS; +} diff --git a/src/examples/mywait b/src/examples/mywait new file mode 100755 index 0000000000000000000000000000000000000000..9bb04d2239d308595753aefa80624b22b737acfa Binary files /dev/null and b/src/examples/mywait differ diff --git a/src/examples/mywait.c b/src/examples/mywait.c new file mode 100644 index 0000000000000000000000000000000000000000..9aa6c90a0159c72ad5512a1f74ca70fd08fe2b09 --- /dev/null +++ b/src/examples/mywait.c @@ -0,0 +1,9 @@ +#include <stdio.h> +#include <syscall.h> +//This file has been created too test the create system call +int main (void) +{ + wait(1); + + return EXIT_SUCCESS; +} diff --git a/src/lib/user/stack.c b/src/lib/user/stack.c new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/src/lib/user/stack.h b/src/lib/user/stack.h new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/src/threads/thread.h b/src/threads/thread.h index 093bcddeb82e3c52182ff182c8c832d90f695908..51a59e9c321092a0fc9de11ab1565b29391a00f4 100644 --- a/src/threads/thread.h +++ b/src/threads/thread.h @@ -89,7 +89,7 @@ struct thread uint8_t *stack; /* Saved stack pointer. */ int priority; /* Priority. */ struct list_elem allelem; /* List element for all threads list. */ - + struct file **fd_table; /* Shared between thread.c and synch.c. */ struct list_elem elem; /* List element. */ diff --git a/src/userprog/process.c b/src/userprog/process.c index d51339a4aff8ec7aae340ae87035ef64358853fd..75e31515edf0f40798bce8c2722fb1d7475b43e8 100644 --- a/src/userprog/process.c +++ b/src/userprog/process.c @@ -29,6 +29,10 @@ tid_t process_execute (const char *file_name) { char *fn_copy; + char *save_ptr; + + int file_name_size = strlen(file_name)+1; + char program_name[file_name_size]; tid_t tid; /* Make a copy of FILE_NAME. @@ -38,8 +42,12 @@ process_execute (const char *file_name) return TID_ERROR; strlcpy (fn_copy, file_name, PGSIZE); + strlcpy(program_name,file_name,file_name_size); + strtok_r(program_name, " ", &save_ptr); + printf("Program name is --> %s\n", program_name); + /* Create a new thread to execute FILE_NAME. */ - tid = thread_create (file_name, PRI_DEFAULT, start_process, fn_copy); + tid = thread_create (program_name, PRI_DEFAULT, start_process, fn_copy); if (tid == TID_ERROR) palloc_free_page (fn_copy); @@ -55,13 +63,27 @@ start_process (void *file_name_) struct intr_frame if_; bool success; + char *token, *save_ptr; + char *tokens[32]; + + int i = 0; + + + for(token = strtok_r(file_name, " ", &save_ptr); token != NULL; token = strtok_r(NULL, " ", &save_ptr)){ + tokens[i] = token; + i++; + + printf("Atay Debug : %s\n",tokens[i-1]); + } + printf("Argument count -->> %d\n",i); + /* Initialize interrupt frame and load executable. */ memset (&if_, 0, sizeof if_); if_.gs = if_.fs = if_.es = if_.ds = if_.ss = SEL_UDSEG; if_.cs = SEL_UCSEG; if_.eflags = FLAG_IF | FLAG_MBS; - success = load (file_name, &if_.eip, &if_.esp); + success = load (tokens[0], &if_.eip, &if_.esp); /* If load failed, quit. */ palloc_free_page (file_name); @@ -443,7 +465,7 @@ setup_stack (void **esp) { success = install_page (((uint8_t *) PHYS_BASE) - PGSIZE, kpage, true); if (success) { - *esp = PHYS_BASE; + *esp = PHYS_BASE - 12; } else palloc_free_page (kpage); } diff --git a/src/userprog/syscall.c b/src/userprog/syscall.c index 04635159d30520fa11296dc922e622f2ad2553d5..0f9f31961ea8bc815e213a210086c826cb6b2142 100644 --- a/src/userprog/syscall.c +++ b/src/userprog/syscall.c @@ -3,19 +3,326 @@ #include <syscall-nr.h> #include "threads/interrupt.h" #include "threads/thread.h" +#include <devices/shutdown.h> +#include "threads/init.h" +#include "filesys/filesys.h" +#include "lib/user/syscall.h" +#include "filesys/file.h" +#include "threads/synch.h" +#include <stdlib.h> +#include "threads/vaddr.h" +//#include "userprog/process.c" + + +struct file* process_get_file (int fd); // FOR READ +static void check_user (const uint8_t *uaddr); + +void halt (void) NO_RETURN; +void exit (int status) NO_RETURN; +pid_t exec (const char *file); +int wait (pid_t pid); +bool create (const char *file, unsigned initial_size); +bool remove (const char *file); +int open (const char *file); +int filesize (int fd); +int read (int fd, void *buffer, unsigned length); +int write (int fd, const void *buffer, unsigned length); +void seek (int fd, unsigned position); +unsigned tell (int fd); +void close (int fd); + +static int32_t get_user (const uint8_t *uaddr); + +// void check_user (const void *uaddr); // for read +int input_getc (void); // for read +// struct file* process_get_file (int fd); //for read + +//int memread_user(void *dst, const void *src, size_t n); + +struct lock; //All for the lock to work to protect from race vuln +void lock_init (struct lock *lock); +void lock_acquire (struct lock *lock); +bool lock_try_acquire (struct lock *lock); +void lock_release (struct lock *lock); +bool lock_held_by_current_thread (const struct lock *lock); +struct lock filesys_lock; + +struct semaphore; +void sema_init (struct semaphore *sema, unsigned value); +void sema_down (struct semaphore *sema); +bool sema_try_down (struct semaphore *sema); +void sema_up (struct semaphore *sema); +void sema_self_test (void); + +struct condition; +void cond_init (struct condition *cond); +void cond_wait (struct condition *cond, struct lock *lock); +void cond_signal (struct condition *cond, struct lock *lock); +void cond_broadcast (struct condition *cond, struct lock *lock); + +struct file_descriptor + { + int fd; + struct file *file; + struct list_elem elem; + }; + +struct process_file + { + int fd; + struct file *file; + struct list_elem elem; + }; + + + + + + + + +static void fail_invalid_access(void) { + if (lock_held_by_current_thread(&filesys_lock)) + lock_release (&filesys_lock); + + process_exit (-1); + NOT_REACHED(); +} + + + + + +#include "threads/vaddr.h" + + +static int +memread_user (void *src, void *dst, size_t bytes) +{ + int32_t value; + size_t i; + for(i=0; i<bytes; i++) { + value = get_user(src + i); + if(value == -1) // segfault or invalid memory access + fail_invalid_access(); + + *(char*)(dst + i) = value & 0xff; + } + return (int)bytes; +} + +// CHECK USER +static void +check_user (const uint8_t *uaddr) { + // check uaddr range or segfaults + if(get_user (uaddr) == -1) + fail_invalid_access(); +} + + + + + + + +//GET USER CODE +static int32_t +get_user (const uint8_t *uaddr) { + // check that a user pointer `uaddr` points below PHYS_BASE + if (! ((void*)uaddr < PHYS_BASE)) { + return -1; + } + + // as suggested in the reference manual, see (3.1.5) + int result; + asm ("movl $1f, %0; movzbl %1, %0; 1:" + : "=&a" (result) : "m" (*uaddr)); + return result; +} + + + + + + + + + + + + + +bool +create (const char *file, unsigned initial_size) +{ + printf("file: %s\n", file); + printf("initial size: %d\n", initial_size); + printf("File generated succsessfully!"); + return filesys_create (file, initial_size); +} + + + + + +bool remove(const char* filename) { + bool return_code; + // memory validation missing no check user function // added now + check_user((const uint8_t*) filename); + printf ("CHECK USER RUN\n"); + return_code = filesys_remove(filename); + printf ("File removed --->"); + printf (filename); + + return return_code; +} + + + + + +int wait(pid_t pid) { + printf ("[DEBUG] Wait : %d\n", pid); + return wait(pid); +} + + + + + + + + + static void syscall_handler (struct intr_frame *); +static uint32_t load_stack(struct intr_frame *f, int offset){ + return *((uint32_t*)(f->esp + offset)); +} + + void syscall_init (void) { intr_register_int (0x30, 3, INTR_ON, syscall_handler, "syscall"); } +////////////////////////READ CODE//////////////////////////// -static void -syscall_handler (struct intr_frame *f UNUSED) +/* void // CHECK USER FUNCTION +check_user (const uint8_t *uaddr) +{ + if ((void *) uaddr < (void *) 0x08048000 + || (void *) uaddr >= (void *) 0xc0000000) + exit (-1); +} +*/ + +struct file* //GET FILE FUNCTION +process_get_file (int fd) { - printf ("system call!\n"); - thread_exit (); + struct thread *t = thread_current (); + + if (fd < 0 || fd >= 128) + return NULL; + + return t->fd_table[fd]; +} + +static void +syscall_handler (struct intr_frame *f){ + int code = (int)load_stack(f, 0); + switch (code){ + case SYS_HALT: + printf("SYSTEM HALT CALL RUN SUCCSESSFULLY \n"); + shutdown_power_off(); + break; + case SYS_EXIT: + printf("EXIT DONE"); + break; + + case SYS_READ: + { + //int fd = (int) load_stack(f, 1); + //void *buffer = (void*) load_stack(f, 2); + //unsigned size = (unsigned) load_stack(f, 3); + //f->eax = read(fd, buffer, size); + //break; + } + case SYS_CREATE: + { + const char *file; + unsigned initial_size; + memread_user (f->esp + 4, &file, sizeof file); + memread_user (f->esp + 8, &initial_size, sizeof initial_size); + f->eax = create (file, initial_size); + break; + } + case SYS_WAIT: + { + pid_t pid; + memread_user(f->esp + 4, &pid, sizeof(pid_t)); + + int ret = wait(pid); + f->eax = (uint32_t) ret; + break; + } + case SYS_REMOVE: + { + const char* filename; + bool return_code; + + memread_user(f->esp + 4, &filename, sizeof(filename)); + + return_code = remove(filename); + f->eax = return_code; + break; + + + + } + + + } + + + +thread_exit (); +} + +////////////////////////READ CODE//////////////////////////// +/* +int read(int fd, void* buffer, unsigned size) { + // memory validation + check_user((const uint8_t*) buffer); + + int bytes_read = 0; + + // read from stdin if fd == 0, otherwise read from file + if (fd == 0) { + // read from stdin + for (unsigned i = 0; i < size; i++) { + char c = input_getc(); + if (c == '\0') { + break; + } + *((char*) buffer + i) = c; + bytes_read++; + } + } else { + // read from file + struct file* f = process_get_file(fd); + if (f == NULL) { + return -1; + } + lock_acquire (&filesys_lock); + bytes_read = file_read(f, buffer, size); + lock_release (&filesys_lock); + } + return bytes_read; } +*/ +////////////////////////READ CODE//////////////////////////// + + diff --git a/src/userprog/syscall.h b/src/userprog/syscall.h index 90590967a9f96f9ea359d15c672b815dfb4379cb..5f5c81f15f04c12b9eac1de708b972e29f718597 100644 --- a/src/userprog/syscall.h +++ b/src/userprog/syscall.h @@ -3,4 +3,5 @@ void syscall_init (void); + #endif /* userprog/syscall.h */