123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310 |
- /*
- *
- * debugger
- *
- */
- #include "defs.h"
- #include "fns.h"
- char BADEQ[] = "unexpected `='";
- BOOL executing;
- extern Rune *lp;
- char eqformat[ARB] = "z";
- char stformat[ARB] = "zMi";
- ADDR ditto;
- ADDR dot;
- int dotinc;
- WORD adrval, cntval, loopcnt;
- int adrflg, cntflg;
- /* command decoding */
- command(char *buf, int defcom)
- {
- char *reg;
- char savc;
- Rune *savlp=lp;
- char savlc = lastc;
- char savpc = peekc;
- static char lastcom = '=', savecom = '=';
- if (defcom == 0)
- defcom = lastcom;
- if (buf) {
- if (*buf==EOR)
- return(FALSE);
- clrinp();
- lp=(Rune*)buf;
- }
- do {
- adrflg=expr(0); /* first address */
- if (adrflg){
- dot=expv;
- ditto=expv;
- }
- adrval=dot;
- if (rdc()==',' && expr(0)) { /* count */
- cntflg=TRUE;
- cntval=expv;
- } else {
- cntflg=FALSE;
- cntval=1;
- reread();
- }
- if (!eol(rdc()))
- lastcom=lastc; /* command */
- else {
- if (adrflg==0)
- dot=inkdot(dotinc);
- reread();
- lastcom=defcom;
- }
- switch(lastcom) {
- case '/':
- case '=':
- case '?':
- savecom = lastcom;
- acommand(lastcom);
- break;
- case '>':
- lastcom = savecom;
- savc=rdc();
- if (reg=regname(savc))
- rput(cormap, reg, dot);
- else
- error("bad variable");
- break;
- case '!':
- lastcom=savecom;
- shell();
- break;
- case '$':
- lastcom=savecom;
- printtrace(nextchar());
- break;
- case ':':
- if (!executing) {
- executing=TRUE;
- subpcs(nextchar());
- executing=FALSE;
- lastcom=savecom;
- }
- break;
- case 0:
- prints(DBNAME);
- break;
- default:
- error("bad command");
- }
- flushbuf();
- } while (rdc()==';');
- if (buf == 0)
- reread();
- else {
- clrinp();
- lp=savlp;
- lastc = savlc;
- peekc = savpc;
- }
- if(adrflg)
- return dot;
- return 1;
- }
- /*
- * [/?][wml]
- */
- void
- acommand(int pc)
- {
- int eqcom;
- Map *map;
- char *fmt;
- char buf[512];
- if (pc == '=') {
- eqcom = 1;
- fmt = eqformat;
- map = dotmap;
- } else {
- eqcom = 0;
- fmt = stformat;
- if (pc == '/')
- map = cormap;
- else
- map = symmap;
- }
- if (!map) {
- snprint(buf, sizeof(buf), "no map for %c", pc);
- error(buf);
- }
- switch (rdc())
- {
- case 'm':
- if (eqcom)
- error(BADEQ);
- cmdmap(map);
- break;
- case 'L':
- case 'l':
- if (eqcom)
- error(BADEQ);
- cmdsrc(lastc, map);
- break;
- case 'W':
- case 'w':
- if (eqcom)
- error(BADEQ);
- cmdwrite(lastc, map);
- break;
- default:
- reread();
- getformat(fmt);
- scanform(cntval, !eqcom, fmt, map, eqcom);
- }
- }
- void
- cmdsrc(int c, Map *map)
- {
- ulong w;
- long locval, locmsk;
- ADDR savdot;
- ushort sh;
- char buf[512];
- int ret;
- if (c == 'L')
- dotinc = 4;
- else
- dotinc = 2;
- savdot=dot;
- expr(1);
- locval=expv;
- if (expr(0))
- locmsk=expv;
- else
- locmsk = ~0;
- if (c == 'L')
- while ((ret = get4(map, dot, &w)) > 0 && (w&locmsk) != locval)
- dot = inkdot(dotinc);
- else
- while ((ret = get2(map, dot, &sh)) > 0 && (sh&locmsk) != locval)
- dot = inkdot(dotinc);
- if (ret < 0) {
- dot=savdot;
- error("%r");
- }
- symoff(buf, 512, dot, CANY);
- dprint(buf);
- }
- static char badwrite[] = "can't write process memory or text image";
- void
- cmdwrite(int wcom, Map *map)
- {
- ADDR savdot;
- char *format;
- int pass;
- if (wcom == 'w')
- format = "x";
- else
- format = "X";
- expr(1);
- pass = 0;
- do {
- pass++;
- savdot=dot;
- exform(1, 1, format, map, 0, pass);
- dot=savdot;
- if (wcom == 'W') {
- if (put4(map, dot, expv) <= 0)
- error(badwrite);
- } else {
- if (put2(map, dot, expv) <= 0)
- error(badwrite);
- }
- savdot=dot;
- dprint("=%8t");
- exform(1, 0, format, map, 0, pass);
- newline();
- } while (expr(0));
- dot=savdot;
- }
- /*
- * collect a register name; return register offset
- * this is not what i'd call a good division of labour
- */
- char *
- regname(int regnam)
- {
- static char buf[64];
- char *p;
- int c;
- p = buf;
- *p++ = regnam;
- while (isalnum(c = readchar())) {
- if (p >= buf+sizeof(buf)-1)
- error("register name too long");
- *p++ = c;
- }
- *p = 0;
- reread();
- return (buf);
- }
- /*
- * shell escape
- */
- void
- shell(void)
- {
- int rc, unixpid;
- char *argp = (char*)lp;
- while (lastc!=EOR)
- rdc();
- if ((unixpid=fork())==0) {
- *lp=0;
- execl("/bin/rc", "rc", "-c", argp, nil);
- exits("execl"); /* botch */
- } else if (unixpid == -1) {
- error("cannot fork");
- } else {
- mkfault = 0;
- while ((rc = waitpid()) != unixpid){
- if(rc == -1 && mkfault){
- mkfault = 0;
- continue;
- }
- break;
- }
- prints("!");
- reread();
- }
- }
|