|
|
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 <sys/dir.h> ! 10: #include <sys/user.h> ! 11: #include "regs.h" ! 12: #include "sym.h" ! 13: #include "space.h" ! 14: ! 15: int maxargs = 20; ! 16: ! 17: /* ! 18: * mc68000 stack frame ! 19: */ ! 20: ! 21: #define F_FP 0 /* saved fp */ ! 22: #define F_PC 4 /* return pc */ ! 23: #define F_ARG 8 /* first argument */ ! 24: #define FP AR6 ! 25: ! 26: /* ! 27: * is the saved psw reasonable? ! 28: * really just a last resort to find the end of the stack ! 29: */ ! 30: ! 31: #define BADPSW(p) (((p)&0xff00) != 0) ! 32: ! 33: /* ! 34: * return an address for a local variable ! 35: * no register vars, unfortunately, as we can't provide an address ! 36: * gn is the procedure; ln the local name ! 37: */ ! 38: ! 39: localaddr(gn, ln) ! 40: char *gn, *ln; ! 41: { ! 42: WORD fp; ! 43: extern WORD expv; ! 44: extern int expsp; ! 45: ADDR laddr(); ! 46: ! 47: if (gn) { ! 48: if (findrtn(gn) == 0) ! 49: error("function not found"); ! 50: } ! 51: else { ! 52: findsym((WORD)atow(rget(PC)), INSTSP); ! 53: if (cursym == NULL) ! 54: error("function not found"); ! 55: } ! 56: if (findframe(&fp) == 0) ! 57: error("stack frame not found"); ! 58: if (ln == NULL) { ! 59: expsp = 0; ! 60: expv = fp; ! 61: return; ! 62: } ! 63: while (localsym()) { ! 64: if (strcmp(ln, cursym->y_name) != 0) ! 65: continue; ! 66: expv = laddr(cursym, fp); ! 67: if (cursym->y_ltype == S_RSYM) ! 68: expsp = REGSP; ! 69: else ! 70: expsp = NOSP; ! 71: return; ! 72: } ! 73: error("bad local variable"); ! 74: /* NOTREACHED */ ! 75: } ! 76: ! 77: /* ! 78: * print a stack traceback ! 79: * give locals if possible ! 80: */ ! 81: ! 82: ctrace(modif) ! 83: char modif; ! 84: { ! 85: register ADDR fp, ap, callpc; ! 86: register int narg; ! 87: register int fl; ! 88: ! 89: if (adrflg) { ! 90: fp = adrval; ! 91: callpc = atow(aget(fp + F_PC, CORF|DATASP)); ! 92: } else { ! 93: fp = (ADDR)rtow(rget(FP)); ! 94: callpc = (ADDR)rtow(rget(PC)); ! 95: } ! 96: clrraddr(); ! 97: while (cntval--) { ! 98: chkerr(); ! 99: findsym(callpc, INSTSP); ! 100: if (cursym == NULL) ! 101: printf("?("); ! 102: else if (strcmp("start", cursym->y_name) == 0) ! 103: break; ! 104: else ! 105: printf("%s(", cursym->y_name); ! 106: fl = getnargs(fp); ! 107: if ((narg = fl) > maxargs) ! 108: narg = maxargs; ! 109: ap = fp + F_ARG; ! 110: while (--fl, --narg >= 0) { ! 111: printf("%R", ltow(lget(ap, CORF|DATASP))); ! 112: ap += SZREG; ! 113: if (narg != 0) ! 114: printc(','); ! 115: } ! 116: if (fl >= 0) ! 117: printf(",..."); ! 118: printf(") from %R\n", callpc); ! 119: if (modif == 'C') ! 120: locals(fp); ! 121: callpc = atow(aget(fp + F_PC, CORF|DATASP)); ! 122: setraddr(fp); ! 123: fp = atow(aget(fp + F_FP, CORF|DATASP)); ! 124: if (fp == 0) ! 125: break; ! 126: } ! 127: clrraddr(); ! 128: } ! 129: ! 130: /* ! 131: * Given a frame pointer determine the number of arguments. ! 132: * Unlike the vax, there is no argument pointer so we look at ! 133: * the instruction in the return pc and try to determine how ! 134: * may arguments are there by the resetting of the stack pointer. ! 135: */ ! 136: #define LEASPSP 0x4fef /* Lea sp@(xx),sp instruction */ ! 137: #define ADDQWL 0x500f /* Addqw #xx,sp instruction */ ! 138: ! 139: getnargs(fp) ! 140: ADDR fp; ! 141: { ! 142: ADDR callpc; ! 143: WORD instr, nargs; ! 144: ! 145: callpc = atow(aget(fp + F_PC, CORF|DATASP)); ! 146: instr = stow(sget(callpc, SYMF|INSTSP)); ! 147: if (instr == LEASPSP) ! 148: nargs = stow(sget(callpc + 2, SYMF|INSTSP)); ! 149: else if ((instr & 0xf12f) == ADDQWL) { ! 150: nargs = (instr >> 9) & 7; ! 151: if (nargs == 0) ! 152: nargs = 8; ! 153: } ! 154: else ! 155: nargs = 0; ! 156: return (nargs / SZREG); ! 157: } ! 158: ! 159: static ! 160: locals(fp) ! 161: ADDR fp; ! 162: { ! 163: WORD val; ! 164: register int sp; ! 165: ADDR laddr(); ! 166: ! 167: while (localsym()) { ! 168: sp = CORF | DATASP; ! 169: if (cursym->y_ltype == S_RSYM) ! 170: sp = CORF | REGSP; ! 171: val = ltow(lget(laddr(cursym, fp), sp)); ! 172: if (errflg == 0) ! 173: printf("%8t%s/%10t%R\n", cursym->y_name, val); ! 174: else { ! 175: printf("%8t%s/%10t?\n", cursym->y_name); ! 176: errflg = 0; ! 177: } ! 178: } ! 179: } ! 180: ! 181: static ADDR ! 182: laddr(sp, fp) ! 183: struct sym *sp; ! 184: ADDR fp; ! 185: { ! 186: ! 187: switch (sp->y_ltype) { ! 188: case S_STSYM: ! 189: return (sp->y_value); ! 190: ! 191: case S_LSYM: ! 192: return (fp - sp->y_value); ! 193: ! 194: case S_PSYM: ! 195: return (fp + sp->y_value); ! 196: ! 197: case S_RSYM: ! 198: return (sp->y_value); ! 199: } ! 200: error("bad local symbol"); ! 201: /* NOTREACHED */ ! 202: } ! 203: ! 204: static int ! 205: findframe(fpp) ! 206: ADDR *fpp; ! 207: { ! 208: register ADDR fp, pc; ! 209: struct sym *svcur; ! 210: ! 211: svcur = cursym; ! 212: fp = rtow(rget(FP)); ! 213: pc = rtow(rget(PC)); ! 214: if (errflg) ! 215: return (0); ! 216: clrraddr(); ! 217: for (;;) { ! 218: findsym(pc, INSTSP); ! 219: if (cursym == svcur) ! 220: break; ! 221: if (cursym && strcmp(cursym->y_name, "start") == 0) { ! 222: clrraddr(); ! 223: return (0); ! 224: } ! 225: setraddr(fp); ! 226: pc = atow(aget(fp + F_PC, CORF|DATASP)); ! 227: fp = atow(aget(fp + F_FP, CORF|DATASP)); ! 228: if (errflg) { ! 229: clrraddr(); ! 230: return (0); ! 231: } ! 232: } ! 233: *fpp = fp; ! 234: return (1); ! 235: } ! 236: ! 237: /* ! 238: * set addresses for saved registers for this frame ! 239: */ ! 240: ! 241: static ! 242: setraddr(fp) ! 243: register ADDR fp; ! 244: { ! 245: register int r; ! 246: register int i; ! 247: extern ADDR raddr[]; ! 248: ! 249: /* all wrong */ ! 250: } ! 251: ! 252: static ! 253: clrraddr() ! 254: { ! 255: register int i; ! 256: extern ADDR raddr[]; ! 257: ! 258: for (i = 0; i <= MAXREG - MINREG; i++) ! 259: raddr[i] = 0; ! 260: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.