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

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

unix.superglobalmegacorp.com

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