Ejemplo n.º 1
0
/*
 * 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;
  }
}
Ejemplo n.º 2
0
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;
    }
}
Ejemplo n.º 3
0
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;
}
Ejemplo n.º 4
0
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();
}
Ejemplo n.º 5
0
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
}