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