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