|
|
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.