Annotation of coherent/d/bin/strip.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Object file services.
        !             3:  * This section is similar to that in nm and size.
        !             4:  */
        !             5: 
        !             6: #include <stdio.h>
        !             7: #include <canon.h>
        !             8: 
        !             9: #if COHERENT
        !            10: #include <n.out.h>
        !            11: #include <signal.h>
        !            12: #endif
        !            13: #if MSDOS
        !            14: #include <nout.h>
        !            15: #define        DOEXE   1
        !            16: #endif
        !            17: #if GEMDOS
        !            18: #include <nout.h>
        !            19: #define        DOPRG   1
        !            20: #endif
        !            21: 
        !            22: char   *argv0;                 /* Command name */
        !            23: char   *fn;                    /* File name */
        !            24: FILE   *ifp;                   /* Input File Pointer */
        !            25: FILE   *ofp;                   /* Output File Pointer */
        !            26: struct ldheader        ldh;    /* The l.out.h header */
        !            27: long   loadsize;               /* Amount of input to copy to output */
        !            28: 
        !            29: /*
        !            30:  *     Read in the l.out header.
        !            31:  */
        !            32: gethdr()
        !            33: {
        !            34:        register int i;
        !            35:        fread((char *)&ldh, 1, sizeof(ldh), ifp);
        !            36:        canshort(ldh.l_magic);
        !            37:        canshort(ldh.l_flag);
        !            38:        canshort(ldh.l_machine);
        !            39:        if (ldh.l_magic != L_MAGIC)
        !            40:                return 1;
        !            41:        if ((ldh.l_flag&LF_32) == 0) {
        !            42:                canshort(ldh.l_tbase);
        !            43:                ldh.l_entry = ldh.l_tbase;
        !            44:                ldh.l_tbase = sizeof(ldh) - 2*sizeof(short);
        !            45:        } else {
        !            46:                canshort(ldh.l_tbase);
        !            47:                canlong(ldh.l_entry);
        !            48:        }
        !            49:        loadsize = 0;
        !            50:        for (i=0; i<NLSEG; i++) {
        !            51:                canlong(ldh.l_ssize[i]);
        !            52:                if (i < L_DEBUG && i != L_BSSI && i != L_BSSD)
        !            53:                        loadsize += ldh.l_ssize[i];
        !            54:        }
        !            55:        return (0);
        !            56: }
        !            57: 
        !            58: /*
        !            59:  * Read the exe header.
        !            60:  */
        !            61: #ifndef DOEXE
        !            62: getexe() { return 1; }
        !            63: #else
        !            64: #include "exe.h"
        !            65: 
        !            66: 
        !            67: execani(ip)    /* convert from MSDOS exe header byte order to host */
        !            68: register short *ip;
        !            69: {
        !            70:        /* First convert to standard pdp-11 byte order */
        !            71:        /* Notice, nothing to do to accomplish this    */
        !            72: 
        !            73:        /* Now convert from pdp-11 byte order to host */
        !            74: 
        !            75:        canshort(*ip);
        !            76: }
        !            77: 
        !            78: getexe()
        !            79: {
        !            80:        long daddr;
        !            81:        exehdr_t exehdr;
        !            82: 
        !            83:        fseek(ifp, 0L, 0);
        !            84:        fread((char *)&exehdr, 1, sizeof(exehdr), ifp);
        !            85:        execani(&exehdr.x_magic);
        !            86:        if (exehdr.x_magic != EXEMAGIC)
        !            87:                return (1);
        !            88:        execani(&exehdr.x_sectors);
        !            89:        execani(&exehdr.x_bytes);
        !            90:        daddr = (long) exehdr.x_sectors * 512;
        !            91:        if ( exehdr.x_bytes != 0 )
        !            92:                daddr += exehdr.x_bytes - 512;
        !            93:        fseek(ifp, daddr, 0);
        !            94:        if (gethdr() != 0)
        !            95:                return 1;
        !            96:        loadsize = daddr;
        !            97:        return 0;
        !            98: }
        !            99: #endif
        !           100: 
        !           101: /*
        !           102:  *     Read a gemdos .prg header.
        !           103:  */
        !           104: #ifndef DOPRG
        !           105: getprg() { return 1; }
        !           106: #else
        !           107: #include "gemout.h"
        !           108: /* convert 68000 byte order to pdp11 byte order and vice versa */
        !           109: #if PDP11
        !           110: gemcani(ip) register unsigned char *ip;
        !           111: {
        !           112:        register t;
        !           113:        t = ip[0]; ip[0] = ip[1]; ip[1] = t;
        !           114: }
        !           115: gemcanl(lp) register unsigned char *lp;
        !           116: {
        !           117:        register t;
        !           118:        t = lp[0]; lp[0] = lp[1]; lp[1] = t;
        !           119:        t = lp[2]; lp[2] = lp[3]; lp[3] = t;
        !           120: }
        !           121: #endif
        !           122: #if M68000
        !           123: #define gemcani(i)     /* Nil */
        !           124: #define gemcanl(l)     /* Nil */
        !           125: #endif
        !           126: 
        !           127: getprg()
        !           128: {
        !           129:        struct gemohdr ghd;
        !           130:        register long daddr;
        !           131:        register int c;
        !           132:        fseek(ifp, 0L, 0);
        !           133:        fread((char *)&ghd, 1, sizeof(ghd), ifp);
        !           134:        gemcani(&ghd.g_magic);
        !           135:        if (ghd.g_magic != GEMOMAGIC)
        !           136:                return 1;
        !           137:        gemcanl(&ghd.g_ssize[0]);
        !           138:        gemcanl(&ghd.g_ssize[1]);
        !           139:        gemcanl(&ghd.g_ssize[2]);
        !           140:        gemcanl(&ghd.g_ssize[3]);
        !           141:        daddr = sizeof(ghd) + ghd.g_ssize[0] + ghd.g_ssize[1] + ghd.g_ssize[3];
        !           142:        fseek(ifp, daddr, 0);
        !           143:        if (getw(ifp) | getw(ifp)) {
        !           144:                while (c = getc(ifp))
        !           145:                        if (c == EOF)
        !           146:                                return 1;
        !           147:        }
        !           148:        daddr = ftell(ifp);
        !           149:        if (gethdr() != 0)
        !           150:                return 1;
        !           151:        loadsize = daddr;
        !           152:        return 0;
        !           153: }
        !           154: #endif
        !           155: 
        !           156: /*
        !           157:  * Strip specific code.
        !           158:  * Strip the debug table, the symbol
        !           159:  * table and the relocation information from a
        !           160:  * object file.
        !           161:  * Optionally keep any combination of the three.
        !           162:  */
        !           163: 
        !           164: char   *tmp;
        !           165: char   werror[] = "write error";
        !           166: char   rerror[] = "cannot reopen";
        !           167: char   xerror[] = "unexpected end of file";
        !           168: char   oerror[] = "not an object file";
        !           169: char   usemsg[] = "Usage: %s [-drs] file [ ... ]\n";
        !           170: 
        !           171: int dkeep;
        !           172: int rkeep;
        !           173: int skeep;
        !           174: 
        !           175: int notcoh = 1;        /* flag indicative of what object type the file is */
        !           176: int notexe = 1;
        !           177: int notprg = 1;
        !           178: 
        !           179: struct ldheader olh;   /* output file l.out.h header */
        !           180: 
        !           181: int    cleanup();
        !           182: 
        !           183: main(argc, argv)
        !           184: char *argv[];
        !           185: {
        !           186:        register estat, i;
        !           187:        register char *cp;
        !           188:        register c;
        !           189:        extern char *tempnam();
        !           190: 
        !           191:        argv0 = argv[0];
        !           192:        if (argc < 2)
        !           193:                usage();
        !           194:        tmp = tempnam(NULL, "s");
        !           195: #if COHERENT
        !           196:        if (signal(SIGINT, SIG_IGN) != SIG_IGN)
        !           197:                signal(SIGINT, cleanup);
        !           198: #endif
        !           199:        estat = 0;
        !           200:        for (i=1; i<argc; i++) {
        !           201:                cp = argv[i];
        !           202:                if (cp[0] == '-') {
        !           203:                        while ((c = *++cp) != 0)
        !           204:                                if (c == 'd') ++dkeep;
        !           205:                                else if (c == 'r') ++rkeep;
        !           206:                                else if (c == 's') ++skeep;
        !           207:                                else usage();
        !           208:                        continue;
        !           209:                }
        !           210:                fn = argv[i];
        !           211:                estat |= strip();
        !           212:                if (ifp != NULL) {
        !           213:                        fclose(ifp);
        !           214:                        ifp = NULL;
        !           215:                }
        !           216:                if (ofp != NULL) {
        !           217:                        fclose(ofp);
        !           218:                        ofp = NULL;
        !           219:                }
        !           220:        }
        !           221:        cleanup(estat);
        !           222: }
        !           223: 
        !           224: /*
        !           225:  * Do all the work.
        !           226:  * The external variables 'ifp' and 'ofp'
        !           227:  * will be closed by the mainline. This makes the
        !           228:  * many error conditions a little easier to
        !           229:  * deal with.
        !           230:  */
        !           231: strip()
        !           232: {
        !           233:        int i;
        !           234:        register long nsize;
        !           235: 
        !           236:        if ((ifp = fopen(fn, "rb")) == NULL) {
        !           237:                diag("cannot open", fn);
        !           238:                return(1);
        !           239:        }
        !           240:        if ((ofp = fopen(tmp, "wb")) == NULL) {
        !           241:                diag("cannot create", tmp);
        !           242:                return(1);
        !           243:        }
        !           244:        if ( (notcoh=gethdr()) != 0
        !           245:         &&  (notexe=getexe()) != 0
        !           246:         &&  (notprg=getprg()) != 0) {
        !           247:                diag("not an object file", fn);
        !           248:                return(1);
        !           249:        }
        !           250:        olh = ldh;
        !           251:        if ( ! dkeep) {
        !           252:                olh.l_ssize[L_DEBUG] = 0;
        !           253:                olh.l_flag &= ~LF_DEBUG;
        !           254:        }
        !           255:        if ( ! rkeep) {
        !           256:                olh.l_flag |= LF_NRB;
        !           257:                olh.l_ssize[L_REL] = 0;
        !           258:        }
        !           259:        if ( ! skeep)
        !           260:                olh.l_ssize[L_SYM] = 0;
        !           261:        if (ldh.l_flag == olh.l_flag
        !           262:         && ldh.l_ssize[L_DEBUG] == olh.l_ssize[L_DEBUG]
        !           263:         && ldh.l_ssize[L_SYM] == olh.l_ssize[L_SYM]
        !           264:         && ldh.l_ssize[L_REL] == olh.l_ssize[L_REL])
        !           265:                return(0);
        !           266: 
        !           267:        if (writehead() != 0            /* header of output file */
        !           268:         || copy(loadsize) != 0         /* all loadable segments */
        !           269:         || writelout() != 0)           /* l.out.h header in exe and prg */
        !           270:                return(1);
        !           271: 
        !           272:        for (i = L_DEBUG; i < NLSEG; i += 1) {
        !           273:                nsize = ldh.l_ssize[i];
        !           274:                if (olh.l_ssize[i] == nsize)
        !           275:                        copy(nsize);
        !           276:                else
        !           277:                        fseek(ifp, nsize, 1);
        !           278:        }
        !           279:        fflush(ofp);
        !           280:        if (ferror(ofp)) {
        !           281:                diag(werror, tmp);
        !           282:                return (1);
        !           283:        }
        !           284:        if (ferror(ifp)) {
        !           285:                diag("read error", fn);
        !           286:                return 1;
        !           287:        } else if (feof(ifp)) {
        !           288:                diag(xerror, fn);
        !           289:                return 1;
        !           290:        }
        !           291:        fclose(ifp);
        !           292:        ifp = NULL;
        !           293:        loadsize = ftell(ofp);
        !           294:        fclose(ofp);
        !           295:        ofp = NULL;
        !           296:        if ((ifp = fopen(tmp, "rb")) == NULL) {
        !           297:                diag(rerror, tmp);
        !           298:                return (1);
        !           299:        }
        !           300:        if ((ofp = fopen(fn, "wb")) == NULL) {
        !           301:                diag(rerror, fn);
        !           302:                return (1);
        !           303:        }
        !           304:        copy(loadsize);
        !           305:        fflush(ofp);
        !           306:        if (ferror(ofp)) {
        !           307:                diag(werror, fn);
        !           308:                fprintf(stderr, "%s: file saved in %s\n", argv0, tmp);
        !           309:                exit(1);
        !           310:        }
        !           311:        return (0);
        !           312: }
        !           313: 
        !           314: /*
        !           315:  * Convert the l.out header structure
        !           316:  * in the buffer 'lh' to and from standard
        !           317:  * ordering.
        !           318:  */
        !           319: canlh(ldhp)
        !           320: register struct ldheader *ldhp;
        !           321: {
        !           322:        register i;
        !           323: 
        !           324:        canshort(ldhp->l_magic);
        !           325:        canshort(ldhp->l_flag);
        !           326:        canshort(ldhp->l_machine);
        !           327:        canshort(ldhp->l_tbase);
        !           328:        for (i=0; i<NLSEG; ++i)
        !           329:                canlong(ldhp->l_ssize[i]);
        !           330:        canlong(ldhp->l_entry);
        !           331: }
        !           332: 
        !           333: /*
        !           334:  *     Writes the header at the beginning of the output file
        !           335:  *     References flags: notcoh, notexe, and notprg.
        !           336:  */
        !           337: writehead()
        !           338: {
        !           339:        if ( !notcoh ) {
        !           340:                register int size;
        !           341:                if ((size = olh.l_tbase) < sizeof olh)
        !           342:                        olh.l_tbase = olh.l_entry;
        !           343:                canlh(&olh);
        !           344:                if (fwrite(&olh, size, 1, ofp) != 1) {
        !           345:                        diag(werror, tmp);
        !           346:                        return (1);
        !           347:                }
        !           348:                canlh(&olh);
        !           349:                if (size < sizeof olh) {
        !           350:                        olh.l_entry = olh.l_tbase;      
        !           351:                        olh.l_tbase = size;
        !           352:                        fseek(ifp, (long)-2*sizeof(short), 1);
        !           353:                }
        !           354:        } else
        !           355:                fseek(ifp, 0l, 0);
        !           356:        return(0);
        !           357: }
        !           358: 
        !           359: /*
        !           360:  * Copy nbytes from ifp to ofp.
        !           361:  */
        !           362: copy(nbytes) long nbytes;
        !           363: {
        !           364:        register int n;
        !           365:        static char buff[16*1024];
        !           366: 
        !           367:        while (nbytes > 0) {
        !           368:                n = nbytes > sizeof buff ? sizeof buff : nbytes;
        !           369:                if (fread(buff, 1, n, ifp) != n)
        !           370:                        return 1;
        !           371:                if (fwrite(buff, 1, n, ofp) != n)
        !           372:                        return 1;
        !           373:                nbytes -= n;
        !           374:        }
        !           375:        return 0;
        !           376: }
        !           377: 
        !           378: /*
        !           379:  *     Write the l.out.h header in the middle of the file for
        !           380:  *     MS-DOS .exe and GEMDOS .prg
        !           381:  *     Leave ifp at the beginning of L_DEBUG.
        !           382:  */
        !           383: writelout()
        !           384: {
        !           385:        if ( !notcoh )
        !           386:                return(0);
        !           387: 
        !           388:        canlh(&olh);
        !           389:        if (fwrite(&olh, sizeof(olh), 1, ofp) != 1) {
        !           390:                diag(werror, tmp);
        !           391:                return(1);
        !           392:        }
        !           393:        canlh(&olh);
        !           394:        fseek(ifp, (long)sizeof(ldh), 1);
        !           395:        return(0);
        !           396: }
        !           397: 
        !           398:        
        !           399: /*
        !           400:  * Print diagnostics.
        !           401:  */
        !           402: diag(s, fn)
        !           403: char *s;
        !           404: char *fn;
        !           405: {
        !           406:        fprintf(stderr, "%s: ", argv0);
        !           407:        if (fn != NULL)
        !           408:                fprintf(stderr, "%s: ", fn);
        !           409:        fprintf(stderr, "%s\n", s);
        !           410: }
        !           411: 
        !           412: /*
        !           413:  * Cleanup tempfile and exit.
        !           414:  * The status is the exit status.
        !           415:  * When a signal occurs, it is the signal
        !           416:  * number which is non-zero so
        !           417:  * this will be an acceptable exit status.
        !           418:  */
        !           419: cleanup(s)
        !           420: {
        !           421:        unlink(tmp);
        !           422:        exit(s);
        !           423: }
        !           424: 
        !           425: /*
        !           426:  * Print usage message.
        !           427:  */
        !           428: usage()
        !           429: {
        !           430:        fprintf(stderr, usemsg, argv0);
        !           431:        exit(1);
        !           432: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.