1*33073Sbostic static char sccsid[] = "@(#)setup.c 4.11 (Berkeley) 87/12/21";
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
setsym()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++)
74*33073Sbostic if (sp->n_un.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
setcor()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");
11520184Ssam physrw(fcor, KVTOPH(cursym->n_value), &masterpcbb, 1);
11620184Ssam 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
getpcb()1523777Sroot getpcb()
1533777Sroot {
1543779Sroot
15520184Ssam 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 */
findstackframe()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;
18420184Ssam lseek(fcor, KVTOPH(cursym->n_value), L_SET);
18516845Ssam read(fcor, &panicstr, sizeof (panicstr));
18616845Ssam if (panicstr == 0)
18716845Ssam return;
18820184Ssam lseek(fcor, KVTOPH((off_t)panicstr), L_SET);
18916845Ssam read(fcor, buf, sizeof (buf));
19016845Ssam for (cp = buf; cp < &buf[sizeof (buf)] && *cp; cp++)
19120184Ssam 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);
21320184Ssam 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 *
checkintstack(fcor)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 *
getframe(fcor,fp)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 */
checkframe(fp)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 */
kstackaddr(addr)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
create(f)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
getfile(filnam,cnt)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
setvar()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