📄 trap.c
字号:
void_dumpstack(Ureg *ureg){ ulong l, sl, el, v, i, instr, op; extern ulong etext; l=(ulong)&l; if(l&4) l += 4; if(up == 0){ el = (ulong)m+BY2PG; sl = el-KSTACK; } else{ sl = (ulong)up->kstack; el = sl + KSTACK; } if(l > el || l < sl){ el = (ulong)m+BY2PG; sl = el-KSTACK; } if(l > el || l < sl) return; print("ktrace /kernel/path %.8lux %.8lux %.8lux\n", (ulong)ureg->pc, (ulong)ureg->sp, (ulong)ureg->r26); i = 0; for(; l<el; l+=8){ v = *(ulong*)l - 4; if(KTZERO < v && v < (ulong)&etext && (v&3) == 0){ /* * Check for JSR/BSR */ instr = *(ulong*)v; op = (instr>>26); if(op == 26 || op == 52){ print("%lux=%lux ", l, v); i++; } } if(i == 4){ i = 0; print("\n"); } } if(i) print("\n");}voiddumpstack(void){ callwithureg(_dumpstack);}intnotify(Ureg *ur){ int l; ulong sp; Note *n; if(up->procctl) procctl(up); if(up->nnote == 0) return 0; spllo(); qlock(&up->debug); up->notepending = 0; if(up->fpstate == FPactive){ savefpregs(&up->fpsave); up->fpstate = FPinactive; } up->fpstate |= FPillegal; n = &up->note[0]; if(strncmp(n->msg, "sys:", 4) == 0) { l = strlen(n->msg); if(l > ERRMAX-15) /* " pc=0x12345678\0" */ l = ERRMAX-15; sprint(n->msg+l, " pc=0x%lux", (ulong)ur->pc); } if(n->flag != NUser && (up->notified || up->notify==0)) { if(n->flag == NDebug) pprint("suicide: %s\n", n->msg); qunlock(&up->debug); pexit(n->msg, n->flag!=NDebug); } if(up->notified) { qunlock(&up->debug); splhi(); return 0; } if(!up->notify) { qunlock(&up->debug); pexit(n->msg, n->flag!=NDebug); } sp = ur->usp & ~(BY2V-1); sp -= sizeof(Ureg); if(!okaddr((ulong)up->notify, BY2WD, 0) || !okaddr(sp-ERRMAX-6*BY2WD, sizeof(Ureg)+ERRMAX-6*BY2WD, 1)) { pprint("suicide: bad address or sp in notify\n");print("suicide: bad address or sp in notify\n"); qunlock(&up->debug); pexit("Suicide", 0); } memmove((Ureg*)sp, ur, sizeof(Ureg)); *(Ureg**)(sp-BY2WD) = up->ureg; /* word under Ureg is old up->ureg */ up->ureg = (void*)sp; sp -= 2*BY2WD+ERRMAX; memmove((char*)sp, up->note[0].msg, ERRMAX); sp -= 4*BY2WD; *(ulong*)(sp+3*BY2WD) = sp+4*BY2WD; /* arg 2 is string */ ur->r0 = (ulong)up->ureg; /* arg 1 (R0) is ureg* */ *(ulong*)(sp+2*BY2WD) = (ulong)up->ureg; /* arg 1 0(FP) is ureg* */ *(ulong*)(sp+0*BY2WD) = 0; /* arg 0 is pc */ ur->usp = sp; ur->pc = (ulong)up->notify; up->notified = 1; up->nnote--; memmove(&up->lastnote, &up->note[0], sizeof(Note)); memmove(&up->note[0], &up->note[1], up->nnote*sizeof(Note)); qunlock(&up->debug); splhi(); return 1;}/* * Check that status is OK to return from note. */intvalidstatus(ulong kstatus, ulong ustatus){ if((kstatus & 7) != (ustatus & 7)) return 0; if((ustatus&UMODE) != UMODE) return 0; return 1;}/* * Return user to state before notify() */voidnoted(Ureg *kur, Ureg **urp, ulong arg0){ Ureg *nur; ulong oureg, sp; qlock(&up->debug); if(arg0!=NRSTR && !up->notified) { qunlock(&up->debug); pprint("call to noted() when not notified\n");print("call to noted() when not notified\n"); pexit("Suicide", 0); } up->notified = 0; up->fpstate &= ~FPillegal; nur = up->ureg; oureg = (ulong)nur; if((oureg & (BY2V-1)) || !okaddr((ulong)oureg-BY2WD, BY2WD+sizeof(Ureg), 0)){ pprint("bad ureg in noted or call to noted() when not notified\n");print("bad ureg in noted or call to noted() when not notified\n"); qunlock(&up->debug); pexit("Suicide", 0); } if(!validstatus(kur->status, nur->status)) { qunlock(&up->debug); pprint("bad noted ureg status %lux\n", (ulong)nur->status);print("bad noted ureg status %lux\n", (ulong)nur->status); pexit("Suicide", 0); } memmove(*urp, up->ureg, sizeof(Ureg)); switch(arg0) { case NCONT: case NRSTR: if(!okaddr(nur->pc, BY2WD, 0) || !okaddr(nur->usp, BY2WD, 0)){ pprint("suicide: trap in noted\n");print("suicide: trap in noted\n"); qunlock(&up->debug); pexit("Suicide", 0); } up->ureg = (Ureg*)(*(ulong*)(oureg-BY2WD)); qunlock(&up->debug); splhi(); rfnote(urp); break; case NSAVE: if(!okaddr(nur->pc, BY2WD, 0) || !okaddr(nur->usp, BY2WD, 0)){ pprint("suicide: trap in noted\n");print("suicide: trap in noted\n"); qunlock(&up->debug); pexit("Suicide", 0); } qunlock(&up->debug); sp = oureg-4*BY2WD-ERRMAX; splhi(); (*urp)->sp = sp; ((ulong*)sp)[1] = oureg; /* arg 1 0(FP) is ureg* */ ((ulong*)sp)[0] = 0; /* arg 0 is pc */ (*urp)->r0 = oureg; /* arg 1 is ureg* */ rfnote(urp); break; default: pprint("unknown noted arg 0x%lux\n", arg0);print("unknown noted arg 0x%lux\n", arg0); up->lastnote.flag = NDebug; /* fall through */ case NDFLT: if(up->lastnote.flag == NDebug) pprint("suicide: %s\n", up->lastnote.msg); qunlock(&up->debug); pexit(up->lastnote.msg, up->lastnote.flag!=NDebug); }}#include "../port/systab.h"longsyscall(Ureg *aur){ int i; char *e; long ret; ulong sp; Ureg *ur; ulong scallnr; m->syscall++; up = m->proc; up->insyscall = 1; ur = aur; up->pc = ur->pc; up->dbgreg = aur; ur->type = 5; /* for debugging */ scallnr = ur->r0; up->scallnr = ur->r0; if(scallnr == RFORK && up->fpstate == FPactive){ savefpregs(&up->fpsave); up->fpstate = FPinactive;//print("SR=%lux+", up->fpsave.fpstatus); } spllo(); sp = ur->sp; up->nerrlab = 0; ret = -1; if(!waserror()) { if(scallnr >= nsyscall || systab[scallnr] == nil){ pprint("bad sys call %d pc %lux\n", up->scallnr, (ulong)ur->pc); postnote(up, 1, "sys: bad sys call", NDebug); error(Ebadarg); } if(sp & (BY2WD-1)){ /* XXX too weak? */ pprint("odd sp in sys call pc %lux sp %lux\n", (ulong)ur->pc, (ulong)ur->sp); postnote(up, 1, "sys: odd stack", NDebug); error(Ebadarg); } if(sp<(USTKTOP-BY2PG) || sp>(USTKTOP-sizeof(Sargs))) validaddr(sp, sizeof(Sargs), 0); up->s = *((Sargs*)(sp+2*BY2WD)); up->psstate = sysctab[scallnr]; ret = systab[scallnr](up->s.args); poperror(); }else{ /* failure: save the error buffer for errstr */ e = up->syserrstr; up->syserrstr = up->errstr; up->errstr = e; } if(up->nerrlab){ print("bad errstack [%uld]: %d extra\n", scallnr, up->nerrlab); for(i = 0; i < NERR; i++) print("sp=%lux pc=%lux\n", up->errlab[i].sp, up->errlab[i].pc); panic("error stack"); } up->nerrlab = 0; up->psstate = 0; up->insyscall = 0; if(scallnr == NOTED) /* ugly hack */ noted(ur, &aur, *(ulong*)(sp+2*BY2WD)); /* doesn't return */ if(scallnr!=RFORK && (up->procctl || up->nnote)){ ur->r0 = ret; /* load up for noted() */ if(notify(ur)) return ur->r0; } return ret;}voidforkchild(Proc *p, Ureg *ur){ Ureg *cur; p->sched.sp = (ulong)p->kstack+KSTACK-(4*BY2WD+sizeof(Ureg)); p->sched.pc = (ulong)forkret; cur = (Ureg*)(p->sched.sp+4*BY2WD); memmove(cur, ur, sizeof(Ureg)); /* Things from bottom of syscall we never got to execute */ p->psstate = 0; p->insyscall = 0;}staticvoidlinkproc(void){ spllo(); up->kpfun(up->kparg); pexit("kproc exiting", 0);}voidkprocchild(Proc *p, void (*func)(void*), void *arg){ p->sched.pc = (ulong)linkproc; p->sched.sp = (ulong)p->kstack+KSTACK; p->kpfun = func; p->kparg = arg;}longexecregs(ulong entry, ulong ssize, ulong nargs){ Ureg *ur; ulong *sp; sp = (ulong*)(USTKTOP - ssize); *--sp = nargs; ur = (Ureg*)up->dbgreg; ur->usp = (ulong)sp; ur->pc = entry; return USTKTOP-BY2WD; /* address of user-level clock */}ulonguserpc(void){ Ureg *ur; ur = (Ureg*)up->dbgreg; return ur->pc;}/* This routine must save the values of registers the user is not permitted to write * from devproc and then restore the saved values before returning */voidsetregisters(Ureg *xp, char *pureg, char *uva, int n){ ulong status; status = xp->status; memmove(pureg, uva, n); xp->status = status;}/* Give enough context in the ureg to produce a kernel stack for * a sleeping process */voidsetkernur(Ureg *xp, Proc *p){ xp->pc = p->sched.pc; xp->sp = p->sched.sp; xp->r26 = (ulong)sched;}ulongdbgpc(Proc *p){ Ureg *ur; ur = p->dbgreg; if(ur == 0) return 0; return ur->pc;}voidillegal(Ureg *ur){ switch ((int)ur->a0) { case 0: /* breakpoint */ ur->pc -= 4; fataltrap(ur, "breakpoint"); break; case 1: /* bugchk */ fataltrap(ur, "trap: bugchk"); break; case 2: /* gentrap */ fataltrap(ur, "trap: gentrap"); break; case 3: /* FEN */ fen(ur); break; case 4: /* opDEC */ fataltrap(ur, "trap: illegal instruction"); break; default: panic("illegal illegal %d", (int)ur->a0); break; }}voidfen(Ureg *ur){ if(up){ switch(up->fpstate){ case FPinit: restfpregs(&initfp); up->fpstate = FPactive;//print("EI=%lux+", initfp.fpstatus); return; case FPinactive: restfpregs(&up->fpsave); up->fpstate = FPactive;//print("EIA=%lux+", up->fpsave.fpstatus); return; } } fataltrap(ur, "trap: floating enable"); /* should never happen */}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -