#include <lib9.h>#include <bio.h>#include <ctype.h>#include "mach.h"#define Extern extern#include "acid.h"#include "../../include/rdbg.h" /* * remote kernel debugging */ enum { chatty = 0}; static long myreadn(int, void*, long);static int rproto(int, char*, int); voidremotemap(Map *m, int i){ setmapio(m, i, remget, remput);} /* * send a /proc control message to remote pid, * and await a reply */intsendremote(int pid, char *msg){ int tag; char dbg[RDBMSGLEN]; if(protodebug) fprint(2, "sendremote: pid %d: %s\n", pid, msg); if(strcmp(msg, "startstop") == 0) tag = Tstartstop; else if(strcmp(msg, "waitstop") == 0) tag = Twaitstop; else if(strcmp(msg, "start") == 0) tag = Tstart; else if(strcmp(msg, "stop") == 0) tag = Tstop; else if(strcmp(msg, "kill") == 0) tag = Tkill; else { werrstr("invalid sendremote: %s", msg); return -1; } memset(dbg, 0, sizeof(dbg)); dbg[0] = tag; dbg[1] = pid>>24; dbg[2] = pid>>16; dbg[3] = pid>>8; dbg[4] = pid; if(rproto(remfd, dbg, sizeof(dbg)) < 0) return -1; return 0;} /* * read a line from /proc/<pid>/<file> into buf */intremoteio(int pid, char *file, char *buf, int nb){ char dbg[RDBMSGLEN]; int tag; if(protodebug) fprint(2, "remoteio %d: %s\n", pid, file); memset(buf, 0, nb); if(strcmp(file, "proc") == 0) tag = Tproc; else if(strcmp(file, "status") == 0) tag = Tstatus; else if(strcmp(file, "note") == 0) tag = Trnote; else { werrstr("invalid remoteio: %s", file); return -1; } memset(dbg, 0, sizeof(dbg)); dbg[0] = tag; dbg[1] = pid>>24; dbg[2] = pid>>16; dbg[3] = pid>>8; dbg[4] = pid; if(rproto(remfd, dbg, sizeof(dbg)) < 0) return -1; if(nb > sizeof(dbg)-1) nb = sizeof(dbg)-1; memmove(buf, dbg+1, nb); return strlen(buf);} intremget(struct segment *s, ulong addr, long off, char *buf, int size){ int n, t; char dbg[RDBMSGLEN]; if (protodebug) fprint(2, "remget addr %#lux off %#lux\n", addr, off); for (t = 0; t < size; t += n) { n = size; if(n > 9) n = 9; memset(dbg, 0, sizeof(dbg)); dbg[0] = Tmget; dbg[1] = off>>24; dbg[2] = off>>16; dbg[3] = off>>8; dbg[4] = off; dbg[5] = n; if(rproto(s->fd, dbg, sizeof(dbg)) < 0) { werrstr("can't read address %#lux: %r", addr); return -1; } memmove(buf, dbg+1, n); buf += n; } return t;} intremput(struct segment *s, ulong addr, long off, char *buf, int size){ int n, i, t; char dbg[RDBMSGLEN]; if (protodebug) fprint(2, "remput addr %#lux off %#lux\n", addr, off); for (t = 0; t < size; t += n) { n = size; if(n > 4) n = 4; memset(dbg, 0, sizeof(dbg)); dbg[0] = Tmput; dbg[1] = off>>24; dbg[2] = off>>16; dbg[3] = off>>8; dbg[4] = off; dbg[5] = n; for(i=0; i<n; i++) dbg[6+i] = *buf++; if(rproto(s->fd, dbg, sizeof(dbg)) < 0) { werrstr("can't write address %#lux: %r", addr); return -1; } } return t;} intremcondset(char op, ulong val){ char dbg[RDBMSGLEN]; if (protodebug) fprint(2, "remcondset op %c val: %#lux\n", op, val); memset(dbg, 0, sizeof(dbg)); dbg[0] = Tcondbreak; dbg[1] = val>>24; dbg[2] = val>>16; dbg[3] = val>>8; dbg[4] = val; dbg[5] = op; if(rproto(remfd, dbg, sizeof(dbg)) < 0) { werrstr("can't set condbreak: %c %#lux: %r", op, val); return -1; } return 0;} intremcondstartstop(int pid){ char dbg[RDBMSGLEN]; if (protodebug) fprint(2, "remcondstartstop pid %d\n", pid); memset(dbg, 0, sizeof(dbg)); dbg[0] = Tstartstop; dbg[1] = pid>>24; dbg[2] = pid>>16; dbg[3] = pid>>8; dbg[4] = pid; if(rproto(remfd, dbg, sizeof(dbg)) < 0) { werrstr("can't send Tstartstop"); return -1; } return dbg[1];} static intrproto(int fd, char *buf, int nb){ int tag; if (protodebug) { int i; print("rproto remote write fd %d bytes: %d\n", fd, nb); for (i=0; i < nb; i++) { print(" %2.2ux", buf[i]&0xFF); } print("\n"); } tag = buf[0]; if(remote_write(fd, buf, nb) != nb || myreadn(fd, buf, nb) != nb){ /* could set alarm */ werrstr("remote i/o: %r"); return -1; } if(buf[0] == Rerr){ buf[nb-1] = 0; werrstr("remote err: %s", buf+1); return -1; } if(buf[0] != tag+1) { werrstr("remote proto err: %.2ux", buf[0]&0xff); return -1; } if(chatty) { int i; fprint(2, "remote [%d]: ", nb); for(i=0; i<nb; i++) fprint(2, " %.2ux", buf[i]&0xff); fprint(2, "\n"); } return nb;} /* * this should probably be in lib9 as readn */static longmyreadn(int f, void *av, long n){ char *a; long m, t; if (protodebug) { print("remote read fd %d bytes: %ld", f, n); } a = av; t = 0; while(t < n){ m = remote_read(f, a+t, n-t); if(m < 0){ if(t == 0) return m; break; } if (protodebug) { print(" rtn: %ld\n", m); if (m) { int i; for (i=0; i < m; i++) print(" %2.2ux", a[i+t]&0xFF); print("\n"); } } t += m; } return t;}
#include <lib9.h>
#include <bio.h>
#include <ctype.h>
#include "mach.h"
#define Extern extern
#include "acid.h"
#include "../../include/rdbg.h"
/*
* remote kernel debugging
*/
enum {
chatty = 0
};
static long myreadn(int, void*, long);
static int rproto(int, char*, int);
void
remotemap(Map *m, int i)
{
setmapio(m, i, remget, remput);
}
/*
* send a /proc control message to remote pid,
* and await a reply
*/
int
sendremote(int pid, char *msg)
{
int tag;
char dbg[RDBMSGLEN];
if(protodebug)
fprint(2, "sendremote: pid %d: %s\n", pid, msg);
if(strcmp(msg, "startstop") == 0)
tag = Tstartstop;
else if(strcmp(msg, "waitstop") == 0)
tag = Twaitstop;
else if(strcmp(msg, "start") == 0)
tag = Tstart;
else if(strcmp(msg, "stop") == 0)
tag = Tstop;
else if(strcmp(msg, "kill") == 0)
tag = Tkill;
else {
werrstr("invalid sendremote: %s", msg);
return -1;
}
memset(dbg, 0, sizeof(dbg));
dbg[0] = tag;
dbg[1] = pid>>24;
dbg[2] = pid>>16;
dbg[3] = pid>>8;
dbg[4] = pid;
if(rproto(remfd, dbg, sizeof(dbg)) < 0)
return -1;
return 0;
}
/*
* read a line from /proc/<pid>/<file> into buf
*/
int
remoteio(int pid, char *file, char *buf, int nb)
{
char dbg[RDBMSGLEN];
int tag;
if(protodebug)
fprint(2, "remoteio %d: %s\n", pid, file);
memset(buf, 0, nb);
if(strcmp(file, "proc") == 0)
tag = Tproc;
else if(strcmp(file, "status") == 0)
tag = Tstatus;
else if(strcmp(file, "note") == 0)
tag = Trnote;
else {
werrstr("invalid remoteio: %s", file);
return -1;
}
memset(dbg, 0, sizeof(dbg));
dbg[0] = tag;
dbg[1] = pid>>24;
dbg[2] = pid>>16;
dbg[3] = pid>>8;
dbg[4] = pid;
if(rproto(remfd, dbg, sizeof(dbg)) < 0)
return -1;
if(nb > sizeof(dbg)-1)
nb = sizeof(dbg)-1;
memmove(buf, dbg+1, nb);
return strlen(buf);
}
int
remget(struct segment *s, ulong addr, long off, char *buf, int size)
{
int n, t;
char dbg[RDBMSGLEN];
if (protodebug)
fprint(2, "remget addr %#lux off %#lux\n", addr, off);
for (t = 0; t < size; t += n) {
n = size;
if(n > 9)
n = 9;
memset(dbg, 0, sizeof(dbg));
dbg[0] = Tmget;
dbg[1] = off>>24;
dbg[2] = off>>16;
dbg[3] = off>>8;
dbg[4] = off;
dbg[5] = n;
if(rproto(s->fd, dbg, sizeof(dbg)) < 0) {
werrstr("can't read address %#lux: %r", addr);
return -1;
}
memmove(buf, dbg+1, n);
buf += n;
}
return t;
}
int
remput(struct segment *s, ulong addr, long off, char *buf, int size)
{
int n, i, t;
char dbg[RDBMSGLEN];
if (protodebug)
fprint(2, "remput addr %#lux off %#lux\n", addr, off);
for (t = 0; t < size; t += n) {
n = size;
if(n > 4)
n = 4;
memset(dbg, 0, sizeof(dbg));
dbg[0] = Tmput;
dbg[1] = off>>24;
dbg[2] = off>>16;
dbg[3] = off>>8;
dbg[4] = off;
dbg[5] = n;
for(i=0; i<n; i++)
dbg[6+i] = *buf++;
if(rproto(s->fd, dbg, sizeof(dbg)) < 0) {
werrstr("can't write address %#lux: %r", addr);
return -1;
}
}
return t;
}
int
remcondset(char op, ulong val)
{
char dbg[RDBMSGLEN];
if (protodebug)
fprint(2, "remcondset op %c val: %#lux\n", op, val);
memset(dbg, 0, sizeof(dbg));
dbg[0] = Tcondbreak;
dbg[1] = val>>24;
dbg[2] = val>>16;
dbg[3] = val>>8;
dbg[4] = val;
dbg[5] = op;
if(rproto(remfd, dbg, sizeof(dbg)) < 0) {
werrstr("can't set condbreak: %c %#lux: %r", op, val);
return -1;
}
return 0;
}
int
remcondstartstop(int pid)
{
char dbg[RDBMSGLEN];
if (protodebug)
fprint(2, "remcondstartstop pid %d\n", pid);
memset(dbg, 0, sizeof(dbg));
dbg[0] = Tstartstop;
dbg[1] = pid>>24;
dbg[2] = pid>>16;
dbg[3] = pid>>8;
dbg[4] = pid;
if(rproto(remfd, dbg, sizeof(dbg)) < 0) {
werrstr("can't send Tstartstop");
return -1;
}
return dbg[1];
}
static int
rproto(int fd, char *buf, int nb)
{
int tag;
if (protodebug) {
int i;
print("rproto remote write fd %d bytes: %d\n", fd, nb);
for (i=0; i < nb; i++) {
print(" %2.2ux", buf[i]&0xFF);
}
print("\n");
}
tag = buf[0];
if(remote_write(fd, buf, nb) != nb ||
myreadn(fd, buf, nb) != nb){ /* could set alarm */
werrstr("remote i/o: %r");
return -1;
}
if(buf[0] == Rerr){
buf[nb-1] = 0;
werrstr("remote err: %s", buf+1);
return -1;
}
if(buf[0] != tag+1) {
werrstr("remote proto err: %.2ux", buf[0]&0xff);
return -1;
}
if(chatty) {
int i;
fprint(2, "remote [%d]: ", nb);
for(i=0; i<nb; i++)
fprint(2, " %.2ux", buf[i]&0xff);
fprint(2, "\n");
}
return nb;
}
/*
* this should probably be in lib9 as readn
*/
static long
myreadn(int f, void *av, long n)
{
char *a;
long m, t;
if (protodebug) {
print("remote read fd %d bytes: %ld", f, n);
}
a = av;
t = 0;
while(t < n){
m = remote_read(f, a+t, n-t);
if(m < 0){
if(t == 0)
return m;
break;
}
if (protodebug) {
print(" rtn: %ld\n", m);
if (m) {
int i;
for (i=0; i < m; i++)
print(" %2.2ux", a[i+t]&0xFF);
print("\n");
}
}
t += m;
}
return t;
}