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