Blob
1 /*2 *3 * debugger4 *5 */7 #include "defs.h"8 #include "fns.h"10 char BADEQ[] = "unexpected `='";12 BOOL executing;13 extern char *lp;15 char eqformat[ARB] = "z";16 char stformat[ARB] = "zMi";18 ADDR ditto;20 ADDR dot;21 WORD dotinc;22 WORD adrval, cntval, loopcnt;23 int adrflg, cntflg;25 /* command decoding */27 int28 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 = '=';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;53 if (rdc()==',' && expr(0)) { /* count */54 cntflg=TRUE;55 cntval=expv;56 } else {57 cntflg=FALSE;58 cntval=1;59 reread();60 }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;78 case '>':79 lastcom = savecom;80 savc=rdc();81 if (reg=regname(savc))82 rput(correg, reg, dot);83 else84 error("bad variable");85 break;87 case '!':88 lastcom=savecom;89 shell();90 break;92 case '$':93 lastcom=savecom;94 printdollar(nextchar());95 break;97 case ':':98 if (!executing) {99 executing=TRUE;100 subpcs(nextchar());101 executing=FALSE;102 lastcom=savecom;103 }104 break;106 case 0:107 prints(DBNAME);108 break;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 }124 if(adrflg)125 return dot;126 return 1;127 }129 /*130 * [/?][wml]131 */133 void134 acommand(int pc)135 {136 int eqcom;137 Map *map;138 char *fmt;139 char buf[512];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 else151 map = symmap;152 }153 if (!map) {154 sprint(buf, "no map for %c", pc);155 error(buf);156 }158 switch (rdc())159 {160 case 'm':161 if (eqcom)162 error(BADEQ);163 cmdmap(map);164 break;166 case 'L':167 case 'l':168 if (eqcom)169 error(BADEQ);170 cmdsrc(lastc, map);171 break;173 case 'W':174 case 'w':175 if (eqcom)176 error(BADEQ);177 cmdwrite(lastc, map);178 break;180 default:181 reread();182 getformat(fmt);183 scanform(cntval, !eqcom, fmt, map, eqcom);184 }185 }187 void188 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;197 if (c == 'L')198 dotinc = 4;199 else200 dotinc = 2;201 savdot=dot;202 expr(1);203 locval=expv;204 if (expr(0))205 locmsk=expv;206 else207 locmsk = ~0;208 if (c == 'L')209 while ((ret = get4(map, dot, &w)) > 0 && (w&locmsk) != locval)210 dot = inkdot(dotinc);211 else212 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 }222 static char badwrite[] = "can't write process memory or text image";224 void225 cmdwrite(int wcom, Map *map)226 {227 ADDR savdot;228 char *format;229 int pass;231 if (wcom == 'w')232 format = "x";233 else234 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 }257 /*258 * collect a register name; return register offset259 * this is not what i'd call a good division of labour260 */262 char *263 regname(int regnam)264 {265 static char buf[64];266 char *p;267 int c;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 }281 /*282 * shell escape283 */285 void286 shell(void)287 {288 int rc, unixpid;289 char *argp = lp;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 }