shithub: riscv

Download patch

ref: 0b22dfd1f69985aabc5af37dca8a217a1e6e54e9
parent: b4ae96bcb95e76293a81241bf6edebf27cab7e35
author: aiju <[email protected]>
date: Sat Jun 25 12:17:20 EDT 2011

5e: added note support
    added wstat / fwstat / alarm

--- a/sys/src/cmd/5e/5e.c
+++ b/sys/src/cmd/5e/5e.c
@@ -67,6 +67,19 @@
 	abort();
 }
 
+int
+notehandler(void *, char *note)
+{
+	if(strncmp(note, "sys:", 4) == 0)
+		return 0;
+	
+	if(strncmp(note, "emu:", 4) == 0)
+		exits(note);
+
+	addnote(note);
+	return 1;
+}
+
 void
 main(int argc, char **argv)
 {
@@ -90,9 +103,14 @@
 	initproc();
 	if(loadtext(argv[0], argc, argv) < 0)
 		sysfatal("%r");
+	atnotify(notehandler, 1);
 	for(;;) {
 		if(ultraverbose)
 			dump();
 		step();
+		while((P->notein - P->noteout) % NNOTE) {
+			donote(P->notes[P->noteout % NNOTE], 0);
+			ainc(&P->noteout);
+		}
 	}
 }
--- a/sys/src/cmd/5e/dat.h
+++ b/sys/src/cmd/5e/dat.h
@@ -5,10 +5,8 @@
 
 enum {
 	STACKSIZE = 0x100000,
-	
 	NAMEMAX = 27,
-	
-	FDBLOCK = 16,
+	NNOTE = 5,
 	SEGNUM = 8,
 
 	flN = 1<<31,
@@ -26,15 +24,24 @@
 };
 
 struct Process {
-	Segment *S[SEGNUM];
+	Process *prev, *next;	/* linked list (for fs) */
+	int pid;
+	char name[NAMEMAX+1];	/* name for status file */
+	Ref *path;		/* Ref + string data */
+
+	Segment *S[SEGNUM];	/* memory */
 	u32int R[16];		/* general purpose registers / PC (R15) */
 	u32int CPSR;		/* status register */
+
 	char errbuf[ERRMAX];
-	char name[NAMEMAX+1];
-	Ref *path; /* Ref + string data */
-	Fd *fd;
-	int pid;
-	Process *prev, *next;
+	Fd *fd;			/* bitmap of OCEXEC files */
+	
+	/* note handling */
+	u32int notehandler;
+	int innote;
+	jmp_buf notejmp;
+	char notes[ERRMAX][NNOTE];
+	long notein, noteout;
 };
 
 extern void **_privates;
@@ -69,4 +76,3 @@
 #define havesymbols 0
 #define ultraverbose 0
 #define systrace 0
-
--- a/sys/src/cmd/5e/fns.h
+++ b/sys/src/cmd/5e/fns.h
@@ -27,3 +27,6 @@
 void addproc(Process *);
 void remproc(Process *);
 Process *findproc(int);
+void donote(char *, ulong);
+void addnote(char *);
+void dump(void);
--- a/sys/src/cmd/5e/proc.c
+++ b/sys/src/cmd/5e/proc.c
@@ -181,6 +181,7 @@
 		return -1;
 	}
 	copyname(file);
+	P->notehandler = P->innote = P->notein = P->noteout = 0;
 	freesegs();
 	memset(P->R, 0, sizeof(P->R));
 	P->CPSR = 0;
@@ -314,4 +315,67 @@
 	fd->nfds = 0;
 	fd->fds = nil;
 	wunlock(fd);
+}
+
+/* call this from a notehandler if you don't want the front to fall off */
+void
+addnote(char *msg)
+{
+	int new;
+	
+	new = P->notein + 1;
+	if((new - P->noteout) % NNOTE == 0)
+		return;
+
+	strncpy(P->notes[P->notein % NNOTE], msg, ERRMAX - 1);
+	P->notein = new;
+}
+
+/* the following code is not for the weak of heart */
+void
+donote(char *msg, ulong type)
+{
+	int rc;
+	u32int *ureg, *sp, uregp, msgp;
+	char *msgb;
+
+	if(P->notehandler == 0)
+		exits(msg);
+
+	uregp = P->R[13] - 18 * 4;
+	ureg = vaddrnol(uregp, 18 * 4);
+	memcpy(ureg, P->R, 15 * 4);
+	ureg[15] = type;
+	ureg[16] = P->CPSR;
+	ureg[17] = P->R[15];
+	P->R[13] = uregp;
+	msgp = P->R[13] -= strlen(msg) + 1;
+	msgb = vaddrnol(msgp, strlen(msg) + 1);
+	strcpy(msgb, msg);
+	P->R[13] -= 3 * 4;
+	sp = vaddrnol(P->R[13], 3 * 4);
+	sp[0] = 0;
+	sp[2] = msgp;
+	P->R[0] = uregp;
+	P->R[15] = P->notehandler;
+	P->innote = 1;
+	switch(rc = setjmp(P->notejmp) - 1) {
+	case -1:
+		for(;;) {
+			if(ultraverbose)
+				dump();
+			step();
+		}
+	case NDFLT:
+		exits(msg);
+	case NCONT:
+		break;
+	default:
+		sysfatal("unhandled noted argument %d", rc);
+	}
+	P->innote = 0;
+	ureg = vaddrnol(uregp, 18 * 4); /* just to be sure */
+	memcpy(P->R, ureg, 15 * 4);
+	P->CPSR = ureg[16];
+	P->R[15] = ureg[17];
 }
