Annotation of coherent/d/bin/cc/c/n2/i8086/outrel.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * The routines in this file make up
                      3:  * a writer for the Coherent reloc.h object
                      4:  * file. During code assembly all the bits get
                      5:  * written to a temporary file. At the very end the
                      6:  * bits get copied back to the final object file.
                      7:  * The symbol table is constructed as the code is read,
                      8:  * each symbol is declared when defined. References are
                      9:  * tacked onto the end of the file.
                     10:  * Relocation instructions for debug and symbol table entries are
                     11:  * also passed through the scratch file.
                     12:  */
                     13: #ifdef vax
                     14: #include "INC$LIB:cc2.h"
                     15: #include "INC$LIB:canon.h"
                     16: #include "INC$LIB:reloc.h"
                     17: #include "INC$LIB:debug.h"
                     18: #else
                     19: #include "cc2.h"
                     20: #include <canon.h>
                     21: #include <reloc.h>
                     22: #include <debug.h>
                     23: #endif
                     24: 
                     25: #if !TINY
                     26: #define dbrpt(x,y)     _dbrpt(x,y)
                     27: #else
                     28: #define dbrpt(x,y)     /* dbrpt(x,y) */
                     29: #endif
                     30: #define        NTXT    512                     /* Text buffer size */
                     31: #define        NREL    256                     /* Relocation buffer size */
                     32: /*
                     33:  * Scratch file operators.
                     34:  */
                     35: #define        TTYPE   017                     /* Type mask */
                     36: #define Tflag(x)       (((x)>>4)&7)    /* Get flag bits */
                     37: #define        TEND    000                     /* End marker */
                     38: #define        TENTER  001                     /* Enter new area */
                     39: #define        TBYTE   002                     /* Byte data */
                     40: #define        TWORD   003                     /* Word data */
                     41: #if 0
                     42: #define TTRIP  004                     /* Triple byte data */
                     43: #define TLONG  005                     /* Long data */
                     44: #endif
                     45: #define TDLAB  006                     /* Debug item */
                     46: #define        TDLOC   007                     /* Debug location */
                     47: #define        TCODE   010                     /* Code segment base */
                     48: #define        TDATA   011                     /* Data segment base */
                     49: #define        TBASE   012                     /* External segment base */
                     50: 
                     51: #define        TPCR    020                     /* PC rel flag, ored in */
                     52: #define        TSYM    040                     /* Symbol based flag, ored in */
                     53: #define locrup(x)      (((x)+01)&~01)  /* memory alignment */
                     54: objhdr_t objhdr = {                    /* object header */
                     55:                REL_OBJ,
                     56:                "i8086",
                     57:                "C",
                     58:                VERSMWC
                     59: };
                     60: 
                     61: summseg_t summseg = {                  /* Summary segment */
                     62:                SUMMARY,
                     63:                sizeof (summseg.seg_off)
                     64: };
                     65: 
                     66: extern char    *calloc();
                     67: extern char    *malloc();
                     68: extern char    *strcpy();
                     69: 
                     70: ADDRESS        SCODE_len;                      /* Length of SCODE in bytes */
                     71: char   txt[NTXT];                      /* Text buffer */
                     72: char   rel[NREL];                      /* Relocation buffer */
                     73: char   *txtp = txt;                    /* Text pointer */
                     74: char   *relp = rel;                    /* Relocation pointer */
                     75: int    refnum = 0;                     /* Symbol reference number */
                     76: static int level = 0;                  /* Debug brace level */
                     77: static int dline = 0;                  /* Most recent line number entry */
                     78: 
                     79: /*
                     80:  * This table converts a C compiler
                     81:  * segment index into a relocatable object segment type.
                     82:  */
                     83: char   segindex[] = {
                     84:        PURCODE,                        /* SCODE */
                     85:        OWNCODE,                        /* SLINK */
                     86:        PURDATA,                        /* SPURE */
                     87:        STRINGS,                        /* SSTRN */
                     88:        OWNDATA,                        /* SDATA */
                     89:        BLDATA,                         /* SBSS */
                     90:        -1,                             /* SANY */
                     91:        -1,                             /* SSTACK */
                     92:        -1,                             /* SALIEN */
                     93:        DEBUG,                          /* SDBG */
                     94:        SYMBOLS                         /* SSYM */
                     95: };
                     96: 
                     97: /*
                     98:  * Output a segment switch.
                     99:  */
                    100: outseg(s)
                    101: {
                    102:        bput(TENTER);
                    103:        bput(s);
                    104: }
                    105: 
                    106: /*
                    107:  * Output an absolute byte.
                    108:  */
                    109: outab(b)
                    110: {
                    111:        bput(TBYTE);
                    112:        bput(b);
                    113:        dot += 1;
                    114: }
                    115: 
                    116: /*
                    117:  * Output an absolute word.
                    118:  */
                    119: outaw(w)
                    120: {
                    121:        bput(TWORD);
                    122:        iput(w);
                    123:        dot += 2;
                    124: }
                    125: 
                    126: 
                    127: #ifdef TLONG
                    128: /*
                    129:  * Output an absolute long.
                    130:  */
                    131: outal(l)
                    132: long l;
                    133: {
                    134:        bput(TLONG);
                    135:        lput(l);
                    136:        dot += 4;
                    137: }
                    138: #endif
                    139: 
                    140: /*
                    141:  * Output a full byte.
                    142:  */
                    143: outxb(sp, b, pcrf)
                    144: register SYM *sp;
                    145: {
                    146:        register opcode;
                    147: 
                    148:        opcode = TBYTE;
                    149:        if (sp != NULL)
                    150:                opcode |= TSYM;
                    151:        if (pcrf)
                    152:                opcode |= TPCR;
                    153:        bput(opcode);
                    154:        bput(b);
                    155:        if (sp != NULL)
                    156:                pput(sp);
                    157:        dot += 1;
                    158: }
                    159: 
                    160: /*
                    161:  * Output a full word.
                    162:  */
                    163: outxw(sp, w, pcrf)
                    164: register SYM *sp;
                    165: {
                    166:        register opcode;
                    167: 
                    168:        opcode = TWORD;
                    169:        if (sp != NULL)
                    170:                opcode |= TSYM;
                    171:        if (pcrf)
                    172:                opcode |= TPCR;
                    173:        bput(opcode);
                    174:        iput(w);
                    175:        if (sp != NULL)
                    176:                pput(sp);
                    177:        dot += 2;
                    178: }
                    179: 
                    180: #ifdef TLONG
                    181: /*
                    182:  * Output a full long.
                    183:  */
                    184: outxl(sp, l, pcrf)
                    185: register SYM *sp;
                    186: long l;
                    187: {
                    188:        register opcode;
                    189: 
                    190:        opcode = TLONG;
                    191:        if (sp != NULL)
                    192:                opcode |= TSYM;
                    193:        if (pcrf)
                    194:                opcode |= TPCR;
                    195:        bput(opcode);
                    196:        lput(lR);
                    197:        if (sp != NULL)
                    198:                pput(sp);
                    199:        dot += 4;
                    200: }
                    201: #endif
                    202: 
                    203: /*
                    204:  * Copy a dlabel record from ifp to ofp.
                    205:  * Flag the symbol table entry if appropriate.
                    206:  */
                    207: outdlab(l,class)
                    208: {
                    209:        register int val;
                    210:        register SYM *sp;
                    211:        int n;
                    212: 
                    213:        if (l == 0)
                    214:                bput(TDLAB);
                    215:        bput(class);
                    216: 
                    217:        /* Get line number. */
                    218:        iput(iget());
                    219: 
                    220:        /* Get value */
                    221:        if (class < DC_AUTO)
                    222:                ;
                    223:        else if (class < DC_MOS)
                    224:                iput(val = iget());
                    225:        else {
                    226:                bput(bget());
                    227:                bput(bget());
                    228:                iput(iget());
                    229:        }
                    230: 
                    231:        /* Get name */
                    232:        sget(id, NCSYMB);
                    233: 
                    234:        /* Check for symbol table entry */
                    235:        if (class==DC_GDEF || class==DC_SEX || class==DC_GREF) {
                    236:                sp = glookup(id, 0);
                    237:                sp->s_flag |= S_PUT;
                    238:        } else if (class==DC_SIN) {
                    239:                sp = llookup(val, 0);
                    240:                sp->s_flag |= S_PUT;
                    241:        }
                    242: 
                    243:        /* Put name */
                    244:        sput(id);
                    245: 
                    246:        /* Get type */
                    247:        for (;;) {
                    248:                switch (bput(bget())) {
                    249:                case DT_NONE:
                    250:                case DT_CHAR:
                    251:                case DT_UCHAR:
                    252:                case DT_SHORT:
                    253:                case DT_USHORT:
                    254:                case DT_INT:
                    255:                case DT_UINT:
                    256:                case DT_LONG:
                    257:                case DT_ULONG:
                    258:                case DT_FLOAT:
                    259:                case DT_DOUBLE:
                    260:                case DT_VOID:
                    261:                        iput(iget());
                    262:                        break;
                    263:                case DT_STRUCT:
                    264:                case DT_UNION:
                    265:                case DT_ENUM:
                    266:                case DD_PTR:
                    267:                case DD_FUNC:
                    268:                case DD_ARRAY:
                    269:                        iput(iget());
                    270:                        continue;
                    271:                        break;
                    272:                case DX_MEMBS:
                    273:                        bput(n = iget());
                    274:                        for ( ; n > 0; n-=1) {
                    275:                                outdlab(1, bget());
                    276:                        }
                    277:                        break;
                    278:                case DX_NAME:
                    279:                        iget();
                    280:                        sget(id, NCSYMB);
                    281:                        sput(id);
                    282:                        break;
                    283:                default:
                    284:                        cbotch("outdlab: %d", n);
                    285:                }
                    286:                break;
                    287:        }
                    288: }
                    289: 
                    290: /*
                    291:  * Output a debug line record.
                    292:  */
                    293: outdlin(op)
                    294: {
                    295:        bput(TDLAB);
                    296:        bput(DC_LINE);
                    297:        iput(line);
                    298:        bput(op);
                    299:        bput(0);
                    300:        bput(DT_NONE);
                    301:        iput(0);
                    302: }
                    303: 
                    304: /*
                    305:  * Output a debug relocation record.
                    306:  */
                    307: outdloc(n)
                    308: {
                    309:        bput(TDLOC);
                    310:        iput(n);
                    311: }
                    312: 
                    313: /*
                    314:  * Abort illegal output.
                    315:  * reloc.h doesn't handle 8087 or Large model.
                    316:  */
                    317: outbad()
                    318: {
                    319:        cbotch("bad temp file object");
                    320: }
                    321: 
                    322: /*
                    323:  * Output a 1 word object containing
                    324:  * the base address of the current code
                    325:  * segment.
                    326:  */
                    327: outcb()
                    328: {
                    329:        return (outbad());
                    330:        bput(TCODE);
                    331:        dot += 2;
                    332: }
                    333: 
                    334: /*
                    335:  * Output a 1 word object containing
                    336:  * the base address of the current data
                    337:  * segment.
                    338:  */
                    339: outdb()
                    340: {
                    341:        return (outbad());
                    342:        bput(TDATA);
                    343:        dot += 2;
                    344: }
                    345: 
                    346: /*
                    347:  * Output a 1 word object containing
                    348:  * the base address of the external symbol
                    349:  * pointed to by `sp'.
                    350:  */
                    351: outsb(sp)
                    352: SYM *sp;
                    353: {
                    354:        return (outbad());
                    355:        bput(TBASE);
                    356:        pput(sp);
                    357:        dot += 2;
                    358: }
                    359: 
                    360: /*
                    361:  * Initialize the code writer.
                    362:  * This routine is called before anything is written to the scratch file.
                    363:  * A no op on coherent reloc.h format.
                    364:  */
                    365: outinit()
                    366: {
                    367: }
                    368: 
                    369: /*
                    370:  * Finish off the code writer.
                    371:  * This routine is called just before the scratch file is closed.
                    372:  * Write either the "end" to the output file
                    373:  * if generating assembler,
                    374:  * or a "TEND" code to stop the
                    375:  * "copycode" routine if writing binary.
                    376:  */
                    377: outdone()
                    378: {
                    379:        register SYM *sp;
                    380:        register int i;
                    381: 
                    382:        if (isvariant(VASM)) {
                    383:                return;
                    384:        }
                    385: 
                    386:        /*
                    387:         * Assign refnums to symbols.
                    388:         * And make dlabel items for internally generated symbols.
                    389:         */
                    390:        for (refnum = i = 0;  i < NSHASH;  i++) {
                    391:                for (sp = hash2[i];  sp != NULL;  sp = sp->s_fp) {
                    392:                        if ((sp->s_flag&S_GBL) != 0
                    393:                         || (sp->s_flag&S_DEF) == 0) {
                    394:                                if ((sp->s_flag&S_LABNO) == 0)
                    395:                                        sp->s_ref = refnum++;
                    396:                                if ((sp->s_flag&S_PUT) == 0) {
                    397:                                        bput(TDLAB);
                    398:                                        bput(DC_GREF);
                    399:                                        iput(0);
                    400:                                        sput(sp->s_id);
                    401:                                        bput(DT_NONE);
                    402:                                        iput(0);
                    403:                                }
                    404:                        }
                    405:                }
                    406:        }
                    407: 
                    408:        bput(TEND);
                    409: }
                    410: 
                    411: /*
                    412:  * Copy back.
                    413:  * Figure out the sizes and final values
                    414:  * of everything. Copy the code from the scratch
                    415:  * file back to the output file.
                    416:  */
                    417: copycode()
                    418: {
                    419:        int op, nd, nr;
                    420:        ADDRESS data;
                    421:        long    addr;
                    422:        fsize_t size, symsize;
                    423:        unsigned char reltype, segtype;
                    424:         
                    425:        SCODE_len = seg[SCODE].s_dot;
                    426: 
                    427:        /*
                    428:         * Initialize output.
                    429:         */
                    430:        oheader(0);
                    431: 
                    432:        /*
                    433:         * Copy out code.
                    434:         */
                    435:        dotseg = SCODE;
                    436:        dot = 0;
                    437:        while ((op=bget()) != TEND) {
                    438:                switch (op & TTYPE) {
                    439: 
                    440:                case TENTER:
                    441:                        oenter(bget());
                    442:                        continue;
                    443: 
                    444:                case TBYTE:
                    445:                        nd = 1;
                    446:                        reltype = B_0;
                    447:                        data = bget();
                    448:                        break;
                    449: 
                    450:                case TWORD:
                    451:                        nd = 2;
                    452:                        reltype = B_01;
                    453:                        data = iget();
                    454:                        break;
                    455: 
                    456: #ifdef TLONG
                    457:                case TLONG:
                    458:                        nd = 4;
                    459:                        reltype = B_0123;
                    460:                        data = lget();
                    461:                        break;
                    462: #endif
                    463: 
                    464:                case TDLAB:
                    465:                        getdlab();
                    466:                        continue;
                    467: 
                    468:                case TDLOC:
                    469:                        getdloc();
                    470:                        continue;
                    471: 
                    472:                default:
                    473:                        cbotch("copycode: op=%d", op);
                    474: 
                    475:                }
                    476: 
                    477:                switch (Tflag(op)) {
                    478: 
                    479:                case 0:                 /* Absolute */
                    480:                        nr = 0;
                    481:                        break;
                    482: 
                    483:                case Tflag(TPCR|TSYM):  /* Symbol based pc relative */
                    484:                        data -= dot+nd;
                    485:                        /* Fall through */
                    486: 
                    487:                case Tflag(TSYM):       /* Symbol based */
                    488:                {
                    489:                        register SYM *sp;
                    490: 
                    491:                        sp = pget();
                    492:                        if ((sp->s_flag&S_DEF) != 0) {
                    493:                                nr = 6;
                    494:                                segtype = segindex[sp->s_seg];
                    495:                                data += sp->s_value;
                    496:                        } else {
                    497:                                nr = 10;
                    498:                                segtype = SYMBOLS;
                    499:                                addr = sp->s_ref;
                    500:                        }
                    501:                        if ((op&TPCR) != 0)
                    502:                                segtype |= PCREL;
                    503:                        break;
                    504:                }
                    505: 
                    506:                case Tflag(TPCR):       /* Absolute pc relative */
                    507:                        data -= dot+nd;
                    508:                        segtype = ABSLUTE|PCREL;
                    509:                        nr = 10;
                    510:                        addr = 0;
                    511:                        break;
                    512: 
                    513:                default:
                    514:                        cbotch("copycode: flags=%o", op);
                    515:                }
                    516: 
                    517:                /*
                    518:                 * Write the current record.
                    519:                 */
                    520:                enuf(nd, nr);
                    521:                if (nr != 0) {
                    522:                        rbbuf(reltype);
                    523:                        rbbuf(segtype);
                    524:                        rlbuf((long) dot);
                    525:                        if (nr == 10)
                    526:                                rlbuf(addr);
                    527:                }
                    528:                do {
                    529:                        bbuf((int) data);
                    530:                        data >>= 8;
                    531:                } while (--nd > 0);
                    532:        }
                    533: 
                    534:        if (isvariant(VLINES))
                    535:                outbrace('}');
                    536:        if (notvariant(VLIB))
                    537:                dump();                 /* Dump the typedefs */
                    538: 
                    539:        /*
                    540:         * Flush buffers.
                    541:         */
                    542:        notenuf();
                    543: 
                    544:        /*
                    545:         * Write symbol table.
                    546:         */
                    547:        summseg.seg_off[SYMBOLS] = ftell(ofp);
                    548:        segtype = SYMBOLS;
                    549:        bput(segtype);
                    550:        size = symsize;
                    551:        cansize(size);
                    552:        owrite(&size, sizeof(size));
                    553:        addr = refnum;
                    554:        canuaddr(addr);
                    555:        owrite(&addr, sizeof(addr));
                    556:        oglobals();
                    557:        symsize = ftell(ofp) - summseg.seg_off[SYMBOLS] - sizeof(fsize_t) - 1;
                    558: 
                    559:        /*
                    560:         * Put end marker.
                    561:         */
                    562:        segtype = LASTSEG;
                    563:        bput(segtype);
                    564: 
                    565:        /*
                    566:         * Now go back and patch the remaining holes.
                    567:         */
                    568:        fseek(ofp, (fsize_t)0, 0);
                    569:        oheader(1);
                    570: 
                    571:        /*
                    572:         * Symbol segment size and count.
                    573:         */
                    574:        fseek(ofp, summseg.seg_off[SYMBOLS]+1, 0);
                    575:        size = symsize;
                    576:        cansize(size);
                    577:        owrite(&size, sizeof(size));
                    578:        addr = refnum;
                    579:        canuaddr(addr);
                    580:        owrite(&addr, sizeof(addr));
                    581: }
                    582: 
                    583: /*
                    584:  * Switch segments.
                    585:  */
                    586: oenter(newseg)
                    587: register int newseg;
                    588: {
                    589:        notenuf();
                    590:        if (dotseg != SSYM)
                    591:                seg[dotseg].s_dot = dot;
                    592:        dotseg = newseg;
                    593:        if (dotseg != SSYM)
                    594:                dot = seg[dotseg].s_dot;
                    595:        else
                    596:        dot = 0;
                    597: }
                    598: 
                    599: /*
                    600:  * This routine checks to see if
                    601:  * there is enough room in the text and relocation
                    602:  * buffers to hold `nt' bytes of text and `nr' bytes of
                    603:  * relocation.
                    604:  */
                    605: enuf(nt, nr)
                    606: {
                    607:        if (txtp+nt>&txt[NTXT] || relp+nr>&rel[NREL])
                    608:                notenuf();
                    609: }
                    610: 
                    611: /*
                    612:  * Flush buffers.
                    613:  */
                    614: notenuf()
                    615: {
                    616:        register n;
                    617:        unsigned char   segtype;
                    618:        fsize_t size;
                    619: 
                    620:        if ((n=txtp-txt) != 0) {
                    621:                if (dotseg != SSYM) {
                    622:                        segtype = segindex[dotseg];
                    623:                        bput(segtype);
                    624:                        size = n;
                    625:                        cansize(size);
                    626:                        owrite(&size, sizeof(size));
                    627:                }
                    628:                owrite(txt, n);
                    629:                if ((n=relp-rel) != 0) {
                    630:                        segtype = RELOCN;
                    631:                        bput(segtype);
                    632:                        size = n;
                    633:                        cansize(size);
                    634:                        owrite(&size, sizeof(size));
                    635:                        owrite(rel, n);
                    636:                        relp = rel;
                    637:                }
                    638:        }
                    639:        txtp = txt;
                    640: }
                    641: 
                    642: /*
                    643:  * Write a byte or long to text or relocation buffers
                    644:  * in canonical ordering.
                    645:  */
                    646: bbuf(b)
                    647: {
                    648:        *txtp++ = b;
                    649:        dot += 1;
                    650: }
                    651: 
                    652: lbuf(l)
                    653: long l;
                    654: {
                    655:        *txtp++ = l >> 16;
                    656:        *txtp++ = l >> 24;
                    657:        *txtp++ = l;
                    658:        *txtp++ = l >> 8;
                    659:        dot += 4;
                    660: }
                    661: 
                    662: rbbuf(b)
                    663: {
                    664:        *relp++ = b;
                    665: }
                    666: 
                    667: rlbuf(l)
                    668: long l;
                    669: {
                    670:        *relp++ = l >> 16;
                    671:        *relp++ = l >> 24;
                    672:        *relp++ = l;
                    673:        *relp++ = l >> 8;
                    674: }
                    675: 
                    676: /*
                    677:  * Write a block of bytes to the output file.
                    678:  */
                    679: owrite(p, n)
                    680: register char *p;
                    681: register int n;
                    682: {
                    683:        while (--n >= 0) 
                    684:                bput(*p++);
                    685: }
                    686: 
                    687: /*
                    688:  * Write the header and summary segment.
                    689:  * Summary is complete on second call only.
                    690:  */
                    691: oheader(n)
                    692: {
                    693:        fsize_t offs;
                    694:        register int i;
                    695:        register struct seg *segp;
                    696: 
                    697:        /*
                    698:         * Write header.
                    699:         */
                    700:        owrite(&objhdr, sizeof(objhdr));
                    701: 
                    702:        /*
                    703:         * Copy segment sizes into summary segment.
                    704:         */
                    705:        for (segp = &seg[i=0];  i < NSEG;  segp++, i++) {
                    706:                if (segindex[i] < 0 || i == SSYM) continue;
                    707:                offs = segp->s_dot;
                    708:                if (i != SDBG)
                    709:                        offs = locrup(offs);
                    710:                if (n == 0 || i >= SDBG)
                    711:                        summseg.seg_off[segindex[i]] += offs;
                    712:                segp->s_dot = 0;
                    713:        }
                    714:        /*
                    715:         * Write summary segment.
                    716:         */
                    717:        bput(summseg.seg_type);
                    718:        offs = summseg.seg_size;
                    719:        cansize(offs);
                    720:        owrite(&offs, sizeof(offs));
                    721:        for (i=0; i<SUMMARY; i+=1) {
                    722:                offs = summseg.seg_off[i];
                    723:                cansize(offs);
                    724:                owrite(&offs, sizeof(offs));
                    725:        }
                    726: }
                    727: 
                    728: /*
                    729:  * Structure to contain debug items on this pass.
                    730:  */
                    731: struct dbgt {
                    732:        struct dbgt *d_dp;              /* Link */
                    733:        int d_ref;                      /* Index number */
                    734:        unsigned char d_class;          /* Storage class */
                    735:        unsigned char d_flag;           /* Flags */
                    736:        unsigned char d_level;          /* Bracket level */
                    737:        unsigned char d_seg;            /* Segment */
                    738:        ADDRESS d_value;                /* Offset in segment */
                    739:        int d_size;                     /* Size of d_data */
                    740:        char d_data[];                  /* Name and type */
                    741: };
                    742: #define D_GBL  1
                    743: #define D_LCL  2
                    744: #define D_TAG  4
                    745: #define D_NAM  8
                    746: #define D_LAB  16
                    747: #define D_ENU  32
                    748: 
                    749: struct dbgt *newdbgt();
                    750: struct dbgt *getdbgt();
                    751: struct dbgt *dbase;
                    752: struct dbgt *dnext;
                    753: char *getmembs();
                    754: 
                    755: /*
                    756:  * Read debug table item(s) into memory.
                    757:  */
                    758: getdlab()
                    759: {
                    760:        register struct dbgt *dp;
                    761:        static int refnum = 0;
                    762: 
                    763:        dp = getdbgt();
                    764: 
                    765:        /* This should be done in cc0 */
                    766: 
                    767:        if (isvariant(VLIB)) {
                    768:                switch (dp->d_class) {
                    769:                        case DC_TYPE:
                    770:                        case DC_STAG:
                    771:                        case DC_UTAG:
                    772:                        case DC_ETAG:
                    773:                                return;
                    774:                }
                    775:        }
                    776:        if (dp->d_class == DC_LINE || dp->d_class == DC_LAB)
                    777:                dp->d_ref = refnum;
                    778: 
                    779:        refnum += 1; 
                    780:        if (dbase  == NULL)
                    781:                dbase = dp;
                    782:        if (dnext != NULL)
                    783:                dnext->d_dp = dp;
                    784:        dbrpt("enter", dp);
                    785:        while (dp->d_dp != NULL) {
                    786:                dp = dp->d_dp;
                    787:                dbrpt("enter", dp);
                    788:        }
                    789:        dnext = dp;
                    790:        if (dp->d_class == DC_FILE)
                    791:                outbrace('{');  
                    792: }
                    793: 
                    794: /*
                    795:  * Read a debug relocation item and patch current `dot'
                    796:  * into the appropriate debug/symbol table item.
                    797:  * If the debug item is '}' and level 2, then dump the batch of locals.
                    798:  * If the debug item is '}' and level 1, then dump the type definitions.
                    799:  */
                    800: getdloc()
                    801: {
                    802:        register struct dbgt *dp;
                    803:        register int ref;
                    804: 
                    805:        ref = iget();
                    806:        for (dp = dbase; ; dp = dp->d_dp) {
                    807:                if (dp == NULL)
                    808:                        cbotch("getdloc: %d", ref);
                    809:                if ((dp->d_flag&D_GBL) != 0)
                    810:                        continue;
                    811:                if (dp->d_ref == ref)
                    812:                        break;
                    813:        }
                    814:        dp->d_seg = segindex[dotseg];
                    815:        dp->d_value = dot;
                    816: 
                    817:        dbrpt("reloc", dp);
                    818:        if (dp->d_data[0] == '}' && dp->d_level <= 2) {
                    819:                outbrace('}');
                    820:                level--;
                    821:                dump();
                    822:        }
                    823: }
                    824: 
                    825: /*
                    826:  * Dump the locals and type definitions
                    827:  */
                    828: 
                    829: dump()
                    830: {
                    831:        register struct dbgt *dp, **dpp;
                    832:        int saveseg;
                    833: 
                    834:        if ((saveseg = dotseg) != SDBG)
                    835:                oenter(SDBG);
                    836:        dpp = &dbase;
                    837:        dnext = NULL;
                    838:        while ((dp = *dpp) != NULL) {
                    839:                if ((dp->d_flag&D_LCL) != 0) {
                    840:                        dbrpt("write", dp);
                    841:                        osymbol(dp, -1);
                    842:                        dp->d_flag &= ~D_LCL;
                    843:                }
                    844:                if ((dp->d_flag&D_GBL) == 0) {
                    845:                        dbrpt("free", dp);
                    846:                        *dpp = dp->d_dp;
                    847:                        free(dp);
                    848:                } else {
                    849:                        dbrpt("save", dp);
                    850:                        dnext = dp;
                    851:                        dpp = &dp->d_dp;
                    852:                }
                    853:        }
                    854:        if (saveseg != SDBG)
                    855:                oenter(saveseg);
                    856: }
                    857: 
                    858: /*
                    859:  * Write out global symbol definitions and references.
                    860:  */
                    861: oglobals()
                    862: {
                    863:        register struct dbgt *dp, *dp1;
                    864:        extern int refnum;
                    865: 
                    866:        oenter(SSYM);
                    867:        for (dp = dbase; dp != NULL; dp = dp1) {
                    868:                dp1 = dp->d_dp;
                    869:                dbrpt("write", dp);
                    870:                if (dp->d_seg == TYPESYM || dp->d_seg == ABSLUTE)
                    871:                        osymbol(dp, refnum++);
                    872:                else
                    873:                        osymbol(dp, dp->d_ref);
                    874:                dbrpt("free", dp);
                    875:                free(dp);
                    876:        }
                    877:        notenuf();
                    878: }
                    879: 
                    880: /*
                    881:  * Write out a symbol to the symbol or debug table.
                    882:  * Debug table symbols have negative refnums,
                    883:  * and may require relocation.
                    884:  */
                    885: osymbol(dp, refnum)
                    886: register struct dbgt *dp;
                    887: {
                    888:        register char *cp;
                    889:        unsigned char segtype;
                    890:        uaddr_t segaddr;
                    891:        int nd, nr;
                    892: 
                    893:        /* Write scope/refnum or seg/value+relocation expression */
                    894:        nd = 5 + dp->d_size;
                    895:        nr = 0;
                    896:        if (refnum >= 0) {
                    897:                if (dp->d_seg == ABSLUTE) {
                    898:                        segtype = MDSCOPE;
                    899:                        nd += 5;
                    900:                } else if (dp->d_seg != LASTSEG) {
                    901:                        segtype = LDSCOPE;
                    902:                        nd += 5;
                    903:                } else
                    904:                        segtype = RFSCOPE;
                    905:                segaddr = refnum;
                    906:        } else {
                    907:                segtype = dp->d_seg;
                    908:                segaddr = dp->d_value;
                    909:                if (segtype < SUMMARY
                    910:                 && segtype != TYPESYM
                    911:                 && segtype != ABSLUTE)
                    912:                        nr = 6;
                    913:        }
                    914:        enuf(nd, nr);
                    915:        bbuf(segtype);
                    916:        if (nr != 0) {
                    917:                rbbuf(B_2301);
                    918:                rbbuf(dp->d_seg);
                    919:                rlbuf((long) dot);
                    920:        }
                    921:        lbuf(segaddr);
                    922: 
                    923:        /* Write name */
                    924:        cp = dp->d_data;
                    925:        nd = dp->d_size;
                    926:        do {
                    927:                bbuf(*cp);
                    928:                nd -= 1;
                    929:        } while (*cp++);
                    930: 
                    931:        /* Write seg/value expression */
                    932:        if (refnum >= 0 && (segtype == MDSCOPE || segtype == LDSCOPE)) {
                    933:                bbuf(dp->d_seg);
                    934:                lbuf((long) dp->d_value);
                    935:        }
                    936: 
                    937:        /* Type */
                    938:        while (--nd >= 0)
                    939:                bbuf(*cp++);
                    940: }
                    941: 
                    942: /*
                    943:  * Read in debug items translating into loader type syntax.
                    944:  * Member definitions are fetched recursively.
                    945:  * If a tag or type definition, the member definitions are appended to the
                    946:  * node surrounded by "{" and "}" nodes.
                    947:  * If not a tag definition, the member definitions are discarded.
                    948:  * In either case, the member types are appended to the type of the
                    949:  * parent node.
                    950:  */
                    951: #define        DSZ 512
                    952: struct dbgt *
                    953: getdbgt()
                    954: {
                    955:        register int n;
                    956:        register char *dptr;
                    957:        struct dbgt d;
                    958:        char data[DSZ];
                    959:        int value, width, offs;
                    960:        int typet, subt, membs;
                    961:        char *sdp;
                    962: 
                    963:        d.d_dp = NULL;
                    964:        d.d_ref = -1;
                    965:        d.d_flag = D_LCL;
                    966:        d.d_level = level;
                    967:        d.d_seg = LASTSEG;
                    968:        d.d_value = 0;
                    969:        d.d_size = 0;
                    970:        width = membs = 0;
                    971: 
                    972:        /*
                    973:         * Loop to read entire record:
                    974:         *      class, optional value, name, type.
                    975:         */
                    976:        dptr = data;
                    977:        for (typet = 0; ; typet += 1) {
                    978: 
                    979:                if (dptr >= data+DSZ) {
                    980:                        dbrpt("1", &d);
                    981:                        cbotch("getdbgt buffer");
                    982:                }
                    983: 
                    984:                n = bget();
                    985:                if (n < DX_MEMBS)
                    986:                        value = iget() * NBPBYTE;
                    987:                else if (n < DC_SEX)
                    988:                        ;
                    989:                else {
                    990:                        dline = iget();
                    991:                        if (n < DC_AUTO)
                    992:                                ;
                    993:                        else if (n < DC_MOS)
                    994:                                value = iget();
                    995:                        else {
                    996:                                width = bget();
                    997:                                offs = bget();
                    998:                                value = iget();
                    999:                        }
                   1000:                }
                   1001:                subt = 0;
                   1002: 
                   1003:                switch (n) {
                   1004: 
                   1005:                /*
                   1006:                 * Classes: fetch values and set flags.
                   1007:                 */
                   1008:                case DC_SEX:
                   1009:                        d.d_flag |= D_NAM;
                   1010:                        goto setclass;
                   1011: 
                   1012:                case DC_GDEF:
                   1013:                case DC_GREF:
                   1014:                        d.d_flag = D_GBL|D_NAM;
                   1015:                        goto setclass;
                   1016: 
                   1017:                case DC_ETAG:
                   1018:                        d.d_flag |= D_ENU;
                   1019:                        strcpy(dptr, "enum ");
                   1020:                        dptr += 5;
                   1021:                        goto tag;
                   1022:                case DC_STAG:
                   1023:                        strcpy(dptr, "struct ");
                   1024:                        dptr += 7;
                   1025:                        goto tag;
                   1026:                case DC_UTAG:
                   1027:                        strcpy(dptr, "union ");
                   1028:                        dptr += 6;
                   1029:                case DC_TYPE:
                   1030:                        tag:
                   1031:                                d.d_flag = (level == 0) ? D_TAG|D_GBL : D_TAG|D_LCL;
                   1032:                                d.d_seg = TYPESYM;
                   1033:                                goto setclass;
                   1034: 
                   1035:                case DC_FILE:
                   1036:                        d.d_seg = PURCODE;
                   1037:                        goto setclass;
                   1038: 
                   1039:                case DC_AUTO:
                   1040:                        d.d_seg = L_STACK;
                   1041:                        d.d_value = value;
                   1042:                        goto setclass;
                   1043: 
                   1044:                case DC_SIN:
                   1045:                        d.d_flag |= D_LAB;
                   1046:                        goto setclass;
                   1047: 
                   1048:                case DC_REG:
                   1049:                        d.d_seg = L_REG;
                   1050:                        d.d_value = value;
                   1051:                        goto setclass;
                   1052: 
                   1053:                case DC_PREG:
                   1054:                        if (level == 0) {
                   1055:                                level++;
                   1056:                                outbrace('{');
                   1057:                        }
                   1058:                        d.d_seg = L_REG;
                   1059:                        d.d_value = value;
                   1060:                        goto setclass;
                   1061: 
                   1062:                case DC_MOE:
                   1063:                        d.d_seg = ABSLUTE;
                   1064:                        d.d_value = value;
                   1065:                        goto setclass;
                   1066: 
                   1067:                case DC_PAUTO:
                   1068:                        if (level  == 0) {
                   1069:                                level++;
                   1070:                                outbrace('{');
                   1071:                        }
                   1072:                        d.d_seg = P_STACK;
                   1073:                        d.d_value = value;
                   1074:                        goto setclass;
                   1075: 
                   1076:                case DC_LAB:
                   1077:                case DC_LINE:
                   1078:                        goto setclass;
                   1079: 
                   1080:                case DC_MOS:
                   1081:                case DC_MOU:
                   1082:                        d.d_seg = FLD_OFF;
                   1083:                        d.d_value = value * NBPBYTE + offs;
                   1084:                        goto setclass;
                   1085: 
                   1086:                /*
                   1087:                 * Set the class field, read the name;
                   1088:                 * Lookup globals and statics.
                   1089:                 */
                   1090:                setclass:
                   1091:                        d.d_class = n;
                   1092:                        while (*dptr++ = bget())
                   1093:                                ;
                   1094:                        if ((d.d_flag&(D_NAM|D_LAB)) != 0) {
                   1095:                                register SYM *sp;
                   1096: 
                   1097:                                if ((d.d_flag&D_NAM) != 0)
                   1098:                                        sp = glookup(data, 0);
                   1099:                                else
                   1100:                                        sp = llookup(value, 0);
                   1101:                                if ((sp->s_flag&S_DEF) != 0) {
                   1102:                                        d.d_seg = segindex[sp->s_seg];
                   1103:                                        d.d_value = sp->s_value;
                   1104: #if COMMON
                   1105:                                } else if (sp->s_value != 0) {
                   1106:                                        d.d_seg = BLDATA|Cb;
                   1107:                                        d.d_value = sp->s_value;
                   1108: #endif
                   1109:                                }
                   1110:                                if ((d.d_flag&D_GBL) != 0)
                   1111:                                        d.d_ref = sp->s_ref;
                   1112:                        }
                   1113:                        continue;
                   1114: 
                   1115:                /*
                   1116:                 * Types: write type and prepare for trailing data.
                   1117:                 * For files and lines, write a phony type.
                   1118:                 */
                   1119:                case DT_NONE:
                   1120:                        if (d.d_class == DC_FILE) {
                   1121:                                register char *p;
                   1122: 
                   1123:                                *dptr++ = STRINGt;
                   1124:                                p = "source file";
                   1125:                                while (*dptr++ = *p++)
                   1126:                                        ;
                   1127:                        }
                   1128:                        if (d.d_class == DC_LINE) {
                   1129:                                *dptr++ = 6;    /* Line */
                   1130:                                *dptr++ = dline;
                   1131:                                *dptr++ = dline >> 8;
                   1132:                                *dptr++ = 0;    /* Column */
                   1133:                                *dptr++ = 0;    /* Flag */
                   1134:                                *dptr++ = 0;    /* Saved instruction */
                   1135:                                *dptr++ = 0;
                   1136:                        }
                   1137:                        break;
                   1138: 
                   1139:                case DT_CHAR:
                   1140:                case DT_SHORT:
                   1141:                case DT_INT:
                   1142:                case DT_LONG:
                   1143:                        n = Integer;
                   1144:                        goto getwidth;
                   1145: 
                   1146:                case DT_UCHAR:
                   1147:                case DT_USHORT:
                   1148:                case DT_UINT:
                   1149:                case DT_ULONG:
                   1150:                        n = Natural;
                   1151:                        goto getwidth;
                   1152: 
                   1153:                case DT_FLOAT:
                   1154:                case DT_DOUBLE:
                   1155:                        n = Rational;
                   1156:                        goto settype;
                   1157: 
                   1158:                case DT_VOID:
                   1159:                        n = Void;
                   1160:                        goto settype;
                   1161: 
                   1162:                case DT_STRUCT:
                   1163:                        membs = n;
                   1164:                        n = Record;
                   1165:                        sdp = dptr;
                   1166:                        goto settype;
                   1167: 
                   1168:                case DT_UNION:
                   1169:                        membs = n;
                   1170:                        n = Union;
                   1171:                        sdp = dptr;
                   1172:                        goto settype;
                   1173: 
                   1174:                case DT_ENUM:
                   1175:                        d.d_flag |= D_ENU;
                   1176:                        membs = n;
                   1177:                        n = Natural;
                   1178:                        sdp = dptr;
                   1179:                        goto settype;
                   1180: 
                   1181:                getwidth:
                   1182:                        if (width)
                   1183:                                value = width;
                   1184: 
                   1185:                settype:
                   1186:                        *dptr++ = 1;
                   1187:                        *dptr++ = n;
                   1188:                        if (n != Void) {
                   1189:                                if (value == 0)
                   1190:                                        *dptr++ = ANYt;
                   1191:                                else if (value <= 0377) {
                   1192:                                        *dptr++ = 1;
                   1193:                                        *dptr++ = value;
                   1194:                                } else {
                   1195:                                        *dptr++ = 2;
                   1196:                                        *dptr++ = value;
                   1197:                                        *dptr++ = value >> 8;
                   1198:                                }
                   1199:                        }
                   1200:                        if (subt) {
                   1201:                                *dptr++ = TYPEt;
                   1202:                                continue;
                   1203:                        }
                   1204:                        if (membs) {
                   1205:                                --typet;
                   1206:                                continue;
                   1207:                        }
                   1208:                        break;
                   1209: 
                   1210:                /*
                   1211:                 * Dimensions: as for types, but flag for subtypes.
                   1212:                 */
                   1213:                case DD_PTR:
                   1214:                        n = Pointer;
                   1215:                        ++subt;
                   1216:                        goto settype;
                   1217: 
                   1218:                case DD_FUNC:
                   1219:                        n = Proc;
                   1220:                        ++subt;
                   1221:                        goto settype;
                   1222: 
                   1223:                case DD_ARRAY:
                   1224:                        n = Array;
                   1225:                        ++subt;
                   1226:                        goto settype;
                   1227: 
                   1228:                /*
                   1229:                 * Trailing struct/union/enum data.
                   1230:                 */
                   1231:                case DX_NAME:
                   1232:                        dptr = sdp;
                   1233:                        *dptr++ = STRINGt;
                   1234:                        switch (membs) {
                   1235:                                case DT_STRUCT:
                   1236:                                        strcpy(dptr, "struct ");
                   1237:                                        dptr += 7;
                   1238:                                        break;
                   1239:                                case DT_UNION:
                   1240:                                        strcpy(dptr, "union ");
                   1241:                                        dptr += 6;
                   1242:                                        break;
                   1243:                                case DT_ENUM:
                   1244:                                        strcpy(dptr, "enum ");
                   1245:                                        dptr += 5;
                   1246:                        }
                   1247:                        while (*dptr++ = bget())
                   1248:                                ;
                   1249:                        membs = 0;
                   1250:                        break;
                   1251: 
                   1252:                case DX_MEMBS:
                   1253:                        level += 1;
                   1254:                        dptr = getmembs(&d, data, dptr);
                   1255:                        level -= 1;
                   1256:                        membs = 0;
                   1257:                        break;
                   1258: 
                   1259:                default:
                   1260:                        cbotch("getdbgt: %d", n);
                   1261:                }
                   1262:                /*
                   1263:                 * Terminate types.
                   1264:                 */
                   1265:                if (dptr + typet >= data + DSZ) {
                   1266:                        dbrpt("2", &d);
                   1267:                        cbotch("getdbgt buffer");
                   1268:                }
                   1269:                while (--typet >= 0)
                   1270:                        *dptr++ = 0;
                   1271:                break;
                   1272:        }
                   1273: 
                   1274:        /*
                   1275:         * Check level change.
                   1276:         */
                   1277:        if (data[0] == '{') {
                   1278:                if (level++ == 0) {
                   1279:                        d.d_level = level++;
                   1280:                        outbrace('{');
                   1281:                }
                   1282:        }
                   1283:        else if (data[0] == '}')
                   1284:                level -= 1;
                   1285: 
                   1286:        /*
                   1287:         * Copy into dynamic storage.
                   1288:         */
                   1289:        d.d_size = dptr - data;
                   1290:        return (newdbgt(&d, data));
                   1291: }
                   1292: 
                   1293: /*
                   1294:  * Read a list of members of a union/struct/enum.
                   1295:  * If struct/union, append member types to caller's buffer.
                   1296:  * If making a debug table:
                   1297:  * If struct/union tag definition, bracket member definitions.
                   1298:  * If enum tag, make member type into "enum tag".
                   1299:  */
                   1300: char *
                   1301: getmembs(dp0, bb, bp)
                   1302: struct dbgt *dp0;
                   1303: char *bb;
                   1304: register char *bp;
                   1305: {
                   1306:        int nmembs, n, istag, isenu, isgbl, isdbg;
                   1307:        char *sbp;
                   1308:        register struct dbgt *dp;
                   1309:        struct dbgt **dpp;
                   1310:        register char *p;
                   1311:        static struct dbgt dbrace = {
                   1312:                NULL,           /* d_dp */
                   1313:                -1,             /* d_ref */
                   1314:                DT_NONE,        /* d_class */
                   1315:                D_LCL,          /* d_flag */
                   1316:                0,              /* d_level */
                   1317:                TYPESYM,        /* d_seg */
                   1318:                0,              /* d_value */
                   1319:                3               /* d_size */
                   1320:        };
                   1321: 
                   1322:        dp = dp0;
                   1323:        nmembs = bget();
                   1324:        istag = (dp->d_flag&D_TAG) != 0;
                   1325:        isenu = (dp->d_flag&D_ENU) != 0;
                   1326:        isgbl = (dp->d_flag&D_GBL) != 0;
                   1327:        isdbg = (isvariant(VDSYMB) && isvariant(VTYPES)) != 0;
                   1328:        if (isenu) {
                   1329:                sbp = bp;
                   1330:                isenu = strlen(bb) + 1 + 1;
                   1331:        }
                   1332:        if ( ! isenu) {
                   1333:                *bp++ = 1;
                   1334:                *bp++ = nmembs;
                   1335:        }
                   1336:        dpp = &dp->d_dp;
                   1337:        if (istag && isdbg && ! isenu) {
                   1338:                dp = *dpp = newdbgt(&dbrace, "{\0\0");
                   1339:                if (isgbl)
                   1340:                        dp->d_flag ^= D_GBL|D_LCL;
                   1341:                dpp = &dp->d_dp;
                   1342:        }
                   1343:        while (--nmembs >= 0) {
                   1344:                dp = *dpp = getdbgt();
                   1345:                if (isgbl)
                   1346:                        dp->d_flag ^= D_GBL|D_LCL;
                   1347:                n = dp->d_size;
                   1348:                p = dp->d_data;
                   1349:                if (isenu && istag && isdbg) {
                   1350:                        dp->d_size += isenu;
                   1351:                        dp = newdbgt(dp, dp->d_data);
                   1352:                        bp = dp->d_data;
                   1353:                        while (*bp++)
                   1354:                                ;
                   1355:                        *bp++ = STRINGt;
                   1356:                        p = bb;
                   1357:                        while (*bp++ = *p++)
                   1358:                                ;
                   1359:                        *bp++ = 0;
                   1360:                        free(*dpp);
                   1361:                        *dpp = dp;
                   1362:                        bp = sbp;
                   1363:                }
                   1364:                if ( ! isenu) {
                   1365:                        do {
                   1366:                                --n;
                   1367:                        } while (*p++);
                   1368:                        *bp++ = TYPEt;
                   1369:                        if (bp + n >= bb + DSZ) {
                   1370:                                dbrpt("3", dp);
                   1371:                                cbotch("getdbgt buffer");
                   1372:                        }
                   1373:                        do {
                   1374:                                *bp++ = *p++;
                   1375:                        } while (--n > 0);
                   1376:                }
                   1377:                if (istag && isdbg)
                   1378:                        dpp = &dp->d_dp;
                   1379:                else
                   1380:                        free(*dpp);
                   1381:        }
                   1382:        if (istag && isdbg && ! isenu) {
                   1383:                dp = *dpp = newdbgt(&dbrace, "}\0\0");
                   1384:                if (isgbl)
                   1385:                        dp->d_flag ^= D_GBL|D_LCL;
                   1386:                dpp = &dp->d_dp;
                   1387:        }
                   1388:        *dpp = NULL;
                   1389:        return (bp);
                   1390: }
                   1391: 
                   1392: /*
                   1393:  * Output a debug brace
                   1394:  */
                   1395: outbrace(c)
                   1396: char c;
                   1397: {
                   1398:        struct dbgt *dp;
                   1399: 
                   1400:        if ((dp = (struct dbgt *)calloc(1, sizeof(struct dbgt) + 10)) == NULL)
                   1401:                cnomem("outbrace");
                   1402:        dp->d_class = DC_LINE;
                   1403:        dp->d_flag = D_LCL;
                   1404:        dp->d_seg = segindex[SCODE];
                   1405:        dp->d_value = ( dotseg == SCODE ? dot : seg[SCODE].s_dot);
                   1406:        dp->d_size = 10;
                   1407:        dp->d_data[0] = c;
                   1408:        *(dp->d_data + 2) = 6;
                   1409:        *(dp->d_data + 3) = dline;
                   1410:        *(dp->d_data + 4) = dline >> 8;
                   1411:        if (dnext != NULL)
                   1412:                dnext->d_dp = dp;
                   1413:        dnext = dp;
                   1414: }
                   1415: 
                   1416: struct dbgt *
                   1417: newdbgt(dp, cp)
                   1418: struct dbgt *dp;
                   1419: register char *cp;
                   1420: {
                   1421:        register struct dbgt *ndp;
                   1422:        register char *ncp;
                   1423:        register int n;
                   1424: 
                   1425:        n = dp->d_size;
                   1426:        if ((ndp = (struct dbgt *)malloc(sizeof(struct dbgt) + n)) == NULL)
                   1427:                cnomem("newdbgt");
                   1428:        *ndp = *dp;
                   1429:        for (ncp = ndp->d_data; --n >= 0; *ncp++ = *cp++)
                   1430:                ;
                   1431:        return (ndp);
                   1432: }
                   1433: 
                   1434: #if !TINY
                   1435: _dbrpt(p, dp)
                   1436: char *p;
                   1437: register struct dbgt *dp;
                   1438: {
                   1439:        if (xflag > 5) {
                   1440:                printf("%5s: %-10s %2x %2d %2x %2x %2x %04x %2x\n",
                   1441:                        p,
                   1442:                        dp->d_data,
                   1443:                        dp->d_class,
                   1444:                        dp->d_ref,
                   1445:                        dp->d_flag,
                   1446:                        dp->d_level,
                   1447:                        dp->d_seg,
                   1448:                        dp->d_value,
                   1449:                        dp->d_size
                   1450:                        );
                   1451:        }
                   1452: }
                   1453: 
                   1454: dbtyp(dp)
                   1455: struct dbgt *dp;
                   1456: {
                   1457:        register int n;
                   1458:        register char *p;
                   1459: 
                   1460:        if (xflag > 20) {
                   1461:                n = dp->d_size;
                   1462:                p = dp->d_data;
                   1463:                do {
                   1464:                        --n;
                   1465:                        putchar(*p);
                   1466:                } while (*p++);
                   1467:                while (--n >= 0) {
                   1468:                        if (*p == STRINGt) {
                   1469:                                putchar(' ');
                   1470:                                putchar('"');
                   1471:                                ++p;
                   1472:                                do {
                   1473:                                        --n;
                   1474:                                } while (putchar(*p++));
                   1475:                                putchar('"');
                   1476:                                continue;
                   1477:                        } else if (*p == TYPEt)
                   1478:                                printf(" TYPEt");
                   1479:                        else if (*p == ANYt)
                   1480:                                printf(" ANYt");
                   1481:                        else
                   1482:                                printf(" %o", *p&0377);
                   1483:                        ++p;
                   1484:                }
                   1485:                putchar('\n');
                   1486:        }
                   1487: }
                   1488: #endif

unix.superglobalmegacorp.com

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