install with -s
[unix-history] / usr / src / old / dbx / coredump.c
CommitLineData
442fe3bf
DF
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 */
77e05717 6
442fe3bf
DF
7#ifndef lint
8static char sccsid[] = "@(#)coredump.c 5.1 (Berkeley) %G%";
9#endif not lint
0022c355
ML
10
11static char rcsid[] = "$Header: coredump.c,v 1.5 84/12/26 10:38:56 linton Exp $";
77e05717
ML
12
13/*
14 * Deal with the core dump anachronism.
77e05717
ML
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>
4c25ec87
ML
24#include <machine/psl.h>
25#include <machine/pte.h>
77e05717
ML
26#include <sys/user.h>
27#include <sys/vm.h>
4c25ec87 28#include <machine/reg.h>
77e05717
ML
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
39typedef struct {
40 Address begin;
41 Address end;
42 Address seekaddr;
43} Map;
44
45private Map datamap, stkmap;
46private File objfile;
47private struct exec hdr;
48
49/*
0022c355 50 * Special variables for debugging the kernel.
77e05717
ML
51 */
52
0022c355
ML
53private integer masterpcbb;
54private integer slr;
55private struct pte *sbr;
56private struct pcb pcb;
57
58private getpcb ()
77e05717 59{
0022c355
ML
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}
77e05717 83
0022c355
ML
84public coredump_getkerinfo ()
85{
86 Symbol s;
87
88 s = lookup(identname("Sysmap", true));
89 if (s == nil) {
90 panic("can't find 'Sysmap'");
77e05717 91 }
0022c355
ML
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
113private copyregs (savreg, reg)
114Word savreg[], reg[];
115{
77e05717
ML
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];
0022c355 132}
77e05717 133
0022c355
ML
134/*
135 * Read the user area information from the core dump.
136 */
77e05717 137
0022c355
ML
138public coredump_xreadin(mask, reg, signo)
139int *mask;
140Word reg[];
141int *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
77e05717 200 }
77e05717
ML
201}
202
203public coredump_close()
204{
205 fclose(objfile);
206}
207
208public coredump_readtext(buff, addr, nbytes)
209char *buff;
210Address addr;
211int nbytes;
212{
0022c355 213 if (hdr.a_magic == OMAGIC or vaddrs) {
77e05717
ML
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
0022c355
ML
221/*
222 * Map a virtual address to a physical address.
223 */
224
225private Address vmap (addr)
226Address 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);
281simple:
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
77e05717
ML
297public coredump_readdata(buff, addr, nbytes)
298char *buff;
299Address addr;
300int nbytes;
301{
0022c355
ML
302 Address a;
303
304 a = addr;
305 if (a < datamap.begin) {
2fd0f574 306 if (hdr.a_magic == OMAGIC) {
0022c355
ML
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);
2fd0f574 316 } else {
0022c355 317 readfromfile(corefile, a, buff, nbytes);
2fd0f574 318 }
0022c355
ML
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
327private vreadfromfile (corefile, v, buff, nbytes)
328File corefile;
329Address v;
330char *buff;
331integer 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
357private readfromfile (f, a, buff, nbytes)
358File f;
359Address a;
360char *buff;
361integer nbytes;
362{
363 integer fileaddr;
364
365 if (a < stkmap.begin) {
366 fileaddr = datamap.seekaddr + a - datamap.begin;
77e05717 367 } else {
0022c355 368 fileaddr = stkmap.seekaddr + a - stkmap.begin;
77e05717 369 }
0022c355
ML
370 fseek(f, fileaddr, 0);
371 fread(buff, nbytes, sizeof(Byte), f);
77e05717 372}