⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 trap.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 2 页
字号:
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 + -