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

unix.superglobalmegacorp.com

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