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