Exemple #1
0
int systemcall(struct PAR_REGS *regs)
{
	char *cpp1, *cpp2, **cppp1; //3, *cpp4, *cpp5, *cpp6, **cppp1, **cppp2;
	int i, ip1, ip2;
	//unsigned long old_cr0;
	
	switch (regs->eax) // Sys call number ?
	{
		case 0: return syscall_test();
		case 1:
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return syscall_open(CHARPPAR(regs->ebx), INTPAR(regs->ebx+4), INTPAR(regs+4+4));
		case 2: return syscall_close(INTPAR(regs->ebx));
		case 3:
			cpp1 = CHARPPAR(regs->ebx+4);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return syscall_read(INTPAR(regs->ebx), cpp1, INTPAR(regs->ebx+4+4));
		case 4: 
			cpp1 = CHARPPAR(regs->ebx+4);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return syscall_write(INTPAR(regs->ebx), cpp1, INTPAR(regs->ebx+4+4));
		case 5: return syscall_lseek(INTPAR(regs->ebx), INTPAR(regs->ebx+4), INTPAR(regs->ebx+4+4));
		case 6: 
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return syscall_mkdir(cpp1, INTPAR(regs->ebx+4));
		case 7: 
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return syscall_rmdir(cpp1);
		case 8: 
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return syscall_chdir(cpp1);
		case 9: 
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return syscall_creat(cpp1, INTPAR(regs->ebx+4));
		case 10:
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			cpp1 = CHARPPAR(regs->ebx+4);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return syscall_rename(CHARPPAR(regs->ebx), CHARPPAR(regs->ebx+4));
		case 11: 
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			cpp1 = CHARPPAR(regs->ebx+4);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return (int) syscall_opendir(CHARPPAR(regs->ebx), (DIR *)CHARPPAR(regs->ebx+4));
		case 12: 
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return syscall_closedir((DIR *) CHARPPAR(regs->ebx));
		case 13: 
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return (int) syscall_readdir((DIR *)CHARPPAR(regs->ebx));
		case 14: 
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			cpp1 = CHARPPAR(regs->ebx+4);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return syscall_stat(CHARPPAR(regs->ebx),(struct stat *)CHARPPAR(regs->ebx+4));
		case 15: 
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return syscall_unlink(CHARPPAR(regs->ebx));
		case 16: 
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return syscall_chmod(CHARPPAR(regs->ebx),(mode_t)INTPAR(regs->ebx+4));
		case 17:
			ip1 = INTPAR(regs->ebx);
			return syscall_dup(ip1);
		case 18:
			ip1 = INTPAR(regs->ebx);
			ip2 = INTPAR(regs->ebx + 4);
			return syscall_dup2(ip1, ip2);
		case 19: syscall_setcursor( INTPAR(regs->ebx),INTPAR(regs->ebx+4)); return 0;
		case 20: return syscall_getchar();
		case 21: return syscall_getchare();
		case 22: return syscall_getscanchar();
		case 23: return syscall_putchar(CHARPAR(regs->ebx));
		case 24: 
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return syscall_puts(CHARPPAR(regs->ebx));
		case 25:
			cpp1 = CHARPPAR(regs->ebx);
			ip1 = INTPAR(regs->ebx + 4);
			syscall_seekdir((DIR *)cpp1, ip1);
			return 0;
		case 26:
			cpp1 = CHARPPAR(regs->ebx);
			return syscall_telldir((DIR *)cpp1);
		case 27:
			cpp1 = CHARPPAR(regs->ebx);
			syscall_rewinddir((DIR *)cpp1);
			return 0;
		case 32: 
			cpp1 = CHARPPAR(regs->ebx+12);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return syscall_readblocks(INTPAR(regs->ebx), INTPAR(regs->ebx+4), INTPAR(regs->ebx+8), CHARPPAR(regs->ebx+12));
		case 33: 
			cpp1 = CHARPPAR(regs->ebx+12);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return syscall_writeblocks(INTPAR(regs->ebx), INTPAR(regs->ebx+4), INTPAR(regs->ebx+8), CHARPPAR(regs->ebx+12));
		case 34: syscall_sync(0); return 0;
		case 50: syscall_tsleep(INTPAR(regs->ebx)); return 0;
		case 60: 
			cpp1 = CHARPPAR(regs->ebx + 4);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return syscall_tsendto(SHORTPAR(regs->ebx), CHARPPAR(regs->ebx+4), INTPAR(regs->ebx+8), INTPAR(regs->ebx+12), INTPAR(regs->ebx+16), SHORTPAR(regs->ebx+20));
		case 62: 
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			cpp1 = CHARPPAR(regs->ebx + 8);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return syscall_trecvfrom(CHARPPAR(regs->ebx), INTPAR(regs->ebx+4), SHORTPPAR(regs->ebx+8), INTPAR(regs->ebx+12));
		case 65: 
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			cppp1 = (char **)CHARPPAR(regs->ebx+4);
			i = 0;
			while (cppp1[i] != NULL)
			{
				if (cppp1[i] < KERNELEND) return EINVALIDPTR;
				i++;
			}
			cppp1 = (char **)CHARPPAR(regs->ebx+8);
			i = 0;
			while (cppp1[i] != NULL)
			{
				if (cppp1[i] < KERNELEND) return EINVALIDPTR;
				i++;
			}
			return syscall_exectask(CHARPPAR(regs->ebx), (char **)CHARPPAR(regs->ebx+4), (char **)CHARPPAR(regs->ebx+8), INTPAR(regs->ebx+12));
		case 66: syscall_exit(INTPAR(regs->ebx)); return 0;
		case 70:
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			cpp1 = CHARPPAR(regs->ebx+4);
			if (cpp1 < KERNELEND && cpp1 != NULL) return EINVALIDPTR;
			cpp1 = CHARPPAR(regs->ebx+8);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			cpp1 = CHARPPAR(regs->ebx+12);
			if (cpp1 < KERNELEND && cpp1 != NULL) return EINVALIDPTR;
			return syscall_pthread_create((pthread_t *)INTPPAR(regs->ebx), (pthread_attr_t *)CHARPPAR(regs->ebx+4), (void *(*)(void *))INTPPAR(regs->ebx+8), (void *)CHARPPAR(regs->ebx+12));
		case 71: 
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND && cpp1 != NULL) return EINVALIDPTR;
			syscall_pthread_exit((void *)CHARPPAR(regs->ebx)); return 0;
		case 72: 
			cpp1 = CHARPPAR(regs->ebx+4);
			if (cpp1 < KERNELEND && cpp1 != NULL) return EINVALIDPTR;
			return syscall_pthread_join((pthread_t)INTPAR(regs->ebx), (void **)CHARPPAR(regs->ebx+4));
		case 73: return syscall_pthread_detach((pthread_t)INTPAR(regs->ebx));
		case 74: return syscall_pthread_yield();
		case 75: 
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			cpp1 = CHARPPAR(regs->ebx+4);
			if (cpp1 < KERNELEND && cpp1 != NULL) return EINVALIDPTR;
			return syscall_pthread_mutex_init((pthread_mutex_t *)INTPAR(regs->ebx), (pthread_mutexattr_t *)CHARPPAR(regs->ebx+4));
		case 76: 
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return syscall_pthread_mutex_trylock((pthread_mutex_t *)INTPAR(regs->ebx));
		case 77: 
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return syscall_pthread_mutex_lock((pthread_mutex_t *)INTPAR(regs->ebx));
		case 78: 
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return syscall_pthread_mutex_unlock((pthread_mutex_t *)INTPAR(regs->ebx));
		case 79: 
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			cpp1 = CHARPPAR(regs->ebx+4);
			if (cpp1 < KERNELEND && cpp1 != NULL) return EINVALIDPTR;
			return syscall_pthread_cond_init((pthread_cond_t *)INTPAR(regs->ebx), (pthread_condattr_t *)CHARPPAR(regs->ebx+4));
		case 80: 
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			cpp1 = CHARPPAR(regs->ebx+4);
			if (cpp1 < KERNELEND && cpp1 != NULL) return EINVALIDPTR;
			return syscall_pthread_cond_wait((pthread_cond_t *)INTPAR(regs->ebx), (pthread_mutex_t *)INTPPAR(regs->ebx+4));
		case 81: 
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return syscall_pthread_cond_signal((pthread_cond_t *)INTPAR(regs->ebx));
		case 82: 
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return syscall_pthread_cond_broadcast((pthread_cond_t *)INTPAR(regs->ebx));
		case 83: 
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			cpp1 = CHARPPAR(regs->ebx+4);
			if (cpp1 < KERNELEND && cpp1 != NULL) return EINVALIDPTR;
			return syscall_pthread_barrier_init((pthread_barrier_t *)INTPAR(regs->ebx), (pthread_barrierattr_t *)INTPPAR(regs->ebx+4), INTPAR(regs->ebx+8));
		case 84: 
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return syscall_pthread_barrier_wait((pthread_barrier_t *)INTPAR(regs->ebx));
		case 90: return syscall_socket(INTPAR(regs->ebx), INTPAR(regs->ebx+4), INTPAR(regs->ebx+8));
		case 91: 
			cpp1 = CHARPPAR(regs->ebx+4);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return syscall_bind(INTPAR(regs->ebx), (struct sockaddr *)INTPPAR(regs->ebx+4), SHORTPAR(regs->ebx+8));
		case 92: 
			cpp1 = CHARPPAR(regs->ebx + 4);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return syscall_recv(INTPAR(regs->ebx), (void *)CHARPPAR(regs->ebx+4), (size_t)INTPAR(regs->ebx+8), INTPAR(regs->ebx+12));
		case 93: 
			cpp1 = CHARPPAR(regs->ebx + 4);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			cpp1 = CHARPPAR(regs->ebx+16);
			if (cpp1 < KERNELEND && cpp1 != NULL) return EINVALIDPTR;
			cpp1 = CHARPPAR(regs->ebx+20);
			if (cpp1 < KERNELEND && cpp1 != NULL) return EINVALIDPTR;
			return syscall_recvfrom(INTPAR(regs->ebx), (void *)CHARPPAR(regs->ebx+4), (size_t)INTPAR(regs->ebx+8), INTPAR(regs->ebx+12), (struct sockaddr *)CHARPPAR(regs->ebx+16), (socklen_t *)SHORTPPAR(regs->ebx+20));
		case 94: 
			cpp1 = CHARPPAR(regs->ebx + 4);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return syscall_send(INTPAR(regs->ebx), (void *)CHARPPAR(regs->ebx+4), (size_t)INTPAR(regs->ebx+8), INTPAR(regs->ebx+12));
		case 95: 
			cpp1 = CHARPPAR(regs->ebx + 4);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			cpp1 = CHARPPAR(regs->ebx + 16);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return syscall_sendto(INTPAR(regs->ebx), (void *)CHARPPAR(regs->ebx+4), (size_t)INTPAR(regs->ebx+8), INTPAR(regs->ebx+12), (struct sockaddr *)CHARPPAR(regs->ebx+16), (socklen_t)SHORTPAR(regs->ebx+20));
		case 96: 
			cpp1 = CHARPPAR(regs->ebx + 4);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return syscall_connect(INTPAR(regs->ebx), (struct sockaddr *)CHARPPAR(regs->ebx+4), (socklen_t)SHORTPAR(regs->ebx+8));
		case 97: 
			cpp1 = CHARPPAR(regs->ebx + 4);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			cpp1 = CHARPPAR(regs->ebx + 8);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return syscall_accept(INTPAR(regs->ebx), (struct sockaddr *)CHARPPAR(regs->ebx+4), (socklen_t *)CHARPPAR(regs->ebx+8));
		case 98: return syscall_listen(INTPAR(regs->ebx), INTPAR(regs->ebx+4));
		case 99: return syscall_kill(INTPAR(regs->ebx));
		case 100: 
			cpp1 = CHARPPAR(regs->ebx + 4);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return syscall_getprocinfo(INTPAR(regs->ebx), (struct uprocinfo *)INTPPAR(regs->ebx+4));
		case 101: 
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return syscall_getpids(INTPPAR(regs->ebx), INTPAR(regs->ebx+4));
		case 102: 
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return syscall_sem_init((sem_t *)(CHARPPAR(regs->ebx)), INTPAR(regs->ebx+4), (unsigned int)INTPAR(regs->ebx+8));
		case 103: 
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return syscall_sem_destroy((sem_t *)(CHARPPAR(regs->ebx)));
		case 104: 
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			cpp1 = CHARPPAR(regs->ebx+16);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return (int)syscall_sem_open(CHARPPAR(regs->ebx), INTPAR(regs->ebx+4), (mode_t)INTPAR(regs->ebx+8), INTPAR(regs->ebx+12), (sem_t *)CHARPPAR(regs->ebx+16));
		case 105: 
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return syscall_sem_close((sem_t *)(CHARPPAR(regs->ebx)));
		case 106: 
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return syscall_sem_unlink(CHARPPAR(regs->ebx));
		case 107: 
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return syscall_sem_wait((sem_t *)(CHARPPAR(regs->ebx)));
		case 108: 
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return syscall_sem_trywait((sem_t *)(CHARPPAR(regs->ebx)));
		case 109: 
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			cpp1 = CHARPPAR(regs->ebx+4);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return syscall_sem_timedwait((sem_t *)(CHARPPAR(regs->ebx)), (const struct timespec *)CHARPPAR(regs->ebx+4));
		case 110: 
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return syscall_sem_post((sem_t *)(CHARPPAR(regs->ebx)));
		case 111: 
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			cpp1 = CHARPPAR(regs->ebx+4);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return syscall_sem_getvalue((sem_t *)(CHARPPAR(regs->ebx)), INTPPAR(regs->ebx+4));
		case 112: 
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND && cpp1 != NULL) return EINVALIDPTR;
			return (int)syscall_time((time_t *)(CHARPPAR(regs->ebx)));
		case 113: return (int)syscall_pthread_self();
		case 114: 
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND && cpp1 != NULL) return EINVALIDPTR;
			return syscall_brk((void *)CHARPPAR(regs->ebx));
		case 115:
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			cpp1 = CHARPPAR(regs->ebx+4);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			cpp1 = CHARPPAR(regs->ebx+8);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return syscall_gettsc((unsigned int *)INTPPAR(regs->ebx), (unsigned int *)INTPPAR(regs->ebx+4), (unsigned int *)INTPPAR(regs->ebx+8));

		case 140:
			print_core_info();
			print_minf_statistics();
			return 0;

		case 147:
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return syscall_wait(INTPPAR(regs->ebx));
		case 148:
			return syscall_pageinfo(INTPAR(regs->ebx), INTPAR(regs->ebx+4));
		case 153:
			syscall_machid();
			return 0;
		case 154:
			return syscall_getcharf(INTPAR(regs->ebx));
		case 155:
			return syscall_ungetcharf(INTPAR(regs->ebx), INTPAR(regs->ebx+4));
		case 156:
			printk("broadcast called\n");
			return syscall_broadcast(INTPAR(regs->ebx), CHARPPAR(regs->ebx+4), INTPAR(regs->ebx+8));
		case 157:
			return syscall_primalloc((unsigned int)INTPAR(regs->ebx));

		case 158:
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return syscall_prifree((void *)CHARPPAR(regs->ebx), (unsigned int)INTPAR(regs->ebx+4));
		case 202:
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			cpp2 = CHARPPAR(regs->ebx + 4);
			if (cpp2 < KERNELEND) return EINVALIDPTR;
			mark_tsc((unsigned int *)cpp1, (unsigned int *)cpp2);
			return 0;

		case 203:
			return (secs * 1000 + millesecs);
			
		case 204:
			cpp1 = CHARPPAR(regs->ebx);
			if (cpp1 < KERNELEND) return EINVALIDPTR;
			return syscall_pthread_mutex_destroy((pthread_mutex_t *) cpp1);
		
		default: return syscall_notimplemented(regs->eax);
	}
}
Exemple #2
0
int does_file_exist(char* file) {
  int fd = syscall_open(file);
  syscall_close(fd);
  return fd >= 0;
}
Exemple #3
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;
    }
}
Exemple #4
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;
}
Exemple #5
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();
}
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
}
/** @brief Handles all syscalls of the tracked pid until it does a blocking action.
 *
 *  Blocking actions are stuff that must be reported to the simulator and which
 *  completion takes time. The most prominent examples are related to sending and
 *  receiving data.
 *
 *  The tracked pid can run more than one syscall in this function if theses calls
 *  are about the metadata that we maintain in simterpose without exposing them to
 *  simgrid. For example, if you call socket() or accept(), we only have to maintain
 *  our metadata but there is no need to inform the simulator, nor to ask for the
 *  completion time of these things.
 */
