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