xref: /original-bsd/old/dbx/coredump.c (revision f1656be1)
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.3 (Berkeley) 01/12/88";
9 #endif not lint
10 
11 static char rcsid[] = "$Header: coredump.c,v 1.4 87/04/15 03:25:22 donn 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 <a.out.h>
23 
24 #ifndef public
25 #define coredump_readin(m, r, s) coredump_xreadin(&(m), r, &(s))
26 
27 #include "machine.h"
28 #endif
29 
30 typedef struct {
31     Address begin;
32     Address end;
33     Address seekaddr;
34 } Map;
35 
36 private Map datamap, stkmap;
37 private File objfile;
38 private struct exec hdr;
39 
40 public coredump_getkerinfo ()
41 {
42     Symbol s;
43 
44     s = lookup(identname("Sysmap", true));
45     if (s == nil) {
46 	panic("can't find 'Sysmap'");
47     }
48     sbr = (struct pte *) (s->symvalue.offset);
49     s = lookup(identname("Syssize", true));
50     if (s == nil) {
51 	panic("can't find 'Syssize'");
52     }
53     slr = (integer) (s->symvalue.offset);
54     printf("sbr %lx slr %lx\n", sbr, slr);
55     s = lookup(identname("masterpaddr", true));
56     if (s == nil) {
57 	panic("can't find 'masterpaddr'");
58     }
59     fseek(
60 	corefile,
61 	datamap.seekaddr + s->symvalue.offset&0x7fffffff - datamap.begin,
62 	0
63     );
64     get(corefile, masterpcbb);
65     masterpcbb = (masterpcbb&PG_PFNUM)*NBPG;
66     getpcb();
67 }
68 
69 /*
70  * Read the user area information from the core dump.
71  */
72 
73 public coredump_xreadin(mask, reg, signo)
74 int *mask;
75 Word reg[];
76 short *signo;
77 {
78     register struct user *up;
79     register Word *savreg;
80     union {
81 	struct user u;
82 	char dummy[ctob(UPAGES)];
83     } ustruct;
84     Symbol s;
85 
86     objfile = fopen(objname, "r");
87     if (objfile == nil) {
88 	fatal("can't read \"%s\"", objname);
89     }
90     get(objfile, hdr);
91     if (vaddrs) {
92 	datamap.begin = 0;
93 	datamap.end = 0xffffffff;
94 	stkmap.begin = 0xffffffff;
95 	stkmap.end = 0xffffffff;
96     } else {
97 	up = &(ustruct.u);
98 	fread(up, ctob(UPAGES), 1, corefile);
99 #	if vax || tahoe
100 	    savreg = (Word *) &(ustruct.dummy[ctob(UPAGES)]);
101 #	else ifdef mc68000
102 	    savreg = (Word *) (
103 		&ustruct.dummy[ctob(UPAGES) - 10] - (NREG * sizeof(Word))
104 	    );
105 #	endif
106 #       ifdef IRIS
107 	    *mask = savreg[RPS];
108 #       else
109 	    *mask = savreg[PS];
110 #       endif
111 	copyregs(savreg, reg);
112 	*signo = up->u_arg[0];
113 	datamap.seekaddr = ctob(UPAGES);
114 	stkmap.begin = USRSTACK - ctob(up->u_ssize);
115 	stkmap.end = USRSTACK;
116 	stkmap.seekaddr = datamap.seekaddr + ctob(up->u_dsize);
117 	switch (hdr.a_magic) {
118 	    case OMAGIC:
119 		datamap.begin = CODESTART;
120 		datamap.end = CODESTART + ctob(up->u_tsize) + ctob(up->u_dsize);
121 		break;
122 
123 	    case NMAGIC:
124 	    case ZMAGIC:
125 		datamap.begin = (Address)
126 		    ptob(btop(ctob(up->u_tsize) - 1) + 1) + CODESTART;
127 		datamap.end = datamap.begin + ctob(up->u_dsize);
128 		break;
129 
130 	    default:
131 		fatal("bad magic number 0x%x", hdr.a_magic);
132 	}
133 #ifdef UXMAG
134 	/*
135 	 * Core dump not from this object file?
136 	 */
137 	if (hdr.a_magic != 0 and up->u_exdata.ux_mag  != 0 and
138 	  hdr.a_magic != up->u_exdata.ux_mag) {
139 	    warning("core dump ignored");
140 	    coredump = false;
141 	    fclose(corefile);
142 	    fclose(objfile);
143 	    start(nil, nil, nil);
144 	}
145 #endif
146     }
147 }
148 
149 public coredump_close()
150 {
151     fclose(objfile);
152 }
153 
154 public coredump_readtext(buff, addr, nbytes)
155 char *buff;
156 Address addr;
157 int nbytes;
158 {
159     if (hdr.a_magic == OMAGIC or vaddrs) {
160 	coredump_readdata(buff, addr, nbytes);
161     } else {
162 	fseek(objfile, N_TXTOFF(hdr) + addr - CODESTART, 0);
163 	fread(buff, nbytes, sizeof(Byte), objfile);
164     }
165 }
166 
167 public coredump_readdata(buff, addr, nbytes)
168 char *buff;
169 Address addr;
170 int nbytes;
171 {
172     Address a;
173 
174     a = addr;
175     if (a < datamap.begin) {
176 	if (hdr.a_magic == OMAGIC) {
177 	    error("[data address 0x%x too low (lb = 0x%x)]", a, datamap.begin);
178 	} else {
179 	    coredump_readtext(buff, a, nbytes);
180 	}
181     } else if (a > stkmap.end) {
182 	error("data address 0x%x too high (ub = 0x%x)", a, stkmap.end);
183     } else {
184 	if (vaddrs) {
185 	    vreadfromfile(corefile, a, buff, nbytes);
186 	} else {
187 	    readfromfile(corefile, a, buff, nbytes);
188 	}
189     }
190 }
191 
192 /*
193  * Read a block of data from a memory image, mapping virtual addresses.
194  * Have to watch out for page boundaries.
195  */
196 
197 private vreadfromfile (corefile, v, buff, nbytes)
198 File corefile;
199 Address v;
200 char *buff;
201 integer nbytes;
202 {
203     Address a;
204     integer i, remainder, pagesize;
205     char *bufp;
206 
207     a = v;
208     pagesize = (integer) ptob(1);
209     remainder = pagesize - (a mod pagesize);
210     if (remainder >= nbytes) {
211 	readfromfile(corefile, vmap(a), buff, nbytes);
212     } else {
213 	readfromfile(corefile, vmap(a), buff, remainder);
214 	a += remainder;
215 	i = nbytes - remainder;
216 	bufp = buff + remainder;
217 	while (i > pagesize) {
218 	    readfromfile(corefile, vmap(a), bufp, pagesize);
219 	    a += pagesize;
220 	    bufp += pagesize;
221 	    i -= pagesize;
222 	}
223 	readfromfile(corefile, vmap(a), bufp, i);
224     }
225 }
226 
227 private readfromfile (f, a, buff, nbytes)
228 File f;
229 Address a;
230 char *buff;
231 integer nbytes;
232 {
233     integer fileaddr;
234 
235     if (a < stkmap.begin) {
236 	fileaddr = datamap.seekaddr + a - datamap.begin;
237     } else {
238 	fileaddr = stkmap.seekaddr + a - stkmap.begin;
239     }
240     fseek(f, fileaddr, 0);
241     fread(buff, nbytes, sizeof(Byte), f);
242 }
243