~kris/9p

9hist

f10a2b7ee8a44e780d088eae793289de77b5ba96 — David du Colombier 34 years ago 26a7fc4
Plan 9 from Bell Labs 1992-06-28
M gnot/dat.h => gnot/dat.h +2 -1
@@ 151,6 151,8 @@ struct User
{
	Proc	*p;
	FPsave	fpsave;			/* address of this is known by vdb */
	int	scallnr;		/* sys call number - known by db */
	Sargs	s;			/* address of this is known by db */
	uchar	balusave[64];		/* #include botch */
	int	nerrlab;
	Label	errlab[NERR];


@@ 158,7 160,6 @@ struct User
	char	elem[NAMELEN];		/* last name element from namec */
	Chan	*slash;
	Chan	*dot;
	Sargs	s;
	/*
	 * Rest of structure controlled by devproc.c and friends.
	 * lock(&p->debug) to modify.

M gnot/trap.c => gnot/trap.c +7 -8
@@ 276,7 276,6 @@ syscall(Ureg *aur)
	int i;
	long ret;
	ulong sp;
	ulong r0;
	Ureg *ur;

	u->p->insyscall = 1;


@@ 302,14 301,14 @@ syscall(Ureg *aur)
	if(u->p->procctl)
		procctl(u->p);

	r0 = ur->r0;
	u->scallnr = ur->r0;
	sp = ur->usp;

	u->nerrlab = 0;
	ret = -1;
	if(!waserror()){
		if(r0 >= sizeof systab/sizeof systab[0]){
			pprint("bad sys call number %d pc %lux\n", r0, ur->pc);
		if(u->scallnr >= sizeof systab/sizeof systab[0]){
			pprint("bad sys call number %d pc %lux\n", u->scallnr, ur->pc);
			postnote(u->p, 1, "sys: bad sys call", NDebug);
			error(Ebadarg);
		}


@@ 324,9 323,9 @@ syscall(Ureg *aur)
			validaddr(sp, sizeof(Sargs), 0);

		u->s = *((Sargs*)(sp+BY2WD));
		u->p->psstate = sysctab[r0];
		u->p->psstate = sysctab[u->scallnr];

		ret = (*systab[r0])(u->s.args);
		ret = (*systab[u->scallnr])(u->s.args);
		poperror();
	}



@@ 334,10 333,10 @@ syscall(Ureg *aur)
	u->p->insyscall = 0;
	u->p->psstate = 0;

	if(r0 == NOTED)		/* ugly hack */
	if(u->scallnr == NOTED)		/* ugly hack */
		noted(aur, *(ulong*)(sp+BY2WD));	/* doesn't return */
	splhi();
	if(r0!=RFORK && (u->p->procctl || u->nnote)){
	if(u->scallnr!=RFORK && (u->p->procctl || u->nnote)){
		ur->r0 = ret;
		notify(ur);
	}

M pc/dat.h => pc/dat.h +2 -1
@@ 125,13 125,14 @@ struct User
{
	Proc	*p;
	FPsave	fpsave;			/* address of this is known by vdb */
	int	scallnr;		/* sys call number - known by db */
	Sargs	s;			/* address of this is known by db */
	int	nerrlab;
	Label	errlab[NERR];
	char	error[ERRLEN];
	char	elem[NAMELEN];		/* last name element from namec */
	Chan	*slash;
	Chan	*dot;
	Sargs	s;
	/*
	 * Rest of structure controlled by devproc.c and friends.
	 * lock(&p->debug) to modify.

M pc/trap.c => pc/trap.c +8 -9
@@ 305,7 305,6 @@ userpc(void)
long
syscall(Ureg *ur)
{
	ulong	ax;
	ulong	sp;
	long	ret;
	int	i;


@@ 318,13 317,13 @@ syscall(Ureg *ur)
	/*
	 *  do something about floating point!!!
	 */
	ax = ur->ax;
	u->scallnr = ur->ax;
	sp = ur->usp;
	u->nerrlab = 0;
	ret = -1;
	if(!waserror()){
		if(ax >= sizeof systab/BY2WD){
			pprint("bad sys call number %d pc %lux\n", ax, ur->pc);
		if(u->scallnr >= sizeof systab/BY2WD){
			pprint("bad sys call number %d pc %lux\n", u->scallnr, ur->pc);
			postnote(u->p, 1, "sys: bad sys call", NDebug);
			error(Ebadarg);
		}


@@ 333,13 332,13 @@ syscall(Ureg *ur)
			validaddr(sp, (1+MAXSYSARG)*BY2WD, 0);

		u->s = *((Sargs*)(sp+1*BY2WD));
		u->p->psstate = sysctab[ax];
		u->p->psstate = sysctab[u->scallnr];

		ret = (*systab[ax])(u->s.args);
		ret = (*systab[u->scallnr])(u->s.args);
		poperror();
	}
	if(u->nerrlab){
		print("bad errstack [%d]: %d extra\n", ax, u->nerrlab);
		print("bad errstack [%d]: %d extra\n", u->scallnr, u->nerrlab);
		for(i = 0; i < NERR; i++)
			print("sp=%lux pc=%lux\n", u->errlab[i].sp, u->errlab[i].pc);
		panic("error stack");


@@ 356,11 355,11 @@ syscall(Ureg *ur)
	 */
	ur->ax = ret;

	if(ax == NOTED)
	if(u->scallnr == NOTED)
		noted(ur, *(ulong*)(sp+BY2WD));

	splhi(); /* avoid interrupts during the iret */
	if(ax!=RFORK && (u->p->procctl || u->nnote))
	if(u->scallnr!=RFORK && (u->p->procctl || u->nnote))
		notify(ur);
	return ret;
}

M port/devbit.c => port/devbit.c +140 -40
@@ 55,6 55,14 @@ struct Arena
	int	nbusy;		/* number of busy blocks */
};

typedef struct	BSubfont BSubfont;
struct BSubfont
{
	GSubfont;
	int	ref;		/* number of times this subfont is open */
	ulong	qid[2];		/* unique id used as a cache tag */
};

struct
{
	Ref;


@@ 63,12 71,13 @@ struct
	int	nmap;		/* number allocated */
	GFont	**font;		/* indexed array */
	int	nfont;		/* number allocated */
	GSubfont**subfont;	/* indexed array */
	BSubfont**subfont;	/* indexed array */
	int	nsubfont;	/* number allocated */
	Arena	*arena;		/* array */
	int	narena;		/* number allocated */
	int	lastid;		/* last allocated bitmap id */
	int	lastsubfid;	/* last allocated subfont id */
	int	lastcachesf;	/* last cached subfont id */
	int	lastfid;	/* last allocated font id */
	int	init;		/* freshly opened; init message pending */
	int	rid;		/* read bitmap id */


@@ 84,7 93,7 @@ void	bitcompact(void);
int	bitalloc(Rectangle, int);
void	bitfree(GBitmap*);
void	fontfree(GFont*);
void	subfontfree(GSubfont*);
void	subfontfree(BSubfont*);
void	arenafree(Arena*);
void	bitstring(GBitmap*, Point, GFont*, uchar*, long, Fcode);
void	bitloadchar(GFont*, int, GSubfont*, int);


@@ 160,7 169,7 @@ Dirtab bitdir[]={
};

#define	NBIT	(sizeof bitdir/sizeof(Dirtab))
#define	NINFO	8192
#define	NINFO	8192	/* max chars per subfont; sanity check only */
#define	HDR	3

void


@@ 181,7 190,7 @@ bitreset(void)
	bit.lastfid = -1;
	bit.font = smalloc(DMAP*sizeof(GFont*));
	bit.nfont = DMAP;
	bit.subfont = smalloc(DMAP*sizeof(GSubfont*));
	bit.subfont = smalloc(DMAP*sizeof(BSubfont*));
	bit.nsubfont = DMAP;
	bit.arena = smalloc(DMAP*sizeof(Arena));
	bit.narena = DMAP;


@@ 257,10 266,14 @@ bitopen(Chan *c, int omode)
		b = smalloc(sizeof(GBitmap));
		*b = gscreen;
		bit.map[0] = b;			/* bitmap 0 is screen */
		bit.subfont[0] = defont;	/* subfont 0 is default */
		bit.subfont[0] = (BSubfont*)defont;	/* subfont 0 is default */
		bit.subfont[0]->ref = 1;
		bit.subfont[0]->qid[0] = 0;
		bit.subfont[0]->qid[1] = 0;
		bit.lastid = -1;
		bit.lastfid = -1;
		bit.lastsubfid = -1;
		bit.lastcachesf = -1;
		bit.rid = -1;
		bit.mid = -1;
		bit.init = 0;


@@ 300,7 313,7 @@ void
bitclose(Chan *c)
{
	GBitmap *b, **bp, **ebp;
	GSubfont *s, **sp, **esp;
	BSubfont *s, **sp, **esp;
	GFont *f, **fp, **efp;

	if(c->qid.path!=CHDIR && (c->flag&COPEN)){


@@ 308,7 321,8 @@ bitclose(Chan *c)
		if(--bit.ref == 0){
			/* 0th bitmap, screen, has no special storage */
			bp = bit.map;
			free(*bp);
			if(*bp)
				free(*bp);
			*bp = 0;
			ebp = &bit.map[bit.nmap];
			bp++;


@@ 323,10 337,8 @@ bitclose(Chan *c)
			esp = &bit.subfont[bit.nsubfont];
			for(sp=&bit.subfont[1]; sp<esp; sp++){
				s = *sp;
				if(s){
				if(s)
					subfontfree(s);
					*sp = 0;
				}
			}
			efp = &bit.font[bit.nfont];
			for(fp=bit.font; fp<efp; fp++){


@@ 355,6 367,7 @@ bitread(Chan *c, void *va, long n, ulong offset)
	int off, j;
	Fontchar *i;
	GBitmap *src;
	BSubfont *s;

	if(c->qid.path & CHDIR)
		return devdirread(c, va, n, bitdir, NBIT, devgen);


@@ 365,8 378,9 @@ bitread(Chan *c, void *va, long n, ulong offset)
		 *	'm'		1
		 *	buttons		1
		 * 	point		8
		 * 	msec		4
		 */
		if(n < 10)
		if(n < 14)
			error(Ebadblt);
	    Again:
		while(mouse.changed == 0)


@@ 381,9 395,10 @@ bitread(Chan *c, void *va, long n, ulong offset)
		p[1] = mouse.buttons;
		PLONG(p+2, mouse.xy.x);
		PLONG(p+6, mouse.xy.y);
		PLONG(p+10, TK2MS(MACHP(0)->ticks));
		mouse.changed = 0;
		unlock(&cursor);
		return 10;
		return 14;
	}
	if(c->qid.path == Qscreen){
		if(offset==0){


@@ 492,6 507,32 @@ bitread(Chan *c, void *va, long n, ulong offset)
		PSHORT(p+1, bit.lastsubfid);
		bit.lastsubfid = -1;
		n = 3;
	}else if(bit.lastcachesf > 0){
		/*
		 * allocate subfont:
		 *	'J'		1
		 *	subfont id	2
		 *	font info	3*12
		 *	fontchars	6*(subfont->n+1)
		 */
		p[0] = 'J';
		PSHORT(p+1, bit.lastcachesf);
		s = bit.subfont[bit.lastcachesf];
		if(s==0 || n<3+3*12+6*(s->n+1))
			error(Ebadblt);
		p += 3;
		sprint((char*)p, "%11d %11d %11d ", s->n,
			s->height, s->ascent);
		p += 3*12;
		for(i=s->info,j=0; j<=s->n; j++,i++,p+=6){
			PSHORT(p, i->x);
			p[2] = i->top;
			p[3] = i->bottom;
			p[4] = i->left;
			p[5] = i->width;
		}
		n = 3+3*12+6*(s->n+1);
		bit.lastcachesf = -1;
	}else if(bit.lastfid >= 0){
		/*
		 * allocate font:


@@ 589,7 630,7 @@ bitwrite(Chan *c, void *va, long n, ulong offset)
{
	uchar *p, *q;
	long m, v, miny, maxy, minx, maxx, t, x, y;
	ulong l, nw, ws, rv;
	ulong l, nw, ws, rv, q0, q1;
	int off, isoff, i, j, ok;
	Point pt, pt1, pt2;
	Rectangle rect;


@@ 597,7 638,7 @@ bitwrite(Chan *c, void *va, long n, ulong offset)
	Fcode fc;
	Fontchar *fcp;
	GBitmap *b, *src, *dst, *bp;
	GSubfont *f, **fp;
	BSubfont *f, **fp;
	GFont *ff, **ffp;

	if(c->qid.path == CHDIR)


@@ 745,17 786,16 @@ bitwrite(Chan *c, void *va, long n, ulong offset)

		case 'g':
			/*
			 * free subfont (free bitmap separately)
			 * free subfont
			 *	'g'		1
			 *	id		2
			 */
			if(m < 3)
				error(Ebadblt);
			v = GSHORT(p+1);
			if(v<0 || v>=bit.nsubfont || (f=bit.subfont[v])==0)
			if(v<0 || v>=bit.nsubfont || (f=bit.subfont[v])==0 || f->ref==0)
				error(Ebadfont);
			subfontfree(f);
			bit.subfont[v] = 0;
			m -= 3;
			p += 3;
			break;


@@ 788,6 828,31 @@ bitwrite(Chan *c, void *va, long n, ulong offset)
			p += 1;
			break;

		case 'j':
			/*
			 * subfont cache check
			 *
			 *	'j'		1
			 *	qid		8	BUG: ignored
			 */
			if(m < 9)
				error(Ebadblt);
			q0 = GLONG(p+1);
			q1 = GLONG(p+5);
			for(i=0; i<bit.nsubfont; i++){
				f = bit.subfont[i];
				if(f && f->qid[0]==q0 && f->qid[1]==q1)
					goto sfcachefound;
			}
			error(Esfnotcached);

		sfcachefound:
			f->ref++;
			bit.lastcachesf = i;
			m -= 9;
			p += 9;
			break;

		case 'k':
			/*
			 * allocate subfont


@@ 796,34 861,40 @@ bitwrite(Chan *c, void *va, long n, ulong offset)
			 *	height		1
			 *	ascent		1
			 *	bitmap id	2
			 *	qid		8
			 *	fontchars	6*(n+1)
			 * next read returns allocated font id
			 */
			if(m < 7)
			if(m < 15)
				error(Ebadblt);
			v = GSHORT(p+1);
			if(v<0 || v>NINFO || m<7+6*(v+1))	/* BUG */
			if(v<0 || v>NINFO || m<15+6*(v+1))
				error(Ebadblt);
			for(i=1; i<bit.nsubfont; i++)
				if(bit.subfont[i] == 0)
					goto subfontfound;
			fp = bit.subfont;
			bit.subfont = smalloc((bit.nsubfont+DMAP)*sizeof(GSubfont*));
			memmove(bit.subfont, fp, bit.nsubfont*sizeof(GSubfont*));
			bit.subfont = smalloc((bit.nsubfont+DMAP)*sizeof(BSubfont*));
			memmove(bit.subfont, fp, bit.nsubfont*sizeof(BSubfont*));
			free(fp);
			bit.nsubfont += DMAP;
		subfontfound:
			f = smalloc(sizeof(GSubfont));
			f = smalloc(sizeof(BSubfont));
			bit.subfont[i] = f;
			f->info = smalloc((v+1)*sizeof(Fontchar));
			f->n = v;
			f->height = p[3];
			f->ascent = p[4];
			f->qid[0] = GLONG(p+7);
			f->qid[1] = GLONG(p+11);
			f->ref = 1;
			v = GSHORT(p+5);
			if(v<0 || v>=bit.nmap || (dst=bit.map[v])==0)
				error(Ebadbitmap);
			m -= 7;
			p += 7;
			f->bits = dst;
			bit.map[v] = 0;	/* subfont now owns bitmap */
			m -= 15;
			p += 15;
			fcp = f->info;
			for(j=0; j<=f->n; j++,fcp++){
				fcp->x = GSHORT(p);


@@ 836,7 907,6 @@ bitwrite(Chan *c, void *va, long n, ulong offset)
				m -= 6;
			}
			bit.lastsubfid = i;
			f->bits = dst;
			break;

		case 'l':


@@ 1099,28 1169,36 @@ bitwrite(Chan *c, void *va, long n, ulong offset)
			 * clear font cache and bitmap
			 *	'v'		1
			 *	id		2
			 *	ncache		2
			 *	width		2
			 */
			if(m < 5)
			if(m < 7)
				error(Ebadblt);
			v = GSHORT(p+1);
			if(v<0 || v>=bit.nfont || (ff=bit.font[v])==0)
			t = GSHORT(p+3);
			if(t<0 || v<0 || v>=bit.nfont || (ff=bit.font[v])==0)
				error(Ebadblt);
			/*
			 * memset not necessary but helps avoid
			 * confusion if the cache is mishandled by the
			 * user.
			 */
			memset(ff->cache, 0, (NFCACHE+NFLOOK)*sizeof(ff->cache[0]));
			if(t == ff->ncache)
				memset(ff->cache, 0, t*sizeof(ff->cache[0]));
			else{
				free(ff->cache);
				ff->cache = smalloc(t*sizeof(ff->cache[0]));
				ff->ncache = t;
			}
			if(ff->b)
				bitfree(ff->b);
			ff->width = GSHORT(p+3);
			ff->width = GSHORT(p+5);
			ff->b = 0;
			i = bitalloc(Rect(0, 0, (NFCACHE+NFLOOK)*ff->width, ff->height), ff->ldepth);
			i = bitalloc(Rect(0, 0, t*ff->width, ff->height), ff->ldepth);
			ff->b = bit.map[i];
			bit.map[i] = 0;	/* disconnect it from GBitmap space */
			p += 5;
			m -= 5;
			p += 7;
			m -= 7;
			break;

		case 'w':


@@ 1212,8 1290,8 @@ bitwrite(Chan *c, void *va, long n, ulong offset)
			if(l >= NFCACHE+NFLOOK)
				error(Ebadblt);
			v = GSHORT(p+5);
			if(v<0 || v>=bit.nsubfont || (f=bit.subfont[v])==0)
				error(Ebadblt);
			if(v<0 || v>=bit.nsubfont || (f=bit.subfont[v])==0 || f->ref==0)
				error(Ebadfont);
			nw = GSHORT(p+7);
			if(nw >= f->n)
				error(Ebadblt);


@@ 1267,6 1345,7 @@ bitalloc(Rectangle rect, int ld)
{
	Arena *a, *ea, *na, *aa;
	GBitmap *b, **bp, **ep;
	BSubfont *s;
	ulong l, ws, nw;
	long t;
	int i, try;


@@ 1319,10 1398,31 @@ bitalloc(Rectangle rect, int ld)
	if(a->nwords < HDR+nw)
		a->nwords = HDR+nw;
	a->words = xalloc(a->nwords*sizeof(ulong));
	if(a->words == 0)
	if(a->words){
		a->wfree = a->words;
		a->nbusy = 0;
		goto found;
	}

	/* free unused subfonts, compact, and try again */
	for(i=0; i<bit.nsubfont; i++){
		s = bit.subfont[i];
		if(s && s->ref==0){
			bitfree(s->bits);
			free(s->info);
			free(s);
			bit.subfont[i] = 0;
		}
	}
	bitcompact();
	for(a=bit.arena; a<ea; a++){
		if(a->words == 0)
			continue;
		if(a->wfree+HDR+nw <= a->words+a->nwords)
			goto found;
	}
	if(a == ea)
		error(Enobitstore);
	a->wfree = a->words;
	a->nbusy = 0;
	
    found:
	b = smalloc(sizeof(GBitmap));


@@ 1384,10 1484,10 @@ fontfree(GFont *f)
}

void
subfontfree(GSubfont *s)
subfontfree(BSubfont *s)
{
	free(s->info);
	free(s);
	s->ref--;
	return;
}

void

M port/devproc.c => port/devproc.c +12 -6
@@ 264,15 264,21 @@ procread(Chan *c, void *va, long n, ulong offset)

		if(offset >= KZERO) {
			/* validate physical kernel addresses */
			if(offset < KZERO+conf.npage0*BY2PG){
				if(offset+n > KZERO+conf.npage0*BY2PG)
					n = KZERO+conf.npage0*BY2PG - offset;
			if(offset < (ulong)end) {
				if(offset+n > (ulong)end)
					n = (ulong)end - offset;
				memmove(a, (char*)offset, n);
				return n;
			}
			if(offset < KZERO+conf.base1+conf.npage1*BY2PG){
				if(offset+n > KZERO+conf.base1+conf.npage1*BY2PG)
					n = KZERO+conf.base1+conf.npage1*BY2PG - offset;
			if(offset >= conf.base0 && offset < conf.npage0){
				if(offset+n > conf.npage0)
					n = conf.npage0 - offset;
				memmove(a, (char*)offset, n);
				return n;
			}
			if(offset >= conf.base1 && offset < conf.npage1){
				if(offset+n > conf.npage1)
					n = conf.npage1 - offset;
				memmove(a, (char*)offset, n);
				return n;
			}

M port/error.h => port/error.h +1 -0
@@ 51,4 51,5 @@ extern char Enetunreach[];	/* network unreachable */
extern char Eintr[];		/* interrupted */
extern char Eneedservice[];	/* service required for tcp/udp/il calls */
extern char Enomem[];		/* kernel allocate failed */
extern char Esfnotcached[];	/* subfont not cached */
extern char Egreg[];		/* it's a thermal problem */

M port/page.c => port/page.c +4 -2
@@ 193,11 193,13 @@ duppage(Page *p)				/* Always call with p locked */
{
	Page *np;

	if(p->image == &swapimage)
		return;

	lock(&palloc);

	/* No freelist cache when memory is very low, No dup for swap pages */
	if(palloc.freecount < swapalloc.highwater || 
	   p->image == &swapimage) {
	if(palloc.freecount < swapalloc.highwater) {
		unlock(&palloc);
		uncachepage(p);	
		return;

M port/swap.c => port/swap.c +8 -20
@@ 37,27 37,14 @@ ulong
newswap(void)
{
	char *look;
	int n;

	lock(&swapalloc);
	if(swapalloc.free == 0)
		panic("out of swap space");

	n = swapalloc.top - swapalloc.alloc;
	look = swapalloc.alloc;
	while(n && *look) {
		n--;
		look++;
	}
	if(n == 0) {
		look = swapalloc.swmap;
		while(*look)
			look++;
	}
	if(look == swapalloc.top)
		swapalloc.alloc = swapalloc.swmap;
	else
		swapalloc.alloc = look+1;
	look = memchr(swapalloc.swmap, 0, conf.nswap);
	if(look == 0)
		panic("inconsistant swap");

	*look = 1;
	swapalloc.free--;


@@ 116,7 103,7 @@ loop:

	for(;;) {
		p++;
		if(p > ep)
		if(p >= ep)
			p = proctab(0);

		if(p->state == Dead || p->kp)


@@ 126,6 113,7 @@ loop:
			for(i = 0; i < NSEG; i++) {
				if(!needpages(junk))
					goto loop;

				if(s = p->seg[i]) {
					type = s->type&SG_TYPE;
					switch(type) {


@@ 264,18 252,18 @@ pagepte(int type, Segment *s, Page **pg)
	case SG_STACK:
	case SG_SHARED:
	case SG_SHDATA:
		daddr = newswap();

		lock(outp);
		outp->ref++;
		uncachepage(outp);
		unlock(outp);

		daddr = newswap();
		outp->daddr = daddr;

		/* Enter swap page into cache before segment is unlocked so that
		 * a fault will cause a cache recovery rather than a pagein on a
		 * partially written block.
		 */
		outp->daddr = daddr;
		cachepage(outp, &swapimage);
		*pg = (Page*)(daddr|PG_ONSWAP);


M port/sysproc.c => port/sysproc.c +1 -1
@@ 498,7 498,7 @@ long
sysdeath(ulong *arg)
{
	USED(arg);
	pprint("deprecated system call");
	pprint("deprecated system call\n");
	pexit("Suicide", 0);
	return 0;	/* not reached */
}

M power/conf.h => power/conf.h +0 -1
@@ 15,7 15,6 @@ Conftab conftab[] = {
	{"arp", &conf.arp },
	{"frag", &conf.frag },
	{"cntrlp", &conf.cntrlp },
	{"dkif", &conf.dkif },
	{ 0, 0 },
};


M power/dat.h => power/dat.h +1 -0
@@ 184,6 184,7 @@ struct User
	char	elem[NAMELEN];		/* last name element from namec */
	Chan	*slash;
	Chan	*dot;
	int	scallnr;		/* sys call number */
	Sargs	s;
	/*
	 * Rest of structure controlled by devproc.c and friends.

M power/trap.c => power/trap.c +7 -8
@@ 495,7 495,6 @@ syscall(Ureg *aur)
{
	long ret;
	ulong sp;
	ulong r1;
	Ureg *ur;
	Proc *p;



@@ 518,13 517,13 @@ syscall(Ureg *aur)
	}
	spllo();

	r1 = ur->r1;
	u->scallnr = ur->r1;
	sp = ur->sp;
	u->nerrlab = 0;
	ret = -1;
	if(!waserror()){
		if(r1 >= sizeof systab/sizeof systab[0]) {
			pprint("bad sys call number %d pc %lux\n", r1, ur->pc);
		if(u->scallnr >= sizeof systab/sizeof systab[0]) {
			pprint("bad sys call number %d pc %lux\n", u->scallnr, ur->pc);
			postnote(p, 1, "sys: bad sys call", NDebug);
			error(Ebadarg);
		}


@@ 539,19 538,19 @@ syscall(Ureg *aur)
			validaddr(sp, sizeof(Sargs), 0);

		u->s = *((Sargs*)(sp+BY2WD));
		p->psstate = sysctab[r1];
		p->psstate = sysctab[u->scallnr];

		ret = (*systab[r1])(u->s.args);
		ret = (*systab[u->scallnr])(u->s.args);
	}
	ur->pc += 4;
	u->nerrlab = 0;

	p->psstate = 0;
	p->insyscall = 0;
	if(r1 == NOTED)					/* ugly hack */
	if(u->scallnr == NOTED)					/* ugly hack */
		noted(&aur, *(ulong*)(sp+BY2WD));	/* doesn't return */
	splhi();
	if(r1!=RFORK && (p->procctl || u->nnote)){
	if(u->scallnr!=RFORK && (p->procctl || u->nnote)){
		ur->r1 = ret;				/* load up for noted() */
		if(notify(ur))
			return ur->r1;

M ss/dat.h => ss/dat.h +2 -1
@@ 131,13 131,14 @@ struct User
	Proc	*p;
					/* &fpsave must be 4 mod 8 */
	FPsave	fpsave;			/* address of this is known by db */
	int	scallnr;		/* sys call number - known by db */
	Sargs	s;			/* address of this is known by db */
	int	nerrlab;
	Label	errlab[NERR];
	char	error[ERRLEN];
	char	elem[NAMELEN];		/* last name element from namec */
	Chan	*slash;
	Chan	*dot;
	Sargs	s;
	/*
	 * Rest of structure controlled by devproc.c and friends.
	 * lock(&p->debug) to modify.

M ss/trap.c => ss/trap.c +7 -8
@@ 349,7 349,6 @@ syscall(Ureg *aur)
	int i;
	long ret;
	ulong sp;
	ulong r7;
	Ureg *ur;

	ur = aur;


@@ 368,14 367,14 @@ syscall(Ureg *aur)
	}
	spllo();

	r7 = ur->r7;
	u->scallnr = ur->r7;
	sp = ur->usp;

	u->nerrlab = 0;
	ret = -1;
	if(!waserror()){
		if(r7 >= sizeof systab/BY2WD){
			pprint("bad sys call number %d pc %lux\n", r7, ur->pc);
		if(u->scallnr >= sizeof systab/BY2WD){
			pprint("bad sys call number %d pc %lux\n", u->scallnr, ur->pc);
			postnote(u->p, 1, "sys: bad sys call", NDebug);
			error(Ebadarg);
		}


@@ 390,9 389,9 @@ syscall(Ureg *aur)
			validaddr(sp, sizeof(Sargs), 0);

		u->s = *((Sargs*)(sp+1*BY2WD));
		u->p->psstate = sysctab[r7];
		u->p->psstate = sysctab[u->scallnr];

		ret = (*systab[r7])(u->s.args);
		ret = (*systab[u->scallnr])(u->s.args);
		poperror();
	}



@@ 404,11 403,11 @@ syscall(Ureg *aur)

	u->p->insyscall = 0;
	u->p->psstate = 0;
	if(r7 == NOTED)	/* ugly hack */
	if(u->scallnr == NOTED)	/* ugly hack */
		noted(&aur, *(ulong*)(sp+1*BY2WD));	/* doesn't return */

	splhi();
	if(r7!=RFORK && (u->p->procctl || u->nnote)){
	if(u->scallnr!=RFORK && (u->p->procctl || u->nnote)){
		ur->r7 = ret;				/* load up for noted() */
		if(notify(ur))
			return ur->r7;