|
|
1.1 root 1: /*
2: * Copyright (c) 1983 Regents of the University of California.
3: * All rights reserved. The Berkeley software License Agreement
4: * specifies the terms and conditions for redistribution.
5: */
6:
7: #ifndef lint
8: static char sccsid[] = "@(#)coredump.c 5.1 (Berkeley) 5/31/85";
9: #endif not lint
10:
11: static char rcsid[] = "$Header: coredump.c,v 1.5 84/12/26 10:38:56 linton Exp $";
12:
13: /*
14: * Deal with the core dump anachronism.
15: */
16:
17: #include "defs.h"
18: #include "coredump.h"
19: #include "machine.h"
20: #include "object.h"
21: #include "main.h"
22: #include <sys/param.h>
23: #include <sys/dir.h>
24: #include <machine/psl.h>
25: #include <machine/pte.h>
26: #include <sys/user.h>
27: #include <sys/vm.h>
28: #include <machine/reg.h>
29: #include <a.out.h>
30:
31: #ifndef public
32: #define coredump_readin(m, r, s) coredump_xreadin(&(m), r, &(s))
33:
34: #include "machine.h"
35: #endif
36:
37: #define MAXSTKADDR (0x80000000 - ctob(UPAGES)) /* highest stack address */
38:
39: typedef struct {
40: Address begin;
41: Address end;
42: Address seekaddr;
43: } Map;
44:
45: private Map datamap, stkmap;
46: private File objfile;
47: private struct exec hdr;
48:
49: /*
50: * Special variables for debugging the kernel.
51: */
52:
53: private integer masterpcbb;
54: private integer slr;
55: private struct pte *sbr;
56: private struct pcb pcb;
57:
58: private getpcb ()
59: {
60: fseek(corefile, masterpcbb & ~0x80000000, 0);
61: get(corefile, pcb);
62: pcb.pcb_p0lr &= ~AST_CLR;
63: printf("p0br %lx p0lr %lx p1br %lx p1lr %lx\n",
64: pcb.pcb_p0br, pcb.pcb_p0lr, pcb.pcb_p1br, pcb.pcb_p1lr
65: );
66: setreg(0, pcb.pcb_r0);
67: setreg(1, pcb.pcb_r1);
68: setreg(2, pcb.pcb_r2);
69: setreg(3, pcb.pcb_r3);
70: setreg(4, pcb.pcb_r4);
71: setreg(5, pcb.pcb_r5);
72: setreg(6, pcb.pcb_r6);
73: setreg(7, pcb.pcb_r7);
74: setreg(8, pcb.pcb_r8);
75: setreg(9, pcb.pcb_r9);
76: setreg(10, pcb.pcb_r10);
77: setreg(11, pcb.pcb_r11);
78: setreg(ARGP, pcb.pcb_ap);
79: setreg(FRP, pcb.pcb_fp);
80: setreg(STKP, pcb.pcb_ksp);
81: setreg(PROGCTR, pcb.pcb_pc);
82: }
83:
84: public coredump_getkerinfo ()
85: {
86: Symbol s;
87:
88: s = lookup(identname("Sysmap", true));
89: if (s == nil) {
90: panic("can't find 'Sysmap'");
91: }
92: sbr = (struct pte *) (s->symvalue.offset);
93: s = lookup(identname("Syssize", true));
94: if (s == nil) {
95: panic("can't find 'Syssize'");
96: }
97: slr = (integer) (s->symvalue.offset);
98: printf("sbr %lx slr %lx\n", sbr, slr);
99: s = lookup(identname("masterpaddr", true));
100: if (s == nil) {
101: panic("can't find 'masterpaddr'");
102: }
103: fseek(
104: corefile,
105: datamap.seekaddr + s->symvalue.offset&0x7fffffff - datamap.begin,
106: 0
107: );
108: get(corefile, masterpcbb);
109: masterpcbb = (masterpcbb&PG_PFNUM)*512;
110: getpcb();
111: }
112:
113: private copyregs (savreg, reg)
114: Word savreg[], reg[];
115: {
116: reg[0] = savreg[R0];
117: reg[1] = savreg[R1];
118: reg[2] = savreg[R2];
119: reg[3] = savreg[R3];
120: reg[4] = savreg[R4];
121: reg[5] = savreg[R5];
122: reg[6] = savreg[R6];
123: reg[7] = savreg[R7];
124: reg[8] = savreg[R8];
125: reg[9] = savreg[R9];
126: reg[10] = savreg[R10];
127: reg[11] = savreg[R11];
128: reg[ARGP] = savreg[AP];
129: reg[FRP] = savreg[FP];
130: reg[STKP] = savreg[SP];
131: reg[PROGCTR] = savreg[PC];
132: }
133:
134: /*
135: * Read the user area information from the core dump.
136: */
137:
138: public coredump_xreadin(mask, reg, signo)
139: int *mask;
140: Word reg[];
141: int *signo;
142: {
143: register struct user *up;
144: register Word *savreg;
145: union {
146: struct user u;
147: char dummy[ctob(UPAGES)];
148: } ustruct;
149: Symbol s;
150:
151: objfile = fopen(objname, "r");
152: if (objfile == nil) {
153: fatal("can't read \"%s\"", objname);
154: }
155: get(objfile, hdr);
156: if (vaddrs) {
157: datamap.begin = 0;
158: datamap.end = 0xffffffff;
159: stkmap.begin = 0xffffffff;
160: stkmap.end = 0xffffffff;
161: } else {
162: up = &(ustruct.u);
163: fread(up, ctob(UPAGES), 1, corefile);
164: savreg = (Word *) &(ustruct.dummy[ctob(UPAGES)]);
165: *mask = savreg[PS];
166: copyregs(savreg, reg);
167: *signo = up->u_arg[0];
168: datamap.seekaddr = ctob(UPAGES);
169: stkmap.begin = MAXSTKADDR - ctob(up->u_ssize);
170: stkmap.end = MAXSTKADDR;
171: stkmap.seekaddr = datamap.seekaddr + ctob(up->u_dsize);
172: switch (hdr.a_magic) {
173: case OMAGIC:
174: datamap.begin = 0;
175: datamap.end = ctob(up->u_tsize) + ctob(up->u_dsize);
176: break;
177:
178: case NMAGIC:
179: case ZMAGIC:
180: datamap.begin = (Address) ptob(btop(ctob(up->u_tsize) - 1) + 1);
181: datamap.end = datamap.begin + ctob(up->u_dsize);
182: break;
183:
184: default:
185: fatal("bad magic number 0x%x", hdr.a_magic);
186: }
187: #ifdef UXMAG
188: /*
189: * Core dump not from this object file?
190: */
191: if (hdr.a_magic != 0 and up->u_exdata.ux_mag != 0 and
192: hdr.a_magic != up->u_exdata.ux_mag) {
193: warning("core dump ignored");
194: coredump = false;
195: fclose(corefile);
196: fclose(objfile);
197: start(nil, nil, nil);
198: }
199: #endif
200: }
201: }
202:
203: public coredump_close()
204: {
205: fclose(objfile);
206: }
207:
208: public coredump_readtext(buff, addr, nbytes)
209: char *buff;
210: Address addr;
211: int nbytes;
212: {
213: if (hdr.a_magic == OMAGIC or vaddrs) {
214: coredump_readdata(buff, addr, nbytes);
215: } else {
216: fseek(objfile, N_TXTOFF(hdr) + addr, 0);
217: fread(buff, nbytes, sizeof(Byte), objfile);
218: }
219: }
220:
221: /*
222: * Map a virtual address to a physical address.
223: */
224:
225: private Address vmap (addr)
226: Address addr;
227: {
228: Address r;
229: integer v, n;
230: struct pte pte;
231:
232: r = addr & ~0xc0000000;
233: v = btop(r);
234: switch (addr&0xc0000000) {
235: case 0xc0000000:
236: case 0x80000000:
237: /*
238: * In system space, so get system pte.
239: * If it is valid or reclaimable then the physical address
240: * is the combination of its page number and the page offset
241: * of the original address.
242: */
243: if (v >= slr) {
244: error("address %x out of segment", addr);
245: }
246: r = ((long) (sbr + v)) & ~0x80000000;
247: goto simple;
248:
249: case 0x40000000:
250: /*
251: * In p1 space, must not be in shadow region.
252: */
253: if (v < pcb.pcb_p1lr) {
254: error("address %x out of segment", addr);
255: }
256: r = (Address) (pcb.pcb_p1br + v);
257: break;
258:
259: case 0x00000000:
260: /*
261: * In p0 space, must not be off end of region.
262: */
263: if (v >= pcb.pcb_p0lr) {
264: error("address %x out of segment", addr);
265: }
266: r = (Address) (pcb.pcb_p0br + v);
267: break;
268:
269: default:
270: /* do nothing */
271: break;
272: }
273: /*
274: * For p0/p1 address, user-level page table should be in
275: * kernel virtual memory. Do second-level indirect by recursing.
276: */
277: if ((r & 0x80000000) == 0) {
278: error("bad p0br or p1br in pcb");
279: }
280: r = vmap(r);
281: simple:
282: /*
283: * "r" is now the address of the pte of the page
284: * we are interested in; get the pte and paste up the physical address.
285: */
286: fseek(corefile, r, 0);
287: n = fread(&pte, sizeof(pte), 1, corefile);
288: if (n != 1) {
289: error("page table botch (fread at %x returns %d)", r, n);
290: }
291: if (pte.pg_v == 0 and (pte.pg_fod != 0 or pte.pg_pfnum == 0)) {
292: error("page no valid or reclamable");
293: }
294: return (addr&PGOFSET) + ((Address) ptob(pte.pg_pfnum));
295: }
296:
297: public coredump_readdata(buff, addr, nbytes)
298: char *buff;
299: Address addr;
300: int nbytes;
301: {
302: Address a;
303:
304: a = addr;
305: if (a < datamap.begin) {
306: if (hdr.a_magic == OMAGIC) {
307: error("[data address 0x%x too low (lb = 0x%x)]", a, datamap.begin);
308: } else {
309: coredump_readtext(buff, a, nbytes);
310: }
311: } else if (a > stkmap.end) {
312: error("data address 0x%x too high (ub = 0x%x)", a, stkmap.end);
313: } else {
314: if (vaddrs) {
315: vreadfromfile(corefile, a, buff, nbytes);
316: } else {
317: readfromfile(corefile, a, buff, nbytes);
318: }
319: }
320: }
321:
322: /*
323: * Read a block of data from a memory image, mapping virtual addresses.
324: * Have to watch out for page boundaries.
325: */
326:
327: private vreadfromfile (corefile, v, buff, nbytes)
328: File corefile;
329: Address v;
330: char *buff;
331: integer nbytes;
332: {
333: Address a;
334: integer i, remainder, pagesize;
335: char *bufp;
336:
337: a = v;
338: pagesize = (integer) ptob(1);
339: remainder = pagesize - (a mod pagesize);
340: if (remainder >= nbytes) {
341: readfromfile(corefile, vmap(a), buff, nbytes);
342: } else {
343: readfromfile(corefile, vmap(a), buff, remainder);
344: a += remainder;
345: i = nbytes - remainder;
346: bufp = buff + remainder;
347: while (i > pagesize) {
348: readfromfile(corefile, vmap(a), bufp, pagesize);
349: a += pagesize;
350: bufp += pagesize;
351: i -= pagesize;
352: }
353: readfromfile(corefile, vmap(a), bufp, i);
354: }
355: }
356:
357: private readfromfile (f, a, buff, nbytes)
358: File f;
359: Address a;
360: char *buff;
361: integer nbytes;
362: {
363: integer fileaddr;
364:
365: if (a < stkmap.begin) {
366: fileaddr = datamap.seekaddr + a - datamap.begin;
367: } else {
368: fileaddr = stkmap.seekaddr + a - stkmap.begin;
369: }
370: fseek(f, fileaddr, 0);
371: fread(buff, nbytes, sizeof(Byte), f);
372: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.