|
|
1.1 ! root 1: /* ! 2: * machine-dependent code for ! 3: * looking in stack frames ! 4: * sequent/32032 version ! 5: */ ! 6: ! 7: #include "defs.h" ! 8: #include "space.h" ! 9: #include <sys/param.h> ! 10: #include "regs.h" ! 11: #include <a.out.h> ! 12: #include "sym.h" ! 13: #include <signal.h> ! 14: ! 15: int maxargs = 20; ! 16: ! 17: /* ! 18: * stuff in the stack frame ! 19: */ ! 20: ! 21: #define F_HACKPC 48 /* signal handler hack */ ! 22: #define F_ARG1 8 /* first argument */ ! 23: #define F_PC 4 ! 24: #define F_FP 0 ! 25: ! 26: /* ! 27: * how to find out the number of arguments to a procedure call: ! 28: * look at the instruction after the call (cxp) ! 29: * it should be an adjspb with an immediate operand ! 30: * the operand (the following byte) is the (negative) number of ! 31: * bytes to be popped off the stack after the call; ! 32: * i.e. the amount of space taken by parameters ! 33: */ ! 34: ! 35: #define adjspbi(x) (((x) & 0xffff) == 0xa57c) ! 36: #define adjoff(x) ((((x) & 0xff0000) >> 16) | 0xffffff00) ! 37: ! 38: /* ! 39: * return an address for a local variable ! 40: * no register vars, unfortunately, as we can't provide an address ! 41: * gn is the procedure; ln the local name ! 42: */ ! 43: ! 44: extern WORD expv; ! 45: extern int expsp; ! 46: ! 47: localaddr(gn, ln) ! 48: char *gn, *ln; ! 49: { ! 50: WORD fp; ! 51: ADDR laddr(); ! 52: ! 53: if (gn) { ! 54: if (findrtn(gn) == 0) ! 55: error("function not found"); ! 56: } ! 57: else { ! 58: findsym((WORD)atow(rget(PC)), INSTSP); ! 59: if (cursym == NULL) ! 60: error("function not found"); ! 61: } ! 62: if (findframe(&fp) == 0) ! 63: error("function not found"); ! 64: if (ln == NULL) { ! 65: expsp = 0; ! 66: expv = fp; ! 67: return; ! 68: } ! 69: while (localsym()) { ! 70: if (strcmp(ln, cursym->y_name) != 0) ! 71: continue; ! 72: expv = laddr(cursym, fp, fp + F_ARG1); ! 73: if (cursym->y_ltype == S_RSYM) ! 74: expsp = REGSP; ! 75: else ! 76: expsp = NOSP; ! 77: return; ! 78: } ! 79: error("local var not found"); ! 80: /* NOTREACHED */ ! 81: } ! 82: ! 83: /* ! 84: * print a stack traceback ! 85: * give locals if possible ! 86: */ ! 87: ! 88: ctrace(modif) ! 89: char modif; ! 90: { ! 91: register ADDR fp, ap, callpc; ! 92: register int narg; ! 93: ADDR ofp; ! 94: ADDR newpc; ! 95: WORD w; ! 96: ! 97: if (adrflg) { ! 98: fp = adrval; ! 99: callpc = atow(aget(fp + F_PC, CORF|DATASP)); ! 100: } else { ! 101: fp = (ADDR)rtow(rget(FP)); ! 102: callpc = (ADDR)rtow(rget(PC)); ! 103: } ! 104: clrraddr(); ! 105: ofp = fp; ! 106: while (cntval--) { ! 107: chkerr(); ! 108: findsym(callpc, INSTSP); ! 109: if (cursym == NULL) ! 110: printf("?("); ! 111: else if (strcmp("start", cursym->y_name) == 0) ! 112: break; ! 113: else ! 114: printf("%s(", cursym->y_name); ! 115: if (strcmp("sigcode", cursym->y_name) == 0) { ! 116: printf(") from %R\n", callpc); ! 117: callpc = ltow(lget(ofp + F_HACKPC, CORF|DATASP)); ! 118: /* ignore saved r0 r1 r2 for now */ ! 119: continue; ! 120: } ! 121: newpc = atow(aget(fp + F_PC, CORF|DATASP)); ! 122: w = ltow(lget(newpc, SYMF|INSTSP)); ! 123: if (!adjspbi(w)) ! 124: narg = 0; ! 125: else ! 126: narg = -adjoff(w)/4; ! 127: for (ap = fp + F_ARG1; --narg >= 0; ap += SZREG) { ! 128: printf("%R", ltow(lget(ap, CORF|DATASP))); ! 129: if (narg != 0) ! 130: printc(','); ! 131: } ! 132: printf(") from %R\n", callpc); ! 133: if (modif == 'C') ! 134: locals(fp, fp + F_ARG1); ! 135: setraddr(callpc, fp); ! 136: callpc = newpc; ! 137: ofp = fp; ! 138: fp = atow(aget(fp + F_FP, CORF|DATASP)); ! 139: if (fp == 0) ! 140: break; ! 141: } ! 142: clrraddr(); ! 143: } ! 144: ! 145: static ! 146: locals(fp, ap) ! 147: ADDR fp, ap; ! 148: { ! 149: WORD val; ! 150: register int sp; ! 151: ADDR laddr(); ! 152: ! 153: while (localsym()) { ! 154: sp = CORF | DATASP; ! 155: if (cursym->y_ltype == S_RSYM) ! 156: sp = CORF | REGSP; ! 157: val = ltow(lget(laddr(cursym, fp, ap), sp)); ! 158: if (errflg == 0) ! 159: printf("%8t%s/%10t%R\n", cursym->y_name, val); ! 160: else { ! 161: printf("%8t%s/%10t?\n", cursym->y_name); ! 162: errflg = 0; ! 163: } ! 164: } ! 165: } ! 166: ! 167: ADDR ! 168: laddr(sp, fp, ap) ! 169: struct sym *sp; ! 170: ADDR fp, ap; ! 171: { ! 172: ! 173: switch (sp->y_ltype) { ! 174: case S_STSYM: ! 175: return (sp->y_value); ! 176: ! 177: case S_LSYM: ! 178: return (fp - sp->y_value); ! 179: ! 180: case S_PSYM: ! 181: return (ap + sp->y_value); ! 182: ! 183: case S_RSYM: ! 184: return (sp->y_value * SZREG); ! 185: } ! 186: error("bad local symbol"); ! 187: /* NOTREACHED */ ! 188: } ! 189: ! 190: int ! 191: findframe(fpp) ! 192: ADDR *fpp; ! 193: { ! 194: register ADDR fp, pc; ! 195: struct sym *svcur; ! 196: ! 197: svcur = cursym; ! 198: fp = rtow(rget(FP)); ! 199: pc = rtow(rget(PC)); ! 200: if (errflg) ! 201: return (0); ! 202: clrraddr(); ! 203: for (;;) { ! 204: findsym(pc, INSTSP); ! 205: if (cursym == svcur) ! 206: break; ! 207: if (cursym && strcmp(cursym->y_name, "start") == 0) { ! 208: clrraddr(); ! 209: return (0); ! 210: } ! 211: setraddr(cursym->y_value, fp); ! 212: pc = atow(aget(fp + F_PC, CORF|DATASP)); ! 213: fp = atow(aget(fp + F_FP, CORF|DATASP)); ! 214: /* sigtramp? */ ! 215: if (errflg) { ! 216: clrraddr(); ! 217: return (0); ! 218: } ! 219: } ! 220: *fpp = fp; ! 221: return (1); ! 222: } ! 223: ! 224: /* ! 225: * set addresses for saved registers for this frame ! 226: * the mask is that from an `enter' instruction ! 227: */ ! 228: ! 229: extern ADDR raddr[]; ! 230: ! 231: setraddr(pc, fp) ! 232: ADDR pc; ! 233: register ADDR fp; ! 234: { ! 235: register int r; ! 236: register int i; ! 237: int roff; ! 238: register int mask; ! 239: ! 240: if ((mask = regmask(pc, &roff)) == 0) ! 241: return; ! 242: fp += roff; ! 243: for (r = 7, i = 0; mask; r--) ! 244: if (mask & (1 << r)) { ! 245: if (MINREG <= r && r <= MAXREG) ! 246: raddr[r - MINREG] = fp + i * SZREG; ! 247: i++; ! 248: mask &=~ (1 << r); ! 249: } ! 250: } ! 251: ! 252: clrraddr() ! 253: { ! 254: register int i; ! 255: ! 256: for (i = 0; i <= MAXREG - MINREG; i++) ! 257: raddr[i] = 0; ! 258: } ! 259: ! 260: /* ! 261: * find the mask of saved registers for this routine ! 262: * ! 263: * pc is the entry point. ! 264: * if the code was run through c2, the first instruction will be `enter'; ! 265: * grab the mask. ! 266: * set *rp to the number of bytes of local storage on the stack ! 267: * (the registers are pushed AFTER local storage) ! 268: * if it wasn't put through c2, the first instruction will be a branch. ! 269: * the instruction branched to will be the `enter.' ! 270: * ! 271: * awful but how else to do it? ! 272: */ ! 273: ! 274: #define enter(w) (((w)&0xff) == 0x82) ! 275: #define entmsk(w) (((w)>>8) & 0xff) ! 276: #define br(w) (((w)&0xff) == 0xea) ! 277: ! 278: int ! 279: regmask(pc, rp) ! 280: ADDR pc; ! 281: int *rp; ! 282: { ! 283: register WORD w; ! 284: long disp(); ! 285: ! 286: *rp = 0; ! 287: w = ltow(lget(pc, SYMF|INSTSP)); ! 288: if (enter(w)) { ! 289: *rp = disp(pc + 2); ! 290: return (entmsk(w)); ! 291: } ! 292: if (!br(w)) ! 293: return (0); ! 294: w = ltow(lget(pc + disp(pc + 1), SYMF|INSTSP)); ! 295: if (enter(w)) ! 296: return (entmsk(w)); ! 297: return (0); ! 298: } ! 299: ! 300: static ! 301: disp(pc) ! 302: ADDR pc; ! 303: { ! 304: register WORD w; ! 305: ! 306: w = ltow(lget(pc, SYMF|INSTSP)); ! 307: if ((w & 0x80) == 0) { ! 308: w &= 0x7f; ! 309: if (w & 0x40) ! 310: w |= 0xffffffc0; ! 311: } ! 312: else if ((w & 0x40) == 0) { ! 313: w = ((w << 8) & 0x3f00) | ((w >> 8) & 0xff); ! 314: if (w & 0x2000) ! 315: w |= 0xffffc000; ! 316: } ! 317: else { ! 318: w = ((w << 24) & 0x3f000000) ! 319: | ((w << 8) & 0xff0000) ! 320: | ((w >> 8) & 0xff00) ! 321: | ((w >> 24) & 0xff); ! 322: if (w & 0x20000000) ! 323: w |= 0xc0000000; ! 324: } ! 325: return (w); ! 326: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.