packages: don't put oss on cd.
[minix.git] / commands / mdb / core.c
blob78448615c6dafefca1c565395564ebe603ebcaef
1 /*
2 * core.c for mdb
4 * reads information from 'core' file
5 * Partly derived from 'adb' by D. Dugger.
6 */
7 #include "mdb.h"
9 #include <signal.h>
10 #include <fcntl.h>
11 #include <stdlib.h>
12 #include <unistd.h>
13 #include <stdio.h>
14 #include <string.h>
15 #include <sys/ptrace.h>
17 #include <machine/archtypes.h>
18 #include <kernel/const.h>
19 #include <kernel/type.h>
20 #include <kernel/proc.h>
22 /* defined in kernel.c */
23 extern struct proc *prc;
25 #include "proto.h"
27 #define BSIZE 512
28 #define LOGBS 9
30 PRIVATE struct file {
31 int fid;
32 char *name;
33 long cblock;
34 unsigned long tmap[3];
35 unsigned long dmap[3];
36 unsigned long smap[3];
37 char buf[BSIZE + BSIZE];
38 } Core_File, *core_file;
40 #define b1 tmap[0]
41 #define e1 tmap[1]
42 #define f1 tmap[2]
43 #define b2 dmap[0]
44 #define e2 dmap[1]
45 #define f2 dmap[2]
46 #define b3 smap[0]
47 #define e3 smap[1]
48 #define f3 smap[2]
50 PRIVATE long cnt[3]; /* Sizes of segments */
51 PRIVATE int h_size; /* Size of core header */
52 PRIVATE char def_name[] = "core"; /* Default core name */
54 #define SIZE_MP_SEG (sizeof(struct mem_map) * NR_LOCAL_SEGS)
55 #define SIZE_KINFO sizeof(struct proc)
56 #define SIZE_HEADER SIZE_MP_SEG
58 FORWARD _PROTOTYPE( int kernel_info , (int fd ));
59 FORWARD _PROTOTYPE( void setmap , (struct file *fp ));
60 FORWARD _PROTOTYPE( void read_info , (struct file *fp ));
61 FORWARD _PROTOTYPE( void ill_addr , (long d , int segment ));
62 FORWARD _PROTOTYPE( long map_addr , (long d , int segment ));
63 FORWARD _PROTOTYPE( unsigned long c_status, (void));
64 FORWARD _PROTOTYPE( long getn, (long d, int s) );
66 /*
67 * set and display mapping for core file
69 PRIVATE void setmap(fp)
70 struct file *fp;
72 long h = (long) h_size;
74 fp->b1 = st_addr;
75 fp->e1 = st_addr + cnt[T];
76 fp->f1 = h;
78 fp->b2 = sd_addr;
79 fp->e2 = sd_addr + cnt[D];
80 fp->f2 = cnt[T] + h;
82 fp->b3 = sk_addr;
83 fp->e3 = sk_addr + cnt[S];
84 fp->f3 = cnt[T] + cnt[D] + h;
86 #ifdef MINIX_PC
87 if(is_separate) {
88 if ( end_addr < et_addr ) end_addr = et_addr;
90 else {
91 fp->b2 = st_addr;
92 fp->e2 = st_addr + cnt[T] + cnt[D];
93 fp->f2 = h;
94 end_addr = fp->e2;
96 fp->b1 = 0;
97 fp->e1 = 0;
98 fp->f1 = 0;
100 #endif
101 Printf("From core file:\n");
102 Printf("T\t%8lx %8lx %8lx\n", core_file->b1, core_file->e1, core_file->f1);
103 Printf("D\t%8lx %8lx %8lx\n", core_file->b2, core_file->e2, core_file->f2);
104 Printf("S\t%8lx %8lx %8lx\n", core_file->b3, core_file->e3, core_file->f3);
105 Printf("\n");
109 /* Print mapping */
110 PUBLIC void prtmap()
112 Printf("%s I & D space\t", (is_separate) ? "Separate " : "Combined ");
113 if (corepid > 0) {
114 Printf("File: %s\n\n", core_file->name);
115 setmap(core_file);
116 disp_maps();
118 else {
119 Printf("Pid: %d\n\n", curpid);
120 update();
121 disp_maps();
125 /* Illegal address */
126 PRIVATE void ill_addr(d, segment)
127 long d;
128 int segment;
130 Printf("Bad addr=%lx seg=%d",d,segment);
131 mdb_error("\n");
134 /* Map virtual address -> core file addresses
135 * depends on current segment if Separate I & D
137 PRIVATE long map_addr(d, segment)
138 long d;
139 int segment;
141 #ifdef MINIX_PC
142 if (is_separate)
143 switch (segment) {
144 case T:
145 if (d >= core_file->b1 && d < core_file->e1)
146 d += core_file->f1 - core_file->b1;
147 else
148 ill_addr(d,segment);
149 break;
150 case D:
151 case S:
152 if (d >= core_file->b2 && d < core_file->e2)
153 d += core_file->f2 - core_file->b2;
154 else if (d >= core_file->b3 && d < core_file->e3)
155 d += core_file->f3 - core_file->b3;
156 else
157 ill_addr(d,segment);
158 break;
160 else {
161 #endif
162 if (d >= core_file->b1 && d < core_file->e1)
163 d += core_file->f1 - core_file->b1;
164 else if (d >= core_file->b2 && d < core_file->e2)
165 d += core_file->f2 - core_file->b2;
166 else if (d >= core_file->b3 && d < core_file->e3)
167 d += core_file->f3 - core_file->b3;
168 else
169 ill_addr(d,segment);
170 #ifdef MINIX_PC
172 #endif
173 return d;
177 /* Get value with address d and segment s */
178 PRIVATE long getn(d, s)
179 long d;
180 int s;
182 long b;
183 register int o,i;
184 union {
185 unsigned long l;
186 unsigned char c[4];
187 } data;
189 /* Map address */
190 d = map_addr(d, s);
192 b = d >> LOGBS;
193 o = d & (BSIZE - 1);
195 if (core_file->cblock != b) {
196 core_file->cblock = b;
197 lseek(core_file->fid, b << LOGBS, 0);
198 read(core_file->fid, core_file->buf, sizeof(core_file->buf));
201 for(i = 0; i<4; i++)
202 data.c[i] = core_file->buf[o+i];
204 #ifdef DEBUG
205 if (debug)
206 Printf("getn at %8lx val %8lx\n", d, data.l);
207 #endif
208 return data.l;
211 /* Read kernel info from core file into lbuf[] */
212 PRIVATE int kernel_info(fd)
213 int fd;
215 int r;
216 int ks;
218 /* Round SIZE_KINFO to multiple of sizeof(long) */
219 /* See mm/signal.c to see how a 'core' file is written */
220 ks = ( SIZE_KINFO / sizeof(long) ) * sizeof(long);
221 r = read(fd, (char *)lbuf, ks);
222 return(r == ks) ? ks : -1;
226 * Print status info from core - returns PC
228 PRIVATE unsigned long c_status()
230 fprintf(stderr, "WARNING: don't know pid from core; using proc nr for pid.\n");
232 Printf("Proc = %6d\n", prc->p_nr);
234 /* Set current pid to that of core */
235 curpid = corepid = prc->p_nr;
236 disp_maps();
237 Printf("\nPC = 0x%0*lx\t", 2 * ADDRSIZE, PC_MEMBER(prc) & MASK(ADDRSIZE));
238 symbolic((long) PC_MEMBER(prc), '\n');
239 dasm((long) PC_MEMBER(prc), 1, 1);
240 return PC_MEMBER(prc);
243 /* Read memory maps and kernel info from core file */
244 PRIVATE void read_info(fp)
245 struct file *fp;
247 struct mem_map seg[NR_LOCAL_SEGS];
248 int r;
249 int i;
251 lseek(fp->fid, 0L, 0L);
253 /* First read memory map of all segments. */
254 if (read(fp->fid, (char *) seg, (int) SIZE_MP_SEG) < 0) {
255 close(fp->fid);
256 Printf("mdb: cannot read core header\n");
257 fp->fid = -1;
258 return;
260 h_size = SIZE_HEADER;
262 /* Read kernel dependent info */
263 r = kernel_info(fp->fid);
264 if (r < 0) {
265 close(fp->fid);
266 Printf("mdb: cannot read kernel info from 'core' file\n");
267 fp->fid = -1;
268 return;
269 } else
270 h_size += r;
272 /* copy info */
273 for (i = T; i <= S; i++)
274 cnt[i] = (long) seg[i].mem_len << CLICK_SHIFT;
276 /* This needs to be set for map_addr() below */
277 if(coreonly && cnt[T] != 0) is_separate = TRUE;
279 st_addr = (long) seg[T].mem_vir << CLICK_SHIFT;
280 et_addr = st_addr + ((long) seg[T].mem_len << CLICK_SHIFT);
282 sd_addr = (long) seg[D].mem_vir << CLICK_SHIFT;
283 end_addr = ed_addr =
284 sd_addr + ((long) seg[D].mem_len << CLICK_SHIFT);
286 sk_addr = (long) seg[S].mem_vir << CLICK_SHIFT;
287 sk_size = (long) seg[S].mem_len << CLICK_SHIFT;
289 setmap(fp);
292 /* initialization for core files
293 * returns PC address from core file
295 PUBLIC unsigned long core_init(filename)
296 char *filename;
298 core_file = &Core_File;
299 core_file->name = (filename != NULL) ? filename : def_name;
301 core_file->fid = open(core_file->name, 0);
302 if (filename != NULL && core_file->fid < 0) {
303 Printf("mdb - warning cannot open: %s\n", core_file->name);
304 return -1;
307 core_file->b1 = core_file->b2 = core_file->b3 = 0;
308 core_file->e1 = core_file->e2 = core_file->e3 = 0;
309 core_file->f1 = core_file->f2 = core_file->f3 = 0;
310 core_file->cblock = -1;
312 if (core_file->fid > 0) {
313 read_info(core_file);
314 return c_status();
316 return 0;
320 /* initialization for a file ( -f option )
321 * always returns 0
322 * Similar to core files.
324 PUBLIC unsigned long file_init(filename)
325 char *filename;
327 core_file = &Core_File;
328 core_file->name = (filename != NULL) ? filename : def_name;
330 core_file->fid = open(core_file->name, 0);
331 if (filename != NULL && core_file->fid < 0) {
332 Printf("mdb - warning cannot open: %s\n", core_file->name);
333 return -1;
336 core_file->b1 = core_file->b2 = core_file->b3 = 0;
337 core_file->e1 = core_file->e2 = core_file->e3 = 0;
338 core_file->f1 = core_file->f2 = core_file->f3 = 0;
339 core_file->cblock = -1;
341 is_separate = FALSE;
342 core_file->e1 = file_size(core_file->fid);
343 curpid = corepid = 1;
344 return 0;
349 * Read from core file
350 * Called by mdbtrace()
352 PUBLIC long read_core(req, addr, data)
353 int req;
354 long addr, data;
356 int i;
357 int segment;
358 long val;
360 switch (req) {
361 case T_GETINS:
362 case T_GETDATA:
363 /* Check segment and address - call getn to read core file */
364 segment = (req == T_GETINS) ? T : D;
365 addr &= MASK(ADDRSIZE);
366 val = getn(addr, segment);
367 #ifdef DEBUG
368 if (debug) Printf("val=>%lx\n", val);
369 #endif
370 return val;
371 break;
372 case T_GETUSER:
373 /* Convert addr to index to long array */
374 i = (int) (addr >> 2);
375 #ifdef DEBUG
376 if (debug) Printf("lbuf[%d] %lx\n", i, lbuf[i]);
377 #endif
378 return lbuf[i];
379 break;
380 case T_OK:
381 case T_EXIT:
382 return 0L;
383 break;
384 default:
385 mdb_error("Not supported with 'core' files\n");