Annotation of coherent/d/bin/cc/c/n2/i8086/outomf.c, revision 1.1.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.