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