xref: /original-bsd/old/dbx/coredump.c (revision e2944021)
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.2 (Berkeley) 02/23/86";
9 #endif not lint
10 
11 static char rcsid[] = "$Header: coredump.c,v 1.5 84/12/26 10:38:56 linton 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(corefile,
60 	datamap.seekaddr + physaddr(s->symvalue.offset) - datamap.begin, 0);
61     get(corefile, masterpcbb);
62     masterpcbb = (masterpcbb&PG_PFNUM)*NBPG;
63     getpcb();
64 }
65 
66 /*
67  * Read the user area information from the core dump.
68  */
69 
70 public coredump_xreadin(mask, reg, signo)
71 int *mask;
72 Word reg[];
73 short *signo;
74 {
75     register struct user *up;
76     register Word *savreg;
77     union {
78 	struct user u;
79 	char dummy[ctob(UPAGES)];
80     } ustruct;
81     Symbol s;
82 
83     objfile = fopen(objname, "r");
84     if (objfile == nil) {
85 	fatal("can't read \"%s\"", objname);
86     }
87     get(objfile, hdr);
88     if (vaddrs) {
89 	datamap.begin = 0;
90 	datamap.end = 0xffffffff;
91 	stkmap.begin = 0xffffffff;
92 	stkmap.end = 0xffffffff;
93     } else {
94 	up = &(ustruct.u);
95 	fread(up, ctob(UPAGES), 1, corefile);
96 	savreg = (Word *) &(ustruct.dummy[ctob(UPAGES)]);
97 	*mask = savreg[PS];
98 	copyregs(savreg, reg);
99 	*signo = up->u_arg[0];
100 	datamap.seekaddr = ctob(UPAGES);
101 	stkmap.begin = USRSTACK - ctob(up->u_ssize);
102 	stkmap.end = USRSTACK;
103 	stkmap.seekaddr = datamap.seekaddr + ctob(up->u_dsize);
104 	switch (hdr.a_magic) {
105 	    case OMAGIC:
106 		datamap.begin = 0;
107 		datamap.end = ctob(up->u_tsize) + ctob(up->u_dsize);
108 		break;
109 
110 	    case NMAGIC:
111 	    case ZMAGIC:
112 		datamap.begin = (Address) ptob(btop(ctob(up->u_tsize) - 1) + 1);
113 		datamap.end = datamap.begin + ctob(up->u_dsize);
114 		break;
115 
116 	    default:
117 		fatal("bad magic number 0x%x", hdr.a_magic);
118 	}
119 #ifdef UXMAG
120 	/*
121 	 * Core dump not from this object file?
122 	 */
123 	if (hdr.a_magic != 0 and up->u_exdata.ux_mag  != 0 and
124 	  hdr.a_magic != up->u_exdata.ux_mag) {
125 	    warning("core dump ignored");
126 	    coredump = false;
127 	    fclose(corefile);
128 	    fclose(objfile);
129 	    start(nil, nil, nil);
130 	}
131 #endif
132     }
133 }
134 
135 public coredump_close()
136 {
137     fclose(objfile);
138 }
139 
140 public coredump_readtext(buff, addr, nbytes)
141 char *buff;
142 Address addr;
143 int nbytes;
144 {
145     if (hdr.a_magic == OMAGIC or vaddrs) {
146 	coredump_readdata(buff, addr, nbytes);
147     } else {
148 	fseek(objfile, N_TXTOFF(hdr) + addr, 0);
149 	fread(buff, nbytes, sizeof(Byte), objfile);
150     }
151 }
152 
153 public coredump_readdata(buff, addr, nbytes)
154 char *buff;
155 Address addr;
156 int nbytes;
157 {
158     Address a;
159 
160     a = addr;
161     if (a < datamap.begin) {
162 	if (hdr.a_magic == OMAGIC) {
163 	    error("[data address 0x%x too low (lb = 0x%x)]", a, datamap.begin);
164 	} else {
165 	    coredump_readtext(buff, a, nbytes);
166 	}
167     } else if (a > stkmap.end) {
168 	error("data address 0x%x too high (ub = 0x%x)", a, stkmap.end);
169     } else {
170 	if (vaddrs) {
171 	    vreadfromfile(corefile, a, buff, nbytes);
172 	} else {
173 	    readfromfile(corefile, a, buff, nbytes);
174 	}
175     }
176 }
177 
178 /*
179  * Read a block of data from a memory image, mapping virtual addresses.
180  * Have to watch out for page boundaries.
181  */
182 
183 private vreadfromfile (corefile, v, buff, nbytes)
184 File corefile;
185 Address v;
186 char *buff;
187 integer nbytes;
188 {
189     Address a;
190     integer i, remainder, pagesize;
191     char *bufp;
192 
193     a = v;
194     pagesize = (integer) ptob(1);
195     remainder = pagesize - (a mod pagesize);
196     if (remainder >= nbytes) {
197 	readfromfile(corefile, vmap(a), buff, nbytes);
198     } else {
199 	readfromfile(corefile, vmap(a), buff, remainder);
200 	a += remainder;
201 	i = nbytes - remainder;
202 	bufp = buff + remainder;
203 	while (i > pagesize) {
204 	    readfromfile(corefile, vmap(a), bufp, pagesize);
205 	    a += pagesize;
206 	    bufp += pagesize;
207 	    i -= pagesize;
208 	}
209 	readfromfile(corefile, vmap(a), bufp, i);
210     }
211 }
212 
213 private readfromfile (f, a, buff, nbytes)
214 File f;
215 Address a;
216 char *buff;
217 integer nbytes;
218 {
219     integer fileaddr;
220 
221     if (a < stkmap.begin) {
222 	fileaddr = datamap.seekaddr + a - datamap.begin;
223     } else {
224 	fileaddr = stkmap.seekaddr + a - stkmap.begin;
225     }
226     fseek(f, fileaddr, 0);
227     fread(buff, nbytes, sizeof(Byte), f);
228 }
229