Annotation of coherent/b/bin/as/c_out.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * coff format output handler.
                      3:  */
                      4: #include <asm.h>
                      5: #include <coff.h>
                      6: #include <utype.h>
                      7: #include <symtab.h>
                      8: 
                      9: #define WHERE 0x40A09C
                     10: 
                     11: #define trace(n) printf("Trace %d\n", n);
                     12: 
                     13: #define CMOD 2         /* clump every 2 bytes */
                     14: #define LIMIT 10       /* bytes of data per line */
                     15: #define STARTP 31      /* start source at. Must be n * 8 -1 */
                     16: #define DATABUF 512    /* size of data buffer */
                     17: #define RELBUF 128     /* entries in relocation buffer */
                     18: #define LINEBUF 128    /* entries in line number buffer */
                     19: #define MANSEG 3       /* Segments that must go out */
                     20: #define ROUNDR 3       /* used to round segments */
                     21: 
                     22: typedef struct seg seg;
                     23: struct seg {           /* coff section header */
                     24:        char            s_name[8];      /* section name */
                     25:        long            s_paddr;        /* physical address, aliased s_nlib */
                     26:        long            s_vaddr;        /* virtual address */
                     27:        long            s_size;         /* section size */
                     28:        long            s_scnptr;       /* file ptr to raw data for section */
                     29:        long            s_relptr;       /* file ptr to relocation */
                     30:        long            s_lnnoptr;      /* file ptr to line numbers */
                     31:        unsigned short  s_nreloc;       /* number of relocation entries */
                     32:        unsigned short  s_nlnno;        /* number of line number entries */
                     33:        long            s_flags;        /* flags */
                     34: 
                     35:        /* Extra data connected with this to allow running this segment */
                     36:        long            data_seekad;    /* next data seek address */
                     37:        long            relo_seekad;    /* next relocation seek address */
                     38:        long            line_seekad;    /* next line seek address */
                     39:        long            curadd;         /* current address this segment */
                     40:        long            hiadd;          /* hi address this pass */
                     41:        short           segSeq;         /* Segment sequence no */
                     42: 
                     43:        char *bp;                       /* data buffer pointer */
                     44:        RELOC *relBp;                   /* relocation buffer pointer */
                     45:        LINENO *lineBp;                 /* line number buffer pointer */
                     46:        char buf[DATABUF];              /* data buffer */
                     47:        RELOC relBuf[RELBUF];           /* relocation entry buffer */
                     48:        LINENO lineBuf[LINEBUF];        /* line number entry buffer */
                     49: };
                     50: 
                     51: static long *tracker;  /* for debugging */
                     52: 
                     53: static seg *segs, *segend;     /* segment bases */
                     54: static seg *cseg;              /* current segment */
                     55: 
                     56: static unsigned short ct, pos, sects, symbs, usects;
                     57: static long datapos, relpos, linepos, sympos, debpos;
                     58: static long strOff = 4;
                     59: static long lastSeek;
                     60: static FILE *ofp;              /* output file */
                     61: 
                     62: static int coffDefCt;          /* count of .def in file */
                     63: static int coffAuxCt;          /* aux records to be written */
                     64: static int coffEfcnCt;         /* end of function records */
                     65: static int txtAt;              /* DEBUG_RECS from last pass */
                     66: #define DEBUG_RECS (coffDefCt + coffAuxCt - coffEfcnCt)
                     67: #define USECTS (txtAt ? usects * 2 : usects)
                     68: static char defSw;             /* in a .def statement */
                     69: static char auxSw;
                     70: static char efcnSw;
                     71: 
                     72: struct xsym {  /* Symbol for debugging becomes SYMENT and maybe auxent */
                     73:        int     symno;
                     74:        int     value;
                     75:        short   scnum;
                     76:        short   type;
                     77:        char    sclass;
                     78:        char    numaux;
                     79:        AUXENT  aux;    /* aux record data */
                     80:        char    *name;  /* name if there is one */
                     81: };
                     82: 
                     83: static struct xsym *syms;              /* all the debug stuff */
                     84: static struct xsym *symptr;            /* currently build debug stuff */
                     85: 
                     86: union word {
                     87:        unsigned char uc[2];
                     88:        unsigned short us;
                     89: };
                     90: 
                     91: union full {
                     92:        unsigned char uc[4];
                     93:        unsigned long ul;
                     94: };
                     95: 
                     96: /*
                     97:  * output spaces and tabs to a position, then output a character.
                     98:  */
                     99: static void
                    100: outTo(to, s)
                    101: {
                    102:        int i;
                    103: 
                    104:        if(!pos)
                    105:                sTitle();
                    106: 
                    107:        for (to += (' ' == s); (i = ((pos | 7) + 1)) <= to; pos = i)
                    108:                putchar('\t');
                    109: 
                    110:        for (; pos < to; pos++)
                    111:                putchar(' ');
                    112: 
                    113:        if (' ' != s)
                    114:                putchar(s);
                    115: }
                    116: 
                    117: /*
                    118:  * Do titles.
                    119:  */
                    120: sTitle()
                    121: {
                    122:        static short pageno;
                    123: 
                    124:        if(pswitch && (++linect > nlpp)) {
                    125:                if(pageno)
                    126:                        printf("\n\n\n\n\n");
                    127:                printf(
                    128:        "\n\nMark Williams 80386 Assembler\t%s\t%s\tPage %d\n\n",
                    129:                        dTime, title, ++pageno);
                    130:                linect = 0;
                    131:        }
                    132: }
                    133: 
                    134: /*
                    135:  * output source line
                    136:  */
                    137: outLine(p, s)
                    138: char *p, s;
                    139: {
                    140:        register char c;
                    141:                
                    142:        if ((2 != pass) ||
                    143:            !lswitch ||
                    144:            (!mlistsw && (NULL != macExp)) ||
                    145:            (NULL == p))
                    146:                return;
                    147: 
                    148:        outTo(STARTP, s);
                    149:        for (; (c = *p++) && ('\n' != c); pos++) {
                    150:                if (lineSize <= pos) {
                    151:                        putchar('\n');
                    152:                        pos = 0;
                    153:                        outTo(STARTP, '|');
                    154:                }
                    155:                if ('\t' == c)
                    156:                        pos |= 7;
                    157:                putchar(c);
                    158:        }
                    159:        putchar('\n');
                    160:        pos = ct = 0;
                    161: }
                    162: 
                    163: /*
                    164:  * Write to obj file.
                    165:  */
                    166: static void
                    167: owrite(buf, size)
                    168: char *buf;
                    169: {
                    170:        if (1 != fwrite(buf, size, 1, ofp))
                    171:                fatal("Write error on object file");    /**/
                    172:        lastSeek += size;
                    173: }
                    174: 
                    175: /*
                    176:  * Seek then Write to obj file.
                    177:  */
                    178: xwrite(add, buf, size)
                    179: long add;
                    180: char *buf;
                    181: {
                    182:        if (add != lastSeek) {
                    183:                if (fseek(ofp, add, 0))
                    184:                        fatal("Seek error on object file");     /**/
                    185:                lastSeek = add;
                    186:        }
                    187:        owrite(buf, size);
                    188: }
                    189: 
                    190: /*
                    191:  * Write actual data.
                    192:  */
                    193: outData(s)
                    194: register seg *s;
                    195: {
                    196:        register size;
                    197: 
                    198:        if (size = s->bp - s->buf) {
                    199:                if (s->s_flags != STYP_BSS) {
                    200:                        xwrite(s->data_seekad, s->buf, size);
                    201:                        s->data_seekad += size;
                    202:                }
                    203:                s->bp = s->buf;
                    204:        }
                    205: }
                    206: 
                    207: /*
                    208:  * Write relocation records.
                    209:  */
                    210: outRel(s)
                    211: register seg *s;
                    212: {
                    213:        register size;
                    214: 
                    215:        if (size = (char *)s->relBp - (char *)s->relBuf) {
                    216:                xwrite(s->relo_seekad, (char *)s->relBuf, size);
                    217:                s->relo_seekad += size;
                    218:        }
                    219:        s->relBp = s->relBuf;
                    220: }
                    221: 
                    222: /*
                    223:  * Write Line records.
                    224:  */
                    225: outLineRec(s)
                    226: register seg *s;
                    227: {
                    228:        register size;
                    229: 
                    230:        if (size = (char *)s->lineBp - (char *)s->lineBuf) {
                    231:                xwrite(s->line_seekad, (char *)s->lineBuf, size);
                    232:                s->line_seekad += size;
                    233:        }
                    234:        s->lineBp = s->lineBuf;
                    235: }
                    236: 
                    237: /*
                    238:  * put object data byte to buffer.
                    239:  */
                    240: binout(b, s)
                    241: unsigned short b;
                    242: register seg *s;
                    243: {
                    244:        if (s->bp == (s->buf + DATABUF))
                    245:                outData(s);
                    246:        *s->bp++ = b;
                    247: }
                    248: 
                    249: 
                    250: /*
                    251:  * Limit data on line. This allows cuts at logical points.
                    252:  */
                    253: static void
                    254: limiter(n)
                    255: {
                    256:        if (lswitch && (ct + n) > LIMIT) {
                    257:                putchar('\n');
                    258:                ct = 0;
                    259:        }
                    260: }
                    261: 
                    262: /*
                    263:  * list data
                    264:  */
                    265: outlst(b)
                    266: unsigned short b;
                    267: {
                    268:        if (dot.sg == 3) {      /* BSS */
                    269:                static int statem = -1; /* only one err per line */
                    270: 
                    271:                if (statement != statem) {
                    272:                        statem = statement;
                    273: 
                    274:                        yyerror("Data defined in .bss");
                    275:                        /* The \fB.bss\fR segment is uninitialized data.
                    276:                         * You cannot place actual values there. */
                    277:                }
                    278:        }
                    279:        binout(b, cseg);
                    280: 
                    281:        if (!lswitch)
                    282:                return;
                    283: 
                    284:        if (!ct) {
                    285:                sTitle();
                    286:                pos = 4;
                    287:                printf("%04lX", dot.loc + segs[dot.sg - 1].s_vaddr);
                    288:        }
                    289: 
                    290:        if (!(ct % CMOD)) {
                    291:                pos++;
                    292:                putchar(' ');
                    293:        }
                    294:        printf("%02X", b & 255);
                    295:        pos += 2;
                    296:        ct++;
                    297: }
                    298: 
                    299: /*
                    300:  * output unrelocated byte
                    301:  */
                    302: outab(b)
                    303: unsigned short b;
                    304: {
                    305:        if (2 == pass) {
                    306:                limiter(1);
                    307:                outlst(b);
                    308:        }
                    309:        dot.loc++;      /* update location ctr */
                    310: }
                    311: 
                    312: /*
                    313:  * output unrelocated word.
                    314:  */
                    315: outaw(u)
                    316: unsigned short u;
                    317: {
                    318:        if (2 == pass) {
                    319:                union word w;
                    320: 
                    321:                w.us = u;
                    322:                limiter(2);
                    323:                outlst(w.uc[0]);
                    324:                outlst(w.uc[1]);
                    325:        }
                    326:        dot.loc += 2;
                    327: }
                    328: 
                    329: /*
                    330:  * output unrelocated long.
                    331:  */
                    332: outal(ul)
                    333: long ul;
                    334: {
                    335:        if (2 == pass) {
                    336:                union full l;
                    337: 
                    338:                l.ul = ul;
                    339:                limiter(4);
                    340:                outlst(l.uc[0]);
                    341:                outlst(l.uc[1]);
                    342:                outlst(l.uc[2]);
                    343:                outlst(l.uc[3]);
                    344:        }
                    345:        dot.loc += 4;
                    346: }
                    347: 
                    348: /*
                    349:  * output relocation.
                    350:  */
                    351: static long
                    352: relOut(oper, sw)
                    353: register expr *oper;
                    354: unsigned sw;
                    355: {
                    356:        register RELOC *bp;
                    357:        register sym *sp;
                    358:        register long rv;
                    359: 
                    360:        rv = oper->exp;
                    361:        if (NULL == (sp = oper->ref) || (sp->type & S_XSYM))
                    362:                return(rv);     /* absolute addr */
                    363: 
                    364:        bp = cseg->relBp++;
                    365:        bp->r_type   = sw;
                    366:        bp->r_vaddr  = dot.loc + cseg->s_vaddr;
                    367: 
                    368:        /*
                    369:         * Only use symbol references when forced
                    370:         * seems to be required by a bug in the
                    371:         * ESIX linker.
                    372:         */
                    373:        if (!(sp->flag & (S_EXREF|S_COMMON))) {
                    374:                int seg = segs[sp->sg - 1].segSeq - 1;
                    375: 
                    376:                bp->r_symndx = txtAt ? (seg * 2) + txtAt : seg;
                    377:        }
                    378:        else {
                    379:                bp->r_symndx = sp->num;
                    380:                if (sp->flag & S_COMMON)
                    381:                        rv += sp->size;
                    382:                rv -= sp->loc;
                    383:        }
                    384: 
                    385:        if (bp == (cseg->relBuf + (RELBUF - 1)))
                    386:                outRel(cseg);
                    387: 
                    388:        /* gimmic addr to make .data after .text */
                    389:        if ((sp->sg > 1) && !(sp->flag & S_COMMON))
                    390:                rv += segs[sp->sg - 1].s_vaddr;
                    391: 
                    392:        return(rv);
                    393: }
                    394:                
                    395: /*
                    396:  * output relocated byte
                    397:  */
                    398: outrb(oper, sw)
                    399: expr *oper;
                    400: int sw;                /* 0 = Relative address, 1 = PC relative address */
                    401: {
                    402:        if (2 == pass) {
                    403:                limiter(1);
                    404:                if (sw)
                    405:                        outlst((unsigned short)(relOut(oper, R_PCRBYTE) -
                    406:                                                (dot.loc + 1)));
                    407:                else
                    408:                        outlst((unsigned short)relOut(oper, R_RELBYTE));
                    409:        }
                    410:        else if (NULL != oper->ref)
                    411:                cseg->s_nreloc++;
                    412:        dot.loc++;
                    413: }
                    414: 
                    415: /*
                    416:  * output relocated word.
                    417:  */
                    418: outrw(oper, sw)
                    419: expr *oper;
                    420: int sw;                /* 0 = Relative address, 1 = PC relative address */
                    421: {
                    422:        union word w;
                    423: 
                    424:        if (2 == pass) {
                    425:                if (sw)
                    426:                        w.us = relOut(oper, R_PCRWORD) - (dot.loc + 2);
                    427:                else
                    428:                        w.us = relOut(oper, R_DIR16);
                    429: 
                    430:                limiter(2);
                    431:                outlst(w.uc[0]);
                    432:                outlst(w.uc[1]);
                    433:        }
                    434:        else if (NULL != oper->ref)
                    435:                cseg->s_nreloc++;
                    436:        dot.loc += 2;
                    437: }
                    438: 
                    439: /*
                    440:  * output relocated long.
                    441:  */
                    442: outrl(oper, sw)
                    443: expr *oper;
                    444: int sw;                /* 0 = Relative address, 1 = PC relative address */
                    445: {
                    446:        union full l;
                    447: 
                    448:        if (2 == pass) {
                    449:                if (sw)
                    450:                        l.ul = relOut(oper, R_PCRLONG) - (dot.loc + 4);
                    451:                else
                    452:                        l.ul = relOut(oper, R_DIR32);
                    453: 
                    454:                limiter(4);
                    455:                outlst(l.uc[0]);
                    456:                outlst(l.uc[1]);
                    457:                outlst(l.uc[2]);
                    458:                outlst(l.uc[3]);
                    459:        }
                    460:        else if (NULL != oper->ref)
                    461:                cseg->s_nreloc++;
                    462:        dot.loc += 4;
                    463: }
                    464: 
                    465: /*
                    466:  * Output symbol table string.
                    467:  */
                    468: outSymStr(sp)
                    469: register sym *sp;
                    470: {
                    471:        register i;
                    472:        register char *name;
                    473: 
                    474:        name = SYMNAME(sp);
                    475:        if ((i = strlen(name)) > SYMNMLEN)
                    476:                owrite(name, i + 1);
                    477: }
                    478: 
                    479: static void showIt(sp)
                    480: sym *sp;
                    481: {
                    482:        int i;
                    483:        char *name;
                    484: 
                    485:        i = strlen(name = SYMNAME(sp));
                    486:        fprintf(stderr, "Trace %X, '%s' flag %d len %d num %d\n",
                    487:                 sp, name, sp->flag, i, sp->num);
                    488: }
                    489: 
                    490: /*
                    491:  * output symbol table entry.
                    492:  */
                    493: SYMENT *
                    494: outSym(sp)
                    495: register sym *sp;
                    496: {
                    497:        static SYMENT s;
                    498:        int i;
                    499:        register char *name;
                    500: 
                    501:        clear(&s);
                    502: 
                    503:        i = strlen(name = SYMNAME(sp));
                    504: 
                    505:        if (i > SYMNMLEN) {
                    506:                s.n_zeroes = 0;
                    507:                s.n_offset = strOff;
                    508:                strOff += i + 1;
                    509:        }
                    510:        else
                    511:                strncpy(s._n._n_name, name, SYMNMLEN);
                    512: 
                    513:        if (sp->sg < 0)
                    514:                s.n_scnum = sp->sg;
                    515:        else
                    516:                s.n_scnum = segs[sp->sg - 1].segSeq;
                    517:        s.n_value = sp->loc;
                    518:        s.n_sclass = C_STAT;
                    519: 
                    520:        if (sp->flag & S_EXDEF) {
                    521:                s.n_sclass = C_EXT;
                    522:                if (sp->flag & S_COMMON) { /* common */
                    523:                        s.n_value = (sp->size ? sp->size : 1);
                    524:                        s.n_scnum = 0;
                    525:                }
                    526:        }
                    527:        if (sp->flag & S_EXREF) {
                    528:                s.n_scnum  = 0;
                    529:                s.n_value  = 0;
                    530:                s.n_sclass = C_EXT;
                    531:        }
                    532: 
                    533:        /* gimmic addr to make .data after .text */
                    534:        if (s.n_scnum > 1)
                    535:                s.n_value += segs[sp->sg - 1].s_vaddr;
                    536: 
                    537:        owrite((char *)&s, sizeof(s));
                    538:        return (&s);
                    539: }
                    540: 
                    541: /*
                    542:  * Go from pass 0 to pass 1 or 2
                    543:  */
                    544: newPass(fn)
                    545: char *fn;
                    546: {
                    547:        register seg *s;
                    548:        unsigned size;
                    549:        long xaddr;
                    550:        
                    551:        if ((cseg->curadd = dot.loc) > cseg->hiadd)
                    552:                cseg->hiadd = cseg->curadd;
                    553:        cseg = segs;    /* return to .text */
                    554:        defCt = macNo = dot.loc = 0;
                    555:        if ((txtAt = DEBUG_RECS) && !pass) {
                    556:                xpass = 1;      /* force another pass */
                    557:                symptr = syms = alloc(coffDefCt * sizeof(*syms));
                    558:        }
                    559:        longMode = pass = dot.sg = 1;
                    560:        if (indPass()) {        /* take an extra pass */
                    561:                usects = 0;
                    562:                for (s = segs; s < segend; s++) {
                    563:                        if (s->hiadd || usects < MANSEG)
                    564:                                usects++;
                    565:                        s->segSeq = usects;
                    566:                        s->bp = s->buf;
                    567:                        s->relBp = s->relBuf;
                    568:                        s->lineBp = s->lineBuf;
                    569:                        s->s_nlnno = s->s_nreloc = s->hiadd = s->curadd = 0;
                    570:                }
                    571:                symGlob(txtAt + USECTS); /* fix symbol table */
                    572:                coffDefCt = coffAuxCt = coffEfcnCt = 0;
                    573:                return;
                    574:        }
                    575: 
                    576:        pass   = 2;     /* last pass */
                    577:        linect = nlpp;
                    578:        usects = xaddr = datapos = relpos = linepos = 0;
                    579:        ofp = xopen(fn, "wb");
                    580:        
                    581:        for (s = segs; s < segend; s++) {
                    582:                if (s->hiadd || usects < MANSEG)
                    583:                        usects++;
                    584:                s->s_paddr = s->s_vaddr = xaddr;
                    585:                s->hiadd += ROUNDR;             /* Round up */
                    586:                s->hiadd &= ~ROUNDR;
                    587:                xaddr += s->s_size = s->hiadd;
                    588:                s->data_seekad = datapos; /* temp value */
                    589:                s->s_relptr = relpos;
                    590:                s->s_lnnoptr = linepos;
                    591:                if (s->s_flags != STYP_BSS) {
                    592:                        datapos += s->hiadd;
                    593:                        relpos  += s->s_nreloc * RELSZ;
                    594:                        linepos += s->s_nlnno  * LINESZ;
                    595:                }
                    596:        }
                    597:        size =  sizeof(FILEHDR) + (usects * sizeof(SCNHDR));
                    598:        debpos  = size + datapos + relpos + linepos;
                    599:        sympos  = debpos + (txtAt * SYMESZ);
                    600:        linepos = size + datapos + relpos;
                    601:        relpos  = size + datapos;
                    602: 
                    603:        if (fseek(ofp, lastSeek = sympos, 0))
                    604:                fatal("Seek error on object file");     /**/
                    605: 
                    606:        usects = 0;
                    607:        for (s = segs; s < segend; s++) {
                    608:                SYMENT sym;
                    609:                AUXENT aux;
                    610: 
                    611:                if (s->hiadd || usects < MANSEG)
                    612:                        usects++;
                    613:                else
                    614:                        continue;
                    615: 
                    616:                /* write symbol records for segments */
                    617:                clear(&sym);
                    618:                s->segSeq = usects;
                    619:                sym.n_sclass = C_STAT;
                    620:                sym.n_value = s->s_vaddr;
                    621:                memcpy(sym._n._n_name, s->s_name, SYMNMLEN);
                    622:                sym.n_scnum = usects;
                    623:                sym.n_numaux = txtAt ? 1 : 0;
                    624:                owrite((char *)&sym, sizeof(sym));
                    625: 
                    626:                if (sym.n_numaux) {
                    627:                        aux.ae_scnlen = s->s_size;
                    628:                        aux.ae_nreloc = s->s_nreloc;
                    629:                        aux.ae_nlinno = s->s_nlnno;
                    630:                        owrite((char *)&aux, sizeof(aux));
                    631:                }
                    632: 
                    633:                if (s->hiadd && (s->s_flags != STYP_BSS))
                    634:                        s->s_scnptr = s->data_seekad += size;
                    635:                else
                    636:                        s->s_scnptr = s->data_seekad = 0;
                    637: 
                    638:                if (s->s_nreloc && (s->s_flags != STYP_BSS))
                    639:                        s->relo_seekad = s->s_relptr += relpos;
                    640:                else
                    641:                        s->relo_seekad = s->s_relptr = 0;
                    642: 
                    643:                if (s->s_nlnno && (s->s_flags != STYP_BSS))
                    644:                        s->line_seekad = s->s_lnnoptr += linepos;
                    645:                else
                    646:                        s->line_seekad = s->s_lnnoptr = 0;
                    647:                s->hiadd = s->curadd = 0;
                    648:        }
                    649: 
                    650:        sympos = ftell(ofp);    /* continue the symbol table from here */
                    651: 
                    652:        /* fix the symbol table setting numbers */
                    653:        symGlob(txtAt + USECTS);
                    654:        coffDefCt = coffAuxCt = coffEfcnCt = 0;
                    655: }
                    656: 
                    657: /*
                    658:  * write record header then segment headers.
                    659:  */
                    660: static void
                    661: writeHeader()
                    662: {
                    663:        register seg *s;
                    664:        FILEHDR head;
                    665:        int i;
                    666:        long loadd;
                    667: 
                    668:        head.f_magic = C_386_MAGIC;
                    669:        time(&head.f_timdat);
                    670:        head.f_nsyms = symbs;
                    671:        head.f_symptr = debpos;
                    672:        head.f_opthdr = 0;
                    673:        head.f_flags = 0;
                    674:        head.f_nscns = usects;
                    675: 
                    676:        xwrite(0L, (char *)&head, sizeof(head));
                    677:        for (loadd = i = 0, s = segs; s < segend; s++) {
                    678:                if (s->hiadd || i < MANSEG) {
                    679:                        i++;
                    680:                        owrite(s, sizeof(SCNHDR));
                    681:                }
                    682:        }
                    683: }
                    684: 
                    685: /*
                    686:  * Finish any output.
                    687:  */
                    688: cleanUp()
                    689: {
                    690:        int pad;
                    691:        register seg *s;
                    692: 
                    693:        s = cseg;               /* close out current seg */
                    694:        if(s->hiadd < (s->curadd = dot.loc))
                    695:                s->hiadd = s->curadd;
                    696: 
                    697:        if (coffDefCt)  /* Write debug symbols */
                    698:                writeDebug();
                    699: 
                    700:        fseek(ofp, sympos, 0);
                    701: 
                    702:        symDump(outSym, txtAt); /* write ordinary symbols */
                    703: 
                    704:        symbs = (ftell(ofp) - debpos) / SYMESZ; /* figure sym ct from loc */
                    705: 
                    706:        if (strOff > 4) {
                    707:                owrite(&strOff, sizeof(strOff)); /* write length of tail */
                    708:                writeDebugLong();   /* dump symbols that are too long */
                    709:                symDump(outSymStr, txtAt);      
                    710:        }
                    711: 
                    712:        writeHeader();  /* now we know header data */
                    713: 
                    714:        for (s = segs; s < segend; s++) {
                    715:                if (s->s_flags == STYP_BSS)
                    716:                        continue;
                    717: 
                    718:                /* go to end of segment */
                    719:                if (s->curadd != s->hiadd)
                    720:                        doOrg(NULL, NULL);
                    721: 
                    722:                /* pad with nop or zero */
                    723:                pad = (s->s_flags == STYP_TEXT) ? NOP : 0;
                    724:                for (; s->hiadd & ROUNDR; s->hiadd++)
                    725:                        binout(pad, s);
                    726:                outData(s);
                    727:                outRel(s);
                    728:                outLineRec(s);
                    729:        }
                    730: }
                    731: 
                    732: /*
                    733:  * org command
                    734:  */
                    735: doOrg(label, oper)
                    736: parm *label;
                    737: data *oper;
                    738: {
                    739:        register seg *s;
                    740:        long from, to;
                    741:        char pad;
                    742: 
                    743:        buildlab(label);
                    744: 
                    745:        from = dot.loc;
                    746:        s = cseg;
                    747:        if (pass == 2)
                    748:                outData(s);
                    749:        s->curadd = dot.loc;            /* first make segment current */
                    750:        if (dot.loc > s->hiadd)
                    751:                s->hiadd = dot.loc;
                    752:        
                    753:        /* process org */
                    754:        switch ((NULL == oper) ? 'n' : oper->type) {
                    755:        case 'n':
                    756:                to = s->hiadd;  /* org to hi spot in segment */
                    757:                break;
                    758:        case 'd':
                    759:        case 's':
                    760:                yyerror("Org to invalid value");
                    761:                /* You may not \fB.org\fR to doubles or strings. */
                    762:                return (1);
                    763:        case 'y':
                    764:                if (oper->d.y->sg != dot.sg) {
                    765:                        yyerror("Org to wrong segment");
                    766:                        /* You must \fB.org\fR to the current segment. */
                    767:                        return (1);
                    768:                }
                    769:                to = oper->d.y->loc;
                    770:                break;
                    771:        case 'l':
                    772:                to = oper->d.l; /* org where requested */
                    773:        }
                    774: 
                    775:        if ((pass != 2) || (s->s_flags == STYP_BSS)) { /* no disk work */
                    776:                s->curadd = dot.loc = to;       /* make segment current again */
                    777:                if (to > s->hiadd)
                    778:                        s->hiadd = dot.loc;
                    779:                return (0);
                    780:        }
                    781:        if (to <= s->hiadd) {   /* no pad if we've been there */
                    782:                s->curadd = dot.loc = to;
                    783:                s->data_seekad += to - from;
                    784:                return (0);
                    785:        }
                    786:        from = s->curadd = dot.loc = s->hiadd;  /* seek to the old end */
                    787:        s->data_seekad += s->hiadd - from;
                    788: 
                    789:        pad = (s->s_flags == STYP_TEXT) ? NOP : 0; /* pad out */
                    790:        for (;from < to; from++)
                    791:                binout(pad, s);
                    792:        s->curadd = dot.loc = to;       /* make segment current again */
                    793:        if (to > s->hiadd)
                    794:                s->hiadd = dot.loc;
                    795:        return (0);
                    796: }
                    797: 
                    798: /*
                    799:  * Initialize segment information.
                    800:  */
                    801: segInit()
                    802: {
                    803:        int i;
                    804:        register seg *s;
                    805: 
                    806:        static char *segclass[] = {
                    807:                ".text", ".data", ".bss"
                    808:        };
                    809:        static long segflag[] = {
                    810:                STYP_TEXT, STYP_DATA, STYP_BSS
                    811:        };
                    812: 
                    813:        cseg = segs = alloc(sizeof(*segs) * MANSEG);
                    814:        segend = segs + MANSEG;
                    815: 
                    816:        for (i = 0, s = segs; s < segend; s++, i++) {
                    817:                strncpy(s->s_name, segclass[i], SYMNMLEN);
                    818:                s->s_flags = segflag[i];
                    819:                s->segSeq = ++sects;
                    820:                s->bp = s->buf;
                    821:                s->relBp = s->relBuf;
                    822:                s->lineBp = s->lineBuf;
                    823:        }
                    824: }
                    825: 
                    826: /*
                    827:  * .ident and .version set stuff in the comment section.
                    828:  */
                    829: cmnt(op, p)
                    830: opc *op;
                    831: parm *p;
                    832: {
                    833: }
                    834: 
                    835: /*
                    836:  * coff debugging statements.
                    837:  */
                    838: coffFile(s)
                    839: parm *s;
                    840: {
                    841: #ifdef NODEBUG
                    842:        return;
                    843: #else
                    844:        coffDefCt++;
                    845:        coffAuxCt++;
                    846:        if (2 == pass) {
                    847:                symptr->sclass = C_FILE;
                    848:                symptr->scnum  = N_DEBUG;
                    849:                symptr->numaux = 1;
                    850:                if ('"' == s->str[0]) {
                    851:                        char *p;
                    852: 
                    853:                        if (NULL != (p = strchr(s->str + 1, '"')))
                    854:                                *p = 0;
                    855:                        strncpy(symptr->aux.ae_fname, s->str + 1, FILNMLEN);
                    856:                }
                    857:                else
                    858:                        strncpy(symptr->aux.ae_fname, s->str, FILNMLEN);
                    859:                symptr->name = ".file";
                    860:                symptr++;
                    861:        }
                    862: #endif
                    863: }
                    864: 
                    865: coffDef(s)
                    866: parm *s;
                    867: {
                    868: #ifdef NODEBUG
                    869:        return;
                    870: #else
                    871:        if (pass) {     /* initialize new symbol */
                    872:                if (defSw)
                    873:                        yywarn("missing .endef");
                    874:                symptr->scnum = N_ABS;
                    875:                if (NULL != symptr->name)
                    876:                        free(symptr->name);
                    877:                symptr->name  = scpy(s->str, 0);
                    878:                symptr->symno = DEBUG_RECS;
                    879:                defSw = 1;
                    880:        }
                    881: #endif
                    882: }
                    883: 
                    884: coffEndef()
                    885: {
                    886: #ifdef NODEBUG
                    887:        return;
                    888: #else
                    889:        if ((1 == pass) && (symptr->scnum != N_DEBUG))
                    890:                symReNumber(symptr->name, DEBUG_RECS);
                    891: 
                    892:        if (2 == pass) {
                    893:                register struct xsym *s;
                    894: 
                    895:                switch (symptr->sclass) {
                    896:                case C_BLOCK:
                    897:                        if (strcmp(symptr->name, ".eb"))
                    898:                                break;
                    899:                        for (s = symptr - 1; s != syms; s--)
                    900:                                if (C_BLOCK == s->sclass &&
                    901:                                    !strcmp(s->name, ".bb") &&
                    902:                                    !s->aux.ae_endndx) {
                    903:                                        s->aux.ae_endndx = DEBUG_RECS + 2;
                    904:                                        break;
                    905:                                }
                    906:                        if (s == syms)
                    907:                                yywarn(".eb does not connect to .bb");
                    908:                                /* A .eb statement does not connect to a
                    909:                                 * .bb statement */
                    910:                        break;
                    911: 
                    912:                case C_EFCN:    /* end of function marker */
                    913:                        for (s = symptr - 1; s != syms; s--) {
                    914:                                if (!strcmp(symptr->name, s->name)) {
                    915:                                        short type;
                    916: 
                    917:                                        /* if this is a function at any level */
                    918:                                        for (type = s->type & ~N_BTMASK;
                    919:                                             type && !ISFCN(type);
                    920:                                             type >>= N_TSHIFT)
                    921:                                                ;
                    922: 
                    923:                                        if (type)
                    924:                                                break;
                    925:                                }
                    926:                        }
                    927:                        if (s == syms)
                    928:                                yywarn(".type -1 does not connect");
                    929:                                /* A type of -1 C_EFCN does not connect to
                    930:                                 * a .def of a function */
                    931:                        else {
                    932:                                s->aux.ae_fsize = symptr->value - s->value;
                    933:                                s->aux.ae_endndx = DEBUG_RECS;
                    934:                        }
                    935:                }
                    936:                symptr->numaux = auxSw;
                    937:                symptr++;
                    938:                if (!defSw)
                    939:                        yywarn(".endef must follow .def"); /* */
                    940:        }
                    941:        coffDefCt++;                    /* we need a spot to remember this */
                    942:        coffEfcnCt += efcnSw;           /* C_EFCN don't write to table */
                    943:        if (!efcnSw)                    /* They don't have aux records */
                    944:                coffAuxCt += auxSw;
                    945:        auxSw = defSw = efcnSw = 0;
                    946: #endif
                    947: }
                    948: 
                    949: /*
                    950:  * .type command
                    951:  */
                    952: coffType(n)
                    953: long n;
                    954: {
                    955: #ifdef NODEBUG
                    956:        return;
                    957: #else
                    958:        if (ISFCN(n)) { /* function build a line record */
                    959:                register LINENO *bp;
                    960: 
                    961:                auxSw = 1;
                    962:                if (2 != pass)
                    963:                        cseg->s_nlnno++;
                    964:                else {
                    965:                        bp = cseg->lineBp++;
                    966:                        bp->l_lnno = 0;
                    967:                        bp->l_addr.l_symndx = DEBUG_RECS;
                    968:                
                    969:                        if (bp == (cseg->lineBuf + (LINEBUF - 1)))
                    970:                                outLineRec(cseg);
                    971:                }
                    972:        }
                    973: 
                    974:        if (2 == pass) {
                    975:                if (!defSw)
                    976:                        yywarn(".type not in .endif");
                    977:                        /* Debug command .type must be in .endif */
                    978:                symptr->type = n;
                    979:        }
                    980: #endif
                    981: }
                    982: 
                    983: coffVal(item)
                    984: data *item;
                    985: {
                    986: #ifdef NODEBUG
                    987:        return;
                    988: #else
                    989:        SYMENT *s;
                    990: 
                    991:        if (2 != pass)
                    992:                return;
                    993:        if (!defSw)
                    994:                yywarn(".val must follow .def"); /* */
                    995: 
                    996:        if ('y' == item->type) {
                    997:                sym *sp = item->d.y;
                    998: 
                    999:                if (sp->flag & S_COMMON) {
                   1000:                        symReNumber(symptr->name, DEBUG_RECS);
                   1001:                        symptr->scnum = N_UNDEF;
                   1002:                        symptr->value = sp->size;
                   1003:                }
                   1004:                else {
                   1005:                        symptr->scnum = sp->sg;
                   1006:                        symptr->value = sp->loc;
                   1007:                }
                   1008:        }
                   1009:        else
                   1010:                symptr->value = item->d.l;
                   1011: #endif
                   1012: }
                   1013: 
                   1014: coffScl(n)
                   1015: long n;
                   1016: {
                   1017: #ifdef NODEBUG
                   1018:        return;
                   1019: #else
                   1020:        if (C_EFCN == n)
                   1021:                efcnSw = 1;
                   1022:        if (!pass)
                   1023:                return;
                   1024:        if (!defSw)
                   1025:                yywarn(".scl must follow .def"); /* */
                   1026:        if (ISTAG(n))
                   1027:                symptr->scnum = N_DEBUG;
                   1028:        symptr->sclass = n;
                   1029: #endif
                   1030: }
                   1031: 
                   1032: coffSize(n)
                   1033: long n;
                   1034: {
                   1035: #ifdef NODEBUG
                   1036:        return;
                   1037: #else
                   1038:        auxSw = 1;
                   1039:        if (2 != pass)
                   1040:                return;
                   1041:        if (!defSw)
                   1042:                yywarn(".size must follow .def"); /* */
                   1043:        symptr->aux.ae_size = n;
                   1044: #endif
                   1045: }
                   1046: 
                   1047: coffDim(n, d)
                   1048: long n;
                   1049: int d;
                   1050: {
                   1051: #ifdef NODEBUG
                   1052:        return;
                   1053: #else
                   1054:        auxSw = 1;
                   1055:        if (2 != pass)
                   1056:                return;
                   1057:        if (!defSw) {
                   1058:                yywarn(".dim must follow .def"); /* */
                   1059:                return;
                   1060:        }
                   1061:        if (DIMNUM <= d) {
                   1062:                yywarn(".dim statement too complex");
                   1063:                /* A .dim statement may contain no more than 4 dimensions. */
                   1064:                return;
                   1065:        }
                   1066:        symptr->aux.ae_dimen[d] = n;
                   1067: #endif
                   1068: }
                   1069: 
                   1070: coffTag(p)
                   1071: parm *p;
                   1072: {
                   1073: #ifdef NODEBUG
                   1074:        return;
                   1075: #else
                   1076:        struct xsym *s;
                   1077: 
                   1078:        auxSw = 1;
                   1079:        if (2 != pass)
                   1080:                return;
                   1081:        for (s = symptr - 1; s != syms; s--) {
                   1082:                if (ISTAG(s->sclass) && !strcmp(p->str, s->name)) {
                   1083:                        if (C_EOS == symptr->sclass)
                   1084:                                s->aux.ae_endndx = symptr->symno + 2;
                   1085:                        symptr->aux.ae_tagndx = s->symno;
                   1086:                        break;
                   1087:                }
                   1088:        }
                   1089:        if (s == syms)
                   1090:                yywarn(".tag does not connect");
                   1091:                /* This tag fails to connect to an earlier unconnected .def
                   1092:                 * of the same name and a proper n_sclass.
                   1093:                 */
                   1094: #endif
                   1095: }
                   1096: 
                   1097: coffLn(n)
                   1098: long n;
                   1099: {
                   1100: #ifdef NODEBUG
                   1101:        return;
                   1102: #else
                   1103:        register LINENO *bp;
                   1104: 
                   1105:        if (2 != pass)
                   1106:                cseg->s_nlnno++;
                   1107:        else {
                   1108:                bp = cseg->lineBp++;
                   1109:                bp->l_lnno = n;
                   1110:                bp->l_addr.l_paddr = dot.loc;
                   1111:                
                   1112:                if (bp == (cseg->lineBuf + (LINEBUF - 1)))
                   1113:                        outLineRec(cseg);
                   1114:        }
                   1115: #endif
                   1116: }
                   1117: 
                   1118: coffLine(n)
                   1119: long n;
                   1120: {
                   1121: #ifdef NODEBUG
                   1122:        return;
                   1123: #else
                   1124:        auxSw = 1;
                   1125:        if (2 != pass)
                   1126:                return;
                   1127:        if (!defSw)
                   1128:                yywarn(".line must follow .def"); /* */
                   1129:        symptr->aux.ae_lnno = n;        
                   1130: #endif
                   1131: }
                   1132: 
                   1133: /*
                   1134:  * Write debug records.
                   1135:  */
                   1136: writeDebug()
                   1137: {
                   1138:        register struct xsym *s, *ends;
                   1139:        int ct = 0, act = 0;
                   1140: 
                   1141:        fseek(ofp, lastSeek = debpos, 0);
                   1142:        for (ends = (s = syms) + coffDefCt; s != ends; s++) {
                   1143:                int i;
                   1144:                SYMENT sym;
                   1145: 
                   1146:                if (C_EFCN == s->sclass)
                   1147:                        continue;
                   1148: 
                   1149:                sym.n_sclass = s->sclass;
                   1150:                sym.n_value  = s->value;
                   1151:                sym.n_scnum  = s->scnum;
                   1152:                sym.n_type   = s->type;
                   1153:                sym.n_numaux = s->numaux;
                   1154: 
                   1155:                if ((i = strlen(s->name)) > SYMNMLEN) {
                   1156:                        sym.n_offset = strOff;
                   1157:                        sym.n_zeroes = 0;
                   1158:                        strOff += i + 1;
                   1159:                }
                   1160:                else
                   1161:                        strncpy(sym.n_name, s->name, SYMNMLEN);
                   1162:                
                   1163:                ct++;
                   1164:                owrite(&sym, SYMESZ);
                   1165:                if (sym.n_numaux) {
                   1166:                        act++;
                   1167:                        owrite(&(s->aux), AUXESZ);
                   1168:                }
                   1169:        }
                   1170:        
                   1171: }
                   1172: 
                   1173: writeDebugLong()
                   1174: {
                   1175:        register struct xsym *s, *ends;
                   1176: 
                   1177:        for (ends = (s = syms) + coffDefCt; s != ends; s++) {
                   1178:                int i;
                   1179: 
                   1180:                if (C_EFCN == s->sclass)
                   1181:                        continue;
                   1182: 
                   1183:                if ((i = strlen(s->name)) > SYMNMLEN)
                   1184:                        owrite(s->name, i + 1);
                   1185:        }
                   1186: }
                   1187:        
                   1188: /*
                   1189:  * .comm and .lcomm commands.
                   1190:  * Improve later.
                   1191:  */
                   1192: comm(op, p, n)
                   1193: opc *op;
                   1194: parm *p;
                   1195: long n;
                   1196: {
                   1197:        if (NULL == p) {
                   1198:                yyerror(".comm must have tag");
                   1199:                /* The format of \fB.comm\fR is \fB.comm name, size\fR. */
                   1200:                return;
                   1201:        }
                   1202:        if (op->code == 2) {
                   1203:                sym *s;
                   1204: 
                   1205:                s = symLookUp(p->str, S_LOCAL, 0L, op->code + 1);
                   1206:                s->size = n;
                   1207:                s->flag = S_EXDEF|S_COMMON;
                   1208:        }
                   1209: }
                   1210: 
                   1211: /*
                   1212:  * segment command.
                   1213:  */
                   1214: void
                   1215: segment(op, p, n)
                   1216: opc *op;
                   1217: parm *p;
                   1218: long n;
                   1219: {
                   1220:        register seg *s;
                   1221:        sym *rv;
                   1222:        static int previous = 0;
                   1223:        int thisSg;
                   1224: 
                   1225:        /* Implement one level segment stack */
                   1226:        if (10000 != op->code) {
                   1227:                thisSg = op->code;
                   1228:                previous = dot.sg - 1;  /* save where we were */
                   1229:        }
                   1230:        else    /* .previous pops the stack */
                   1231:                thisSg = previous;
                   1232: 
                   1233:        s = segs + thisSg;
                   1234: 
                   1235:        if (NULL == p) {        /* segment change */
                   1236:                if ((cseg->curadd = dot.loc) > cseg->hiadd)
                   1237:                        cseg->hiadd = cseg->curadd;
                   1238: 
                   1239:                cseg = s;
                   1240:                dot.loc = s->curadd;
                   1241:                dot.sg = thisSg + 1;
                   1242:                return;
                   1243:        }
                   1244: 
                   1245:        /* set up data */
                   1246:        rv = symLookUp(p->str, S_LOCAL, s->curadd, thisSg + 1);
                   1247:        rv->size = n;
                   1248:        s->curadd += n;
                   1249:        if (s->curadd > s->hiadd)
                   1250:                s->hiadd = s->curadd;
                   1251:        return;
                   1252: }
                   1253: 
                   1254: /*
                   1255:  * Switch to a section by name.
                   1256:  * add it if required.
                   1257:  */
                   1258: void
                   1259: section(name)
                   1260: char *name;
                   1261: {
                   1262:        int motion, i;
                   1263:        char *oldsegs;
                   1264:        register seg *s;
                   1265:        static opc segOp = { 0, S_SEGMENT };
                   1266: 
                   1267:        /* These are common segment names with their flags */
                   1268:        static char *segclass[] = {
                   1269:                ".init", ".fini", ".rodata",
                   1270:                ".comment", ".ctors", ".dtors"
                   1271:        };
                   1272:        static long segflag[] = {
                   1273:                STYP_TEXT, STYP_DATA, STYP_DATA,
                   1274:                STYP_INFO, STYP_DATA, STYP_DATA
                   1275:        };
                   1276: 
                   1277:        /* Look for section in segment list */
                   1278:        for (segOp.code = 0; segOp.code < sects; segOp.code++) {
                   1279:                if (!strncmp(name, segs[segOp.code].s_name, 8)) {
                   1280:                        segment(&segOp, NULL, 0L);
                   1281:                        return;
                   1282:                }
                   1283:        }
                   1284: 
                   1285:        /* realloc segment list with room for one more */
                   1286:        oldsegs = (char *)segs;
                   1287:        if (NULL == (segs = realloc(segs, sizeof(*segs) * ++sects)))
                   1288:                fatal("Out of memory"); /**/
                   1289: 
                   1290:        /* adjust pointers to segment list */
                   1291:        motion = (char *)segs - oldsegs;
                   1292: #define adjust(ptr) ptr = (char *)(((char *)(ptr)) + motion)
                   1293:        adjust(cseg);
                   1294:        adjust(segend);
                   1295:        for (s = segs; s < segend; s++) {
                   1296:                adjust(s->bp);
                   1297:                adjust(s->relBp);
                   1298:                adjust(s->lineBp);
                   1299:        }
                   1300: #undef adjust
                   1301:        segend++;
                   1302: 
                   1303:        /* build new entry on segment list */
                   1304:        memset(s, '\0', sizeof(*s));
                   1305:        strncpy(s->s_name, name, SYMNMLEN);
                   1306:        
                   1307:        s->s_flags = STYP_TEXT;         /* set default */
                   1308:        for (i = 0; i < 6; i++) {       /* look at common names */
                   1309:                if (!strcmp(name, segclass[i])) {
                   1310:                        s->s_flags = segflag[i];
                   1311:                        break;
                   1312:                }
                   1313:        }
                   1314: 
                   1315:        s->segSeq = sects - 1;
                   1316:        s->bp = s->buf;
                   1317:        s->relBp = s->relBuf;
                   1318:        s->lineBp = s->lineBuf;
                   1319: 
                   1320:        segment(&segOp, NULL, 0L);      /* switch to the new entry */
                   1321: }

unix.superglobalmegacorp.com

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