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