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

1.1       root        1: /*
                      2:  * This file writes writes Intel iAPX-86 OMF with csd debugging information.
                      3:  * Based on outomf.c, but with MWC CSD-format debug info (as in outrel.c)
                      4:  * instead of Intel format.
                      5:  * The 'out...' routines write to a temporary file during code assembly.
                      6:  * At the end of assembly, 'copycode' uses the 'put...' routines
                      7:  * to write the object file.
                      8:  * This is necessary: SEGDEF records must be written before
                      9:  * LEDATA and FIXUPP records, but each SEGDEF includes the size
                     10:  * of the segment in bytes.
                     11:  * However, the size of the DEBUG segment is fixed up ex post facto.
                     12:  */
                     13: 
                     14: /*
                     15:  * Reference: "8086 Relocatable Object Formats,"
                     16:  * Intel 121748-001 (C) Intel 1981.
                     17:  */
                     18: 
                     19: #ifdef vax
                     20: #include "INC$LIB:cc2.h"
                     21: #include "INC$LIB:debug.h"
                     22: #else
                     23: #include "cc2.h"
                     24: #include "debug.h"
                     25: #endif
                     26: 
                     27: #define        NTXT    256                     /* Text buffer size */
                     28: #define        NREL    256                     /* Relocation buffer size */
                     29: 
                     30: #ifndef __LINE__
                     31: #define        __LINE__        0
                     32: #endif
                     33: 
                     34: #if !TINY
                     35: #define        dbrpt(x,y)      _dbrpt(x,y)
                     36: #else
                     37: #define        dbrpt(x,y)      /* _dbrpt(x,y) */
                     38: #endif
                     39: 
                     40: /*
                     41:  * Scratch file opcodes.
                     42:  * Flags are or'ed in to TBYTE and TWORD opcodes only.
                     43:  */
                     44: #define        TTYPE   0x07                    /* Type */
                     45: #define        TPCR    0x08                    /* PC rel flag */
                     46: #define        TSYM    0x10                    /* Symbol based flag */
                     47: 
                     48: #define        TEND    0x00                    /* End marker */
                     49: #define        TENTER  0x01                    /* Enter new area */
                     50: #define        TBYTE   0x02                    /* Byte data */
                     51: #define        TWORD   0x03                    /* Word data */
                     52: #define        TCODE   0x04                    /* Code segment base */
                     53: #define        TDATA   0x05                    /* Data segment base */
                     54: #define        TBASE   0x06                    /* External segment base */
                     55: #define        TDLAB   0x07                    /* Debug label */
                     56: #define        TDLOC   0x08                    /* Debug location */
                     57: 
                     58: #if    EMUFIXUPS
                     59: /*
                     60:  * If EMUFIXUPS is defined at compile time, the generated output writer
                     61:  * targets 8087 instructions with magic "M:..." fixups.
                     62:  * The linker can then create objects which use either 8087 hardware
                     63:  * or software floating point emulation; in the latter case, the
                     64:  * linker changes the 8087 instructions into traps to the emulator.
                     65:  */
                     66: #define        T8087   0xE0                    /* 8087 flags */
                     67: #define        TWT     0x20                    /* M:_WT  */
                     68: #define        TWST    0x40                    /* M:_WST */
                     69: #define        TWES    0x60                    /* M:_WES */
                     70: #define        TWCS    0x80                    /* M:_WCS */
                     71: #define        TWSS    0xA0                    /* M:_WSS */
                     72: #define        TWDS    0xC0                    /* M:_WDS */
                     73: #endif
                     74: 
                     75: /*
                     76:  * OMF types.
                     77:  */
                     78: #define        THEADR  0x80                    /* Translator module header */
                     79: #define        COMENT  0x88                    /* Comment */
                     80: #define        MODEND  0x8A                    /* Module end */
                     81: #define        EXTDEF  0x8C                    /* External definition (reference) */
                     82: #define        TYPDEF  0x8E                    /* Type definition */
                     83: #define        PUBDEF  0x90                    /* Public definition (definition) */
                     84: #define        LNAMES  0x96                    /* List of names */
                     85: #define        SEGDEF  0x98                    /* Segment definition */
                     86: #define        GRPDEF  0x9A                    /* Group definition */
                     87: #define        FIXUPP  0x9C                    /* Fixups */
                     88: #define        LEDATA  0xA0                    /* Enumerated data */
                     89: #define        LIDATA  0xA2                    /* Iterated data */
                     90: 
                     91: /*
                     92:  * Some OMF fields and flags.
                     93:  */
                     94: #define        BYTE    (0x01<<5)               /* Byte alignment */
                     95: #define        PARA    (0x03<<5)               /* Paragraph alignment */
                     96: #define        BIG     0x02                    /* 64k */
                     97: #define        CCON    (0x02<<2)               /* C field, concatenate */
                     98: #define        CMEM    (0x01<<2)               /* C field, memory */
                     99: #define        CSTACK  (0x05<<2)               /* C field, stack */
                    100: 
                    101: #define        LOCAT   0x80                    /* Locat flag bit */
                    102: #define        M       0x40                    /* M bit; 0=self rel, 1=seg rel */
                    103: #define        LOBYTE  (0x00<<2)               /* Locat */
                    104: #define        OFFSET  (0x01<<2)               /* Locat */
                    105: #define        BASE    (0x02<<2)               /* Locat */
                    106: #define        POINTER (0x03<<2)               /* Locat */
                    107: #define        HIBYTE  (0x04<<2)               /* Locat */
                    108: 
                    109: #define        SECWAY  0x04                    /* Secondary way */
                    110: #define        FD8087  0x36                    /* FIXDAT for 8087 fixup */
                    111: #define        FSI     (0<<4)                  /* Frame segment index */
                    112: #define        FGI     (1<<4)                  /* Frame group index */
                    113: #define        FEI     (2<<4)                  /* Frame external index */
                    114: #define        FFN     (3<<4)                  /* Frame frame number */
                    115: #define        FLSEG   (4<<4)                  /* Frame of LSEG */
                    116: #define        FTARGET (5<<4)                  /* Frame of TARGET object */
                    117: #define        FNONE   (6<<4)                  /* No frame */
                    118: #define        TSI     0                       /* Target: segment index */
                    119: #define        TGI     1                       /* Target: group index */
                    120: #define        TEI     2                       /* Target: external index */
                    121: #define        TFN     3                       /* Target: frame */
                    122: #define        F       0x80                    /* Frame thread used */
                    123: #define        T       0x08                    /* Target thread used */
                    124: #define        FT0     0x00                    /* 0 */
                    125: #define        FT1     0x10                    /* 1 */
                    126: 
                    127: #define        VCSD    (isvariant(VTYPES)||isvariant(VDSYMB))
                    128: 
                    129: /*
                    130:  * Structure to contain debug items on this pass.
                    131:  * Debug items are kept in a linked list rooted at 'dbase',
                    132:  * with 'dnext' pointing at the most recent item.
                    133:  */
                    134: struct dbgt {
                    135:        struct dbgt     *d_dp;          /* Link */
                    136:        int             d_ref;          /* Index number */
                    137:        unsigned char   d_class;        /* Storage class */
                    138:        unsigned char   d_flag;         /* Flags */
                    139:        unsigned char   d_level;        /* Bracket level */
                    140:        unsigned char   d_seg;          /* Reloc-style segment */
                    141:        unsigned char   d_cseg;         /* C Segment */
                    142:        ADDRESS         d_value;        /* Offset in segment */
                    143:        int             d_size;         /* Size of d_data */
                    144:        char            d_data[];       /* Name and type */
                    145: };
                    146: /* Flag bits. */
                    147: #define        D_GBL    1
                    148: #define        D_LCL    2
                    149: #define        D_TAG    4
                    150: #define        D_NAM    8
                    151: #define        D_LAB   16
                    152: #define        D_ENU   32
                    153: 
                    154: /*
                    155:  * Globals for output writer.
                    156:  */
                    157: static int     checksum;               /* For putrecord and putbyte */
                    158: static char    txt[NTXT+5];            /* Text buffer */
                    159: static char    rel[NREL];              /* Relocation buffer */
                    160: static ADDRESS code_size;              /* Size of CODE */
                    161: static ADDRESS data_size;              /* Size of DATA */
                    162: static ADDRESS const_size;             /* Size of CONST */
                    163: static ADDRESS bss_size;               /* Size of BSS */
                    164: static char    *txtp = txt;            /* Text pointer */
                    165: static char    *relp = rel;            /* Relocation pointer */
                    166: static struct dbgt     *dbase;         /* Root debug list item */
                    167: static struct dbgt     *dnext;         /* Last debug list item */
                    168: static int     level = 0;              /* Debug brace level */
                    169: static int     dline = 0;              /* Most recent line number entry */
                    170: 
                    171: #if    EMUFIXUPS
                    172: static int     has8087;                /* Has 8087 code flag */
                    173: static SYM     *wsp[6];                /* Links to emulator symbols */
                    174: #endif
                    175: 
                    176: #if    VAXFMT
                    177: /*
                    178:  * The Intel cross software packs the OMF
                    179:  * data into 512 byte blocks as 510 byte variable length
                    180:  * records, with the last record short.
                    181:  */
                    182: #define        NVDATA  510                     /* Blocksize - 2 */
                    183: static char    vaxbuf[NVDATA];         /* Buffer */
                    184: static char    *vaxptr = vaxbuf;       /* Pointer */
                    185: #endif
                    186: 
                    187: /*
                    188:  * Function declarations.
                    189:  */
                    190: extern char            *calloc();
                    191: extern long            ftell();
                    192: extern struct dbgt     *getdbgt();
                    193: extern char            *getmembs();
                    194: extern char            *malloc();
                    195: extern struct dbgt     *newdbgt();
                    196: extern long            putsegdef();
                    197: extern char            *setindex();
                    198: extern char            *setsymid();
                    199: extern char            *strcpy();
                    200: 
                    201: /*
                    202:  * These tables are indexed by a compiler segment name (SCODE et al)
                    203:  * to get an OMF segment index.
                    204:  * These tables understand the way the SSTRN segment moves
                    205:  * around when the ROM option is given, and
                    206:  * are dependent on the order of the calls to putsegdef() in copycode().
                    207:  */
                    208: static char    lnonseg[] = {
                    209:        1,                              /* SCODE => module_CODE */
                    210:        1,                              /* SLINK => module_CODE */
                    211:        1,                              /* SPURE => module_CODE */
                    212:        2,                              /* SSTRN => module_DATA */
                    213:        2,                              /* SDATA => module_DATA */
                    214:        2                               /* SBSS  => module_DATA */
                    215: };
                    216: 
                    217: static char    lromseg[] = {
                    218:        1,                              /* SCODE => module_CODE */
                    219:        1,                              /* SLINK => module_CODE */
                    220:        1,                              /* SPURE => module_CODE */
                    221:        1,                              /* SSTRN => module_CODE */
                    222:        2,                              /* SDATA => module_DATA */
                    223:        2                               /* SBSS  => module_DATA */
                    224: };
                    225: 
                    226: static char    lramseg[] = {
                    227:        1,                              /* SCODE => module_CODE */
                    228:        1,                              /* SLINK => module_CODE */
                    229:        2,                              /* SPURE => module_DATA */
                    230:        2,                              /* SSTRN => module_DATA */
                    231:        2,                              /* SDATA => module_DATA */
                    232:        2                               /* SBSS  => module_DATA */
                    233: };
                    234: 
                    235: static char    snonseg[] = {
                    236:        1,                              /* SCODE => CODE */
                    237:        1,                              /* SLINK => CODE */
                    238:        2,                              /* SPURE => CONST */
                    239:        3,                              /* SSTRN => DATA */
                    240:        3,                              /* SDATA => DATA */
                    241:        3                               /* SBSS  => DATA */
                    242: };
                    243: 
                    244: static char    sromseg[] = {
                    245:        1,                              /* SCODE => CODE */
                    246:        1,                              /* SLINK => CODE */
                    247:        2,                              /* SPURE => CONST */
                    248:        2,                              /* SSTRN => CONST */
                    249:        3,                              /* SDATA => DATA */
                    250:        3                               /* SDATA => DATA */
                    251: };
                    252: 
                    253: static char    sramseg[] = {
                    254:        1,                              /* SCODE => CODE */
                    255:        1,                              /* SLINK => CODE */
                    256:        3,                              /* SPURE => DATA */
                    257:        3,                              /* SSTRN => DATA */
                    258:        3,                              /* SDATA => DATA */
                    259:        3                               /* SDATA => DATA */
                    260: };
                    261: 
                    262: /*
                    263:  * Same game, but for group index codes.
                    264:  * This is used only in SMALL model.
                    265:  */
                    266: static char    grpindex[] = {
                    267:        1,                              /* SCODE => CGROUP */
                    268:        1,                              /* SLINK => CGROUP */
                    269:        2,                              /* SPURE => DGROUP */
                    270:        2,                              /* SSTRN => DGROUP */
                    271:        2,                              /* SDATA => DGROUP */
                    272:        2                               /* SBSS  => DGROUP */
                    273: };
                    274: 
                    275: /*
                    276:  * Some prefabricated OMF items.
                    277:  * These are just blasted out via calls to putrecord().
                    278:  */
                    279: static char    lthred[]        = { 0x40, 1,            /* module_CODE */
                    280:                                    0x41, 2 };          /* module_DATA */
                    281: static char    gdef1[]         = { 7, 0xFF, 1 };
                    282: static char    gdef2[]         = { 8, 0xFF, 2, 0xFF, 3, 0xFF, 4, 0xFF, 5 };
                    283: static char    sthred[]        = { 0x00, 1,            /* Code */
                    284:                                    0x01, 2,            /* Const */
                    285:                                    0x02, 3,            /* Data */
                    286:                                    0x44, 1,            /* Frame -> CGROUP */
                    287:                                    0x45, 2             /* Frame -> DGROUP */
                    288:                                };
                    289: static char    typdef[]        = { 0, 0, 0x80 };
                    290: static char    modend[]        = { 0x00 };
                    291: 
                    292: /*
                    293: ** First pass routines.
                    294: ** Output items to the temporary file.
                    295: */
                    296: /*
                    297:  * Initialize the code writer.
                    298:  */
                    299: outinit()
                    300: {
                    301: #if    MONOLITHIC
                    302: #if    EMUFIXUPS
                    303:        register int    i;
                    304: 
                    305:        has8087 = 0;
                    306:        for (i=0; i<6; ++i)
                    307:                wsp[i] = NULL;
                    308: #endif
                    309:        txtp = &txt[0];
                    310:        relp = &rel[0];
                    311:        dbase = dnext = NULL;
                    312: #if    VAXFMT
                    313:        vaxptr = &vaxbuf[0];
                    314: #endif
                    315: #endif
                    316: }
                    317: 
                    318: /*
                    319:  * Output a segment switch.
                    320:  */
                    321: outseg(s)
                    322: {
                    323:        bput(TENTER);
                    324:        bput(s);
                    325: }
                    326: 
                    327: /*
                    328:  * Output an absolute byte.
                    329:  */
                    330: outab(b)
                    331: {
                    332:        bput(TBYTE);
                    333:        bput(b);
                    334:        ++dot;
                    335: }
                    336: 
                    337: /*
                    338:  * Output an absolute word.
                    339:  */
                    340: outaw(w)
                    341: {
                    342:        bput(TWORD);
                    343:        iput(w);
                    344:        dot += 2;
                    345: }
                    346: 
                    347: /*
                    348:  * Output a full byte.
                    349:  */
                    350: outxb(sp, b, pcrf)
                    351: register SYM *sp;
                    352: {
                    353:        register opcode;
                    354: 
                    355:        opcode = TBYTE;
                    356:        if (sp != NULL)
                    357:                opcode |= TSYM;
                    358:        if (pcrf)
                    359:                opcode |= TPCR;
                    360:        bput(opcode);
                    361:        bput(b);
                    362:        if (sp != NULL)
                    363:                pput(sp);
                    364:        ++dot;
                    365: }
                    366: 
                    367: /*
                    368:  * Output a full word.
                    369:  */
                    370: outxw(sp, w, pcrf)
                    371: register SYM *sp;
                    372: {
                    373:        register opcode;
                    374: 
                    375:        opcode = TWORD;
                    376:        if (sp != NULL)
                    377:                opcode |= TSYM;
                    378:        if (pcrf)
                    379:                opcode |= TPCR;
                    380:        bput(opcode);
                    381:        iput(w);
                    382:        if (sp != NULL)
                    383:                pput(sp);
                    384:        dot += 2;
                    385: }
                    386: 
                    387: #if    EMUFIXUPS
                    388: /*
                    389:  * Output a one byte opcode for the 8087.
                    390:  */
                    391: outfb(b)
                    392: {
                    393:        has8087 = 1;
                    394:        bput(TBYTE|TWT);
                    395:        bput(b);
                    396:        ++dot;
                    397: }
                    398: 
                    399: /*
                    400:  * Output a two byte opcode for the 8087.
                    401:  */
                    402: outfw(w, prefix)
                    403: {
                    404:        has8087 = 1;
                    405:        bput(TWORD|((prefix>>3)+TWST));
                    406:        iput(w);
                    407:        dot += 2;
                    408: }
                    409: #endif
                    410: 
                    411: #if    0
                    412: /*
                    413:  * Because the compiler now generates LARGE model code with links,
                    414:  * the following routines are currently unused.
                    415:  * They are retained for future reference.
                    416:  */
                    417: /*
                    418:  * Output a 1 word object containing
                    419:  * the base address of the current code segment.
                    420:  */
                    421: outcb()
                    422: {
                    423:        bput(TCODE);
                    424:        dot += 2;
                    425: }
                    426: 
                    427: /*
                    428:  * Output a 1 word object containing
                    429:  * the base address of the current data segment.
                    430:  */
                    431: outdb()
                    432: {
                    433:        bput(TDATA);
                    434:        dot += 2;
                    435: }
                    436: #endif
                    437: 
                    438: /*
                    439:  * Output a 1 word object containing
                    440:  * the base address of the external symbol pointed to by 'sp'.
                    441:  */
                    442: outsb(sp)
                    443: SYM *sp;
                    444: {
                    445:        bput(TBASE);
                    446:        pput(sp);
                    447:        dot += 2;
                    448: }
                    449: 
                    450: /*
                    451:  * Copy a dlabel record from ifp to ofp.
                    452:  * Flag the symbol table entry if appropriate.
                    453:  * Recursive for DX_MEMBS member lists.
                    454:  */
                    455: outdlab(l,class)
                    456: {
                    457:        register int val;
                    458:        register SYM *sp;
                    459:        int n;
                    460: 
                    461:        if (l == 0)
                    462:                bput(TDLAB);
                    463:        bput(class);
                    464: 
                    465:        /* Get line number. */
                    466:        iput(iget());
                    467: 
                    468:        /* Get value */
                    469:        if (class < DC_AUTO)
                    470:                ;
                    471:        else if (class < DC_MOS)
                    472:                iput(val = iget());
                    473:        else {
                    474:                bput(bget());
                    475:                bput(bget());
                    476:                iput(iget());
                    477:        }
                    478: 
                    479:        /* Get name */
                    480:        sget(id, NCSYMB);
                    481: 
                    482:        /* Check for symbol table entry */
                    483:        if (class==DC_GDEF || class==DC_SEX || class==DC_GREF) {
                    484:                sp = glookup(id, 0);
                    485:                sp->s_flag |= S_PUT;
                    486:        } else if (class==DC_SIN) {
                    487:                sp = llookup(val, 0);
                    488:                sp->s_flag |= S_PUT;
                    489:        }
                    490: 
                    491:        /* Put name */
                    492:        sput(id);
                    493: 
                    494:        /* Get type */
                    495:        for (;;) {
                    496:                switch (bput(bget())) {
                    497:                case DT_NONE:
                    498:                case DT_CHAR:
                    499:                case DT_UCHAR:
                    500:                case DT_SHORT:
                    501:                case DT_USHORT:
                    502:                case DT_INT:
                    503:                case DT_UINT:
                    504:                case DT_LONG:
                    505:                case DT_ULONG:
                    506:                case DT_FLOAT:
                    507:                case DT_DOUBLE:
                    508:                case DT_VOID:
                    509:                        iput(iget());
                    510:                        break;
                    511:                case DT_STRUCT:
                    512:                case DT_UNION:
                    513:                case DT_ENUM:
                    514:                case DD_PTR:
                    515:                case DD_FUNC:
                    516:                case DD_ARRAY:
                    517:                        iput(iget());
                    518:                        continue;
                    519:                        break;
                    520:                case DX_MEMBS:
                    521:                        bput(n = iget());
                    522:                        for ( ; n > 0; n-=1) {
                    523:                                outdlab(1, bget());
                    524:                        }
                    525:                        break;
                    526:                case DX_NAME:
                    527:                        iget();
                    528:                        sget(id, NCSYMB);
                    529:                        sput(id);
                    530:                        break;
                    531:                default:
                    532:                        cbotch("outdlab: %d", n);
                    533:                }
                    534:                break;
                    535:        }
                    536: }
                    537: 
                    538: #if    0                       /* This routine is apparently unused. */
                    539: /*
                    540:  * Output a debug line record.
                    541:  */
                    542: outdlin(op)
                    543: {
                    544:        bput(TDLAB);
                    545:        bput(DC_LINE);
                    546:        iput(line);
                    547:        bput(op);
                    548:        bput(0);
                    549:        bput(DT_NONE);
                    550:        iput(0);
                    551: }
                    552: #endif
                    553: 
                    554: /*
                    555:  * Output a debug relocation record.
                    556:  * This 'n' is an index into the list of debug records written.
                    557:  */
                    558: outdloc(n)
                    559: {
                    560:        bput(TDLOC);
                    561:        iput(n);
                    562: }
                    563: 
                    564: /*
                    565:  * Finish up the code.
                    566:  * Some old outrel.c code is retained below for reference.
                    567:  */
                    568: outdone()
                    569: {
                    570: #if    0
                    571:        register SYM *sp;
                    572:        register int i;
                    573: #endif
                    574: 
                    575:        if (isvariant(VASM))
                    576:                return;
                    577: 
                    578: #if    0
                    579:        /*
                    580:         * Make dlabel items for internally generated symbols.
                    581:         */
                    582:        for (i = 0; i < NSHASH; i++) {
                    583:                for (sp = hash2[i]; sp != NULL; sp = sp->s_fp) {
                    584:                        if (((sp->s_flag&S_GBL) != 0 || (sp->s_flag&S_DEF) == 0)
                    585:                         && ((sp->s_flag&S_PUT) == 0)) {
                    586:                                bput(TDLAB);
                    587:                                bput(DC_GREF);
                    588:                                iput(0);
                    589:                                sput(sp->s_id);
                    590:                                bput(DT_NONE);
                    591:                                iput(0);
                    592:                        }
                    593:                }
                    594:        }
                    595: #endif
                    596: 
                    597: #if    EMUFIXUPS
                    598:        /*
                    599:         * Put magic names into the symbol table
                    600:         * if any 8087 code was generated.
                    601:         */
                    602:        if (has8087) {
                    603:                wsp[0] = glookup("M:_WT",  0);
                    604:                wsp[1] = glookup("M:_WST", 0);
                    605:                wsp[2] = glookup("M:_WES", 0);
                    606:                wsp[3] = glookup("M:_WCS", 0);
                    607:                wsp[4] = glookup("M:_WSS", 0);
                    608:                wsp[5] = glookup("M:_WDS", 0);
                    609:        }
                    610: #endif
                    611:        bput(TEND);
                    612: }
                    613: 
                    614: /*
                    615: ** Second pass routines.
                    616: ** Read the temporary file and write the output.
                    617: */
                    618: /*
                    619:  * Finish up.
                    620:  * Figure out the sizes and final values of everything.
                    621:  * Copy the code from the scratch file back to the output file.
                    622:  */
                    623: copycode()
                    624: {
                    625:        register int    op;
                    626:        register SYM    *sp;
                    627:        register int    i;
                    628:        register ADDRESS v;
                    629:        int             fixup;
                    630:        int             nd;
                    631:        int             nr;
                    632:        int             data;
                    633:        char            coment[30];
                    634:        long            debugdef;
                    635: 
                    636:        /*
                    637:         * Assign base addresses to the compiler's logical segments, based on
                    638:         * the compilation model and the settings of the VROM and VRAM flags.
                    639:         */
                    640:        seg[SCODE].s_mseek = 0;
                    641:        v  = rup(seg[SCODE].s_dot);
                    642:        seg[SLINK].s_mseek = v;
                    643:        v += rup(seg[SLINK].s_dot);
                    644:        if ((isvariant(VSMALL))  || (isvariant(VRAM))) {
                    645:                code_size = v;
                    646:                v = 0;
                    647:        }
                    648:        seg[SPURE].s_mseek = v;
                    649:        v += rup(seg[SPURE].s_dot);
                    650:        if (notvariant(VROM) && notvariant(VRAM)) {
                    651:                if (isvariant(VSMALL))
                    652:                        const_size = v;
                    653:                else
                    654:                        code_size  = v;
                    655:                v = 0;
                    656:        }
                    657:        seg[SSTRN].s_mseek = v;
                    658:        v += rup(seg[SSTRN].s_dot);
                    659:        if (isvariant(VROM)) {
                    660:                if (isvariant(VSMALL))
                    661:                        const_size = v;
                    662:                else
                    663:                        code_size  = v;
                    664:                v = 0;
                    665:        }
                    666:        seg[SDATA].s_mseek = v;
                    667:        v += rup(seg[SDATA].s_dot);
                    668:        seg[SBSS].s_mseek  = v;
                    669:        bss_size  = rup(seg[SBSS].s_dot);
                    670:        data_size = v + bss_size;
                    671: 
                    672:        /*
                    673:         * Put out the preamble.
                    674:         */
                    675:        puttheadr();                                            /* THEADR */
                    676:        coment[0] = coment[1] = '\0';
                    677:        sprintf(&coment[2], "%s %s %s %s",
                    678: #ifdef vax
                    679:                "VAX",
                    680: #else
                    681: #ifdef UDI
                    682:                "UDI",
                    683: #else
                    684: #ifdef MSDOS
                    685:                "MS-DOS",
                    686: #else
                    687:                "COHERENT",
                    688: #endif
                    689: #endif
                    690: #endif
                    691:                "MWC86", VERSMWC,
                    692:                (isvariant(VSMALL)) ? "SMALL" : "LARGE");
                    693:        putrecord(COMENT, coment, strlen(&coment[2])+2);        /* COMENT */
                    694:        putlnames();                                            /* LNAMES */
                    695:        if (isvariant(VLARGE)) {
                    696:                putsegdef(PARA|CCON, code_size, 2, 4);          /* [1] */
                    697:                putsegdef(PARA|CCON, data_size, 3, 5);          /* [2] */
                    698:                if (VCSD)
                    699:                        debugdef = putsegdef(BYTE|CCON, 0, 7, 6); /* [3] */
                    700:        } else {
                    701:                putsegdef(BYTE|CCON, code_size,  2, 2);         /* [1] */
                    702:                putsegdef(BYTE|CCON, const_size, 4, 4);         /* [2] */
                    703:                putsegdef(BYTE|CCON, data_size,  3, 3);         /* [3] */
                    704:                putsegdef(PARA|CSTACK,       0,  5, 5);         /* [4] */
                    705:                putsegdef(PARA|CMEM,         0,  6, 6);         /* [5] */
                    706:                if (VCSD)
                    707:                        debugdef = putsegdef(BYTE|CCON, 0,  10, 9);     /* [6] */
                    708:                putrecord(GRPDEF, gdef1, sizeof(gdef1));        /* [1] */
                    709:                putrecord(GRPDEF, gdef2, sizeof(gdef2));        /* [2] */
                    710:        }
                    711:        putrecord(TYPDEF, typdef, sizeof(typdef));              /* TYPDEF */
                    712:        if (isvariant(VLARGE))
                    713:                putrecord(FIXUPP, lthred, sizeof(lthred));
                    714:        else
                    715:                putrecord(FIXUPP, sthred, sizeof(sthred));      /* Threads */
                    716:        putsymdef();                                    /* PUBDEF, EXTDEF */
                    717: 
                    718:        /*
                    719:         * Copy out code.
                    720:         */
                    721:        for (i=0; i<NSEG; ++i)
                    722:                seg[i].s_dot = seg[i].s_mseek;
                    723:        dotseg = SCODE;
                    724:        dot = seg[SCODE].s_dot;
                    725:        while ((op = bget()) != TEND) {
                    726:                switch (op) {
                    727: 
                    728:                case TENTER:
                    729:                        notenuf();
                    730:                        enter(bget());
                    731:                        continue;
                    732:                case TDLAB:
                    733:                        getdlab();
                    734:                        continue;
                    735:                case TDLOC:
                    736:                        getdloc();
                    737:                        continue;
                    738: #if    0
                    739: /* See comment on outcb()/outdb() above. */
                    740:                case TCODE:
                    741:                case TDATA:
                    742:                        if (isvariant(VSMALL))
                    743:                                cbotch("code:data");
                    744:                        enuf(2, 4);
                    745:                        fixup = txtp - (txt+3);
                    746:                        *txtp++ = 0;
                    747:                        *txtp++ = 0;
                    748:                        *relp++ = LOCAT|M|BASE|(fixup>>8);
                    749:                        *relp++ = fixup;
                    750:                        *relp++ = FTARGET|SECWAY|TSI;
                    751:                        *relp++ = (op==TCODE) ? 1 : 2;
                    752:                        dot += 2;
                    753:                        continue;
                    754: #endif
                    755:                case TBASE:
                    756:                        if (isvariant(VSMALL))
                    757:                                cbotch("base");
                    758:                        sp = pget();
                    759:                        if ((sp->s_flag&S_DEF) != 0) {
                    760:                                enuf(2, 4);
                    761:                                fixup = txtp - (txt+3);
                    762:                                *txtp++ = 0;
                    763:                                *txtp++ = 0;
                    764:                                *relp++ = LOCAT|M|BASE|(fixup>>8);
                    765:                                *relp++ = fixup;
                    766:                                *relp++ = FTARGET|SECWAY|TSI;
                    767:                                *relp++ = getsegindex(sp->s_seg);
                    768:                                dot += 2;
                    769:                                continue;
                    770:                        }
                    771:                        nr = 4;
                    772:                        if (sp->s_ref >= 128)
                    773:                                ++nr;
                    774:                        enuf(2, nr);
                    775:                        fixup = txtp - (txt+3);
                    776:                        *txtp++ = 0;
                    777:                        *txtp++ = 0;
                    778:                        *relp++ = LOCAT|M|BASE|(fixup>>8);
                    779:                        *relp++ = fixup;
                    780:                        *relp++ = FTARGET|SECWAY|TEI;
                    781:                        relp = setindex(relp, sp->s_ref);
                    782:                        dot += 2;
                    783:                        continue;
                    784:                }
                    785:                if ((op&TTYPE) == TBYTE) {
                    786:                        nd = 1;
                    787:                        data = bget();
                    788:                } else {
                    789:                        nd = 2;
                    790:                        data = iget();
                    791:                }
                    792: #if    EMUFIXUPS
                    793:                /*
                    794:                 * 8087 opcodes.
                    795:                 * Apply magic relocation for the emulator.
                    796:                 */
                    797:                if ((op&T8087) != 0) {
                    798:                        sp = wsp[((op&T8087)-TWT)>>5];
                    799:                        nr = 6;
                    800:                        if (sp->s_ref >= 128)
                    801:                                ++nr;
                    802:                        enuf(nd, nr);
                    803:                        fixup = txtp - (txt+3);
                    804:                        *txtp++ = data;
                    805:                        if (nd != 1) {
                    806:                                *txtp++ = data >> 8;
                    807:                                fixup |= OFFSET << 8;   /* Locat */
                    808:                        }
                    809:                        fixup |= M << 8;                /* Seg rel */
                    810:                        *relp++ = (fixup>>8) | LOCAT;   /* Not thread */
                    811:                        *relp++ = fixup;
                    812:                        *relp++ = FD8087;               /* Symbol based */
                    813:                        *relp++ = 0;                    /* Frame # */
                    814:                        *relp++ = 0;
                    815:                        relp = setindex(relp, sp->s_ref);
                    816:                        dot += nd;
                    817:                        continue;
                    818:                }
                    819: #endif
                    820:                /*
                    821:                 * Absolute.
                    822:                 */
                    823:                if ((op&(TSYM|TPCR)) == 0) {
                    824:                        enuf(nd, 0);
                    825:                        *txtp++ = data;
                    826:                        if (nd != 1)
                    827:                                *txtp++ = data >> 8;
                    828:                        dot += nd;
                    829:                        continue;
                    830:                }
                    831:                /*
                    832:                 * Absolute PC rel.
                    833:                 */
                    834:                if ((op&TSYM) == 0) {
                    835:                        enuf(nd, 6);
                    836:                        fixup = txtp - (txt+3);
                    837:                        *txtp++ = 0;
                    838:                        if (nd != 1) {
                    839:                                *txtp++ = 0;
                    840:                                fixup |= OFFSET << 8;
                    841:                        }
                    842:                        *relp++ = (fixup>>8) | LOCAT;   /* Not thread */
                    843:                        *relp++ = fixup;
                    844:                        *relp++ = FTARGET|TFN;          /* Absolute frame */
                    845:                        *relp++ = 0;                    /* Frame number */
                    846:                        *relp++ = data;                 /* Disp */
                    847:                        *relp++ = data >> 8;
                    848:                        dot += nd;
                    849:                        continue;
                    850:                }
                    851:                /*
                    852:                 * Symbol based.
                    853:                 * I would like to always do this
                    854:                 * in the primary way. However, LINK-86
                    855:                 * doesn't do 3 byte offsets, so I cannot
                    856:                 * do a negative one.
                    857:                 */
                    858:                sp = pget();
                    859:                if ((sp->s_flag&S_DEF) != 0) {
                    860:                        data += sp->s_value;
                    861:                        /* Absolute */
                    862:                        if ((op&TPCR)!=0 && sp->s_seg==dotseg) {
                    863:                                enuf(nd, 0);
                    864:                                data -= dot+nd;
                    865:                                *txtp++ = data;
                    866:                                if (nd != 1)
                    867:                                        *txtp++ = data >> 8;
                    868:                                dot += nd;
                    869:                                continue;
                    870:                        }
                    871:                        /* Segment relative */
                    872:                        enuf(nd, 6);
                    873:                        fixup = txtp - (txt+3);
                    874:                        *txtp++ = 0;
                    875:                        if (nd != 1) {
                    876:                                *txtp++ = 0;
                    877:                                fixup |= OFFSET << 8;   /* Loc */
                    878:                        }
                    879:                        if ((op&TPCR) == 0)
                    880:                                fixup |= M << 8;        /* Seg rel */
                    881:                        *relp++ = (fixup>>8) | LOCAT;   /* Not thread */
                    882:                        *relp++ = fixup;
                    883:                        fixup = F|FT0|TSI;              /* F code, seg ind */
                    884:                        if (getsegindex(sp->s_seg) != 1)
                    885:                                fixup |= FT1;           /* F data */
                    886:                        *relp++ = fixup;
                    887:                        *relp++ = getsegindex(sp->s_seg);
                    888:                        *relp++ = data;                 /* Disp */
                    889:                        *relp++ = data >> 8;
                    890:                        dot += nd;
                    891:                        continue;
                    892:                }
                    893:                /*
                    894:                 * Symbol relative.
                    895:                 */
                    896:                nr = 4;
                    897:                if (sp->s_ref >= 128)                   /* Two byte index */
                    898:                        ++nr;
                    899:                enuf(nd, nr);
                    900:                fixup = txtp - (txt+3);
                    901:                *txtp++ = data;
                    902:                if (nd != 1) {
                    903:                        *txtp++ = data >> 8;
                    904:                        fixup |= OFFSET << 8;           /* Loc */
                    905:                }
                    906:                if ((op&TPCR) == 0)
                    907:                        fixup |= M << 8;                /* Seg rel */
                    908:                *relp++ = LOCAT|(fixup>>8);             /* Not THREAD */
                    909:                *relp++ = fixup;
                    910:                *relp++ = FTARGET|SECWAY|TEI;           /* Fix dat */
                    911:                relp = setindex(relp, sp->s_ref);
                    912:                dot += nd;
                    913:        }
                    914:        if (isvariant(VLINES))
                    915:                outbrace('}');
                    916:        if (notvariant(VLIB))
                    917:                dump();
                    918:        if (VCSD)
                    919:                oglobals();                             /* Dump globals */
                    920:        enter(SDATA);                                   /* flush */
                    921:        /*
                    922:         * If the size of the SBSS segment is nonzero,
                    923:         * use an LIDATA item to get it zeroed when the program is run.
                    924:         */
                    925:        if (bss_size != 0) {
                    926:                txtp = &txt[0];
                    927:                *txtp++ = (isvariant(VSMALL)) ? 3 : 2;  /* DATA */
                    928:                *txtp++ = seg[SBSS].s_mseek;            /* Offset */
                    929:                *txtp++ = seg[SBSS].s_mseek >> 8;
                    930:                *txtp++ = bss_size;                     /* Length of loop */
                    931:                *txtp++ = bss_size >> 8;
                    932:                *txtp++ = 0;
                    933:                *txtp++ = 0;
                    934:                *txtp++ = 1;
                    935:                *txtp++ = 0;
                    936:                putrecord(LIDATA, txt, 9);              /* LIDATA */
                    937:        }
                    938:        putrecord(MODEND, modend, sizeof(modend));      /* MODEND */
                    939: #if VAXFMT
                    940:        vaxflush();
                    941: #endif
                    942:        if (VCSD) {
                    943:                if (fseek(ofp, debugdef, 0) == -1)
                    944:                        cbotch("fixsegdef seek failed");
                    945:                if (isvariant(VLARGE))
                    946:                        putsegdef(BYTE|CCON, seg[SDBG].s_dot, 7, 6);
                    947:                else
                    948:                        putsegdef(BYTE|CCON, seg[SDBG].s_dot, 10, 9);
                    949:        }
                    950: }
                    951: 
                    952: /*
                    953: ** Header writing routines.
                    954: */
                    955: /*
                    956:  * Put out a THEADR item.
                    957:  * The name is just the module name that the compiler has been keeping.
                    958:  * It must be mapped into upper case before writing it to the file.
                    959:  */
                    960: puttheadr()
                    961: {
                    962:        register char *p1, *p2;
                    963:        register c;
                    964:        char b[40];
                    965: 
                    966:        p1 = module;
                    967:        p2 = &b[0];
                    968:        *p2++ = strlen(p1);
                    969:        while ((c = *p1++) != '\0') {
                    970: #if    0
                    971:                if (c>='a' && c<='z')
                    972:                        c -= 'a'-'A';
                    973: #endif
                    974:                *p2++ = c;
                    975:        }
                    976:        putrecord(THEADR, b, p2-b);
                    977: }
                    978: 
                    979: /*
                    980:  * Write the list of names record.
                    981:  * For SMALL model, write the standard 'lnames' record:
                    982:  *     [1]  ""
                    983:  *     [2]  "CODE"
                    984:  *     [3]  "DATA"
                    985:  *     [4]  "CONST"
                    986:  *     [5]  "STACK"
                    987:  *     [6]  "MEMORY"
                    988:  *     [7]  "CGROUP"
                    989:  *     [8]  "DGROUP"
                    990:  *     [9]  "DEBUG"            (if -VCSD)
                    991:  *     [10] "module_DEBUG"     (if -VCSD)
                    992:  * For LARGE model, the names are:
                    993:  *     [1]  ""
                    994:  *     [2]  "module_CODE"
                    995:  *     [3]  "module_DATA"
                    996:  *     [4]  "CODE"
                    997:  *     [5]  "DATA"
                    998:  *     [6]  "DEBUG"            (if -VCSD)
                    999:  *     [7]  "module_DEBUG"     (if -VCSD)
                   1000:  */
                   1001: putlnames()
                   1002: {
                   1003:        register char *p1;
                   1004:        char *movelname();
                   1005:        char b[1 + 1+40+5 + 1+40+5 + 1+4 + 1+4 + 1+5 + 1+40+6];
                   1006: 
                   1007:        p1 = &b[0];
                   1008:        *p1++ = 0;                                      /* "" */
                   1009:        if (isvariant(VSMALL)) {
                   1010:                p1 = movelname(p1, "CODE", 0);
                   1011:                p1 = movelname(p1, "DATA", 0);
                   1012:                p1 = movelname(p1, "CONST", 0);
                   1013:                p1 = movelname(p1, "STACK", 0);
                   1014:                p1 = movelname(p1, "MEMORY", 0);
                   1015:                p1 = movelname(p1, "CGROUP", 0);
                   1016:                p1 = movelname(p1, "DGROUP", 0);
                   1017:        } else {
                   1018:                p1 = movelname(p1, "CODE", 1);
                   1019:                p1 = movelname(p1, "DATA", 1);
                   1020:                p1 = movelname(p1, "CODE", 0);
                   1021:                p1 = movelname(p1, "DATA", 0);
                   1022:        }
                   1023:        if (VCSD) {
                   1024:                p1 = movelname(p1, "DEBUG", 0);
                   1025:                p1 = movelname(p1, "DEBUG", 1);
                   1026:        }
                   1027:        putrecord(LNAMES, b, p1-b);
                   1028: }
                   1029: 
                   1030: /*
                   1031:  * If flag==0, move p2 to the supplied buffer p1.
                   1032:  * If flag==1, move module_p2 to p1.
                   1033:  * Used by putlnames().
                   1034:  */
                   1035: char *
                   1036: movelname(p1, p2, flag)
                   1037: register char *p1;
                   1038: char *p2;
                   1039: {
                   1040:        register char *p3;
                   1041:        register c;
                   1042: 
                   1043:        p3 = module;
                   1044:        if (flag) {
                   1045:                *p1++ = strlen(p3) + 1 + strlen(p2);    /* length of "module_p2" */
                   1046:                while ((c = *p3++) != '\0') {           /* copy module name */
                   1047: #if    0
                   1048:                        if (c>='a' && c<='z')
                   1049:                                c -= 'a'-'A';
                   1050: #endif
                   1051:                        *p1++ = c;
                   1052:                }
                   1053:                *p1++ = '_';                            /* append '_' */
                   1054:        } else
                   1055:                *p1++ = strlen(p2);
                   1056:        p3 = p2;
                   1057:        while ((c = *p3++) != '\0')                     /* copy p2 */
                   1058:                *p1++ = c;
                   1059:        return (p1);
                   1060: }
                   1061: 
                   1062: /*
                   1063:  * This routine formats and outputs a SEGDEF item.
                   1064:  * There is no checking for BIG segments (segments that are 64k in size).
                   1065:  * The overlay index points to a null name.
                   1066:  * Return the location of the first byte of the record.
                   1067:  */
                   1068: long
                   1069: putsegdef(flag, size, segi, classi)
                   1070: {
                   1071:        long l;
                   1072:        register char *bp;
                   1073:        char b[6];
                   1074: 
                   1075:        l = ftell(ofp);
                   1076:        bp = &b[0];
                   1077:        *bp++ = flag;
                   1078:        *bp++ = size;
                   1079:        *bp++ = size >> 8;
                   1080:        *bp++ = segi;
                   1081:        *bp++ = classi;
                   1082:        *bp++ = 1;
                   1083:        putrecord(SEGDEF, b, 6);
                   1084:        return(l);
                   1085: }
                   1086: 
                   1087: /*
                   1088:  * Sweep through the symbol table:
                   1089:  *     1) Make symbols LSEG relative.
                   1090:  *     2) Assign reference numbers.
                   1091:  *     3) Output EXTDEF or PUBDEF.
                   1092:  */
                   1093: putsymdef()
                   1094: {
                   1095:        register SYM *sp;
                   1096:        register int refnum;
                   1097:        register int i;
                   1098: 
                   1099:        refnum = 1;
                   1100:        for (i=0; i<NSHASH; ++i) {
                   1101:                for (sp = hash2[i]; sp != NULL; sp = sp->s_fp ) {
                   1102:                        if ((sp->s_flag&S_DEF) != 0)
                   1103:                                sp->s_value += seg[sp->s_seg].s_mseek;
                   1104:                        if ((sp->s_flag&S_GBL)!=0 || (sp->s_flag&S_DEF)==0) {
                   1105:                                sp->s_ref = 0;
                   1106:                                if ((sp->s_flag&S_DEF) != 0) {
                   1107:                                        putpubdef(sp);
                   1108:                                } else {
                   1109:                                        sp->s_ref = refnum++;
                   1110:                                        putextdef(sp);
                   1111:                                }
                   1112:                        }
                   1113:                }
                   1114:        }
                   1115: }
                   1116: 
                   1117: /*
                   1118:  * Put out a PUBDEF item for symbol 'sp'.
                   1119:  * All defs are tagged with the group
                   1120:  * so that a FTARGET,EI fixup can determine the correct frame.
                   1121:  */
                   1122: putpubdef(sp)
                   1123: register SYM *sp;
                   1124: {
                   1125:        register char *bp;
                   1126:        char b[1+1+40+2+1];
                   1127: 
                   1128:        bp = &b[0];
                   1129:        *bp++ = getgrpindex(sp->s_seg);
                   1130:        *bp++ = getsegindex(sp->s_seg);
                   1131:        bp = setsymid(bp, sp->s_id);
                   1132:        *bp++ = sp->s_value;
                   1133:        *bp++ = sp->s_value >> 8;
                   1134:        *bp++ = 1;
                   1135:        putrecord(PUBDEF, b, bp-b);
                   1136: }
                   1137: 
                   1138: /*
                   1139:  * Put out an EXTDEF item for symbol 'sp'.
                   1140:  */
                   1141: putextdef(sp)
                   1142: register SYM *sp;
                   1143: {
                   1144:        register char *bp;
                   1145:        char b[40+2];
                   1146: 
                   1147:        bp = setsymid(b, sp->s_id);
                   1148:        *bp++ = 1;
                   1149:        putrecord(EXTDEF, b, bp-b);
                   1150: }
                   1151: 
                   1152: /*
                   1153:  * Translate compiler segment codes
                   1154:  * to OMF segment index value, using tables.
                   1155:  * The table is selected by the model and the
                   1156:  * setting of the VROM and VRAM variants.
                   1157:  */
                   1158: getsegindex(s)
                   1159: register int   s;
                   1160: {
                   1161:        if (s > SBSS) {
                   1162:                if (s == SDBG)
                   1163:                        return(isvariant(VSMALL) ? 6 : 3);
                   1164:                else
                   1165:                        cbotch("getsegindex, seg=%d", s);
                   1166:        }
                   1167:        if (isvariant(VSMALL))
                   1168:                return(  (isvariant(VRAM))  ? sramseg[s]
                   1169:                       : (notvariant(VROM)) ? snonseg[s]
                   1170:                                            : sromseg[s]);
                   1171:        else
                   1172:                return(  (isvariant(VRAM))  ? lramseg[s]
                   1173:                       : (notvariant(VROM)) ? lnonseg[s]
                   1174:                                            : lromseg[s]);
                   1175: }
                   1176: 
                   1177: /*
                   1178:  * Like getsegindex(), but returns a reloc-type segment name for CSD.
                   1179:  */
                   1180: segindex(s) register int s;
                   1181: {
                   1182:        register int seg;
                   1183: 
                   1184:        seg = getsegindex(s);           /* Map to output segment */
                   1185:        if (isvariant(VSMALL)) {
                   1186:                if (seg == 1)
                   1187:                        return(PURCODE);
                   1188:                else if (seg == 2 || seg == 3)
                   1189:                        return(PURDATA);
                   1190:        } else {
                   1191:                if (seg == 1)
                   1192:                        return(PURCODE);
                   1193:                else if (seg == 2)
                   1194:                        return(PURDATA);
                   1195:        }
                   1196:        cbotch("segindex, s=%x, seg=%x\n", s, seg);
                   1197: }
                   1198:        
                   1199: /*
                   1200:  * Translate compiler segment codes
                   1201:  * to OMF group index value, using table and model.
                   1202:  */
                   1203: getgrpindex(s)
                   1204: register int s;
                   1205: {
                   1206:        return (isvariant(VSMALL) ? grpindex[s] : 0);
                   1207: }
                   1208: 
                   1209: /*
                   1210: ** Debug information processors.
                   1211: */
                   1212: /*
                   1213:  * Read debug table item(s) into memory.
                   1214:  */
                   1215: getdlab()
                   1216: {
                   1217:        register struct dbgt *dp;
                   1218:        static int refnum = 0;
                   1219: 
                   1220:        dp = getdbgt();
                   1221: 
                   1222:        /* This should be done in cc0 */
                   1223: 
                   1224:        if (isvariant(VLIB)) {
                   1225:                switch (dp->d_class) {
                   1226:                        case DC_TYPE:
                   1227:                        case DC_STAG:
                   1228:                        case DC_UTAG:
                   1229:                        case DC_ETAG:
                   1230:                                return;
                   1231:                }
                   1232:        }
                   1233:        if (dp->d_class == DC_LINE || dp->d_class == DC_LAB)
                   1234:                dp->d_ref = refnum;
                   1235: 
                   1236:        refnum += 1; 
                   1237:        if (dbase  == NULL)
                   1238:                dbase = dp;
                   1239:        if (dnext != NULL)
                   1240:                dnext->d_dp = dp;
                   1241:        dbrpt("enter", dp);
                   1242:        while (dp->d_dp != NULL) {
                   1243:                dp = dp->d_dp;
                   1244:                dbrpt("enter", dp);
                   1245:        }
                   1246:        dnext = dp;
                   1247:        if (dp->d_class == DC_FILE)
                   1248:                outbrace('{');  
                   1249: }
                   1250: 
                   1251: /*
                   1252:  * Read in debug items translating into loader type syntax.
                   1253:  * Member definitions are fetched recursively.
                   1254:  * If a tag or type definition, the member definitions are appended to the
                   1255:  * node surrounded by "{" and "}" nodes.
                   1256:  * If not a tag definition, the member definitions are discarded.
                   1257:  * In either case, the member types are appended to the type of the
                   1258:  * parent node.
                   1259:  */
                   1260: #define        DSZ 512
                   1261: struct dbgt *
                   1262: getdbgt()
                   1263: {
                   1264:        register int n;
                   1265:        register char *dptr;
                   1266:        struct dbgt d;
                   1267:        char data[DSZ];
                   1268:        int value, width, offs;
                   1269:        int typet, subt, membs;
                   1270:        char *sdp;
                   1271: 
                   1272:        d.d_dp = NULL;
                   1273:        d.d_ref = -1;
                   1274:        d.d_flag = D_LCL;
                   1275:        d.d_level = level;
                   1276:        d.d_seg = LASTSEG;
                   1277:        d.d_cseg = 0;
                   1278:        d.d_value = 0;
                   1279:        d.d_size = 0;
                   1280:        width = membs = 0;
                   1281: 
                   1282:        /*
                   1283:         * Loop to read entire record:
                   1284:         *      class, optional value, name, type.
                   1285:         */
                   1286:        dptr = data;
                   1287:        for (typet = 0; ; typet += 1) {
                   1288: 
                   1289:                if (dptr >= data+DSZ) {
                   1290:                        dbrpt("1", &d);
                   1291:                        cbotch("getdbgt buffer");
                   1292:                }
                   1293: 
                   1294:                n = bget();
                   1295:                if (n < DX_MEMBS)
                   1296:                        value = iget() * NBPBYTE;
                   1297:                else if (n < DC_SEX)
                   1298:                        ;
                   1299:                else {
                   1300:                        dline = iget();
                   1301:                        if (n < DC_AUTO)
                   1302:                                ;
                   1303:                        else if (n < DC_MOS)
                   1304:                                value = iget();
                   1305:                        else {
                   1306:                                width = bget();
                   1307:                                offs = bget();
                   1308:                                value = iget();
                   1309:                        }
                   1310:                }
                   1311:                subt = 0;
                   1312: 
                   1313:                switch (n) {
                   1314: 
                   1315:                /*
                   1316:                 * Classes: fetch values and set flags.
                   1317:                 */
                   1318:                case DC_SEX:
                   1319:                        d.d_flag |= D_NAM;
                   1320:                        goto setclass;
                   1321: 
                   1322:                case DC_GDEF:
                   1323:                case DC_GREF:
                   1324:                        d.d_flag = D_GBL|D_NAM;
                   1325:                        goto setclass;
                   1326: 
                   1327:                case DC_ETAG:
                   1328:                        d.d_flag |= D_ENU;
                   1329:                        strcpy(dptr, "enum ");
                   1330:                        dptr += 5;
                   1331:                        goto tag;
                   1332:                case DC_STAG:
                   1333:                        strcpy(dptr, "struct ");
                   1334:                        dptr += 7;
                   1335:                        goto tag;
                   1336:                case DC_UTAG:
                   1337:                        strcpy(dptr, "union ");
                   1338:                        dptr += 6;
                   1339:                case DC_TYPE:
                   1340:                        tag:
                   1341:                                d.d_flag = (level == 0) ? D_TAG|D_GBL
                   1342:                                                        : D_TAG|D_LCL;
                   1343:                                d.d_seg = TYPESYM;
                   1344:                                goto setclass;
                   1345: 
                   1346:                case DC_FILE:
                   1347:                        d.d_seg = PURCODE;
                   1348:                        goto setclass;
                   1349: 
                   1350:                case DC_AUTO:
                   1351:                        d.d_seg = L_STACK;
                   1352:                        d.d_value = value;
                   1353:                        goto setclass;
                   1354: 
                   1355:                case DC_SIN:
                   1356:                        d.d_flag |= D_LAB;
                   1357:                        goto setclass;
                   1358: 
                   1359:                case DC_LAB:
                   1360:                        goto setclass;
                   1361: 
                   1362:                case DC_REG:
                   1363:                        d.d_seg = L_REG;
                   1364:                        d.d_value = value;
                   1365:                        goto setclass;
                   1366: 
                   1367:                case DC_PREG:
                   1368:                        if (level == 0) {
                   1369:                                level++;
                   1370:                                outbrace('{');
                   1371:                        }
                   1372:                        d.d_seg = L_REG;
                   1373:                        d.d_value = value;
                   1374:                        goto setclass;
                   1375: 
                   1376:                case DC_MOE:
                   1377:                        d.d_seg = ABSLUTE;
                   1378:                        d.d_value = value;
                   1379:                        goto setclass;
                   1380: 
                   1381:                case DC_PAUTO:
                   1382:                        if (level  == 0) {
                   1383:                                level++;
                   1384:                                outbrace('{');
                   1385:                        }
                   1386:                        d.d_seg = P_STACK;
                   1387:                        d.d_value = value;
                   1388:                        goto setclass;
                   1389: 
                   1390:                case DC_LINE:
                   1391:                        goto setclass;
                   1392: 
                   1393:                case DC_MOS:
                   1394:                case DC_MOU:
                   1395:                        d.d_seg = FLD_OFF;
                   1396:                        d.d_value = value * NBPBYTE + offs;
                   1397:                        goto setclass;
                   1398: 
                   1399:                /*
                   1400:                 * Set the class field, read the name;
                   1401:                 * Lookup globals and statics.
                   1402:                 */
                   1403:                setclass:
                   1404:                        d.d_class = n;
                   1405:                        while (*dptr++ = bget())
                   1406:                                ;
                   1407:                        if ((d.d_flag&(D_NAM|D_LAB)) != 0) {
                   1408:                                register SYM *sp;
                   1409: 
                   1410:                                if ((d.d_flag&D_NAM) != 0)
                   1411:                                        sp = glookup(data, 0);
                   1412:                                else
                   1413:                                        sp = llookup(value, 0);
                   1414:                                if ((sp->s_flag&S_DEF) != 0) {
                   1415:                                        d.d_cseg = sp->s_seg;
                   1416:                                        d.d_seg = segindex(sp->s_seg);
                   1417:                                        d.d_value = sp->s_value;
                   1418:                                }
                   1419: #if COMMON
                   1420:                                else if (sp->s_value != 0) {
                   1421:                                        d.d_seg = BLDATA|Cb;
                   1422:                                        d.d_value = sp->s_value;
                   1423:                                }
                   1424: #endif
                   1425:                                if ((d.d_flag&D_GBL) != 0)
                   1426:                                        d.d_ref = sp->s_ref;
                   1427:                        }
                   1428:                        continue;
                   1429: 
                   1430:                /*
                   1431:                 * Types: write type and prepare for trailing data.
                   1432:                 * For files and lines, write a phony type.
                   1433:                 */
                   1434:                case DT_NONE:
                   1435:                        if (d.d_class == DC_FILE) {
                   1436:                                register char *p;
                   1437: 
                   1438:                                *dptr++ = STRINGt;
                   1439:                                p = "source file";
                   1440:                                while (*dptr++ = *p++)
                   1441:                                        ;
                   1442:                        }
                   1443:                        if (d.d_class == DC_LINE) {
                   1444:                                *dptr++ = 6;    /* Line */
                   1445:                                *dptr++ = dline;
                   1446:                                *dptr++ = dline >> 8;
                   1447:                                *dptr++ = 0;    /* Column */
                   1448:                                *dptr++ = 0;    /* Flag */
                   1449:                                *dptr++ = 0;    /* Saved instruction */
                   1450:                                *dptr++ = 0;
                   1451:                        }
                   1452:                        break;
                   1453: 
                   1454:                case DT_CHAR:
                   1455:                case DT_SHORT:
                   1456:                case DT_INT:
                   1457:                case DT_LONG:
                   1458:                        n = Integer;
                   1459:                        goto getwidth;
                   1460: 
                   1461:                case DT_UCHAR:
                   1462:                case DT_USHORT:
                   1463:                case DT_UINT:
                   1464:                case DT_ULONG:
                   1465:                        n = Natural;
                   1466:                        goto getwidth;
                   1467: 
                   1468:                case DT_FLOAT:
                   1469:                case DT_DOUBLE:
                   1470:                        n = Rational;
                   1471:                        goto settype;
                   1472: 
                   1473:                case DT_VOID:
                   1474:                        n = Void;
                   1475:                        goto settype;
                   1476: 
                   1477:                case DT_STRUCT:
                   1478:                        membs = n;
                   1479:                        n = Record;
                   1480:                        sdp = dptr;
                   1481:                        goto settype;
                   1482: 
                   1483:                case DT_UNION:
                   1484:                        membs = n;
                   1485:                        n = Union;
                   1486:                        sdp = dptr;
                   1487:                        goto settype;
                   1488: 
                   1489:                case DT_ENUM:
                   1490:                        d.d_flag |= D_ENU;
                   1491:                        membs = n;
                   1492:                        n = Natural;
                   1493:                        sdp = dptr;
                   1494:                        goto settype;
                   1495: 
                   1496:                getwidth:
                   1497:                        if (width)
                   1498:                                value = width;
                   1499: 
                   1500:                settype:
                   1501:                        *dptr++ = 1;
                   1502:                        *dptr++ = n;
                   1503:                        if (n != Void) {
                   1504:                                if (value == 0)
                   1505:                                        *dptr++ = ANYt;
                   1506:                                else if (value <= 0377) {
                   1507:                                        *dptr++ = 1;
                   1508:                                        *dptr++ = value;
                   1509:                                } else {
                   1510:                                        *dptr++ = 2;
                   1511:                                        *dptr++ = value;
                   1512:                                        *dptr++ = value >> 8;
                   1513:                                }
                   1514:                        }
                   1515:                        if (subt) {
                   1516:                                *dptr++ = TYPEt;
                   1517:                                continue;
                   1518:                        }
                   1519:                        if (membs) {
                   1520:                                --typet;
                   1521:                                continue;
                   1522:                        }
                   1523:                        break;
                   1524: 
                   1525:                /*
                   1526:                 * Dimensions: as for types, but flag for subtypes.
                   1527:                 */
                   1528:                case DD_PTR:
                   1529:                        n = Pointer;
                   1530:                        ++subt;
                   1531:                        goto settype;
                   1532: 
                   1533:                case DD_FUNC:
                   1534:                        n = Proc;
                   1535:                        ++subt;
                   1536:                        goto settype;
                   1537: 
                   1538:                case DD_ARRAY:
                   1539:                        n = Array;
                   1540:                        ++subt;
                   1541:                        goto settype;
                   1542: 
                   1543:                /*
                   1544:                 * Trailing struct/union/enum data.
                   1545:                 */
                   1546:                case DX_NAME:
                   1547:                        dptr = sdp;
                   1548:                        *dptr++ = STRINGt;
                   1549:                        switch (membs) {
                   1550:                                case DT_STRUCT:
                   1551:                                        strcpy(dptr, "struct ");
                   1552:                                        dptr += 7;
                   1553:                                        break;
                   1554:                                case DT_UNION:
                   1555:                                        strcpy(dptr, "union ");
                   1556:                                        dptr += 6;
                   1557:                                        break;
                   1558:                                case DT_ENUM:
                   1559:                                        strcpy(dptr, "enum ");
                   1560:                                        dptr += 5;
                   1561:                        }
                   1562:                        while (*dptr++ = bget())
                   1563:                                ;
                   1564:                        membs = 0;
                   1565:                        break;
                   1566: 
                   1567:                case DX_MEMBS:
                   1568:                        level += 1;
                   1569:                        dptr = getmembs(&d, data, dptr);
                   1570:                        level -= 1;
                   1571:                        membs = 0;
                   1572:                        break;
                   1573: 
                   1574:                default:
                   1575:                        cbotch("getdbgt: %d", n);
                   1576:                }
                   1577:                /*
                   1578:                 * Terminate types.
                   1579:                 */
                   1580:                if (dptr + typet >= data + DSZ) {
                   1581:                        dbrpt("2", &d);
                   1582:                        cbotch("getdbgt buffer");
                   1583:                }
                   1584:                while (--typet >= 0)
                   1585:                        *dptr++ = 0;
                   1586:                break;
                   1587:        }
                   1588: 
                   1589:        /*
                   1590:         * Check level change.
                   1591:         */
                   1592:        if (data[0] == '{') {
                   1593:                if (level++ == 0) {
                   1594:                        d.d_level = level++;
                   1595:                        outbrace('{');
                   1596:                }
                   1597:        }
                   1598:        else if (data[0] == '}')
                   1599:                level -= 1;
                   1600: 
                   1601:        /*
                   1602:         * Copy into dynamic storage.
                   1603:         */
                   1604:        d.d_size = dptr - data;
                   1605:        return (newdbgt(&d, data));
                   1606: }
                   1607: 
                   1608: /*
                   1609:  * Enter a new output segment.
                   1610:  */
                   1611: enter(newseg)
                   1612: register int newseg;
                   1613: {
                   1614:        if (dotseg == newseg)
                   1615:                return;                 /* already in newseg */
                   1616:        notenuf();                      /* flush */
                   1617:        seg[dotseg].s_dot = dot;        /* save current dot */
                   1618:        dotseg = newseg;                /* reset dotseg */
                   1619:        dot = seg[dotseg].s_dot;        /* and dot */
                   1620: }
                   1621: 
                   1622: /*
                   1623:  * Read a debug relocation item and patch current 'dot'
                   1624:  * into the appropriate debug/symbol table item.
                   1625:  * If the debug item is '}' and level 2, then dump the batch of locals.
                   1626:  * If the debug item is '}' and level 1, then dump the type definitions.
                   1627:  */
                   1628: getdloc()
                   1629: {
                   1630:        register struct dbgt *dp;
                   1631:        register int ref;
                   1632: 
                   1633:        ref = iget();
                   1634:        for (dp = dbase; ; dp = dp->d_dp) {
                   1635:                if (dp == NULL)
                   1636:                        cbotch("getdloc: %d", ref);
                   1637:                if ((dp->d_flag&D_GBL) != 0)
                   1638:                        continue;
                   1639:                if (dp->d_ref == ref)
                   1640:                        break;
                   1641:        }
                   1642:        dp->d_cseg = dotseg;
                   1643:        dp->d_seg = segindex(dotseg);
                   1644:        dp->d_value = dot;
                   1645: 
                   1646:        dbrpt("reloc", dp);
                   1647:        if (dp->d_data[0] == '}' && dp->d_level <= 2) {
                   1648:                outbrace('}');
                   1649:                level--;
                   1650:                dump();
                   1651:        }
                   1652: }
                   1653: 
                   1654: /*
                   1655:  * Dump the locals and type definitions.
                   1656:  */
                   1657: dump()
                   1658: {
                   1659:        register struct dbgt *dp, **dpp;
                   1660:        int saveseg;
                   1661: 
                   1662:        saveseg = dotseg;
                   1663:        enter(SDBG);
                   1664:        dpp = &dbase;
                   1665:        dnext = NULL;
                   1666:        while ((dp = *dpp) != NULL) {
                   1667:                if ((dp->d_flag&D_LCL) != 0) {
                   1668:                        dbrpt("write", dp);
                   1669:                        osymbol(dp, -1);
                   1670:                        dp->d_flag &= ~D_LCL;
                   1671:                }
                   1672:                if ((dp->d_flag&D_GBL) == 0) {
                   1673:                        dbrpt("free", dp);
                   1674:                        *dpp = dp->d_dp;
                   1675:                        free(dp);
                   1676:                } else {
                   1677:                        dbrpt("save", dp);
                   1678:                        dnext = dp;
                   1679:                        dpp = &dp->d_dp;
                   1680:                }
                   1681:        }
                   1682:        enter(saveseg);
                   1683: }
                   1684: 
                   1685: /*
                   1686:  * Write out global symbol definitions and references.
                   1687:  */
                   1688: oglobals()
                   1689: {
                   1690:        register struct dbgt *dp, *dp1;
                   1691: 
                   1692:        enter(SDBG);
                   1693:        for (dp = dbase; dp != NULL; dp = dp1) {
                   1694:                dp1 = dp->d_dp;
                   1695:                dbrpt("write", dp);
                   1696:                if (dp->d_seg == TYPESYM || dp->d_seg == ABSLUTE)
                   1697:                        osymbol(dp, 0);
                   1698:                else
                   1699:                        osymbol(dp, dp->d_ref);
                   1700:                dbrpt("free", dp);
                   1701:                free(dp);
                   1702:        }
                   1703:        notenuf();
                   1704: }
                   1705: 
                   1706: /*
                   1707:  * Write out a symbol to the symbol or debug table.
                   1708:  * TYPESYM and ABSLUTE symbols have refnum 0.
                   1709:  * Debug table symbols have negative refnums and may require relocation.
                   1710:  */
                   1711: osymbol(dp, refnum)
                   1712: register struct dbgt *dp;
                   1713: {
                   1714:        register char *cp;
                   1715:        unsigned char seg;
                   1716:        int nd, nr, fixup, fixseg;
                   1717: 
                   1718:        /* Write scope/refnum or seg/value+relocation expression */
                   1719:        seg = dp->d_seg;
                   1720:        nd = 5 + dp->d_size;
                   1721:        nr = 0;
                   1722: #if 0
                   1723: printf("osymbol(%s, %x) seg=%x cseg=%x nd=%x\n", dp->d_data, refnum, seg,
                   1724: dp->d_cseg, nd);
                   1725: #endif
                   1726:        if (refnum >= 0) {
                   1727:                if (seg == LASTSEG) {
                   1728:                        for (cp=dp->d_data; *cp++; )
                   1729:                                ;               /* skip the name */
                   1730:                        seg = (*cp++ == 1 && *cp++ == Proc) ? PURCODE : PURDATA;
                   1731:                        fixseg = -1;            /* external fixup */
                   1732:                } else
                   1733:                        fixseg = getsegindex(dp->d_cseg);
                   1734:                if (seg != TYPESYM && seg != ABSLUTE)
                   1735:                        nr = (isvariant(VLARGE)) ? 10 : 6;
                   1736:        } else if (refnum < 0) {
                   1737:                if (seg < SUMMARY && seg != TYPESYM && seg != ABSLUTE) {
                   1738:                        nr = (isvariant(VLARGE)) ? 10 : 6;
                   1739:                        fixseg = getsegindex(dp->d_cseg);
                   1740:                }
                   1741:                else
                   1742:                        fixseg = 1;                     /* CODE */
                   1743:        }
                   1744:        enuf(nd, nr);
                   1745:        dot += nd;                      /* bump dot */
                   1746:        *txtp++ = seg;                  /* reloc-style segment */
                   1747:        if (fixseg == -1) {             /* extern fixup */
                   1748:                if (isvariant(VLARGE)) {
                   1749:                        fixup = txtp - (txt+3);
                   1750:                        *relp++ = LOCAT|M|BASE|(fixup>>8);
                   1751:                        *relp++ = fixup;
                   1752:                        *relp++ = FTARGET|SECWAY|TEI;
                   1753:                        relp = setindex(relp, refnum);
                   1754:                }
                   1755:                *txtp++ = 0;
                   1756:                *txtp++ = 0;
                   1757:                fixup = txtp - (txt+3);
                   1758:                *relp++ = LOCAT|M|OFFSET|(fixup>>8);
                   1759:                *relp++ = fixup;
                   1760:                *relp++ = FTARGET|SECWAY|TEI;
                   1761:                relp = setindex(relp, refnum);
                   1762:                *txtp++ = 0;
                   1763:                *txtp++ = 0;
                   1764:        } else {
                   1765:                if (nr != 0 && isvariant(VLARGE)) {     /* segment fixup */
                   1766:                        fixup = txtp - (txt+3);
                   1767:                        *relp++ = LOCAT|M|BASE|(fixup>>8);
                   1768:                        *relp++ = fixup;
                   1769:                        *relp++ = FTARGET|SECWAY|TSI;
                   1770:                        *relp++ = fixseg;
                   1771:                }
                   1772:                *txtp++ = 0;
                   1773:                *txtp++ = 0;                    /* segment text */
                   1774:                if (nr != 0) {                  /* offset text and fixup */
                   1775:                        fixup = txtp - (txt+3);
                   1776:                        *relp++ = LOCAT|M|OFFSET|(fixup>>8);
                   1777:                        *relp++ = fixup;
                   1778:                        if (fixseg == 1)
                   1779:                                *relp++ = F|FT0|TSI;    /* fixup F code, seg index */
                   1780:                        else
                   1781:                                *relp++ = F|FT1|TSI;    /* fixup F data, seg index */
                   1782:                        *relp++ = fixseg;
                   1783:                        *relp++ = dp->d_value;
                   1784:                        *relp++ = dp->d_value >> 8;
                   1785:                        *txtp++ = 0;
                   1786:                        *txtp++ = 0;
                   1787:                } else {
                   1788:                        *txtp++ = dp->d_value;
                   1789:                        *txtp++ = dp->d_value >> 8;     /* nonrelocated offset */
                   1790:                }
                   1791:        }
                   1792: 
                   1793:        /* Write name */
                   1794:        cp = dp->d_data;
                   1795:        nd = dp->d_size;
                   1796:        do {
                   1797:                *txtp++ = *cp;
                   1798:                --nd;
                   1799:        } while (*cp++);
                   1800: 
                   1801:        /* Type */
                   1802:        while (--nd >= 0)
                   1803:                *txtp++ = *cp++;        /* type */
                   1804: }
                   1805: 
                   1806: /*
                   1807:  * Read a list of members of a union/struct/enum.
                   1808:  * If struct/union, append member types to caller's buffer.
                   1809:  * If making a debug table:
                   1810:  * If struct/union tag definition, bracket member definitions.
                   1811:  * If enum tag, make member type into "enum tag".
                   1812:  */
                   1813: char *
                   1814: getmembs(dp0, bb, bp)
                   1815: struct dbgt *dp0;
                   1816: char *bb;
                   1817: register char *bp;
                   1818: {
                   1819:        int nmembs, n, istag, isenu, isgbl, isdbg;
                   1820:        char *sbp;
                   1821:        register struct dbgt *dp;
                   1822:        struct dbgt **dpp;
                   1823:        register char *p;
                   1824:        static struct dbgt dbrace = {
                   1825:                NULL,           /* d_dp         */
                   1826:                -1,             /* d_ref        */
                   1827:                DT_NONE,        /* d_class      */
                   1828:                D_LCL,          /* d_flag       */
                   1829:                0,              /* d_level      */
                   1830:                TYPESYM,        /* d_seg        */
                   1831:                0,              /* d_cseg       */
                   1832:                0,              /* d_value      */
                   1833:                3               /* d_size       */
                   1834:        };
                   1835: 
                   1836:        dp = dp0;
                   1837:        nmembs = bget();
                   1838:        istag = (dp->d_flag&D_TAG) != 0;
                   1839:        isenu = (dp->d_flag&D_ENU) != 0;
                   1840:        isgbl = (dp->d_flag&D_GBL) != 0;
                   1841:        isdbg = VCSD;
                   1842:        if (isenu) {
                   1843:                sbp = bp;
                   1844:                isenu = strlen(bb) + 1 + 1;
                   1845:        }
                   1846:        if ( ! isenu) {
                   1847: #if    DO_STRUCT_TYPE
                   1848:                /* Note that this blows up for nmembs > 255 anyway */
                   1849:                *bp++ = 1;
                   1850:                *bp++ = nmembs;
                   1851: #else
                   1852:                *bp++ = 1;
                   1853:                *bp++ = 1;
                   1854:                *bp++ = ANYt;
                   1855: #endif
                   1856:                dpp = &dp->d_dp;
                   1857:                dp = *dpp = newdbgt(&dbrace, "{\0\0");
                   1858:                if (isgbl)
                   1859:                        dp->d_flag ^= D_GBL|D_LCL;
                   1860:        }
                   1861:        dpp = &dp->d_dp;
                   1862:        while (--nmembs >= 0) {
                   1863:                /* Note that dp could be a tagless structure, ie a list */
                   1864:                dp = *dpp = getdbgt();
                   1865:                if (isgbl)
                   1866:                        dp->d_flag ^= D_GBL|D_LCL;
                   1867:                n = dp->d_size;
                   1868:                p = dp->d_data;
                   1869:                if (isenu && istag && isdbg) {
                   1870:                        /* Enumerators eschew member lists */
                   1871:                        dp->d_size += isenu;
                   1872:                        dp = newdbgt(dp, dp->d_data);
                   1873:                        bp = dp->d_data;
                   1874:                        while (*bp++)
                   1875:                                ;
                   1876:                        *bp++ = STRINGt;
                   1877:                        p = bb;
                   1878:                        while (*bp++ = *p++)
                   1879:                                ;
                   1880:                        *bp++ = 0;
                   1881:                        free(*dpp);
                   1882:                        *dpp = dp;
                   1883:                        bp = sbp;
                   1884:                }
                   1885: #if    DO_STRUCT_TYPE
                   1886:                if ( ! isenu) {
                   1887:                        do {
                   1888:                                --n;
                   1889:                        } while (*p++);
                   1890:                        *bp++ = TYPEt;
                   1891:                        if (bp + n >= bb + DSZ) {
                   1892:                                dbrpt("3", dp);
                   1893:                                cbotch("getdbgt buffer");
                   1894:                        }
                   1895:                        do {
                   1896:                                *bp++ = *p++;
                   1897:                        } while (--n > 0);
                   1898:                }
                   1899: #endif
                   1900:                if (istag && isdbg)
                   1901:                        dpp = &dp->d_dp;
                   1902:                else
                   1903:                        free(*dpp);
                   1904:        }
                   1905:        if ( ! isenu) {
                   1906:                dp = *dpp = newdbgt(&dbrace, "}\0\0");
                   1907:                dpp = &dp->d_dp;
                   1908:                if (isgbl)
                   1909:                        dp->d_flag ^= D_GBL|D_LCL;
                   1910:        }
                   1911:        *dpp = NULL;
                   1912:        return (bp);
                   1913: }
                   1914: 
                   1915: struct dbgt *
                   1916: newdbgt(dp, cp)
                   1917: struct dbgt *dp;
                   1918: register char *cp;
                   1919: {
                   1920:        register struct dbgt *ndp;
                   1921:        register char *ncp;
                   1922:        register int n;
                   1923: 
                   1924:        n = dp->d_size;
                   1925:        if ((ndp = (struct dbgt *)malloc(sizeof(struct dbgt) + n)) == NULL)
                   1926:                cnomem("newdbgt");
                   1927:        *ndp = *dp;
                   1928:        for (ncp = ndp->d_data; --n >= 0; *ncp++ = *cp++)
                   1929:                ;
                   1930:        return (ndp);
                   1931: }
                   1932: 
                   1933: /*
                   1934:  * Output a debug brace.
                   1935:  */
                   1936: outbrace(c)
                   1937: int c;
                   1938: {
                   1939:        struct dbgt *dp;
                   1940: 
                   1941:        if ((dp = (struct dbgt *)calloc(1, sizeof(struct dbgt) + 10)) == NULL)
                   1942:                cnomem("outbrace");
                   1943:        dp->d_class = DC_LINE;
                   1944:        dp->d_flag = D_LCL;
                   1945:        dp->d_seg = segindex(SCODE);
                   1946:        dp->d_value = ( dotseg == SCODE ? dot : seg[SCODE].s_dot);
                   1947:        dp->d_size = 10;
                   1948:        dp->d_data[0] = c;
                   1949:        *(dp->d_data + 2) = 6;
                   1950:        *(dp->d_data + 3) = dline;
                   1951:        *(dp->d_data + 4) = dline >> 8;
                   1952:        if (dnext != NULL)
                   1953:                dnext->d_dp = dp;
                   1954:        dnext = dp;
                   1955: }
                   1956: 
                   1957: #if !TINY
                   1958: _dbrpt(p, dp)
                   1959: char *p;
                   1960: register struct dbgt *dp;
                   1961: {
                   1962:        if (xflag > 5)
                   1963:                printf("%5s: %-10s %2x %2d %2x %2x %2x %2x %04x %2x\n",
                   1964:                        p,
                   1965:                        dp->d_data,
                   1966:                        dp->d_class,
                   1967:                        dp->d_ref,
                   1968:                        dp->d_flag,
                   1969:                        dp->d_level,
                   1970:                        dp->d_seg,
                   1971:                        dp->d_cseg,
                   1972:                        dp->d_value,
                   1973:                        dp->d_size
                   1974:                );
                   1975: }
                   1976: 
                   1977: #endif
                   1978: 
                   1979: /*
                   1980: ** Low level record formatting.
                   1981: */
                   1982: /*
                   1983:  * Put OMF index i at cp and return updated cp.
                   1984:  */
                   1985: char *
                   1986: setindex(cp, i)
                   1987: register char *cp;
                   1988: register unsigned i;
                   1989: {
                   1990:        if (i >= 128)
                   1991:                *cp++ = (i >> 8) | 0x80;
                   1992:        *cp++ = i;
                   1993:        return (cp);
                   1994: }
                   1995: 
                   1996: /*
                   1997:  * This routine takes the name pointed to by 'cp' and
                   1998:  * moves it into an OMF record. The 'bp' argument
                   1999:  * is the OMF buffer pointer. The updated value
                   2000:  * of 'bp' is returned.
                   2001:  */
                   2002: char *
                   2003: setsymid(bp, cp)
                   2004: register char *bp;
                   2005: register char *cp;
                   2006: {
                   2007:        register c, n;
                   2008: 
                   2009:        if ((n=strlen(cp)) > 39) {
                   2010:                cwarn("symbol \"%s\" truncated to 39 characters", cp);
                   2011:                n = 39;
                   2012:        }
                   2013:        *bp++ = n;
                   2014:        while (n--) {
                   2015: #if    0
                   2016:                if ((c = *cp++)>='a' && c<='z')
                   2017:                        c -= 'a'-'A';
                   2018:                *bp++ = c;
                   2019: #else
                   2020:                *bp++ = *cp++;
                   2021: #endif
                   2022:        }
                   2023:        return (bp);
                   2024: }
                   2025: 
                   2026: /*
                   2027:  * Put a record.
                   2028:  * The 'type' argument is the record type.
                   2029:  * The body of the record starts at 'p' and is
                   2030:  * 'n' bytes long. The checksum is added.
                   2031:  */
                   2032: putrecord(type, p, n)
                   2033: register char *p;
                   2034: register n;
                   2035: {
                   2036:        checksum = 0;
                   2037:        putbyte(type);
                   2038:        putbyte(n+1);           /* +1 for the checksum */
                   2039:        putbyte((n+1)>>8);
                   2040:        while(n--)
                   2041:                putbyte(*p++);
                   2042:        putbyte(-checksum);
                   2043: }
                   2044: 
                   2045: putbyte(b)
                   2046: register b;
                   2047: {
                   2048: #if VAXFMT
                   2049:        if (vaxptr >= &vaxbuf[NVDATA]) {
                   2050:                vaxflush();
                   2051:                vaxptr = vaxbuf;
                   2052:        }
                   2053:        *vaxptr++ = b;
                   2054: #else
                   2055:        bput(b);
                   2056: #endif
                   2057:        checksum += b;
                   2058: }
                   2059: 
                   2060: /*
                   2061: ** Output buffering.
                   2062: */
                   2063: /*
                   2064:  * This routine checks to see if
                   2065:  * there is enough room in the text and relocation
                   2066:  * buffers to hold 'nt' bytes of text and 'nr' bytes of
                   2067:  * relocation.
                   2068:  */
                   2069: enuf(nt, nr)
                   2070: {
                   2071:        if (txtp+nt>&txt[NTXT] || relp+nr>&rel[NREL])
                   2072:                notenuf();
                   2073:        if (txtp == txt) {
                   2074:                *txtp++ = getsegindex(dotseg);
                   2075:                *txtp++ = dot;
                   2076:                *txtp++ = dot >> 8;
                   2077:        }
                   2078: }
                   2079: 
                   2080: /*
                   2081:  * Flush the buffer.
                   2082:  */
                   2083: notenuf()
                   2084: {
                   2085:        register n;
                   2086: 
                   2087:        if ((n = txtp-txt) > 3) {
                   2088:                putrecord(LEDATA, txt, n);
                   2089:                if ((n = relp-rel) != 0) {
                   2090:                        putrecord(FIXUPP, rel, n);
                   2091:                        relp = rel;
                   2092:                }
                   2093:        }
                   2094:        txtp = txt;
                   2095: }
                   2096: 
                   2097: /*
                   2098:  * Round up to the next word.
                   2099:  */
                   2100: rup(a)
                   2101: ADDRESS a;
                   2102: {
                   2103:        return ((a+01)&~01);
                   2104: }
                   2105: 
                   2106: #if VAXFMT
                   2107: /*
                   2108:  * Flush out a record on the VAX. The record is a standard,
                   2109:  * RMS variable length record. This routine checks for no bytes
                   2110:  * in the buffer, so it can be unconditionally called at the
                   2111:  * end to flush the buffer out.
                   2112:  * The record is padded out to NVDATA bytes with zeros. This
                   2113:  * only happens on the last block; the data beyond the end
                   2114:  * is zeroed.
                   2115:  */
                   2116: vaxflush()
                   2117: {
                   2118:        register int    n;
                   2119: 
                   2120:        if ((n = vaxptr-vaxbuf) != 0) {
                   2121:                if (fwrite(vaxbuf, n, 1, ofp) != 1
                   2122:                ||  fflush(ofp) == EOF)
                   2123:                        cfatal("output write error");
                   2124:        }
                   2125: }
                   2126: #endif

unix.superglobalmegacorp.com

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