|
|
1.1 root 1: /*
2: * File: dcore.c
3: *
4: * Purpose: Display contents of core file intelligibly.
5: *
6: * $Log: dcore.c,v $
7: * Revision 1.1 93/04/16 07:01:38 bin
8: * Initial revision
9: *
10: */
11:
12: /*
13: * ----------------------------------------------------------------------
14: * Includes.
15: */
16: #include <stdio.h>
17: #include <sys/core.h>
18: #include <sys/reg.h>
19: #include <sys/uproc.h>
20:
21: /*
22: * ----------------------------------------------------------------------
23: * Definitions.
24: * Constants.
25: * Macros with argument lists.
26: * Typedefs.
27: * Enums.
28: */
29: #define DEFAULT_CORE_NAME "core"
30: #define DSIZE 16
31:
32: struct seg_info {
33: int si_base;
34: int si_size;
35: long si_offset;
36: };
37:
38: /*
39: * ----------------------------------------------------------------------
40: * Functions.
41: * Import Functions.
42: * Export Functions.
43: * Local Functions.
44: */
45:
46: /*
47: * ----------------------------------------------------------------------
48: * Global Data.
49: * Import Variables.
50: * Export Variables.
51: * Local Variables.
52: */
53: static char * cmd;
54: static int tflag; /* "-t" option says text segment was dumped */
55: static char * coreName = DEFAULT_CORE_NAME;
56: static FILE * fp;
57: static struct ch_info chInfo;
58: static char *segName[NUSEG] = {
59: "USER", "TEXT", "DATA", "STACK"
60: };
61: static struct seg_info segInfo[NUSEG];
62:
63: /*
64: * ----------------------------------------------------------------------
65: * Code.
66: */
67:
68: void
69: usage()
70: {
71: fprintf(stderr, "Usage: %s [-t] [corefile]\n", cmd);
72: exit(1);
73: }
74:
75: /*
76: * Given text name and vital stats for a segment, do a hex dump.
77: */
78: void
79: dumpseg(name, infop)
80: char *name;
81: struct seg_info *infop;
82: {
83: /* use the fact that segment size is a multiple of NBPC */
84: unsigned char coredata[DSIZE];
85: unsigned char savedata[DSIZE];
86: int segOffset;
87: int i;
88: /*
89: * sameState:
90: * -1 just starting; don't look for matching display lines
91: * 0 current line does not match previous line
92: * 1 current line matches previous line
93: * 2 current line matches previous 2 or more lines
94: */
95: int sameState = -1;
96: int doPrint, match;
97:
98: /* make sure we can seek to start of segment */
99: if (fseek(fp, infop->si_offset, 0) < 0) {
100: fprintf(stderr, "Can't seek to %s segment!\n", name);
101: exit(1);
102: }
103:
104: printf("\nContents of %s segment:\n", name);
105: for (segOffset = 0; segOffset < infop->si_size; segOffset += DSIZE) {
106: int readLen = DSIZE;
107: int remains = infop->si_size - segOffset;
108:
109: if (readLen > remains)
110: readLen = remains;
111:
112: if (fread(coredata, readLen, 1, fp) !=1) {
113: fprintf(stderr, "Can't read core data.\n");
114: exit(1);
115: }
116:
117: /* always display last line of segment */
118: if (remains <= DSIZE)
119: match = 1;
120: else
121: match = memcmp(coredata, savedata, DSIZE);
122:
123: switch(sameState) {
124: case -1:
125: sameState = 0;
126: doPrint = 1;
127: break;
128: case 0:
129: if (match) {
130: doPrint = 1;
131: } else {
132: sameState = 1;
133: doPrint = 0;
134: }
135: break;
136: case 1:
137: if (match) {
138: doPrint = 1;
139: sameState = 0;
140: } else {
141: sameState = 2;
142: doPrint = 0;
143: printf(" *\n");
144: }
145: break;
146: case 2:
147: if (match) {
148: doPrint = 1;
149: sameState = 0;
150: } else {
151: doPrint = 0;
152: }
153: break;
154: }
155: if (doPrint) {
156: printf("%06X", segOffset);
157: for (i = 0; i < readLen; i++)
158: printf(" %02X", coredata[i]);
159: printf("\n");
160: }
161: memcpy(savedata, coredata, DSIZE);
162: }
163: }
164:
165: /*
166: * Once the file has been opened and magic number checked, this function
167: * does the work.
168: *
169: * Globals used: fp, chInfo.
170: */
171: void
172: dcore()
173: {
174: long offset;
175: static struct uproc uProc;
176: static int regs[SS+1];
177: int i;
178: int base, size;
179:
180: /* display uproc version number */
181: offset = chInfo.ch_info_len + chInfo.ch_uproc_offset;
182: if (fseek(fp, offset, 0) < 0) {
183: fprintf(stderr, "Can't seek to uproc.\n");
184: exit(1);
185: }
186: if (fread(&uProc, sizeof(uProc), 1, fp) !=1) {
187: fprintf(stderr, "Can't read uproc.\n");
188: exit(1);
189: }
190: printf("uproc version = 0x%04x\n", uProc.u_version);
191:
192: /* display register set */
193: offset = chInfo.ch_info_len + ((int)(uProc.u_regl) & (NBPC-1));
194: if (fseek(fp, offset, 0) < 0) {
195: fprintf(stderr, "Can't seek to register set.\n");
196: exit(1);
197: }
198: if (fread(regs, sizeof(regs), 1, fp) !=1) {
199: fprintf(stderr, "Can't read register set.\n");
200: exit(1);
201: }
202:
203: printf("\neax=%08X\tebx=%08X\tecx=%08X\tedx=%08X\n",
204: regs[EAX], regs[EBX], regs[ECX], regs[EDX]);
205: printf("esi=%08X\tedi=%08X\tebp=%08X\tesp=%08X\n",
206: regs[ESI], regs[EDI], regs[EBP], regs[ESP]);
207: printf("eip=%08X\tuesp=%08X\tefl=%08X\n",
208: regs[EIP], regs[UESP], regs[EFL]);
209: printf("\ncs=%04X\tds=%04X\tes=%04X\tss=%04X\tfs=%04X\tgs=%04X\n",
210: regs[CS]&0xffff, regs[DS]&0xffff, regs[ES]&0xffff,
211: regs[SS]&0xffff, regs[FS]&0xffff, regs[GS]&0xffff);
212: printf("\nerr #%d \tcmd=%s\n", regs[ERR], uProc.u_comm);
213:
214: /* display segment sizes */
215: printf("\nSegment\tBase\t\tSize\n");
216: offset = chInfo.ch_info_len;
217: for (i = 0; i < NUSEG; i++) {
218: base = (int)(uProc.u_segl[i].sr_base);
219: size = uProc.u_segl[i].sr_size;
220: if (i == SISTACK)
221: base -= size;
222: printf("%s\t%08x\t%08x\n", segName[i], base, size);
223: segInfo[i].si_offset = offset;
224: segInfo[i].si_base = base;
225: segInfo[i].si_size = size;
226:
227: /* text is in core file only if "-t" specified */
228: if (tflag || i != SISTEXT)
229: offset += size;
230: }
231:
232: /* dump segments */
233: for (i = 0; i < NUSEG; i++) {
234: if (!tflag && i == SISTEXT)
235: continue;
236: dumpseg(segName[i], segInfo + i);
237: }
238: }
239:
240: main(argc, argv)
241: int argc;
242: char *argv[];
243: {
244: int argn;
245:
246: /* command line housekeeping */
247: cmd = argv[0];
248: for (argn = 1; argn < argc; argn++) {
249: if (argv[argn][0] == '-') {
250: switch(argv[argn][1]) {
251: case 't':
252: tflag = 1;
253: break;
254: default:
255: usage();
256: }
257: } else {
258: coreName = argv[argn];
259: /* this should be the last argument */
260: if (argn < argc - 1)
261: usage();
262: }
263: }
264:
265: /* try to open the core file for reading */
266: if ((fp = fopen(coreName, "r")) == NULL) {
267: fprintf(stderr, "Can't open %s for reading.\n", coreName);
268: exit(1);
269: }
270:
271: /* simple test for core file format */
272: if (fread(&chInfo, sizeof(chInfo), 1, fp) !=1) {
273: fprintf(stderr, "Can't read core header.\n");
274: exit(1);
275: }
276:
277: if (chInfo.ch_magic != CORE_MAGIC) {
278: fprintf(stderr, "Not a core file.\n");
279: exit(1);
280: }
281: printf("Core file: %s ", coreName);
282:
283: /* call a function to do the work */
284: dcore();
285:
286: /* cleanup */
287: fclose(fp);
288: exit(0);
289: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.