URI:
       tcommand.c - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       tcommand.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 }