|
|
1.1 ! root 1: static char sccsid[] = "@(#)setup.c 4.11 (Berkeley) 87/12/21"; ! 2: /* ! 3: * adb - routines to read a.out+core at startup ! 4: */ ! 5: #include "defs.h" ! 6: #include <frame.h> ! 7: #include <ctype.h> ! 8: #include <sys/stat.h> ! 9: #include <sys/file.h> ! 10: #include <vax/rpb.h> ! 11: ! 12: off_t datbas; /* offset of the base of the data segment */ ! 13: off_t stksiz; /* stack size in the core image */ ! 14: INT sigcode; /* belongs in head.h */ ! 15: ! 16: char *symfil = "a.out"; ! 17: char *corfil = "core"; ! 18: ! 19: setsym() ! 20: { ! 21: off_t loc; ! 22: struct exec hdr; ! 23: register struct nlist *sp; ! 24: int ssiz; ! 25: char *strtab; ! 26: ! 27: fsym = getfile(symfil, 1); ! 28: txtmap.ufd = fsym; ! 29: if (read(fsym, (char *)&hdr, sizeof hdr) != sizeof hdr || ! 30: N_BADMAG(hdr)) { ! 31: txtmap.e1 = MAXFILE; ! 32: return; ! 33: } ! 34: filhdr = hdr; ! 35: loc = filhdr.a_text+filhdr.a_data; ! 36: txtmap.f1 = txtmap.f2 = N_TXTOFF(filhdr); ! 37: txtmap.b1 = 0; ! 38: switch (filhdr.a_magic) { ! 39: ! 40: case OMAGIC: ! 41: txtmap.b1 = txtmap.e1 = 0; ! 42: txtmap.b2 = datbas = 0; ! 43: txtmap.e2 = loc; ! 44: break; ! 45: ! 46: case ZMAGIC: ! 47: case NMAGIC: ! 48: txtmap.e1 = filhdr.a_text; ! 49: txtmap.b2 = datbas = round(filhdr.a_text, PAGSIZ); ! 50: txtmap.e2 = datbas + filhdr.a_data; ! 51: txtmap.f2 += txtmap.e1; ! 52: } ! 53: loc = N_SYMOFF(filhdr); ! 54: symtab = (struct nlist *) malloc(filhdr.a_syms); ! 55: esymtab = &symtab[filhdr.a_syms / sizeof (struct nlist)]; ! 56: if (symtab == NULL) ! 57: goto nospac; ! 58: lseek(fsym, loc, L_SET); ! 59: if (filhdr.a_syms == 0) ! 60: goto nosymt; ! 61: /* SHOULD SQUISH OUT STABS HERE!!! */ ! 62: if (read(fsym, symtab, filhdr.a_syms) != filhdr.a_syms) ! 63: goto readerr; ! 64: if (read(fsym, &ssiz, sizeof (ssiz)) != sizeof (ssiz)) ! 65: goto oldfmt; ! 66: strtab = (char *) malloc(ssiz); ! 67: if (strtab == 0) ! 68: goto nospac; ! 69: *(int *)strtab = ssiz; ! 70: ssiz -= sizeof (ssiz); ! 71: if (read(fsym, strtab + sizeof (ssiz), ssiz) != ssiz) ! 72: goto readerr; ! 73: for (sp = symtab; sp < esymtab; sp++) ! 74: if (sp->n_un.n_strx) ! 75: /* SHOULD PERFORM RANGE CHECK HERE */ ! 76: sp->n_un.n_name = strtab + sp->n_un.n_strx; ! 77: nosymt: ! 78: if (INKERNEL(filhdr.a_entry)) { ! 79: txtmap.b1 += KERNOFF; ! 80: txtmap.e1 += KERNOFF; ! 81: txtmap.b2 += KERNOFF; ! 82: txtmap.e2 += KERNOFF; ! 83: } ! 84: return; ! 85: readerr: ! 86: printf("Error reading symbol|string table\n"); ! 87: exit(1); ! 88: nospac: ! 89: printf("Not enough space for symbol|string table\n"); ! 90: exit(1); ! 91: oldfmt: ! 92: printf("Old format a.out - no string table\n"); ! 93: exit(1); ! 94: } ! 95: ! 96: setcor() ! 97: { ! 98: ! 99: fcor = datmap.ufd = getfile(corfil,2); ! 100: if (kernel && fcor != -1 && INKERNEL(filhdr.a_entry)) { ! 101: struct stat stb; ! 102: ! 103: kcore = 1; ! 104: fstat(fcor, &stb); ! 105: datmap.b1 = 0; ! 106: datmap.e1 = -1; ! 107: if (kernel == 0 && (stb.st_mode & S_IFREG)) ! 108: datmap.b1 = 0x80000000; ! 109: lookup("_Sysmap"); ! 110: sbr = cursym->n_value; ! 111: lookup("_Syssize"); ! 112: slr = cursym->n_value; ! 113: printf("sbr %x slr %x\n", sbr, slr); ! 114: lookup("_masterpaddr"); ! 115: physrw(fcor, KVTOPH(cursym->n_value), &masterpcbb, 1); ! 116: masterpcbb = (masterpcbb&PG_PFNUM)*NBPG; ! 117: getpcb(); ! 118: findstackframe(); ! 119: return; ! 120: } ! 121: if (read(fcor, (char *)&u, ctob(UPAGES))!=ctob(UPAGES) || ! 122: !INUDOT(u.u_pcb.pcb_ksp) || !INSTACK(u.u_pcb.pcb_usp)) { ! 123: datmap.e1 = MAXFILE; ! 124: return; ! 125: } ! 126: signo = u.u_arg[0]; ! 127: sigcode = u.u_code; ! 128: filhdr.a_text = ctob(u.u_tsize); ! 129: filhdr.a_data = ctob(u.u_dsize); ! 130: stksiz = ctob(u.u_ssize); ! 131: switch (filhdr.a_magic) { ! 132: ! 133: case OMAGIC: ! 134: datmap.b1 = 0; ! 135: datmap.e1 = filhdr.a_text+filhdr.a_data; ! 136: datmap.f2 = ctob(UPAGES) + datmap.e1; ! 137: break; ! 138: ! 139: case NMAGIC: ! 140: case ZMAGIC: ! 141: datmap.b1 = round(filhdr.a_text, PAGSIZ); ! 142: datmap.e1 = datmap.b1 + filhdr.a_data; ! 143: datmap.f2 = ctob(UPAGES) + filhdr.a_data; ! 144: break; ! 145: } ! 146: datbas = datmap.b1; ! 147: datmap.f1 = ctob(UPAGES); ! 148: datmap.b2 = MAXSTOR - stksiz; ! 149: datmap.e2 = MAXSTOR; ! 150: } ! 151: ! 152: getpcb() ! 153: { ! 154: ! 155: lseek(fcor, KVTOPH(masterpcbb), L_SET); ! 156: read(fcor, &pcb, sizeof (struct pcb)); ! 157: pcb.pcb_p0lr &= ~AST_CLR; ! 158: printf("p0br %x p0lr %x p1br %x p1lr %x\n", ! 159: pcb.pcb_p0br, pcb.pcb_p0lr, pcb.pcb_p1br, pcb.pcb_p1lr); ! 160: } ! 161: ! 162: caddr_t rpb, scb; ! 163: caddr_t intstack, eintstack; ! 164: caddr_t ustack, eustack; ! 165: struct frame *getframe(); ! 166: struct frame *checkintstack(); ! 167: ! 168: /* ! 169: * Find the current stack frame when debugging the kernel. ! 170: * If we're looking at a crash dump and this was not a ``clean'' ! 171: * crash, then we must search the interrupt stack carefully ! 172: * looking for a valid frame. ! 173: */ ! 174: findstackframe() ! 175: { ! 176: char *panicstr, buf[256]; ! 177: register struct frame *fp; ! 178: caddr_t addr; ! 179: register char *cp; ! 180: int mask; ! 181: ! 182: if (lookup("_panicstr") == 0) ! 183: return; ! 184: lseek(fcor, KVTOPH(cursym->n_value), L_SET); ! 185: read(fcor, &panicstr, sizeof (panicstr)); ! 186: if (panicstr == 0) ! 187: return; ! 188: lseek(fcor, KVTOPH((off_t)panicstr), L_SET); ! 189: read(fcor, buf, sizeof (buf)); ! 190: for (cp = buf; cp < &buf[sizeof (buf)] && *cp; cp++) ! 191: if (!isascii(*cp) || (!isprint(*cp) && !isspace(*cp))) ! 192: *cp = '?'; ! 193: if (*cp) ! 194: *cp = '\0'; ! 195: printf("panic: %s\n", buf); ! 196: /* ! 197: * After a panic, look at the top of the rpb stack to ! 198: * find a stack frame. If this was a clean crash, ! 199: * i.e. one which left the interrupt and kernel stacks ! 200: * in a reasonable state, then we should find a pointer ! 201: * to the proper stack frame here (at location scb-4). ! 202: * If we don't find a reasonable frame here, then we ! 203: * must search down through the interrupt stack. ! 204: */ ! 205: intstack = lookup("_intstack")->n_value; ! 206: #define NISP 3 /* from locore.s */ ! 207: eintstack = intstack + NISP*NBPG; ! 208: rpb = lookup("_rpb")->n_value; ! 209: scb = lookup("_scb")->n_value; ! 210: lookup("_u"); ! 211: ustack = cursym->n_value + (int)&((struct user *)0)->u_stack[0]; ! 212: eustack = cursym->n_value + ctob(UPAGES); ! 213: physrw(fcor, KVTOPH((int)scb - sizeof (caddr_t)), &addr, 1); ! 214: fp = getframe(fcor, addr); ! 215: if (fp == 0) ! 216: fp = checkintstack(); ! 217: /* search kernel stack? */ ! 218: if (fp == 0) { ! 219: printf("can't locate stack frame\n"); ! 220: return; ! 221: } ! 222: /* probably shouldn't clobber pcb, but for now this is easy */ ! 223: pcb.pcb_fp = addr; ! 224: pcb.pcb_pc = fp->fr_savpc; ! 225: pcb.pcb_ap = addr + sizeof (struct frame) + fp->fr_spa; ! 226: for (mask = fp->fr_mask; mask; mask >>= 1) ! 227: if (mask & 01) ! 228: pcb.pcb_ap += sizeof (caddr_t); ! 229: } ! 230: ! 231: /* ! 232: * Search interrupt stack for a valid frame. ! 233: */ ! 234: struct frame * ! 235: checkintstack(fcor) ! 236: { ! 237: char stack[NISP*NBPG]; ! 238: off_t off = vtophys(intstack); ! 239: struct frame *fp; ! 240: register caddr_t addr; ! 241: ! 242: if (off == -1 || lseek(fcor, off, L_SET) != off || ! 243: read(fcor, stack, sizeof (stack)) != sizeof (stack)) ! 244: return ((struct frame *)0); ! 245: addr = eintstack; ! 246: do { ! 247: addr -= sizeof (caddr_t); ! 248: fp = (struct frame *)&stack[addr - intstack]; ! 249: } while (addr >= intstack + sizeof (struct frame) && ! 250: !checkframe(fp)); ! 251: return (addr < intstack+sizeof (struct frame) ? (struct frame *)0 : fp); ! 252: } ! 253: ! 254: /* ! 255: * Get a stack frame and verify it looks like ! 256: * something which might be on a kernel stack. ! 257: */ ! 258: struct frame * ! 259: getframe(fcor, fp) ! 260: int fcor; ! 261: caddr_t fp; ! 262: { ! 263: static struct frame frame; ! 264: off_t off; ! 265: ! 266: if (!kstackaddr(fp) || (off = vtophys(fp)) == -1) ! 267: return ((struct frame *)0); ! 268: if (lseek(fcor, off, L_SET) != off || ! 269: read(fcor, &frame, sizeof (frame)) != sizeof (frame)) ! 270: return ((struct frame *)0); ! 271: if (!checkframe(&frame)) ! 272: return ((struct frame *)0); ! 273: return (&frame); ! 274: } ! 275: ! 276: /* ! 277: * Check a call frame to see if it's ok as ! 278: * a kernel stack frame. ! 279: */ ! 280: checkframe(fp) ! 281: register struct frame *fp; ! 282: { ! 283: ! 284: if (fp->fr_handler != 0 || fp->fr_s == 0) ! 285: return (0); ! 286: if (!kstackaddr(fp->fr_savap) || !kstackaddr(fp->fr_savfp)) ! 287: return (0); ! 288: return (within(fp->fr_savpc, txtmap.b1, txtmap.e1)); ! 289: } ! 290: ! 291: /* ! 292: * Check if an address is in one of the kernel's stacks: ! 293: * interrupt stack, rpb stack (during restart sequence), ! 294: * or u. stack. ! 295: */ ! 296: kstackaddr(addr) ! 297: caddr_t addr; ! 298: { ! 299: ! 300: return (within(addr, intstack, eintstack) || ! 301: within(addr, rpb + sizeof (struct rpb), scb) || ! 302: within(addr, ustack, eustack)); ! 303: } ! 304: ! 305: create(f) ! 306: char *f; ! 307: { ! 308: register int fd; ! 309: ! 310: fd = creat(f, 0644); ! 311: if (fd < 0) ! 312: return (-1); ! 313: close(fd); ! 314: return (open(f, wtflag)); ! 315: } ! 316: ! 317: getfile(filnam, cnt) ! 318: char *filnam; ! 319: { ! 320: register int fsym; ! 321: ! 322: if (eqstr(filnam, "-")) ! 323: return (-1); ! 324: fsym = open(filnam, wtflag); ! 325: if (fsym < 0 && xargc > cnt) { ! 326: if (wtflag) ! 327: fsym = create(filnam); ! 328: if (fsym < 0) ! 329: printf("cannot open `%s'\n", filnam); ! 330: } ! 331: return (fsym); ! 332: } ! 333: ! 334: setvar() ! 335: { ! 336: ! 337: var[varchk('b')] = datbas; ! 338: var[varchk('d')] = filhdr.a_data; ! 339: var[varchk('e')] = filhdr.a_entry; ! 340: var[varchk('m')] = filhdr.a_magic; ! 341: var[varchk('s')] = stksiz; ! 342: var[varchk('t')] = filhdr.a_text; ! 343: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.