📄 mips-syscall.c
字号:
{ expand_data (R[REG_A0]); R[REG_RES] = program_break; program_break += R[REG_A0]; R[REG_ERR] = 0; break; } case SYS_brk: /* Round up to 4096 byte (page) boundary */ if ( ( (int) R[REG_A0] - (int) data_top) > 0) expand_data (ROUND_UP (R[REG_A0], 4096)- (int)data_top); R[REG_RES] = program_break; program_break = ROUND_UP (R[REG_A0], 4096); R[REG_ERR] = 0; break; case SYS_sigvec: { int x; if (R[REG_A2] != 0) * (struct sigvec *) MEM_ADDRESS (R[REG_A2]) = sighandler[R[REG_A0]]; READ_MEM_WORD (x, R[REG_A1]); sighandler[R[REG_A0]].sv_handler = (void (*) ()) x; READ_MEM_WORD (x,R[REG_A1] + sizeof (int *)); sighandler[R[REG_A0]].sv_mask = x; READ_MEM_WORD (x,R[REG_A1] + sizeof (int *) + sizeof (sigset_t)); sighandler[R[REG_A0]].sv_flags = x; exception_address[R[REG_A0]] = R[REG_A3]; R[REG_ERR] = 0; break; } case SYS_sigreturn: do_sigreturn (MEM_ADDRESS (R[REG_A0])); R[REG_ERR] = 0; break; case SYS_sigsetmask: R[REG_RES] = prog_sigmask; prog_sigmask = R[REG_A0]; R[REG_ERR] = 0; break; case SYS_sigblock: R[REG_RES] = prog_sigmask; prog_sigmask |= R[REG_A0]; R[REG_ERR] = 0; break; case SYS_cacheflush:#if 0 R[REG_RES] = cache_flush ((void*)MEM_ADDRESS (R[REG_A0]), R[REG_A1], R[REG_A2]);#endif R[REG_ERR] = 0; break; case SYS_cachectl:#if 0 R[REG_RES] = cache_ctl ((void*)MEM_ADDRESS (R[REG_A0]), R[REG_A1],R [REG_A2]);#endif R[REG_ERR] = 0; break; default: run_error ("Unknown special system call: %d\n",R[REG_V0]); break; } break; default: run_error ("Unknown type for syscall: %d\n", R[REG_V0]); break; } }#else run_error ("Can't use MIPS syscall on non-MIPS system\n");#endif return (1);}/* Execute a Unix system call. Returns negative on error. */#if (mips && dec)#ifdef __STDC__static intunixsyscall (void)#elsestatic intunixsyscall ()#endif{ void* arg0, arg1, arg2, arg3; arg0 = SYSCALL_ARG (REG_V0,arg0, REG_A0); arg1 = SYSCALL_ARG (REG_V0,arg1, REG_A1); arg2 = SYSCALL_ARG (REG_V0,arg2, REG_A2); arg3 = SYSCALL_ARG (REG_V0,arg3, REG_A3); R[REG_RES] = syscall (R[REG_V0], arg0, arg1, arg2, arg3); /* See if an error has occurred during the system call. If so, the libc wrapper must be notifified by setting register 7 to be less than zero and the return value should be errno. If not, register 7 should be zero. r7 acts like the carry flag in the old days. */ if (R[REG_RES] < 0) { R[REG_ERR] = -1; R[REG_RES] = errno; return (-1); } else { R[REG_ERR] = 0; return (R[REG_RES]); }}#endif#if (mips && dec)#ifdef __STDC__static intreverse_fds (int fd)#elsestatic intreverse_fds (fd) int fd;#endif{ int i; for (i = 0; i < OPEN_MAX; i++) if (prog_fds[i] == fd) return (i); run_error ("Couldn't reverse translate fds\n"); return (-1);}#endif#ifdef __STDC__voidprint_syscall_usage (void)#elsevoidprint_syscall_usage ()#endif{ int x; printf ("System call counts...\n\n"); printf ("Call#\t\tFrequency\n"); for (x = 0; x < MAX_SYSCALL; x ++) if (syscall_usage[x] > 0) printf("%d(%s)\t\t%d\n", x, syscall_table[x].syscall_name, syscall_usage[x]); printf ("\n");}#ifdef __STDC__voidinitialize_prog_fds (void)#elsevoidinitialize_prog_fds ()#endif{ int x; for (x = 0; x < OPEN_MAX; prog_fds[x++] = -1); if (((prog_fds[0] = dup(0)) < 0) || ((prog_fds[1] = dup(1)) < 0) || ((prog_fds[2] = dup(2)) < 0)) error("init_prog_fds");}/* clear out programs file descriptors, close necessary files */#ifdef __STDC__voidkill_prog_fds (void)#elsevoidkill_prog_fds ()#endif{ int x; for (x = 0; x < OPEN_MAX; x++) if (prog_fds[x] != -1) close(prog_fds[x]);}#ifdef __STDC__voidhandle_exception (void)#elsevoidhandle_exception ()#endif{ if (!quiet && ((Cause >> 2) & 0xf) != INT_EXCPT) error ("Exception occurred at PC=0x%08x\n", EPC); exception_occurred = 0; PC = EXCEPTION_ADDR; switch ((Cause >> 2) & 0xf) { case INT_EXCPT: if (!source_file) R[REG_A0] = SIGINT; break; case ADDRL_EXCPT: if (!source_file) R[REG_A0] = SIGSEGV; if (!quiet) error (" Unaligned address in inst/data fetch: 0x%08x\n",BadVAddr); break; case ADDRS_EXCPT: if (!source_file) R[REG_A0] = SIGSEGV; if (!quiet) error (" Unaligned address in store: 0x%08x\n", BadVAddr); break; case IBUS_EXCPT: if (!source_file) R[REG_A0] = SIGBUS; if (!quiet) error (" Bad address in text read: 0x%08x\n", BadVAddr); break; case DBUS_EXCPT: if (!source_file) R[REG_A0] = SIGBUS; if (!quiet) error (" Bad address in data/stack read: 0x%08x\n", BadVAddr); break; case BKPT_EXCPT: exception_occurred = 0; return; case SYSCALL_EXCPT: if (!quiet) error (" Error in syscall\n"); break; case RI_EXCPT: if (!quiet) error (" Reserved instruction execution\n"); break; case OVF_EXCPT: if (!source_file) R[REG_A0] = SIGFPE; if (!quiet) error (" Arithmetic overflow\n"); break; default: if (!quiet) error ("Unknown exception: %d\n", Cause >> 2); break; } if (!source_file) {#if (mips && dec) if ((prog_sigmask & (1 << R[REG_A0])) == 1) return; if((int) sighandler[R[REG_A0]].sv_handler == 0) run_error ("Exception occurred at PC=0x%08x\nNo handler for it.\n", EPC); setup_signal_stack(); R[REG_A1] = 48; R[REG_A2] = R[29]; R[REG_A3] = (int) sighandler[R[REG_A0]].sv_handler; if ((PC = exception_address[R[REG_A0]]) == 0) PC = (int) find_symbol_address ("sigvec") + 44;#endif }}#if (mips && dec)#ifdef __STDC__static voidsetup_signal_stack (void)#elsestatic voidsetup_signal_stack ()#endif{ int i; struct sigcontext *sc; R[29] -= sizeof(struct sigcontext) + 4; sc = (struct sigcontext *) MEM_ADDRESS (R[29]); sc->sc_onstack = 0 /**/; sc->sc_mask = prog_sigmask; sc->sc_pc = EPC; for(i=0; i < 32; ++i) /* general purpose registers */ sc->sc_regs[i] = R[i]; sc->sc_mdlo = LO; /* mul/div low */ sc->sc_mdhi = HI; sc->sc_ownedfp = 0; /* fp has been used */ for(i=0; i < 32; ++i) /* FPU registers */ sc->sc_fpregs[i] = FPR[i]; sc->sc_fpc_csr = 0; /* floating point control and status reg */ sc->sc_fpc_eir = 0; sc->sc_cause = Cause; /* cp0 cause register */ sc->sc_badvaddr = BadVAddr; /* cp0 bad virtual address */ sc->sc_badpaddr = 0; /* cpu bd bad physical address */}#endif#if (mips && dec)#ifdef __STDC__static voiddo_sigreturn (mem_addr sigptr)#elsestatic voiddo_sigreturn (sigptr) mem_addr sigptr;#endif{ int i; struct sigcontext *sc; sc = (struct sigcontext *) sigptr; prog_sigmask = sc->sc_mask; PC = sc->sc_pc - BYTES_PER_WORD; for(i=0; i < 32; ++i) R[i] = sc->sc_regs[i]; LO = sc->sc_mdlo; HI = sc->sc_mdhi; for(i=0; i < 32; ++i) /* FPU registers */ FPR[i] = sc->sc_fpregs[i]; Cause = sc->sc_cause; BadVAddr = sc->sc_badvaddr; R[29] += sizeof(struct sigcontext) + 4;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -