|
|
1.1 root 1: /*
2: * size.c
3: */
4:
5: /*
6: * Object and archive file services.
7: * This section is common to nm and size.
8: * And should be common to ndis.
9: */
10: #include <stdio.h>
11: #include <ar.h>
12: #include <canon.h>
13:
14: #if COHERENT
15: #include <n.out.h>
16: #define DEFFILE "l.out"
17: #endif
18: #if MSDOS
19: #include <nout.h>
20: #define DEFFILE "l.exe"
21: #define DOEXE 1
22: #endif
23: #if GEMDOS
24: #include <nout.h>
25: #define DEFFILE "l.prg"
26: #define DOPRG 1
27: #endif
28:
29: char *argv0; /* Command name */
30: char *fn; /* File name */
31: FILE *fp; /* Input file */
32: struct ldheader ldh; /* The l.out.h header */
33: struct ldheader skh; /* Seek positions for segments */
34: struct ldsym lds; /* Symbol buffer */
35: struct ar_hdr ahb; /* Archive header buffer */
36: int title; /* Title each line */
37: int amemb; /* Archive member */
38: long offset; /* Into archive for start of l.out */
39: int status; /* Exit status */
40:
41: /*
42: * Open and close files.
43: * If an archive arrange that (*ffp)()
44: * is called on each member.
45: * Otherwise call (*ffp)() on the file itself.
46: */
47: ar(ffp) int (*ffp)();
48: {
49: int magic;
50:
51: amemb = 0;
52: offset = 0;
53: if ((fp = fopen(fn, "rb")) == NULL) {
54: error("cannot open");
55: return;
56: }
57: magic = getw(fp);
58: canshort(magic);
59: if (magic == ARMAG) {
60: title = amemb = 1;
61: while (fread(&ahb, sizeof(ahb), 1, fp) == 1) {
62: offset = ftell(fp);
63: if (strncmp(ahb.ar_name, HDRNAME, DIRSIZ) != 0)
64: (*ffp)();
65: cansize(ahb.ar_size);
66: fseek(fp, offset+ahb.ar_size, 0);
67: }
68: } else {
69: fseek(fp, 0L, 0);
70: (*ffp)();
71: }
72: if (ferror(fp))
73: error("read error");
74: fclose(fp);
75: }
76:
77: /*
78: * Read in the l.out header.
79: */
80: gethdr()
81: {
82: register int i;
83: fread((char *)&ldh, 1, sizeof(ldh), fp);
84: canshort(ldh.l_magic);
85: canshort(ldh.l_flag);
86: canshort(ldh.l_machine);
87: if (ldh.l_magic != L_MAGIC)
88: return 1;
89: if ((ldh.l_flag&LF_32) == 0) {
90: canshort(ldh.l_tbase);
91: ldh.l_entry = ldh.l_tbase;
92: ldh.l_tbase = sizeof(ldh) - 2*sizeof(short);
93: } else {
94: canshort(ldh.l_tbase);
95: canlong(ldh.l_entry);
96: }
97: skh.l_ssize[L_SYM] = ldh.l_tbase;
98: for (i=0; i<NLSEG; i++) {
99: cansize(ldh.l_ssize[i]);
100: if (i < L_SYM && i != L_BSSI && i != L_BSSD)
101: skh.l_ssize[L_SYM] += ldh.l_ssize[i];
102: }
103: return (0);
104: }
105:
106: /*
107: * Read the exe header.
108: */
109: #ifndef DOEXE
110: getexe() { return 1; }
111: #else
112: #include "exe.h"
113:
114: execani(ip) /* convert from MSDOS exe header byte order to host */
115: register short *ip;
116: {
117: /* First convert to standard pdp-11 byte order */
118: /* Notice, nothing to do to accomplish this */
119:
120: /* Now convert from pdp-11 byte order to host */
121:
122: canshort(*ip);
123: }
124:
125: getexe()
126: {
127: long daddr;
128: exehdr_t exehdr;
129:
130: fseek(fp, offset, 0);
131: fread((char *)&exehdr, 1, sizeof(exehdr), fp);
132: execani(&exehdr.x_magic);
133: if (exehdr.x_magic != EXEMAGIC)
134: return (1);
135: execani(&exehdr.x_sectors);
136: execani(&exehdr.x_bytes);
137: daddr = (long) exehdr.x_sectors * 512;
138: if ( exehdr.x_bytes != 0 )
139: daddr += exehdr.x_bytes - 512;
140: fseek(fp, offset+daddr, 0);
141: if (gethdr() != 0)
142: return 1;
143: daddr += ldh.l_tbase + ldh.l_ssize[L_DEBUG];
144: skh.l_ssize[L_SYM] = daddr;
145: return 0;
146: }
147: #endif
148:
149: /*
150: * Read a gemdos .prg header.
151: */
152: #ifndef DOPRG
153: getprg() { return 1; }
154: #else
155: #include "gemout.h"
156: /* convert 68000 byte order to pdp11 byte order and vice versa */
157: #if PDP11
158: gcani(ip) register unsigned char *ip;
159: {
160: register t;
161: t = ip[0]; ip[0] = ip[1]; ip[1] = t;
162: }
163: gcanl(lp) register unsigned char *lp;
164: {
165: register t;
166: t = lp[0]; lp[0] = lp[1]; lp[1] = t;
167: t = lp[2]; lp[2] = lp[3]; lp[3] = t;
168: }
169: #endif
170: #if M68000
171: #define gcani(i) /* Nil */
172: #define gcanl(l) /* Nil */
173: #endif
174:
175: getprg()
176: {
177: struct gemohdr ghd;
178: register long daddr;
179: register int c;
180: fseek(fp, offset, 0);
181: fread((char *)&ghd, 1, sizeof(ghd), fp);
182: gcani(&ghd.g_magic);
183: if (ghd.g_magic != GEMOMAGIC)
184: return 1;
185: gcanl(&ghd.g_ssize[0]);
186: gcanl(&ghd.g_ssize[1]);
187: gcanl(&ghd.g_ssize[2]);
188: gcanl(&ghd.g_ssize[3]);
189: daddr = sizeof(ghd) + ghd.g_ssize[0] + ghd.g_ssize[1] + ghd.g_ssize[3];
190: fseek(fp, daddr+offset, 0);
191: if (getw(fp) | getw(fp)) {
192: while (c = getc(fp))
193: if (c == EOF)
194: return 1;
195: }
196: daddr = ftell(fp) - offset;
197: if (gethdr() != 0)
198: return 1;
199: daddr += ldh.l_tbase + ldh.l_ssize[L_DEBUG];
200: skh.l_ssize[L_SYM] = daddr;
201: return 0;
202: }
203: #endif
204:
205: /*
206: * Print a title.
207: */
208: dotitle(fp, tail) FILE *fp; char *tail;
209: {
210: if (amemb)
211: fprintf(fp, "%s(%.*s)", fn, DIRSIZ, ahb.ar_name);
212: else
213: fprintf(fp, "%s", fn);
214: if (tail)
215: fprintf(fp, "%s", tail);
216: }
217: /*
218: * Give up.
219: * Tag the line with the file
220: * name.
221: */
222: error(a)
223: {
224: fprintf(stderr, "%s: ", argv0);
225: dotitle(stderr, ": ");
226: fprintf(stderr, "%r\n", &a);
227: status = 1;
228: }
229:
230: /*
231: * Size specific code.
232: */
233: int cflag; /* include common space indication */
234: int tflag; /* print totals for all files */
235: int aflag; /* print all segments */
236:
237: long tsize[NLSEG];
238: long tcomm;
239: long total;
240:
241: char octf[] = "%06lo";
242: char hexf[] = "%04lx";
243: char lngf[] = "%08lx";
244: char segf[] = "%06lx";
245:
246: char *afmt[] = { /* Purloined from nm.c */
247: octf, /* Unused or unknown */
248: octf, /* 11 */
249: lngf, /* VAX */
250: segf, /* 360 */
251: lngf, /* Z-8001 */
252: hexf, /* Z-8002 */
253: hexf, /* 8086 */
254: hexf, /* 8080 and 8085 */
255: hexf, /* 6800 */
256: hexf, /* 6809 */
257: lngf, /* 68000 */
258: lngf, /* NS16000 */
259: lngf /* Large Model 8086 */
260: };
261:
262: char *format = octf;
263:
264: #define MTYPES (sizeof(afmt)/sizeof(char *))
265:
266: main(argc, argv) int argc; char *argv[];
267: {
268: register char *p;
269: register c, i;
270: int nf;
271: extern size();
272:
273: argv0 = argv[0];
274: for (i = 1; i<argc && argv[i][0]=='-'; ++i) {
275: p = &argv[i][1];
276: while (c = *p++) {
277: switch (c) {
278: case 'a': ++aflag; break;
279: case 'c': ++cflag; break;
280: case 't': ++tflag; break;
281: default: usage(); break;
282: }
283: }
284: }
285: if ((nf = argc-i) != 0) {
286: if (nf > 1)
287: title = 1;
288: while (i < argc) {
289: fn = argv[i++];
290: ar(size);
291: }
292: if (title && tflag) {
293: printf("Total: ");
294: for (i=L_SHRI; i<NLSEG; ++i) {
295: if (aflag == 0 && i == L_DEBUG)
296: break;
297: if (i != L_SHRI)
298: putchar('+');
299: printf("%ld", tsize[i]);
300: }
301: if (cflag && tcomm!=0)
302: printf("+%ld", tcomm);
303: printf(" %ld (", total);
304: printf(format, total);
305: printf(")\n");
306: }
307: } else {
308: fn = DEFFILE;
309: ar(size);
310: }
311: exit(status);
312: }
313:
314: /*
315: * Size.
316: * You are seeked to the start of a file
317: * which is not an archive.
318: */
319: size()
320: {
321: register int i;
322: int machine;
323: long common;
324: long size;
325: long tot;
326:
327: if (gethdr() != 0
328: && getexe() != 0
329: && getprg() != 0) {
330: error("not an object file");
331: return;
332: }
333: machine = ldh.l_machine;
334:
335: if ( machine >= MTYPES )
336: machine = 0;
337: format = afmt[machine];
338:
339: if (title)
340: dotitle(stdout, ": ");
341: tot = 0;
342: for (i=L_SHRI; i<NLSEG; ++i) {
343: size = ldh.l_ssize[i];
344: tsize[i] += size;
345: if (aflag != 0 || i < L_DEBUG) {
346: if (i != L_SHRI)
347: putchar('+');
348: printf("%ld", size);
349: tot += size;
350: }
351: }
352: if (cflag) {
353: common = 0;
354: fseek(fp, skh.l_ssize[L_SYM]+offset, 0);
355: if (ldh.l_flag & LF_32) {
356: while (ldh.l_ssize[L_SYM]) {
357: fread(&lds, sizeof(lds), 1, fp);
358: canshort(lds.ls_type);
359: canlong(lds.ls_addr);
360: if (lds.ls_type == (L_GLOBAL|L_REF))
361: common += (long)lds.ls_addr;
362: ldh.l_ssize[L_SYM] -= sizeof(lds);
363: }
364: } else {
365: while (ldh.l_ssize[L_SYM]) {
366: fread(&lds, sizeof(lds)-sizeof(short), 1, fp);
367: canshort(lds.ls_type);
368: i = *(unsigned *)(&lds.ls_addr);
369: canshort(i);
370: if (lds.ls_type == (L_GLOBAL|L_REF))
371: common += (unsigned)i;
372: ldh.l_ssize[L_SYM] -= sizeof(lds)-sizeof(short);
373: }
374: }
375: if (common != 0) {
376: printf("+%ld", common);
377: tot += common;
378: tcomm += common;
379: }
380: }
381: printf(" %ld (", tot);
382: printf(format, tot);
383: printf(")\n");
384: total += tot;
385: }
386:
387: usage()
388: {
389: fprintf(stderr, "Usage: size [-act] [file ...]\n");
390: exit(1);
391: }
392:
393: /* end of size.c */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.