1*16845Ssam static char sccsid[] = "@(#)setup.c 4.8 (Berkeley) 84/08/05"; 23766Sroot /* 33766Sroot * adb - routines to read a.out+core at startup 43766Sroot */ 53766Sroot #include "defs.h" 6*16845Ssam #include <frame.h> 7*16845Ssam #include <ctype.h> 88927Srrh #include <sys/stat.h> 9*16845Ssam #include <sys/file.h> 10*16845Ssam #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; 58*16845Ssam 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; 1133777Sroot printf("sbr %X slr %X\n", sbr, slr); 1146416Sroot lookup("_masterpaddr"); 115*16845Ssam physrw(fcor, cursym->n_value&~0x80000000, &masterpcbb, 1); 1166416Sroot masterpcbb = (masterpcbb&PG_PFNUM)*512; 1173777Sroot getpcb(); 118*16845Ssam 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*16845Ssam lseek(fcor, masterpcbb&~0x80000000, L_SET); 1563777Sroot read(fcor, &pcb, sizeof (struct pcb)); 1573779Sroot pcb.pcb_p0lr &= ~AST_CLR; 1583777Sroot 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 162*16845Ssam caddr_t rpb, scb; 163*16845Ssam caddr_t intstack, eintstack; 164*16845Ssam caddr_t ustack, eustack; 165*16845Ssam struct frame *getframe(); 166*16845Ssam struct frame *checkintstack(); 167*16845Ssam 168*16845Ssam /* 169*16845Ssam * Find the current stack frame when debugging the kernel. 170*16845Ssam * If we're looking at a crash dump and this was not a ``clean'' 171*16845Ssam * crash, then we must search the interrupt stack carefully 172*16845Ssam * looking for a valid frame. 173*16845Ssam */ 174*16845Ssam findstackframe() 175*16845Ssam { 176*16845Ssam char *panicstr, buf[256]; 177*16845Ssam register struct frame *fp; 178*16845Ssam caddr_t addr; 179*16845Ssam register char *cp; 180*16845Ssam int mask; 181*16845Ssam 182*16845Ssam if (lookup("_panicstr") == 0) 183*16845Ssam return; 184*16845Ssam lseek(fcor, cursym->n_value&~0x80000000, L_SET); 185*16845Ssam read(fcor, &panicstr, sizeof (panicstr)); 186*16845Ssam if (panicstr == 0) 187*16845Ssam return; 188*16845Ssam lseek(fcor, ((off_t)panicstr)&~0x80000000, L_SET); 189*16845Ssam read(fcor, buf, sizeof (buf)); 190*16845Ssam for (cp = buf; cp < &buf[sizeof (buf)] && *cp; cp++) 191*16845Ssam if (!isascii(*cp) || !isprint(*cp)) 192*16845Ssam *cp = '?'; 193*16845Ssam if (*cp) 194*16845Ssam *cp = '\0'; 195*16845Ssam printf("panic: %s\n", buf); 196*16845Ssam /* 197*16845Ssam * After a panic, look at the top of the rpb stack to 198*16845Ssam * find a stack frame. If this was a clean crash, 199*16845Ssam * i.e. one which left the interrupt and kernel stacks 200*16845Ssam * in a reasonable state, then we should find a pointer 201*16845Ssam * to the proper stack frame here (at location scb-4). 202*16845Ssam * If we don't find a reasonable frame here, then we 203*16845Ssam * must search down through the interrupt stack. 204*16845Ssam */ 205*16845Ssam intstack = lookup("_intstack")->n_value; 206*16845Ssam #define NISP 3 /* from locore.s */ 207*16845Ssam eintstack = intstack + NISP*NBPG; 208*16845Ssam rpb = lookup("_rpb")->n_value; 209*16845Ssam scb = lookup("_scb")->n_value; 210*16845Ssam lookup("_u"); 211*16845Ssam ustack = cursym->n_value + (int)&((struct user *)0)->u_stack[0]; 212*16845Ssam eustack = cursym->n_value + ctob(UPAGES); 213*16845Ssam physrw(fcor, ((int)scb - sizeof (caddr_t))&~0x80000000, &addr, 1); 214*16845Ssam fp = getframe(fcor, addr); 215*16845Ssam if (fp == 0) 216*16845Ssam fp = checkintstack(); 217*16845Ssam /* search kernel stack? */ 218*16845Ssam if (fp == 0) { 219*16845Ssam printf("can't locate stack frame\n"); 220*16845Ssam return; 221*16845Ssam } 222*16845Ssam /* probably shouldn't clobber pcb, but for now this is easy */ 223*16845Ssam pcb.pcb_fp = addr; 224*16845Ssam pcb.pcb_pc = fp->fr_savpc; 225*16845Ssam pcb.pcb_ap = addr + sizeof (struct frame) + fp->fr_spa; 226*16845Ssam for (mask = fp->fr_mask; mask; mask >>= 1) 227*16845Ssam if (mask & 01) 228*16845Ssam pcb.pcb_ap += sizeof (caddr_t); 229*16845Ssam } 230*16845Ssam 231*16845Ssam /* 232*16845Ssam * Search interrupt stack for a valid frame. 233*16845Ssam */ 234*16845Ssam struct frame * 235*16845Ssam checkintstack(fcor) 236*16845Ssam { 237*16845Ssam char stack[NISP*NBPG]; 238*16845Ssam off_t off = vtophys(intstack); 239*16845Ssam struct frame *fp; 240*16845Ssam register caddr_t addr; 241*16845Ssam 242*16845Ssam if (off == -1 || lseek(fcor, off, L_SET) != off || 243*16845Ssam read(fcor, stack, sizeof (stack)) != sizeof (stack)) 244*16845Ssam return ((struct frame *)0); 245*16845Ssam addr = eintstack; 246*16845Ssam do { 247*16845Ssam addr -= sizeof (caddr_t); 248*16845Ssam fp = (struct frame *)&stack[addr - intstack]; 249*16845Ssam } while (addr >= intstack + sizeof (struct frame) && 250*16845Ssam !checkframe(fp)); 251*16845Ssam return (addr < intstack+sizeof (struct frame) ? (struct frame *)0 : fp); 252*16845Ssam } 253*16845Ssam 254*16845Ssam /* 255*16845Ssam * Get a stack frame and verify it looks like 256*16845Ssam * something which might be on a kernel stack. 257*16845Ssam */ 258*16845Ssam struct frame * 259*16845Ssam getframe(fcor, fp) 260*16845Ssam int fcor; 261*16845Ssam caddr_t fp; 262*16845Ssam { 263*16845Ssam static struct frame frame; 264*16845Ssam off_t off; 265*16845Ssam 266*16845Ssam if (!kstackaddr(fp) || (off = vtophys(fp)) == -1) 267*16845Ssam return ((struct frame *)0); 268*16845Ssam if (lseek(fcor, off, L_SET) != off || 269*16845Ssam read(fcor, &frame, sizeof (frame)) != sizeof (frame)) 270*16845Ssam return ((struct frame *)0); 271*16845Ssam if (!checkframe(&frame)) 272*16845Ssam return ((struct frame *)0); 273*16845Ssam return (&frame); 274*16845Ssam } 275*16845Ssam 276*16845Ssam /* 277*16845Ssam * Check a call frame to see if it's ok as 278*16845Ssam * a kernel stack frame. 279*16845Ssam */ 280*16845Ssam checkframe(fp) 281*16845Ssam register struct frame *fp; 282*16845Ssam { 283*16845Ssam 284*16845Ssam if (fp->fr_handler != 0 || fp->fr_s == 0) 285*16845Ssam return (0); 286*16845Ssam if (!kstackaddr(fp->fr_savap) || !kstackaddr(fp->fr_savfp)) 287*16845Ssam return (0); 288*16845Ssam return (within(fp->fr_savpc, txtmap.b1, txtmap.e1)); 289*16845Ssam } 290*16845Ssam 291*16845Ssam /* 292*16845Ssam * Check if an address is in one of the kernel's stacks: 293*16845Ssam * interrupt stack, rpb stack (during restart sequence), 294*16845Ssam * or u. stack. 295*16845Ssam */ 296*16845Ssam kstackaddr(addr) 297*16845Ssam caddr_t addr; 298*16845Ssam { 299*16845Ssam 300*16845Ssam return (within(addr, intstack, eintstack) || 301*16845Ssam within(addr, rpb + sizeof (struct rpb), scb) || 302*16845Ssam within(addr, ustack, eustack)); 303*16845Ssam } 304*16845Ssam 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