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

1.1       root        1: /*
                      2:  * This file writes writes Intel iAPX-86 OMF with csd debugging information.
                      3:  * Based on outomf.c, but with MWC CSD-format debug info (as in outrel.c)
                      4:  * instead of Intel format.
                      5:  * The 'out...' routines write to a temporary file during code assembly.
                      6:  * At the end of assembly, 'copycode' uses the 'put...' routines
                      7:  * to write the object file.
                      8:  * This is necessary: SEGDEF records must be written before
                      9:  * LEDATA and FIXUPP records, but each SEGDEF includes the size
                     10:  * of the segment in bytes.
                     11:  * However, the size of the DEBUG segment is fixed up ex post facto.
                     12:  */
                     13: 
                     14: /*
                     15:  * Reference: "8086 Relocatable Object Formats,"
                     16:  * Intel 121748-001 (C) Intel 1981.
                     17:  */
                     18: 
                     19: #ifdef vax
                     20: #include "INC$LIB:cc2.h"
                     21: #include "INC$LIB:debug.h"
                     22: #else
                     23: #include "cc2.h"
                     24: #include "debug.h"
                     25: #endif
                     26: 
                     27: #define        NTXT    (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.