|
|
1.1 root 1: /*
2: * File: dlout.c
3: *
4: * Purpose: Display contents of l.out file intelligibly.
5: *
6: * $Log: dlout.c,v $
7: * Revision 1.1 93/04/16 07:01:40 bin
8: * Initial revision
9: *
10: */
11:
12: /*
13: * ----------------------------------------------------------------------
14: * Includes.
15: */
16: #include <canon.h>
17: #include <l.out.h>
18: #include <stdio.h>
19: #include <sys/reg.h>
20: #include <sys/uproc.h>
21:
22: /*
23: * ----------------------------------------------------------------------
24: * Definitions.
25: * Constants.
26: * Macros with argument lists.
27: * Typedefs.
28: * Enums.
29: */
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 struct ldheader ldHead;
55: static char * loutName = NULL;
56: static FILE * fp;
57: static char *segName[NUSEG] = {
58: "USER", "TEXT", "DATA", "STACK"
59: };
60: static struct seg_info segInfo[NUSEG];
61:
62: /*
63: * ----------------------------------------------------------------------
64: * Code.
65: */
66:
67: void
68: usage()
69: {
70: fprintf(stderr, "Usage: %s l.out-file\n", cmd);
71: exit(1);
72: }
73:
74: /*
75: * Given text name and vital stats for a segment, do a hex dump.
76: */
77: void
78: dumpseg(name, infop)
79: char *name;
80: struct seg_info *infop;
81: {
82: unsigned char coredata[DSIZE];
83: unsigned char savedata[DSIZE];
84: int segOffset;
85: int i;
86: /*
87: * sameState:
88: * -1 just starting; don't look for matching display lines
89: * 0 current line does not match previous line
90: * 1 current line matches previous line
91: * 2 current line matches previous 2 or more lines
92: */
93: int sameState = -1;
94: int doPrint, match;
95:
96: /* make sure we can seek to start of segment */
97: if (fseek(fp, infop->si_offset, 0) < 0) {
98: fprintf(stderr, "Can't seek to %s segment!\n", name);
99: exit(1);
100: }
101:
102: printf("\nContents of %s segment:\n", name);
103: for (segOffset = 0; segOffset < infop->si_size; segOffset += DSIZE) {
104: int readLen = DSIZE;
105: int remains = infop->si_size - segOffset;
106:
107: if (readLen > remains)
108: readLen = remains;
109:
110: if (fread(coredata, readLen, 1, fp) !=1) {
111: fprintf(stderr, "Can't read core data.\n");
112: exit(1);
113: }
114:
115: /* always display last line of segment */
116: if (remains <= DSIZE)
117: match = 1;
118: else
119: match = memcmp(coredata, savedata, DSIZE);
120:
121: switch(sameState) {
122: case -1:
123: sameState = 0;
124: doPrint = 1;
125: break;
126: case 0:
127: if (match) {
128: doPrint = 1;
129: } else {
130: sameState = 1;
131: doPrint = 0;
132: }
133: break;
134: case 1:
135: if (match) {
136: doPrint = 1;
137: sameState = 0;
138: } else {
139: sameState = 2;
140: doPrint = 0;
141: printf(" *\n");
142: }
143: break;
144: case 2:
145: if (match) {
146: doPrint = 1;
147: sameState = 0;
148: } else {
149: doPrint = 0;
150: }
151: break;
152: }
153: if (doPrint) {
154: printf("%06X", segOffset);
155: for (i = 0; i < readLen; i++)
156: printf(" %02X", coredata[i]);
157: printf("\n");
158: }
159: memcpy(savedata, coredata, DSIZE);
160: }
161: }
162:
163: /*
164: * Once the file has been opened and magic number checked, this function
165: * does the work.
166: *
167: * Globals used: fp, chInfo.
168: */
169: void
170: dlout()
171: {
172: int i;
173: unsigned int shrds; /* size of shared data */
174:
175: /* canonicalize where necessary */
176: canint(ldHead.l_machine);
177: if (ldHead.l_machine!=M_8086) {
178: fprintf(stderr, "Wrong machine.\n");
179: exit(1);
180: }
181:
182: for (i=0; i<NXSEG; i++) {
183: cansize(ldHead.l_ssize[i]);
184: }
185: canint(ldHead.l_flag);
186: canvaddr(ldHead.l_entry);
187:
188: /* display shared/unshared */
189: if (ldHead.l_flag & LF_SHR)
190: printf("shared executable\n");
191: else
192: printf("nonshared executable\n");
193:
194:
195: /* display entry point */
196: printf("entry point = %04X\n", ldHead.l_entry);
197:
198: /* fetch segment data */
199: segInfo[SISTEXT].si_offset = sizeof(struct ldheader);
200: segInfo[SISTEXT].si_base = NBPS;
201: segInfo[SISTEXT].si_size = ldHead.l_ssize[L_SHRI];
202:
203: segInfo[SIPDATA].si_offset = sizeof(struct ldheader) +
204: segInfo[SISTEXT].si_size;
205: segInfo[SIPDATA].si_base = 0;
206: segInfo[SIPDATA].si_size = ldHead.l_ssize[L_SHRD] +
207: ldHead.l_ssize[L_PRVD];
208: if (ldHead.l_flag & LF_SHR) {
209: shrds = ldHead.l_ssize[L_SHRD];
210: printf("shrds = %04X\n", shrds);
211: }
212:
213: segInfo[SIBSS].si_offset = 0;
214: segInfo[SIBSS].si_base = segInfo[SIPDATA].si_size;
215: segInfo[SIBSS].si_size = ldHead.l_ssize[L_BSSD];
216:
217: /* display segment sizes */
218: printf("\nSegment\tBase\t\tSize\n");
219: for (i = 0; i < NUSEG; i++) {
220: if (i != SISTEXT && i != SIPDATA)
221: continue;
222: printf("%s\t%08x\t%08x\n",
223: segName[i], segInfo[i].si_base, segInfo[i].si_size);
224: }
225:
226: /* dump segments */
227: for (i = 0; i < NUSEG; i++) {
228: if (i != SISTEXT && i != SIPDATA)
229: continue;
230: dumpseg(segName[i], segInfo + i);
231: }
232: #if 0
233: long offset;
234: static struct uproc uProc;
235: static int regs[SS+1];
236: int i;
237: int base, size;
238:
239: /* display uproc version number */
240: offset = chInfo.ch_info_len + chInfo.ch_uproc_offset;
241: if (fseek(fp, offset, 0) < 0) {
242: fprintf(stderr, "Can't seek to uproc.\n");
243: exit(1);
244: }
245: if (fread(&uProc, sizeof(uProc), 1, fp) !=1) {
246: fprintf(stderr, "Can't read uproc.\n");
247: exit(1);
248: }
249: printf("uproc version = 0x%04x\n", uProc.u_version);
250:
251: #endif
252: }
253:
254: main(argc, argv)
255: int argc;
256: char *argv[];
257: {
258:
259: /* command line housekeeping */
260: cmd = argv[0];
261: if (argc != 2)
262: usage();
263: loutName = argv[1];
264:
265: /* try to open the l.out file for reading */
266: if ((fp = fopen(loutName, "r")) == NULL) {
267: fprintf(stderr, "Can't open %s for reading.\n", loutName);
268: exit(1);
269: }
270:
271: /* simple test for l.out file format */
272: if (fread(&ldHead, sizeof(ldHead), 1, fp) !=1) {
273: fprintf(stderr, "Can't read l.out header\n");
274: exit(1);
275: }
276:
277: if (ldHead.l_magic != L_MAGIC) {
278: fprintf(stderr, "Not a l.out file.\n");
279: exit(1);
280: }
281: printf("L.out file: %s\n", loutName);
282:
283: /* call a function to do the work */
284: dlout();
285:
286: /* cleanup */
287: fclose(fp);
288: exit(0);
289: }
290:
291: long
292: _canl(n)
293: int n;
294: {
295: return (n<<16)|((n>>16)&0xffff);
296: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.