Annotation of coherent/d/bin/strip.c, revision 1.1.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.