ref: babf901b4a508c3ec5d1f89655f10377bbdf9637
dir: /utils/acid/rdebug.c/
#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;
}