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