Annotation of 43BSDTahoe/ucb/gprof/gprof.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1983 Regents of the University of California.
                      3:  * All rights reserved.
                      4:  *
                      5:  * Redistribution and use in source and binary forms are permitted
                      6:  * provided that the above copyright notice and this paragraph are
                      7:  * duplicated in all such forms and that any documentation,
                      8:  * advertising materials, and other materials related to such
                      9:  * distribution and use acknowledge that the software was developed
                     10:  * by the University of California, Berkeley.  The name of the
                     11:  * University may not be used to endorse or promote products derived
                     12:  * from this software without specific prior written permission.
                     13:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
                     14:  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
                     15:  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
                     16:  */
                     17: 
                     18: #ifndef lint
                     19: char copyright[] =
                     20: "@(#) Copyright (c) 1983 Regents of the University of California.\n\
                     21:  All rights reserved.\n";
                     22: #endif /* not lint */
                     23: 
                     24: #ifndef lint
                     25: static char sccsid[] = "@(#)gprof.c    5.5 (Berkeley) 6/29/88";
                     26: #endif /* not lint */
                     27: 
                     28: #include "gprof.h"
                     29: 
                     30: char   *whoami = "gprof";
                     31: 
                     32:     /*
                     33:      * things which get -E excluded by default.
                     34:      */
                     35: char   *defaultEs[] = { "mcount" , "__mcleanup" , 0 };
                     36: 
                     37: main(argc, argv)
                     38:     int argc;
                     39:     char **argv;
                     40: {
                     41:     char       **sp;
                     42:     nltype     **timesortnlp;
                     43: 
                     44:     --argc;
                     45:     argv++;
                     46:     debug = 0;
                     47:     bflag = TRUE;
                     48:     while ( *argv != 0 && **argv == '-' ) {
                     49:        (*argv)++;
                     50:        switch ( **argv ) {
                     51:        case 'a':
                     52:            aflag = TRUE;
                     53:            break;
                     54:        case 'b':
                     55:            bflag = FALSE;
                     56:            break;
                     57:        case 'c':
                     58:            cflag = TRUE;
                     59:            break;
                     60:        case 'd':
                     61:            dflag = TRUE;
                     62:            (*argv)++;
                     63:            debug |= atoi( *argv );
                     64:            debug |= ANYDEBUG;
                     65: #          ifdef DEBUG
                     66:                printf("[main] debug = %d\n", debug);
                     67: #          else not DEBUG
                     68:                printf("%s: -d ignored\n", whoami);
                     69: #          endif DEBUG
                     70:            break;
                     71:        case 'E':
                     72:            ++argv;
                     73:            addlist( Elist , *argv );
                     74:            Eflag = TRUE;
                     75:            addlist( elist , *argv );
                     76:            eflag = TRUE;
                     77:            break;
                     78:        case 'e':
                     79:            addlist( elist , *++argv );
                     80:            eflag = TRUE;
                     81:            break;
                     82:        case 'F':
                     83:            ++argv;
                     84:            addlist( Flist , *argv );
                     85:            Fflag = TRUE;
                     86:            addlist( flist , *argv );
                     87:            fflag = TRUE;
                     88:            break;
                     89:        case 'f':
                     90:            addlist( flist , *++argv );
                     91:            fflag = TRUE;
                     92:            break;
                     93:        case 'k':
                     94:            addlist( kfromlist , *++argv );
                     95:            addlist( ktolist , *++argv );
                     96:            kflag = TRUE;
                     97:            break;
                     98:        case 's':
                     99:            sflag = TRUE;
                    100:            break;
                    101:        case 'z':
                    102:            zflag = TRUE;
                    103:            break;
                    104:        }
                    105:        argv++;
                    106:     }
                    107:     if ( *argv != 0 ) {
                    108:        a_outname  = *argv;
                    109:        argv++;
                    110:     } else {
                    111:        a_outname  = A_OUTNAME;
                    112:     }
                    113:     if ( *argv != 0 ) {
                    114:        gmonname = *argv;
                    115:        argv++;
                    116:     } else {
                    117:        gmonname = GMONNAME;
                    118:     }
                    119:        /*
                    120:         *      turn off default functions
                    121:         */
                    122:     for ( sp = &defaultEs[0] ; *sp ; sp++ ) {
                    123:        Eflag = TRUE;
                    124:        addlist( Elist , *sp );
                    125:        eflag = TRUE;
                    126:        addlist( elist , *sp );
                    127:     }
                    128:        /*
                    129:         *      how many ticks per second?
                    130:         *      if we can't tell, report time in ticks.
                    131:         */
                    132:     hz = hertz();
                    133:     if (hz == 0) {
                    134:        hz = 1;
                    135:        fprintf(stderr, "time is in ticks, not seconds\n");
                    136:     }
                    137:        /*
                    138:         *      get information about a.out file.
                    139:         */
                    140:     getnfile();
                    141:        /*
                    142:         *      get information about mon.out file(s).
                    143:         */
                    144:     do {
                    145:        getpfile( gmonname );
                    146:        if ( *argv != 0 ) {
                    147:            gmonname = *argv;
                    148:        }
                    149:     } while ( *argv++ != 0 );
                    150:        /*
                    151:         *      dump out a gmon.sum file if requested
                    152:         */
                    153:     if ( sflag ) {
                    154:        dumpsum( GMONSUM );
                    155:     }
                    156:        /*
                    157:         *      assign samples to procedures
                    158:         */
                    159:     asgnsamples();
                    160:        /*
                    161:         *      assemble the dynamic profile
                    162:         */
                    163:     timesortnlp = doarcs();
                    164:        /*
                    165:         *      print the dynamic profile
                    166:         */
                    167:     printgprof( timesortnlp ); 
                    168:        /*
                    169:         *      print the flat profile
                    170:         */
                    171:     printprof();       
                    172:        /*
                    173:         *      print the index
                    174:         */
                    175:     printindex();      
                    176:     done();
                    177: }
                    178: 
                    179:     /*
                    180:      * Set up string and symbol tables from a.out.
                    181:      * and optionally the text space.
                    182:      * On return symbol table is sorted by value.
                    183:      */
                    184: getnfile()
                    185: {
                    186:     FILE       *nfile;
                    187:     int                valcmp();
                    188: 
                    189:     nfile = fopen( a_outname ,"r");
                    190:     if (nfile == NULL) {
                    191:        perror( a_outname );
                    192:        done();
                    193:     }
                    194:     fread(&xbuf, 1, sizeof(xbuf), nfile);
                    195:     if (N_BADMAG(xbuf)) {
                    196:        fprintf(stderr, "%s: %s: bad format\n", whoami , a_outname );
                    197:        done();
                    198:     }
                    199:     getstrtab(nfile);
                    200:     getsymtab(nfile);
                    201:     gettextspace( nfile );
                    202:     qsort(nl, nname, sizeof(nltype), valcmp);
                    203:     fclose(nfile);
                    204: #   ifdef DEBUG
                    205:        if ( debug & AOUTDEBUG ) {
                    206:            register int j;
                    207: 
                    208:            for (j = 0; j < nname; j++){
                    209:                printf("[getnfile] 0X%08x\t%s\n", nl[j].value, nl[j].name);
                    210:            }
                    211:        }
                    212: #   endif DEBUG
                    213: }
                    214: 
                    215: getstrtab(nfile)
                    216:     FILE       *nfile;
                    217: {
                    218: 
                    219:     fseek(nfile, (long)(N_SYMOFF(xbuf) + xbuf.a_syms), 0);
                    220:     if (fread(&ssiz, sizeof (ssiz), 1, nfile) == 0) {
                    221:        fprintf(stderr, "%s: %s: no string table (old format?)\n" ,
                    222:                whoami , a_outname );
                    223:        done();
                    224:     }
                    225:     strtab = (char *)calloc(ssiz, 1);
                    226:     if (strtab == NULL) {
                    227:        fprintf(stderr, "%s: %s: no room for %d bytes of string table",
                    228:                whoami , a_outname , ssiz);
                    229:        done();
                    230:     }
                    231:     if (fread(strtab+sizeof(ssiz), ssiz-sizeof(ssiz), 1, nfile) != 1) {
                    232:        fprintf(stderr, "%s: %s: error reading string table\n",
                    233:                whoami , a_outname );
                    234:        done();
                    235:     }
                    236: }
                    237: 
                    238:     /*
                    239:      * Read in symbol table
                    240:      */
                    241: getsymtab(nfile)
                    242:     FILE       *nfile;
                    243: {
                    244:     register long      i;
                    245:     int                        askfor;
                    246:     struct nlist       nbuf;
                    247: 
                    248:     /* pass1 - count symbols */
                    249:     fseek(nfile, (long)N_SYMOFF(xbuf), 0);
                    250:     nname = 0;
                    251:     for (i = xbuf.a_syms; i > 0; i -= sizeof(struct nlist)) {
                    252:        fread(&nbuf, sizeof(nbuf), 1, nfile);
                    253:        if ( ! funcsymbol( &nbuf ) ) {
                    254:            continue;
                    255:        }
                    256:        nname++;
                    257:     }
                    258:     if (nname == 0) {
                    259:        fprintf(stderr, "%s: %s: no symbols\n", whoami , a_outname );
                    260:        done();
                    261:     }
                    262:     askfor = nname + 1;
                    263:     nl = (nltype *) calloc( askfor , sizeof(nltype) );
                    264:     if (nl == 0) {
                    265:        fprintf(stderr, "%s: No room for %d bytes of symbol table\n",
                    266:                whoami, askfor * sizeof(nltype) );
                    267:        done();
                    268:     }
                    269: 
                    270:     /* pass2 - read symbols */
                    271:     fseek(nfile, (long)N_SYMOFF(xbuf), 0);
                    272:     npe = nl;
                    273:     nname = 0;
                    274:     for (i = xbuf.a_syms; i > 0; i -= sizeof(struct nlist)) {
                    275:        fread(&nbuf, sizeof(nbuf), 1, nfile);
                    276:        if ( ! funcsymbol( &nbuf ) ) {
                    277: #          ifdef DEBUG
                    278:                if ( debug & AOUTDEBUG ) {
                    279:                    printf( "[getsymtab] rejecting: 0x%x %s\n" ,
                    280:                            nbuf.n_type , strtab + nbuf.n_un.n_strx );
                    281:                }
                    282: #          endif DEBUG
                    283:            continue;
                    284:        }
                    285:        npe->value = nbuf.n_value;
                    286:        npe->name = strtab+nbuf.n_un.n_strx;
                    287: #      ifdef DEBUG
                    288:            if ( debug & AOUTDEBUG ) {
                    289:                printf( "[getsymtab] %d %s 0x%08x\n" ,
                    290:                        nname , npe -> name , npe -> value );
                    291:            }
                    292: #      endif DEBUG
                    293:        npe++;
                    294:        nname++;
                    295:     }
                    296:     npe->value = -1;
                    297: }
                    298: 
                    299:     /*
                    300:      * read in the text space of an a.out file
                    301:      */
                    302: gettextspace( nfile )
                    303:     FILE       *nfile;
                    304: {
                    305:     char       *malloc();
                    306:     
                    307:     if ( cflag == 0 ) {
                    308:        return;
                    309:     }
                    310:     textspace = (u_char *) malloc( xbuf.a_text );
                    311:     if ( textspace == 0 ) {
                    312:        fprintf( stderr , "%s: ran out room for %d bytes of text space:  " ,
                    313:                        whoami , xbuf.a_text );
                    314:        fprintf( stderr , "can't do -c\n" );
                    315:        return;
                    316:     }
                    317:     (void) fseek( nfile , N_TXTOFF( xbuf ) , 0 );
                    318:     if ( fread( textspace , 1 , xbuf.a_text , nfile ) != xbuf.a_text ) {
                    319:        fprintf( stderr , "%s: couldn't read text space:  " , whoami );
                    320:        fprintf( stderr , "can't do -c\n" );
                    321:        free( textspace );
                    322:        textspace = 0;
                    323:        return;
                    324:     }
                    325: }
                    326:     /*
                    327:      * information from a gmon.out file is in two parts:
                    328:      * an array of sampling hits within pc ranges,
                    329:      * and the arcs.
                    330:      */
                    331: getpfile(filename)
                    332:     char *filename;
                    333: {
                    334:     FILE               *pfile;
                    335:     FILE               *openpfile();
                    336:     struct rawarc      arc;
                    337: 
                    338:     pfile = openpfile(filename);
                    339:     readsamples(pfile);
                    340:        /*
                    341:         *      the rest of the file consists of
                    342:         *      a bunch of <from,self,count> tuples.
                    343:         */
                    344:     while ( fread( &arc , sizeof arc , 1 , pfile ) == 1 ) {
                    345: #      ifdef DEBUG
                    346:            if ( debug & SAMPLEDEBUG ) {
                    347:                printf( "[getpfile] frompc 0x%x selfpc 0x%x count %d\n" ,
                    348:                        arc.raw_frompc , arc.raw_selfpc , arc.raw_count );
                    349:            }
                    350: #      endif DEBUG
                    351:            /*
                    352:             *  add this arc
                    353:             */
                    354:        tally( &arc );
                    355:     }
                    356:     fclose(pfile);
                    357: }
                    358: 
                    359: FILE *
                    360: openpfile(filename)
                    361:     char *filename;
                    362: {
                    363:     struct hdr tmp;
                    364:     FILE       *pfile;
                    365: 
                    366:     if((pfile = fopen(filename, "r")) == NULL) {
                    367:        perror(filename);
                    368:        done();
                    369:     }
                    370:     fread(&tmp, sizeof(struct hdr), 1, pfile);
                    371:     if ( s_highpc != 0 && ( tmp.lowpc != h.lowpc ||
                    372:         tmp.highpc != h.highpc || tmp.ncnt != h.ncnt ) ) {
                    373:        fprintf(stderr, "%s: incompatible with first gmon file\n", filename);
                    374:        done();
                    375:     }
                    376:     h = tmp;
                    377:     s_lowpc = (unsigned long) h.lowpc;
                    378:     s_highpc = (unsigned long) h.highpc;
                    379:     lowpc = (unsigned long)h.lowpc / sizeof(UNIT);
                    380:     highpc = (unsigned long)h.highpc / sizeof(UNIT);
                    381:     sampbytes = h.ncnt - sizeof(struct hdr);
                    382:     nsamples = sampbytes / sizeof (UNIT);
                    383: #   ifdef DEBUG
                    384:        if ( debug & SAMPLEDEBUG ) {
                    385:            printf( "[openpfile] hdr.lowpc 0x%x hdr.highpc 0x%x hdr.ncnt %d\n",
                    386:                h.lowpc , h.highpc , h.ncnt );
                    387:            printf( "[openpfile]   s_lowpc 0x%x   s_highpc 0x%x\n" ,
                    388:                s_lowpc , s_highpc );
                    389:            printf( "[openpfile]     lowpc 0x%x     highpc 0x%x\n" ,
                    390:                lowpc , highpc );
                    391:            printf( "[openpfile] sampbytes %d nsamples %d\n" ,
                    392:                sampbytes , nsamples );
                    393:        }
                    394: #   endif DEBUG
                    395:     return(pfile);
                    396: }
                    397: 
                    398: tally( rawp )
                    399:     struct rawarc      *rawp;
                    400: {
                    401:     nltype             *parentp;
                    402:     nltype             *childp;
                    403: 
                    404:     parentp = nllookup( rawp -> raw_frompc );
                    405:     childp = nllookup( rawp -> raw_selfpc );
                    406:     if ( kflag
                    407:         && onlist( kfromlist , parentp -> name )
                    408:         && onlist( ktolist , childp -> name ) ) {
                    409:        return;
                    410:     }
                    411:     childp -> ncall += rawp -> raw_count;
                    412: #   ifdef DEBUG
                    413:        if ( debug & TALLYDEBUG ) {
                    414:            printf( "[tally] arc from %s to %s traversed %d times\n" ,
                    415:                    parentp -> name , childp -> name , rawp -> raw_count );
                    416:        }
                    417: #   endif DEBUG
                    418:     addarc( parentp , childp , rawp -> raw_count );
                    419: }
                    420: 
                    421: /*
                    422:  * dump out the gmon.sum file
                    423:  */
                    424: dumpsum( sumfile )
                    425:     char *sumfile;
                    426: {
                    427:     register nltype *nlp;
                    428:     register arctype *arcp;
                    429:     struct rawarc arc;
                    430:     FILE *sfile;
                    431: 
                    432:     if ( ( sfile = fopen ( sumfile , "w" ) ) == NULL ) {
                    433:        perror( sumfile );
                    434:        done();
                    435:     }
                    436:     /*
                    437:      * dump the header; use the last header read in
                    438:      */
                    439:     if ( fwrite( &h , sizeof h , 1 , sfile ) != 1 ) {
                    440:        perror( sumfile );
                    441:        done();
                    442:     }
                    443:     /*
                    444:      * dump the samples
                    445:      */
                    446:     if (fwrite(samples, sizeof (UNIT), nsamples, sfile) != nsamples) {
                    447:        perror( sumfile );
                    448:        done();
                    449:     }
                    450:     /*
                    451:      * dump the normalized raw arc information
                    452:      */
                    453:     for ( nlp = nl ; nlp < npe ; nlp++ ) {
                    454:        for ( arcp = nlp -> children ; arcp ; arcp = arcp -> arc_childlist ) {
                    455:            arc.raw_frompc = arcp -> arc_parentp -> value;
                    456:            arc.raw_selfpc = arcp -> arc_childp -> value;
                    457:            arc.raw_count = arcp -> arc_count;
                    458:            if ( fwrite ( &arc , sizeof arc , 1 , sfile ) != 1 ) {
                    459:                perror( sumfile );
                    460:                done();
                    461:            }
                    462: #          ifdef DEBUG
                    463:                if ( debug & SAMPLEDEBUG ) {
                    464:                    printf( "[dumpsum] frompc 0x%x selfpc 0x%x count %d\n" ,
                    465:                            arc.raw_frompc , arc.raw_selfpc , arc.raw_count );
                    466:                }
                    467: #          endif DEBUG
                    468:        }
                    469:     }
                    470:     fclose( sfile );
                    471: }
                    472: 
                    473: valcmp(p1, p2)
                    474:     nltype *p1, *p2;
                    475: {
                    476:     if ( p1 -> value < p2 -> value ) {
                    477:        return LESSTHAN;
                    478:     }
                    479:     if ( p1 -> value > p2 -> value ) {
                    480:        return GREATERTHAN;
                    481:     }
                    482:     return EQUALTO;
                    483: }
                    484: 
                    485: readsamples(pfile)
                    486:     FILE       *pfile;
                    487: {
                    488:     register i;
                    489:     UNIT       sample;
                    490:     
                    491:     if (samples == 0) {
                    492:        samples = (UNIT *) calloc(sampbytes, sizeof (UNIT));
                    493:        if (samples == 0) {
                    494:            fprintf( stderr , "%s: No room for %d sample pc's\n", 
                    495:                whoami , sampbytes / sizeof (UNIT));
                    496:            done();
                    497:        }
                    498:     }
                    499:     for (i = 0; i < nsamples; i++) {
                    500:        fread(&sample, sizeof (UNIT), 1, pfile);
                    501:        if (feof(pfile))
                    502:                break;
                    503:        samples[i] += sample;
                    504:     }
                    505:     if (i != nsamples) {
                    506:        fprintf(stderr,
                    507:            "%s: unexpected EOF after reading %d/%d samples\n",
                    508:                whoami , --i , nsamples );
                    509:        done();
                    510:     }
                    511: }
                    512: 
                    513: /*
                    514:  *     Assign samples to the procedures to which they belong.
                    515:  *
                    516:  *     There are three cases as to where pcl and pch can be
                    517:  *     with respect to the routine entry addresses svalue0 and svalue1
                    518:  *     as shown in the following diagram.  overlap computes the
                    519:  *     distance between the arrows, the fraction of the sample
                    520:  *     that is to be credited to the routine which starts at svalue0.
                    521:  *
                    522:  *         svalue0                                         svalue1
                    523:  *            |                                               |
                    524:  *            v                                               v
                    525:  *
                    526:  *            +-----------------------------------------------+
                    527:  *            |                                               |
                    528:  *       |  ->|    |<-         ->|         |<-         ->|    |<-  |
                    529:  *       |         |             |         |             |         |
                    530:  *       +---------+             +---------+             +---------+
                    531:  *
                    532:  *       ^         ^             ^         ^             ^         ^
                    533:  *       |         |             |         |             |         |
                    534:  *      pcl       pch           pcl       pch           pcl       pch
                    535:  *
                    536:  *     For the vax we assert that samples will never fall in the first
                    537:  *     two bytes of any routine, since that is the entry mask,
                    538:  *     thus we give call alignentries() to adjust the entry points if
                    539:  *     the entry mask falls in one bucket but the code for the routine
                    540:  *     doesn't start until the next bucket.  In conjunction with the
                    541:  *     alignment of routine addresses, this should allow us to have
                    542:  *     only one sample for every four bytes of text space and never
                    543:  *     have any overlap (the two end cases, above).
                    544:  */
                    545: asgnsamples()
                    546: {
                    547:     register int       j;
                    548:     UNIT               ccnt;
                    549:     double             time;
                    550:     unsigned long      pcl, pch;
                    551:     register int       i;
                    552:     unsigned long      overlap;
                    553:     unsigned long      svalue0, svalue1;
                    554: 
                    555:     /* read samples and assign to namelist symbols */
                    556:     scale = highpc - lowpc;
                    557:     scale /= nsamples;
                    558:     alignentries();
                    559:     for (i = 0, j = 1; i < nsamples; i++) {
                    560:        ccnt = samples[i];
                    561:        if (ccnt == 0)
                    562:                continue;
                    563:        pcl = lowpc + scale * i;
                    564:        pch = lowpc + scale * (i + 1);
                    565:        time = ccnt;
                    566: #      ifdef DEBUG
                    567:            if ( debug & SAMPLEDEBUG ) {
                    568:                printf( "[asgnsamples] pcl 0x%x pch 0x%x ccnt %d\n" ,
                    569:                        pcl , pch , ccnt );
                    570:            }
                    571: #      endif DEBUG
                    572:        totime += time;
                    573:        for (j = j - 1; j < nname; j++) {
                    574:            svalue0 = nl[j].svalue;
                    575:            svalue1 = nl[j+1].svalue;
                    576:                /*
                    577:                 *      if high end of tick is below entry address, 
                    578:                 *      go for next tick.
                    579:                 */
                    580:            if (pch < svalue0)
                    581:                    break;
                    582:                /*
                    583:                 *      if low end of tick into next routine,
                    584:                 *      go for next routine.
                    585:                 */
                    586:            if (pcl >= svalue1)
                    587:                    continue;
                    588:            overlap = min(pch, svalue1) - max(pcl, svalue0);
                    589:            if (overlap > 0) {
                    590: #              ifdef DEBUG
                    591:                    if (debug & SAMPLEDEBUG) {
                    592:                        printf("[asgnsamples] (0x%x->0x%x-0x%x) %s gets %f ticks %d overlap\n",
                    593:                                nl[j].value/sizeof(UNIT), svalue0, svalue1,
                    594:                                nl[j].name, 
                    595:                                overlap * time / scale, overlap);
                    596:                    }
                    597: #              endif DEBUG
                    598:                nl[j].time += overlap * time / scale;
                    599:            }
                    600:        }
                    601:     }
                    602: #   ifdef DEBUG
                    603:        if (debug & SAMPLEDEBUG) {
                    604:            printf("[asgnsamples] totime %f\n", totime);
                    605:        }
                    606: #   endif DEBUG
                    607: }
                    608: 
                    609: 
                    610: unsigned long
                    611: min(a, b)
                    612:     unsigned long a,b;
                    613: {
                    614:     if (a<b)
                    615:        return(a);
                    616:     return(b);
                    617: }
                    618: 
                    619: unsigned long
                    620: max(a, b)
                    621:     unsigned long a,b;
                    622: {
                    623:     if (a>b)
                    624:        return(a);
                    625:     return(b);
                    626: }
                    627: 
                    628:     /*
                    629:      * calculate scaled entry point addresses (to save time in asgnsamples),
                    630:      * and possibly push the scaled entry points over the entry mask,
                    631:      * if it turns out that the entry point is in one bucket and the code
                    632:      * for a routine is in the next bucket.
                    633:      */
                    634: alignentries()
                    635: {
                    636:     register struct nl *nlp;
                    637:     unsigned long      bucket_of_entry;
                    638:     unsigned long      bucket_of_code;
                    639: 
                    640:     for (nlp = nl; nlp < npe; nlp++) {
                    641:        nlp -> svalue = nlp -> value / sizeof(UNIT);
                    642:        bucket_of_entry = (nlp->svalue - lowpc) / scale;
                    643:        bucket_of_code = (nlp->svalue + UNITS_TO_CODE - lowpc) / scale;
                    644:        if (bucket_of_entry < bucket_of_code) {
                    645: #          ifdef DEBUG
                    646:                if (debug & SAMPLEDEBUG) {
                    647:                    printf("[alignentries] pushing svalue 0x%x to 0x%x\n",
                    648:                            nlp->svalue, nlp->svalue + UNITS_TO_CODE);
                    649:                }
                    650: #          endif DEBUG
                    651:            nlp->svalue += UNITS_TO_CODE;
                    652:        }
                    653:     }
                    654: }
                    655: 
                    656: bool
                    657: funcsymbol( nlistp )
                    658:     struct nlist       *nlistp;
                    659: {
                    660:     extern char        *strtab;        /* string table from a.out */
                    661:     extern int aflag;          /* if static functions aren't desired */
                    662:     char       *name;
                    663: 
                    664:        /*
                    665:         *      must be a text symbol,
                    666:         *      and static text symbols don't qualify if aflag set.
                    667:         */
                    668:     if ( ! (  ( nlistp -> n_type == ( N_TEXT | N_EXT ) )
                    669:           || ( ( nlistp -> n_type == N_TEXT ) && ( aflag == 0 ) ) ) ) {
                    670:        return FALSE;
                    671:     }
                    672:        /*
                    673:         *      can't have any `funny' characters in name,
                    674:         *      where `funny' includes  `.', .o file names
                    675:         *                      and     `$', pascal labels.
                    676:         */
                    677:     for ( name = strtab + nlistp -> n_un.n_strx ; *name ; name += 1 ) {
                    678:        if ( *name == '.' || *name == '$' ) {
                    679:            return FALSE;
                    680:        }
                    681:     }
                    682:     return TRUE;
                    683: }
                    684: 
                    685: done()
                    686: {
                    687: 
                    688:     exit(0);
                    689: }

unix.superglobalmegacorp.com

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