Annotation of 43BSDReno/pgrm/pascal/src/stab.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1980 Regents of the University of California.
        !             3:  * All rights reserved.  The Berkeley software License Agreement
        !             4:  * specifies the terms and conditions for redistribution.
        !             5:  */
        !             6: 
        !             7: #ifndef lint
        !             8: static char sccsid[] = "@(#)stab.c     5.3 (Berkeley) 1/3/88";
        !             9: #endif not lint
        !            10: 
        !            11:     /*
        !            12:      * Procedures to put out symbol table information
        !            13:      * and stabs for separate compilation type checking.
        !            14:      * These use the .stabs, .stabn, and .stabd directives.
        !            15:      */
        !            16: 
        !            17: #include       "whoami.h"
        !            18: #ifdef PC
        !            19:     /* and the rest of the file */
        !            20: #   include    "0.h"
        !            21: #   include    "objfmt.h"
        !            22: #   include    "yy.h"
        !            23: #   include    <stab.h>
        !            24: 
        !            25:     /*
        !            26:      *  additional symbol definition for <stab.h>
        !            27:      * that is used by the separate compilation facility --
        !            28:      * eventually, <stab.h> should be updated to include this 
        !            29:      */
        !            30: 
        !            31: #   include    "pstab.h"
        !            32: #   include    "pc.h"
        !            33: 
        !            34: 
        !            35: #define private static
        !            36: 
        !            37: int oldway = 0;
        !            38: 
        !            39:     /*
        !            40:      * absolute value: line numbers are negative if error recovery.
        !            41:      */
        !            42: #define        ABS( x )        ( x < 0 ? -x : x )
        !            43: long checksum();
        !            44: 
        !            45: /*
        !            46:  * Generate information about variables.
        !            47:  */
        !            48: 
        !            49: stabgvar (p, length, line)
        !            50: struct nl *p;
        !            51: int length, line;
        !            52: {
        !            53:     putprintf("        .stabs  \"%s\",0x%x,0,0x%x,0x%x",
        !            54:        0, p->symbol, N_PC, N_PGVAR, ABS(line)
        !            55:     );
        !            56:     if (oldway != 0) {
        !            57:        oldstabgvar(p->symbol, p2type(p->type), 0, length, line);
        !            58:     } else if (opt('g')) {
        !            59:        putprintf("\t.stabs\t\"%s:G", 1, p->symbol);
        !            60:        gentype(p->type);
        !            61:        putprintf("\",0x%x,0,0x%x,0", 0, N_GSYM, length);
        !            62:     }
        !            63: }
        !            64: 
        !            65: stablvar (p, offset, length)
        !            66: struct nl *p;
        !            67: int offset, length;
        !            68: {
        !            69:     int level;
        !            70: 
        !            71:     level = (p->nl_block & 037);
        !            72:     if (oldway != 0) {
        !            73:        oldstablvar(p->symbol, p2type(p->type), level, offset, length);
        !            74:     } else if (opt('g')) {
        !            75:        putprintf("\t.stabs\t\"%s:", 1, p->symbol);
        !            76:        gentype(p->type);
        !            77:        putprintf("\",0x%x,0,0x%x,0x%x", 0, N_LSYM, length, offset);
        !            78:     }
        !            79: }
        !            80: 
        !            81:     /*
        !            82:      * global variables
        !            83:      */
        !            84: /*ARGSUSED*/
        !            85: oldstabgvar( name , type , offset , length , line )
        !            86:     char       *name;
        !            87:     int                type;
        !            88:     int                offset;
        !            89:     int                length;
        !            90:     int                line;
        !            91:     {
        !            92:        if ( ! opt('g') ) {
        !            93:                return;
        !            94:        }
        !            95:        putprintf( "    .stabs  \"" , 1 );
        !            96:        putprintf( NAMEFORMAT , 1 , (int) name );
        !            97:        putprintf( "\",0x%x,0,0x%x,0" , 0 , N_GSYM , type );
        !            98:        putprintf( "    .stabs  \"" , 1 );
        !            99:        putprintf( NAMEFORMAT , 1 , (int) name );
        !           100:        putprintf( "\",0x%x,0,0,0x%x" , 0 , N_LENG , length );
        !           101: }
        !           102: 
        !           103:     /*
        !           104:      * local variables
        !           105:      */
        !           106: /*ARGSUSED*/
        !           107: oldstablvar( name , type , level , offset , length )
        !           108:     char       *name;
        !           109:     int                type;
        !           110:     int                level;
        !           111:     int                offset;
        !           112:     int                length;
        !           113:     {
        !           114: 
        !           115:        if ( ! opt('g') ) {
        !           116:                return;
        !           117:        }
        !           118:        putprintf( "    .stabs  \"" , 1 );
        !           119:        putprintf( NAMEFORMAT , 1 , (int) name );
        !           120:        putprintf( "\",0x%x,0,0x%x,0x%x" , 0 , N_LSYM , type , -offset );
        !           121:        putprintf( "    .stabs  \"" , 1 );
        !           122:        putprintf( NAMEFORMAT , 1 , (int) name );
        !           123:        putprintf( "\",0x%x,0,0,0x%x" , 0 , N_LENG , length );
        !           124: }
        !           125: 
        !           126: 
        !           127: stabparam (p, offset, length)
        !           128: struct nl *p;
        !           129: int offset, length;
        !           130: {
        !           131:     if (oldway != 0) {
        !           132:        oldstabparam(p->symbol, p2type(p->type), offset, length);
        !           133:     } else if (opt('g')) {
        !           134:        putprintf("\t.stabs\t\"%s:", 1, p->symbol);
        !           135:        if (p->class == REF) {
        !           136:            putprintf("v", 1);
        !           137:        } else {
        !           138:            putprintf("p", 1);
        !           139:        }
        !           140:        gentype((p->class == FPROC || p->class ==FFUNC) ? p : p->type);
        !           141:        putprintf("\",0x%x,0,0x%x,0x%x", 0, N_PSYM, length, offset);
        !           142:     }
        !           143: }
        !           144: 
        !           145:     /*
        !           146:      * parameters
        !           147:      */
        !           148: oldstabparam( name , type , offset , length )
        !           149:     char       *name;
        !           150:     int                type;
        !           151:     int                offset;
        !           152:     int                length;
        !           153:     {
        !           154:        
        !           155:        if ( ! opt('g') ) {
        !           156:                return;
        !           157:        }
        !           158:        putprintf( "    .stabs  \"" , 1 );
        !           159:        putprintf( NAMEFORMAT , 1 , (int) name );
        !           160:        putprintf( "\",0x%x,0,0x%x,0x%x" , 0 , N_PSYM , type , offset );
        !           161:        putprintf( "    .stabs  \"" , 1 );
        !           162:        putprintf( NAMEFORMAT , 1 , (int) name );
        !           163:        putprintf( "\",0x%x,0,0,0x%x" , 0 , N_LENG , length );
        !           164:     }
        !           165: 
        !           166:     /*
        !           167:      * fields
        !           168:      */
        !           169: 
        !           170:     /*
        !           171:      * left brackets
        !           172:      *  (dbx handles module-2 without these, so we won't use them either)
        !           173:      */
        !           174: stablbrac( level )
        !           175:     int        level;
        !           176:     {
        !           177: 
        !           178:        if ( ! opt('g') || oldway == 0 ) {
        !           179:                return;
        !           180:        }
        !           181:        putprintf( "    .stabd  0x%x,0,0x%x" , 0 , N_LBRAC , level );
        !           182:     }
        !           183: 
        !           184:     /*
        !           185:      * right brackets
        !           186:      */
        !           187: stabrbrac( level )
        !           188:     int        level;
        !           189:     {
        !           190: 
        !           191:        if ( ! opt('g') || oldway == 0 ) {
        !           192:                return;
        !           193:        }
        !           194:        putprintf( "    .stabd  0x%x,0,0x%x" , 0 , N_RBRAC , level );
        !           195:     }
        !           196: 
        !           197: stabfunc (p, name, line, level)
        !           198: struct nl *p;
        !           199: char *name;
        !           200: int line, level;
        !           201: {
        !           202:     char extname[BUFSIZ],nestspec[BUFSIZ];
        !           203:     
        !           204:     if ( level == 1 ) {
        !           205:        if (p->class == FUNC) {
        !           206:            putprintf(" .stabs  \"%s\",0x%x,0,0x%x,0x%x" ,
        !           207:                0 , name , N_PC , N_PGFUNC , ABS( line )
        !           208:            );
        !           209:        } else if (p->class == PROC) {
        !           210:            putprintf(" .stabs  \"%s\",0x%x,0,0x%x,0x%x" ,
        !           211:                0 , name , N_PC , N_PGPROC , ABS( line )
        !           212:            );
        !           213:        }
        !           214:     }
        !           215:     if (oldway != 0) {
        !           216:        oldstabfunc(name, p->class, line, level);
        !           217:     } else if (opt('g')) {
        !           218:        putprintf("\t.stabs\t\"%s:", 1, name);
        !           219:        if (p->class == FUNC) {
        !           220:            putprintf("F", 1);
        !           221:            gentype(p->type);
        !           222:            putprintf(",", 1);
        !           223:        } else {
        !           224:            putprintf("P,", 1);
        !           225:        }
        !           226:        sextname(extname, name, level);  /* set extname to entry label */
        !           227:        putprintf("%s,", 1, &(extname[1])); /* remove initial underbar */
        !           228:        snestspec(nestspec, level);
        !           229:        putprintf("%s\",0x%x,0,0,%s", 0, nestspec, N_FUN, extname);
        !           230:     }
        !           231: }
        !           232: 
        !           233:     /*
        !           234:      * construct the colon-separated static nesting string into a
        !           235:      * caller-supplied buffer
        !           236:      */
        !           237: private snestspec(buffer, level)
        !           238:     char buffer[];
        !           239:     int level;
        !           240: {
        !           241:     char *starthere;
        !           242:     int i;
        !           243:     
        !           244:     if (level <= 1) {
        !           245:        buffer[0] = '\0';
        !           246:     } else {
        !           247:        starthere = &buffer[0];
        !           248:        for ( i = 1 ; i < level ; i++ ) {
        !           249:            sprintf(starthere, "%s:", enclosing[i]);
        !           250:            starthere += strlen(enclosing[i]) + 1;
        !           251:        }
        !           252:        *--starthere = '\0'; /* remove last colon */
        !           253:        if (starthere >= &buffer[BUFSIZ-1]) {
        !           254:            panic("snestspec");
        !           255:        }
        !           256:     }
        !           257: }
        !           258: 
        !           259:     /*
        !           260:      * functions
        !           261:      */
        !           262: oldstabfunc( name , typeclass , line , level )
        !           263:     char       *name;
        !           264:     int                typeclass;
        !           265:     int                line;
        !           266:     long       level;
        !           267:     {
        !           268:        char    extname[ BUFSIZ ];
        !           269: 
        !           270:            /*
        !           271:             *  for sdb
        !           272:             */
        !           273:        if ( ! opt('g') ) {
        !           274:                return;
        !           275:        }
        !           276:        putprintf( "    .stabs  \"" , 1 );
        !           277:        putprintf( NAMEFORMAT , 1 , (int) name );
        !           278:        sextname( extname , name , (int) level );
        !           279:        putprintf( "\",0x%x,0,0x%x,%s" , 0 , N_FUN , line , (int) extname );
        !           280:     }
        !           281: 
        !           282:     /*
        !           283:      * source line numbers
        !           284:      */
        !           285: stabline( line )
        !           286:     int        line;
        !           287:     {
        !           288:        if ( ! opt('g') ) {
        !           289:                return;
        !           290:        }
        !           291:        putprintf( "    .stabd  0x%x,0,0x%x" , 0 , N_SLINE , ABS( line ) );
        !           292:     }
        !           293: 
        !           294:     /*
        !           295:      * source files get none or more of these:
        !           296:      *  one as they are entered,
        !           297:      *  and one every time they are returned to from nested #includes
        !           298:      */
        !           299: stabsource(filename, firsttime)
        !           300:     char       *filename;
        !           301:     bool       firsttime;
        !           302: {
        !           303:     int                label;
        !           304:     
        !           305:        /*
        !           306:         *      for separate compilation
        !           307:         */
        !           308:     putprintf("        .stabs  \"%s\",0x%x,0,0x%x,0x%x", 0,
        !           309:            (int) filename, N_PC, N_PSO, N_FLAGCHECKSUM);
        !           310:        /*
        !           311:         *      for debugger
        !           312:         */
        !           313:     if ( ! opt('g') ) {
        !           314:            return;
        !           315:     }
        !           316:     if (oldway != 0) {
        !           317:        label = (int) getlab();
        !           318:        putprintf( "    .stabs  \"" , 1 );
        !           319:        putprintf( NAMEFORMAT , 1 , filename );
        !           320:        putprintf( "\",0x%x,0,0," , 1 , N_SO );
        !           321:        putprintf( PREFIXFORMAT , 0 , LLABELPREFIX , label );
        !           322:        putprintf( PREFIXFORMAT , 1 , LLABELPREFIX , label );
        !           323:        putprintf( ":" , 0 );
        !           324:     } else {
        !           325:        if (firsttime) {
        !           326:            putprintf( "        .stabs  \"" , 1 );
        !           327:            putprintf( NAMEFORMAT , 1 , filename );
        !           328:            putprintf( "\",0x%x,0,0,0" , 0 , N_SO );
        !           329:        }
        !           330:     }
        !           331: }
        !           332: 
        !           333:     /*
        !           334:      * included files get one or more of these:
        !           335:      * one as they are entered by a #include,
        !           336:      * and one every time they are returned to from nested #includes.
        !           337:      */
        !           338: stabinclude(filename, firsttime)
        !           339:     char       *filename;
        !           340:     bool       firsttime;
        !           341: {
        !           342:     int                label;
        !           343:     long       check;
        !           344:     
        !           345:        /*
        !           346:         *      for separate compilation
        !           347:         */
        !           348:     if (firsttime) {
        !           349:        check = checksum(filename);
        !           350:     } else {
        !           351:        check = N_FLAGCHECKSUM;
        !           352:     }
        !           353:     putprintf("        .stabs  \"%s\",0x%x,0,0x%x,0x%x", 0,
        !           354:            (int) filename, N_PC, N_PSOL, check);
        !           355:        /*
        !           356:         *      for sdb
        !           357:         */
        !           358:     if ( ! opt('g') ) {
        !           359:            return;
        !           360:     }
        !           361:     if (oldway != 0) {
        !           362:        label = (int) getlab();
        !           363:        putprintf( "    .stabs  \"" , 1 );
        !           364:        putprintf( NAMEFORMAT , 1 , filename );
        !           365:        putprintf( "\",0x%x,0,0," , 1 , N_SOL );
        !           366:        putprintf( PREFIXFORMAT , 0 , LLABELPREFIX , label );
        !           367:        putprintf( PREFIXFORMAT , 1 , LLABELPREFIX , label );
        !           368:        putprintf( ":" , 0 );
        !           369:     }
        !           370: }
        !           371: 
        !           372:     /*
        !           373:      * anyone know a good checksum for ascii files?
        !           374:      * this does a rotate-left and then exclusive-or's in the character.
        !           375:      * also, it avoids returning checksums of 0.
        !           376:      * The rotate is implemented by shifting and adding back the
        !           377:      * sign bit when negative.
        !           378:      */
        !           379: long
        !           380: checksum(filename)
        !           381:     char       *filename;
        !           382: {
        !           383:     FILE               *filep;
        !           384:     register int       input;
        !           385:     register long      check;
        !           386: 
        !           387:     filep = fopen(filename, "r");
        !           388:     if (filep == NULL) {
        !           389:        perror(filename);
        !           390:        pexit(DIED);
        !           391:     }
        !           392:     check = 0;
        !           393:     while ((input = getc(filep)) != EOF) {
        !           394:        if (check < 0) {
        !           395:            check <<= 1;
        !           396:            check += 1;
        !           397:        } else {
        !           398:            check <<= 1;
        !           399:        }
        !           400:        check ^= input;
        !           401:     }
        !           402:     (void) fclose(filep);
        !           403:     if ((unsigned) check <= N_FLAGCHECKSUM) {
        !           404:        return N_FLAGCHECKSUM + 1;
        !           405:     } else {
        !           406:        return check;
        !           407:     }
        !           408: }
        !           409: 
        !           410: /*
        !           411:  * global Pascal symbols :
        !           412:  *   labels, types, constants, and external procedure and function names:
        !           413:  *   These are used by the separate compilation facility
        !           414:  *   to be able to check for disjoint header files.
        !           415:  */
        !           416: 
        !           417:     /*
        !           418:      * global labels
        !           419:      */
        !           420: stabglabel( label , line )
        !           421:     char       *label;
        !           422:     int                line;
        !           423:     {
        !           424: 
        !           425:        putprintf( "    .stabs  \"%s\",0x%x,0,0x%x,0x%x" , 0 
        !           426:                    , (int) label , N_PC , N_PGLABEL , ABS( line ) );
        !           427:     }
        !           428: 
        !           429:     /*
        !           430:      * global constants
        !           431:      */
        !           432: stabgconst( constant , line )
        !           433:     char       *constant;
        !           434:     int                line;
        !           435:     {
        !           436: 
        !           437:            putprintf( "        .stabs  \"%s\",0x%x,0,0x%x,0x%x" , 0 
        !           438:                        , (int) constant , N_PC , N_PGCONST , ABS( line ) );
        !           439:     }
        !           440: 
        !           441: /*
        !           442:  * Generate symbolic information about a constant.
        !           443:  */
        !           444: 
        !           445: stabconst (c)
        !           446: struct nl *c;
        !           447: {
        !           448:     if (opt('g') && oldway == 0) {
        !           449:        putprintf("\t.stabs\t\"%s:c=", 1, c->symbol);
        !           450:        if (c->type == nl + TSTR) {
        !           451:            putprintf("s'%s'", 1, c->ptr[0]);
        !           452:        } else if (c->type == nl + T1CHAR) {
        !           453:            putprintf("c%d", 1, c->range[0]);
        !           454:        } else if (isa(c->type, "i")) {
        !           455:            putprintf("i%d", 1, c->range[0]);
        !           456:        } else if (isa(c->type, "d")) {
        !           457:            putprintf("r%g", 1, c->real);
        !           458:        } else {
        !           459:            putprintf("e", 1);
        !           460:            gentype(c->type);
        !           461:            putprintf(",%d", 1, c->range[0]);
        !           462:        }
        !           463:        putprintf("\",0x%x,0,0x%x,0x%x", 0, N_LSYM, 0, 0);
        !           464:     }
        !           465: }
        !           466: 
        !           467: stabgtype (name, type, line)
        !           468: char *name;
        !           469: struct nl *type;
        !           470: int line;
        !           471: {
        !           472:     putprintf("        .stabs  \"%s\",0x%x,0,0x%x,0x%x" ,
        !           473:        0, name, N_PC , N_PGTYPE, ABS(line)
        !           474:     );
        !           475:     if (oldway == 0) {
        !           476:        stabltype(name, type);
        !           477:     }
        !           478: }
        !           479: 
        !           480: stabltype (name, type)
        !           481: char *name;
        !           482: struct nl *type;
        !           483: {
        !           484:     if (opt('g')) {
        !           485:        putprintf("\t.stabs\t\"%s:t", 1, name);
        !           486:        gentype(type);
        !           487:        putprintf("\",0x%x,0,0,0", 0, N_LSYM);
        !           488:     }
        !           489: }
        !           490: 
        !           491:     /*
        !           492:      * external functions and procedures
        !           493:      */        
        !           494: stabefunc( name , typeclass , line )
        !           495:     char       *name;
        !           496:     int                typeclass;
        !           497:     int                line;
        !           498:     {
        !           499:        int     type;
        !           500: 
        !           501:        if ( typeclass == FUNC ) {
        !           502:            type = N_PEFUNC;
        !           503:        } else if ( typeclass == PROC ) {
        !           504:            type = N_PEPROC;
        !           505:        } else {
        !           506:            return;
        !           507:        }
        !           508:        putprintf( "    .stabs  \"%s\",0x%x,0,0x%x,0x%x" , 0 
        !           509:                    , (int) name , N_PC , type , ABS( line ) );
        !           510:     }
        !           511: 
        !           512: /*
        !           513:  * Generate type information encoded as a string for dbx.
        !           514:  * The fwdptrnum field is used only when the type is a pointer
        !           515:  * to a type that isn't known when it was entered.  When the
        !           516:  * type field is filled for some such tptr, fixfwdtype should
        !           517:  * be called to output an equivalencing type definition.
        !           518:  */
        !           519: 
        !           520: typedef struct TypeDesc *TypeDesc;
        !           521: 
        !           522: struct TypeDesc {
        !           523:     struct nl *tptr;
        !           524:     int tnum;
        !           525:     int fwdptrnum;
        !           526:     TypeDesc chain;
        !           527: };
        !           528: 
        !           529: #define TABLESIZE 2003
        !           530: 
        !           531: #define typehash(t) ( ( ((int) t) >> 2 ) % TABLESIZE )
        !           532: 
        !           533: private int tcount = 1;
        !           534: private TypeDesc typetable[TABLESIZE];
        !           535: 
        !           536: private TypeDesc tdlookup (t)
        !           537: struct nl *t;
        !           538: {
        !           539:     register TypeDesc td;
        !           540: 
        !           541:     td = typetable[typehash(t)];
        !           542:     while (td != NIL && td->tptr != t) {
        !           543:        td = td->chain;
        !           544:     }
        !           545:     return td;
        !           546: }
        !           547: 
        !           548: private int typelookup (t)
        !           549: struct nl *t;
        !           550: {
        !           551:     register TypeDesc td;
        !           552:     int r;
        !           553: 
        !           554:     td = tdlookup(t);
        !           555:     if (td == NIL) {
        !           556:        r = 0;
        !           557:     } else {
        !           558:        r = td->tnum;
        !           559:     }
        !           560:     return r;
        !           561: }
        !           562: 
        !           563: private int entertype (type)
        !           564: struct nl *type;
        !           565: {
        !           566:     register TypeDesc td;
        !           567:     register int i;
        !           568: 
        !           569:     td = (TypeDesc) malloc(sizeof(struct TypeDesc));
        !           570:     td->tptr = type;
        !           571:     td->tnum = tcount;
        !           572:     td->fwdptrnum = 0;
        !           573:     ++tcount;
        !           574:     i = typehash(type);
        !           575:     td->chain = typetable[i];
        !           576:     typetable[i] = td;
        !           577:     return td->tnum;
        !           578: }
        !           579: 
        !           580: /*
        !           581:  * The in_types table currently contains "boolean", "char", "integer",
        !           582:  * "real" and "_nil".  (See nl.c for definition.)
        !           583:  * The lookup call below will give the TYPE class nl entry for these
        !           584:  * types.  In each case except _nil, the type field of that entry is a RANGE
        !           585:  * class nl entry for the type.  Sometimes other symbol table entries
        !           586:  * point to the TYPE entry (e.g., when there is a range over the base type),
        !           587:  * and other entries point to the RANGE entry (e.g., for a variable of the
        !           588:  * given type).  We don't really want to distinguish between these uses
        !           589:  * in dbx, and since it appears that the RANGE entries are not reused if
        !           590:  * a range happens to coincide, we will give the two the same identifying
        !           591:  * dbx type number.
        !           592:  */
        !           593: 
        !           594: private inittypes()
        !           595: {
        !           596:     int i;
        !           597:     extern char *in_types[];
        !           598:     struct nl *p;
        !           599: 
        !           600:     for (i = 0; in_types[i] != NIL; i++) {
        !           601:        p = lookup(in_types[i]);
        !           602:        if (p != NIL) {
        !           603:            entertype(p);
        !           604:            if (p->type != NIL) {
        !           605:                --tcount; /* see comment above */
        !           606:                entertype(p->type);
        !           607:            }
        !           608:        }
        !           609:     }
        !           610: }
        !           611: 
        !           612: static genarray (t)
        !           613: struct nl *t;
        !           614: {
        !           615:     register struct nl *p;
        !           616: 
        !           617:     for (p = t->chain; p != NIL; p = p->chain) {
        !           618:        putprintf("a", 1);
        !           619:        gentype(p);
        !           620:        putprintf(";", 1);
        !           621:     }
        !           622:     gentype(t->type);
        !           623: }
        !           624: 
        !           625: /*
        !           626:  * Really we should walk through ptr[NL_FIELDLIST] for the fields,
        !           627:  * and then do the variant tag and fields separately, but dbx
        !           628:  * doesn't support this yet.
        !           629:  * So, since all the fields of all the variants are on the chain,
        !           630:  * we walk through that.  Except that this gives the fields in the
        !           631:  * reverse order, so we want to print in reverse order.
        !           632:  */
        !           633: 
        !           634: static genrecord (t)
        !           635: struct nl *t;
        !           636: {
        !           637:     putprintf("s%d", 1, t->value[NL_OFFS]);
        !           638:     if (t->chain != NIL) {
        !           639:        genrecfield(t->chain, 1);
        !           640:     }
        !           641:     putprintf(";", 1);
        !           642: }
        !           643: 
        !           644: static genrecfield (t, n)
        !           645: struct nl *t;
        !           646: int n;
        !           647: {
        !           648:     if (t->chain != NULL) {
        !           649:        genrecfield(t->chain, n + 1);
        !           650:        if (n % 2 == 0) {
        !           651:            gencontinue();
        !           652:        }
        !           653:     }
        !           654:     putprintf("%s:", 1, t->symbol);
        !           655:     gentype(t->type);
        !           656:     putprintf(",%d,%d;", 1, 8*t->value[NL_OFFS], 8*lwidth(t->type));
        !           657: }
        !           658: 
        !           659: static genvarnt (t)
        !           660: struct nl *t;
        !           661: {
        !           662:     genrecord(t);
        !           663: }
        !           664: 
        !           665: static genptr (t)
        !           666: struct nl *t;
        !           667: {
        !           668:     register TypeDesc td;
        !           669:     
        !           670:     putprintf("*", 1);
        !           671:     if (t->type != NIL) {
        !           672:        gentype(t->type);
        !           673:     } else {
        !           674:        /*
        !           675:         * unresolved forward pointer: use tcount to represent what is
        !           676:          * begin pointed to, to be defined later
        !           677:         */
        !           678:        td = tdlookup(t);
        !           679:        if (td == NIL) {
        !           680:            panic("nil ptr in stab.genptr");
        !           681:        }
        !           682:        td->fwdptrnum = tcount;
        !           683:        putprintf("%d", 1, tcount);
        !           684:        ++tcount;
        !           685:     }
        !           686: }
        !           687: 
        !           688: /*
        !           689:  * The type t is a pointer which has just had its type field filled.
        !           690:  * We need to generate a type stab saying that the number saved
        !           691:  * in t's fwdptrnum is the same as the t->type's number
        !           692:  */
        !           693: 
        !           694: fixfwdtype (t)
        !           695: struct nl *t;
        !           696: {
        !           697:     register TypeDesc td;
        !           698:     
        !           699:     if (opt('g') && oldway == 0) {
        !           700:        td = tdlookup(t);
        !           701:        if (td != NIL) {
        !           702:            putprintf("\t.stabs\t\":t%d=", 1, td->fwdptrnum);
        !           703:            gentype(t->type);
        !           704:            putprintf("\",0x%x,0,0,0", 0, N_LSYM);
        !           705:        }
        !           706:     }
        !           707: }
        !           708: 
        !           709: static genenum (t)
        !           710: struct nl *t;
        !           711: {
        !           712:     register struct nl *e;
        !           713:     register int i;
        !           714: 
        !           715:     putprintf("e", 1);
        !           716:     i = 1;
        !           717:     e = t->chain;
        !           718:     while (e != NULL) {
        !           719:        if (i > 2) {
        !           720:            gencontinue();
        !           721:            i = 0;
        !           722:        }
        !           723:        putprintf("%s:%d,", 1, e->symbol, e->range[0]);
        !           724:        e = e->chain;
        !           725:        ++i;
        !           726:     }
        !           727:     putprintf(";", 1);
        !           728: }
        !           729: 
        !           730: static genset (t)
        !           731: struct nl *t;
        !           732: {
        !           733:     putprintf("S", 1);
        !           734:     gentype(t->type);
        !           735: }
        !           736: 
        !           737: static genrange (t)
        !           738: struct nl *t;
        !           739: {
        !           740:     putprintf("r", 1);
        !           741:     gentype(t->type);
        !           742:     putprintf(";%d;%d", 1, t->range[0], t->range[1]);
        !           743: }
        !           744: 
        !           745: static genfparam (t)
        !           746: struct nl *t;
        !           747: {
        !           748:     struct nl *p;
        !           749:     int count;
        !           750:     
        !           751:     if (t->type != NULL) {
        !           752:        putprintf("f", 1);
        !           753:        gentype(t->type);
        !           754:        putprintf(",", 1);
        !           755:     } else {
        !           756:        putprintf("p", 1);
        !           757:     }
        !           758:     count = 0;
        !           759:     for (p = t->ptr[NL_FCHAIN]; p != NULL; p = p->chain) {
        !           760:        ++count;
        !           761:     }
        !           762:     putprintf("%d;", 1, count);
        !           763:     for (p = t->ptr[NL_FCHAIN]; p != NULL; p = p->chain) {
        !           764:        gentype(p->type);
        !           765:        putprintf(",%d;", 1, p->class);
        !           766:     }
        !           767: }
        !           768: 
        !           769: static genfile (t)
        !           770: struct nl *t;
        !           771: {
        !           772:     putprintf("d", 1);
        !           773:     gentype(t->type);
        !           774: }
        !           775: 
        !           776: static gentype (t)
        !           777: struct nl *t;
        !           778: {
        !           779:     int id;
        !           780: 
        !           781:     if (tcount == 1) {
        !           782:        inittypes();
        !           783:     }
        !           784:     id = typelookup(t);
        !           785:     if (id != 0) {
        !           786:        putprintf("%d", 1, id);
        !           787:     } else if (t->class == SCAL && t->chain == NULL) {
        !           788:        id = typelookup(t->type);
        !           789:        if (id != 0) {
        !           790:            putprintf("%d", 1, id);
        !           791:        } else {
        !           792:            genenum(t->type);
        !           793:        }
        !           794:     } else {
        !           795:        id = entertype(t);
        !           796:        putprintf("%d=", 1, id);
        !           797:        switch (t->class) {
        !           798:            case TYPE:
        !           799:                gentype(t->type);
        !           800:                break;
        !           801: 
        !           802:            case ARRAY:
        !           803:                genarray(t);
        !           804:                break;
        !           805: 
        !           806:            case RECORD:
        !           807:                genrecord(t);
        !           808:                break;
        !           809: 
        !           810:            case VARNT:
        !           811:                genvarnt(t);
        !           812:                break;
        !           813: 
        !           814:            case REF:
        !           815:                gentype(t->type);
        !           816:                break;
        !           817: 
        !           818:            case PTR:
        !           819:                genptr(t);
        !           820:                break;
        !           821: 
        !           822:            case SET:
        !           823:                genset(t);
        !           824:                break;
        !           825: 
        !           826:            case RANGE:
        !           827:                genrange(t);
        !           828:                break;
        !           829: 
        !           830:            case SCAL:
        !           831:                genenum(t);
        !           832:                break;
        !           833: 
        !           834:            case FPROC:
        !           835:            case FFUNC:
        !           836:                genfparam(t);
        !           837:                break;
        !           838: 
        !           839:            case FILET:
        !           840:            case PTRFILE:
        !           841:                genfile(t);
        !           842:                break;
        !           843: 
        !           844:            default:
        !           845:                /* This shouldn't happen */
        !           846:                /* Rather than bomb outright, let debugging go on */
        !           847:                warning();
        !           848:                error("Bad type class found in stab");
        !           849:                putprintf("1", 1, t->class);
        !           850:                break;
        !           851:        }
        !           852:     }
        !           853: }
        !           854: 
        !           855: /*
        !           856:  * Continue stab information in a namelist new entry.  This is necessary
        !           857:  * to avoid overflowing putprintf's buffer.
        !           858:  */
        !           859: 
        !           860: static gencontinue ()
        !           861: {
        !           862:     putprintf("?\",0x%x,0,0,0", 0, N_LSYM);
        !           863:     putprintf("\t.stabs\t\"", 1);
        !           864: }
        !           865: 
        !           866: #endif PC

unix.superglobalmegacorp.com

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