void func1(int off) { syscall_vga_print_hex(off); syscall_vga_print_str("ok\n"); for (unsigned i = 0; i < 200000; ++i) { if (i % 5000 == 0) syscall_vga_print_str("-"); } syscall_vga_print_str("exit\n"); syscall_thread_exit(); }
static inline int syscallenter(struct thread *td, struct syscall_args *sa) { struct proc *p; int error, traced; PCPU_INC(cnt.v_syscall); p = td->td_proc; td->td_pticks = 0; if (td->td_ucred != p->p_ucred) cred_update_thread(td); if (p->p_flag & P_TRACED) { traced = 1; PROC_LOCK(p); td->td_dbgflags &= ~TDB_USERWR; td->td_dbgflags |= TDB_SCE; PROC_UNLOCK(p); } else traced = 0; error = (p->p_sysent->sv_fetch_syscall_args)(td, sa); #ifdef KTRACE if (KTRPOINT(td, KTR_SYSCALL)) ktrsyscall(sa->code, sa->narg, sa->args); #endif CTR6(KTR_SYSC, "syscall: td=%p pid %d %s (%#lx, %#lx, %#lx)", td, td->td_proc->p_pid, syscallname(p, sa->code), sa->args[0], sa->args[1], sa->args[2]); if (error == 0) { STOPEVENT(p, S_SCE, sa->narg); if (p->p_flag & P_TRACED && p->p_stops & S_PT_SCE) { PROC_LOCK(p); ptracestop((td), SIGTRAP); PROC_UNLOCK(p); } if (td->td_dbgflags & TDB_USERWR) { /* * Reread syscall number and arguments if * debugger modified registers or memory. */ error = (p->p_sysent->sv_fetch_syscall_args)(td, sa); #ifdef KTRACE if (KTRPOINT(td, KTR_SYSCALL)) ktrsyscall(sa->code, sa->narg, sa->args); #endif if (error != 0) goto retval; } #ifdef CAPABILITY_MODE /* * In capability mode, we only allow access to system calls * flagged with SYF_CAPENABLED. */ if (IN_CAPABILITY_MODE(td) && !(sa->callp->sy_flags & SYF_CAPENABLED)) { error = ECAPMODE; goto retval; } #endif error = syscall_thread_enter(td, sa->callp); if (error != 0) goto retval; #ifdef KDTRACE_HOOKS /* * If the systrace module has registered it's probe * callback and if there is a probe active for the * syscall 'entry', process the probe. */ if (systrace_probe_func != NULL && sa->callp->sy_entry != 0) (*systrace_probe_func)(sa->callp->sy_entry, sa->code, sa->callp, sa->args, 0); #endif AUDIT_SYSCALL_ENTER(sa->code, td); error = (sa->callp->sy_call)(td, sa->args); AUDIT_SYSCALL_EXIT(error, td); /* Save the latest error return value. */ td->td_errno = error; #ifdef KDTRACE_HOOKS /* * If the systrace module has registered it's probe * callback and if there is a probe active for the * syscall 'return', process the probe. */ if (systrace_probe_func != NULL && sa->callp->sy_return != 0) (*systrace_probe_func)(sa->callp->sy_return, sa->code, sa->callp, NULL, (error) ? -1 : td->td_retval[0]); #endif syscall_thread_exit(td, sa->callp); CTR4(KTR_SYSC, "syscall: p=%p error=%d return %#lx %#lx", p, error, td->td_retval[0], td->td_retval[1]); } retval: if (traced) { PROC_LOCK(p); td->td_dbgflags &= ~TDB_SCE; PROC_UNLOCK(p); } (p->p_sysent->sv_set_syscall_retval)(td, error); return (error); }
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; } }