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

unix.superglobalmegacorp.com

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