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