source: trunk/minix/commands/mdb/core.c@ 11

Last change on this file since 11 was 9, checked in by Mattia Monga, 14 years ago

Minix 3.1.2a

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