1*1332Sbill static char sccsid[] = "@(#)docomm.c 4.1 10/09/80"; 2*1332Sbill #include <signal.h> 3*1332Sbill #include "head.h" 4*1332Sbill #include <a.out.h> 5*1332Sbill #include <stab.h> 6*1332Sbill 7*1332Sbill struct user u; 8*1332Sbill L_INT cntval; 9*1332Sbill INT signo; 10*1332Sbill INT adrflg; 11*1332Sbill INT pid; 12*1332Sbill ADDR userpc; 13*1332Sbill char *s; 14*1332Sbill enum {NOCOM, PRCOM, DSCOM, DSICOM} lastcom; 15*1332Sbill /* last command: nothing noteworthy, print source, 16*1332Sbill display variable, display instruction */ 17*1332Sbill 18*1332Sbill docommand() { 19*1332Sbill register char *p; 20*1332Sbill register int i; 21*1332Sbill register ADDR addr, bkaddr; 22*1332Sbill struct proct *procp; 23*1332Sbill char s[4]; 24*1332Sbill 25*1332Sbill cntval = 1; 26*1332Sbill adrflg = 0; 27*1332Sbill errflg = 0; 28*1332Sbill 29*1332Sbill if (scallf) { 30*1332Sbill doscall(); 31*1332Sbill setcur(1); 32*1332Sbill lastcom = NOCOM; 33*1332Sbill return; 34*1332Sbill } 35*1332Sbill 36*1332Sbill if (reflag) { /* search for regular expression */ 37*1332Sbill dore(); 38*1332Sbill lastcom = PRCOM; 39*1332Sbill return; 40*1332Sbill } 41*1332Sbill 42*1332Sbill if (cmd == '\0') { 43*1332Sbill if (integ != 0 && var[0] != '\0') { 44*1332Sbill error("Invalid command (1)"); 45*1332Sbill return; 46*1332Sbill } 47*1332Sbill if (integ != 0) { /* print line number */ 48*1332Sbill ffind(integ); 49*1332Sbill fprint(); 50*1332Sbill lastcom = PRCOM; 51*1332Sbill return; 52*1332Sbill } 53*1332Sbill if (var[0] != 0) { 54*1332Sbill printf("Unexpected null command\n"); 55*1332Sbill return; 56*1332Sbill } 57*1332Sbill } 58*1332Sbill 59*1332Sbill switch (cmd) { 60*1332Sbill 61*1332Sbill case 'Y': 62*1332Sbill debug = !debug; 63*1332Sbill break; 64*1332Sbill 65*1332Sbill case 'V': 66*1332Sbill version(); 67*1332Sbill break; 68*1332Sbill 69*1332Sbill case 'M': 70*1332Sbill if (args[0]) { 71*1332Sbill setmap(args); 72*1332Sbill } else { 73*1332Sbill printmap("? map", &txtmap); 74*1332Sbill printmap("/ map", &datmap); 75*1332Sbill } 76*1332Sbill break; 77*1332Sbill 78*1332Sbill case 'x': 79*1332Sbill printregs(); 80*1332Sbill break; 81*1332Sbill 82*1332Sbill case 'X': 83*1332Sbill printpc(); 84*1332Sbill break; 85*1332Sbill 86*1332Sbill case 'a': 87*1332Sbill if (integ) { 88*1332Sbill cpstr(args, "l\n"); 89*1332Sbill } else if (proc[0]) { 90*1332Sbill cpall(args, "T\n"); 91*1332Sbill } else { 92*1332Sbill error("Bad arguments"); 93*1332Sbill break; 94*1332Sbill } 95*1332Sbill goto setbrk; 96*1332Sbill break; 97*1332Sbill 98*1332Sbill case 'l': 99*1332Sbill setcur(1); 100*1332Sbill lastcom = NOCOM; 101*1332Sbill break; 102*1332Sbill 103*1332Sbill case 'T': 104*1332Sbill prfrx(1); 105*1332Sbill lastcom = NOCOM; 106*1332Sbill break; 107*1332Sbill 108*1332Sbill case 't': 109*1332Sbill prframe(); 110*1332Sbill lastcom = NOCOM; 111*1332Sbill break; 112*1332Sbill 113*1332Sbill case 'e': 114*1332Sbill p = args; 115*1332Sbill if (*p == '\0') { 116*1332Sbill #ifndef FLEXNAMES 117*1332Sbill printf("%.16s() in \"%s\"\n", 118*1332Sbill curproc()->pname, curfile); 119*1332Sbill #else 120*1332Sbill printf("%s() in \"%s\"\n", 121*1332Sbill curproc()->pname, curfile); 122*1332Sbill #endif 123*1332Sbill break; 124*1332Sbill } 125*1332Sbill 126*1332Sbill while (*p != '\0') 127*1332Sbill if (*p++ == '.') goto l1; 128*1332Sbill /* argument is procedure name */ 129*1332Sbill procp = findproc(args); 130*1332Sbill if ((procp->pname[0] != '\0') && (procp->sfptr != badfile)) { 131*1332Sbill finit(adrtofilep(procp->paddr)->sfilename); 132*1332Sbill ffind(procp->lineno); 133*1332Sbill } 134*1332Sbill else printf("Can't find %s\n", args); 135*1332Sbill #ifndef FLEXNAMES 136*1332Sbill printf("%.16s() in \"%s\"\n", curproc()->pname, curfile); 137*1332Sbill #else 138*1332Sbill printf("%s() in \"%s\"\n", curproc()->pname, curfile); 139*1332Sbill #endif 140*1332Sbill lastcom = PRCOM; 141*1332Sbill break; 142*1332Sbill 143*1332Sbill l1: /* argument is filename */ 144*1332Sbill finit(args); 145*1332Sbill printf("\"%s\"\n", curfile); 146*1332Sbill lastcom = PRCOM; 147*1332Sbill break; 148*1332Sbill 149*1332Sbill case 'p': 150*1332Sbill if (integ) ffind(integ); 151*1332Sbill fprint(); 152*1332Sbill lastcom = PRCOM; 153*1332Sbill break; 154*1332Sbill 155*1332Sbill case 'q': 156*1332Sbill exit(0); 157*1332Sbill 158*1332Sbill case 'w': 159*1332Sbill if (integ) ffind(integ); 160*1332Sbill i = fline; 161*1332Sbill fback(WINDOW/2); 162*1332Sbill fprintn(WINDOW); 163*1332Sbill ffind(i); 164*1332Sbill lastcom = PRCOM; 165*1332Sbill break; 166*1332Sbill 167*1332Sbill case 'Q': 168*1332Sbill prdebug(); 169*1332Sbill break; 170*1332Sbill 171*1332Sbill case 'z': 172*1332Sbill if (integ) ffind(integ); 173*1332Sbill fprintn(WINDOW); 174*1332Sbill lastcom = PRCOM; 175*1332Sbill break; 176*1332Sbill 177*1332Sbill case '-': 178*1332Sbill fback(integ ? integ : 1); 179*1332Sbill fpargs(); 180*1332Sbill lastcom = PRCOM; 181*1332Sbill break; 182*1332Sbill 183*1332Sbill case '+': 184*1332Sbill fforward(integ ? integ : 1); 185*1332Sbill fpargs(); 186*1332Sbill lastcom = PRCOM; 187*1332Sbill break; 188*1332Sbill 189*1332Sbill case '\n': 190*1332Sbill switch (lastcom) { 191*1332Sbill case PRCOM: 192*1332Sbill fforward(1); 193*1332Sbill fprint(); 194*1332Sbill break; 195*1332Sbill case DSCOM: 196*1332Sbill oaddr += oincr ? oincr : typetosize(otype, WORDSIZE); 197*1332Sbill printf("0x%x/ ", oaddr); 198*1332Sbill dispf((ADDR) oaddr, odesc, 199*1332Sbill oclass == N_RSYM ? oclass : N_GSYM, otype, 0, 0, DSP); 200*1332Sbill break; 201*1332Sbill case DSICOM: 202*1332Sbill dot += oincr; 203*1332Sbill prisploc(); 204*1332Sbill dispi(dot, odesc, N_GSYM, 0, 0); 205*1332Sbill break; 206*1332Sbill } 207*1332Sbill break; 208*1332Sbill 209*1332Sbill case '\004': 210*1332Sbill if (!isatty(0)) 211*1332Sbill exit(0); 212*1332Sbill switch (lastcom) { 213*1332Sbill case PRCOM: 214*1332Sbill fforward(1); 215*1332Sbill printf("\b"); 216*1332Sbill fprintn(WINDOW); 217*1332Sbill lastcom = PRCOM; 218*1332Sbill break; 219*1332Sbill case DSICOM: 220*1332Sbill printf("\b"); 221*1332Sbill for (i=0; i<WINDOW; i++) { 222*1332Sbill dot += oincr; 223*1332Sbill prisploc(); 224*1332Sbill if (dispi(dot, odesc, N_GSYM, 0, 0) == -1) 225*1332Sbill break; 226*1332Sbill } 227*1332Sbill break; 228*1332Sbill case DSCOM: 229*1332Sbill printf("\b"); 230*1332Sbill for (i=0; i<WINDOW; i++) { 231*1332Sbill oaddr += oincr ? 232*1332Sbill oincr : typetosize(otype, WORDSIZE); 233*1332Sbill printf("0x%x/ ", oaddr); 234*1332Sbill if (dispf((ADDR) oaddr, odesc, 235*1332Sbill oclass == N_RSYM ? oclass : 236*1332Sbill N_GSYM, otype, 0, 0, DSP) == -1) 237*1332Sbill break; 238*1332Sbill } 239*1332Sbill break; 240*1332Sbill default: 241*1332Sbill printf("\n"); 242*1332Sbill } 243*1332Sbill break; 244*1332Sbill 245*1332Sbill case 'r': 246*1332Sbill if (args[0] == '\0') getargs(); 247*1332Sbill case 'R': 248*1332Sbill signo = 0; 249*1332Sbill cpstr(oldargs, args); 250*1332Sbill if (debug) error("calling dopcs"); 251*1332Sbill if (integ) cntval = integ; 252*1332Sbill if (!executing) { 253*1332Sbill executing = TRUE; 254*1332Sbill if (integ) cntval = integ; 255*1332Sbill dopcs('r'); 256*1332Sbill executing = FALSE; 257*1332Sbill } 258*1332Sbill if (debug) error("exiting dopcs"); 259*1332Sbill bkaddr = -1; 260*1332Sbill goto f1; 261*1332Sbill 262*1332Sbill case 'c': 263*1332Sbill signo = 0; 264*1332Sbill case 'C': 265*1332Sbill if (proc[0] != '\0' || integ != 0) { 266*1332Sbill setdot(); 267*1332Sbill if (dot == -1) { 268*1332Sbill error("Cannot set temporary breakpoint"); 269*1332Sbill break; 270*1332Sbill } 271*1332Sbill dopcs('b'); 272*1332Sbill bkaddr = dot; 273*1332Sbill } else 274*1332Sbill bkaddr = -1; 275*1332Sbill integ = atoi(args); 276*1332Sbill 277*1332Sbill f1: if (debug) error("calling dopcs"); 278*1332Sbill if (integ) cntval = integ; 279*1332Sbill dopcs('c'); 280*1332Sbill if (debug) error("exiting dopcs"); 281*1332Sbill if (bkaddr != -1) { 282*1332Sbill ADDR dotsave; 283*1332Sbill dotsave = dot; 284*1332Sbill dot = bkaddr; 285*1332Sbill dopcs('d'); 286*1332Sbill dot = dotsave; 287*1332Sbill } 288*1332Sbill if (!signo) printf("Breakpoint"); 289*1332Sbill printf(" at\n"); 290*1332Sbill setcur(1); 291*1332Sbill lastcom = NOCOM; 292*1332Sbill break; 293*1332Sbill 294*1332Sbill case 'S': 295*1332Sbill case 's': 296*1332Sbill signo = 0; 297*1332Sbill integ = atoi(args); 298*1332Sbill singstep(integ ? integ : 1, cmd); 299*1332Sbill if (signo) printf("\n"); 300*1332Sbill setcur(1); 301*1332Sbill lastcom = NOCOM; 302*1332Sbill break; 303*1332Sbill 304*1332Sbill case 'g': 305*1332Sbill if (pid == 0 || signo) { 306*1332Sbill error("Not stopped at breakpoint"); 307*1332Sbill break; 308*1332Sbill } 309*1332Sbill setdot(); 310*1332Sbill if (dot == -1) { 311*1332Sbill error("Bad address"); 312*1332Sbill break; 313*1332Sbill } 314*1332Sbill adrflg = 1; 315*1332Sbill integ = atoi(args); 316*1332Sbill if (integ) cntval = integ; 317*1332Sbill dopcs('c'); 318*1332Sbill if (!signo) printf("Breakpoint"); 319*1332Sbill printf(" at\n"); 320*1332Sbill setcur(1); 321*1332Sbill lastcom = NOCOM; 322*1332Sbill break; 323*1332Sbill 324*1332Sbill case 'k': 325*1332Sbill if (scallx) { 326*1332Sbill userpc = dot = *(ADDR *)(((ADDR)&u)+PC) = pcs; 327*1332Sbill *(ADDR *)(((ADDR)&u)+FP) = fps; 328*1332Sbill *(ADDR *)(((ADDR)&u)+AP) = aps; 329*1332Sbill if (bkpts) 330*1332Sbill bkpts->flag = flagss; 331*1332Sbill scallx = 0; 332*1332Sbill error("Procedure killed"); 333*1332Sbill longjmp(env, 0); 334*1332Sbill } else { 335*1332Sbill dopcs('k'); 336*1332Sbill printf("\n"); 337*1332Sbill lastcom = NOCOM; 338*1332Sbill break; 339*1332Sbill } 340*1332Sbill 341*1332Sbill case 'B': 342*1332Sbill prbkpt(); 343*1332Sbill break; 344*1332Sbill 345*1332Sbill case 'b': 346*1332Sbill setbrk: 347*1332Sbill if (proc[0] == '\0' && integ == 0) { 348*1332Sbill integ = fline; 349*1332Sbill } 350*1332Sbill setdot(); 351*1332Sbill if (dot == -1 || dot == 0) { 352*1332Sbill error("Cannot set breakpoint"); 353*1332Sbill break; 354*1332Sbill } 355*1332Sbill dopcs('b'); 356*1332Sbill s[0] = ' '; 357*1332Sbill s[1] = cmd; 358*1332Sbill s[2] = '\n'; 359*1332Sbill s[3] = 0; 360*1332Sbill s[1] = cmd; 361*1332Sbill printbkpt(s, adrtoprocp(dot), dot); 362*1332Sbill break; 363*1332Sbill 364*1332Sbill case 'd': 365*1332Sbill if (proc[0] == '\0' && integ == 0) { 366*1332Sbill idbkpt(); 367*1332Sbill break; 368*1332Sbill } 369*1332Sbill setdot(); 370*1332Sbill if (dot == -1) { 371*1332Sbill error("Non existent breakpoint"); 372*1332Sbill break; 373*1332Sbill } 374*1332Sbill dopcs('d'); 375*1332Sbill break; 376*1332Sbill 377*1332Sbill case 'D': 378*1332Sbill dabkpt(); 379*1332Sbill error("All breakpoints deleted"); 380*1332Sbill break; 381*1332Sbill 382*1332Sbill case 'm': 383*1332Sbill addr = varaddr(proc[0] ? proc : curproc()->pname, var); 384*1332Sbill printf("stopped with value %d\n", monex(addr, 'd')); 385*1332Sbill setcur(1); 386*1332Sbill lastcom = NOCOM; 387*1332Sbill break; 388*1332Sbill 389*1332Sbill case '?': 390*1332Sbill if (!(var[0] == '.' && var[1] == '\0')) 391*1332Sbill setdot(); 392*1332Sbill if (errflg) { 393*1332Sbill error(errflg); 394*1332Sbill break; 395*1332Sbill } 396*1332Sbill prisploc(); 397*1332Sbill dispi(dot, args[0] ? args : "i", N_GSYM, 0, 0); 398*1332Sbill lastcom = DSICOM; 399*1332Sbill break; 400*1332Sbill 401*1332Sbill case '/': 402*1332Sbill if (var[0] == '.' && var[1] == '\0') { 403*1332Sbill if (integ == 0) integ = oaddr; 404*1332Sbill dispf((ADDR) integ, args[0] ? args : odesc, 405*1332Sbill oclass == N_RSYM ? oclass : N_GSYM, otype, 0, 0, DSP); 406*1332Sbill oaddr = integ; 407*1332Sbill } else 408*1332Sbill if (integ && (var[0] == '\0')) { 409*1332Sbill dispf((ADDR) integ, args, N_GSYM, 0, 0, 0, DSP); 410*1332Sbill oaddr = integ; 411*1332Sbill cpstr(odesc, args); 412*1332Sbill oclass = N_GSYM; 413*1332Sbill otype = 0; 414*1332Sbill } else 415*1332Sbill dispvar(proc, var, args); 416*1332Sbill lastcom = DSCOM; 417*1332Sbill break; 418*1332Sbill 419*1332Sbill case '=': 420*1332Sbill if (var[0] == '\0') { 421*1332Sbill if (proc[0]) { 422*1332Sbill addr = getaddr(proc, integ); 423*1332Sbill if (addr == -1) { 424*1332Sbill error("Unknown address"); 425*1332Sbill break; 426*1332Sbill } 427*1332Sbill } 428*1332Sbill else 429*1332Sbill addr = integ; 430*1332Sbill dispf(addr, args[0] ? args : "x", 0, -1, 0, 0, DSP); 431*1332Sbill } else 432*1332Sbill findvar(proc, var, args[0] ? args : "x", 2); 433*1332Sbill break; 434*1332Sbill 435*1332Sbill case '!': 436*1332Sbill if (var[0] == '\0') 437*1332Sbill addr = getaddr(proc, integ); 438*1332Sbill else 439*1332Sbill addr = varaddr(proc, var); 440*1332Sbill if (addr == -1) 441*1332Sbill error("Unknown variable"); 442*1332Sbill else { 443*1332Sbill if (number(args[0]) || eqany(args[0], ".-")) { 444*1332Sbill char *p; 445*1332Sbill double atof(); 446*1332Sbill union { 447*1332Sbill struct{ 448*1332Sbill int w1, w2; 449*1332Sbill } ww; 450*1332Sbill double d; 451*1332Sbill } dbl; 452*1332Sbill 453*1332Sbill p = (args[0] == '-') ? args+1 : args; 454*1332Sbill for (; *p != '.' && *p != 'e'; p++) { 455*1332Sbill if (!number(*p)) goto l2; 456*1332Sbill } 457*1332Sbill dbl.d = atof(args); 458*1332Sbill putval(addr, 'd', dbl.ww.w1); 459*1332Sbill if (typetodesc(sl_type,0)[0] == 'g') 460*1332Sbill putval(addr+WORDSIZE, 'd', dbl.ww.w2); 461*1332Sbill break; 462*1332Sbill } 463*1332Sbill l2: if (percentflag) 464*1332Sbill *(ADDR *)(((ADDR)&u)+addr) = argvalue(args); 465*1332Sbill else if (sl_class == N_RSYM && addr < 16) 466*1332Sbill putreg(addr,typetodesc(sl_type,subflag)[0], 467*1332Sbill argvalue(args)); 468*1332Sbill else 469*1332Sbill putval(addr,typetodesc(sl_type,subflag)[0], 470*1332Sbill argvalue(args)); 471*1332Sbill } 472*1332Sbill lastcom = NOCOM; 473*1332Sbill break; 474*1332Sbill 475*1332Sbill case '"': 476*1332Sbill printf(args); 477*1332Sbill break; 478*1332Sbill } 479*1332Sbill } 480*1332Sbill 481*1332Sbill fpargs() { 482*1332Sbill register int i; 483*1332Sbill 484*1332Sbill switch(args[0]) { 485*1332Sbill case 'p': 486*1332Sbill case '\0': 487*1332Sbill fprint(); 488*1332Sbill break; 489*1332Sbill case 'w': 490*1332Sbill i = fline; 491*1332Sbill fback(WINDOW/2); 492*1332Sbill fprintn(WINDOW); 493*1332Sbill ffind(i); 494*1332Sbill break; 495*1332Sbill case 'z': 496*1332Sbill fprintn(WINDOW); 497*1332Sbill break; 498*1332Sbill } 499*1332Sbill } 500*1332Sbill 501*1332Sbill MSG BADTXT; 502*1332Sbill /* Used by a, b, c, C, d and g commands to find linenumber */ 503*1332Sbill setdot() { 504*1332Sbill if (ncolonflag) { 505*1332Sbill dot = integ; 506*1332Sbill get(dot, ISP); 507*1332Sbill if (errflg) 508*1332Sbill dot = -1; 509*1332Sbill } else { 510*1332Sbill dot = getaddr(proc, integ); 511*1332Sbill if (dot == -1) 512*1332Sbill errflg = "Bad line number"; 513*1332Sbill } 514*1332Sbill } 515