|
|
1.1 root 1: #ifndef lint
2: static char sccsid[] = "@(#)setup.c 1.1 (Berkeley) 2/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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.