--- a/sys/src/cmd/5e/seg.c
+++ b/sys/src/cmd/5e/seg.c
@@ -94,6 +94,7 @@
 	if(len < 0)
 		len = strlen(targ) + 1;
 	ret = emalloc(len);
+	setmalloctag(ret, getcallerpc(&addr));
 	memcpy(ret, targ, len);
 	segunlock(seg);
 	*copied = 1;
@@ -103,7 +104,7 @@
 void *
 bufifnec(u32int addr, int len, int *buffered)
 {
-	void *targ;
+	void *targ, *v;
 	Segment *seg;
 	
 	targ = vaddr(addr, len, &seg);
@@ -113,7 +114,9 @@
 	}
 	segunlock(seg);
 	*buffered = 1;
-	return emalloc(len);
+	v = emalloc(len);
+	setmalloctag(v, getcallerpc(&addr));
+	return v;
 }
 
 void
@@ -122,8 +125,10 @@
 	void *targ;
 	Segment *seg;
 
-	if(len <= 0)
+	if(len <= 0) {
+		free(data);
 		return;
+	}
 	targ = vaddr(addr, len, &seg);
 	memmove(targ, data, len);
 	segunlock(seg);
--- a/sys/src/cmd/5e/sys.c
+++ b/sys/src/cmd/5e/sys.c
@@ -197,6 +197,46 @@
 }
 
 static void
+syswstat(void)
+{
+	u32int name, edir, nedir;
+	char *namet;
+	void *edirt;
+	int copied, copied2;
+	
+	name = arg(0);
+	namet = copyifnec(name, -1, &copied);
+	edir = arg(1);
+	nedir = arg(2);
+	edirt = copyifnec(edir, nedir, &copied2);
+	if(systrace)
+		fprint(2, "wstat(%#ux=\"%s\", %#ux, %ud)\n", name, namet, edir, nedir);
+	P->R[0] = noteerr(wstat(namet, edirt, nedir), nedir);
+	if(copied)
+		free(namet);
+	if(copied2)
+		free(edirt);
+}
+
+static void
+sysfwstat(void)
+{
+	u32int fd, edir, nedir;
+	void *edirt;
+	int copied;
+	
+	fd = arg(0);
+	edir = arg(1);
+	nedir = arg(2);
+	edirt = copyifnec(edir, nedir, &copied);
+	if(systrace)
+		fprint(2, "fwstat(%d, %#ux, %d)\n", fd, edir, nedir);
+	P->R[0] = noteerr(fwstat(fd, edirt, nedir), nedir);
+	if(copied)
+		free(edirt);
+}
+
+static void
 sysexits(void)
 {
 	if(arg(0) == 0)
@@ -266,9 +306,30 @@
 static void
 sysnotify(void)
 {
+	u32int handler;
+	
+	handler = arg(0);
+	if(systrace)
+		fprint(2, "notify(%#ux)\n", handler);
+	P->notehandler = handler;
+	P->R[0] = 0;
 }
 
 static void
+sysnoted(void)
+{
+	u32int v;
+	
+	v = arg(0);
+	if(systrace)
+		fprint(2, "noted(%d)\n", v);
+	if(P->innote)
+		longjmp(P->notejmp, v + 1);
+	cherrstr("the front fell off");
+	P->R[0] = -1;
+}
+
+static void
 sysrfork(void)
 {
 	u32int flags;
@@ -541,6 +602,17 @@
 		free(filet);
 }
 
+static void
+sysalarm(void)
+{
+	u32int msec;
+	
+	msec = arg(0);
+	if(systrace)
+		fprint(2, "alarm(%d)\n", msec);
+	P->R[0] = alarm(msec);
+}
+
 void
 syscall(void)
 {
@@ -556,10 +628,13 @@
 		[ERRSTR] syserrstr,
 		[STAT] sysstat,
 		[FSTAT] sysfstat,
+		[WSTAT] syswstat,
+		[FWSTAT] sysfwstat,
 		[SEEK] sysseek,
 		[CHDIR] syschdir,
 		[FD2PATH] sysfd2path,
 		[NOTIFY] sysnotify,
+		[NOTED] sysnoted,
 		[RFORK] sysrfork,
 		[EXEC] sysexec,
 		[AWAIT] sysawait,
@@ -571,6 +646,7 @@
 		[DUP] sysdup,
 		[MOUNT] sysmount,
 		[REMOVE] sysremove,
+		[ALARM] sysalarm,
 	};
 	
 	n = P->R[0];
--- a/sys/src/cmd/5e/util.c
+++ b/sys/src/cmd/5e/util.c
@@ -12,6 +12,7 @@
 	v = malloc(size);
 	if(v == nil)
 		sysfatal("%r");
+	setmalloctag(v, getcallerpc(&size));
 	return v;
 }
 
@@ -22,6 +23,7 @@
 	
 	v = emalloc(size);
 	memset(v, 0, size);
+	setmalloctag(v, getcallerpc(&size));
 	return v;
 }
 
@@ -33,5 +35,6 @@
 	v = realloc(old, size);
 	if(v == nil)
 		sysfatal("%r");
+	setrealloctag(v, getcallerpc(&old));
 	return v;
 }