/* * get system call */ static void syscall_handler (struct intr_frame *f) { int *esp = (int *)syscall_user_to_kernel_vaddr(f->esp); switch(*esp) { case SYS_WRITE: syscall_write(f); break; case SYS_EXIT: syscall_exit(f); break; case SYS_HALT: syscall_halt(f); break; case SYS_EXEC: syscall_exec(f); break; case SYS_CREATE: syscall_create(f); break; case SYS_REMOVE: syscall_remove(f); break; case SYS_OPEN: syscall_open(f); break; case SYS_FILESIZE: syscall_filesize(f); break; case SYS_READ: syscall_read(f); break; case SYS_SEEK: syscall_seek(f); break; case SYS_TELL: syscall_tell(f); break; case SYS_CLOSE: syscall_close(f); break; case SYS_WAIT: syscall_wait(f); break; } }
static void syscall_handler (struct intr_frame *f) { int syscall_num; VALIDATE_AND_GET_ARG (f->esp, syscall_num, f); void *cur_sp = f->esp + sizeof (void *); /* store user program stack pointer to the thread's user_esp before changing to kernel mode */ struct thread *t = thread_current (); t->user_esp = f->esp; switch (syscall_num) { case SYS_HALT: syscall_halt (f, cur_sp); break; case SYS_EXIT: syscall_exit (f, cur_sp); break; case SYS_EXEC: syscall_exec (f, cur_sp); break; case SYS_WAIT: syscall_wait (f, cur_sp); break; case SYS_CREATE: syscall_create (f, cur_sp); break; case SYS_REMOVE: syscall_remove (f, cur_sp); break; case SYS_OPEN: syscall_open (f, cur_sp); break; case SYS_FILESIZE: syscall_filesize (f, cur_sp); break; case SYS_READ: syscall_read (f, cur_sp); break; case SYS_WRITE: syscall_write (f, cur_sp); break; case SYS_SEEK: syscall_seek (f, cur_sp); break; case SYS_TELL: syscall_tell (f, cur_sp); break; case SYS_CLOSE: syscall_close (f, cur_sp); break; case SYS_MMAP: syscall_mmap (f, cur_sp); break; case SYS_MUNMAP: syscall_unmmap (f, cur_sp); break; default : printf ("Invalid system call! #%d\n", syscall_num); syscall_thread_exit (f, -1); break; } }
static void syscall_handler (struct intr_frame *f) { /* Validate the first addr of the stack frame */ void *esp = utok_addr (f->esp, NULL); if (esp == NULL) { syscall_exit (-1); return; } enum SYSCALL_NUMBER call_number = *(enum SYSCALL_NUMBER *) esp; if (call_number < syscall_first_call || call_number > syscall_last_call) { syscall_exit (-1); return; } /* Buffer the arguments for validation */ int argc = syscall_argc[call_number]; uint32_t argbuf[3]; int i = 0; for (; i < argc; i++) { /* Validate each argument */ void *vaddr = uptr_valid((uint32_t *) f->esp + 1 + i, f->esp); if (vaddr == NULL) { syscall_exit (-1); return; } /* Translate the argument to kernel virtual (== physical) memory */ argbuf[i] = *(uint32_t *) vaddr; } int retval = 0; /* Switch based on call_number to delegate to corresponding syscall. Have not implemented several syscalls as of this project. Use validation methods to check user-provided arguments. */ switch (call_number) { case SYS_HALT: syscall_halt (); break; case SYS_EXIT: syscall_exit ((int) argbuf[0]); break; case SYS_EXEC: if (str_valid ((void *) argbuf[0], f->esp) == NULL) { syscall_exit (-1); return; } retval = syscall_exec ((char *) argbuf[0]); break; case SYS_WAIT: retval = syscall_wait ((int) argbuf[0]); break; case SYS_CREATE: if (str_valid ((char *) argbuf[0], f->esp) == NULL) { syscall_exit (-1); return; } retval = (int) syscall_create ((char *) argbuf[0], (unsigned) argbuf[1]); break; case SYS_REMOVE: if (!uptr_valid ((char *) argbuf[0], f->esp)) { syscall_exit (-1); return; } retval = (int) syscall_remove ((char *) argbuf[0]); break; case SYS_OPEN: if (str_valid ((char *) argbuf[0], f->esp) == NULL) { syscall_exit (-1); return; } retval = (int) syscall_open ((char *) argbuf[0]); break; case SYS_FILESIZE: retval = syscall_filesize ((int) argbuf[0]); break; case SYS_READ: if (buffer_valid ((void *) argbuf[1], f->esp, (unsigned) argbuf[2]) == NULL) { syscall_exit (-1); return; } retval = syscall_read ((int) argbuf[0], (void *) argbuf[1], (unsigned) argbuf[2]); break; case SYS_WRITE: if (buffer_valid ((void *) argbuf[1], f->esp, (unsigned) argbuf[2]) == NULL) { syscall_exit (-1); return; } retval = syscall_write ((int) argbuf[0], (void *) argbuf[1], (unsigned) argbuf[2]); break; case SYS_SEEK: syscall_seek ((int) argbuf[0], (unsigned) argbuf[1]); break; case SYS_TELL: retval = (int) syscall_tell ((int) argbuf[0]); break; case SYS_CLOSE: syscall_close ((int) argbuf[0]); break; #ifdef VM case SYS_MMAP: // addr will be checked internally inside mmap retval = (int) syscall_mmap ((int) argbuf[0], (void *) argbuf[1]); break; case SYS_MUNMAP: syscall_munmap ((int) argbuf[0]); break; #endif default: printf("unhandled system call!\n"); thread_exit(); } f->eax = retval; }
static void syscall_handler (struct intr_frame *f) { int nsyscall, i; int *esp = (int *)f -> esp; if(!is_valid(esp)) thread_exit(); int *arg_int[3]; void **arg_ptr[3]; // Get system call number. nsyscall = *(esp++); /* argc number 0: SYS_HALT 1: SYS_EXIT, SYS_EXEC, SYS_WAIT, SYS_TELL, SYS_REMOVE, SYS_OPEN, SYS_CLOSE, SYS_FILESIZE 2: SYS_CREATE, SYS_SEEK 3: SYS_READ, SYS_WRITE */ if(nsyscall == SYS_HALT) { shutdown_power_off(); } else if(nsyscall == SYS_EXIT) { for(i = 0; i < 1; i++) { if(is_valid((esp+i))) { arg_int[i] = esp + i; } else thread_exit(); } syscall_exit(*arg_int[0]); } else if(nsyscall == SYS_EXEC) { for(i = 0; i < 1; i++) { if(is_valid((esp+i))) { arg_ptr[i] = (void **)(esp + i); } else thread_exit(); } if(!is_valid(*arg_ptr[0])) thread_exit(); lock_acquire(&lock_sys); f->eax = process_execute(*arg_ptr[0]); lock_release(&lock_sys); } else if(nsyscall == SYS_WAIT) { for(i = 0; i < 1; i++) { if(is_valid((esp+i))) { arg_int[i] = esp + i; } else thread_exit(); } f->eax = process_wait(*arg_int[0]); } else if(nsyscall == SYS_TELL) { for(i = 0; i < 1; i++) { if(is_valid((esp+i))) { arg_int[i] = esp + i; } else thread_exit(); } lock_acquire(&lock_sys); f->eax = syscall_tell(*arg_int[0]); lock_release(&lock_sys); } else if(nsyscall == SYS_REMOVE) { for(i = 0; i < 1; i++) { if(is_valid((esp+i))) { arg_ptr[i] = (void **)(esp + i); } else thread_exit(); } if(!is_valid(*arg_ptr[0])) thread_exit(); lock_acquire(&lock_sys); f->eax = filesys_remove(*arg_ptr[0]); lock_release(&lock_sys); } else if(nsyscall == SYS_OPEN) { for(i = 0; i < 1; i++) { if(is_valid((esp+i))) { arg_ptr[i] = (void **)(esp + i); } else thread_exit(); } if(!is_valid(*arg_ptr[0])) thread_exit(); lock_acquire(&lock_sys); f->eax = syscall_open(*arg_ptr[0]); lock_release(&lock_sys); } else if(nsyscall == SYS_CLOSE) { for(i = 0; i < 1; i++) { if(is_valid((esp+i))) { arg_int[i] = esp + i; } else thread_exit(); } lock_acquire(&lock_sys); syscall_close(*arg_int[0]); lock_release(&lock_sys); } else if(nsyscall == SYS_FILESIZE) { for(i = 0; i < 1; i++) { if(is_valid((esp+i))) { arg_int[i] = esp + i; } else thread_exit(); } lock_acquire(&lock_sys); f->eax = syscall_filesize(*arg_int[0]); lock_release(&lock_sys); } else if(nsyscall == SYS_CREATE) { for(i = 0; i < 2; i++) { if(is_valid((esp+i))) { arg_int[i] = esp + i; arg_ptr[i] = (void **)(esp + i); } else thread_exit(); } if(!is_valid(*arg_ptr[0])) thread_exit(); lock_acquire(&lock_sys); f->eax = filesys_create(*arg_ptr[0], *arg_int[1]); lock_release(&lock_sys); } else if(nsyscall == SYS_SEEK) { for(i = 0; i < 2; i++) { if(is_valid((esp+i))) { arg_int[i] = esp + i; } else thread_exit(); } lock_acquire(&lock_sys); syscall_seek(*arg_int[0], *arg_int[1]); lock_release(&lock_sys); } else if(nsyscall == SYS_READ) { for(i = 0; i < 3; i++) { if(is_valid((esp+i))) { arg_int[i] = esp + i; arg_ptr[i] = (void **)(esp + i); } else thread_exit(); } if(!is_valid(*arg_ptr[1])) thread_exit(); lock_acquire(&lock_sys); f->eax = syscall_read(*arg_int[0], *arg_ptr[1], *arg_int[2]); lock_release(&lock_sys); } else if(nsyscall == SYS_WRITE) { for(i = 0; i < 3; i++) { if(is_valid((esp+i))) { arg_int[i] = esp + i; arg_ptr[i] = (void **)(esp + i); } else thread_exit(); } if(!is_valid(*arg_ptr[1])) thread_exit(); lock_acquire(&lock_sys); f->eax = syscall_write(*arg_int[0], *arg_ptr[1], *arg_int[2]); lock_release(&lock_sys); } else if(nsyscall == SYS_CHDIR) { for(i = 0; i < 1; i++) { if(is_valid((esp+i))) { arg_ptr[i] = (void **)(esp + i); } else thread_exit(); } if(!is_valid(*arg_ptr[0])) thread_exit(); lock_acquire(&lock_sys); f->eax = syscall_chdir(*arg_ptr[0]); lock_release(&lock_sys); } else if(nsyscall == SYS_MKDIR) { for(i = 0; i < 1; i++) { if(is_valid((esp+i))) { arg_ptr[i] = (void **)(esp + i); } else thread_exit(); } if(!is_valid(*arg_ptr[0])) thread_exit(); lock_acquire(&lock_sys); f->eax = syscall_mkdir(*arg_ptr[0]); lock_release(&lock_sys); } else if(nsyscall == SYS_READDIR) { for(i = 0; i < 2; i++) { if(is_valid((esp+i))) { arg_int[i] = esp + i; arg_ptr[i] = (void **)(esp + i); } else thread_exit(); } if(!is_valid(*arg_ptr[1])) thread_exit(); lock_acquire(&lock_sys); f->eax = syscall_readdir(*arg_int[0], *arg_ptr[1]); lock_release(&lock_sys); } else if(nsyscall == SYS_ISDIR) { for(i = 0; i < 1; i++) { if(is_valid((esp+i))) { arg_int[i] = esp + i; } else thread_exit(); } lock_acquire(&lock_sys); f->eax = syscall_isdir(*arg_int[0]); lock_release(&lock_sys); } else if(nsyscall == SYS_INUMBER) { for(i = 0; i < 1; i++) { if(is_valid((esp+i))) { arg_int[i] = esp + i; } else thread_exit(); } lock_acquire(&lock_sys); f->eax = syscall_inumber(*arg_int[0]); lock_release(&lock_sys); } else thread_exit(); }
static void syscall_handler (struct intr_frame *f) { int nsyscall, argc, i; int *esp = (int *)f->esp; /* get argument pointer */ int *arg_int[3]; void **arg_ptr[3]; /* verify the argument pointer */ if (!IS_VALID(esp)) goto error_end; /* system call number */ nsyscall = *(esp++); /* number of arguments */ switch (nsyscall) { case SYS_HALT: argc = 0; break; case SYS_EXIT: case SYS_EXEC: case SYS_WAIT: case SYS_TELL: case SYS_CLOSE: case SYS_REMOVE: case SYS_OPEN: case SYS_FILESIZE: argc = 1; break; case SYS_CREATE: case SYS_SEEK: argc = 2; break; case SYS_READ: case SYS_WRITE: argc = 3; break; default: goto error_end; } /* verify the argument pointer */ for (i = 0; i < argc; i++) if (IS_VALID(esp + i)) { arg_int[i] = esp + i; arg_ptr[i] = (void**)(esp + i); } else { break; } if (i < argc) goto error_end; /* system call */ switch (nsyscall) { case SYS_HALT: shutdown_power_off(); break; case SYS_EXIT: syscall_exit(*arg_int[0]); break; case SYS_EXEC: if (!IS_VALID(*arg_ptr[0])) goto error_end; lock_acquire (&lock_filesys); f->eax = process_execute(*arg_ptr[0]); lock_release (&lock_filesys); break; case SYS_WAIT: f->eax = process_wait(*arg_int[0]); break; case SYS_TELL: lock_acquire (&lock_filesys); f->eax = syscall_tell(*arg_int[0]); lock_release (&lock_filesys); break; case SYS_CLOSE: lock_acquire (&lock_filesys); process_file_close(*arg_int[0]); lock_release (&lock_filesys); break; case SYS_REMOVE: if (!IS_VALID(*arg_ptr[0])) goto error_end; lock_acquire (&lock_filesys); f->eax = syscall_remove(*arg_ptr[0]); lock_release (&lock_filesys); break; case SYS_OPEN: if (!IS_VALID(*arg_ptr[0])) goto error_end; lock_acquire (&lock_filesys); f->eax = process_file_open(*arg_ptr[0]); lock_release (&lock_filesys); break; case SYS_FILESIZE: lock_acquire (&lock_filesys); f->eax = syscall_filesize(*arg_int[0]); lock_release (&lock_filesys); break; case SYS_CREATE: if (!IS_VALID(*arg_ptr[0])) goto error_end; lock_acquire (&lock_filesys); f->eax = syscall_create(*arg_ptr[0], *arg_int[1]); lock_release (&lock_filesys); break; case SYS_SEEK: lock_acquire (&lock_filesys); syscall_seek(*arg_int[0], *arg_int[1]); lock_release (&lock_filesys); break; case SYS_READ: if (!IS_VALID(*arg_ptr[1])) goto error_end; lock_acquire (&lock_filesys); f->eax = syscall_read(*arg_int[0], *arg_ptr[1], *arg_int[2]); lock_release (&lock_filesys); break; case SYS_WRITE: if (!IS_VALID(*arg_ptr[1])) goto error_end; lock_acquire (&lock_filesys); f->eax = syscall_write(*arg_int[0], *arg_ptr[1], *arg_int[2]); lock_release (&lock_filesys); break; default: printf ("Unknown syscall : %d\n", nsyscall); goto error_end; } return; error_end: thread_exit (); }
static void syscall_handler (struct intr_frame *f) { // XXX : EDIT WITH 'syscall.h' 'lib/user/syscall.c' 'lib/syscall-nr.h //printf ("system call!\n"); void *now = f->esp; // XXX : Check PTR Range, and bash to syscall_exit(-1); if(!is_valid_ptr(now)) syscall_exit(-1); int syscall_number = *(int *)(f->esp); int argc_size_table[22] = { // CHECK syscall-nr.h 0, // SYS_HALT (*) :0 1, // SYS_EXIT (*) :1 1, // SYS_EXEC (*) :2 1, // SYS_WAIT (*) :3 2, // SYS_CREATE :4 1, // SYS_REMOVE :5 1, // SYS_OPEN :6 1, // SYS_FILESIZE :7 3, // SYS_READ (*) :8 3, // SYS_WRITE (*):9 2, // SYS_SEEK :10 1, // SYS_TELL :11 1, // SYS_CLOSE :12 (proj 2-2) 2, // SYS_MMAP 1, // SYS_MUNMAP 1, // SYS_CHDIR 1, // SYS_MKDIR 2, // SYS_READDIR 1, // SYS_ISDIR 1, // SYS_INUMBER 1, // SYS_PIBONACCI 4 // SYS_SUM_OF_FOUR_INTEGERS }; int argc_size = argc_size_table[syscall_number]; //printf("SYSCALL %d SIZE %d\n", syscall_number, argc_size); void *argc[4] = {NULL,}; { int i; for(i = 0; i < argc_size; i++){ now += 4; // sizeof(void *); // IT WILL USE 4 Bytes. (ref:man38). argc[i] = now; // XXX : Check argument's ptr; if(!is_valid_ptr(argc[i])) syscall_exit(-1); // printf("%x\n", now); } } switch(syscall_number){ default: case -1: break; case 0: // SYS_HALT syscall_halt(); break; case 1: // SYS_EXIT syscall_exit(*(int *)argc[0]); break; case 2: // SYS_EXEC f->eax = syscall_exec(*(const char **)argc[0]); break; case 3: // SYS_WAIT //printf("CALLED SYS_WAIT!\n"); f->eax = syscall_wait(*(pid_t *)argc[0]); break; case 4: // SYS_CREATE f->eax = syscall_create(*(const char **)argc[0], *(unsigned *)argc[1]); break; case 5: // SYS_REMOVE f->eax = syscall_remove(*(const char **)argc[0]); break; case 6: // SYS_OPEN f->eax = syscall_open(*(const char **)argc[0]); break; case 7: // SYS_FILESIZE f->eax = syscall_filesize(*(int *)argc[0]); break; case 8: // SYS_READ f->eax = syscall_read( *(int *)argc[0], *(void **)argc[1], *(unsigned *)argc[2] ); break; case 9: // SYS_WRITE //printf("CALLED WRITE! %d %x %u\n", *(int *)argc[0], argc[1], *(unsigned *)argc[2]); f->eax = syscall_write( *(int *)argc[0], *(const void **)argc[1], *(unsigned *)argc[2] ); break; case 10: // SYS_SEEK syscall_seek(*(int *)argc[0], *(unsigned *)argc[1] ); break; case 11: // SYS_TELL f->eax = syscall_tell(*(int *)argc[0]); break; case 12: // SYS_CLOSE syscall_close(*(int *)argc[0]); break; case 20: // SYS_PIBONACCI f->eax = syscall_pibonacci(*(int *)argc[0]); break; case 21: // SYS_SUM_OF_FOUR_INTEGERS f->eax = syscall_sum_of_four_integers( *(int *)argc[0], *(int *)argc[1], *(int *)argc[2], *(int *)argc[3] ); break; // case *: } // printf("SYSCALL_RETURN: %d\n", f->eax); // thread_exit (); // XXX }
/** * Handle system calls. Interrupts are enabled when this function is * called. * * @param user_context The userland context (CPU registers as they * where when system call instruction was called in userland) */ void syscall_handle(context_t *user_context) { /* When a syscall is executed in userland, register a0 contains * the number of the syscall. Registers a1, a2 and a3 contain the * arguments of the syscall. The userland code expects that after * returning from the syscall instruction the return value of the * syscall is found in register v0. Before entering this function * the userland context has been saved to user_context and after * returning from this function the userland context will be * restored from user_context. */ switch (A0) { case SYSCALL_HALT: halt_kernel(); break; case SYSCALL_READ: { int filehandle = (int)A1; if (filehandle == FILEHANDLE_STDIN || filehandle == FILEHANDLE_STDOUT || filehandle == FILEHANDLE_STDERR) { V0 = io_read((int) A1, (void*) A2, (int) A3); } else { V0 = syscall_read((openfile_t)A1, (void *)A2, (int)A3); } } break; case SYSCALL_WRITE: { int filehandle = (int)A1; if (filehandle == FILEHANDLE_STDIN || filehandle == FILEHANDLE_STDOUT || filehandle == FILEHANDLE_STDERR) { V0 = io_write((int) A1, (void*) A2, (int) A3); } else { V0 = syscall_write((openfile_t)A1, (void *)A2, (int)A3); } } break; case SYSCALL_EXEC: V0 = syscall_exec((char*) A1); break; case SYSCALL_EXIT: syscall_exit((int) A1); break; case SYSCALL_JOIN: V0 = syscall_join((process_id_t) A1); break; case SYSCALL_OPEN: V0 = syscall_open((char *) A1); break; case SYSCALL_CLOSE: V0 = syscall_close((openfile_t) A1); break; case SYSCALL_SEEK: V0 = syscall_seek((openfile_t)A1, (int)A2); break; case SYSCALL_CREATE: V0 = syscall_create((const char *)A1, (int)A2); break; case SYSCALL_REMOVE: V0 = syscall_remove((const char *)A1); break; case SYSCALL_TELL: V0 = syscall_tell((openfile_t)A1); break; case SYSCALL_SEM_OPEN: V0 = (uint32_t) usr_sem_open((char*) A1, A2); break; case SYSCALL_SEM_PROCURE: V0 = usr_sem_p((usr_sem_t*) A1); break; case SYSCALL_SEM_VACATE: V0 = usr_sem_v((usr_sem_t*) A1); break; case SYSCALL_SEM_DESTROY: V0 = usr_sem_destroy((usr_sem_t*) A1); break; default: KERNEL_PANIC("Unhandled system call\n"); } /* Move to next instruction after system call */ user_context->pc += 4; }