📄 syscall.c
字号:
r4 = P->R[4]; r5 = P->R[5]; r6 = P->R[6]; if (!ReadSyscallStringNolength(cpuNum, 0, r4)) { return STALL; } err = open((const void *) S->syscallBuf[0], r5, r6); /* the libc stub code looks at a3 to decide if the call succeeded or failed */ if(err < 0) { P->R[7] = 1; P->R[2] = errno; } else { P->R[7] = 0; P->R[2] = err; } /* errno may not be supported correctly across threads */ /* Success */ break; case SYS_close: SIM_DEBUG(('o', "Emulating close() system call\n")); r4 = P->R[4]; err = close(r4); /* the libc stub code looks at a3 to decide if the call succeeded or failed */ if(err < 0) { P->R[7] = 1; P->R[2] = errno; } else { P->R[7] = 0; P->R[2] = err; } break; case SYS_read: SIM_DEBUG(('o', "Emulating read() system call...WARNING: incompletely tested!\n")); r4 = P->R[4]; r5 = P->R[5]; r6 = P->R[6]; if (r6 > SYSCALL_BUF_SIZE) { CPUError("Detected read syscall length (%d) > SYSCALL_BUF_SIZE", r6); } if (S->syscallState[0] == -1) { /* first time through *//* AllocateSyscallString(P, 0, r6); */ S->syscallState[0] = 0; err = read(r4, (void *) S->syscallBuf[0], r6); /* the libc stub code looks at a3 to decide if the call succeeded or failed */ if(err < 0) { P->R[7] = 1; P->R[2] = errno; break; } else { P->syscallStatus = 0; P->syscallResult = err; } } if (!WriteSyscallString(cpuNum, 0, r5, P->syscallResult)) { SIM_DEBUG(('o', "read() returning STALL\n")); return STALL; } else { P->R[7] = P->syscallStatus; P->R[2] = P->syscallResult; } /* errno may not be supported correctly across threads */ /* Success */ break; case SYS_write: SIM_DEBUG(('o', "Emulating write() system call\n")); r4 = P->R[4]; r5 = P->R[5]; r6 = P->R[6]; if (r6 > SYSCALL_BUF_SIZE) { CPUError("Detected write syscall length (%d) > SYSCALL_BUF_SIZE", r6); } if (!ReadSyscallString(cpuNum, 0, r5, r6)) { return STALL; } err = write(r4, (const void *) S->syscallBuf[0], r6); /* the libc stub code looks at a3 to decide if the call succeeded or failed */ if(err < 0) { P->R[7] = 1; P->R[2] = errno; } else { P->R[7] = 0; P->R[2] = err; } /* errno may not be supported correctly across threads */ /* Success */ break; case SYS_prctl: if (P->R[4] == PR_GETNSHARE) { P->R[7] = 0; /* Allow Share Group queries */ } else { CPUError("Encountered unsupported %d (prctl) function code #%d, exiting\n", syscallNum, P->R[4]); } break; /* Success if here *//* Passed MipsyHandleSyscall after some Prologue*//* Passed directly to MipsyHandleSyscall *//* These functions areguments are clean and can be sent directly */ case SYS_syscall: /* I have NO IDEA what this does */ case SYS_ioctl: case SYS_dup: case SYS_pipe: case SYS_setuid: case SYS_getuid: case SYS_getpid: case SYS_kill: case SYS_lseek:/* WARNING: --- Watch ksigaction --- */ case SYS_ksigaction: MipsyHandleSyscall(P); break;/* Intercept this call as a request to determine if you're on mipsy. The user program can check the return value */ case SYS_sync: P->R[REG_V0] = IN_MIPSY; break;/* Yet Another Syscall Hack -- this one stalls the CPU for a small, random number of cycles. Register a2 provides a 'shift factor' which allows us to model exponential backoff. */ case SYS_pause: { static uint stallTime[SIM_MAXCPUS]; uint shiftamount, mask; if (S->syscallState[0] == -1) { shiftamount = (P->R[4] > 24) ? 24 : P->R[4]; mask = (32 << shiftamount) - 1; S->syscallState[0] = 0; stallTime[cpuNum] = random() & mask; CPUPrint("EmulateSyscall: SYS_pause cpu %d backs off for %d cycles (MAX %d)\n", cpuNum, stallTime[cpuNum], mask); } if (stallTime[cpuNum] > 0) { stallTime[cpuNum]--; return STALL; } } break;/* Non-handled syscalls */ case SYS_fork: case SYS_creat: case SYS_link: case SYS_unlink: case SYS_execv: case SYS_chdir: case SYS_time: case SYS_chmod: case SYS_chown: case SYS_mount: case SYS_umount: case SYS_stime: case SYS_stat: case SYS_ptrace: case SYS_alarm: case SYS_utime: case SYS_access: case SYS_nice: case SYS_statfs: case SYS_fstatfs: case SYS_setpgrp: case SYS_syssgi: case SYS_times: case SYS_profil: case SYS_plock: case SYS_setgid: case SYS_getgid: case SYS_msgsys: case SYS_sysmips: case SYS_acct: case SYS_shmsys: case SYS_semsys: case SYS_uadmin: case SYS_sysmp: case SYS_utssys: case SYS_execve: case SYS_umask: case SYS_chroot: case SYS_fcntl: case SYS_ulimit: case SYS_rmdir: case SYS_mkdir: case SYS_getdents: case SYS_sginap: case SYS_sgikopt: case SYS_sysfs: case SYS_getmsg: case SYS_putmsg: case SYS_poll:/* This system call is internal for mips signal handling code */ case SYS_sigreturn:/* 4.3BSD-compatible socket/protocol system calls */ case SYS_accept: case SYS_bind: case SYS_connect: case SYS_gethostid: case SYS_getpeername: case SYS_getsockname: case SYS_getsockopt: case SYS_listen: case SYS_recv: case SYS_recvfrom: case SYS_recvmsg: case SYS_select: case SYS_send: case SYS_sendmsg: case SYS_sendto: case SYS_sethostid: case SYS_setsockopt: case SYS_shutdown: case SYS_socket: case SYS_gethostname: case SYS_sethostname: case SYS_getdomainname: case SYS_setdomainname:/* other 4.3BSD system calls */ case SYS_truncate: case SYS_ftruncate: case SYS_rename: case SYS_symlink: case SYS_readlink: case SYS_nfssvc: case SYS_getfh: case SYS_async_daemon: case SYS_exportfs: case SYS_setregid: case SYS_setreuid: case SYS_getitimer: case SYS_setitimer: case SYS_adjtime: case SYS_BSD_getime:/* Parallel processing system calls */ case SYS_sproc: case SYS_procblk: case SYS_sprocsp:/* memory-mapped file calls */ case SYS_mmap: case SYS_munmap: case SYS_mprotect: case SYS_msync: case SYS_madvise: case SYS_pagelock: case SYS_getpagesize:/* BSD quotactl syscall, used to be libattach */ case SYS_quotactl:/* 4.3BSD set/getpgrp syscalls */ case SYS_BSDgetpgrp: case SYS_BSDsetpgrp:/* 4.3BSD vhangup, fsync, and fchdir */ case SYS_vhangup: case SYS_fsync: case SYS_fchdir:/* 4.3BSD getrlimit/setrlimit syscalls */ case SYS_getrlimit: case SYS_setrlimit:/* mips cache syscalls */ case SYS_cacheflush: case SYS_cachectl:/* 4.3BSD fchown/fchmod syscalls */ case SYS_fchown: case SYS_fchmod:/* 4.3BSD socketpair syscall */ case SYS_socketpair:/* SVR4.1 new syscalls */ case SYS_sysinfo: case SYS_nuname: case SYS_xstat: case SYS_lxstat: case SYS_xmknod:/* Posix.1 signal calls */ case SYS_sigpending: case SYS_sigprocmask: case SYS_sigsuspend:/* Posix.4 signal calls */ case SYS_sigpoll: case SYS_swapctl: case SYS_getcontext: case SYS_setcontext: case SYS_waitsys: case SYS_sigstack: case SYS_sigaltstack: case SYS_sigsendset: case SYS_statvfs: case SYS_fstatvfs: case SYS_getpmsg: case SYS_putpmsg:/* more SVR4.1 new syscall */ case SYS_lchown: case SYS_priocntl:/* Posix.4 signal calls */ case SYS_ksigqueue: CPUError("Encountered unsupported system call #%d (%s), exiting\n", syscallNum, syscallName[syscallNum]); break; default: CPUError("Encountered invalid system call #%d (?? %s), exiting\n", syscallNum, syscallName[syscallNum]); break; } /* Clean up this syscall's internal state */ if (S->syscallState[0] != -1) { S->syscallState[0]=-1; } if (S->syscallState[1] != -1) { S->syscallState[1]=-1; } S->syscallNum = -1; return 1; /* This instruction is now complete */}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -