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