1 #include <lib9.h> 2 #include <bio.h> 3 #include <ctype.h> 4 #include "mach.h" 5 #define Extern extern 6 #include "acid.h" 7 #include "../../include/rdbg.h" 8 9 /* 10 * remote kernel debugging 11 */ 12 13 enum { 14 chatty = 0 15 }; 16 17 static long myreadn(int, void*, long); 18 static int rproto(int, char*, int); 19 20 void 21 remotemap(Map *m, int i) 22 { 23 setmapio(m, i, remget, remput); 24 } 25 26 /* 27 * send a /proc control message to remote pid, 28 * and await a reply 29 */ 30 int 31 sendremote(int pid, char *msg) 32 { 33 int tag; 34 char dbg[RDBMSGLEN]; 35 36 if(protodebug) 37 fprint(2, "sendremote: pid %d: %s\n", pid, msg); 38 if(strcmp(msg, "startstop") == 0) 39 tag = Tstartstop; 40 else if(strcmp(msg, "waitstop") == 0) 41 tag = Twaitstop; 42 else if(strcmp(msg, "start") == 0) 43 tag = Tstart; 44 else if(strcmp(msg, "stop") == 0) 45 tag = Tstop; 46 else if(strcmp(msg, "kill") == 0) 47 tag = Tkill; 48 else { 49 werrstr("invalid sendremote: %s", msg); 50 return -1; 51 } 52 memset(dbg, 0, sizeof(dbg)); 53 dbg[0] = tag; 54 dbg[1] = pid>>24; 55 dbg[2] = pid>>16; 56 dbg[3] = pid>>8; 57 dbg[4] = pid; 58 if(rproto(remfd, dbg, sizeof(dbg)) < 0) 59 return -1; 60 return 0; 61 } 62 63 /* 64 * read a line from /proc/<pid>/<file> into buf 65 */ 66 int 67 remoteio(int pid, char *file, char *buf, int nb) 68 { 69 char dbg[RDBMSGLEN]; 70 int tag; 71 72 if(protodebug) 73 fprint(2, "remoteio %d: %s\n", pid, file); 74 memset(buf, nb, 0); 75 if(strcmp(file, "proc") == 0) 76 tag = Tproc; 77 else if(strcmp(file, "status") == 0) 78 tag = Tstatus; 79 else if(strcmp(file, "note") == 0) 80 tag = Trnote; 81 else { 82 werrstr("invalid remoteio: %s", file); 83 return -1; 84 } 85 memset(dbg, 0, sizeof(dbg)); 86 dbg[0] = tag; 87 dbg[1] = pid>>24; 88 dbg[2] = pid>>16; 89 dbg[3] = pid>>8; 90 dbg[4] = pid; 91 if(rproto(remfd, dbg, sizeof(dbg)) < 0) 92 return -1; 93 if(nb > sizeof(dbg)-1) 94 nb = sizeof(dbg)-1; 95 memmove(buf, dbg+1, nb); 96 return strlen(buf); 97 } 98 99 int 100 remget(struct segment *s, ulong addr, long off, char *buf, int size) 101 { 102 int n, t; 103 char dbg[RDBMSGLEN]; 104 105 if (protodebug) 106 fprint(2, "remget addr %#lux off %#lux\n", addr, off); 107 for (t = 0; t < size; t += n) { 108 n = size; 109 if(n > 9) 110 n = 9; 111 memset(dbg, 0, sizeof(dbg)); 112 dbg[0] = Tmget; 113 dbg[1] = off>>24; 114 dbg[2] = off>>16; 115 dbg[3] = off>>8; 116 dbg[4] = off; 117 dbg[5] = n; 118 if(rproto(s->fd, dbg, sizeof(dbg)) < 0) { 119 werrstr("can't read address %#lux: %r", addr); 120 return -1; 121 } 122 memmove(buf, dbg+1, n); 123 buf += n; 124 } 125 return t; 126 } 127 128 int 129 remput(struct segment *s, ulong addr, long off, char *buf, int size) 130 { 131 int n, i, t; 132 char dbg[RDBMSGLEN]; 133 134 if (protodebug) 135 fprint(2, "remput addr %#lux off %#lux\n", addr, off); 136 for (t = 0; t < size; t += n) { 137 n = size; 138 if(n > 4) 139 n = 4; 140 memset(dbg, 0, sizeof(dbg)); 141 dbg[0] = Tmput; 142 dbg[1] = off>>24; 143 dbg[2] = off>>16; 144 dbg[3] = off>>8; 145 dbg[4] = off; 146 dbg[5] = n; 147 for(i=0; i<n; i++) 148 dbg[6+i] = *buf++; 149 if(rproto(s->fd, dbg, sizeof(dbg)) < 0) { 150 werrstr("can't write address %#lux: %r", addr); 151 return -1; 152 } 153 } 154 return t; 155 } 156 157 int 158 remcondset(char op, ulong val) 159 { 160 char dbg[RDBMSGLEN]; 161 162 if (protodebug) 163 fprint(2, "remcondset op %c val: %#lux\n", op, val); 164 memset(dbg, 0, sizeof(dbg)); 165 166 dbg[0] = Tcondbreak; 167 dbg[1] = val>>24; 168 dbg[2] = val>>16; 169 dbg[3] = val>>8; 170 dbg[4] = val; 171 dbg[5] = op; 172 if(rproto(remfd, dbg, sizeof(dbg)) < 0) { 173 werrstr("can't set condbreak: %c %#lux: %r", op, val); 174 return -1; 175 } 176 return 0; 177 } 178 179 int 180 remcondstartstop(int pid) 181 { 182 char dbg[RDBMSGLEN]; 183 184 if (protodebug) 185 fprint(2, "remcondstartstop pid %d\n", pid); 186 memset(dbg, 0, sizeof(dbg)); 187 188 dbg[0] = Tstartstop; 189 dbg[1] = pid>>24; 190 dbg[2] = pid>>16; 191 dbg[3] = pid>>8; 192 dbg[4] = pid; 193 194 if(rproto(remfd, dbg, sizeof(dbg)) < 0) { 195 werrstr("can't send Tstartstop"); 196 return -1; 197 } 198 199 return dbg[1]; 200 } 201 202 static int 203 rproto(int fd, char *buf, int nb) 204 { 205 int tag; 206 207 if (protodebug) { 208 int i; 209 print("rproto remote write fd %d bytes: %d\n", fd, nb); 210 for (i=0; i < nb; i++) { 211 print(" %2.2ux", buf[i]&0xFF); 212 } 213 print("\n"); 214 } 215 tag = buf[0]; 216 if(remote_write(fd, buf, nb) != nb || 217 myreadn(fd, buf, nb) != nb){ /* could set alarm */ 218 werrstr("remote i/o: %r"); 219 return -1; 220 } 221 if(buf[0] == Rerr){ 222 buf[nb-1] = 0; 223 werrstr("remote err: %s", buf+1); 224 return -1; 225 } 226 if(buf[0] != tag+1) { 227 werrstr("remote proto err: %.2ux", buf[0]&0xff); 228 return -1; 229 } 230 if(chatty) { 231 int i; 232 fprint(2, "remote [%d]: ", nb); 233 for(i=0; i<nb; i++) 234 fprint(2, " %.2ux", buf[i]&0xff); 235 fprint(2, "\n"); 236 } 237 return nb; 238 } 239 240 /* 241 * this should probably be in lib9 as readn 242 */ 243 static long 244 myreadn(int f, void *av, long n) 245 { 246 char *a; 247 long m, t; 248 249 if (protodebug) { 250 print("remote read fd %d bytes: %ld", f, n); 251 } 252 a = av; 253 t = 0; 254 while(t < n){ 255 m = remote_read(f, a+t, n-t); 256 if(m < 0){ 257 if(t == 0) 258 return m; 259 break; 260 } 261 if (protodebug) { 262 print(" rtn: %ld\n", m); 263 if (m) { 264 int i; 265 266 for (i=0; i < m; i++) 267 print(" %2.2ux", a[i+t]&0xFF); 268 print("\n"); 269 } 270 } 271 t += m; 272 } 273 return t; 274 } 275