1*20184Ssam static char sccsid[] = "@(#)setup.c 4.10 (Berkeley) 85/05/09"; 23766Sroot /* 33766Sroot * adb - routines to read a.out+core at startup 43766Sroot */ 53766Sroot #include "defs.h" 616845Ssam #include <frame.h> 716845Ssam #include <ctype.h> 88927Srrh #include <sys/stat.h> 916845Ssam #include <sys/file.h> 1016845Ssam #include <vax/rpb.h> 113766Sroot 123766Sroot off_t datbas; /* offset of the base of the data segment */ 133766Sroot off_t stksiz; /* stack size in the core image */ 143766Sroot INT sigcode; /* belongs in head.h */ 153766Sroot 163766Sroot char *symfil = "a.out"; 173766Sroot char *corfil = "core"; 183766Sroot 193766Sroot setsym() 203766Sroot { 213766Sroot off_t loc; 223766Sroot struct exec hdr; 233766Sroot register struct nlist *sp; 243766Sroot int ssiz; 253766Sroot char *strtab; 263766Sroot 273766Sroot fsym = getfile(symfil, 1); 283766Sroot txtmap.ufd = fsym; 293766Sroot if (read(fsym, (char *)&hdr, sizeof hdr) != sizeof hdr || 303766Sroot N_BADMAG(hdr)) { 313766Sroot txtmap.e1 = MAXFILE; 323766Sroot return; 333766Sroot } 343766Sroot filhdr = hdr; 353766Sroot loc = filhdr.a_text+filhdr.a_data; 363766Sroot txtmap.f1 = txtmap.f2 = N_TXTOFF(filhdr); 373766Sroot txtmap.b1 = 0; 383766Sroot switch (filhdr.a_magic) { 393766Sroot 403766Sroot case OMAGIC: 413766Sroot txtmap.b1 = txtmap.e1 = 0; 423766Sroot txtmap.b2 = datbas = 0; 433766Sroot txtmap.e2 = loc; 443766Sroot break; 453766Sroot 463766Sroot case ZMAGIC: 473766Sroot case NMAGIC: 483766Sroot txtmap.e1 = filhdr.a_text; 493766Sroot txtmap.b2 = datbas = round(filhdr.a_text, PAGSIZ); 503766Sroot txtmap.e2 = datbas + filhdr.a_data; 513766Sroot txtmap.f2 += txtmap.e1; 523766Sroot } 533766Sroot loc = N_SYMOFF(filhdr); 543766Sroot symtab = (struct nlist *) malloc(filhdr.a_syms); 553766Sroot esymtab = &symtab[filhdr.a_syms / sizeof (struct nlist)]; 563766Sroot if (symtab == NULL) 573766Sroot goto nospac; 5816845Ssam lseek(fsym, loc, L_SET); 593766Sroot if (filhdr.a_syms == 0) 603766Sroot goto nosymt; 613766Sroot /* SHOULD SQUISH OUT STABS HERE!!! */ 623766Sroot if (read(fsym, symtab, filhdr.a_syms) != filhdr.a_syms) 633766Sroot goto readerr; 643766Sroot if (read(fsym, &ssiz, sizeof (ssiz)) != sizeof (ssiz)) 653766Sroot goto oldfmt; 663766Sroot strtab = (char *) malloc(ssiz); 673766Sroot if (strtab == 0) 683766Sroot goto nospac; 693766Sroot *(int *)strtab = ssiz; 703766Sroot ssiz -= sizeof (ssiz); 713766Sroot if (read(fsym, strtab + sizeof (ssiz), ssiz) != ssiz) 723766Sroot goto readerr; 733766Sroot for (sp = symtab; sp < esymtab; sp++) 743766Sroot if (sp->n_strx) 753766Sroot /* SHOULD PERFORM RANGE CHECK HERE */ 763766Sroot sp->n_un.n_name = strtab + sp->n_un.n_strx; 773766Sroot nosymt: 783766Sroot if (INKERNEL(filhdr.a_entry)) { 793766Sroot txtmap.b1 += KERNOFF; 803766Sroot txtmap.e1 += KERNOFF; 813766Sroot txtmap.b2 += KERNOFF; 823766Sroot txtmap.e2 += KERNOFF; 833766Sroot } 843766Sroot return; 853766Sroot readerr: 863766Sroot printf("Error reading symbol|string table\n"); 873766Sroot exit(1); 883766Sroot nospac: 893766Sroot printf("Not enough space for symbol|string table\n"); 903766Sroot exit(1); 913766Sroot oldfmt: 923766Sroot printf("Old format a.out - no string table\n"); 933766Sroot exit(1); 943766Sroot } 953766Sroot 963766Sroot setcor() 973766Sroot { 983766Sroot 993766Sroot fcor = datmap.ufd = getfile(corfil,2); 1006416Sroot if (kernel && fcor != -1 && INKERNEL(filhdr.a_entry)) { 1013766Sroot struct stat stb; 1023766Sroot 1033779Sroot kcore = 1; 1043766Sroot fstat(fcor, &stb); 1053766Sroot datmap.b1 = 0; 1063766Sroot datmap.e1 = -1; 1073778Sroot if (kernel == 0 && (stb.st_mode & S_IFREG)) 1083778Sroot datmap.b1 = 0x80000000; 1093777Sroot lookup("_Sysmap"); 1103777Sroot sbr = cursym->n_value; 1113777Sroot lookup("_Syssize"); 1123777Sroot slr = cursym->n_value; 11318812Smckusick printf("sbr %x slr %x\n", sbr, slr); 1146416Sroot lookup("_masterpaddr"); 115*20184Ssam physrw(fcor, KVTOPH(cursym->n_value), &masterpcbb, 1); 116*20184Ssam masterpcbb = (masterpcbb&PG_PFNUM)*NBPG; 1173777Sroot getpcb(); 11816845Ssam findstackframe(); 1193766Sroot return; 1203766Sroot } 1213766Sroot if (read(fcor, (char *)&u, ctob(UPAGES))!=ctob(UPAGES) || 1223766Sroot !INUDOT(u.u_pcb.pcb_ksp) || !INSTACK(u.u_pcb.pcb_usp)) { 1233766Sroot datmap.e1 = MAXFILE; 1243766Sroot return; 1253766Sroot } 1263766Sroot signo = u.u_arg[0]; 1273766Sroot sigcode = u.u_code; 1283766Sroot filhdr.a_text = ctob(u.u_tsize); 1293766Sroot filhdr.a_data = ctob(u.u_dsize); 1303766Sroot stksiz = ctob(u.u_ssize); 1313766Sroot switch (filhdr.a_magic) { 1323766Sroot 1333766Sroot case OMAGIC: 1343766Sroot datmap.b1 = 0; 1353766Sroot datmap.e1 = filhdr.a_text+filhdr.a_data; 1363766Sroot datmap.f2 = ctob(UPAGES) + datmap.e1; 1373766Sroot break; 1383766Sroot 1393766Sroot case NMAGIC: 1403766Sroot case ZMAGIC: 1413766Sroot datmap.b1 = round(filhdr.a_text, PAGSIZ); 1423766Sroot datmap.e1 = datmap.b1 + filhdr.a_data; 1433766Sroot datmap.f2 = ctob(UPAGES) + filhdr.a_data; 1443766Sroot break; 1453766Sroot } 1463766Sroot datbas = datmap.b1; 1473766Sroot datmap.f1 = ctob(UPAGES); 1483766Sroot datmap.b2 = MAXSTOR - stksiz; 1493766Sroot datmap.e2 = MAXSTOR; 1503766Sroot } 1513766Sroot 1523777Sroot getpcb() 1533777Sroot { 1543779Sroot 155*20184Ssam lseek(fcor, KVTOPH(masterpcbb), L_SET); 1563777Sroot read(fcor, &pcb, sizeof (struct pcb)); 1573779Sroot pcb.pcb_p0lr &= ~AST_CLR; 15818812Smckusick printf("p0br %x p0lr %x p1br %x p1lr %x\n", 1593777Sroot pcb.pcb_p0br, pcb.pcb_p0lr, pcb.pcb_p1br, pcb.pcb_p1lr); 1603777Sroot } 1613777Sroot 16216845Ssam caddr_t rpb, scb; 16316845Ssam caddr_t intstack, eintstack; 16416845Ssam caddr_t ustack, eustack; 16516845Ssam struct frame *getframe(); 16616845Ssam struct frame *checkintstack(); 16716845Ssam 16816845Ssam /* 16916845Ssam * Find the current stack frame when debugging the kernel. 17016845Ssam * If we're looking at a crash dump and this was not a ``clean'' 17116845Ssam * crash, then we must search the interrupt stack carefully 17216845Ssam * looking for a valid frame. 17316845Ssam */ 17416845Ssam findstackframe() 17516845Ssam { 17616845Ssam char *panicstr, buf[256]; 17716845Ssam register struct frame *fp; 17816845Ssam caddr_t addr; 17916845Ssam register char *cp; 18016845Ssam int mask; 18116845Ssam 18216845Ssam if (lookup("_panicstr") == 0) 18316845Ssam return; 184*20184Ssam lseek(fcor, KVTOPH(cursym->n_value), L_SET); 18516845Ssam read(fcor, &panicstr, sizeof (panicstr)); 18616845Ssam if (panicstr == 0) 18716845Ssam return; 188*20184Ssam lseek(fcor, KVTOPH((off_t)panicstr), L_SET); 18916845Ssam read(fcor, buf, sizeof (buf)); 19016845Ssam for (cp = buf; cp < &buf[sizeof (buf)] && *cp; cp++) 191*20184Ssam if (!isascii(*cp) || (!isprint(*cp) && !isspace(*cp))) 19216845Ssam *cp = '?'; 19316845Ssam if (*cp) 19416845Ssam *cp = '\0'; 19516845Ssam printf("panic: %s\n", buf); 19616845Ssam /* 19716845Ssam * After a panic, look at the top of the rpb stack to 19816845Ssam * find a stack frame. If this was a clean crash, 19916845Ssam * i.e. one which left the interrupt and kernel stacks 20016845Ssam * in a reasonable state, then we should find a pointer 20116845Ssam * to the proper stack frame here (at location scb-4). 20216845Ssam * If we don't find a reasonable frame here, then we 20316845Ssam * must search down through the interrupt stack. 20416845Ssam */ 20516845Ssam intstack = lookup("_intstack")->n_value; 20616845Ssam #define NISP 3 /* from locore.s */ 20716845Ssam eintstack = intstack + NISP*NBPG; 20816845Ssam rpb = lookup("_rpb")->n_value; 20916845Ssam scb = lookup("_scb")->n_value; 21016845Ssam lookup("_u"); 21116845Ssam ustack = cursym->n_value + (int)&((struct user *)0)->u_stack[0]; 21216845Ssam eustack = cursym->n_value + ctob(UPAGES); 213*20184Ssam physrw(fcor, KVTOPH((int)scb - sizeof (caddr_t)), &addr, 1); 21416845Ssam fp = getframe(fcor, addr); 21516845Ssam if (fp == 0) 21616845Ssam fp = checkintstack(); 21716845Ssam /* search kernel stack? */ 21816845Ssam if (fp == 0) { 21916845Ssam printf("can't locate stack frame\n"); 22016845Ssam return; 22116845Ssam } 22216845Ssam /* probably shouldn't clobber pcb, but for now this is easy */ 22316845Ssam pcb.pcb_fp = addr; 22416845Ssam pcb.pcb_pc = fp->fr_savpc; 22516845Ssam pcb.pcb_ap = addr + sizeof (struct frame) + fp->fr_spa; 22616845Ssam for (mask = fp->fr_mask; mask; mask >>= 1) 22716845Ssam if (mask & 01) 22816845Ssam pcb.pcb_ap += sizeof (caddr_t); 22916845Ssam } 23016845Ssam 23116845Ssam /* 23216845Ssam * Search interrupt stack for a valid frame. 23316845Ssam */ 23416845Ssam struct frame * 23516845Ssam checkintstack(fcor) 23616845Ssam { 23716845Ssam char stack[NISP*NBPG]; 23816845Ssam off_t off = vtophys(intstack); 23916845Ssam struct frame *fp; 24016845Ssam register caddr_t addr; 24116845Ssam 24216845Ssam if (off == -1 || lseek(fcor, off, L_SET) != off || 24316845Ssam read(fcor, stack, sizeof (stack)) != sizeof (stack)) 24416845Ssam return ((struct frame *)0); 24516845Ssam addr = eintstack; 24616845Ssam do { 24716845Ssam addr -= sizeof (caddr_t); 24816845Ssam fp = (struct frame *)&stack[addr - intstack]; 24916845Ssam } while (addr >= intstack + sizeof (struct frame) && 25016845Ssam !checkframe(fp)); 25116845Ssam return (addr < intstack+sizeof (struct frame) ? (struct frame *)0 : fp); 25216845Ssam } 25316845Ssam 25416845Ssam /* 25516845Ssam * Get a stack frame and verify it looks like 25616845Ssam * something which might be on a kernel stack. 25716845Ssam */ 25816845Ssam struct frame * 25916845Ssam getframe(fcor, fp) 26016845Ssam int fcor; 26116845Ssam caddr_t fp; 26216845Ssam { 26316845Ssam static struct frame frame; 26416845Ssam off_t off; 26516845Ssam 26616845Ssam if (!kstackaddr(fp) || (off = vtophys(fp)) == -1) 26716845Ssam return ((struct frame *)0); 26816845Ssam if (lseek(fcor, off, L_SET) != off || 26916845Ssam read(fcor, &frame, sizeof (frame)) != sizeof (frame)) 27016845Ssam return ((struct frame *)0); 27116845Ssam if (!checkframe(&frame)) 27216845Ssam return ((struct frame *)0); 27316845Ssam return (&frame); 27416845Ssam } 27516845Ssam 27616845Ssam /* 27716845Ssam * Check a call frame to see if it's ok as 27816845Ssam * a kernel stack frame. 27916845Ssam */ 28016845Ssam checkframe(fp) 28116845Ssam register struct frame *fp; 28216845Ssam { 28316845Ssam 28416845Ssam if (fp->fr_handler != 0 || fp->fr_s == 0) 28516845Ssam return (0); 28616845Ssam if (!kstackaddr(fp->fr_savap) || !kstackaddr(fp->fr_savfp)) 28716845Ssam return (0); 28816845Ssam return (within(fp->fr_savpc, txtmap.b1, txtmap.e1)); 28916845Ssam } 29016845Ssam 29116845Ssam /* 29216845Ssam * Check if an address is in one of the kernel's stacks: 29316845Ssam * interrupt stack, rpb stack (during restart sequence), 29416845Ssam * or u. stack. 29516845Ssam */ 29616845Ssam kstackaddr(addr) 29716845Ssam caddr_t addr; 29816845Ssam { 29916845Ssam 30016845Ssam return (within(addr, intstack, eintstack) || 30116845Ssam within(addr, rpb + sizeof (struct rpb), scb) || 30216845Ssam within(addr, ustack, eustack)); 30316845Ssam } 30416845Ssam 3053766Sroot create(f) 3063766Sroot char *f; 3073766Sroot { 3083766Sroot register int fd; 3093766Sroot 3103766Sroot fd = creat(f, 0644); 3113766Sroot if (fd < 0) 3123766Sroot return (-1); 3133766Sroot close(fd); 3143766Sroot return (open(f, wtflag)); 3153766Sroot } 3163766Sroot 3173766Sroot getfile(filnam, cnt) 3183766Sroot char *filnam; 3193766Sroot { 3203766Sroot register int fsym; 3213766Sroot 3223766Sroot if (eqstr(filnam, "-")) 3233766Sroot return (-1); 3243766Sroot fsym = open(filnam, wtflag); 3253766Sroot if (fsym < 0 && xargc > cnt) { 3263766Sroot if (wtflag) 3273766Sroot fsym = create(filnam); 3283766Sroot if (fsym < 0) 3293766Sroot printf("cannot open `%s'\n", filnam); 3303766Sroot } 3313766Sroot return (fsym); 3323766Sroot } 3333766Sroot 3343766Sroot setvar() 3353766Sroot { 3363766Sroot 3373766Sroot var[varchk('b')] = datbas; 3383766Sroot var[varchk('d')] = filhdr.a_data; 3393766Sroot var[varchk('e')] = filhdr.a_entry; 3403766Sroot var[varchk('m')] = filhdr.a_magic; 3413766Sroot var[varchk('s')] = stksiz; 3423766Sroot var[varchk('t')] = filhdr.a_text; 3433766Sroot } 344