command.c (4336B)
1 /* 2 * 3 * debugger 4 * 5 */ 6 7 #include "defs.h" 8 #include "fns.h" 9 10 char BADEQ[] = "unexpected `='"; 11 12 BOOL executing; 13 extern char *lp; 14 15 char eqformat[ARB] = "z"; 16 char stformat[ARB] = "zMi"; 17 18 ADDR ditto; 19 20 ADDR dot; 21 WORD dotinc; 22 WORD adrval, cntval, loopcnt; 23 int adrflg, cntflg; 24 25 /* command decoding */ 26 27 int 28 command(char *buf, int defcom) 29 { 30 char *reg; 31 char savc; 32 char *savlp=lp; 33 char savlc = lastc; 34 char savpc = peekc; 35 static char lastcom = '=', savecom = '='; 36 37 if (defcom == 0) 38 defcom = lastcom; 39 if (buf) { 40 if (*buf==EOR) 41 return(FALSE); 42 clrinp(); 43 lp=buf; 44 } 45 do { 46 adrflg=expr(0); /* first address */ 47 if (adrflg){ 48 dot=expv; 49 ditto=expv; 50 } 51 adrval=dot; 52 53 if (rdc()==',' && expr(0)) { /* count */ 54 cntflg=TRUE; 55 cntval=expv; 56 } else { 57 cntflg=FALSE; 58 cntval=1; 59 reread(); 60 } 61 62 if (!eol(rdc())) 63 lastcom=lastc; /* command */ 64 else { 65 if (adrflg==0) 66 dot=inkdot(dotinc); 67 reread(); 68 lastcom=defcom; 69 } 70 switch(lastcom) { 71 case '/': 72 case '=': 73 case '?': 74 savecom = lastcom; 75 acommand(lastcom); 76 break; 77 78 case '>': 79 lastcom = savecom; 80 savc=rdc(); 81 if (reg=regname(savc)) 82 rput(correg, reg, dot); 83 else 84 error("bad variable"); 85 break; 86 87 case '!': 88 lastcom=savecom; 89 shell(); 90 break; 91 92 case '$': 93 lastcom=savecom; 94 printdollar(nextchar()); 95 break; 96 97 case ':': 98 if (!executing) { 99 executing=TRUE; 100 subpcs(nextchar()); 101 executing=FALSE; 102 lastcom=savecom; 103 } 104 break; 105 106 case 0: 107 prints(DBNAME); 108 break; 109 110 default: 111 error("bad command"); 112 } 113 flushbuf(); 114 } while (rdc()==';'); 115 if (buf == 0) 116 reread(); 117 else { 118 clrinp(); 119 lp=savlp; 120 lastc = savlc; 121 peekc = savpc; 122 } 123 124 if(adrflg) 125 return dot; 126 return 1; 127 } 128 129 /* 130 * [/?][wml] 131 */ 132 133 void 134 acommand(int pc) 135 { 136 int eqcom; 137 Map *map; 138 char *fmt; 139 char buf[512]; 140 141 if (pc == '=') { 142 eqcom = 1; 143 fmt = eqformat; 144 map = dotmap; 145 } else { 146 eqcom = 0; 147 fmt = stformat; 148 if (pc == '/') 149 map = cormap; 150 else 151 map = symmap; 152 } 153 if (!map) { 154 sprint(buf, "no map for %c", pc); 155 error(buf); 156 } 157 158 switch (rdc()) 159 { 160 case 'm': 161 if (eqcom) 162 error(BADEQ); 163 cmdmap(map); 164 break; 165 166 case 'L': 167 case 'l': 168 if (eqcom) 169 error(BADEQ); 170 cmdsrc(lastc, map); 171 break; 172 173 case 'W': 174 case 'w': 175 if (eqcom) 176 error(BADEQ); 177 cmdwrite(lastc, map); 178 break; 179 180 default: 181 reread(); 182 getformat(fmt); 183 scanform(cntval, !eqcom, fmt, map, eqcom); 184 } 185 } 186 187 void 188 cmdsrc(int c, Map *map) 189 { 190 u32int w; 191 long locval, locmsk; 192 ADDR savdot; 193 ushort sh; 194 char buf[512]; 195 int ret; 196 197 if (c == 'L') 198 dotinc = 4; 199 else 200 dotinc = 2; 201 savdot=dot; 202 expr(1); 203 locval=expv; 204 if (expr(0)) 205 locmsk=expv; 206 else 207 locmsk = ~0; 208 if (c == 'L') 209 while ((ret = get4(map, dot, &w)) > 0 && (w&locmsk) != locval) 210 dot = inkdot(dotinc); 211 else 212 while ((ret = get2(map, dot, &sh)) > 0 && (sh&locmsk) != locval) 213 dot = inkdot(dotinc); 214 if (ret < 0) { 215 dot=savdot; 216 error("%r"); 217 } 218 symoff(buf, 512, dot, CANY); 219 dprint(buf); 220 } 221 222 static char badwrite[] = "can't write process memory or text image"; 223 224 void 225 cmdwrite(int wcom, Map *map) 226 { 227 ADDR savdot; 228 char *format; 229 int pass; 230 231 if (wcom == 'w') 232 format = "x"; 233 else 234 format = "X"; 235 expr(1); 236 pass = 0; 237 do { 238 pass++; 239 savdot=dot; 240 exform(1, 1, format, map, 0, pass); 241 dot=savdot; 242 if (wcom == 'W') { 243 if (put4(map, dot, expv) <= 0) 244 error(badwrite); 245 } else { 246 if (put2(map, dot, expv) <= 0) 247 error(badwrite); 248 } 249 savdot=dot; 250 dprint("=%8t"); 251 exform(1, 0, format, map, 0, pass); 252 newline(); 253 } while (expr(0)); 254 dot=savdot; 255 } 256 257 /* 258 * collect a register name; return register offset 259 * this is not what i'd call a good division of labour 260 */ 261 262 char * 263 regname(int regnam) 264 { 265 static char buf[64]; 266 char *p; 267 int c; 268 269 p = buf; 270 *p++ = regnam; 271 while (isalnum(c = readchar())) { 272 if (p >= buf+sizeof(buf)-1) 273 error("register name too long"); 274 *p++ = c; 275 } 276 *p = 0; 277 reread(); 278 return (buf); 279 } 280 281 /* 282 * shell escape 283 */ 284 285 void 286 shell(void) 287 { 288 int rc, unixpid; 289 char *argp = lp; 290 291 while (lastc!=EOR) 292 rdc(); 293 if ((unixpid=fork())==0) { 294 *lp=0; 295 execl("/bin/rc", "rc", "-c", argp, 0); 296 exits("execl"); /* botch */ 297 } else if (unixpid == -1) { 298 error("cannot fork"); 299 } else { 300 mkfault = 0; 301 while ((rc = waitpid()) != unixpid){ 302 if(rc == -1 && mkfault){ 303 mkfault = 0; 304 continue; 305 } 306 break; 307 } 308 prints("!"); 309 reread(); 310 } 311 }