1: static char sccsid[] = "@(#)setup.c 4.10 (Berkeley) 85/05/09"; 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_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: }