|
|
1.1 root 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.