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