BSD 4 release
[unix-history] / usr / src / cmd / sdb / docomm.c
index 740cfc8..1e20b48 100644 (file)
@@ -1,32 +1,41 @@
+static char sccsid[] = "@(#)docomm.c 4.1 10/9/80";
 #include <signal.h>
 #include "head.h"
 #include <a.out.h>
 #include <signal.h>
 #include "head.h"
 #include <a.out.h>
+#include <stab.h>
 
 struct user u;
 L_INT  cntval;
 INT    signo;
 INT    adrflg;
 
 struct user u;
 L_INT  cntval;
 INT    signo;
 INT    adrflg;
-long   oldaddr = -1;
+INT    pid;
+ADDR   userpc;
+char   *s;
+enum   {NOCOM, PRCOM, DSCOM, DSICOM} lastcom;
+               /* last command: nothing noteworthy, print source,
+                       display variable, display instruction */
 
 docommand() {
        register char   *p;
        register int    i;
 
 docommand() {
        register char   *p;
        register int    i;
-       register ADDR   addr, odot;
+       register ADDR   addr, bkaddr;
        struct proct    *procp;
        struct proct    *procp;
+       char s[4];
        
        
-       if (signo == SIGINT) signo = 0;
        cntval = 1;
        adrflg = 0;
        errflg = 0;
 
        if (scallf) {
                doscall();
        cntval = 1;
        adrflg = 0;
        errflg = 0;
 
        if (scallf) {
                doscall();
-               setcur();
+               setcur(1);
+               lastcom = NOCOM;
                return;
        }
        
        if (reflag) {  /* search for regular expression */
                dore();
                return;
        }
        
        if (reflag) {  /* search for regular expression */
                dore();
+               lastcom = PRCOM;
                return;
        }
        
                return;
        }
        
@@ -38,6 +47,7 @@ docommand() {
                if (integ != 0) { /* print line number */
                        ffind(integ);
                        fprint();
                if (integ != 0) { /* print line number */
                        ffind(integ);
                        fprint();
+                       lastcom = PRCOM;
                        return;
                }
                if (var[0] != 0) {
                        return;
                }
                if (var[0] != 0) {
@@ -48,18 +58,68 @@ docommand() {
                
        switch (cmd) {
        
                
        switch (cmd) {
        
-       case 'a':
+       case 'Y':
                debug = !debug;
                break;
                debug = !debug;
                break;
+
+       case 'V':
+               version();
+               break;
+
+       case 'M':
+               if (args[0]) {
+                       setmap(args);
+               } else {
+                       printmap("? map", &txtmap);
+                       printmap("/ map", &datmap);
+               }
+               break;
+
+       case 'x':
+               printregs();
+               break;
+
+       case 'X':
+               printpc();
+               break;
+
+       case 'a':
+               if (integ) {
+                       cpstr(args, "l\n");
+               } else if (proc[0]) {
+                       cpall(args, "T\n");
+               } else {
+                       error("Bad arguments");
+                       break;
+               }
+               goto setbrk;
+               break;  
+
+       case 'l':
+               setcur(1);
+               lastcom = NOCOM;
+               break;
+               
+       case 'T':
+               prfrx(1);
+               lastcom = NOCOM;
+               break;
                
        case 't':
                prframe();
                
        case 't':
                prframe();
+               lastcom = NOCOM;
                break;
                
        case 'e':
                p = args;
                if (*p == '\0') {
                break;
                
        case 'e':
                p = args;
                if (*p == '\0') {
-                       printf("%.8s() in \"%s\"\n", curproc()->pname, curfile);
+#ifndef FLEXNAMES
+                       printf("%.16s() in \"%s\"\n",
+                               curproc()->pname, curfile);
+#else
+                       printf("%s() in \"%s\"\n",
+                               curproc()->pname, curfile);
+#endif
                        break;
                }
 
                        break;
                }
 
@@ -72,17 +132,24 @@ docommand() {
                        ffind(procp->lineno);
                }
                else printf("Can't find %s\n", args);
                        ffind(procp->lineno);
                }
                else printf("Can't find %s\n", args);
-               printf("%.8s() in \"%s\"\n", curproc()->pname, curfile);
+#ifndef FLEXNAMES
+               printf("%.16s() in \"%s\"\n", curproc()->pname, curfile);
+#else
+               printf("%s() in \"%s\"\n", curproc()->pname, curfile);
+#endif
+               lastcom = PRCOM;
                break;
                
        l1:     /* argument is filename */
                finit(args);
                printf("\"%s\"\n", curfile);
                break;
                
        l1:     /* argument is filename */
                finit(args);
                printf("\"%s\"\n", curfile);
+               lastcom = PRCOM;
                break;
                
        case 'p':
                if (integ) ffind(integ);
                fprint();
                break;
                
        case 'p':
                if (integ) ffind(integ);
                fprint();
+               lastcom = PRCOM;
                break;
                
        case 'q':
                break;
                
        case 'q':
@@ -94,104 +161,204 @@ docommand() {
                fback(WINDOW/2);
                fprintn(WINDOW);
                ffind(i);
                fback(WINDOW/2);
                fprintn(WINDOW);
                ffind(i);
+               lastcom = PRCOM;
                break;
                
                break;
                
-       case 'x':
+       case 'Q':
                prdebug();
                break;
 
        case 'z':
                if (integ) ffind(integ);
                fprintn(WINDOW);
                prdebug();
                break;
 
        case 'z':
                if (integ) ffind(integ);
                fprintn(WINDOW);
+               lastcom = PRCOM;
                break;
 
        case '-':
                fback(integ ? integ : 1);
                fpargs();
                break;
 
        case '-':
                fback(integ ? integ : 1);
                fpargs();
+               lastcom = PRCOM;
                break;
 
        case '+':
                fforward(integ ? integ : 1);
                fpargs();
                break;
 
        case '+':
                fforward(integ ? integ : 1);
                fpargs();
+               lastcom = PRCOM;
                break;
 
        case '\n':
                break;
 
        case '\n':
-               fforward(1);
-               fprint();
+               switch (lastcom) {
+               case PRCOM:
+                       fforward(1);
+                       fprint();
+                       break;
+               case DSCOM:
+                       oaddr += oincr ? oincr : typetosize(otype, WORDSIZE);
+                       printf("0x%x/ ", oaddr);
+                       dispf((ADDR) oaddr, odesc,
+                           oclass == N_RSYM ? oclass : N_GSYM, otype, 0, 0, DSP);
+                       break;
+               case DSICOM:
+                       dot += oincr;
+                       prisploc();
+                       dispi(dot, odesc, N_GSYM, 0, 0);
+                       break;
+               }
                break;
 
        case '\004':
                break;
 
        case '\004':
-               fforward(1);
-               printf("\b");
-               fprintn(WINDOW);
+               if (!isatty(0))
+                       exit(0);
+               switch (lastcom) {
+               case PRCOM:
+                       fforward(1);
+                       printf("\b");
+                       fprintn(WINDOW);
+                       lastcom = PRCOM;
+                       break;
+               case DSICOM:
+                       printf("\b");
+                       for (i=0; i<WINDOW; i++) {
+                               dot += oincr;
+                               prisploc();
+                               if (dispi(dot, odesc, N_GSYM, 0, 0) == -1)
+                                       break;
+                       }
+                       break;
+               case DSCOM:
+                       printf("\b");
+                       for (i=0; i<WINDOW; i++) {
+                               oaddr += oincr ?
+                                       oincr : typetosize(otype, WORDSIZE);
+                               printf("0x%x/ ", oaddr);
+                               if (dispf((ADDR) oaddr, odesc,
+                                       oclass == N_RSYM ? oclass :
+                                       N_GSYM, otype, 0, 0, DSP) == -1)
+                                       break;
+                       }
+                       break;
+               default:
+                       printf("\n");
+               }
                break;
 
        case 'r':
                break;
 
        case 'r':
-               if (debug) error("calling subpcs");
+               if (args[0] == '\0') getargs();
+       case 'R':
+               signo = 0;
+               cpstr(oldargs, args);
+               if (debug) error("calling dopcs");
                if (integ) cntval = integ;
                if (!executing) {
                        executing = TRUE;
                        if (integ) cntval = integ;
                if (integ) cntval = integ;
                if (!executing) {
                        executing = TRUE;
                        if (integ) cntval = integ;
-                       subpcs('r');
+                       dopcs('r');
                        executing = FALSE;
                }
                        executing = FALSE;
                }
-               if (debug) error("exiting subpcs");
-/*
-               setcur();
-               break;
-*/
+               if (debug) error("exiting dopcs");
+               bkaddr = -1;
+               goto f1;
 
        case 'c':
 
        case 'c':
-               if (debug) error("calling subpcs");
+               signo = 0;
+       case 'C':
+               if (proc[0] != '\0' || integ != 0) {
+                       setdot();
+                       if (dot == -1) {
+                               error("Cannot set temporary breakpoint");
+                               break;
+                       }
+                       dopcs('b');
+                       bkaddr = dot;
+               } else
+                       bkaddr = -1;
+               integ = atoi(args);
+
+f1:            if (debug) error("calling dopcs");
                if (integ) cntval = integ;
                if (integ) cntval = integ;
-               subpcs('c');
-               if (debug) error("exiting subpcs");
+               dopcs('c');
+               if (debug) error("exiting dopcs");
+               if (bkaddr != -1) {
+                       ADDR dotsave;
+                       dotsave = dot;
+                       dot = bkaddr;
+                       dopcs('d');
+                       dot = dotsave;
+               }
                if (!signo) printf("Breakpoint");
                printf(" at\n");
                if (!signo) printf("Breakpoint");
                printf(" at\n");
-               setcur();
+               setcur(1);
+               lastcom = NOCOM;
                break;
                
                break;
                
+       case 'S':
        case 's':
        case 's':
-               singstep(integ ? integ : 1);
+               signo = 0;
+               integ = atoi(args);
+               singstep(integ ? integ : 1, cmd);
                if (signo) printf("\n");
                if (signo) printf("\n");
-               setcur();
+               setcur(1);
+               lastcom = NOCOM;
                break;
                
                break;
                
-       case 'n':
-               odot = *(ADDR *) (((ADDR) &u) + PC);
-               for (i=1; i<100; i++) {
-                       dot = getaddr(adrtoprocp(odot)->pname, adrtolineno(odot)+i);
-                       if (dot != odot || dot == -1) break;
+       case 'g':
+               if (pid == 0  ||  signo) {
+                       error("Not stopped at breakpoint");
+                       break;
                }
                }
-               if (odot == dot  ||  dot == -1) {
-                       error("Cannot find next line");
+               setdot();
+               if (dot == -1) {
+                       error("Bad address");
                        break;
                }
                        break;
                }
-               if (debug) printf("Setting bkpt with i=%d at %d, odot = %d\n", i, dot, odot);
-               odot = dot;
-               subpcs('b');
-               subpcs('c');
-               if (!signo) printf("Next statement\n");
-               else printf(" at\n");
-               setcur();
-               dot = odot;
-               subpcs('d');
+               adrflg = 1;
+               integ = atoi(args);
+               if (integ) cntval = integ;
+               dopcs('c');
+               if (!signo) printf("Breakpoint");
+               printf(" at\n");
+               setcur(1);
+               lastcom = NOCOM;
                break;
                break;
-               
+
+       case 'k':
+               if (scallx) {
+                       userpc = dot = *(ADDR *)(((ADDR)&u)+PC) = pcs;
+                       *(ADDR *)(((ADDR)&u)+FP) = fps;
+                       *(ADDR *)(((ADDR)&u)+AP) = aps;
+                       if (bkpts)
+                               bkpts->flag = flagss;
+                       scallx = 0;
+                       error("Procedure killed");
+                       longjmp(env, 0);
+               } else {
+                       dopcs('k');
+                       printf("\n");
+                       lastcom = NOCOM;
+                       break;
+               }
+
+       case 'B':
+               prbkpt();
+               break;
+
        case 'b':
        case 'b':
+       setbrk:
                if (proc[0] == '\0' && integ == 0) {
                if (proc[0] == '\0' && integ == 0) {
-                       prbkpt();
+                       integ = fline;
                }
                }
-               else {
-                       dot = getaddr(proc,integ);
-                       if (dot == -1) {
-                               error("Cannot set breakpoint");
-                               break;
-                       }
-                       subpcs('b');
-                       printf("%.8s:%d b\n",adrtoprocp(dot)->pname,
-                               adrtolineno(dot));
+               setdot();
+               if (dot == -1 || dot == 0) {
+                       error("Cannot set breakpoint");
+                       break;
                }
                }
+               dopcs('b');
+               s[0] = ' ';
+               s[1] = cmd;
+               s[2] = '\n';
+               s[3] = 0;
+               s[1] = cmd;
+               printbkpt(s, adrtoprocp(dot), dot);
                break;
                
        case 'd':
                break;
                
        case 'd':
@@ -199,58 +366,114 @@ docommand() {
                        idbkpt();
                        break;
                }
                        idbkpt();
                        break;
                }
-               dot = getaddr(proc,integ);
+               setdot();
                if (dot == -1) {
                        error("Non existent breakpoint");
                        break;
                }
                if (dot == -1) {
                        error("Non existent breakpoint");
                        break;
                }
-               subpcs('d');
+               dopcs('d');
                break;
                
                break;
                
+       case 'D':
+               dabkpt();
+               error("All breakpoints deleted");
+               break;
+
        case 'm':
                addr = varaddr(proc[0] ? proc : curproc()->pname, var);
                printf("stopped with value %d\n", monex(addr, 'd'));
        case 'm':
                addr = varaddr(proc[0] ? proc : curproc()->pname, var);
                printf("stopped with value %d\n", monex(addr, 'd'));
-               setcur();
+               setcur(1);
+               lastcom = NOCOM;
                break;
                
                break;
                
+       case '?':
+               if (!(var[0] == '.' && var[1] == '\0'))
+                       setdot();
+               if (errflg) {
+                       error(errflg);
+                       break;
+               }
+               prisploc();
+               dispi(dot, args[0] ? args : "i", N_GSYM, 0, 0);
+               lastcom = DSICOM;
+               break;
+
        case '/':
                if (var[0] == '.' && var[1] == '\0') {
        case '/':
                if (var[0] == '.' && var[1] == '\0') {
-                       if (integ == 0) integ = oldaddr;
+                       if (integ == 0) integ = oaddr;
                        dispf((ADDR) integ, args[0] ? args : odesc,
                        dispf((ADDR) integ, args[0] ? args : odesc,
-                               oclass == N_RSYM ? oclass : N_GSYM, otype, 0);
-                       oldaddr = integ;
-                       break;
-               }
-               if (integ) {
-                       dispf((ADDR) integ, args, N_GSYM, 0, 0);
-                       break;
-               }
-               oldaddr = dispvar(proc[0] ? proc : curproc()->pname, var, args);
+                           oclass == N_RSYM ? oclass : N_GSYM, otype, 0, 0, DSP);
+                       oaddr = integ;
+               } else
+               if (integ && (var[0] == '\0')) {
+                       dispf((ADDR) integ, args, N_GSYM, 0, 0, 0, DSP);
+                       oaddr = integ;
+                       cpstr(odesc, args);
+                       oclass = N_GSYM;
+                       otype = 0;
+               } else
+                       dispvar(proc, var, args);
+               lastcom = DSCOM;
                break;
                
        case '=':
                break;
                
        case '=':
-               if (var[0] == '\0')
-                       addr = getaddr(proc, integ);
-               else
-                       addr = varaddr(proc[0] ? proc : curproc()->pname, var);
-               if (addr == -1)
-                       error("Unknown address");
-               else
-                       printf("0x%x\n", addr);
+               if (var[0] == '\0') {
+                       if (proc[0]) {
+                               addr = getaddr(proc, integ);
+                               if (addr == -1) {
+                                       error("Unknown address");
+                                       break;
+                               }
+                       }
+                       else
+                               addr = integ;
+                       dispf(addr, args[0] ? args : "x", 0, -1, 0, 0, DSP);
+               } else 
+                       findvar(proc, var, args[0] ? args : "x", 2);
                break;
 
        case '!':
                if (var[0] == '\0')
                        addr = getaddr(proc, integ);
                else
                break;
 
        case '!':
                if (var[0] == '\0')
                        addr = getaddr(proc, integ);
                else
-                       addr = varaddr(proc[0] ? proc : curproc()->pname, var);
+                       addr = varaddr(proc, var);
                if (addr == -1) 
                        error("Unknown variable");
                if (addr == -1) 
                        error("Unknown variable");
-               else
-                       if (sl_class == N_RSYM)
-                               putreg(addr,typetodesc(sl_type,subflag)[0],argvalue(args));
+               else {
+                       if (number(args[0]) || eqany(args[0], ".-")) {
+                               char *p;
+                               double atof();
+                               union {
+                                       struct{
+                                               int w1, w2;
+                                       } ww;
+                                       double d;
+                               } dbl;
+
+                               p = (args[0] == '-') ? args+1 : args;
+                               for (; *p != '.' && *p != 'e'; p++) {
+                                       if (!number(*p)) goto l2;
+                               }
+                               dbl.d = atof(args);
+                               putval(addr, 'd', dbl.ww.w1);
+                               if (typetodesc(sl_type,0)[0] == 'g')
+                                       putval(addr+WORDSIZE, 'd', dbl.ww.w2);
+                               break;
+                       }
+l2:                    if (percentflag)
+                               *(ADDR *)(((ADDR)&u)+addr) = argvalue(args);
+                       else if (sl_class == N_RSYM && addr < 16)
+                               putreg(addr,typetodesc(sl_type,subflag)[0],
+                                               argvalue(args));
                        else
                        else
-                               putval(addr,typetodesc(sl_type,subflag)[0],argvalue(args));
+                               putval(addr,typetodesc(sl_type,subflag)[0],
+                                               argvalue(args));
+               }
+               lastcom = NOCOM;
+               break;
+
+       case '"':
+               printf(args);
                break;
        }
 }
                break;
        }
 }
@@ -274,3 +497,18 @@ case 'w':
                break;
        }
 }
                break;
        }
 }
+
+MSG    BADTXT;
+/* Used by a, b, c, C, d and g commands to find linenumber */
+setdot() {
+       if (ncolonflag) {
+               dot = integ;
+               get(dot, ISP);
+               if (errflg)
+                       dot = -1;
+       } else {
+               dot = getaddr(proc, integ);
+               if (dot == -1)
+                       errflg = "Bad line number";
+       }
+}