|
|
1.1 ! root 1: /* ! 2: * machine-dependent code for ! 3: * looking in stack frames ! 4: * vax version ! 5: */ ! 6: ! 7: #include "defs.h" ! 8: #include <sys/param.h> ! 9: #include "regs.h" ! 10: #include "sym.h" ! 11: #include "space.h" ! 12: ! 13: int maxargs = 20; ! 14: ! 15: /* ! 16: * VAX stack frame ! 17: */ ! 18: ! 19: #define F_PSW 4 ! 20: #define F_FLAGS 6 ! 21: #define F_AP 8 /* saved ap */ ! 22: #define F_FP 12 /* saved fp */ ! 23: #define F_PC 16 /* return pc */ ! 24: #define F_REGS 20 /* saved regs, if any */ ! 25: ! 26: /* ! 27: * flags ! 28: */ ! 29: ! 30: #define FFREGS 0x1fff /* saved register flags; 01 is r0 */ ! 31: #define FFCALLS 0x2000 /* called by calls, not callg */ ! 32: #define FFOFF 0xc000 /* offset added to align stack */ ! 33: #define SALIGN(f) (((f)>>14) & 03) ! 34: ! 35: /* ! 36: * is the saved psw reasonable? ! 37: * really just a last resort to find the end of the stack ! 38: */ ! 39: ! 40: #define BADPSW(p) (((p)&0xff00) != 0) ! 41: ! 42: /* ! 43: * is the pc probably in signal trampoline code? ! 44: * == it's in the user block ! 45: */ ! 46: ! 47: #define sigtramp(pc) (0x80000000 > (pc) && (pc) > 0x80000000 - ctob(UPAGES)) ! 48: ! 49: #define F_HACK 64 /* where to find the saved pc in a trampoline frame */ ! 50: /* ! 51: * return an address for a local variable ! 52: * no register vars, unfortunately, as we can't provide an address ! 53: * gn is the procedure; ln the local name ! 54: * ! 55: * this is vax dependent because symbol tables vary ! 56: */ ! 57: ! 58: localaddr(gn, ln) ! 59: char *gn, *ln; ! 60: { ! 61: WORD fp, ap; ! 62: extern WORD expv; ! 63: extern int expsp; ! 64: ADDR laddr(); ! 65: ! 66: if (gn) { ! 67: if (findrtn(gn) == 0) ! 68: error("function not found"); ! 69: } ! 70: else { ! 71: findsym((WORD)atow(rget(PC)), INSTSP); ! 72: if (cursym == NULL) ! 73: error("function not found"); ! 74: } ! 75: if (findframe(&fp, &ap) == 0) ! 76: error("stack frame not found"); ! 77: if (ln == NULL) { ! 78: expsp = 0; ! 79: expv = fp; ! 80: return; ! 81: } ! 82: while (localsym()) { ! 83: if (strcmp(ln, cursym->y_name) != 0) ! 84: continue; ! 85: expv = laddr(cursym, fp, ap); ! 86: if (cursym->y_ltype == S_RSYM) ! 87: expsp = REGSP; ! 88: else ! 89: expsp = NOSP; ! 90: return; ! 91: } ! 92: error("bad local variable"); ! 93: /* NOTREACHED */ ! 94: } ! 95: ! 96: /* ! 97: * print a stack traceback ! 98: * give locals if possible ! 99: */ ! 100: ! 101: ctrace(modif) ! 102: char modif; ! 103: { ! 104: register ADDR fp, ap, callpc; ! 105: register int narg; ! 106: ADDR oap; ! 107: register int fl; ! 108: int tramp; ! 109: ! 110: if (adrflg) { ! 111: fp = adrval; ! 112: fl = stow(sget(fp + F_FLAGS, CORF|DATASP)); ! 113: if ((fl & FFCALLS) == 0) ! 114: ap = fp; /* callg, can't figure out ap */ ! 115: else { ! 116: ap = adrval + F_REGS + SALIGN(fl); ! 117: fl &= FFREGS; ! 118: while (fl) { ! 119: if (fl & 1) ! 120: ap += SZREG; ! 121: fl >>= 1; ! 122: } ! 123: } ! 124: callpc = atow(aget(fp + F_PC, CORF|DATASP)); ! 125: } else { ! 126: ap = (ADDR)rtow(rget(AP)); ! 127: fp = (ADDR)rtow(rget(FP)); ! 128: callpc = (ADDR)rtow(rget(PC)); ! 129: } ! 130: clrraddr(); ! 131: while (cntval--) { ! 132: chkerr(); ! 133: tramp = 0; ! 134: if (sigtramp(callpc)) { ! 135: printf("sigtramp("); ! 136: tramp++; ! 137: } else { ! 138: findsym(callpc, INSTSP); ! 139: if (cursym == NULL) ! 140: printf("?("); ! 141: else if (strcmp("start", cursym->y_name) == 0) ! 142: break; ! 143: else ! 144: printf("%s(", cursym->y_name); ! 145: } ! 146: fl = ctow(cget(ap, CORF|DATASP)); ! 147: if ((narg = fl) > maxargs) ! 148: narg = maxargs; ! 149: oap = ap; ! 150: while (--fl, --narg >= 0) { ! 151: printf("%R", ltow(lget(ap += SZREG, CORF|DATASP))); ! 152: if (narg != 0) ! 153: printc(','); ! 154: } ! 155: if (fl >= 0) ! 156: printf(",..."); ! 157: printf(") from %R\n", callpc); ! 158: if (modif == 'C') ! 159: locals(fp, oap); ! 160: if (tramp) /* hack */ ! 161: callpc = atow(aget(fp + F_HACK, CORF|DATASP)); ! 162: else ! 163: callpc = atow(aget(fp + F_PC, CORF|DATASP)); ! 164: fl = stow(sget(fp + F_FLAGS, CORF|DATASP)); ! 165: setraddr(fl, fp); ! 166: ap = atow(aget(fp + F_AP, CORF|DATASP)); ! 167: fp = atow(aget(fp + F_FP + SALIGN(fl), CORF|DATASP)); ! 168: if (fp == 0) ! 169: break; ! 170: fl = stow(sget(fp + F_PSW, CORF|DATASP)); ! 171: if (BADPSW(fl)) ! 172: break; ! 173: } ! 174: clrraddr(); ! 175: } ! 176: ! 177: static ! 178: locals(fp, ap) ! 179: ADDR fp, ap; ! 180: { ! 181: WORD val; ! 182: register int sp; ! 183: ADDR laddr(); ! 184: ! 185: while (localsym()) { ! 186: sp = CORF | DATASP; ! 187: if (cursym->y_ltype == S_RSYM) ! 188: sp = CORF | REGSP; ! 189: val = ltow(lget(laddr(cursym, fp, ap), sp)); ! 190: if (errflg == 0) ! 191: printf("%8t%s/%10t%R\n", cursym->y_name, val); ! 192: else { ! 193: printf("%8t%s/%10t?\n", cursym->y_name); ! 194: errflg = 0; ! 195: } ! 196: } ! 197: } ! 198: ! 199: static ADDR ! 200: laddr(sp, fp, ap) ! 201: struct sym *sp; ! 202: ADDR fp, ap; ! 203: { ! 204: ! 205: switch (sp->y_ltype) { ! 206: case S_STSYM: ! 207: return (sp->y_value); ! 208: ! 209: case S_LSYM: ! 210: return (fp - sp->y_value); ! 211: ! 212: case S_PSYM: ! 213: return (ap + sp->y_value); ! 214: ! 215: case S_RSYM: ! 216: return (sp->y_value * SZREG); ! 217: } ! 218: error("bad local symbol"); ! 219: /* NOTREACHED */ ! 220: } ! 221: ! 222: static int ! 223: findframe(fpp, app) ! 224: ADDR *fpp, *app; ! 225: { ! 226: register ADDR fp, ap, pc; ! 227: register int fl; ! 228: struct sym *svcur; ! 229: ! 230: svcur = cursym; ! 231: fp = rtow(rget(FP)); ! 232: ap = rtow(rget(AP)); ! 233: pc = rtow(rget(PC)); ! 234: if (errflg) ! 235: return (0); ! 236: clrraddr(); ! 237: for (;;) { ! 238: findsym(pc, INSTSP); ! 239: if (cursym == svcur) ! 240: break; ! 241: if (cursym && strcmp(cursym->y_name, "start") == 0) { ! 242: clrraddr(); ! 243: return (0); ! 244: } ! 245: fl = stow(sget((ADDR)fp + F_FLAGS, CORF|DATASP)); ! 246: setraddr(fl, fp); ! 247: pc = atow(aget(fp + F_PC, CORF|DATASP)); ! 248: ap = atow(aget(fp + F_AP, CORF|DATASP)); ! 249: fp = atow(aget(fp + F_FP + SALIGN(fl), CORF|DATASP)); ! 250: /* sigtramp? */ ! 251: if (errflg) { ! 252: clrraddr(); ! 253: return (0); ! 254: } ! 255: } ! 256: *fpp = fp; ! 257: *app = ap; ! 258: return (1); ! 259: } ! 260: ! 261: /* ! 262: * set addresses for saved registers for this frame ! 263: */ ! 264: ! 265: static ! 266: setraddr(mask, fp) ! 267: register int mask; ! 268: register ADDR fp; ! 269: { ! 270: register int r; ! 271: register int i; ! 272: extern ADDR raddr[]; ! 273: ! 274: mask &= FFREGS; ! 275: for (r = 0, i = 0; mask; r++) ! 276: if (mask & (1 << r)) { ! 277: if (MINREG <= r && r <= MAXREG) ! 278: raddr[r - MINREG] = fp + F_REGS + ! 279: i * SZREG; ! 280: i++; ! 281: mask &=~ (1 << r); ! 282: } ! 283: } ! 284: ! 285: static ! 286: clrraddr() ! 287: { ! 288: register int i; ! 289: extern ADDR raddr[]; ! 290: ! 291: for (i = 0; i <= MAXREG - MINREG; i++) ! 292: raddr[i] = 0; ! 293: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.