xref: /csrg-svn/old/dbx/coredump.c (revision 18215)
19661Slinton /* Copyright (c) 1982 Regents of the University of California */
29661Slinton 
3*18215Slinton static	char sccsid[] = "@(#)coredump.c	1.7 (Berkeley) 03/01/85";
49661Slinton 
5*18215Slinton static char rcsid[] = "$Header: coredump.c,v 1.5 84/12/26 10:38:56 linton Exp $";
6*18215Slinton 
79661Slinton /*
89661Slinton  * Deal with the core dump anachronism.
99661Slinton  */
109661Slinton 
119661Slinton #include "defs.h"
129661Slinton #include "coredump.h"
139661Slinton #include "machine.h"
149661Slinton #include "object.h"
159661Slinton #include "main.h"
169661Slinton #include <sys/param.h>
179661Slinton #include <sys/dir.h>
189839Slinton #include <machine/psl.h>
199839Slinton #include <machine/pte.h>
209661Slinton #include <sys/user.h>
219661Slinton #include <sys/vm.h>
229839Slinton #include <machine/reg.h>
239661Slinton #include <a.out.h>
249661Slinton 
259661Slinton #ifndef public
269661Slinton #define coredump_readin(m, r, s) coredump_xreadin(&(m), r, &(s))
279661Slinton 
289661Slinton #include "machine.h"
299661Slinton #endif
309661Slinton 
319661Slinton #define MAXSTKADDR (0x80000000 - ctob(UPAGES))	/* highest stack address */
329661Slinton 
339661Slinton typedef struct {
349661Slinton     Address begin;
359661Slinton     Address end;
369661Slinton     Address seekaddr;
379661Slinton } Map;
389661Slinton 
399661Slinton private Map datamap, stkmap;
409661Slinton private File objfile;
419661Slinton private struct exec hdr;
429661Slinton 
439661Slinton /*
44*18215Slinton  * Special variables for debugging the kernel.
459661Slinton  */
469661Slinton 
47*18215Slinton private integer masterpcbb;
48*18215Slinton private integer slr;
49*18215Slinton private struct pte *sbr;
50*18215Slinton private struct pcb pcb;
51*18215Slinton 
52*18215Slinton private getpcb ()
539661Slinton {
54*18215Slinton     fseek(corefile, masterpcbb & ~0x80000000, 0);
55*18215Slinton     get(corefile, pcb);
56*18215Slinton     pcb.pcb_p0lr &= ~AST_CLR;
57*18215Slinton     printf("p0br %lx p0lr %lx p1br %lx p1lr %lx\n",
58*18215Slinton 	pcb.pcb_p0br, pcb.pcb_p0lr, pcb.pcb_p1br, pcb.pcb_p1lr
59*18215Slinton     );
60*18215Slinton     setreg(0, pcb.pcb_r0);
61*18215Slinton     setreg(1, pcb.pcb_r1);
62*18215Slinton     setreg(2, pcb.pcb_r2);
63*18215Slinton     setreg(3, pcb.pcb_r3);
64*18215Slinton     setreg(4, pcb.pcb_r4);
65*18215Slinton     setreg(5, pcb.pcb_r5);
66*18215Slinton     setreg(6, pcb.pcb_r6);
67*18215Slinton     setreg(7, pcb.pcb_r7);
68*18215Slinton     setreg(8, pcb.pcb_r8);
69*18215Slinton     setreg(9, pcb.pcb_r9);
70*18215Slinton     setreg(10, pcb.pcb_r10);
71*18215Slinton     setreg(11, pcb.pcb_r11);
72*18215Slinton     setreg(ARGP, pcb.pcb_ap);
73*18215Slinton     setreg(FRP, pcb.pcb_fp);
74*18215Slinton     setreg(STKP, pcb.pcb_ksp);
75*18215Slinton     setreg(PROGCTR, pcb.pcb_pc);
76*18215Slinton }
779661Slinton 
78*18215Slinton public coredump_getkerinfo ()
79*18215Slinton {
80*18215Slinton     Symbol s;
81*18215Slinton 
82*18215Slinton     s = lookup(identname("Sysmap", true));
83*18215Slinton     if (s == nil) {
84*18215Slinton 	panic("can't find 'Sysmap'");
859661Slinton     }
86*18215Slinton     sbr = (struct pte *) (s->symvalue.offset);
87*18215Slinton     s = lookup(identname("Syssize", true));
88*18215Slinton     if (s == nil) {
89*18215Slinton 	panic("can't find 'Syssize'");
90*18215Slinton     }
91*18215Slinton     slr = (integer) (s->symvalue.offset);
92*18215Slinton     printf("sbr %lx slr %lx\n", sbr, slr);
93*18215Slinton     s = lookup(identname("masterpaddr", true));
94*18215Slinton     if (s == nil) {
95*18215Slinton 	panic("can't find 'masterpaddr'");
96*18215Slinton     }
97*18215Slinton     fseek(
98*18215Slinton 	corefile,
99*18215Slinton 	datamap.seekaddr + s->symvalue.offset&0x7fffffff - datamap.begin,
100*18215Slinton 	0
101*18215Slinton     );
102*18215Slinton     get(corefile, masterpcbb);
103*18215Slinton     masterpcbb = (masterpcbb&PG_PFNUM)*512;
104*18215Slinton     getpcb();
105*18215Slinton }
106*18215Slinton 
107*18215Slinton private copyregs (savreg, reg)
108*18215Slinton Word savreg[], reg[];
109*18215Slinton {
1109661Slinton     reg[0] = savreg[R0];
1119661Slinton     reg[1] = savreg[R1];
1129661Slinton     reg[2] = savreg[R2];
1139661Slinton     reg[3] = savreg[R3];
1149661Slinton     reg[4] = savreg[R4];
1159661Slinton     reg[5] = savreg[R5];
1169661Slinton     reg[6] = savreg[R6];
1179661Slinton     reg[7] = savreg[R7];
1189661Slinton     reg[8] = savreg[R8];
1199661Slinton     reg[9] = savreg[R9];
1209661Slinton     reg[10] = savreg[R10];
1219661Slinton     reg[11] = savreg[R11];
1229661Slinton     reg[ARGP] = savreg[AP];
1239661Slinton     reg[FRP] = savreg[FP];
1249661Slinton     reg[STKP] = savreg[SP];
1259661Slinton     reg[PROGCTR] = savreg[PC];
126*18215Slinton }
1279661Slinton 
128*18215Slinton /*
129*18215Slinton  * Read the user area information from the core dump.
130*18215Slinton  */
1319661Slinton 
132*18215Slinton public coredump_xreadin(mask, reg, signo)
133*18215Slinton int *mask;
134*18215Slinton Word reg[];
135*18215Slinton int *signo;
136*18215Slinton {
137*18215Slinton     register struct user *up;
138*18215Slinton     register Word *savreg;
139*18215Slinton     union {
140*18215Slinton 	struct user u;
141*18215Slinton 	char dummy[ctob(UPAGES)];
142*18215Slinton     } ustruct;
143*18215Slinton     Symbol s;
144*18215Slinton 
145*18215Slinton     objfile = fopen(objname, "r");
146*18215Slinton     if (objfile == nil) {
147*18215Slinton 	fatal("can't read \"%s\"", objname);
1489661Slinton     }
149*18215Slinton     get(objfile, hdr);
150*18215Slinton     if (vaddrs) {
151*18215Slinton 	datamap.begin = 0;
152*18215Slinton 	datamap.end = 0xffffffff;
153*18215Slinton 	stkmap.begin = 0xffffffff;
154*18215Slinton 	stkmap.end = 0xffffffff;
155*18215Slinton     } else {
156*18215Slinton 	up = &(ustruct.u);
157*18215Slinton 	fread(up, ctob(UPAGES), 1, corefile);
158*18215Slinton 	savreg = (Word *) &(ustruct.dummy[ctob(UPAGES)]);
159*18215Slinton 	*mask = savreg[PS];
160*18215Slinton 	copyregs(savreg, reg);
161*18215Slinton 	*signo = up->u_arg[0];
162*18215Slinton 	datamap.seekaddr = ctob(UPAGES);
163*18215Slinton 	stkmap.begin = MAXSTKADDR - ctob(up->u_ssize);
164*18215Slinton 	stkmap.end = MAXSTKADDR;
165*18215Slinton 	stkmap.seekaddr = datamap.seekaddr + ctob(up->u_dsize);
166*18215Slinton 	switch (hdr.a_magic) {
167*18215Slinton 	    case OMAGIC:
168*18215Slinton 		datamap.begin = 0;
169*18215Slinton 		datamap.end = ctob(up->u_tsize) + ctob(up->u_dsize);
170*18215Slinton 		break;
171*18215Slinton 
172*18215Slinton 	    case NMAGIC:
173*18215Slinton 	    case ZMAGIC:
174*18215Slinton 		datamap.begin = (Address) ptob(btop(ctob(up->u_tsize) - 1) + 1);
175*18215Slinton 		datamap.end = datamap.begin + ctob(up->u_dsize);
176*18215Slinton 		break;
177*18215Slinton 
178*18215Slinton 	    default:
179*18215Slinton 		fatal("bad magic number 0x%x", hdr.a_magic);
180*18215Slinton 	}
181*18215Slinton #ifdef UXMAG
182*18215Slinton 	/*
183*18215Slinton 	 * Core dump not from this object file?
184*18215Slinton 	 */
185*18215Slinton 	if (hdr.a_magic != 0 and up->u_exdata.ux_mag  != 0 and
186*18215Slinton 	  hdr.a_magic != up->u_exdata.ux_mag) {
187*18215Slinton 	    warning("core dump ignored");
188*18215Slinton 	    coredump = false;
189*18215Slinton 	    fclose(corefile);
190*18215Slinton 	    fclose(objfile);
191*18215Slinton 	    start(nil, nil, nil);
192*18215Slinton 	}
193*18215Slinton #endif
194*18215Slinton     }
1959661Slinton }
1969661Slinton 
1979661Slinton public coredump_close()
1989661Slinton {
1999661Slinton     fclose(objfile);
2009661Slinton }
2019661Slinton 
2029661Slinton public coredump_readtext(buff, addr, nbytes)
2039661Slinton char *buff;
2049661Slinton Address addr;
2059661Slinton int nbytes;
2069661Slinton {
207*18215Slinton     if (hdr.a_magic == OMAGIC or vaddrs) {
2089661Slinton 	coredump_readdata(buff, addr, nbytes);
2099661Slinton     } else {
2109661Slinton 	fseek(objfile, N_TXTOFF(hdr) + addr, 0);
2119661Slinton 	fread(buff, nbytes, sizeof(Byte), objfile);
2129661Slinton     }
2139661Slinton }
2149661Slinton 
215*18215Slinton /*
216*18215Slinton  * Map a virtual address to a physical address.
217*18215Slinton  */
218*18215Slinton 
219*18215Slinton private Address vmap (addr)
220*18215Slinton Address addr;
221*18215Slinton {
222*18215Slinton     Address r;
223*18215Slinton     integer v, n;
224*18215Slinton     struct pte pte;
225*18215Slinton 
226*18215Slinton     r = addr & ~0xc0000000;
227*18215Slinton     v = btop(r);
228*18215Slinton     switch (addr&0xc0000000) {
229*18215Slinton 	case 0xc0000000:
230*18215Slinton 	case 0x80000000:
231*18215Slinton 	    /*
232*18215Slinton 	     * In system space, so get system pte.
233*18215Slinton 	     * If it is valid or reclaimable then the physical address
234*18215Slinton 	     * is the combination of its page number and the page offset
235*18215Slinton 	     * of the original address.
236*18215Slinton 	     */
237*18215Slinton 	    if (v >= slr) {
238*18215Slinton 		error("address %x out of segment", addr);
239*18215Slinton 	    }
240*18215Slinton 	    r = ((long) (sbr + v)) & ~0x80000000;
241*18215Slinton 	    goto simple;
242*18215Slinton 
243*18215Slinton 	case 0x40000000:
244*18215Slinton 	    /*
245*18215Slinton 	     * In p1 space, must not be in shadow region.
246*18215Slinton 	     */
247*18215Slinton 	    if (v < pcb.pcb_p1lr) {
248*18215Slinton 		error("address %x out of segment", addr);
249*18215Slinton 	    }
250*18215Slinton 	    r = (Address) (pcb.pcb_p1br + v);
251*18215Slinton 	    break;
252*18215Slinton 
253*18215Slinton 	case 0x00000000:
254*18215Slinton 	    /*
255*18215Slinton 	     * In p0 space, must not be off end of region.
256*18215Slinton 	     */
257*18215Slinton 	    if (v >= pcb.pcb_p0lr) {
258*18215Slinton 		error("address %x out of segment", addr);
259*18215Slinton 	    }
260*18215Slinton 	    r = (Address) (pcb.pcb_p0br + v);
261*18215Slinton 	    break;
262*18215Slinton 
263*18215Slinton 	default:
264*18215Slinton 	    /* do nothing */
265*18215Slinton 	    break;
266*18215Slinton     }
267*18215Slinton     /*
268*18215Slinton      * For p0/p1 address, user-level page table should be in
269*18215Slinton      * kernel virtual memory.  Do second-level indirect by recursing.
270*18215Slinton      */
271*18215Slinton     if ((r & 0x80000000) == 0) {
272*18215Slinton 	error("bad p0br or p1br in pcb");
273*18215Slinton     }
274*18215Slinton     r = vmap(r);
275*18215Slinton simple:
276*18215Slinton     /*
277*18215Slinton      * "r" is now the address of the pte of the page
278*18215Slinton      * we are interested in; get the pte and paste up the physical address.
279*18215Slinton      */
280*18215Slinton     fseek(corefile, r, 0);
281*18215Slinton     n = fread(&pte, sizeof(pte), 1, corefile);
282*18215Slinton     if (n != 1) {
283*18215Slinton 	error("page table botch (fread at %x returns %d)", r, n);
284*18215Slinton     }
285*18215Slinton     if (pte.pg_v == 0 and (pte.pg_fod != 0 or pte.pg_pfnum == 0)) {
286*18215Slinton 	error("page no valid or reclamable");
287*18215Slinton     }
288*18215Slinton     return (addr&PGOFSET) + ((Address) ptob(pte.pg_pfnum));
289*18215Slinton }
290*18215Slinton 
2919661Slinton public coredump_readdata(buff, addr, nbytes)
2929661Slinton char *buff;
2939661Slinton Address addr;
2949661Slinton int nbytes;
2959661Slinton {
296*18215Slinton     Address a;
297*18215Slinton 
298*18215Slinton     a = addr;
299*18215Slinton     if (a < datamap.begin) {
30016608Ssam 	if (hdr.a_magic == OMAGIC) {
301*18215Slinton 	    error("[data address 0x%x too low (lb = 0x%x)]", a, datamap.begin);
30216608Ssam 	} else {
303*18215Slinton 	    coredump_readtext(buff, a, nbytes);
30416608Ssam 	}
305*18215Slinton     } else if (a > stkmap.end) {
306*18215Slinton 	error("data address 0x%x too high (ub = 0x%x)", a, stkmap.end);
3079661Slinton     } else {
308*18215Slinton 	if (vaddrs) {
309*18215Slinton 	    vreadfromfile(corefile, a, buff, nbytes);
310*18215Slinton 	} else {
311*18215Slinton 	    readfromfile(corefile, a, buff, nbytes);
312*18215Slinton 	}
3139661Slinton     }
3149661Slinton }
315*18215Slinton 
316*18215Slinton /*
317*18215Slinton  * Read a block of data from a memory image, mapping virtual addresses.
318*18215Slinton  * Have to watch out for page boundaries.
319*18215Slinton  */
320*18215Slinton 
321*18215Slinton private vreadfromfile (corefile, v, buff, nbytes)
322*18215Slinton File corefile;
323*18215Slinton Address v;
324*18215Slinton char *buff;
325*18215Slinton integer nbytes;
326*18215Slinton {
327*18215Slinton     Address a;
328*18215Slinton     integer i, remainder, pagesize;
329*18215Slinton     char *bufp;
330*18215Slinton 
331*18215Slinton     a = v;
332*18215Slinton     pagesize = (integer) ptob(1);
333*18215Slinton     remainder = pagesize - (a mod pagesize);
334*18215Slinton     if (remainder >= nbytes) {
335*18215Slinton 	readfromfile(corefile, vmap(a), buff, nbytes);
336*18215Slinton     } else {
337*18215Slinton 	readfromfile(corefile, vmap(a), buff, remainder);
338*18215Slinton 	a += remainder;
339*18215Slinton 	i = nbytes - remainder;
340*18215Slinton 	bufp = buff + remainder;
341*18215Slinton 	while (i > pagesize) {
342*18215Slinton 	    readfromfile(corefile, vmap(a), bufp, pagesize);
343*18215Slinton 	    a += pagesize;
344*18215Slinton 	    bufp += pagesize;
345*18215Slinton 	    i -= pagesize;
346*18215Slinton 	}
347*18215Slinton 	readfromfile(corefile, vmap(a), bufp, i);
348*18215Slinton     }
349*18215Slinton }
350*18215Slinton 
351*18215Slinton private readfromfile (f, a, buff, nbytes)
352*18215Slinton File f;
353*18215Slinton Address a;
354*18215Slinton char *buff;
355*18215Slinton integer nbytes;
356*18215Slinton {
357*18215Slinton     integer fileaddr;
358*18215Slinton 
359*18215Slinton     if (a < stkmap.begin) {
360*18215Slinton 	fileaddr = datamap.seekaddr + a - datamap.begin;
361*18215Slinton     } else {
362*18215Slinton 	fileaddr = stkmap.seekaddr + a - stkmap.begin;
363*18215Slinton     }
364*18215Slinton     fseek(f, fileaddr, 0);
365*18215Slinton     fread(buff, nbytes, sizeof(Byte), f);
366*18215Slinton }
367