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

1.1     ! root        1: /*
        !             2:  * This file contains a fairly general writer for Intel iAPX-86 OMF.
        !             3:  * The 'out...' routines write to a temporary file during code assembly.
        !             4:  * At the end of assembly, 'copycode' uses the 'put...' routines
        !             5:  * to write the object file.
        !             6:  * This is necessary: SEGDEF records must be written before
        !             7:  * LEDATA and FIXUPP records, but each SEGDEF includes the size
        !             8:  * of the segment in bytes.
        !             9:  */
        !            10: 
        !            11: /*
        !            12:  * References:  "8086 Relocatable Object Formats,"
        !            13:  * Intel 121748-001 (C) Intel 1981.
        !            14:  * "Type Definition Records for High Level Languages,"
        !            15:  * Version 2.0, 6/25/84, Intel 114834 (Intel proprietary).
        !            16:  */
        !            17: 
        !            18: #ifdef   vax
        !            19: #include "INC$LIB:cc2.h"
        !            20: #else
        !            21: #include "cc2.h"
        !            22: #endif
        !            23: 
        !            24: /*
        !            25:  * As of 4/29/85, PSCOPE does not support unnamed blocks correctly.
        !            26:  * The output writer therefore suppresses unnamed blocks #ifdef NOABLOCKS.
        !            27:  */
        !            28: #if    INTEL
        !            29: #define        NOABLOCKS 1
        !            30: int    blkcount;
        !            31: #endif
        !            32: 
        !            33: #define        NTXT    256                     /* Text buffer size */
        !            34: #define        NREL    256                     /* Relocation buffer size */
        !            35: 
        !            36: #ifndef __LINE__
        !            37: #define        __LINE__        0
        !            38: #endif
        !            39: 
        !            40: /*
        !            41:  * Scratch file opcodes.
        !            42:  * Flags are or'ed in to TBYTE and TWORD opcodes only.
        !            43:  */
        !            44: #define        TTYPE   07                      /* Type */
        !            45: #define        TPCR    010                     /* PC relative flag */
        !            46: #define        TSYM    020                     /* Symbol based flag */
        !            47: 
        !            48: #define        TEND    00                      /* End marker */
        !            49: #define        TENTER  01                      /* Enter new area */
        !            50: #define        TBYTE   02                      /* Byte data */
        !            51: #define        TWORD   03                      /* Word data */
        !            52: #define        TCODE   04                      /* Code segment base */
        !            53: #define        TDATA   05                      /* Data segment base */
        !            54: #define        TBASE   06                      /* External segment base */
        !            55: #define        TDLAB   07                      /* Debug label */
        !            56: #define        TDLOC   010                     /* 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   0340                    /* 8087 flags */
        !            67: #define        TWT     0040                    /* M:_WT  */
        !            68: #define        TWST    0100                    /* M:_WST */
        !            69: #define        TWES    0140                    /* M:_WES */
        !            70: #define        TWCS    0200                    /* M:_WCS */
        !            71: #define        TWSS    0240                    /* M:_WSS */
        !            72: #define        TWDS    0300                    /* M:_WDS */
        !            73: #endif
        !            74: 
        !            75: /*
        !            76:  * OMF types.
        !            77:  */
        !            78: #define        BLKDEF  0x7A                    /* Block definition */
        !            79: #define        BLKEND  0x7C                    /* Block end */
        !            80: #define        DEBSYM  0x7E                    /* Debug symbol */
        !            81: #define        THEADR  0x80                    /* Translator module header */
        !            82: #define        COMENT  0x88                    /* Comment */
        !            83: #define        MODEND  0x8A                    /* Module end */
        !            84: #define        EXTDEF  0x8C                    /* External definition (reference) */
        !            85: #define        TYPDEF  0x8E                    /* Type definition */
        !            86: #define        PUBDEF  0x90                    /* Public definition (definition) */
        !            87: #define        LINNUM  0x94                    /* Line # */
        !            88: #define        LNAMES  0x96                    /* List of names */
        !            89: #define        SEGDEF  0x98                    /* Segment definition */
        !            90: #define        GRPDEF  0x9A                    /* Group definition */
        !            91: #define        FIXUPP  0x9C                    /* Fixups */
        !            92: #define        LEDATA  0xA0                    /* Enumerated data */
        !            93: #define        LIDATA  0xA2                    /* Iterated data */
        !            94: 
        !            95: /*
        !            96:  * Some OMF fields and flags.
        !            97:  */
        !            98: #define        PARA    (0x03<<5)               /* Paragraph alignment */
        !            99: #define        BIG     0x02                    /* 64k */
        !           100: #define        CCON    (0x02<<2)               /* C field, concatenate */
        !           101: #define        CMEM    (0x01<<2)               /* C field, memory */
        !           102: #define        CSTACK  (0x05<<2)               /* C field, stack */
        !           103: 
        !           104: #define        LOCAT   0x80                    /* Locat flag bit */
        !           105: #define        M       0x40                    /* M bit; 0=self rel, 1=seg rel */
        !           106: #define        LOBYTE  (0x00<<2)               /* Locat */
        !           107: #define        OFFSET  (0x01<<2)               /* Locat */
        !           108: #define        BASE    (0x02<<2)               /* Locat */
        !           109: #define        POINTER (0x03<<2)               /* Locat */
        !           110: #define        HIBYTE  (0x04<<2)               /* Locat */
        !           111: 
        !           112: #define        SECWAY  0x04                    /* Secondary way */
        !           113: #define        FD8087  0x36                    /* FIXDAT for 8087 fixup */
        !           114: #define        FSI     (0<<4)                  /* Frame segment index */
        !           115: #define        FGI     (1<<4)                  /* Frame group index */
        !           116: #define        FEI     (2<<4)                  /* Frame external index */
        !           117: #define        FFN     (3<<4)                  /* Frame frame number */
        !           118: #define        FLSEG   (4<<4)                  /* Frame of LSEG */
        !           119: #define        FTARGET (5<<4)                  /* Frame of TARGET object */
        !           120: #define        FNONE   (6<<4)                  /* No frame */
        !           121: #define        TSI     0                       /* Target: segment index */
        !           122: #define        TGI     1                       /* Target: group index */
        !           123: #define        TEI     2                       /* Target: external index */
        !           124: #define        TFN     3                       /* Target: frame */
        !           125: #define        F       0x80                    /* Frame thread used */
        !           126: #define        T       0x08                    /* Target thread used */
        !           127: #define        FT0     0x00                    /* 0 */
        !           128: #define        FT1     0x10                    /* 1 */
        !           129: 
        !           130: /*
        !           131:  * Type representations for TYPDEF records.
        !           132:  */
        !           133: #if    INTEL
        !           134: /* Intel proprietary. */
        !           135: #define        OTSFUNC 0x5E                    /* SHORT$NOPOP */
        !           136: #define        OTLFUNC 0x5F                    /* LONG$NOPOP */
        !           137: #define        OTUPACK 0x66                    /* Unpacked */
        !           138: #define        OTLABEL 0x71                    /* LABEL */
        !           139: #define        OTLONG  0x72                    /* LONG */
        !           140: #define        OTSHORT 0x73                    /* SHORT */
        !           141: #define        OTPROC  0x74                    /* PROCEDURE */
        !           142: #define        OTPARA  0x75                    /* PARAMETER */
        !           143: #define        OTARRAY 0x77                    /* ARRAY */
        !           144: #define        OTSTRUC 0x79                    /* STRUCTURE */
        !           145: #define        OTPOINT 0x7A                    /* POINTER */
        !           146: #define        OTSCAL  0x7B                    /* SCALAR */
        !           147: #define        OTUINT  0x7C                    /* UNSINT */
        !           148: #define        OTSINT  0x7D                    /* SGNINT */
        !           149: #define        OTREAL  0x7E                    /* REAL */
        !           150: #define        OTLIST  0x7F                    /* LIST */
        !           151: #endif
        !           152: 
        !           153: #define        OTNIL   0x80                    /* NIL */
        !           154: #define        OTUNUM2 0x81                    /* Unsigned numeric (2 byte) leaf */
        !           155: #define        OTNAME  0x82                    /* Name leaf */
        !           156: #define        OTINDEX 0x83                    /* Index leaf */
        !           157: #define        OTUNUM3 0x84                    /* Unsigned numeric (3 byte) leaf */
        !           158: 
        !           159: /*
        !           160:  * A linked list of TINFO records containing OMF type definitions
        !           161:  * is generated while reading DLABEL records.
        !           162:  * The type index corresponds to the position in the TINFO list.
        !           163:  * The tflag keeps track of whether a forward reference
        !           164:  * tagname type ever gets resolved.
        !           165:  * The length must directly precede the info for puttypdef() to work right.
        !           166:  */
        !           167: typedef        struct  typeinfo {
        !           168:        struct  typeinfo *t_tp;         /* link */
        !           169:        char    t_tflag;                /* tag name flag */
        !           170:        int     t_length;               /* length */
        !           171:        char    t_info[];               /* info */
        !           172: } TINFO;
        !           173: 
        !           174: /*
        !           175:  * To generate correct references to tagged types,
        !           176:  * the tag name is entered first as a type and
        !           177:  * all references to the type are made by tag name.
        !           178:  * When types are dumped, a list of these patch
        !           179:  * records is consulted to substitute the tag definition
        !           180:  * for the tag name.
        !           181:  */
        !           182: typedef struct typefix {
        !           183:        struct  typefix *t_tp;          /* link */
        !           184:        int     t_ttype;                /* dummy definition */
        !           185:        int     t_type;                 /* fixed definition */
        !           186: } TYFIX;
        !           187: 
        !           188: static TINFO   *typelistp;             /* Typdef list */
        !           189: static TYFIX   *typefixp;              /* Type fix list */
        !           190: static TINFO   *gettype();
        !           191: static int     checksum;               /* For putrecord and putbyte */
        !           192: static char    txt[NTXT];              /* Text buffer */
        !           193: static char    rel[NREL];              /* Relocation buffer */
        !           194: static ADDRESS code_size;              /* Size of CODE */
        !           195: static ADDRESS data_size;              /* Size of DATA */
        !           196: static  ADDRESS        const_size;             /* Size of CONST */
        !           197: static ADDRESS bss_size;               /* Size of BSS */
        !           198: static char    *txtp = txt;            /* Text pointer */
        !           199: static char    *relp = rel;            /* Relocation pointer */
        !           200: 
        !           201: #if    EMUFIXUPS
        !           202: static int     has8087;                /* Has 8087 code flag */
        !           203: static SYM     *wsp[6];                /* Links to emulator symbols */
        !           204: #endif
        !           205: 
        !           206: #if    VAXFMT
        !           207: /*
        !           208:  * The Intel cross software packs the OMF
        !           209:  * data into 512 byte blocks as 510 byte variable length
        !           210:  * records, with the last record short.
        !           211:  */
        !           212: #define        NVDATA  510                     /* Blocksize - 2 */
        !           213: static char    vaxbuf[NVDATA];         /* Buffer */
        !           214: static char    *vaxptr = vaxbuf;       /* Pointer */
        !           215: #endif
        !           216: 
        !           217: extern char    *setsymid();
        !           218: extern char    *setindex();
        !           219: extern char    *setsize();
        !           220: extern char    *setnumb();
        !           221: extern long    lastsize;
        !           222: 
        !           223: /*
        !           224:  * These tables are indexed by a compiler segment name (SCODE et al)
        !           225:  * to get the OMF segment index.
        !           226:  * These tables understand the way the SSTRN segment moves
        !           227:  * around when the ROM option is given, and
        !           228:  * are dependent on the order of the calls to putsegdef() in copycode().
        !           229:  */
        !           230: static char    lnonseg[] = {
        !           231:        1,                              /* SCODE => module_CODE */
        !           232:        1,                              /* SLINK => module_CODE */
        !           233:        1,                              /* SPURE => module_CODE */
        !           234:        2,                              /* SSTRN => module_DATA */
        !           235:        2,                              /* SDATA => module_DATA */
        !           236:        2                               /* SBSS  => module_DATA */
        !           237: };
        !           238: 
        !           239: static char    lromseg[] = {
        !           240:        1,                              /* SCODE => module_CODE */
        !           241:        1,                              /* SLINK => module_CODE */
        !           242:        1,                              /* SPURE => module_CODE */
        !           243:        1,                              /* SSTRN => module_CODE */
        !           244:        2,                              /* SDATA => module_DATA */
        !           245:        2                               /* SBSS  => module_DATA */
        !           246: };
        !           247: 
        !           248: static char    lramseg[] = {
        !           249:        1,                              /* SCODE => module_CODE */
        !           250:        1,                              /* SLINK => module_CODE */
        !           251:        2,                              /* SPURE => module_DATA */
        !           252:        2,                              /* SSTRN => module_DATA */
        !           253:        2,                              /* SDATA => module_DATA */
        !           254:        2                               /* SBSS  => module_DATA */
        !           255: };
        !           256: 
        !           257: static char    snonseg[] = {
        !           258:        1,                              /* SCODE => CODE */
        !           259:        1,                              /* SLINK => CODE */
        !           260:        2,                              /* SPURE => CONST */
        !           261:        3,                              /* SSTRN => DATA */
        !           262:        3,                              /* SDATA => DATA */
        !           263:        3                               /* SBSS  => DATA */
        !           264: };
        !           265: 
        !           266: static char    sromseg[] = {
        !           267:        1,                              /* SCODE => CODE */
        !           268:        1,                              /* SLINK => CODE */
        !           269:        2,                              /* SPURE => CONST */
        !           270:        2,                              /* SSTRN => CONST */
        !           271:        3,                              /* SDATA => DATA */
        !           272:        3                               /* SDATA => DATA */
        !           273: };
        !           274: 
        !           275: static char    sramseg[] = {
        !           276:        1,                              /* SCODE => CODE */
        !           277:        1,                              /* SLINK => CODE */
        !           278:        3,                              /* SPURE => DATA */
        !           279:        3,                              /* SSTRN => DATA */
        !           280:        3,                              /* SDATA => DATA */
        !           281:        3                               /* SDATA => DATA */
        !           282: };
        !           283: 
        !           284: /*
        !           285:  * Same game, but for group index codes.
        !           286:  * This is used only in SMALL model.
        !           287:  */
        !           288: static char    grpindex[] = {
        !           289:        1,                              /* SCODE => CGROUP */
        !           290:        1,                              /* SLINK => CGROUP */
        !           291:        2,                              /* SPURE => DGROUP */
        !           292:        2,                              /* SSTRN => DGROUP */
        !           293:        2,                              /* SDATA => DGROUP */
        !           294:        2                               /* SBSS  => DGROUP */
        !           295: };
        !           296: 
        !           297: /*
        !           298:  * Some prefabricated OMF items.
        !           299:  * These are just blasted out via a call to putrecord().
        !           300:  */
        !           301: static char    lthred[]        = { 0x40, 0x01,         /* module_CODE */
        !           302:                                    0x41, 0x02 };       /* module_DATA */
        !           303: static char    lnames[]        = { 0,
        !           304:                                    4, 'C', 'O', 'D', 'E',
        !           305:                                    4, 'D', 'A', 'T', 'A',
        !           306:                                    5, 'C', 'O', 'N', 'S', 'T',
        !           307:                                    5, 'S', 'T', 'A', 'C', 'K',
        !           308:                                    6, 'M', 'E', 'M', 'O', 'R', 'Y',
        !           309:                                    6, 'C', 'G', 'R', 'O', 'U', 'P',
        !           310:                                    6, 'D', 'G', 'R', 'O', 'U', 'P'
        !           311:                                };
        !           312: static char    gdef1[]         = { 7, 0xFF, 1 };
        !           313: static char    gdef2[]         = { 8, 0xFF, 2, 0xFF, 3, 0xFF, 4, 0xFF, 5 };
        !           314: static char    sthred[]        = { 0x00, 0x01,         /* Code */
        !           315:                                    0x01, 0x02,         /* Const */
        !           316:                                    0x02, 0x03,         /* Data */
        !           317:                                    0x44, 0x01,         /* Frame -> cgroup */
        !           318:                                    0x45, 0x02          /* Frame -> dgroup */
        !           319:                                };
        !           320: static char    modend[]        = { 0x00 };
        !           321: static int     blkindex;               /* current block index */
        !           322: 
        !           323: /*
        !           324: ** First pass routines.
        !           325: ** Output items to the temporary file.
        !           326: */
        !           327: /*
        !           328:  * Initialize the code writer.
        !           329:  */
        !           330: outinit()
        !           331: {
        !           332:        register TINFO *tp;
        !           333: #if    MONOLITHIC
        !           334:        register int    i;
        !           335: 
        !           336:        txtp = &txt[0];
        !           337:        relp = &rel[0];
        !           338: #if    EMUFIXUPS
        !           339:        has8087 = 0;
        !           340:        for (i=0; i<6; ++i)
        !           341:                wsp[i] = NULL;
        !           342: #endif
        !           343: #if    VAXFMT
        !           344:        vaxptr = &vaxbuf[0];
        !           345: #endif
        !           346: #endif
        !           347:        typelistp = tp = (TINFO *)malloc(sizeof(TINFO)+1);
        !           348:        tp->t_tp = NULL;
        !           349:        tp->t_tflag = 0;
        !           350:        tp->t_length = 1;
        !           351:        tp->t_info[0] = OTNIL;
        !           352:        typefixp = NULL;
        !           353: }
        !           354: 
        !           355: /*
        !           356:  * Output a segment switch.
        !           357:  */
        !           358: outseg(s)
        !           359: {
        !           360:        bput(TENTER);
        !           361:        bput(s);
        !           362: }
        !           363: 
        !           364: /*
        !           365:  * Output an absolute byte.
        !           366:  */
        !           367: outab(b)
        !           368: {
        !           369:        bput(TBYTE);
        !           370:        bput(b);
        !           371:        ++dot;
        !           372: }
        !           373: 
        !           374: /*
        !           375:  * Output an absolute word.
        !           376:  */
        !           377: outaw(w)
        !           378: {
        !           379:        bput(TWORD);
        !           380:        iput(w);
        !           381:        dot += 2;
        !           382: }
        !           383: 
        !           384: /*
        !           385:  * Output a full byte.
        !           386:  */
        !           387: outxb(sp, b, pcrf)
        !           388: register SYM *sp;
        !           389: {
        !           390:        register opcode;
        !           391: 
        !           392:        opcode = TBYTE;
        !           393:        if (sp != NULL)
        !           394:                opcode |= TSYM;
        !           395:        if (pcrf)
        !           396:                opcode |= TPCR;
        !           397:        bput(opcode);
        !           398:        bput(b);
        !           399:        if (sp != NULL)
        !           400:                pput(sp);
        !           401:        ++dot;
        !           402: }
        !           403: 
        !           404: /*
        !           405:  * Output a full word.
        !           406:  */
        !           407: outxw(sp, w, pcrf)
        !           408: register SYM *sp;
        !           409: {
        !           410:        register opcode;
        !           411: 
        !           412:        opcode = TWORD;
        !           413:        if (sp != NULL)
        !           414:                opcode |= TSYM;
        !           415:        if (pcrf)
        !           416:                opcode |= TPCR;
        !           417:        bput(opcode);
        !           418:        iput(w);
        !           419:        if (sp != NULL)
        !           420:                pput(sp);
        !           421:        dot += 2;
        !           422: }
        !           423: 
        !           424: #if    EMUFIXUPS
        !           425: /*
        !           426:  * Output a one byte opcode for the 8087.
        !           427:  */
        !           428: outfb(b)
        !           429: {
        !           430:        has8087 = 1;
        !           431:        bput(TBYTE|TWT);
        !           432:        bput(b);
        !           433:        ++dot;
        !           434: }
        !           435: 
        !           436: /*
        !           437:  * Output a two byte opcode for the 8087.
        !           438:  */
        !           439: outfw(w, prefix)
        !           440: {
        !           441:        has8087 = 1;
        !           442:        bput(TWORD|((prefix>>3)+TWST));
        !           443:        iput(w);
        !           444:        dot += 2;
        !           445: }
        !           446: #endif
        !           447: 
        !           448: #if    0
        !           449: /*
        !           450:  * Because the compiler now generates LARGE model code with links,
        !           451:  * the following routines are currently unused.
        !           452:  * They are retained for future reference.
        !           453:  */
        !           454: /*
        !           455:  * Output a 1 word object containing
        !           456:  * the base address of the current code segment.
        !           457:  */
        !           458: outcb()
        !           459: {
        !           460:        bput(TCODE);
        !           461:        dot += 2;
        !           462: }
        !           463: 
        !           464: /*
        !           465:  * Output a 1 word object containing
        !           466:  * the base address of the current data segment.
        !           467:  */
        !           468: outdb()
        !           469: {
        !           470:        bput(TDATA);
        !           471:        dot += 2;
        !           472: }
        !           473: #endif
        !           474: 
        !           475: /*
        !           476:  * Output a 1 word object containing
        !           477:  * the base address of the external symbol pointed to by 'sp'.
        !           478:  */
        !           479: outsb(sp)
        !           480: SYM *sp;
        !           481: {
        !           482:        bput(TBASE);
        !           483:        pput(sp);
        !           484:        dot += 2;
        !           485: }
        !           486: 
        !           487: /*
        !           488:  * Read a dlabel record from ifp.
        !           489:  * If l(evel) == 0, then only the DLABEL and class bytes have been read;
        !           490:  * For GDEF's and SEX's in SCODE, we save the symbol pointer, accumulate the
        !           491:  * argument list types, and back patch the type appropriately.
        !           492:  * For everything else at level zero, we translate the type to Oomf
        !           493:  * and write a truncated record to the scratch file.
        !           494:  */
        !           495: SYM *curfsp;   /* function sp */
        !           496: int curfna;    /* nargs */
        !           497: int curfar[NARGS];     /* arg types */
        !           498: 
        !           499: outdlab(l, class)
        !           500: {
        !           501:        register int value;
        !           502:        register int nline;
        !           503:        register SYM *sp;
        !           504:        register int type;
        !           505:        register int seg;
        !           506:        register int ttype;
        !           507: 
        !           508:        /* Get line number */
        !           509:        nline = iget();
        !           510: 
        !           511:        if (l != 0)
        !           512:                dbfatal(__LINE__);
        !           513:        value = 0;
        !           514:        seg = dotseg;
        !           515:        /* Get value */
        !           516:        if (class < DC_AUTO)
        !           517:                ;
        !           518:        else if (class < DC_MOS)
        !           519:                value = iget();
        !           520:        else
        !           521:                dbfatal(__LINE__);
        !           522: 
        !           523:        /* Get name */
        !           524:        sget(id, NCSYMB);
        !           525: 
        !           526:        /* Check for symbol table entry */
        !           527:        sp = NULL;
        !           528:        if (class==DC_GDEF || class==DC_SEX || class==DC_GREF) {
        !           529:                sp = glookup(id, 0);
        !           530:        } else {
        !           531:                /* Make all c names the same, hopefully */
        !           532:                strcat(id, "_");
        !           533:        }
        !           534:        if (sp != NULL) {
        !           535:                seg = sp->s_seg;
        !           536:                value = sp->s_value;
        !           537:        }
        !           538:        /* Check for tag definition */
        !           539:        if (class==DC_ETAG
        !           540:         || class==DC_STAG
        !           541:         || class==DC_UTAG)
        !           542:                ttype = tlookup(id, strlen(id)+1);
        !           543:        else
        !           544:                ttype = 0;
        !           545: 
        !           546:        /* Write part of truncated record */
        !           547:        bput(TDLAB);
        !           548:        bput(class);
        !           549:        iput(nline);
        !           550:        iput(value);
        !           551:        bput(seg);
        !           552:        sput(id);
        !           553: 
        !           554:        /* Get type and enter into table */
        !           555:        /* This will possibly overwrite id[], so it must come after glookup */
        !           556:        type = dbtmap(ttype);
        !           557: 
        !           558:        /* Write out truncated record. */
        !           559:        iput(type);
        !           560: 
        !           561:        /* Store the type for PUBDEF and EXTDEF records. */
        !           562:        if (sp != NULL) {
        !           563:                sp->s_type = type;
        !           564:                /* Begin collecting parameter types */
        !           565:                if ((class == DC_GDEF || class == DC_SEX)
        !           566:                 && sp->s_seg == SCODE) {
        !           567:                        curfsp = sp;
        !           568:                        curfna = 0;
        !           569:                }
        !           570:        }
        !           571:        /* Collect parameter types */
        !           572:        if (class == DC_PAUTO || class == DC_PREG)
        !           573:                curfar[curfna++] = type;
        !           574:        /* Dump the parameter list, tricky stuff. */
        !           575:        if (class == DC_LINE && id[0] == '{' && curfna >= 0) {
        !           576:                arglisttype();
        !           577:                curfna = -1;
        !           578:        }
        !           579:        /* Back patch tag definition */
        !           580:        if (ttype != 0)
        !           581:                tpatch(ttype, type);
        !           582: }
        !           583: 
        !           584: /*
        !           585:  * Enter a patch into the typefix list.
        !           586:  */
        !           587: tpatch(ttype, type)
        !           588: {
        !           589:        register TYFIX *tp;
        !           590: 
        !           591:        tp = (TYFIX *) malloc(sizeof(*tp));
        !           592:        if (tp == NULL) dbmemory(__LINE__);
        !           593:        tp->t_ttype = ttype;
        !           594:        tp->t_type = type;
        !           595:        tp->t_tp = typefixp;
        !           596:        typefixp = tp;
        !           597: }
        !           598: 
        !           599: /*
        !           600:  * Return type index associated with type definition
        !           601:  * at infop of length len.
        !           602:  * Define a new TINFO item if necessary.
        !           603:  */
        !           604: tlookup(infop, len)
        !           605: register char *infop;
        !           606: int len;
        !           607: {
        !           608: #if    INTEL
        !           609:        register TINFO *tp, *lasttp;
        !           610:        register int i, index;
        !           611:        register char *cp1, *cp2;
        !           612:        tp = typelistp;
        !           613:        index = 1;
        !           614:        /* Search the TINFO list for the type. */
        !           615:        while (tp != NULL) {
        !           616:                if (tp->t_length == len) {
        !           617:                        cp1 = infop;
        !           618:                        cp2 = tp->t_info;
        !           619:                        i = len;
        !           620:                        while ((*cp1++ == *cp2++) && (--i > 0))
        !           621:                                ;
        !           622:                        if (i == 0) return (index);
        !           623:                }
        !           624:                index++;
        !           625:                lasttp = tp;
        !           626:                tp = tp->t_tp;
        !           627:        }
        !           628:        /* Not found, add new type to TINFO list. */
        !           629:        if ((tp=(TINFO *)malloc(sizeof(TINFO)+len)) == NULL)
        !           630:                cnomem("tlookup");
        !           631:        tp->t_tp = NULL;
        !           632:        tp->t_tflag = 0;
        !           633:        tp->t_length = len;
        !           634:        cp1 = tp->t_info;
        !           635:        while (len--)
        !           636:                *cp1++ = *infop++;
        !           637:        /* Outinit puts the nil type on the list so never empty */
        !           638:        lasttp->t_tp = tp;
        !           639:        return (index);
        !           640: #else
        !           641:        return (1);
        !           642: #endif
        !           643: }
        !           644: 
        !           645: /*
        !           646:  * Length and OMF type of scalar C types.
        !           647:  * The order corresponds to the order of DT_ types in ops.h.
        !           648:  */
        !           649: #if    INTEL
        !           650: static char ntypes [DT_DOUBLE+1][2] = {
        !           651:        { 0x00, OTNIL },                /* DT_NONE */
        !           652:        { 0x08, OTSINT },               /* DT_CHAR */
        !           653:        { 0x08, OTUINT },               /* DT_UCHAR */
        !           654:        { 0x10, OTSINT },               /* DT_SHORT */
        !           655:        { 0x10, OTUINT },               /* DT_USHORT */
        !           656:        { 0x10, OTSINT },               /* DT_INT */
        !           657:        { 0x10, OTUINT },               /* DT_UINT */
        !           658:        { 0x20, OTSINT },               /* DT_LONG */
        !           659:        { 0x20, OTUINT },               /* DT_ULONG */
        !           660:        { 0x20, OTREAL },               /* DT_FLOAT */
        !           661:        { 0x40, OTREAL }                /* DT_DOUBLE */
        !           662: };
        !           663: #endif
        !           664: 
        !           665: /*
        !           666:  * Read the dimension/type/info list from input
        !           667:  * and return the Ooomf type index.
        !           668:  * Store the size back through the pointer supplied.
        !           669:  * This routine is reentrant so that
        !           670:  * types of structure members are mappable while
        !           671:  * the structure definition is mapped.
        !           672:  */
        !           673: 
        !           674: dbtmap(ttype)
        !           675: {
        !           676:        int             type;
        !           677:        unsigned        size;
        !           678:        register char   *bp;
        !           679:        char            bb[10];
        !           680: 
        !           681:        bp = bb;
        !           682:        type = bget();
        !           683:        size = iget();
        !           684:        switch (type) {
        !           685:        case DT_NONE:
        !           686: #if    INTEL
        !           687:                *bp++ = OTNIL;
        !           688: #endif
        !           689:                break;
        !           690:        case DT_CHAR:
        !           691:        case DT_UCHAR:
        !           692:        case DT_SHORT:
        !           693:        case DT_USHORT:
        !           694:        case DT_INT:
        !           695:        case DT_UINT:
        !           696:        case DT_LONG:
        !           697:        case DT_ULONG:
        !           698:        case DT_FLOAT:
        !           699:        case DT_DOUBLE:
        !           700: #if    INTEL
        !           701:                *bp++ = OTSCAL;                 /* SCALAR */
        !           702:                bp = setsize(bp, (long)(ntypes[type][0]));      /* length */
        !           703:                *bp++ = ntypes[type][1];        /* OMF type */
        !           704: #endif
        !           705:                break;
        !           706:        case DT_VOID:
        !           707: #if    INTEL
        !           708:                *bp++ = OTNIL;
        !           709: #endif
        !           710:                break;
        !           711:        case DT_STRUCT:
        !           712:        case DT_UNION:
        !           713:        case DT_ENUM:
        !           714:                if (bget() == DX_NAME) {
        !           715:                        lastsize = ((long)size) * NBPBYTE;
        !           716:                        return (dbxname(ttype));
        !           717:                }
        !           718:                else if (type == DT_STRUCT)
        !           719:                        return (dbxstruct(size, ttype));
        !           720:                else if (type == DT_UNION)
        !           721:                        return (dbxunion(size, ttype));
        !           722:                else
        !           723:                        return (dbxenum(size, ttype));
        !           724:        case DD_PTR:
        !           725: #if    INTEL
        !           726:                *bp++ = OTPOINT;
        !           727:                *bp++ = OTINDEX;                
        !           728: #endif
        !           729:                type = dbtmap(ttype);
        !           730: #if    INTEL
        !           731:                bp = setindex(bp, type);
        !           732:                type = tlookup(bb, bp-bb);
        !           733:                bp = bb;
        !           734:                *bp++ = OTSCAL;
        !           735:                bp = setsize(bp, isvariant(VLARGE) ? 0x20L : 0x10L);
        !           736:                *bp++ = OTINDEX;
        !           737:                bp = setindex(bp, type);
        !           738: #endif
        !           739:                break;
        !           740:        case DD_FUNC:
        !           741: #if    INTEL
        !           742:                *bp++ = OTPROC;
        !           743:                *bp++ = OTNIL;
        !           744:                *bp++ = OTINDEX;
        !           745: #endif
        !           746:                type = dbtmap(ttype);
        !           747: #if    INTEL
        !           748:                bp = setindex(bp, type);
        !           749:                if (isvariant(VLARGE)) *bp++ = OTLFUNC;
        !           750:                else *bp++ = OTSFUNC;
        !           751:                *bp++ = 0;      /* Zero args, possibly corrected later */
        !           752: #endif
        !           753:                break;
        !           754:        case DD_ARRAY:
        !           755:                type = dbtmap(ttype);
        !           756: #if    INTEL
        !           757:                *bp++ = OTARRAY;
        !           758:                bp = setsize(bp, ((long)size)*NBPBYTE);
        !           759:                *bp++ = OTINDEX;
        !           760:                bp = setindex(bp, type);
        !           761: #endif
        !           762:                break;
        !           763:        default:
        !           764:                dbfatal(__LINE__);
        !           765:        }
        !           766:        return (tlookup(bb, bp-bb));
        !           767: }
        !           768: 
        !           769: dbfatal(lineno)
        !           770: {
        !           771:        cbotch("debug label format in %d", lineno);
        !           772: }
        !           773: 
        !           774: dbmemory(lineno)
        !           775: {
        !           776:        cnomem("dbmemory %d", lineno);
        !           777: }
        !           778: 
        !           779: /*
        !           780:  * Construct typdef for enum, struct, or union.
        !           781:  */
        !           782: dbxname(ttype)
        !           783: {
        !           784:        register char   *bp;
        !           785:        register TINFO  *tp;
        !           786:        register int i;
        !           787: 
        !           788:        /* DX_NAME records supply tag name of type which
        !           789:         * will be defined later.
        !           790:         * Tag references point to type consisting of
        !           791:         * the tag name; type will be backpatched into
        !           792:         * a struct/union/enum typdef */
        !           793:        iget();         /* Dummy size */
        !           794:        bp = &id[0];
        !           795:        while (*bp = bget())
        !           796:                ++bp;
        !           797:        *bp = '_';
        !           798:        *++bp = 0;
        !           799:        i = tlookup(id, ++bp-id);
        !           800:        tp = gettype(i);
        !           801:        tp->t_tflag = 1;
        !           802:        return(i);
        !           803: }
        !           804: 
        !           805: dbxstruct(s, ttype)
        !           806: unsigned       s;      /* Size of structure in bytes */
        !           807: {
        !           808:        int     nmemb;  /* The number of members */
        !           809:        int     i;      /* Member counter */
        !           810:        unsigned        bwid;   /* Bit width of current field */
        !           811:        unsigned        boff;   /* Bit offset of current field */
        !           812:        unsigned        valu;   /* Byte offset of current member */
        !           813:        int     type;   /* type index of current member */
        !           814: #if    INTEL
        !           815:        int     size;   /* Size of name field */
        !           816:        long    offs;   /* Bit offset computed from valu and boff */
        !           817:        long    loffs;  /* Bit offset computed from previous member */
        !           818:        int     nname;  /* Number of bytes required for name list */
        !           819:        int     tlist;  /* Type list index */
        !           820:        int     nlist;  /* Name list index */
        !           821:        struct  slist {
        !           822:                struct slist *sl_sp;
        !           823:                int     sl_type;
        !           824:                char    sl_id[];
        !           825:        };
        !           826:        struct slist *sp1;
        !           827:        register struct slist *sp2;
        !           828:        char *lp;
        !           829:        register char *bp;
        !           830:        char bb[64];
        !           831: #endif
        !           832: 
        !           833:        /* Struct member list */
        !           834: #if    INTEL
        !           835:        sp1 = NULL;
        !           836:        offs = loffs = 0;
        !           837:        nname = 0;
        !           838: #endif
        !           839:        nmemb = iget();         /* Number of members */
        !           840:                                /* Does not include filler fields */
        !           841:        /* Read in member descriptions */
        !           842:        for (i = nmemb; i > 0; i -= 1) {
        !           843:                if (bget() != DC_MOS)
        !           844:                        dbfatal(__LINE__);
        !           845:                iget();         /* forget line */
        !           846:                bwid = bget();  /* bit width */
        !           847:                boff = bget();  /* bit offset */
        !           848:                valu = iget();  /* byte offset */
        !           849:                sget(id, NCSYMB);
        !           850: #if    INTEL
        !           851:                strcat(id, "_");
        !           852:                /* Enter into list, possibly prefixing nil filler field */
        !           853:                offs = (long)valu * (long)NBPBYTE + boff;
        !           854:                if (offs != loffs) {
        !           855:                        /* Nil named filler field so pscope doesn't lose */
        !           856:                        /* its place in the structure */
        !           857:                        nmemb += 1;
        !           858:                        nname += 2;     /* Bytes required for nlist */
        !           859:                        sp2 = (struct slist *)malloc(sizeof(*sp2)+1);
        !           860:                        if (sp2 == NULL)
        !           861:                                dbmemory(__LINE__);
        !           862:                        sp2->sl_type = dbfmap((int)(offs-loffs), DT_UINT);
        !           863:                        sp2->sl_id[0] = 0;
        !           864:                        sp2->sl_sp = sp1;
        !           865:                        sp1 = sp2;
        !           866:                }
        !           867:                size = strlen(id)+2;    /* OTNAME, count/nul */
        !           868:                nname += size;
        !           869:                sp2 = (struct slist *)malloc(sizeof(*sp2)+size);
        !           870:                if (sp2 == NULL) dbmemory(__LINE__);
        !           871:                strcpy(sp2->sl_id, id);
        !           872: #endif
        !           873:                /* Now get the type with its possible id field */
        !           874:                if (bwid != 0) {
        !           875:                        /* Only fields have non-zero widths and offsets */
        !           876:                        type = dbfmap(bwid, bget());
        !           877:                        iget(); /* Subtype size */
        !           878:                        lastsize = bwid;
        !           879:                } else {
        !           880:                        /* Non field member, must lookup its width */
        !           881:                        type = dbtmap(0);
        !           882:                }
        !           883: #if    INTEL
        !           884:                sp2->sl_type = type;
        !           885:                sp2->sl_sp = sp1;
        !           886:                sp1 = sp2;
        !           887:                loffs = offs + lastsize;
        !           888: #endif
        !           889:        }
        !           890: #if    INTEL
        !           891:        /* Reverse member list */
        !           892:        sp2 = sp1;
        !           893:        sp1 = NULL;
        !           894:        while (sp2 != NULL) {
        !           895:                struct slist *tsp;
        !           896: 
        !           897:                tsp = sp2->sl_sp;
        !           898:                sp2->sl_sp = sp1;
        !           899:                sp1 = sp2;
        !           900:                sp2 = tsp;
        !           901:        }
        !           902:        /* Construct type list */
        !           903:        lp = bp = malloc(nmemb*3+nmemb/8+8);
        !           904:        if (bp == NULL) dbmemory(__LINE__);
        !           905:        *bp++ = OTLIST;
        !           906:        sp2 = sp1;
        !           907:        for (i = 0; i < nmemb; i += 1) {
        !           908:                if ((i%8) == 7) *bp++ = 0;      /* EN byte */
        !           909:                *bp++ = OTINDEX;
        !           910:                bp = setindex(bp, sp2->sl_type);
        !           911:                sp2 = sp2->sl_sp;
        !           912:        }
        !           913:        tlist = tlookup(lp, bp-lp);
        !           914:        free(lp);
        !           915:        /* Construct name list */
        !           916:        lp = bp = malloc(nname+nmemb/8+8);
        !           917:        if (bp == NULL) dbmemory(__LINE__);
        !           918:        *bp++ = OTLIST;
        !           919:        sp2 = sp1;
        !           920:        for (i = 0; i < nmemb; i += 1) {
        !           921:                if (sp2==NULL) dbfatal(__LINE__);
        !           922:                if ((i%8) == 7) *bp++ = 0;      /* EN byte */
        !           923:                *bp++ = OTNAME;
        !           924:                bp = setsymid(bp, sp2->sl_id);
        !           925:                sp2 = sp2->sl_sp;
        !           926:                free(sp1);
        !           927:                sp1 = sp2;
        !           928:        }
        !           929:        nlist = tlookup(lp, bp-lp);
        !           930:        free(lp);
        !           931:        /* Construct the true type record */
        !           932:        bp = &bb[0];
        !           933:        *bp++ = OTSTRUC;
        !           934:        /* Set length of structure */
        !           935:        bp = setsize(bp, ((long)s)*NBPBYTE);
        !           936:        /* Set number of members */
        !           937:        bp = setnumb(bp, (long)nmemb);
        !           938:        *bp++ = OTINDEX;
        !           939:        bp = setindex(bp, tlist);
        !           940:        *bp++ = OTINDEX;
        !           941:        bp = setindex(bp, nlist);
        !           942:        *bp++ = OTNAME;
        !           943:        if (ttype == 0)
        !           944:                *bp++ = 0;
        !           945:        else
        !           946:                bp = setsymid(bp, gettype(ttype)->t_info);
        !           947:        return (tlookup(bb, bp-bb));
        !           948: #else
        !           949:        return (1);
        !           950: #endif
        !           951: }
        !           952: 
        !           953: /*
        !           954:  * Map a bitfield type.
        !           955:  * Should only have CHAR, UCHAR, sort of type.
        !           956:  */
        !           957: dbfmap(bw, bt)
        !           958: int bw;                /* Bit width */
        !           959: int bt;                /* Base type */
        !           960: {
        !           961: #if    INTEL
        !           962:        char bb[4];
        !           963: 
        !           964:        bb[0] = OTSCAL;
        !           965:        bb[1] = bw;
        !           966:        switch (bt) {
        !           967:        case DT_CHAR:   case DT_SHORT:  case DT_INT:    case DT_LONG:
        !           968:                bb[2] = OTSINT;
        !           969:                break;
        !           970:        case DT_UCHAR:  case DT_USHORT: case DT_UINT:   case DT_ULONG:
        !           971:                bb[2] = OTUINT;
        !           972:                break;
        !           973:        default:
        !           974:                dbfatal(__LINE__);
        !           975:        }
        !           976:        return (tlookup(bb, 3));
        !           977: #else
        !           978:        return (1);
        !           979: #endif
        !           980: }
        !           981: 
        !           982: dbxunion(s, ttype)
        !           983: unsigned       s;      /* Size of union in bytes */
        !           984: {
        !           985:        int     nmemb;
        !           986:        int     i;
        !           987: #if    INTEL
        !           988:        char    *lp;
        !           989:        register char *bp;
        !           990:        int size;
        !           991: #endif
        !           992: 
        !           993:        /* Union member list */
        !           994:        nmemb = iget();         /* Number of members in union */
        !           995: #if    INTEL
        !           996:        size = (ttype) ? strlen(gettype(ttype)->t_info) : 0;
        !           997:        lp = bp = malloc(18+7*nmemb+(10+3*nmemb)/8+1+size);
        !           998:        if (bp == NULL) dbmemory(__LINE__);
        !           999:        *bp++ = OTSTRUC;
        !          1000:        bp = setsize(bp, ((long)s)*NBPBYTE);
        !          1001:        *bp++ = 0;              /* Invariant records */
        !          1002:        *bp++ = OTNIL;          /* Invariant type list */
        !          1003:        *bp++ = OTNIL;          /* Invariant name list */
        !          1004:        *bp++ = OTNAME;
        !          1005:        if (ttype == 0)
        !          1006:                *bp++ = 0;
        !          1007:        else
        !          1008:                bp = setsymid(bp, gettype(ttype)->t_info);
        !          1009:        *bp++ = OTUPACK;        /* Unpacked or something */
        !          1010:        bp = setnumb(bp, (long)nmemb);
        !          1011:        *bp++ = 0;              /* EN byte, for more leaves */
        !          1012:        *bp++ = OTNIL;          /* Selector field type */
        !          1013:        *bp++ = OTNIL;          /* Selector field name */
        !          1014: #endif
        !          1015:        i = 1;
        !          1016:        while (--nmemb >= 0) {
        !          1017:                int     type;
        !          1018: #if    INTEL
        !          1019:                int     tlist;
        !          1020:                int     nlist;
        !          1021:                char    bb[50];
        !          1022:                register char *tbp;
        !          1023: #endif
        !          1024: 
        !          1025:                if (bget() != DC_MOU) dbfatal(__LINE__);
        !          1026:                iget();         /* forget line */
        !          1027:                bget();         /* forget bit width */
        !          1028:                bget();         /* forget bit offset */
        !          1029:                iget();         /* forget byte offset */
        !          1030:                sget(id, NCSYMB);
        !          1031: #if    INTEL
        !          1032:                /* Make name list item */
        !          1033:                strcat(id, "_");
        !          1034:                tbp = bb;
        !          1035:                *tbp++ = OTLIST;
        !          1036:                *tbp++ = OTNAME;
        !          1037:                tbp = setsymid(tbp, id);
        !          1038:                nlist = tlookup(bb, tbp-bb);
        !          1039: #endif
        !          1040:                type = dbtmap(0);
        !          1041: #if    INTEL
        !          1042:                /* Make type list item */
        !          1043:                tbp = bb;
        !          1044:                *tbp++ = OTLIST;
        !          1045:                *tbp++ = OTINDEX;
        !          1046:                tbp = setindex(tbp, type);
        !          1047:                tlist = tlookup(bb, tbp-bb);
        !          1048:                /* Append member items to typdef */
        !          1049:                if ((++i%8) == 0) *bp++ = 0;    /* EN extend list */
        !          1050:                *bp++ = 1;
        !          1051:                if ((++i%8) == 0) *bp++ = 0;
        !          1052:                *bp++ = OTINDEX;
        !          1053:                bp = setindex(bp, tlist);
        !          1054:                if ((++i%8) == 0) *bp++ = 0;
        !          1055:                *bp++ = OTINDEX;
        !          1056:                bp = setindex(bp, nlist);
        !          1057: #endif
        !          1058:        }
        !          1059: #if    INTEL
        !          1060:        lastsize = ((long)s) * NBPBYTE;
        !          1061:        i = tlookup(lp, bp-lp);
        !          1062:        free(lp);
        !          1063:        return (i);
        !          1064: #else
        !          1065:        return (1);
        !          1066: #endif
        !          1067: }
        !          1068: 
        !          1069: dbxenum(s, ttype)
        !          1070: unsigned       s;      /* Size of enum type in bytes */
        !          1071: {
        !          1072:        int     nmemb;
        !          1073:        int     i;
        !          1074:        int     valu;
        !          1075:        int     nname;
        !          1076: #if    INTEL
        !          1077:        int     minvalu;
        !          1078:        int     maxvalu;
        !          1079:        int     range;
        !          1080:        int     nlist;
        !          1081:        struct el {
        !          1082:                struct el *el_ep;
        !          1083:                int     el_valu;
        !          1084:                char    el_id[];
        !          1085:        };
        !          1086:        struct el **epp;
        !          1087:        register char *bp;
        !          1088:        char *lp;
        !          1089:        char bb[16];
        !          1090: #endif
        !          1091:        
        !          1092:        /* Enum member list */
        !          1093:        nname = 0;
        !          1094:        nmemb = iget();         /* Number of members in enum */
        !          1095: #if    INTEL
        !          1096:        epp = (struct el **)malloc(nmemb * sizeof(*epp));
        !          1097:        if (epp == NULL) dbmemory(__LINE__);
        !          1098:        maxvalu = -MAXIV-1;
        !          1099:        minvalu = MAXIV;
        !          1100: #endif
        !          1101:        for (i = 0; i < nmemb; i += 1) {
        !          1102: #if    INTEL
        !          1103:                int size;
        !          1104:                register struct el *ep;
        !          1105: #endif
        !          1106: 
        !          1107: 
        !          1108:                if (bget() != DC_MOE) dbfatal(__LINE__);
        !          1109:                iget();         /* forget line */
        !          1110:                valu = iget();  /* value */
        !          1111:                sget(id, NCSYMB);
        !          1112: #if    INTEL
        !          1113:                strcat(id, "_");
        !          1114:                size = strlen(id)+2;
        !          1115:                nname += size;
        !          1116: #endif
        !          1117:                dbtmap(0);
        !          1118: #if    INTEL
        !          1119:                ep = malloc(sizeof(*ep)+size);
        !          1120:                if (ep == NULL) dbmemory(__LINE__);
        !          1121:                ep->el_valu = valu;
        !          1122:                strcpy(ep->el_id, id);
        !          1123:                if (valu < minvalu)
        !          1124:                        minvalu = valu;
        !          1125:                else if (valu > maxvalu)
        !          1126:                        maxvalu = valu;
        !          1127:                epp[i] = ep;
        !          1128: #endif
        !          1129:        }
        !          1130: #if    INTEL
        !          1131:        /* Construct name list */
        !          1132:        range = maxvalu - minvalu + 1;
        !          1133:        if (range > nmemb)
        !          1134:                nname += (range-nmemb)*2;
        !          1135:        nname += range/8 + 3;
        !          1136:        lp = bp = malloc(nname);
        !          1137:        if (bp == NULL) dbmemory(__LINE__);
        !          1138:        *bp++ = OTLIST;
        !          1139:        for (valu = minvalu; valu <= maxvalu; valu += 1) {
        !          1140:                if (((valu-minvalu)%8) == 7) *bp++ = 0; /* EN byte */
        !          1141:                *bp++ = OTNAME;
        !          1142:                for (i = 0; i < nmemb; i += 1)
        !          1143:                        if (epp[i]->el_valu == valu)
        !          1144:                                break;
        !          1145:                if (i < nmemb) {
        !          1146:                        bp = setsymid(bp, epp[i]->el_id);
        !          1147:                        free(epp[i]);
        !          1148:                } else
        !          1149:                        *bp++ = 0;
        !          1150:                if (bp > lp + nname) cbotch("enum overrun");
        !          1151:        }
        !          1152:        free(epp);
        !          1153:        nlist = tlookup(lp, bp-lp);
        !          1154:        free(lp);
        !          1155:        /* Construct type record */
        !          1156:        bp = &bb[0];
        !          1157:        *bp++ = OTSCAL;
        !          1158:        bp = setsize(bp, ((long)s)*NBPBYTE);
        !          1159:        *bp++ = OTSINT;
        !          1160:        *bp++ = OTNAME;
        !          1161:        if (ttype == 0)
        !          1162:                *bp++ = 0;
        !          1163:        else
        !          1164:                bp = setsymid(bp, gettype(ttype)->t_info);
        !          1165:        *bp++ = OTINDEX;
        !          1166:        bp = setindex(bp, nlist);
        !          1167:        bp = setnumb(bp, (long)minvalu);
        !          1168:        bp = setnumb(bp, (long)maxvalu);
        !          1169:        return (tlookup(bb, bp-bb));
        !          1170: #else
        !          1171:        return (1);
        !          1172: #endif
        !          1173: }
        !          1174: 
        !          1175: /*
        !          1176:  * Construct list of arg types and return its type.
        !          1177:  * The list may contain more than 8 leaves, requiring extra EN bytes.
        !          1178:  * The function's type with zero args has already been computed.
        !          1179:  * We must expand the type and append nargs, arglist type, and
        !          1180:  * reenter.
        !          1181:  */
        !          1182: arglisttype()
        !          1183: {
        !          1184: #if    INTEL
        !          1185:        int type;
        !          1186:        int oldtypesize;
        !          1187:        char *oldtype;
        !          1188: 
        !          1189:        if (curfna == 0)
        !          1190:                return;
        !          1191:        {       /* Compute argument list type */
        !          1192:                register char *bp;
        !          1193:                register int i;
        !          1194:                register char *sbp;
        !          1195:                char b[3*NARGS+3];
        !          1196: 
        !          1197:                bp = &b[0];
        !          1198:                *bp++ = OTLIST;
        !          1199:                for (i=0; i<curfna; ++i) {
        !          1200:                        if (i%8 == 7)
        !          1201:                                *bp++ = 0;              /* EN byte */
        !          1202:                        *bp++ = OTINDEX;
        !          1203:                        sbp = bp;
        !          1204:                        *bp++ = OTPARA;
        !          1205:                        *bp++ = OTINDEX;
        !          1206:                        bp = setindex(bp, curfar[i]);
        !          1207:                        bp = setindex(sbp, tlookup(sbp, bp-sbp));
        !          1208:                }
        !          1209:                type = tlookup(b, bp-b);
        !          1210:        }
        !          1211:        {       /* Find old type */
        !          1212:                register TINFO *tp;
        !          1213: 
        !          1214:                tp = gettype(curfsp->s_type);
        !          1215:                oldtype = tp->t_info;
        !          1216:                oldtypesize = tp->t_length;
        !          1217:        }
        !          1218:        {       /* Expand and compute new type */
        !          1219:                register char *bp;
        !          1220:                char b[16];
        !          1221: 
        !          1222:                bp = b;
        !          1223:                while (--oldtypesize > 0)       /* Last byte should be zero */
        !          1224:                        *bp++ = *oldtype++;
        !          1225:                bp = setnumb(bp, (long)curfna); /* Number of args */
        !          1226:                *bp++ = OTINDEX;
        !          1227:                bp = setindex(bp, type);        /* Arg types */
        !          1228:                curfsp->s_type = tlookup(b, bp-b);
        !          1229:        }
        !          1230: #else
        !          1231:        return;
        !          1232: #endif
        !          1233: }
        !          1234: 
        !          1235: /*
        !          1236:  * Output a debug line record.
        !          1237:  */
        !          1238: outdlin(op)
        !          1239: {
        !          1240:        bput(TDLAB);
        !          1241:        bput(DC_LINE);
        !          1242:        iput(line);
        !          1243:        bput(op);
        !          1244:        bput(0);
        !          1245:        bput(1);        /* Nil type */
        !          1246: }
        !          1247: 
        !          1248: /*
        !          1249:  * Output a debug relocation record.
        !          1250:  * This 'n' is an index into the list of debug records written.
        !          1251:  */
        !          1252: outdloc(n)
        !          1253: {
        !          1254:        bput(TDLOC);
        !          1255:        iput(n);
        !          1256: }
        !          1257: 
        !          1258: /*
        !          1259:  * Finish up the code.
        !          1260:  */
        !          1261: outdone()
        !          1262: {
        !          1263:        if (notvariant(VASM))
        !          1264:                bput(TEND);
        !          1265: #if    EMUFIXUPS
        !          1266:        /*
        !          1267:         * Put magic names into the symbol table
        !          1268:         * if any 8087 code was generated.
        !          1269:         */
        !          1270:        if (has8087) {
        !          1271:                wsp[0] = glookup("M:_WT",  0);
        !          1272:                wsp[1] = glookup("M:_WST", 0);
        !          1273:                wsp[2] = glookup("M:_WES", 0);
        !          1274:                wsp[3] = glookup("M:_WCS", 0);
        !          1275:                wsp[4] = glookup("M:_WSS", 0);
        !          1276:                wsp[5] = glookup("M:_WDS", 0);
        !          1277:        }
        !          1278: #endif
        !          1279: }
        !          1280: 
        !          1281: /*
        !          1282: ** Second pass routines.
        !          1283: ** Read the temporary file and write the output.
        !          1284: */
        !          1285: /*
        !          1286:  * Finish up.
        !          1287:  * Figure out the sizes and final values
        !          1288:  * of everything. Copy the code from the scratch
        !          1289:  * file back to the output file.
        !          1290:  */
        !          1291: copycode()
        !          1292: {
        !          1293:        register int    op;
        !          1294:        register SYM    *sp;
        !          1295:        register int    i;
        !          1296:        register ADDRESS v;
        !          1297:        int             fixup;
        !          1298:        int             nd;
        !          1299:        int             data;
        !          1300:        char            coment[30];
        !          1301: 
        !          1302:        /*
        !          1303:         * Assign the base addresses to the
        !          1304:         * compiler's logical segments, based on the
        !          1305:         * compilation model and the setting of the VROM
        !          1306:         * variant flag. The VROM option only changes
        !          1307:         * where the strings are placed.
        !          1308:         */
        !          1309:        seg[SCODE].s_mseek = 0;
        !          1310:        v  = rup(seg[SCODE].s_dot);
        !          1311:        seg[SLINK].s_mseek = v;
        !          1312:        v += rup(seg[SLINK].s_dot);
        !          1313:        if ((isvariant(VSMALL))  || (isvariant(VRAM))) {
        !          1314:                code_size = v;
        !          1315:                v = 0;
        !          1316:        }
        !          1317:        seg[SPURE].s_mseek = v;
        !          1318:        v += rup(seg[SPURE].s_dot);
        !          1319:        if (notvariant(VROM) && notvariant(VRAM)) {
        !          1320:                if (isvariant(VSMALL))
        !          1321:                        const_size = v;
        !          1322:                else
        !          1323:                        code_size  = v;
        !          1324:                v = 0;
        !          1325:        }
        !          1326:        seg[SSTRN].s_mseek = v;
        !          1327:        v += rup(seg[SSTRN].s_dot);
        !          1328:        if (isvariant(VROM)) {
        !          1329:                if (isvariant(VSMALL))
        !          1330:                        const_size = v;
        !          1331:                else
        !          1332:                        code_size  = v;
        !          1333:                v = 0;
        !          1334:        }
        !          1335:        seg[SDATA].s_mseek = v;
        !          1336:        v += rup(seg[SDATA].s_dot);
        !          1337:        seg[SBSS].s_mseek  = v;
        !          1338:        bss_size  = rup(seg[SBSS].s_dot);
        !          1339:        data_size = v + bss_size;
        !          1340:        /*
        !          1341:         * Put out the preamble.
        !          1342:         */
        !          1343:        puttheadr();
        !          1344:        coment[0] = coment[1] = '\0';
        !          1345:        sprintf(&coment[2], "%s %s %s %s",
        !          1346: #ifdef vax
        !          1347:                "VAX",
        !          1348: #else
        !          1349: #ifdef UDI
        !          1350:                "UDI",
        !          1351: #else
        !          1352: #ifdef MSDOS
        !          1353:                "MS-DOS",
        !          1354: #else
        !          1355:                "COHERENT",
        !          1356: #endif
        !          1357: #endif
        !          1358: #endif
        !          1359: #if    INTEL
        !          1360:                "iC86", VERSINT,
        !          1361: #else
        !          1362:                "MWC86", VERSMWC,
        !          1363: #endif
        !          1364:                (isvariant(VSMALL)) ? "SMALL" : "LARGE");
        !          1365:        putrecord(COMENT, coment, strlen(&coment[2])+2);
        !          1366:        if (isvariant(VLARGE)) {
        !          1367:                putlnames();
        !          1368:                putsegdef(PARA|CCON, code_size, 2, 4);
        !          1369:                putsegdef(PARA|CCON, data_size, 3, 5);
        !          1370:        } else {
        !          1371:                putrecord(LNAMES, lnames, sizeof(lnames));
        !          1372:                putsegdef(PARA|CCON, code_size,  2, 2);
        !          1373:                putsegdef(PARA|CCON, const_size, 4, 4);
        !          1374:                putsegdef(PARA|CCON, data_size,  3, 3);
        !          1375:                putsegdef(PARA|CSTACK,       0,  5, 5);
        !          1376:                putsegdef(PARA|CMEM,     0,  6, 6);
        !          1377:                putrecord(GRPDEF, gdef1, sizeof(gdef1));
        !          1378:                putrecord(GRPDEF, gdef2, sizeof(gdef2));
        !          1379:        }
        !          1380:        /*
        !          1381:         * Write out type and symbol definitions.
        !          1382:         */
        !          1383:        puttypdef();
        !          1384:        putsymdef();
        !          1385: 
        !          1386:        /*
        !          1387:         * Copy out code.
        !          1388:         */
        !          1389:        if (isvariant(VLARGE))
        !          1390:                putrecord(FIXUPP, lthred, sizeof(lthred));
        !          1391:        else
        !          1392:                putrecord(FIXUPP, sthred, sizeof(sthred));
        !          1393:        for (i=0; i<NSEG; ++i)
        !          1394:                seg[i].s_dot = seg[i].s_mseek;
        !          1395:        dotseg = SCODE;
        !          1396:        dot = seg[SCODE].s_dot;
        !          1397:        while ((op = bget()) != TEND) {
        !          1398:                switch (op) {
        !          1399: 
        !          1400:                case TENTER:
        !          1401:                        notenuf();
        !          1402:                        seg[dotseg].s_dot = dot;
        !          1403:                        dotseg = bget();
        !          1404:                        dot = seg[dotseg].s_dot;
        !          1405:                        continue;
        !          1406:                case TDLAB:
        !          1407:                        getdlab();
        !          1408:                        continue;
        !          1409:                case TDLOC:
        !          1410:                        getdloc();
        !          1411:                        continue;
        !          1412: #if    0
        !          1413: /* See comment on outcb()/outdb() above. */
        !          1414:                case TCODE:
        !          1415:                case TDATA:
        !          1416:                        if (isvariant(VSMALL))
        !          1417:                                cbotch("code:data");
        !          1418:                        enuf(2, 4);
        !          1419:                        fixup = txtp - (txt+3);
        !          1420:                        *txtp++ = 0;
        !          1421:                        *txtp++ = 0;
        !          1422:                        *relp++ = LOCAT|M|BASE|(fixup>>8);
        !          1423:                        *relp++ = fixup;
        !          1424:                        *relp++ = FTARGET|SECWAY|TSI;
        !          1425:                        *relp++ = (op==TCODE) ? 1 : 2;
        !          1426:                        dot += 2;
        !          1427:                        continue;
        !          1428: #endif
        !          1429:                case TBASE:
        !          1430:                        if (isvariant(VSMALL))
        !          1431:                                cbotch("base");
        !          1432:                        sp = pget();
        !          1433:                        if ((sp->s_flag&S_DEF) != 0) {
        !          1434:                                enuf(2, 4);
        !          1435:                                fixup = txtp - (txt+3);
        !          1436:                                *txtp++ = 0;
        !          1437:                                *txtp++ = 0;
        !          1438:                                *relp++ = LOCAT|M|BASE|(fixup>>8);
        !          1439:                                *relp++ = fixup;
        !          1440:                                *relp++ = FTARGET|SECWAY|TSI;
        !          1441:                                *relp++ = getsegindex(sp->s_seg);
        !          1442:                                dot += 2;
        !          1443:                                continue;
        !          1444:                        }
        !          1445:                        enuf(2, 5);
        !          1446:                        fixup = txtp - (txt+3);
        !          1447:                        *txtp++ = 0;
        !          1448:                        *txtp++ = 0;
        !          1449:                        *relp++ = LOCAT|M|BASE|(fixup>>8);
        !          1450:                        *relp++ = fixup;
        !          1451:                        *relp++ = FTARGET|SECWAY|TEI;
        !          1452:                        relp = setindex(relp, sp->s_ref);
        !          1453:                        dot += 2;
        !          1454:                        continue;
        !          1455:                }
        !          1456:                if ((op&TTYPE) == TBYTE) {
        !          1457:                        nd = 1;
        !          1458:                        data = bget();
        !          1459:                } else {
        !          1460:                        nd = 2;
        !          1461:                        data = iget();
        !          1462:                }
        !          1463: #if    EMUFIXUPS
        !          1464:                /*
        !          1465:                 * 8087 opcodes.
        !          1466:                 * Apply magic relocation for the emulator.
        !          1467:                 */
        !          1468:                if ((op&T8087) != 0) {
        !          1469:                        sp = wsp[((op&T8087)-TWT)>>5];
        !          1470:                        enuf(nd, 7);
        !          1471:                        fixup = txtp - (txt+3);
        !          1472:                        *txtp++ = data;
        !          1473:                        if (nd != 1) {
        !          1474:                                *txtp++ = data >> 8;
        !          1475:                                fixup |= OFFSET << 8;   /* Locat */
        !          1476:                        }
        !          1477:                        fixup |= M << 8;                /* Seg rel */
        !          1478:                        *relp++ = (fixup>>8) | LOCAT;   /* Not thread */
        !          1479:                        *relp++ = fixup;
        !          1480:                        *relp++ = FD8087;               /* Symbol based */
        !          1481:                        *relp++ = 0;                    /* Frame # */
        !          1482:                        *relp++ = 0;
        !          1483:                        relp = setindex(relp, sp->s_ref);
        !          1484:                        dot += nd;
        !          1485:                        continue;
        !          1486:                }
        !          1487: #endif
        !          1488:                /*
        !          1489:                 * Absolute.
        !          1490:                 */
        !          1491:                if ((op&(TSYM|TPCR)) == 0) {
        !          1492:                        enuf(nd, 0);
        !          1493:                        *txtp++ = data;
        !          1494:                        if (nd != 1)
        !          1495:                                *txtp++ = data >> 8;
        !          1496:                        dot += nd;
        !          1497:                        continue;
        !          1498:                }
        !          1499:                /*
        !          1500:                 * Absolute PC rel.
        !          1501:                 */
        !          1502:                if ((op&TSYM) == 0) {
        !          1503:                        enuf(nd, 6);
        !          1504:                        fixup = txtp - (txt+3);
        !          1505:                        *txtp++ = 0;
        !          1506:                        if (nd != 1) {
        !          1507:                                *txtp++ = 0;
        !          1508:                                fixup |= OFFSET << 8;
        !          1509:                        }
        !          1510:                        *relp++ = (fixup>>8) | LOCAT;   /* Not thread */
        !          1511:                        *relp++ = fixup;
        !          1512:                        *relp++ = FTARGET|TFN;          /* Absolute frame */
        !          1513:                        *relp++ = 0;                    /* Frame number */
        !          1514:                        *relp++ = data;                 /* Disp */
        !          1515:                        *relp++ = data >> 8;
        !          1516:                        dot += nd;
        !          1517:                        continue;
        !          1518:                }
        !          1519:                /*
        !          1520:                 * Symbol based.
        !          1521:                 * I would like to always do this
        !          1522:                 * in the primary way. However, LINK-86
        !          1523:                 * doesn't do 3 byte offsets, so I cannot
        !          1524:                 * do a negative one.
        !          1525:                 */
        !          1526:                sp = pget();
        !          1527:                if ((sp->s_flag&S_DEF) != 0) {
        !          1528:                        data += sp->s_value;
        !          1529:                        /* Absolute */
        !          1530:                        if ((op&TPCR)!=0 && sp->s_seg==dotseg) {
        !          1531:                                enuf(nd, 0);
        !          1532:                                data -= dot+nd;
        !          1533:                                *txtp++ = data;
        !          1534:                                if (nd != 1)
        !          1535:                                        *txtp++ = data >> 8;
        !          1536:                                dot += nd;
        !          1537:                                continue;
        !          1538:                        }
        !          1539:                        /* Segment relative */
        !          1540:                        enuf(nd, 6);
        !          1541:                        fixup = txtp - (txt+3);
        !          1542:                        *txtp++ = 0;
        !          1543:                        if (nd != 1) {
        !          1544:                                *txtp++ = 0;
        !          1545:                                fixup |= OFFSET << 8;   /* Loc */
        !          1546:                        }
        !          1547:                        if ((op&TPCR) == 0)
        !          1548:                                fixup |= M << 8;        /* Seg rel */
        !          1549:                        *relp++ = (fixup>>8) | LOCAT;   /* Not thread */
        !          1550:                        *relp++ = fixup;
        !          1551:                        fixup = F|FT0|TSI;              /* F code, seg ind */
        !          1552:                        if (getsegindex(sp->s_seg) != 1)
        !          1553:                                fixup |= FT1;           /* F data */
        !          1554:                        *relp++ = fixup;
        !          1555:                        *relp++ = getsegindex(sp->s_seg);
        !          1556:                        *relp++ = data;                 /* Disp */
        !          1557:                        *relp++ = data >> 8;
        !          1558:                        dot += nd;
        !          1559:                        continue;
        !          1560:                }
        !          1561:                /*
        !          1562:                 * Symbol relative.
        !          1563:                 */
        !          1564:                enuf(nd, 5);
        !          1565:                fixup = txtp - (txt+3);
        !          1566:                *txtp++ = data;
        !          1567:                if (nd != 1) {
        !          1568:                        *txtp++ = data >> 8;
        !          1569:                        fixup |= OFFSET << 8;           /* Loc */
        !          1570:                }
        !          1571:                if ((op&TPCR) == 0)
        !          1572:                        fixup |= M << 8;                /* Seg rel */
        !          1573:                *relp++ = LOCAT|(fixup>>8);             /* Not THREAD */
        !          1574:                *relp++ = fixup;
        !          1575:                *relp++ = FTARGET|SECWAY|TEI;           /* Fix dat */
        !          1576:                relp = setindex(relp, sp->s_ref);
        !          1577:                dot += nd;
        !          1578:        }
        !          1579:        notenuf();                                      /* Flush */
        !          1580:        /*
        !          1581:         * If the size of the SBSS segment
        !          1582:         * is non zero, use an LIDATA item to get it
        !          1583:         * zeroed when the program is run.
        !          1584:         */
        !          1585:        if (bss_size != 0) {
        !          1586:                txtp = &txt[0];
        !          1587:                if (isvariant(VSMALL))
        !          1588:                        *txtp++ = 3;                    /* DATA */
        !          1589:                else
        !          1590:                        *txtp++ = 2;                    /* module_DATA */
        !          1591:                *txtp++ = seg[SBSS].s_mseek;            /* Offset */
        !          1592:                *txtp++ = seg[SBSS].s_mseek >> 8;
        !          1593:                *txtp++ = bss_size;                     /* Length of loop */
        !          1594:                *txtp++ = bss_size >> 8;
        !          1595:                *txtp++ = 0;
        !          1596:                *txtp++ = 0;
        !          1597:                *txtp++ = 1;
        !          1598:                *txtp++ = 0;
        !          1599:                putrecord(LIDATA, txt, 9);              /* Emit OMF */
        !          1600:        }
        !          1601:        dbdump();       /* Clean up db tables */
        !          1602:        putrecord(MODEND, modend, sizeof(modend));
        !          1603: #if    VAXFMT
        !          1604:        vaxflush();
        !          1605: #endif
        !          1606: }
        !          1607: 
        !          1608: /*
        !          1609: ** Header writing routines.
        !          1610: */
        !          1611: /*
        !          1612:  * Put out a THEADR item.
        !          1613:  * The name is just the module name that
        !          1614:  * the compiler has been keeping. It must be
        !          1615:  * mapped into upper case before writing
        !          1616:  * it to the file.
        !          1617:  */
        !          1618: puttheadr()
        !          1619: {
        !          1620:        register char *p1, *p2;
        !          1621:        register c;
        !          1622:        char b[40];
        !          1623: 
        !          1624:        p1 = module;
        !          1625:        p2 = &b[0];
        !          1626:        *p2++ = strlen(p1);
        !          1627:        while ((c = *p1++) != '\0') {
        !          1628:                if (c>='a' && c<='z')
        !          1629:                        c -= 'a'-'A';
        !          1630:                *p2++ = c;
        !          1631:        }
        !          1632:        putrecord(THEADR, b, p2-b);
        !          1633: }
        !          1634: 
        !          1635: /*
        !          1636:  * Make up the list of names
        !          1637:  * record for the LARGE model of segmentation.
        !          1638:  * The names are set up like this: 1 => "",
        !          1639:  * 2 => "module_CODE", 3 => "module_DATA", 4 => "CODE"
        !          1640:  * 5 => "DATA".
        !          1641:  */
        !          1642: putlnames()
        !          1643: {
        !          1644:        register char *p1, *p2;
        !          1645:        register c;
        !          1646:        char *movelname();
        !          1647:        char b[40+40+11];
        !          1648: 
        !          1649:        p1 = &b[0];
        !          1650:        *p1++ = 0;                                      /* EMPTY */
        !          1651:        p1 = movelname(p1, "CODE");
        !          1652:        p1 = movelname(p1, "DATA");
        !          1653:        p2 = "\004CODE\004DATA";
        !          1654:        while ((c = *p2++) != '\0')
        !          1655:                *p1++ = c;
        !          1656:        putrecord(LNAMES, b, p1-b);
        !          1657: }
        !          1658: 
        !          1659: /*
        !          1660:  * Move the module name with the supplied suffix to the supplied buffer.
        !          1661:  * Used by putlnames().
        !          1662:  */
        !          1663: char *
        !          1664: movelname(p1, p2)
        !          1665: register char *p1;
        !          1666: char *p2;
        !          1667: {
        !          1668:        register char *p3;
        !          1669:        register c;
        !          1670: 
        !          1671:        p3 = module;
        !          1672:        *p1++ = strlen(p3) + 5;         /* "_CODE" or "_DATA" */
        !          1673:        while ((c = *p3++) != '\0') {
        !          1674:                if (c>='a' && c<='z')
        !          1675:                        c -= 'a'-'A';
        !          1676:                *p1++ = c;
        !          1677:        }
        !          1678:        *p1++ = '_';
        !          1679:        p3 = p2;
        !          1680:        while ((c = *p3++) != '\0')
        !          1681:                *p1++ = c;
        !          1682:        return (p1);
        !          1683: }
        !          1684: 
        !          1685: /*
        !          1686:  * This routine formats and outputs a SEGDEF
        !          1687:  * item. There is no checking for BIG segments (these
        !          1688:  * are segments that are 64k in size).
        !          1689:  * The overlay index is set to point to a null name.
        !          1690:  */
        !          1691: putsegdef(flag, size, segi, classi)
        !          1692: {
        !          1693:        register char *bp;
        !          1694:        char b[6];
        !          1695: 
        !          1696:        bp = &b[0];
        !          1697:        *bp++ = flag;
        !          1698:        *bp++ = size;
        !          1699:        *bp++ = size >> 8;
        !          1700:        *bp++ = segi;
        !          1701:        *bp++ = classi;
        !          1702:        *bp++ = 1;
        !          1703:        putrecord(SEGDEF, b, 6);
        !          1704: }
        !          1705: 
        !          1706: /*
        !          1707:  * Write TYPDEF records.
        !          1708:  * This assumes that the length member directly precedes the info array.
        !          1709:  */
        !          1710: puttypdef()
        !          1711: {
        !          1712:        register TINFO *tp;
        !          1713:        register int length;
        !          1714:        register TINFO *ttp;
        !          1715: 
        !          1716:        fixpatch();
        !          1717:        tp = typelistp;
        !          1718:        while (tp != NULL) {
        !          1719:                length = tp->t_length + 2;
        !          1720:                tp->t_length = 0;
        !          1721:                if (tp->t_tflag) {
        !          1722:                        length = 3;
        !          1723:                        tp->t_info[0] = OTNIL;
        !          1724:                }
        !          1725:                putrecord(TYPDEF, tp->t_info - 2, length);
        !          1726:                ttp = tp;
        !          1727:                tp = tp->t_tp;
        !          1728:                free(ttp);
        !          1729:        }
        !          1730: }
        !          1731: 
        !          1732: fixpatch()
        !          1733: {
        !          1734:        register TYFIX *fp;
        !          1735: #if    INTEL
        !          1736:        register TINFO *ttp, *pttp, *tp, *ptp;
        !          1737: #endif
        !          1738: 
        !          1739:        while ((fp = typefixp) != NULL) {
        !          1740: #if    INTEL
        !          1741:                if (fp->t_ttype >= fp->t_type) dbfatal(__LINE__);
        !          1742:                /*
        !          1743:                 * This depends on NIL being at type index 1.
        !          1744:                 * Excise the dummy type def.
        !          1745:                 */
        !          1746:                pttp = gettype(fp->t_ttype-1);
        !          1747:                ttp = pttp->t_tp;
        !          1748:                pttp->t_tp = ttp->t_tp;
        !          1749:                /*
        !          1750:                 * Excise the real type def.
        !          1751:                 */
        !          1752:                ptp = gettype(fp->t_type-2);
        !          1753:                tp = ptp->t_tp;
        !          1754:                ptp->t_tp = tp->t_tp;
        !          1755:                /*
        !          1756:                 * Insert the dummy and blank it.
        !          1757:                 */
        !          1758:                ttp->t_tp = ptp->t_tp;
        !          1759:                ptp->t_tp = ttp;
        !          1760:                ttp->t_length = 1;
        !          1761:                ttp->t_tflag = 0;
        !          1762:                ttp->t_info[0] = OTNIL;
        !          1763:                /*
        !          1764:                 * Insert the real definition.
        !          1765:                 */
        !          1766:                tp->t_tp = pttp->t_tp;
        !          1767:                pttp->t_tp = tp;
        !          1768: #endif
        !          1769:                /*
        !          1770:                 * Release the memory.
        !          1771:                 */
        !          1772:                typefixp = fp->t_tp;
        !          1773:                free(fp);
        !          1774:        }
        !          1775: }
        !          1776: 
        !          1777: static TINFO *
        !          1778: gettype(index)
        !          1779: {
        !          1780:        register TINFO *tp;
        !          1781: 
        !          1782:        tp = typelistp;
        !          1783:        while (--index != 0)
        !          1784:                if ((tp = tp->t_tp) == NULL)
        !          1785:                        dbfatal(__LINE__);
        !          1786:        return (tp);
        !          1787: }
        !          1788: 
        !          1789: /*
        !          1790:  * Sweep through the symbol table:
        !          1791:  *     1) Make symbols LSEG relative.
        !          1792:  *     2) Assign reference numbers.
        !          1793:  *     3) Output EXTDEF or PUBDEF.
        !          1794:  *     4) Output DEBSYM.
        !          1795:  */
        !          1796: putsymdef()
        !          1797: {
        !          1798:        register SYM *sp;
        !          1799:        register int refnum;
        !          1800:        register int i;
        !          1801: 
        !          1802:        refnum = 1;
        !          1803:        for (i=0; i<NSHASH; ++i) {
        !          1804:                sp = hash2[i];
        !          1805:                while (sp != NULL) {
        !          1806:                        if ((sp->s_flag&S_DEF) != 0)
        !          1807:                                sp->s_value += seg[sp->s_seg].s_mseek;
        !          1808:                        if ((sp->s_flag&S_GBL)!=0 || (sp->s_flag&S_DEF)==0) {
        !          1809:                                sp->s_ref = 0;
        !          1810:                                if ((sp->s_flag&S_DEF) != 0) {
        !          1811:                                        putpubdef(sp);
        !          1812:                                } else {
        !          1813:                                        sp->s_ref = refnum++;
        !          1814:                                        putextdef(sp);
        !          1815:                                }
        !          1816:                        }
        !          1817:                        sp = sp->s_fp;
        !          1818:                }
        !          1819:        }
        !          1820: }
        !          1821: 
        !          1822: /*
        !          1823:  * Put out a PUBDEF item for symbol 'sp'.
        !          1824:  * All defs are tagged with the group
        !          1825:  * so that a FTARGET,EI fixup can determine the correct frame.
        !          1826:  */
        !          1827: putpubdef(sp)
        !          1828: register SYM *sp;
        !          1829: {
        !          1830:        register char *bp;
        !          1831:        char b[1+1+40+2+1];
        !          1832: 
        !          1833:        bp = &b[0];
        !          1834:        *bp++ = getgrpindex(sp->s_seg);
        !          1835:        *bp++ = getsegindex(sp->s_seg);
        !          1836:        bp = setsymid(bp, sp->s_id);
        !          1837:        *bp++ = sp->s_value;
        !          1838:        *bp++ = sp->s_value >> 8;
        !          1839:        if (sp->s_type == 0)
        !          1840:                *bp++ = 1;
        !          1841:        else
        !          1842:                bp = setindex(bp, sp->s_type);
        !          1843:        putrecord(PUBDEF, b, bp-b);
        !          1844: }
        !          1845: 
        !          1846: /*
        !          1847:  * Put out an EXTDEF item for symbol 'sp'.
        !          1848:  */
        !          1849: putextdef(sp)
        !          1850: register SYM *sp;
        !          1851: {
        !          1852:        register char *bp;
        !          1853:        char b[40+2];
        !          1854: 
        !          1855:        bp = setsymid(b, sp->s_id);
        !          1856:        if (sp->s_type == 0)
        !          1857:                *bp++ = 1;
        !          1858:        else
        !          1859:                bp = setindex(bp, sp->s_type);
        !          1860:        putrecord(EXTDEF, b, bp-b);
        !          1861: }
        !          1862: 
        !          1863: /*
        !          1864:  * Translate compiler segment codes
        !          1865:  * to OMF segment index value, using tables.
        !          1866:  * The table is selected by the model and the
        !          1867:  * setting of the VROM variant.
        !          1868:  */
        !          1869: getsegindex(s)
        !          1870: register int   s;
        !          1871: {
        !          1872:        if (isvariant(VSMALL)) {
        !          1873:                if (isvariant(VRAM))
        !          1874:                        return (sramseg[s]);
        !          1875:                if (notvariant(VROM))
        !          1876:                        return (snonseg[s]);
        !          1877:                return (sromseg[s]);
        !          1878:        }
        !          1879:        if (isvariant(VRAM))
        !          1880:                return (lramseg[s]);
        !          1881:        if (notvariant(VROM))
        !          1882:                return (lnonseg[s]);
        !          1883:        return (lromseg[s]);
        !          1884: }
        !          1885: 
        !          1886: /*
        !          1887:  * Translate compiler segment codes
        !          1888:  * to OMF group index value, using table and model.
        !          1889:  */
        !          1890: getgrpindex(s)
        !          1891: register int s;
        !          1892: {
        !          1893:        if (isvariant(VSMALL)) return (grpindex[s]);
        !          1894:        else return (0);
        !          1895: }
        !          1896: 
        !          1897: /*
        !          1898: ** Debug information processors.
        !          1899: */
        !          1900: /*
        !          1901:  * Structure to contain debug items on this pass.
        !          1902:  */
        !          1903: struct dbgt {
        !          1904:        struct dbgt *d_dp;              /* Link */
        !          1905:        int d_ref;                      /* Index number */
        !          1906:        unsigned char d_class;          /* Storage class */
        !          1907:        unsigned char d_flag;           /* Flags */
        !          1908:        unsigned char d_level;          /* Bracket level */
        !          1909:        unsigned char d_seg;            /* Segment */
        !          1910:        ADDRESS d_value;                /* Offset in segment */
        !          1911:        int d_type;                     /* Type index */
        !          1912:        int d_line;                     /* Line number */
        !          1913:        char d_id[];                    /* Name */
        !          1914: };
        !          1915: 
        !          1916: struct dbgt *getdbgt();
        !          1917: struct dbgt *dbase;
        !          1918: struct dbgt *dnext;
        !          1919: #if    !TINY
        !          1920: #define        dbrpt(x,y)      _dbrpt(x,y)
        !          1921: #else
        !          1922: #define        dbrpt(x,y)      /* _dbrpt(x,y) */
        !          1923: #endif
        !          1924: 
        !          1925: /*
        !          1926:  * Read debug table item(s) into memory.
        !          1927:  * These are buffered until appropriate moments.
        !          1928:  */
        !          1929: getdlab()
        !          1930: {
        !          1931:        register struct dbgt *dp;
        !          1932:        static int refnum = 0;
        !          1933: 
        !          1934:        dp = getdbgt();
        !          1935:        if (dp->d_class == DC_LINE || dp->d_class == DC_LAB)
        !          1936:                dp->d_ref = refnum;
        !          1937:        refnum += 1;
        !          1938:        if (dbase == NULL)
        !          1939:                dbase = dp;
        !          1940:        if (dnext != NULL)
        !          1941:                dnext->d_dp = dp;
        !          1942:        dbrpt("enter", dp);
        !          1943:        while (dp->d_dp != NULL) {
        !          1944:                dp = dp->d_dp;
        !          1945:                dbrpt("enter", dp);
        !          1946:        }
        !          1947:        dnext = dp;
        !          1948: }
        !          1949: 
        !          1950: /*
        !          1951:  * Read in debug item in form abbreviated by outdlab().
        !          1952:  */
        !          1953: struct dbgt *
        !          1954: getdbgt()
        !          1955: {
        !          1956:        register char *cp;
        !          1957:        register struct dbgt *dp;
        !          1958:        static int level = 0;
        !          1959:        struct dbgt d;
        !          1960:        SYM *sp;
        !          1961: 
        !          1962:        d.d_level = level;
        !          1963: 
        !          1964:        /*
        !          1965:         * Read the values in.
        !          1966:         */
        !          1967:        d.d_class = bget();
        !          1968:        d.d_line = iget();
        !          1969:        d.d_value = iget();
        !          1970:        d.d_seg = bget();
        !          1971: 
        !          1972:        /*
        !          1973:         * Read name.
        !          1974:         */
        !          1975:        for (cp = id; *cp = bget(); cp += 1);
        !          1976: 
        !          1977:        /*
        !          1978:         * Read type.
        !          1979:         */
        !          1980:        d.d_type = iget();
        !          1981: 
        !          1982:        /*
        !          1983:         * Check level change.
        !          1984:         */
        !          1985:        if (d.d_class == DC_LINE) {
        !          1986:                switch (id[0]) {
        !          1987:                case '{': level += 1; break;
        !          1988:                case '}': level -= 1; break;
        !          1989:                }
        !          1990:        }
        !          1991: 
        !          1992:        /*
        !          1993:         * Find location of static internal items.
        !          1994:         */
        !          1995:        if (d.d_class == DC_SIN) {
        !          1996:                sp = llookup(d.d_value, 0);
        !          1997:                d.d_value = sp->s_value;
        !          1998:                d.d_seg = sp->s_seg;
        !          1999:        }
        !          2000: 
        !          2001:        /*
        !          2002:         * Copy into dynamic storage.
        !          2003:         */
        !          2004:        dp = (struct dbgt *)malloc(sizeof(struct dbgt) + cp - id + 1);
        !          2005:        if (dp == NULL)
        !          2006:                cnomem("getdbgt");
        !          2007:        dp->d_level = d.d_level;
        !          2008:        dp->d_class = d.d_class;
        !          2009:        dp->d_line = d.d_line;
        !          2010:        dp->d_seg = d.d_seg;
        !          2011:        if (d.d_seg < SANY)
        !          2012:                d.d_value += seg[d.d_seg].s_mseek;
        !          2013:        dp->d_value = d.d_value;
        !          2014:        dp->d_type = d.d_type;
        !          2015:        dp->d_dp = NULL;
        !          2016:        dp->d_ref = -1;
        !          2017:        while (cp >= id) {
        !          2018:                dp->d_id[cp-id] = *cp;
        !          2019:                cp -= 1;
        !          2020:        }
        !          2021:        return (dp);
        !          2022: }
        !          2023: 
        !          2024: /*
        !          2025:  * Read a debug relocation item and patch current 'dot'
        !          2026:  * into the appropriate debug/symbol table item.
        !          2027:  * If the debug item is '}' and level 1, then dump everything in the list.
        !          2028:  */
        !          2029: getdloc()
        !          2030: {
        !          2031:        register struct dbgt *dp;
        !          2032:        register int ref;
        !          2033: 
        !          2034:        ref = iget();
        !          2035:        for (dp = dbase; ; dp = dp->d_dp) {
        !          2036:                if (dp == NULL)
        !          2037:                        cbotch("getdloc: %d", ref);
        !          2038:                if (dp->d_ref == ref)
        !          2039:                        break;
        !          2040:        }
        !          2041:        dp->d_seg = dotseg;
        !          2042:        dp->d_value = dot;
        !          2043: 
        !          2044:        dbrpt("reloc", dp);
        !          2045:        if (dp->d_id[0] == '}' && dp->d_level == 1)
        !          2046:                dbdump();
        !          2047: }
        !          2048: 
        !          2049: /*
        !          2050:  * Dump all the debug symbols.
        !          2051:  */
        !          2052: dbdump()
        !          2053: {
        !          2054:        register struct dbgt *dp, **dpp;
        !          2055:        extern char *regnames[];
        !          2056: 
        !          2057:        dpp = &dbase;
        !          2058:        dnext = NULL;
        !          2059:        while ((dp = *dpp) != NULL) {
        !          2060:                switch (dp->d_class) {
        !          2061:                case DC_GDEF:           /* Global def. */
        !          2062:                case DC_SEX:            /* Static external */
        !          2063:                        /* Function definitions replace initial { */
        !          2064:                        if (dp->d_seg == SCODE) {
        !          2065:                                /* The initial BLKDEF occurs before PROLOG
        !          2066:                                 * at the function entry point.  Could be
        !          2067:                                 * moved after PROLOG if desired.
        !          2068:                                 * The last BLKEND occurs just
        !          2069:                                 * before the EPILOG, and can also be moved.
        !          2070:                                 */
        !          2071:                                SYM *sp;
        !          2072: 
        !          2073:                                sp = glookup(dp->d_id, 0);
        !          2074:                                dp->d_type = sp->s_type;
        !          2075:                                putlno(dp);
        !          2076:                                putblkdef(dp);
        !          2077:                        } else
        !          2078:                                putdebsym(dp);
        !          2079:                        break;
        !          2080:                case DC_GREF:           /* Global ref. */
        !          2081:                        break;
        !          2082:                case DC_TYPE:           /* Typedef name */
        !          2083:                case DC_STAG:           /* Structure tag */
        !          2084:                case DC_UTAG:           /* Union tag */
        !          2085:                case DC_ETAG:           /* Enumeration tag */
        !          2086:                case DC_FILE:           /* Source file name */
        !          2087:                        break;
        !          2088:                case DC_AUTO:           /* Auto */
        !          2089:                case DC_PAUTO:          /* Parametric auto */
        !          2090:                        putlocsym(dp);
        !          2091:                        break;
        !          2092:                case DC_SIN:            /* Static internal */
        !          2093:                case DC_LAB:            /* Label */
        !          2094:                        putdebsym(dp);
        !          2095:                        break;
        !          2096:                case DC_REG:            /* Register */
        !          2097:                case DC_PREG:           /* Parametric register */
        !          2098: #if    INTEL
        !          2099:                        line = dp->d_line;
        !          2100:                        cwarn("variable \"%s\" is in register %s",
        !          2101:                                dp->d_id, regnames[dp->d_value]);
        !          2102: #endif
        !          2103:                        break;
        !          2104:                case DC_MOE:            /* Member of enumeration */
        !          2105:                        break;
        !          2106:                case DC_LINE:           /* Line number */
        !          2107:                        switch (dp->d_id[0]) {
        !          2108:                        case '{':       /* Block begins */
        !          2109:                                /* GDEF or SEX takes first blkdef */
        !          2110:                                if (dp->d_level != 0) {
        !          2111:                                        putlno(dp);
        !          2112:                                        putblkdef(dp);
        !          2113:                                }
        !          2114:                                break;
        !          2115:                        case ';':       /* Line number */
        !          2116:                                putlno(dp);
        !          2117:                                break;
        !          2118:                        case '}':       /* Block ends */
        !          2119: #ifdef NOABLOCKS
        !          2120:                                if (blkcount > 0) {
        !          2121:                                        blkcount--;
        !          2122:                                        break;
        !          2123:                                }
        !          2124: #endif
        !          2125:                                putrecord(BLKEND, NULL, 0);
        !          2126:                                break;
        !          2127:                        default:
        !          2128:                                cbotch("bad line record (dbdump)");
        !          2129:                        }
        !          2130:                        break;
        !          2131:                case DC_MOS:            /* Member of structure */
        !          2132:                case DC_MOU:            /* Member of union */
        !          2133:                case DC_CALL:           /* Function call */
        !          2134:                        break;
        !          2135:                default:
        !          2136:                        cbotch("bad class (dbdump)");
        !          2137:                }
        !          2138:                *dpp = dp->d_dp;
        !          2139:                free(dp);
        !          2140:        }
        !          2141: }
        !          2142: 
        !          2143: /*
        !          2144:  * Put out a DEBSYM item.
        !          2145:  * The symbol pointed to by 'dp' is a public
        !          2146:  * definition in this module.
        !          2147:  * This only gets executed under the VDEBUG option.
        !          2148:  */
        !          2149: putdebsym(dp)
        !          2150: register struct dbgt *dp;
        !          2151: {
        !          2152:        register char *bp;
        !          2153:        char b[1+1+1+40+2+1];
        !          2154: 
        !          2155:        bp = &b[0];
        !          2156:        *bp++ = 0;                              /* B=0, L=0, FM=0 */
        !          2157:        *bp++ = getgrpindex(dp->d_seg);
        !          2158:        *bp++ = getsegindex(dp->d_seg);
        !          2159:        bp = setsymid(bp, dp->d_id);
        !          2160:        *bp++ = dp->d_value;
        !          2161:        *bp++ = dp->d_value >> 8;
        !          2162:        bp = setindex(bp, dp->d_type);
        !          2163:        putrecord(DEBSYM, b, bp-b);
        !          2164: }
        !          2165: 
        !          2166: /*
        !          2167:  * Process a local symbol definition.
        !          2168:  * Put out a DEBSYM record for symbol sp.
        !          2169:  */
        !          2170: putlocsym(dp)
        !          2171: register struct dbgt *dp;
        !          2172: {
        !          2173:        register char *bp;
        !          2174:        char b[1+2+40+2+1];
        !          2175: 
        !          2176:        bp = &b[0];
        !          2177:        *bp++ = 2;                              /* B=0, L=0, FM=2 */
        !          2178:        bp = setindex(bp, blkindex);
        !          2179:        bp = setsymid(bp, dp->d_id);
        !          2180:        *bp++ = dp->d_value;
        !          2181:        *bp++ = dp->d_value >> 8;
        !          2182:        bp = setindex(bp, dp->d_type);
        !          2183:        putrecord(DEBSYM, b, bp-b);
        !          2184: }
        !          2185: 
        !          2186: /*
        !          2187:  * Process a block definition item.
        !          2188:  */
        !          2189: putblkdef(dp)
        !          2190: register struct dbgt *dp;
        !          2191: {
        !          2192:        char b[1+1+40+2+2+1+2+1];
        !          2193:        register char *bp;
        !          2194:        char info = 0;
        !          2195:        int isproc;
        !          2196:        int episize;
        !          2197: 
        !          2198:        isproc = dp->d_id[0] != '{';
        !          2199: #ifdef NOABLOCKS
        !          2200:        if (!isproc) {
        !          2201:                blkcount++;
        !          2202:                return;
        !          2203:        }
        !          2204: #endif
        !          2205:        ++blkindex;                     /* update block index */
        !          2206:        bp = &b[0];
        !          2207:        *bp++ = getgrpindex(dp->d_seg);
        !          2208:        *bp++ = getsegindex(dp->d_seg);
        !          2209:        if (isproc)
        !          2210:                bp = setsymid(bp, dp->d_id);    /* name */
        !          2211:        else
        !          2212:                *bp++ = 0;                      /* no name */
        !          2213:        *bp++ = dp->d_value;
        !          2214:        *bp++ = dp->d_value >> 8;               /* offset */
        !          2215:        dp->d_value = blklength(dp, &episize);
        !          2216:        if (isproc)
        !          2217:                dp->d_value += episize;
        !          2218:        *bp++ = dp->d_value;
        !          2219:        *bp++ = dp->d_value >> 8;               /* length */
        !          2220:        if (isproc) {
        !          2221:                info |= 0x80;                   /* procedure bit */
        !          2222:                if (isvariant(VLARGE)) {
        !          2223:                        info |= 0x40;
        !          2224:                }
        !          2225:                *bp++ = info;
        !          2226:                *bp++ = 6;
        !          2227:                *bp++ = 0;                      /* return address offset */
        !          2228:                bp = setindex(bp, dp->d_type);  /* type index */
        !          2229:        } else
        !          2230:                *bp++ = info;
        !          2231:        putrecord(BLKDEF, b, bp-b);
        !          2232: }
        !          2233: 
        !          2234: blklength(dp, epp)
        !          2235: register struct dbgt *dp;
        !          2236: int *epp;
        !          2237: {
        !          2238:        register int level;
        !          2239:        register ADDRESS length;
        !          2240:        int autoseen;
        !          2241: 
        !          2242:        autoseen = 0;
        !          2243:        level = dp->d_level + 1;
        !          2244:        length = dp->d_value;
        !          2245:        while ((dp = dp->d_dp) != NULL) {
        !          2246:                if (dp->d_class == DC_AUTO)
        !          2247:                        ++autoseen;
        !          2248:                else if (dp->d_class == DC_LINE
        !          2249:                 && dp->d_id[0] == '}'
        !          2250:                 && dp->d_level == level) {
        !          2251:                        *epp = (isvariant(V80186)) ? 4 : (autoseen) ? 6 : 4;
        !          2252:                        return ((int) (dp->d_value - length));
        !          2253:                }
        !          2254:        }
        !          2255:        cbotch("missing blkend");
        !          2256: }
        !          2257: 
        !          2258: /*
        !          2259:  * Put out a line number item.
        !          2260:  */
        !          2261: putlno(dp)
        !          2262: register struct dbgt *dp;
        !          2263: {
        !          2264:        register char *p1;
        !          2265:        char b[10];
        !          2266:        static last = 0;
        !          2267: 
        !          2268:        if ((dp->d_line) == last)
        !          2269:                return;
        !          2270:        last = dp->d_line;
        !          2271:        p1 = &b[0];
        !          2272:        *p1++ = getgrpindex(dp->d_seg);
        !          2273:        *p1++ = getsegindex(dp->d_seg);
        !          2274:        *p1++ = dp->d_line;
        !          2275:        *p1++ = dp->d_line>>8;
        !          2276:        *p1++ = dp->d_value;
        !          2277:        *p1++ = dp->d_value>>8;
        !          2278:        putrecord(LINNUM, b, p1-b);
        !          2279: }
        !          2280: 
        !          2281: #if    !TINY
        !          2282: _dbrpt(p, dp)
        !          2283: char *p;
        !          2284: register struct dbgt *dp;
        !          2285: {
        !          2286:        if (xflag > 5)
        !          2287:                printf("%s:     %d %s %d %d %o %d\n",
        !          2288:                        p,
        !          2289:                        dp->d_class,
        !          2290:                        dp->d_id,
        !          2291:                        dp->d_ref,
        !          2292:                        dp->d_level,
        !          2293:                        dp->d_flag,
        !          2294:                        dp->d_type,
        !          2295:                        0);
        !          2296: }
        !          2297: 
        !          2298: #endif
        !          2299: 
        !          2300: /*
        !          2301: ** Low level record formatting.
        !          2302: */
        !          2303: /*
        !          2304:  * Splat a bit size for the people.
        !          2305:  */
        !          2306: long lastsize;
        !          2307: char *
        !          2308: setsize(bp, size)
        !          2309: char *bp;
        !          2310: long size;
        !          2311: {
        !          2312:        lastsize = size;
        !          2313:        return (setnumb(bp, size));
        !          2314: }
        !          2315: 
        !          2316: /*
        !          2317:  * Splat an unsigned numeric leaf.
        !          2318:  * This assumes that the leaf will fit in at most 3 bytes,
        !          2319:  * since the biggest objects the compiler knows about are
        !          2320:  * 64K bytes or NBPBYTE*64K = 512K bits.
        !          2321:  */
        !          2322: char *
        !          2323: setnumb(bp, numb)
        !          2324: char *bp;
        !          2325: unsigned long numb;
        !          2326: {
        !          2327:        if (numb < 128)
        !          2328:                *bp++ = numb;
        !          2329:        else  if (numb < 0x10000L) {
        !          2330:                *bp++ = OTUNUM2;
        !          2331:                *bp++ = numb;
        !          2332:                *bp++ = numb >> 8;
        !          2333:        }
        !          2334:        else {
        !          2335:                *bp++ = OTUNUM3;
        !          2336:                *bp++ = numb;
        !          2337:                *bp++ = numb >> 8;
        !          2338:                *bp++ = numb >> 16;
        !          2339:        }
        !          2340:        return (bp);
        !          2341: }
        !          2342: 
        !          2343: /*
        !          2344:  * Put OMF index i at cp and return updated cp.
        !          2345:  */
        !          2346: char *
        !          2347: setindex(cp, i)
        !          2348: register char *cp;
        !          2349: register unsigned i;
        !          2350: {
        !          2351:        if (i >= 128)
        !          2352:                *cp++ = (i >> 8) | 0x80;
        !          2353:        *cp++ = i;
        !          2354:        return (cp);
        !          2355: }
        !          2356: 
        !          2357: /*
        !          2358:  * This routine takes the name pointed to by 'cp' and
        !          2359:  * moves it into an OMF record. The 'bp' argument
        !          2360:  * is the OMF buffer pointer. The updated value
        !          2361:  * of 'bp' is returned.
        !          2362:  */
        !          2363: char *
        !          2364: setsymid(bp, cp)
        !          2365: register char *bp;
        !          2366: register char *cp;
        !          2367: {
        !          2368:        register c, n;
        !          2369: 
        !          2370:        if ((n=strlen(cp)) > 39) {
        !          2371:                cwarn("symbol \"%s\" truncated to 39 characters", cp);
        !          2372:                n = 39;
        !          2373:        }
        !          2374:        *bp++ = n;
        !          2375:        while (n--) {
        !          2376:                if ((c = *cp++)>='a' && c<='z')
        !          2377:                        c -= 'a'-'A';
        !          2378:                *bp++ = c;
        !          2379:        }
        !          2380:        return (bp);
        !          2381: }
        !          2382: 
        !          2383: /*
        !          2384:  * Put a record.
        !          2385:  * The 'type' argument is the record type.
        !          2386:  * The body of the record starts at 'p' and is
        !          2387:  * 'n' bytes long. The checksum is added.
        !          2388:  */
        !          2389: putrecord(type, p, n)
        !          2390: register unsigned char *p;
        !          2391: register n;
        !          2392: {
        !          2393:        checksum = 0;
        !          2394:        putbyte(type);
        !          2395:        putbyte(n+1);           /* +1 for the checksum */
        !          2396:        putbyte((n+1)>>8);
        !          2397:        while(n--)
        !          2398:                putbyte(*p++);
        !          2399:        putbyte(-checksum);
        !          2400: }
        !          2401: 
        !          2402: putbyte(b)
        !          2403: register b;
        !          2404: {
        !          2405: #if    VAXFMT
        !          2406:        if (vaxptr >= &vaxbuf[NVDATA]) {
        !          2407:                vaxflush();
        !          2408:                vaxptr = vaxbuf;
        !          2409:        }
        !          2410:        *vaxptr++ = b;
        !          2411: #else
        !          2412:        bput(b);
        !          2413: #endif
        !          2414:        checksum += b;
        !          2415: }
        !          2416: 
        !          2417: /*
        !          2418: ** Output buffering.
        !          2419: */
        !          2420: /*
        !          2421:  * Check if there is enough room in the text and relocation
        !          2422:  * buffers to hold 'nt' bytes of text and 'nr' bytes of relocation.
        !          2423:  */
        !          2424: enuf(nt, nr)
        !          2425: {
        !          2426:        if (txtp+nt>&txt[NTXT] || relp+nr>&rel[NREL])
        !          2427:                notenuf();
        !          2428:        if (txtp == txt) {
        !          2429:                *txtp++ = getsegindex(dotseg);
        !          2430:                *txtp++ = dot;
        !          2431:                *txtp++ = dot >> 8;
        !          2432:        }
        !          2433: }
        !          2434: 
        !          2435: /*
        !          2436:  * Flush the buffer.
        !          2437:  */
        !          2438: notenuf()
        !          2439: {
        !          2440:        register n;
        !          2441: 
        !          2442:        if ((n = txtp-txt) > 3) {
        !          2443:                putrecord(LEDATA, txt, n);
        !          2444:                if ((n = relp-rel) != 0) {
        !          2445:                        putrecord(FIXUPP, rel, n);
        !          2446:                        relp = rel;
        !          2447:                }
        !          2448:        }
        !          2449:        txtp = txt;
        !          2450: }
        !          2451: 
        !          2452: /*
        !          2453:  * Round up to the next word.
        !          2454:  */
        !          2455: rup(a)
        !          2456: ADDRESS a;
        !          2457: {
        !          2458:        return ((a+01)&~01);
        !          2459: }
        !          2460: 
        !          2461: #if    VAXFMT
        !          2462: /*
        !          2463:  * Flush out a record on the VAX. The record is a standard,
        !          2464:  * RMS variable length record. This routine checks for no bytes
        !          2465:  * in the buffer, so it can be unconditionally called at the
        !          2466:  * end to flush the buffer out.
        !          2467:  * The record is padded out to NVDATA bytes with zeros. This
        !          2468:  * only happens on the last block; the data beyond the end
        !          2469:  * is zeroed.
        !          2470:  */
        !          2471: vaxflush()
        !          2472: {
        !          2473:        register int    n;
        !          2474: 
        !          2475:        if ((n = vaxptr-vaxbuf) != 0) {
        !          2476:                if (fwrite(vaxbuf, n, 1, ofp) != 1
        !          2477:                ||  fflush(ofp) == EOF)
        !          2478:                        cfatal("output write error");
        !          2479:        }
        !          2480: }
        !          2481: #endif
        !          2482: 

unix.superglobalmegacorp.com

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