int process_handle(process_descriptor_t * proc)
{
  reg_s arg;
  pid_t pid = proc->pid;
  XBT_DEBUG("PROCESS HANDLE MSG");
  while (1) {
    ptrace_get_register(pid, &arg);
    int ret;
    XBT_DEBUG("found syscall: [%d] %s (%ld) = %ld, in_syscall = %d", pid, syscall_list[arg.reg_orig], arg.reg_orig,
	      arg.ret, proc->in_syscall);

    switch (arg.reg_orig) {
    case SYS_creat:
      syscall_creat(&arg, proc);
      break;

    case SYS_open:
      XBT_DEBUG("On open");
      XBT_DEBUG("Valeur des registres dans l'AS:");
      XBT_DEBUG("Valeur de retour %lu", arg.ret);
      XBT_DEBUG("Valeur des arg %lu %lu %lu %lu %lu %lu", arg.arg[0], arg.arg[1], arg.arg[2], arg.arg[3], arg.arg[4], arg.arg[5]);
      syscall_open(&arg, proc);
      break;

    case SYS_close:
      syscall_close(&arg, proc);
      break;

    case SYS_read:
      syscall_read(&arg, proc);
      break;

    case SYS_write:
      XBT_DEBUG("On write");
      XBT_DEBUG("Valeur des registres dans l'AS:");
      XBT_DEBUG("Valeur de retour %lu", arg.ret);
      XBT_DEBUG("Valeur des arg %lu %lu %lu %lu %lu %lu", arg.arg[0], arg.arg[1], arg.arg[2], arg.arg[3], arg.arg[4], arg.arg[5]);
      if ((ret = syscall_write(&arg, proc)))
	return ret;
      break;

    case SYS_dup:
      syscall_dup(&arg, proc);
      break;

    case SYS_dup2:
      syscall_dup2(&arg, proc);
      break;

    case SYS_fcntl:
      syscall_fcntl(&arg, proc);
      break;

    case SYS_lseek:
      syscall_lseek(&arg, proc);
      break;

    case SYS_poll:
      syscall_poll(&arg, proc);
      break;

    case SYS_select:
      syscall_select(&arg, proc);
      break;

    case SYS_pipe:
      syscall_pipe(&arg, proc);

    case SYS_brk:
      syscall_brk(&arg, proc);
      break;

    case SYS_socket:
      syscall_socket(&arg, proc);
      break;

    case SYS_connect:
      syscall_connect(&arg, proc);
      break;

    case SYS_bind:
      syscall_bind(&arg, proc);
      break;

    case SYS_listen:
      syscall_listen(&arg, proc);
      break;

    case SYS_accept:
      syscall_accept(&arg, proc);
      break;

#if UINTPTR_MAX == 0xffffffff
      /* 32-bit architecture */
    case SYS_send:
      ret = syscall_send(&arg, proc);
      if (ret)
	return ret;
      break;

    case SYS_recv:
      syscall_recv(&arg, proc);
      break;
#endif

    case SYS_sendto:
      ret = syscall_sendto(&arg, proc);
      if (ret)
        return ret;
      break;

    case SYS_recvfrom:
      syscall_recvfrom(&arg, proc);
      break;

    case SYS_sendmsg:
      if ((ret = syscall_sendmsg( &arg, proc)))
        return ret;
      break;

    case SYS_recvmsg:
      syscall_recvmsg(&arg, proc);
      break;

    case SYS_shutdown:
      syscall_shutdown(&arg, proc);
      break;

    case SYS_getpeername:
      syscall_getpeername(&arg, proc);
      break;

    case SYS_getsockopt:
      syscall_getsockopt(&arg, proc);
      break;

    case SYS_setsockopt:
      syscall_setsockopt(&arg, proc);
      break;

    case SYS_clone:
      syscall_clone(&arg, proc);
      break;

    case SYS_execve:
      syscall_execve(&arg, proc);
      break;

    case SYS_exit:
      XBT_DEBUG("exit(%ld) called", arg.arg[0]);
      return syscall_exit(&arg, proc);
      break;

    case SYS_exit_group:
      XBT_DEBUG("exit_group(%ld) called", arg.arg[0]);
      return syscall_exit(&arg, proc);
      break;

    case SYS_getpid:
      syscall_getpid(&arg, proc);
      break;

    case SYS_tuxcall:
      syscall_tuxcall(&arg, proc);
      break;

    default:
      syscall_default(pid, &arg, proc);
      break;
    }

      // Step the traced process
      ptrace_resume_process(pid);
      // XBT_DEBUG("process resumed, waitpid");
      waitpid(pid, &(proc->status), __WALL);
    }                             // while(1)

      THROW_IMPOSSIBLE;             //There's no way to quit the loop
      return 0;
    }
Exemple #8
0
/**
 * 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;
}