1*1331Sbill static char sccsid[] = "@(#)display.c 4.1 10/09/80"; 2*1331Sbill #include "head.h" 3*1331Sbill #include <a.out.h> 4*1331Sbill #include <stab.h> 5*1331Sbill #include "cdefs.h" 6*1331Sbill struct user u; 7*1331Sbill BKPTR bkpthead; 8*1331Sbill 9*1331Sbill #ifdef FLEXNAMES 10*1331Sbill #define bread(a,b,c) stread(b,c) 11*1331Sbill #define blseek(a,b,c) stseek(b,c) 12*1331Sbill #endif 13*1331Sbill 14*1331Sbill /* initialize frame pointers to top of call stack */ 15*1331Sbill /* MACHINE DEPENDENT */ 16*1331Sbill struct proct * 17*1331Sbill initframe() { 18*1331Sbill argp = *(ADDR *) (((ADDR) &u) + AP); 19*1331Sbill frame = *(ADDR *) (((ADDR) &u) + FP); 20*1331Sbill callpc = *(ADDR *) (((ADDR) &u) + PC); 21*1331Sbill if ((frame == 0) || (frame & 0xf0000000 != 0x70000000)) 22*1331Sbill return(badproc); 23*1331Sbill return(adrtoprocp(callpc++)); /* ++ because UNIX backs up instrs */ 24*1331Sbill } 25*1331Sbill 26*1331Sbill 27*1331Sbill struct proct * 28*1331Sbill nextframe() { 29*1331Sbill callpc = get(frame+16, DSP); 30*1331Sbill argp = get(frame+8, DSP); 31*1331Sbill frame = get(frame+12, DSP) & EVEN; 32*1331Sbill if (callpc > 0x70000000) { /* error handler kludge */ 33*1331Sbill callpc = get(argp+12, DSP); 34*1331Sbill argp = get(frame+8, DSP); 35*1331Sbill frame = get(frame+12, DSP) & EVEN; 36*1331Sbill } 37*1331Sbill if ((frame == 0) || (frame & 0xf0000000 != 0x70000000)) 38*1331Sbill return(badproc); 39*1331Sbill return(adrtoprocp(callpc-1)); 40*1331Sbill } 41*1331Sbill 42*1331Sbill /* returns core image address for variable */ 43*1331Sbill /* MACHINE DEPENDENT */ 44*1331Sbill ADDR 45*1331Sbill formaddr(class, addr) 46*1331Sbill register char class; 47*1331Sbill ADDR addr; { 48*1331Sbill if (debug) printf("formaddr(%o, %d)\n", class & 0377, addr); 49*1331Sbill switch(class & STABMASK) { 50*1331Sbill case N_RSYM: 51*1331Sbill return(stackreg(addr)); 52*1331Sbill case N_GSYM: 53*1331Sbill case N_SSYM: 54*1331Sbill case N_STSYM: 55*1331Sbill case N_LCSYM: 56*1331Sbill return(addr); 57*1331Sbill 58*1331Sbill case N_PSYM: 59*1331Sbill return(argp+addr); 60*1331Sbill 61*1331Sbill case N_LSYM: 62*1331Sbill return(frame+addr); 63*1331Sbill 64*1331Sbill default: 65*1331Sbill printf("Bad class in formaddr: 0%o", 66*1331Sbill class & 0377); 67*1331Sbill return(0); 68*1331Sbill } 69*1331Sbill } 70*1331Sbill 71*1331Sbill char class; 72*1331Sbill 73*1331Sbill /* 74*1331Sbill * stackreg(reg): 75*1331Sbill * If the register for the current frame is somewhere on the stack 76*1331Sbill * then return the address of where it is, otherwise its still in 77*1331Sbill * the register so return the register number. 78*1331Sbill * We distinguish the two by noting that register numbers are less 79*1331Sbill * than 16 and that stack addresses are greater. 80*1331Sbill * 81*1331Sbill * MACHINE DEPENDENT 82*1331Sbill */ 83*1331Sbill ADDR 84*1331Sbill stackreg(reg) { 85*1331Sbill register int curframe, regfl, mask, i; 86*1331Sbill struct proct *procp; 87*1331Sbill ADDR regaddr; 88*1331Sbill 89*1331Sbill curframe = frame; 90*1331Sbill regaddr = reg; 91*1331Sbill regfl = 0x10000 << reg; 92*1331Sbill for (procp=initframe(); frame!=curframe; procp=nextframe()) { 93*1331Sbill if (procp == badproc) { 94*1331Sbill error("Stackreg error: frame"); 95*1331Sbill return(-1); 96*1331Sbill } 97*1331Sbill mask = get(frame+4, DSP); 98*1331Sbill if (mask & regfl) { 99*1331Sbill regaddr = frame + 20; 100*1331Sbill for (i=0; i<reg; i++) { 101*1331Sbill if (mask & 0x10000) 102*1331Sbill regaddr += WORDSIZE; 103*1331Sbill mask = mask >> 1; 104*1331Sbill } 105*1331Sbill if (!(mask & 0x10000)) { 106*1331Sbill error("Stackreg error: contents"); 107*1331Sbill return(-1); 108*1331Sbill } 109*1331Sbill } 110*1331Sbill } 111*1331Sbill return(regaddr); 112*1331Sbill } 113*1331Sbill 114*1331Sbill /* returns address of proc:var. Sets externals class and subflag */ 115*1331Sbill ADDR 116*1331Sbill varaddr(proc, var) 117*1331Sbill char *proc, *var; { 118*1331Sbill return(findvar(proc, var, "", 0)); 119*1331Sbill } 120*1331Sbill 121*1331Sbill /* 122*1331Sbill * displays values of variables matching proc:var, 123*1331Sbill * returns its address 124*1331Sbill */ 125*1331Sbill ADDR 126*1331Sbill dispvar(proc, var, fmt) 127*1331Sbill char *proc, *var, *fmt; { 128*1331Sbill return(findvar(proc, var, fmt, 1)); 129*1331Sbill } 130*1331Sbill 131*1331Sbill /* 132*1331Sbill * Find and print values of all variables matching proc:var 133*1331Sbill * using specified format. 134*1331Sbill * Returns address of last matching variable. 135*1331Sbill * 136*1331Sbill * prvar==0 => no output, 137*1331Sbill * prvar==1 => output value, 138*1331Sbill * prvar==2 => output addr 139*1331Sbill */ 140*1331Sbill ADDR 141*1331Sbill findvar(proc, var, fmt, prvar) 142*1331Sbill char *proc, *var, *fmt; { 143*1331Sbill ADDR addr = -1, a = -1; 144*1331Sbill int metaflag = 0, match=0, nullflag=0, depthcnt = -1; 145*1331Sbill char *comblk; 146*1331Sbill register struct proct *procp; 147*1331Sbill 148*1331Sbill if (percentflag) { /* kludge for register names */ 149*1331Sbill return(regout(var, prvar, fmt)); 150*1331Sbill } 151*1331Sbill 152*1331Sbill if (var[0] == '\0') { 153*1331Sbill error("Unexpected null variable name"); 154*1331Sbill return(-1); 155*1331Sbill } 156*1331Sbill 157*1331Sbill metaflag = eqany('*', proc) || eqany('?', proc) || 158*1331Sbill eqany('*', var) || eqany('?', var); 159*1331Sbill 160*1331Sbill if (proc[0] == '\0') { 161*1331Sbill nullflag++; 162*1331Sbill proc = curproc()->pname; 163*1331Sbill } 164*1331Sbill 165*1331Sbill comblk = colonflag ? "" : "*"; 166*1331Sbill 167*1331Sbill if (integ && !eqany(var[0], "->.[")) { 168*1331Sbill depthcnt = integ; 169*1331Sbill } 170*1331Sbill if (integ) { 171*1331Sbill if (eqany(var[0], "->.[")) 172*1331Sbill match++; 173*1331Sbill else 174*1331Sbill depthcnt = integ; 175*1331Sbill } 176*1331Sbill 177*1331Sbill procp = initframe(); 178*1331Sbill if (!eqany(var[0], "->.[") && !(nullflag && colonflag)) { 179*1331Sbill do { 180*1331Sbill if (eqpat(proc, procp->pname)) { 181*1331Sbill match++; 182*1331Sbill if (--depthcnt==0 || integ==0) { 183*1331Sbill a = outvar(procp->pname, var, fmt, 184*1331Sbill metaflag, integ, N_GSYM, 185*1331Sbill 0, prname, comblk, prvar); 186*1331Sbill if (a != -1) 187*1331Sbill addr = a; 188*1331Sbill if (depthcnt == 0) 189*1331Sbill break; 190*1331Sbill } 191*1331Sbill } 192*1331Sbill } while ((procp=nextframe()) != badproc); 193*1331Sbill } 194*1331Sbill 195*1331Sbill if ((colonflag || metaflag || a == -1) && 196*1331Sbill (nullflag || eqpat(proc, ""))) { 197*1331Sbill a = outvar("", var, fmt, metaflag, integ, 198*1331Sbill N_GSYM, 0, prname, comblk, prvar); 199*1331Sbill if (a != -1) { 200*1331Sbill addr = a; 201*1331Sbill match++; 202*1331Sbill } 203*1331Sbill } 204*1331Sbill 205*1331Sbill if (match==0 && colonflag) { 206*1331Sbill procp = initframe(); 207*1331Sbill do { 208*1331Sbill if (eqstr(curproc()->pname, procp->pname)) 209*1331Sbill break; 210*1331Sbill } while ((procp=nextframe()) != badproc); 211*1331Sbill a = outvar(curproc()->pname, var, fmt, metaflag, 212*1331Sbill integ, N_GSYM, 0, prname, 213*1331Sbill nullflag ? "_BLNK_" : proc, prvar); 214*1331Sbill if (a != -1) { 215*1331Sbill addr = a; 216*1331Sbill match++; 217*1331Sbill } 218*1331Sbill } 219*1331Sbill 220*1331Sbill if (addr == -1 && match == 0) { 221*1331Sbill addr = extoutvar(var, fmt, metaflag, prvar); 222*1331Sbill if (addr != -1) 223*1331Sbill return(addr); 224*1331Sbill } 225*1331Sbill if (match == 0) { 226*1331Sbill printf("%s not an active procedure\n", proc); 227*1331Sbill return(-1); 228*1331Sbill } 229*1331Sbill if (addr == -1) { 230*1331Sbill if (var[0] == '.') 231*1331Sbill var++; 232*1331Sbill if (proc[0]) 233*1331Sbill #ifndef FLEXNAMES 234*1331Sbill printf("%.16s:%s not found\n", proc, var); 235*1331Sbill #else 236*1331Sbill printf("%s:%s not found\n", proc, var); 237*1331Sbill #endif 238*1331Sbill else 239*1331Sbill printf("%s not found\n", var); 240*1331Sbill return(-1); 241*1331Sbill } 242*1331Sbill return(addr); 243*1331Sbill } 244*1331Sbill 245*1331Sbill char * 246*1331Sbill typetodesc(type, subflag) 247*1331Sbill short type; { 248*1331Sbill register int ptr, ftn, ary; 249*1331Sbill register char *desc; 250*1331Sbill 251*1331Sbill static char *typedesc[] = { 252*1331Sbill "d", /* undef */ 253*1331Sbill "d", /* farg */ 254*1331Sbill "c", /* char */ 255*1331Sbill "hd", /* short */ 256*1331Sbill "d", /* int */ 257*1331Sbill "ld", /* long */ 258*1331Sbill "f", /* float */ 259*1331Sbill "g", /* double */ 260*1331Sbill "d", /* strty */ 261*1331Sbill "d", /* unionty */ 262*1331Sbill "d", /* enumty */ 263*1331Sbill "d", /* moety */ 264*1331Sbill "bu", /* uchar */ 265*1331Sbill "hu", /* ushort */ 266*1331Sbill "u", /* unsigned */ 267*1331Sbill "lu", /* ulong */ 268*1331Sbill "d" /* ? */ 269*1331Sbill }; 270*1331Sbill 271*1331Sbill ptr = ftn = ary = 0; 272*1331Sbill 273*1331Sbill desc = typedesc[type&BTMASK]; 274*1331Sbill for (; type & TMASK; type = DECREF(type)) { 275*1331Sbill if (ISPTR(type)) ptr++; 276*1331Sbill else if (ISFTN(type)) ftn++; 277*1331Sbill else if (ISARY(type)) ary++; 278*1331Sbill } 279*1331Sbill 280*1331Sbill if ((ptr-subflag == 1 || ary-subflag == 1) && desc[0] == 'c') 281*1331Sbill return("s"); 282*1331Sbill if (debug) 283*1331Sbill printf ("PTR %d; FTN %d; ARY %d; DESC %s\n",ptr,ftn,ary,desc); 284*1331Sbill if (ptr + ary == subflag) 285*1331Sbill return(desc); 286*1331Sbill if (ptr) return("x"); 287*1331Sbill if (ptr==1 && ftn==1) return("p"); 288*1331Sbill return(desc); 289*1331Sbill } 290*1331Sbill 291*1331Sbill typetosize(type, stsize) 292*1331Sbill short type; { 293*1331Sbill register int ptr, ftn, ary; 294*1331Sbill register int size; 295*1331Sbill 296*1331Sbill static char typesize[] = { 297*1331Sbill 4, /* undef */ 298*1331Sbill 4, /* farg */ 299*1331Sbill 1, /* char */ 300*1331Sbill 2, /* short */ 301*1331Sbill WORDSIZE, /* int */ 302*1331Sbill 4, /* long */ 303*1331Sbill 4, /* float */ 304*1331Sbill 8, /* double */ 305*1331Sbill 0, /* strty */ 306*1331Sbill 0, /* unionty */ 307*1331Sbill 4, /* enumty */ 308*1331Sbill 4, /* moety */ 309*1331Sbill 1, /* uchar */ 310*1331Sbill 2, /* ushort */ 311*1331Sbill 4, /* unsigned */ 312*1331Sbill 4, /* ulong */ 313*1331Sbill 4 /* ? */ 314*1331Sbill }; 315*1331Sbill 316*1331Sbill ptr = ftn = ary = 0; 317*1331Sbill 318*1331Sbill size = typesize[type&BTMASK]; 319*1331Sbill for (; type & TMASK; type = DECREF(type)) { 320*1331Sbill if (ISPTR(type)) ptr++; 321*1331Sbill else if (ISFTN(type)) ftn++; 322*1331Sbill else if (ISARY(type)) ary++; 323*1331Sbill } 324*1331Sbill 325*1331Sbill if (debug) 326*1331Sbill printf ("PTR %d; FTN %d; ARY %d; SIZE %d; STSIZE %d\n", 327*1331Sbill ptr,ftn,ary,size,stsize); 328*1331Sbill if (ptr>1) return(4); 329*1331Sbill if (size == 0) return(stsize); 330*1331Sbill else return(size); 331*1331Sbill } 332*1331Sbill 333*1331Sbill 334*1331Sbill /* print breakpoints */ 335*1331Sbill prbkpt() { 336*1331Sbill register BKPTR bkptr; 337*1331Sbill register int cnt; 338*1331Sbill char *cmdp; 339*1331Sbill 340*1331Sbill cnt = 0; 341*1331Sbill 342*1331Sbill for (bkptr = bkpthead; bkptr; bkptr=bkptr->nxtbkpt) 343*1331Sbill if (bkptr->flag) { 344*1331Sbill cnt++; 345*1331Sbill printbkpt("", adrtoprocp(bkptr->loc), bkptr->loc); 346*1331Sbill cmdp = bkptr->comm; 347*1331Sbill if (*cmdp != '\n') { 348*1331Sbill printf(" <"); 349*1331Sbill while (*cmdp != '\n') 350*1331Sbill printf("%c", *cmdp++); 351*1331Sbill printf(">\n"); 352*1331Sbill } 353*1331Sbill else 354*1331Sbill printf("\n"); 355*1331Sbill } 356*1331Sbill if (cnt == 0) 357*1331Sbill printf("No breakpoints set\n"); 358*1331Sbill } 359*1331Sbill 360*1331Sbill /* interactively delete breakpoints */ 361*1331Sbill 362*1331Sbill idbkpt() { 363*1331Sbill register BKPTR bkptr; 364*1331Sbill register int yesflg, cnt; 365*1331Sbill register char c; 366*1331Sbill 367*1331Sbill cnt = 0; 368*1331Sbill 369*1331Sbill for (bkptr = bkpthead; bkptr; bkptr=bkptr->nxtbkpt) 370*1331Sbill if (bkptr->flag) { 371*1331Sbill printbkpt(" ? ", adrtoprocp(bkptr->loc), bkptr->loc); 372*1331Sbill yesflg = 0; 373*1331Sbill cnt++; 374*1331Sbill do { 375*1331Sbill c = getchar(); 376*1331Sbill if (c == 'y' || c == 'd') yesflg++; 377*1331Sbill } while (c != '\n'); 378*1331Sbill if (yesflg) 379*1331Sbill bkptr->flag = 0; 380*1331Sbill } 381*1331Sbill if (cnt == 0) 382*1331Sbill printf("No breakpoints set\n"); 383*1331Sbill } 384*1331Sbill 385*1331Sbill /* delete all breakpoints */ 386*1331Sbill 387*1331Sbill dabkpt() { 388*1331Sbill register BKPTR bkptr; 389*1331Sbill 390*1331Sbill for (bkptr = bkpthead; bkptr; bkptr=bkptr->nxtbkpt) 391*1331Sbill bkptr->flag = 0; 392*1331Sbill } 393*1331Sbill 394*1331Sbill /* 395*1331Sbill * Print name of breakpoint for a, b, d commands: 396*1331Sbill */ 397*1331Sbill printbkpt(s, procp, dot) 398*1331Sbill char *s; struct proct *procp; ADDR dot; { 399*1331Sbill adrtolineno(dot); 400*1331Sbill if (dot != lnfaddr) 401*1331Sbill printf("0x%x (", dot); 402*1331Sbill prlnoff(procp, dot); 403*1331Sbill if (dot != lnfaddr) 404*1331Sbill printf(")"); 405*1331Sbill printf("%s", s); 406*1331Sbill } 407*1331Sbill 408*1331Sbill /* print call frame */ 409*1331Sbill prframe() { 410*1331Sbill prfrx(0); 411*1331Sbill } 412*1331Sbill 413*1331Sbill /* set top to print just the top procedure */ 414*1331Sbill prfrx(top) { 415*1331Sbill int narg; 416*1331Sbill long offset; 417*1331Sbill register char class; 418*1331Sbill register int endflg; 419*1331Sbill char *p; 420*1331Sbill struct proct *procp; 421*1331Sbill struct nlist stentry; 422*1331Sbill 423*1331Sbill if ((procp = initframe()) == badproc) return; 424*1331Sbill do { 425*1331Sbill if (get(frame+12, DSP) == 0) return; 426*1331Sbill p = procp->pname; 427*1331Sbill if (eqstr("__dbsubc", p)) return; 428*1331Sbill if (p[0] == '_') { 429*1331Sbill endflg = 1; 430*1331Sbill #ifndef FLEXNAMES 431*1331Sbill printf("%.15s(", p+1); 432*1331Sbill #else 433*1331Sbill printf("%s(", p+1); 434*1331Sbill #endif 435*1331Sbill } 436*1331Sbill else { 437*1331Sbill #ifndef FLEXNAMES 438*1331Sbill printf("%.16s(", p); 439*1331Sbill #else 440*1331Sbill printf("%s(", p); 441*1331Sbill #endif 442*1331Sbill endflg = 0; 443*1331Sbill } 444*1331Sbill if (endflg == 0) { 445*1331Sbill offset = procp->st_offset; 446*1331Sbill blseek(&sbuf, offset, 0); 447*1331Sbill do { 448*1331Sbill if (bread(&sbuf, &stentry, sizeof stentry) < 449*1331Sbill sizeof stentry) { 450*1331Sbill endflg++; 451*1331Sbill break; 452*1331Sbill } 453*1331Sbill class = stentry.n_type & STABMASK; 454*1331Sbill } while (class == N_FUN); 455*1331Sbill while (class != N_PSYM) { 456*1331Sbill if (bread(&sbuf, &stentry, sizeof stentry) < 457*1331Sbill sizeof stentry) { 458*1331Sbill endflg++; 459*1331Sbill break; 460*1331Sbill } 461*1331Sbill class = stentry.n_type & STABMASK; 462*1331Sbill if (class == N_FUN) { 463*1331Sbill endflg++; 464*1331Sbill break; 465*1331Sbill } 466*1331Sbill } 467*1331Sbill } 468*1331Sbill 469*1331Sbill narg = get(argp, DSP); 470*1331Sbill if (narg & ~0xff) narg = 0; 471*1331Sbill argp += WORDSIZE; 472*1331Sbill while (narg) { 473*1331Sbill if (endflg) { 474*1331Sbill printf("%d", get(argp, DSP)); 475*1331Sbill argp += 4; 476*1331Sbill } else { 477*1331Sbill int length; 478*1331Sbill #ifndef FLEXNAMES 479*1331Sbill printf("%.16s=", stentry.n_name); 480*1331Sbill #else 481*1331Sbill printf("%s=", stentry.n_un.n_name); 482*1331Sbill #endif 483*1331Sbill dispx(argp, "", N_GSYM, stentry.n_desc, 484*1331Sbill 0, 0, DSP); 485*1331Sbill length = typetosize(stentry.n_desc, 0); 486*1331Sbill if (length > WORDSIZE) 487*1331Sbill argp += length; 488*1331Sbill else 489*1331Sbill argp += WORDSIZE; 490*1331Sbill } 491*1331Sbill do { 492*1331Sbill if (endflg) break; 493*1331Sbill if (bread(&sbuf, &stentry, sizeof stentry) < 494*1331Sbill sizeof stentry) { 495*1331Sbill endflg++; 496*1331Sbill break; 497*1331Sbill } 498*1331Sbill class = stentry.n_type & STABMASK; 499*1331Sbill if (class == N_FUN) { 500*1331Sbill endflg++; 501*1331Sbill break; 502*1331Sbill } 503*1331Sbill } while (class != N_PSYM); 504*1331Sbill l1: if (--narg != 0) printf(","); 505*1331Sbill } 506*1331Sbill printf(")"); 507*1331Sbill if (debug) printf(" @ 0x%x ", callpc); 508*1331Sbill if (procp->sfptr != badfile) 509*1331Sbill printf(" [%s:%d]", adrtofilep(callpc-1)->sfilename, 510*1331Sbill adrtolineno(callpc-1)); 511*1331Sbill printf("\n"); 512*1331Sbill } while (((procp = nextframe()) != badproc) && !top); 513*1331Sbill } 514*1331Sbill 515*1331Sbill INT signo; 516*1331Sbill STRING signals[]; 517*1331Sbill extern nsig; 518*1331Sbill sigprint() 519*1331Sbill { 520*1331Sbill 521*1331Sbill if (signo < nsig) 522*1331Sbill printf("%s", signals[signo]); 523*1331Sbill else 524*1331Sbill printf("signal %d???", signals[signo]); 525*1331Sbill } 526