xref: /inferno-os/utils/acid/rdebug.c (revision 791d91a843b378fddfb985b72dab7b5b35da5225)
174a4d8c2SCharles.Forsyth #include <lib9.h>
274a4d8c2SCharles.Forsyth #include <bio.h>
374a4d8c2SCharles.Forsyth #include <ctype.h>
474a4d8c2SCharles.Forsyth #include "mach.h"
574a4d8c2SCharles.Forsyth #define Extern extern
674a4d8c2SCharles.Forsyth #include "acid.h"
774a4d8c2SCharles.Forsyth #include "../../include/rdbg.h"
874a4d8c2SCharles.Forsyth 
974a4d8c2SCharles.Forsyth /*
1074a4d8c2SCharles.Forsyth  * remote kernel debugging
1174a4d8c2SCharles.Forsyth  */
1274a4d8c2SCharles.Forsyth 
1374a4d8c2SCharles.Forsyth enum {
1474a4d8c2SCharles.Forsyth 	chatty = 0
1574a4d8c2SCharles.Forsyth };
1674a4d8c2SCharles.Forsyth 
1774a4d8c2SCharles.Forsyth static	long	myreadn(int, void*, long);
1874a4d8c2SCharles.Forsyth static	int	rproto(int, char*, int);
1974a4d8c2SCharles.Forsyth 
2074a4d8c2SCharles.Forsyth void
remotemap(Map * m,int i)2174a4d8c2SCharles.Forsyth remotemap(Map *m, int i)
2274a4d8c2SCharles.Forsyth {
2374a4d8c2SCharles.Forsyth 	setmapio(m, i, remget, remput);
2474a4d8c2SCharles.Forsyth }
2574a4d8c2SCharles.Forsyth 
2674a4d8c2SCharles.Forsyth /*
2774a4d8c2SCharles.Forsyth  * send a /proc control message to remote pid,
2874a4d8c2SCharles.Forsyth  * and await a reply
2974a4d8c2SCharles.Forsyth  */
3074a4d8c2SCharles.Forsyth int
sendremote(int pid,char * msg)3174a4d8c2SCharles.Forsyth sendremote(int pid, char *msg)
3274a4d8c2SCharles.Forsyth {
3374a4d8c2SCharles.Forsyth 	int tag;
3474a4d8c2SCharles.Forsyth 	char dbg[RDBMSGLEN];
3574a4d8c2SCharles.Forsyth 
3674a4d8c2SCharles.Forsyth 	if(protodebug)
3774a4d8c2SCharles.Forsyth 		fprint(2, "sendremote: pid %d: %s\n", pid, msg);
3874a4d8c2SCharles.Forsyth 	if(strcmp(msg, "startstop") == 0)
3974a4d8c2SCharles.Forsyth 		tag = Tstartstop;
4074a4d8c2SCharles.Forsyth 	else if(strcmp(msg, "waitstop") == 0)
4174a4d8c2SCharles.Forsyth 		tag = Twaitstop;
4274a4d8c2SCharles.Forsyth 	else if(strcmp(msg, "start") == 0)
4374a4d8c2SCharles.Forsyth 		tag = Tstart;
4474a4d8c2SCharles.Forsyth 	else if(strcmp(msg, "stop") == 0)
4574a4d8c2SCharles.Forsyth 		tag = Tstop;
4674a4d8c2SCharles.Forsyth 	else if(strcmp(msg, "kill") == 0)
4774a4d8c2SCharles.Forsyth 		tag = Tkill;
4874a4d8c2SCharles.Forsyth 	else {
4974a4d8c2SCharles.Forsyth 		werrstr("invalid sendremote: %s", msg);
5074a4d8c2SCharles.Forsyth 		return -1;
5174a4d8c2SCharles.Forsyth 	}
5274a4d8c2SCharles.Forsyth 	memset(dbg, 0, sizeof(dbg));
5374a4d8c2SCharles.Forsyth 	dbg[0] = tag;
5474a4d8c2SCharles.Forsyth 	dbg[1] = pid>>24;
5574a4d8c2SCharles.Forsyth 	dbg[2] = pid>>16;
5674a4d8c2SCharles.Forsyth 	dbg[3] = pid>>8;
5774a4d8c2SCharles.Forsyth 	dbg[4] = pid;
5874a4d8c2SCharles.Forsyth 	if(rproto(remfd, dbg, sizeof(dbg)) < 0)
5974a4d8c2SCharles.Forsyth 		return -1;
6074a4d8c2SCharles.Forsyth 	return 0;
6174a4d8c2SCharles.Forsyth }
6274a4d8c2SCharles.Forsyth 
6374a4d8c2SCharles.Forsyth /*
6474a4d8c2SCharles.Forsyth  * read a line from /proc/<pid>/<file> into buf
6574a4d8c2SCharles.Forsyth  */
6674a4d8c2SCharles.Forsyth int
remoteio(int pid,char * file,char * buf,int nb)6774a4d8c2SCharles.Forsyth remoteio(int pid, char *file, char *buf, int nb)
6874a4d8c2SCharles.Forsyth {
6974a4d8c2SCharles.Forsyth 	char dbg[RDBMSGLEN];
7074a4d8c2SCharles.Forsyth 	int tag;
7174a4d8c2SCharles.Forsyth 
7274a4d8c2SCharles.Forsyth 	if(protodebug)
7374a4d8c2SCharles.Forsyth 		fprint(2, "remoteio %d: %s\n", pid, file);
74*791d91a8Sforsyth 	memset(buf, 0, nb);
7574a4d8c2SCharles.Forsyth 	if(strcmp(file, "proc") == 0)
7674a4d8c2SCharles.Forsyth 		tag = Tproc;
7774a4d8c2SCharles.Forsyth 	else if(strcmp(file, "status") == 0)
7874a4d8c2SCharles.Forsyth 		tag = Tstatus;
7974a4d8c2SCharles.Forsyth 	else if(strcmp(file, "note") == 0)
8074a4d8c2SCharles.Forsyth 		tag = Trnote;
8174a4d8c2SCharles.Forsyth 	else {
8274a4d8c2SCharles.Forsyth 		werrstr("invalid remoteio: %s", file);
8374a4d8c2SCharles.Forsyth 		return -1;
8474a4d8c2SCharles.Forsyth 	}
8574a4d8c2SCharles.Forsyth 	memset(dbg, 0, sizeof(dbg));
8674a4d8c2SCharles.Forsyth 	dbg[0] = tag;
8774a4d8c2SCharles.Forsyth 	dbg[1] = pid>>24;
8874a4d8c2SCharles.Forsyth 	dbg[2] = pid>>16;
8974a4d8c2SCharles.Forsyth 	dbg[3] = pid>>8;
9074a4d8c2SCharles.Forsyth 	dbg[4] = pid;
9174a4d8c2SCharles.Forsyth 	if(rproto(remfd, dbg, sizeof(dbg)) < 0)
9274a4d8c2SCharles.Forsyth 		return -1;
9374a4d8c2SCharles.Forsyth 	if(nb > sizeof(dbg)-1)
9474a4d8c2SCharles.Forsyth 		nb = sizeof(dbg)-1;
9574a4d8c2SCharles.Forsyth 	memmove(buf, dbg+1, nb);
9674a4d8c2SCharles.Forsyth 	return strlen(buf);
9774a4d8c2SCharles.Forsyth }
9874a4d8c2SCharles.Forsyth 
9974a4d8c2SCharles.Forsyth int
remget(struct segment * s,ulong addr,long off,char * buf,int size)10074a4d8c2SCharles.Forsyth remget(struct segment *s, ulong addr, long off, char *buf, int size)
10174a4d8c2SCharles.Forsyth {
10274a4d8c2SCharles.Forsyth 	int n, t;
10374a4d8c2SCharles.Forsyth 	char dbg[RDBMSGLEN];
10474a4d8c2SCharles.Forsyth 
10574a4d8c2SCharles.Forsyth 	if (protodebug)
10674a4d8c2SCharles.Forsyth 		fprint(2, "remget addr %#lux off %#lux\n", addr, off);
10774a4d8c2SCharles.Forsyth 	for (t = 0; t < size; t += n) {
10874a4d8c2SCharles.Forsyth 		n = size;
10974a4d8c2SCharles.Forsyth 		if(n > 9)
11074a4d8c2SCharles.Forsyth 			n = 9;
11174a4d8c2SCharles.Forsyth 		memset(dbg, 0, sizeof(dbg));
11274a4d8c2SCharles.Forsyth 		dbg[0] = Tmget;
11374a4d8c2SCharles.Forsyth 		dbg[1] = off>>24;
11474a4d8c2SCharles.Forsyth 		dbg[2] = off>>16;
11574a4d8c2SCharles.Forsyth 		dbg[3] = off>>8;
11674a4d8c2SCharles.Forsyth 		dbg[4] = off;
11774a4d8c2SCharles.Forsyth 		dbg[5] = n;
11874a4d8c2SCharles.Forsyth 		if(rproto(s->fd, dbg, sizeof(dbg)) < 0) {
11974a4d8c2SCharles.Forsyth 			werrstr("can't read address %#lux: %r", addr);
12074a4d8c2SCharles.Forsyth 			return -1;
12174a4d8c2SCharles.Forsyth 		}
12274a4d8c2SCharles.Forsyth 		memmove(buf, dbg+1, n);
12374a4d8c2SCharles.Forsyth 		buf += n;
12474a4d8c2SCharles.Forsyth 	}
12574a4d8c2SCharles.Forsyth 	return t;
12674a4d8c2SCharles.Forsyth }
12774a4d8c2SCharles.Forsyth 
12874a4d8c2SCharles.Forsyth int
remput(struct segment * s,ulong addr,long off,char * buf,int size)12974a4d8c2SCharles.Forsyth remput(struct segment *s, ulong addr, long off, char *buf, int size)
13074a4d8c2SCharles.Forsyth {
13174a4d8c2SCharles.Forsyth 	int n, i, t;
13274a4d8c2SCharles.Forsyth 	char dbg[RDBMSGLEN];
13374a4d8c2SCharles.Forsyth 
13474a4d8c2SCharles.Forsyth 	if (protodebug)
13574a4d8c2SCharles.Forsyth 		fprint(2, "remput addr %#lux off %#lux\n", addr, off);
13674a4d8c2SCharles.Forsyth 	for (t = 0; t < size; t += n) {
13774a4d8c2SCharles.Forsyth 		n = size;
13874a4d8c2SCharles.Forsyth 		if(n > 4)
13974a4d8c2SCharles.Forsyth 			n = 4;
14074a4d8c2SCharles.Forsyth 		memset(dbg, 0, sizeof(dbg));
14174a4d8c2SCharles.Forsyth 		dbg[0] = Tmput;
14274a4d8c2SCharles.Forsyth 		dbg[1] = off>>24;
14374a4d8c2SCharles.Forsyth 		dbg[2] = off>>16;
14474a4d8c2SCharles.Forsyth 		dbg[3] = off>>8;
14574a4d8c2SCharles.Forsyth 		dbg[4] = off;
14674a4d8c2SCharles.Forsyth 		dbg[5] = n;
14774a4d8c2SCharles.Forsyth 		for(i=0; i<n; i++)
14874a4d8c2SCharles.Forsyth 			dbg[6+i] = *buf++;
14974a4d8c2SCharles.Forsyth 		if(rproto(s->fd, dbg, sizeof(dbg)) < 0) {
15074a4d8c2SCharles.Forsyth 			werrstr("can't write address %#lux: %r", addr);
15174a4d8c2SCharles.Forsyth 			return -1;
15274a4d8c2SCharles.Forsyth 		}
15374a4d8c2SCharles.Forsyth 	}
15474a4d8c2SCharles.Forsyth 	return t;
15574a4d8c2SCharles.Forsyth }
15674a4d8c2SCharles.Forsyth 
15774a4d8c2SCharles.Forsyth int
remcondset(char op,ulong val)15874a4d8c2SCharles.Forsyth remcondset(char op, ulong val)
15974a4d8c2SCharles.Forsyth {
16074a4d8c2SCharles.Forsyth 	char dbg[RDBMSGLEN];
16174a4d8c2SCharles.Forsyth 
16274a4d8c2SCharles.Forsyth 	if (protodebug)
16374a4d8c2SCharles.Forsyth 		fprint(2, "remcondset op %c val: %#lux\n", op, val);
16474a4d8c2SCharles.Forsyth 	memset(dbg, 0, sizeof(dbg));
16574a4d8c2SCharles.Forsyth 
16674a4d8c2SCharles.Forsyth 	dbg[0] = Tcondbreak;
16774a4d8c2SCharles.Forsyth 	dbg[1] = val>>24;
16874a4d8c2SCharles.Forsyth 	dbg[2] = val>>16;
16974a4d8c2SCharles.Forsyth 	dbg[3] = val>>8;
17074a4d8c2SCharles.Forsyth 	dbg[4] = val;
17174a4d8c2SCharles.Forsyth 	dbg[5] = op;
17274a4d8c2SCharles.Forsyth 	if(rproto(remfd, dbg, sizeof(dbg)) < 0) {
17374a4d8c2SCharles.Forsyth 		werrstr("can't set condbreak: %c %#lux: %r", op, val);
17474a4d8c2SCharles.Forsyth 		return -1;
17574a4d8c2SCharles.Forsyth 	}
17674a4d8c2SCharles.Forsyth 	return 0;
17774a4d8c2SCharles.Forsyth }
17874a4d8c2SCharles.Forsyth 
17974a4d8c2SCharles.Forsyth int
remcondstartstop(int pid)18074a4d8c2SCharles.Forsyth remcondstartstop(int pid)
18174a4d8c2SCharles.Forsyth {
18274a4d8c2SCharles.Forsyth 	char dbg[RDBMSGLEN];
18374a4d8c2SCharles.Forsyth 
18474a4d8c2SCharles.Forsyth 	if (protodebug)
18574a4d8c2SCharles.Forsyth 		fprint(2, "remcondstartstop pid %d\n", pid);
18674a4d8c2SCharles.Forsyth 	memset(dbg, 0, sizeof(dbg));
18774a4d8c2SCharles.Forsyth 
18874a4d8c2SCharles.Forsyth 	dbg[0] = Tstartstop;
18974a4d8c2SCharles.Forsyth 	dbg[1] = pid>>24;
19074a4d8c2SCharles.Forsyth 	dbg[2] = pid>>16;
19174a4d8c2SCharles.Forsyth 	dbg[3] = pid>>8;
19274a4d8c2SCharles.Forsyth 	dbg[4] = pid;
19374a4d8c2SCharles.Forsyth 
19474a4d8c2SCharles.Forsyth 	if(rproto(remfd, dbg, sizeof(dbg)) < 0) {
19574a4d8c2SCharles.Forsyth 		werrstr("can't send Tstartstop");
19674a4d8c2SCharles.Forsyth 		return -1;
19774a4d8c2SCharles.Forsyth 	}
19874a4d8c2SCharles.Forsyth 
19974a4d8c2SCharles.Forsyth 	return dbg[1];
20074a4d8c2SCharles.Forsyth }
20174a4d8c2SCharles.Forsyth 
20274a4d8c2SCharles.Forsyth static int
rproto(int fd,char * buf,int nb)20374a4d8c2SCharles.Forsyth rproto(int fd, char *buf, int nb)
20474a4d8c2SCharles.Forsyth {
20574a4d8c2SCharles.Forsyth 	int tag;
20674a4d8c2SCharles.Forsyth 
20774a4d8c2SCharles.Forsyth 	if (protodebug) {
20874a4d8c2SCharles.Forsyth 		int i;
20974a4d8c2SCharles.Forsyth 		print("rproto remote write fd %d bytes: %d\n", fd, nb);
21074a4d8c2SCharles.Forsyth 		for (i=0; i < nb; i++) {
21174a4d8c2SCharles.Forsyth 			print(" %2.2ux", buf[i]&0xFF);
21274a4d8c2SCharles.Forsyth 		}
21374a4d8c2SCharles.Forsyth 		print("\n");
21474a4d8c2SCharles.Forsyth 	}
21574a4d8c2SCharles.Forsyth 	tag = buf[0];
21674a4d8c2SCharles.Forsyth 	if(remote_write(fd, buf, nb) != nb ||
21774a4d8c2SCharles.Forsyth 	    myreadn(fd, buf, nb) != nb){	/* could set alarm */
21874a4d8c2SCharles.Forsyth 		werrstr("remote i/o: %r");
21974a4d8c2SCharles.Forsyth 		return -1;
22074a4d8c2SCharles.Forsyth 	}
22174a4d8c2SCharles.Forsyth 	if(buf[0] == Rerr){
22274a4d8c2SCharles.Forsyth 		buf[nb-1] = 0;
22374a4d8c2SCharles.Forsyth 		werrstr("remote err: %s", buf+1);
22474a4d8c2SCharles.Forsyth 		return -1;
22574a4d8c2SCharles.Forsyth 	}
22674a4d8c2SCharles.Forsyth 	if(buf[0] != tag+1) {
22774a4d8c2SCharles.Forsyth 		werrstr("remote proto err: %.2ux", buf[0]&0xff);
22874a4d8c2SCharles.Forsyth 		return -1;
22974a4d8c2SCharles.Forsyth 	}
23074a4d8c2SCharles.Forsyth 	if(chatty) {
23174a4d8c2SCharles.Forsyth 		int i;
23274a4d8c2SCharles.Forsyth 		fprint(2, "remote [%d]: ", nb);
23374a4d8c2SCharles.Forsyth 		for(i=0; i<nb; i++)
23474a4d8c2SCharles.Forsyth 			fprint(2, " %.2ux", buf[i]&0xff);
23574a4d8c2SCharles.Forsyth 		fprint(2, "\n");
23674a4d8c2SCharles.Forsyth 	}
23774a4d8c2SCharles.Forsyth 	return nb;
23874a4d8c2SCharles.Forsyth }
23974a4d8c2SCharles.Forsyth 
24074a4d8c2SCharles.Forsyth /*
24174a4d8c2SCharles.Forsyth  * this should probably be in lib9 as readn
24274a4d8c2SCharles.Forsyth  */
24374a4d8c2SCharles.Forsyth static long
myreadn(int f,void * av,long n)24474a4d8c2SCharles.Forsyth myreadn(int f, void *av, long n)
24574a4d8c2SCharles.Forsyth {
24674a4d8c2SCharles.Forsyth 	char *a;
24774a4d8c2SCharles.Forsyth 	long m, t;
24874a4d8c2SCharles.Forsyth 
24974a4d8c2SCharles.Forsyth 	if (protodebug) {
25074a4d8c2SCharles.Forsyth 		print("remote read fd %d bytes: %ld", f, n);
25174a4d8c2SCharles.Forsyth 	}
25274a4d8c2SCharles.Forsyth 	a = av;
25374a4d8c2SCharles.Forsyth 	t = 0;
25474a4d8c2SCharles.Forsyth 	while(t < n){
25574a4d8c2SCharles.Forsyth 		m = remote_read(f, a+t, n-t);
25674a4d8c2SCharles.Forsyth 		if(m < 0){
25774a4d8c2SCharles.Forsyth 			if(t == 0)
25874a4d8c2SCharles.Forsyth 				return m;
25974a4d8c2SCharles.Forsyth 			break;
26074a4d8c2SCharles.Forsyth 		}
26174a4d8c2SCharles.Forsyth 		if (protodebug) {
26274a4d8c2SCharles.Forsyth 			print(" rtn: %ld\n", m);
26374a4d8c2SCharles.Forsyth 			if (m) {
26474a4d8c2SCharles.Forsyth 				int i;
26574a4d8c2SCharles.Forsyth 
26674a4d8c2SCharles.Forsyth 				for (i=0; i < m; i++)
26774a4d8c2SCharles.Forsyth 					print(" %2.2ux", a[i+t]&0xFF);
26874a4d8c2SCharles.Forsyth 				print("\n");
26974a4d8c2SCharles.Forsyth 			}
27074a4d8c2SCharles.Forsyth 		}
27174a4d8c2SCharles.Forsyth 		t += m;
27274a4d8c2SCharles.Forsyth 	}
27374a4d8c2SCharles.Forsyth 	return t;
27474a4d8c2SCharles.Forsyth }
275