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