Annotation of 43BSDReno/pgrm/gprof/hp.gprof.tar, revision 1.1.1.1

1.1       root        1: gprof/   775     22     12           0  4611253540   5106 gprof/Makefile   444     14     12        5404  4341434366   6642 #
                      2: # Copyright (c) 1987 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 this notice is preserved and that due credit is given
                      7: # to the University of California at Berkeley. The name of the University
                      8: # may not be used to endorse or promote products derived from this
                      9: # software without specific written prior permission. This software
                     10: # is provided ``as is'' without express or implied warranty.
                     11: #
                     12: #      @(#)Makefile    5.10 (Berkeley) 1/2/88
                     13: #
                     14: CFLAGS=        -O
                     15: LIBC=  /lib/libc.a
                     16: HDRS=  gprof.h ${MACHINE}.h
                     17: SRCS=  gprof.c arcs.c dfn.c lookup.c ${MACHINE}.c hertz.c \
                     18:        printgprof.c printlist.c
                     19: OBJS=  gprof.o arcs.o dfn.o lookup.o ${MACHINE}.o hertz.o \
                     20:        printgprof.o printlist.o
                     21: LIBDIR=        ../../lib
                     22: 
                     23: all: gprof
                     24: 
                     25: gprof: ${OBJS} ${LIBC}
                     26:        ${CC} -o $@ ${CFLAGS} ${OBJS}
                     27: 
                     28: gcrt0.h: FRC
                     29:        -if [ -r gcrt0.h ] && \
                     30:                cmp -s gcrt0.h ${LIBDIR}/libc/${MACHINE}/csu/gmon.h; then \
                     31:                :; \
                     32:        else \
                     33:                rm -f gcrt0.h; \
                     34:                cp ${LIBDIR}/libc/${MACHINE}/csu/gmon.h gcrt0.h; \
                     35:        fi
                     36: 
                     37: clean: FRC
                     38:        rm -f ${OBJS} core gprof
                     39: 
                     40: depend: FRC
                     41:        mkdep ${CFLAGS} ${SRCS}
                     42: 
                     43: install: FRC
                     44:        install -s -m 755 gprof ${DESTDIR}/usr/ucb/gprof
                     45:        install -c -m 644 gprof.flat ${DESTDIR}/usr/lib
                     46:        install -c -m 644 gprof.callg ${DESTDIR}/usr/lib
                     47: 
                     48: lint: FRC
                     49:        lint ${CFLAGS} ${SRCS}
                     50: 
                     51: tags: FRC
                     52:        ctags ${SRCS}
                     53: 
                     54: FRC:
                     55: 
                     56: # DO NOT DELETE THIS LINE -- mkdep uses it.
                     57: # DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY.
                     58: 
                     59: gprof.o: gprof.c gprof.h /usr/include/stdio.h /usr/include/sys/types.h
                     60: gprof.o: /usr/include/sys/stat.h /usr/include/a.out.h /usr/include/sys/exec.h
                     61: gprof.o: gcrt0.h tahoe.h
                     62: arcs.o: arcs.c gprof.h /usr/include/stdio.h /usr/include/sys/types.h
                     63: arcs.o: /usr/include/sys/stat.h /usr/include/a.out.h /usr/include/sys/exec.h
                     64: arcs.o: gcrt0.h tahoe.h
                     65: dfn.o: dfn.c /usr/include/stdio.h gprof.h /usr/include/stdio.h
                     66: dfn.o: /usr/include/sys/types.h /usr/include/sys/stat.h /usr/include/a.out.h
                     67: dfn.o: /usr/include/sys/exec.h gcrt0.h tahoe.h
                     68: lookup.o: lookup.c gprof.h /usr/include/stdio.h /usr/include/sys/types.h
                     69: lookup.o: /usr/include/sys/stat.h /usr/include/a.out.h /usr/include/sys/exec.h
                     70: lookup.o: gcrt0.h tahoe.h
                     71: tahoe.o: tahoe.c gprof.h /usr/include/stdio.h /usr/include/sys/types.h
                     72: tahoe.o: /usr/include/sys/stat.h /usr/include/a.out.h /usr/include/sys/exec.h
                     73: tahoe.o: gcrt0.h tahoe.h
                     74: hertz.o: hertz.c /usr/include/sys/time.h /usr/include/time.h
                     75: printgprof.o: printgprof.c gprof.h /usr/include/stdio.h
                     76: printgprof.o: /usr/include/sys/types.h /usr/include/sys/stat.h
                     77: printgprof.o: /usr/include/a.out.h /usr/include/sys/exec.h gcrt0.h tahoe.h
                     78: printlist.o: printlist.c gprof.h /usr/include/stdio.h /usr/include/sys/types.h
                     79: printlist.o: /usr/include/sys/stat.h /usr/include/a.out.h
                     80: printlist.o: /usr/include/sys/exec.h gcrt0.h tahoe.h
                     81: 
                     82: # IF YOU PUT ANYTHING HERE IT WILL GO AWAY
                     83: gprof/tags   664     22     12        5307  4167370176   6074 Mgprof     gprof.c /^main(argc, argv)$/
                     84: addarc arcs.c  /^addarc( parentp , childp , count )$/
                     85: addlist        printlist.c     /^addlist( listp , funcname )$/
                     86: alignentries   gprof.c /^alignentries()$/
                     87: arccmp printgprof.c    /^arccmp( thisp , thatp )$/
                     88: arclookup      lookup.c        /^arclookup( parentp , childp )$/
                     89: asgnsamples    gprof.c /^asgnsamples()$/
                     90: cyclelink      arcs.c  /^cyclelink()$/
                     91: cycletime      arcs.c  /^cycletime()$/
                     92: dfn    dfn.c   /^dfn( parentp )$/
                     93: dfn_busy       dfn.c   /^dfn_busy( childp )$/
                     94: dfn_findcycle  dfn.c   /^dfn_findcycle( childp )$/
                     95: dfn_numbered   dfn.c   /^dfn_numbered( childp )$/
                     96: dfn_post_visit dfn.c   /^dfn_post_visit( parentp )$/
                     97: dfn_pre_visit  dfn.c   /^dfn_pre_visit( parentp )$/
                     98: dfn_self_cycle dfn.c   /^dfn_self_cycle( parentp )$/
                     99: doarcs arcs.c  /^doarcs()$/
                    100: doflags        arcs.c  /^doflags()$/
                    101: done   gprof.c /^done()$/
                    102: dotime arcs.c  /^dotime()$/
                    103: dumpsum        gprof.c /^dumpsum( sumfile )$/
                    104: findcall       tahoe.c /^findcall( parentp , p_lowpc , p_highpc )$/
                    105: flatprofheader printgprof.c    /^flatprofheader()$/
                    106: flatprofline   printgprof.c    /^flatprofline( np )$/
                    107: funcsymbol     gprof.c /^funcsymbol( nlistp )$/
                    108: getnfile       gprof.c /^getnfile()$/
                    109: getpfile       gprof.c /^getpfile(filename)$/
                    110: getstrtab      gprof.c /^getstrtab(nfile)$/
                    111: getsymtab      gprof.c /^getsymtab(nfile)$/
                    112: gettextspace   gprof.c /^gettextspace( nfile )$/
                    113: gprofheader    printgprof.c    /^gprofheader()$/
                    114: gprofline      printgprof.c    /^gprofline( np )$/
                    115: hertz  hertz.c /^hertz()$/
                    116: inheritflags   arcs.c  /^inheritflags( childp )$/
                    117: max    gprof.c /^max(a, b)$/
                    118: membercmp      printgprof.c    /^membercmp( this , that )$/
                    119: min    gprof.c /^min(a, b)$/
                    120: namecmp        printgprof.c    /^namecmp( npp1 , npp2 )$/
                    121: nllookup       lookup.c        /^nllookup( address )$/
                    122: onlist printlist.c     /^onlist( listp , funcname )$/
                    123: openpfile      gprof.c /^openpfile(filename)$/
                    124: operandlength  tahoe.c /^operandlength( modep )$/
                    125: operandmode    tahoe.c /^operandmode( modep )$/
                    126: operandname    tahoe.c /^operandname( mode )$/
                    127: printblurb     printgprof.c    /^printblurb( blurbname )$/
                    128: printchildren  printgprof.c    /^printchildren( parentp )$/
                    129: printcycle     printgprof.c    /^printcycle( cyclep )$/
                    130: printgprof     printgprof.c    /^printgprof(timesortnlp)$/
                    131: printindex     printgprof.c    /^printindex()$/
                    132: printmembers   printgprof.c    /^printmembers( cyclep )$/
                    133: printname      printgprof.c    /^printname( selfp )$/
                    134: printparents   printgprof.c    /^printparents( childp )$/
                    135: printprof      printgprof.c    /^printprof()$/
                    136: readsamples    gprof.c /^readsamples(pfile)$/
                    137: reladdr        tahoe.c /^reladdr( modep )$/
                    138: sortchildren   printgprof.c    /^sortchildren( parentp )$/
                    139: sortmembers    printgprof.c    /^sortmembers( cyclep )$/
                    140: sortparents    printgprof.c    /^sortparents( childp )$/
                    141: tally  gprof.c /^tally( rawp )$/
                    142: timecmp        printgprof.c    /^timecmp( npp1 , npp2 )$/
                    143: timepropagate  arcs.c  /^timepropagate( parentp )$/
                    144: topcmp arcs.c  /^topcmp( npp1 , npp2 )$/
                    145: totalcmp       printgprof.c    /^totalcmp( npp1 , npp2 )$/
                    146: valcmp gprof.c /^valcmp(p1, p2)$/
                    147:  gcrt0.h tahoe.h
                    148: 
                    149: # IF YOU PUT ANYTHING HERE IT WILL GO AWAY
                    150: gprof/printlist.c   444     22     12        3250  4044774075   7376 /*
                    151:  * Copyright (c) 1983 Regents of the University of California.
                    152:  * All rights reserved.  The Berkeley software License Agreement
                    153:  * specifies the terms and conditions for redistribution.
                    154:  */
                    155: 
                    156: #ifndef lint
                    157: static char sccsid[] = "@(#)printlist.c        5.2 (Berkeley) 4/27/87";
                    158: #endif not lint
                    159: 
                    160: #include "gprof.h"
                    161: 
                    162:     /*
                    163:      * these are the lists of names:
                    164:      * there is the list head and then the listname
                    165:      * is a pointer to the list head
                    166:      * (for ease of passing to stringlist functions).
                    167:      */
                    168: struct stringlist      kfromhead = { 0 , 0 };
                    169: struct stringlist      *kfromlist = &kfromhead;
                    170: struct stringlist      ktohead = { 0 , 0 };
                    171: struct stringlist      *ktolist = &ktohead;
                    172: struct stringlist      fhead = { 0 , 0 };
                    173: struct stringlist      *flist = &fhead;
                    174: struct stringlist      Fhead = { 0 , 0 };
                    175: struct stringlist      *Flist = &Fhead;
                    176: struct stringlist      ehead = { 0 , 0 };
                    177: struct stringlist      *elist = &ehead;
                    178: struct stringlist      Ehead = { 0 , 0 };
                    179: struct stringlist      *Elist = &Ehead;
                    180: 
                    181: addlist( listp , funcname )
                    182:     struct stringlist  *listp;
                    183:     char               *funcname;
                    184: {
                    185:     struct stringlist  *slp;
                    186: 
                    187:     slp = (struct stringlist *) malloc( sizeof(struct stringlist));
                    188:     if ( slp == (struct stringlist *) 0 ) {
                    189:        fprintf( stderr, "gprof: ran out room for printlist\n" );
                    190:        done();
                    191:     }
                    192:     slp -> next = listp -> next;
                    193:     slp -> string = funcname;
                    194:     listp -> next = slp;
                    195: }
                    196: 
                    197: bool
                    198: onlist( listp , funcname )
                    199:     struct stringlist  *listp;
                    200:     char               *funcname;
                    201: {
                    202:     struct stringlist  *slp;
                    203: 
                    204:     for ( slp = listp -> next ; slp ; slp = slp -> next ) {
                    205:        if ( ! strcmp( slp -> string , funcname ) ) {
                    206:            return TRUE;
                    207:        }
                    208:        if ( funcname[0] == '_' && ! strcmp( slp -> string , &funcname[1] ) ) {
                    209:            return TRUE;
                    210:        }
                    211:     }
                    212:     return FALSE;
                    213: }
                    214: tahoe.c        /^operandlength( modep )$/
                    215: operandmode    tahoe.c /^operandmode( modep )$/
                    216: operandname    tahoe.c /^operandname( mode )$/
                    217: printblurb     printgprof.c    /^printblurb( blurbname )$/
                    218: printchildren  printgprof.c    /^printchildren( parentp )$/
                    219: printcycle     printgprof.c    /^printcycle( cyclep )$/
                    220: printgprof     printgprof.c    /^printgprof(timesortnlp)$/
                    221: printindex     gprof/gprof.c   444     33     12       36756  4436154435   6523 /*
                    222:  * Copyright (c) 1983 Regents of the University of California.
                    223:  * All rights reserved.  The Berkeley software License Agreement
                    224:  * specifies the terms and conditions for redistribution.
                    225:  */
                    226: 
                    227: #ifndef lint
                    228: char copyright[] =
                    229: "@(#) Copyright (c) 1983 Regents of the University of California.\n\
                    230:  All rights reserved.\n";
                    231: #endif not lint
                    232: 
                    233: #ifndef lint
                    234: static char sccsid[] = "@(#)gprof.c    5.3 (Berkeley) 1/2/88";
                    235: #endif not lint
                    236: 
                    237: #include "gprof.h"
                    238: 
                    239: char   *whoami = "gprof";
                    240: 
                    241:     /*
                    242:      * things which get -E excluded by default.
                    243:      */
                    244: char   *defaultEs[] = { "mcount" , "__mcleanup" , 0 };
                    245: 
                    246: main(argc, argv)
                    247:     int argc;
                    248:     char **argv;
                    249: {
                    250:     char       **sp;
                    251:     nltype     **timesortnlp;
                    252: 
                    253:     --argc;
                    254:     argv++;
                    255:     debug = 0;
                    256:     bflag = TRUE;
                    257:     while ( *argv != 0 && **argv == '-' ) {
                    258:        (*argv)++;
                    259:        switch ( **argv ) {
                    260:        case 'a':
                    261:            aflag = TRUE;
                    262:            break;
                    263:        case 'b':
                    264:            bflag = FALSE;
                    265:            break;
                    266:        case 'c':
                    267: #if hp300
                    268:            fprintf(stderr, "gprof -c isn't supported on hp300s yet\n");
                    269:            exit(1);
                    270: #endif
                    271:            cflag = TRUE;
                    272:            break;
                    273:        case 'd':
                    274:            dflag = TRUE;
                    275:            (*argv)++;
                    276:            debug |= atoi( *argv );
                    277:            debug |= ANYDEBUG;
                    278: #          ifdef DEBUG
                    279:                printf("[main] debug = %d\n", debug);
                    280: #          else not DEBUG
                    281:                printf("%s: -d ignored\n", whoami);
                    282: #          endif DEBUG
                    283:            break;
                    284:        case 'E':
                    285:            ++argv;
                    286:            addlist( Elist , *argv );
                    287:            Eflag = TRUE;
                    288:            addlist( elist , *argv );
                    289:            eflag = TRUE;
                    290:            break;
                    291:        case 'e':
                    292:            addlist( elist , *++argv );
                    293:            eflag = TRUE;
                    294:            break;
                    295:        case 'F':
                    296:            ++argv;
                    297:            addlist( Flist , *argv );
                    298:            Fflag = TRUE;
                    299:            addlist( flist , *argv );
                    300:            fflag = TRUE;
                    301:            break;
                    302:        case 'f':
                    303:            addlist( flist , *++argv );
                    304:            fflag = TRUE;
                    305:            break;
                    306:        case 'H':
                    307:            hz = atoi( *++argv );
                    308:            if (hz < 0 || hz > 100000) {
                    309:                fprintf(stderr, "unreasonable HZ value, using default\n");
                    310:                hz = 0;
                    311:            }
                    312:            break;
                    313:        case 'k':
                    314:            addlist( kfromlist , *++argv );
                    315:            addlist( ktolist , *++argv );
                    316:            kflag = TRUE;
                    317:            break;
                    318:        case 's':
                    319:            sflag = TRUE;
                    320:            break;
                    321:        case 'z':
                    322:            zflag = TRUE;
                    323:            break;
                    324:        }
                    325:        argv++;
                    326:     }
                    327:     if ( *argv != 0 ) {
                    328:        a_outname  = *argv;
                    329:        argv++;
                    330:     } else {
                    331:        a_outname  = A_OUTNAME;
                    332:     }
                    333:     if ( *argv != 0 ) {
                    334:        gmonname = *argv;
                    335:        argv++;
                    336:     } else {
                    337:        gmonname = GMONNAME;
                    338:     }
                    339:        /*
                    340:         *      turn off default functions
                    341:         */
                    342:     for ( sp = &defaultEs[0] ; *sp ; sp++ ) {
                    343:        Eflag = TRUE;
                    344:        addlist( Elist , *sp );
                    345:        eflag = TRUE;
                    346:        addlist( elist , *sp );
                    347:     }
                    348:        /*
                    349:         *      how many ticks per second?
                    350:         *      if we can't tell, report time in ticks.
                    351:         */
                    352:     if (hz == 0)
                    353:        hz = hertz();
                    354:     if (hz == 0) {
                    355:        hz = 1;
                    356:        fprintf(stderr, "time is in ticks, not seconds\n");
                    357:     }
                    358:        /*
                    359:         *      get information about a.out file.
                    360:         */
                    361:     getnfile();
                    362:        /*
                    363:         *      get information about mon.out file(s).
                    364:         */
                    365:     do {
                    366:        getpfile( gmonname );
                    367:        if ( *argv != 0 ) {
                    368:            gmonname = *argv;
                    369:        }
                    370:     } while ( *argv++ != 0 );
                    371:        /*
                    372:         *      dump out a gmon.sum file if requested
                    373:         */
                    374:     if ( sflag ) {
                    375:        dumpsum( GMONSUM );
                    376:     }
                    377:        /*
                    378:         *      assign samples to procedures
                    379:         */
                    380:     asgnsamples();
                    381:        /*
                    382:         *      assemble the dynamic profile
                    383:         */
                    384:     timesortnlp = doarcs();
                    385:        /*
                    386:         *      print the dynamic profile
                    387:         */
                    388:     printgprof( timesortnlp ); 
                    389:        /*
                    390:         *      print the flat profile
                    391:         */
                    392:     printprof();       
                    393:        /*
                    394:         *      print the index
                    395:         */
                    396:     printindex();      
                    397:     done();
                    398: }
                    399: 
                    400:     /*
                    401:      * Set up string and symbol tables from a.out.
                    402:      * and optionally the text space.
                    403:      * On return symbol table is sorted by value.
                    404:      */
                    405: getnfile()
                    406: {
                    407:     FILE       *nfile;
                    408:     int                valcmp();
                    409: 
                    410:     nfile = fopen( a_outname ,"r");
                    411:     if (nfile == NULL) {
                    412:        perror( a_outname );
                    413:        done();
                    414:     }
                    415:     fread(&xbuf, 1, sizeof(xbuf), nfile);
                    416:     if (N_BADMAG(xbuf)) {
                    417:        fprintf(stderr, "%s: %s: bad format\n", whoami , a_outname );
                    418:        done();
                    419:     }
                    420:     getstrtab(nfile);
                    421:     getsymtab(nfile);
                    422:     gettextspace( nfile );
                    423:     qsort(nl, nname, sizeof(nltype), valcmp);
                    424:     fclose(nfile);
                    425: #   ifdef DEBUG
                    426:        if ( debug & AOUTDEBUG ) {
                    427:            register int j;
                    428: 
                    429:            for (j = 0; j < nname; j++){
                    430:                printf("[getnfile] 0X%08x\t%s\n", nl[j].value, nl[j].name);
                    431:            }
                    432:        }
                    433: #   endif DEBUG
                    434: }
                    435: 
                    436: getstrtab(nfile)
                    437:     FILE       *nfile;
                    438: {
                    439: 
                    440:     fseek(nfile, (long)(N_SYMOFF(xbuf) + xbuf.a_syms), 0);
                    441:     if (fread(&ssiz, sizeof (ssiz), 1, nfile) == 0) {
                    442:        fprintf(stderr, "%s: %s: no string table (old format?)\n" ,
                    443:                whoami , a_outname );
                    444:        done();
                    445:     }
                    446:     strtab = (char *)calloc(ssiz, 1);
                    447:     if (strtab == NULL) {
                    448:        fprintf(stderr, "%s: %s: no room for %d bytes of string table",
                    449:                whoami , a_outname , ssiz);
                    450:        done();
                    451:     }
                    452:     if (fread(strtab+sizeof(ssiz), ssiz-sizeof(ssiz), 1, nfile) != 1) {
                    453:        fprintf(stderr, "%s: %s: error reading string table\n",
                    454:                whoami , a_outname );
                    455:        done();
                    456:     }
                    457: }
                    458: 
                    459:     /*
                    460:      * Read in symbol table
                    461:      */
                    462: getsymtab(nfile)
                    463:     FILE       *nfile;
                    464: {
                    465:     register long      i;
                    466:     int                        askfor;
                    467:     struct nlist       nbuf;
                    468: 
                    469:     /* pass1 - count symbols */
                    470:     fseek(nfile, (long)N_SYMOFF(xbuf), 0);
                    471:     nname = 0;
                    472:     for (i = xbuf.a_syms; i > 0; i -= sizeof(struct nlist)) {
                    473:        fread(&nbuf, sizeof(nbuf), 1, nfile);
                    474:        if ( ! funcsymbol( &nbuf ) ) {
                    475:            continue;
                    476:        }
                    477:        nname++;
                    478:     }
                    479:     if (nname == 0) {
                    480:        fprintf(stderr, "%s: %s: no symbols\n", whoami , a_outname );
                    481:        done();
                    482:     }
                    483:     askfor = nname + 1;
                    484:     nl = (nltype *) calloc( askfor , sizeof(nltype) );
                    485:     if (nl == 0) {
                    486:        fprintf(stderr, "%s: No room for %d bytes of symbol table\n",
                    487:                whoami, askfor * sizeof(nltype) );
                    488:        done();
                    489:     }
                    490: 
                    491:     /* pass2 - read symbols */
                    492:     fseek(nfile, (long)N_SYMOFF(xbuf), 0);
                    493:     npe = nl;
                    494:     nname = 0;
                    495:     for (i = xbuf.a_syms; i > 0; i -= sizeof(struct nlist)) {
                    496:        fread(&nbuf, sizeof(nbuf), 1, nfile);
                    497:        if ( ! funcsymbol( &nbuf ) ) {
                    498: #          ifdef DEBUG
                    499:                if ( debug & AOUTDEBUG ) {
                    500:                    printf( "[getsymtab] rejecting: 0x%x %s\n" ,
                    501:                            nbuf.n_type , strtab + nbuf.n_un.n_strx );
                    502:                }
                    503: #          endif DEBUG
                    504:            continue;
                    505:        }
                    506:        npe->value = nbuf.n_value;
                    507:        npe->name = strtab+nbuf.n_un.n_strx;
                    508: #      ifdef DEBUG
                    509:            if ( debug & AOUTDEBUG ) {
                    510:                printf( "[getsymtab] %d %s 0x%08x\n" ,
                    511:                        nname , npe -> name , npe -> value );
                    512:            }
                    513: #      endif DEBUG
                    514:        npe++;
                    515:        nname++;
                    516:     }
                    517:     npe->value = -1;
                    518: }
                    519: 
                    520:     /*
                    521:      * read in the text space of an a.out file
                    522:      */
                    523: gettextspace( nfile )
                    524:     FILE       *nfile;
                    525: {
                    526:     char       *malloc();
                    527:     
                    528:     if ( cflag == 0 ) {
                    529:        return;
                    530:     }
                    531:     textspace = (u_char *) malloc( xbuf.a_text );
                    532:     if ( textspace == 0 ) {
                    533:        fprintf( stderr , "%s: ran out room for %d bytes of text space:  " ,
                    534:                        whoami , xbuf.a_text );
                    535:        fprintf( stderr , "can't do -c\n" );
                    536:        return;
                    537:     }
                    538:     (void) fseek( nfile , N_TXTOFF( xbuf ) , 0 );
                    539:     if ( fread( textspace , 1 , xbuf.a_text , nfile ) != xbuf.a_text ) {
                    540:        fprintf( stderr , "%s: couldn't read text space:  " , whoami );
                    541:        fprintf( stderr , "can't do -c\n" );
                    542:        free( textspace );
                    543:        textspace = 0;
                    544:        return;
                    545:     }
                    546: }
                    547:     /*
                    548:      * information from a gmon.out file is in two parts:
                    549:      * an array of sampling hits within pc ranges,
                    550:      * and the arcs.
                    551:      */
                    552: getpfile(filename)
                    553:     char *filename;
                    554: {
                    555:     FILE               *pfile;
                    556:     FILE               *openpfile();
                    557:     struct rawarc      arc;
                    558: 
                    559:     pfile = openpfile(filename);
                    560:     readsamples(pfile);
                    561:        /*
                    562:         *      the rest of the file consists of
                    563:         *      a bunch of <from,self,count> tuples.
                    564:         */
                    565:     while ( fread( &arc , sizeof arc , 1 , pfile ) == 1 ) {
                    566: #      ifdef DEBUG
                    567:            if ( debug & SAMPLEDEBUG ) {
                    568:                printf( "[getpfile] frompc 0x%x selfpc 0x%x count %d\n" ,
                    569:                        arc.raw_frompc , arc.raw_selfpc , arc.raw_count );
                    570:            }
                    571: #      endif DEBUG
                    572:            /*
                    573:             *  add this arc
                    574:             */
                    575:        tally( &arc );
                    576:     }
                    577:     fclose(pfile);
                    578: }
                    579: 
                    580: FILE *
                    581: openpfile(filename)
                    582:     char *filename;
                    583: {
                    584:     struct hdr tmp;
                    585:     FILE       *pfile;
                    586: 
                    587:     if((pfile = fopen(filename, "r")) == NULL) {
                    588:        perror(filename);
                    589:        done();
                    590:     }
                    591:     fread(&tmp, sizeof(struct hdr), 1, pfile);
                    592:     if ( s_highpc != 0 && ( tmp.lowpc != h.lowpc ||
                    593:         tmp.highpc != h.highpc || tmp.ncnt != h.ncnt ) ) {
                    594:        fprintf(stderr, "%s: incompatible with first gmon file\n", filename);
                    595:        done();
                    596:     }
                    597:     h = tmp;
                    598:     s_lowpc = (unsigned long) h.lowpc;
                    599:     s_highpc = (unsigned long) h.highpc;
                    600:     lowpc = (unsigned long)h.lowpc / sizeof(UNIT);
                    601:     highpc = (unsigned long)h.highpc / sizeof(UNIT);
                    602:     sampbytes = h.ncnt - sizeof(struct hdr);
                    603:     nsamples = sampbytes / sizeof (UNIT);
                    604: #   ifdef DEBUG
                    605:        if ( debug & SAMPLEDEBUG ) {
                    606:            printf( "[openpfile] hdr.lowpc 0x%x hdr.highpc 0x%x hdr.ncnt %d\n",
                    607:                h.lowpc , h.highpc , h.ncnt );
                    608:            printf( "[openpfile]   s_lowpc 0x%x   s_highpc 0x%x\n" ,
                    609:                s_lowpc , s_highpc );
                    610:            printf( "[openpfile]     lowpc 0x%x     highpc 0x%x\n" ,
                    611:                lowpc , highpc );
                    612:            printf( "[openpfile] sampbytes %d nsamples %d\n" ,
                    613:                sampbytes , nsamples );
                    614:        }
                    615: #   endif DEBUG
                    616:     return(pfile);
                    617: }
                    618: 
                    619: tally( rawp )
                    620:     struct rawarc      *rawp;
                    621: {
                    622:     nltype             *parentp;
                    623:     nltype             *childp;
                    624: 
                    625:     parentp = nllookup( rawp -> raw_frompc );
                    626:     childp = nllookup( rawp -> raw_selfpc );
                    627:     if ( kflag
                    628:         && onlist( kfromlist , parentp -> name )
                    629:         && onlist( ktolist , childp -> name ) ) {
                    630:        return;
                    631:     }
                    632:     childp -> ncall += rawp -> raw_count;
                    633: #   ifdef DEBUG
                    634:        if ( debug & TALLYDEBUG ) {
                    635:            printf( "[tally] arc from %s to %s traversed %d times\n" ,
                    636:                    parentp -> name , childp -> name , rawp -> raw_count );
                    637:        }
                    638: #   endif DEBUG
                    639:     addarc( parentp , childp , rawp -> raw_count );
                    640: }
                    641: 
                    642: /*
                    643:  * dump out the gmon.sum file
                    644:  */
                    645: dumpsum( sumfile )
                    646:     char *sumfile;
                    647: {
                    648:     register nltype *nlp;
                    649:     register arctype *arcp;
                    650:     struct rawarc arc;
                    651:     FILE *sfile;
                    652: 
                    653:     if ( ( sfile = fopen ( sumfile , "w" ) ) == NULL ) {
                    654:        perror( sumfile );
                    655:        done();
                    656:     }
                    657:     /*
                    658:      * dump the header; use the last header read in
                    659:      */
                    660:     if ( fwrite( &h , sizeof h , 1 , sfile ) != 1 ) {
                    661:        perror( sumfile );
                    662:        done();
                    663:     }
                    664:     /*
                    665:      * dump the samples
                    666:      */
                    667:     if (fwrite(samples, sizeof (UNIT), nsamples, sfile) != nsamples) {
                    668:        perror( sumfile );
                    669:        done();
                    670:     }
                    671:     /*
                    672:      * dump the normalized raw arc information
                    673:      */
                    674:     for ( nlp = nl ; nlp < npe ; nlp++ ) {
                    675:        for ( arcp = nlp -> children ; arcp ; arcp = arcp -> arc_childlist ) {
                    676:            arc.raw_frompc = arcp -> arc_parentp -> value;
                    677:            arc.raw_selfpc = arcp -> arc_childp -> value;
                    678:            arc.raw_count = arcp -> arc_count;
                    679:            if ( fwrite ( &arc , sizeof arc , 1 , sfile ) != 1 ) {
                    680:                perror( sumfile );
                    681:                done();
                    682:            }
                    683: #          ifdef DEBUG
                    684:                if ( debug & SAMPLEDEBUG ) {
                    685:                    printf( "[dumpsum] frompc 0x%x selfpc 0x%x count %d\n" ,
                    686:                            arc.raw_frompc , arc.raw_selfpc , arc.raw_count );
                    687:                }
                    688: #          endif DEBUG
                    689:        }
                    690:     }
                    691:     fclose( sfile );
                    692: }
                    693: 
                    694: valcmp(p1, p2)
                    695:     nltype *p1, *p2;
                    696: {
                    697:     if ( p1 -> value < p2 -> value ) {
                    698:        return LESSTHAN;
                    699:     }
                    700:     if ( p1 -> value > p2 -> value ) {
                    701:        return GREATERTHAN;
                    702:     }
                    703:     return EQUALTO;
                    704: }
                    705: 
                    706: readsamples(pfile)
                    707:     FILE       *pfile;
                    708: {
                    709:     register i;
                    710:     UNIT       sample;
                    711:     
                    712:     if (samples == 0) {
                    713:        samples = (UNIT *) calloc(sampbytes, sizeof (UNIT));
                    714:        if (samples == 0) {
                    715:            fprintf( stderr , "%s: No room for %d sample pc's\n", 
                    716:                whoami , sampbytes / sizeof (UNIT));
                    717:            done();
                    718:        }
                    719:     }
                    720:     for (i = 0; i < nsamples; i++) {
                    721:        fread(&sample, sizeof (UNIT), 1, pfile);
                    722:        if (feof(pfile))
                    723:                break;
                    724:        samples[i] += sample;
                    725:     }
                    726:     if (i != nsamples) {
                    727:        fprintf(stderr,
                    728:            "%s: unexpected EOF after reading %d/%d samples\n",
                    729:                whoami , --i , nsamples );
                    730:        done();
                    731:     }
                    732: }
                    733: 
                    734: /*
                    735:  *     Assign samples to the procedures to which they belong.
                    736:  *
                    737:  *     There are three cases as to where pcl and pch can be
                    738:  *     with respect to the routine entry addresses svalue0 and svalue1
                    739:  *     as shown in the following diagram.  overlap computes the
                    740:  *     distance between the arrows, the fraction of the sample
                    741:  *     that is to be credited to the routine which starts at svalue0.
                    742:  *
                    743:  *         svalue0                                         svalue1
                    744:  *            |                                               |
                    745:  *            v                                               v
                    746:  *
                    747:  *            +-----------------------------------------------+
                    748:  *            |                                               |
                    749:  *       |  ->|    |<-         ->|         |<-         ->|    |<-  |
                    750:  *       |         |             |         |             |         |
                    751:  *       +---------+             +---------+             +---------+
                    752:  *
                    753:  *       ^         ^             ^         ^             ^         ^
                    754:  *       |         |             |         |             |         |
                    755:  *      pcl       pch           pcl       pch           pcl       pch
                    756:  *
                    757:  *     For the vax we assert that samples will never fall in the first
                    758:  *     two bytes of any routine, since that is the entry mask,
                    759:  *     thus we give call alignentries() to adjust the entry points if
                    760:  *     the entry mask falls in one bucket but the code for the routine
                    761:  *     doesn't start until the next bucket.  In conjunction with the
                    762:  *     alignment of routine addresses, this should allow us to have
                    763:  *     only one sample for every four bytes of text space and never
                    764:  *     have any overlap (the two end cases, above).
                    765:  */
                    766: asgnsamples()
                    767: {
                    768:     register int       j;
                    769:     UNIT               ccnt;
                    770:     double             time;
                    771:     unsigned long      pcl, pch;
                    772:     register int       i;
                    773:     unsigned long      overlap;
                    774:     unsigned long      svalue0, svalue1;
                    775: 
                    776:     /* read samples and assign to namelist symbols */
                    777:     scale = highpc - lowpc;
                    778:     scale /= nsamples;
                    779:     alignentries();
                    780:     for (i = 0, j = 1; i < nsamples; i++) {
                    781:        ccnt = samples[i];
                    782:        if (ccnt == 0)
                    783:                continue;
                    784:        pcl = lowpc + scale * i;
                    785:        pch = lowpc + scale * (i + 1);
                    786:        time = ccnt;
                    787: #      ifdef DEBUG
                    788:            if ( debug & SAMPLEDEBUG ) {
                    789:                printf( "[asgnsamples] pcl 0x%x pch 0x%x ccnt %d\n" ,
                    790:                        pcl , pch , ccnt );
                    791:            }
                    792: #      endif DEBUG
                    793:        totime += time;
                    794:        for (j = j - 1; j < nname; j++) {
                    795:            svalue0 = nl[j].svalue;
                    796:            svalue1 = nl[j+1].svalue;
                    797:                /*
                    798:                 *      if high end of tick is below entry address, 
                    799:                 *      go for next tick.
                    800:                 */
                    801:            if (pch < svalue0)
                    802:                    break;
                    803:                /*
                    804:                 *      if low end of tick into next routine,
                    805:                 *      go for next routine.
                    806:                 */
                    807:            if (pcl >= svalue1)
                    808:                    continue;
                    809:            overlap = min(pch, svalue1) - max(pcl, svalue0);
                    810:            if (overlap > 0) {
                    811: #              ifdef DEBUG
                    812:                    if (debug & SAMPLEDEBUG) {
                    813:                        printf("[asgnsamples] (0x%x->0x%x-0x%x) %s gets %f ticks %d overlap\n",
                    814:                                nl[j].value/sizeof(UNIT), svalue0, svalue1,
                    815:                                nl[j].name, 
                    816:                                overlap * time / scale, overlap);
                    817:                    }
                    818: #              endif DEBUG
                    819:                nl[j].time += overlap * time / scale;
                    820:            }
                    821:        }
                    822:     }
                    823: #   ifdef DEBUG
                    824:        if (debug & SAMPLEDEBUG) {
                    825:            printf("[asgnsamples] totime %f\n", totime);
                    826:        }
                    827: #   endif DEBUG
                    828: }
                    829: 
                    830: 
                    831: unsigned long
                    832: min(a, b)
                    833:     unsigned long a,b;
                    834: {
                    835:     if (a<b)
                    836:        return(a);
                    837:     return(b);
                    838: }
                    839: 
                    840: unsigned long
                    841: max(a, b)
                    842:     unsigned long a,b;
                    843: {
                    844:     if (a>b)
                    845:        return(a);
                    846:     return(b);
                    847: }
                    848: 
                    849:     /*
                    850:      * calculate scaled entry point addresses (to save time in asgnsamples),
                    851:      * and possibly push the scaled entry points over the entry mask,
                    852:      * if it turns out that the entry point is in one bucket and the code
                    853:      * for a routine is in the next bucket.
                    854:      */
                    855: alignentries()
                    856: {
                    857:     register struct nl *nlp;
                    858:     unsigned long      bucket_of_entry;
                    859:     unsigned long      bucket_of_code;
                    860: 
                    861:     for (nlp = nl; nlp < npe; nlp++) {
                    862:        nlp -> svalue = nlp -> value / sizeof(UNIT);
                    863:        bucket_of_entry = (nlp->svalue - lowpc) / scale;
                    864:        bucket_of_code = (nlp->svalue + UNITS_TO_CODE - lowpc) / scale;
                    865:        if (bucket_of_entry < bucket_of_code) {
                    866: #          ifdef DEBUG
                    867:                if (debug & SAMPLEDEBUG) {
                    868:                    printf("[alignentries] pushing svalue 0x%x to 0x%x\n",
                    869:                            nlp->svalue, nlp->svalue + UNITS_TO_CODE);
                    870:                }
                    871: #          endif DEBUG
                    872:            nlp->svalue += UNITS_TO_CODE;
                    873:        }
                    874:     }
                    875: }
                    876: 
                    877: bool
                    878: funcsymbol( nlistp )
                    879:     struct nlist       *nlistp;
                    880: {
                    881:     extern char        *strtab;        /* string table from a.out */
                    882:     extern int aflag;          /* if static functions aren't desired */
                    883:     char       *name;
                    884: 
                    885:        /*
                    886:         *      must be a text symbol,
                    887:         *      and static text symbols don't qualify if aflag set.
                    888:         */
                    889:     if ( ! (  ( nlistp -> n_type == ( N_TEXT | N_EXT ) )
                    890:           || ( ( nlistp -> n_type == N_TEXT ) && ( aflag == 0 ) ) ) ) {
                    891:        return FALSE;
                    892:     }
                    893:        /*
                    894:         *      can't have any `funny' characters in name,
                    895:         *      where `funny' includes  `.', .o file names
                    896:         *                      and     `$', pascal labels.
                    897:         */
                    898:     for ( name = strtab + nlistp -> n_un.n_strx ; *name ; name += 1 ) {
                    899:        if ( *name == '.' || *name == '$' ) {
                    900:            return FALSE;
                    901:        }
                    902:     }
                    903:     return TRUE;
                    904: }
                    905: 
                    906: done()
                    907: {
                    908: 
                    909:     exit(0);
                    910: }
                    911: -------+
                    912:  *           gprof/gprof.h   444     22     12       15325  4230312011   6465 /*
                    913:  * Copyright (c) 1983 Regents of the University of California.
                    914:  * All rights reserved.  The Berkeley software License Agreement
                    915:  * specifies the terms and conditions for redistribution.
                    916:  *
                    917:  *     @(#)gprof.h     5.4 (Berkeley) 1/2/88
                    918:  */
                    919: 
                    920: #include <stdio.h>
                    921: #include <sys/types.h>
                    922: #include <sys/stat.h>
                    923: #include <a.out.h>
                    924: #include "gcrt0.h"
                    925: 
                    926: #if vax
                    927: #   include "vax.h"
                    928: #endif
                    929: #if sun
                    930: #   include "sun.h"
                    931: #endif
                    932: #if tahoe
                    933: #   include "tahoe.h"
                    934: #endif
                    935: #if hp300
                    936: #   include "hp300.h"
                    937: #endif
                    938: 
                    939: 
                    940:     /*
                    941:      * who am i, for error messages.
                    942:      */
                    943: char   *whoami;
                    944: 
                    945:     /*
                    946:      * booleans
                    947:      */
                    948: typedef int    bool;
                    949: #define        FALSE   0
                    950: #define        TRUE    1
                    951: 
                    952:     /*
                    953:      * ticks per second
                    954:      */
                    955: long   hz;
                    956: 
                    957: typedef        u_short UNIT;           /* unit of profiling */
                    958: char   *a_outname;
                    959: #define        A_OUTNAME               "a.out"
                    960: 
                    961: char   *gmonname;
                    962: #define        GMONNAME                "gmon.out"
                    963: #define        GMONSUM                 "gmon.sum"
                    964: 
                    965:     /*
                    966:      * blurbs on the flat and graph profiles.
                    967:      */
                    968: #define        FLAT_BLURB      "/usr/lib/gprof.flat"
                    969: #define        CALLG_BLURB     "/usr/lib/gprof.callg"
                    970: 
                    971:     /*
                    972:      * a constructed arc,
                    973:      *     with pointers to the namelist entry of the parent and the child,
                    974:      *     a count of how many times this arc was traversed,
                    975:      *     and pointers to the next parent of this child and
                    976:      *         the next child of this parent.
                    977:      */
                    978: struct arcstruct {
                    979:     struct nl          *arc_parentp;   /* pointer to parent's nl entry */
                    980:     struct nl          *arc_childp;    /* pointer to child's nl entry */
                    981:     long               arc_count;      /* how calls from parent to child */
                    982:     double             arc_time;       /* time inherited along arc */
                    983:     double             arc_childtime;  /* childtime inherited along arc */
                    984:     struct arcstruct   *arc_parentlist; /* parents-of-this-child list */
                    985:     struct arcstruct   *arc_childlist; /* children-of-this-parent list */
                    986: };
                    987: typedef struct arcstruct       arctype;
                    988: 
                    989:     /*
                    990:      * The symbol table;
                    991:      * for each external in the specified file we gather
                    992:      * its address, the number of calls and compute its share of cpu time.
                    993:      */
                    994: struct nl {
                    995:     char               *name;          /* the name */
                    996:     unsigned long      value;          /* the pc entry point */
                    997:     unsigned long      svalue;         /* entry point aligned to histograms */
                    998:     double             time;           /* ticks in this routine */
                    999:     double             childtime;      /* cumulative ticks in children */
                   1000:     long               ncall;          /* how many times called */
                   1001:     long               selfcalls;      /* how many calls to self */
                   1002:     double             propfraction;   /* what % of time propagates */
                   1003:     double             propself;       /* how much self time propagates */
                   1004:     double             propchild;      /* how much child time propagates */
                   1005:     bool               printflag;      /* should this be printed? */
                   1006:     int                        index;          /* index in the graph list */
                   1007:     int                        toporder;       /* graph call chain top-sort order */
                   1008:     int                        cycleno;        /* internal number of cycle on */
                   1009:     struct nl          *cyclehead;     /* pointer to head of cycle */
                   1010:     struct nl          *cnext;         /* pointer to next member of cycle */
                   1011:     arctype            *parents;       /* list of caller arcs */
                   1012:     arctype            *children;      /* list of callee arcs */
                   1013: };
                   1014: typedef struct nl      nltype;
                   1015: 
                   1016: nltype *nl;                    /* the whole namelist */
                   1017: nltype *npe;                   /* the virtual end of the namelist */
                   1018: int    nname;                  /* the number of function names */
                   1019: 
                   1020:     /*
                   1021:      * flag which marks a nl entry as topologically ``busy''
                   1022:      * flag which marks a nl entry as topologically ``not_numbered''
                   1023:      */
                   1024: #define        DFN_BUSY        -1
                   1025: #define        DFN_NAN         0
                   1026: 
                   1027:     /* 
                   1028:      * namelist entries for cycle headers.
                   1029:      * the number of discovered cycles.
                   1030:      */
                   1031: nltype *cyclenl;               /* cycle header namelist */
                   1032: int    ncycle;                 /* number of cycles discovered */
                   1033: 
                   1034:     /*
                   1035:      * The header on the gmon.out file.
                   1036:      * gmon.out consists of one of these headers,
                   1037:      * and then an array of ncnt samples
                   1038:      * representing the discretized program counter values.
                   1039:      * this should be a struct phdr, but since everything is done
                   1040:      * as UNITs, this is in UNITs too.
                   1041:      */
                   1042: struct hdr {
                   1043:     UNIT       *lowpc;
                   1044:     UNIT       *highpc;
                   1045:     int        ncnt;
                   1046: };
                   1047: 
                   1048: struct hdr     h;
                   1049: 
                   1050: int    debug;
                   1051: 
                   1052:     /*
                   1053:      * Each discretized pc sample has
                   1054:      * a count of the number of samples in its range
                   1055:      */
                   1056: UNIT   *samples;
                   1057: 
                   1058: unsigned long  s_lowpc;        /* lowpc from the profile file */
                   1059: unsigned long  s_highpc;       /* highpc from the profile file */
                   1060: unsigned lowpc, highpc;                /* range profiled, in UNIT's */
                   1061: unsigned sampbytes;            /* number of bytes of samples */
                   1062: int    nsamples;               /* number of samples */
                   1063: double actime;                 /* accumulated time thus far for putprofline */
                   1064: double totime;                 /* total time for all routines */
                   1065: double printtime;              /* total of time being printed */
                   1066: double scale;                  /* scale factor converting samples to pc
                   1067:                                   values: each sample covers scale bytes */
                   1068: char   *strtab;                /* string table in core */
                   1069: off_t  ssiz;                   /* size of the string table */
                   1070: struct exec xbuf;              /* exec header of a.out */
                   1071: unsigned char  *textspace;             /* text space of a.out in core */
                   1072: 
                   1073:     /*
                   1074:      * option flags, from a to z.
                   1075:      */
                   1076: bool   aflag;                          /* suppress static functions */
                   1077: bool   bflag;                          /* blurbs, too */
                   1078: bool   cflag;                          /* discovered call graph, too */
                   1079: bool   dflag;                          /* debugging options */
                   1080: bool   eflag;                          /* specific functions excluded */
                   1081: bool   Eflag;                          /* functions excluded with time */
                   1082: bool   fflag;                          /* specific functions requested */
                   1083: bool   Fflag;                          /* functions requested with time */
                   1084: bool   kflag;                          /* arcs to be deleted */
                   1085: bool   sflag;                          /* sum multiple gmon.out files */
                   1086: bool   zflag;                          /* zero time/called functions, too */
                   1087: 
                   1088:     /*
                   1089:      * structure for various string lists
                   1090:      */
                   1091: struct stringlist {
                   1092:     struct stringlist  *next;
                   1093:     char               *string;
                   1094: };
                   1095: struct stringlist      *elist;
                   1096: struct stringlist      *Elist;
                   1097: struct stringlist      *flist;
                   1098: struct stringlist      *Flist;
                   1099: struct stringlist      *kfromlist;
                   1100: struct stringlist      *ktolist;
                   1101: 
                   1102:     /*
                   1103:      * function declarations
                   1104:      */
                   1105: /*
                   1106:                addarc();
                   1107: */
                   1108: int            arccmp();
                   1109: arctype                *arclookup();
                   1110: /*
                   1111:                asgnsamples();
                   1112:                printblurb();
                   1113:                cyclelink();
                   1114:                dfn();
                   1115: */
                   1116: bool           dfn_busy();
                   1117: /*
                   1118:                dfn_findcycle();
                   1119: */
                   1120: bool           dfn_numbered();
                   1121: /*
                   1122:                dfn_post_visit();
                   1123:                dfn_pre_visit();
                   1124:                dfn_self_cycle();
                   1125: */
                   1126: nltype         **doarcs();
                   1127: /*
                   1128:                done();
                   1129:                findcalls();
                   1130:                flatprofheader();
                   1131:                flatprofline();
                   1132: */
                   1133: bool           funcsymbol();
                   1134: /*
                   1135:                getnfile();
                   1136:                getpfile();
                   1137:                getstrtab();
                   1138:                getsymtab();
                   1139:                gettextspace();
                   1140:                gprofheader();
                   1141:                gprofline();
                   1142:                main();
                   1143: */
                   1144: unsigned long  max();
                   1145: int            membercmp();
                   1146: unsigned long  min();
                   1147: nltype         *nllookup();
                   1148: FILE           *openpfile();
                   1149: long           operandlength();
                   1150: operandenum    operandmode();
                   1151: char           *operandname();
                   1152: /*
                   1153:                printchildren();
                   1154:                printcycle();
                   1155:                printgprof();
                   1156:                printmembers();
                   1157:                printname();
                   1158:                printparents();
                   1159:                printprof();
                   1160:                readsamples();
                   1161: */
                   1162: unsigned long  reladdr();
                   1163: /*
                   1164:                sortchildren();
                   1165:                sortmembers();
                   1166:                sortparents();
                   1167:                tally();
                   1168:                timecmp();
                   1169:                topcmp();
                   1170: */
                   1171: int            totalcmp();
                   1172: /*
                   1173:                valcmp();
                   1174: */
                   1175: 
                   1176: #define        LESSTHAN        -1
                   1177: #define        EQUALTO         0
                   1178: #define        GREATERTHAN     1
                   1179: 
                   1180: #define        DFNDEBUG        1
                   1181: #define        CYCLEDEBUG      2
                   1182: #define        ARCDEBUG        4
                   1183: #define        TALLYDEBUG      8
                   1184: #define        TIMEDEBUG       16
                   1185: #define        SAMPLEDEBUG     32
                   1186: #define        AOUTDEBUG       64
                   1187: #define        CALLDEBUG       128
                   1188: #define        LOOKUPDEBUG     256
                   1189: #define        PROPDEBUG       512
                   1190: #define        ANYDEBUG        1024
                   1191: ext;           /* pointer to next member of cycle */
                   1192:     arctype            *parents;       /* list of caller arcs */
                   1193:     arctype            *children;      /* list of callee arcs */
                   1194: };
                   1195: typedef struct nl      nltype;
                   1196: 
                   1197: nltype *nl;                    /* the whole namelist */
                   1198: nltype *npe;                   /* the virtual end of the namelist */
                   1199: int    nname;                  /* the number of funcgprof/dfn.c   444     22     12       14644  3500670430   6130 /*
                   1200:  * Copyright (c) 1983 Regents of the University of California.
                   1201:  * All rights reserved.  The Berkeley software License Agreement
                   1202:  * specifies the terms and conditions for redistribution.
                   1203:  */
                   1204: 
                   1205: #ifndef lint
                   1206: static char sccsid[] = "@(#)dfn.c      5.1 (Berkeley) 6/4/85";
                   1207: #endif not lint
                   1208: 
                   1209: #include <stdio.h>
                   1210: #include "gprof.h"
                   1211: 
                   1212: #define        DFN_DEPTH       100
                   1213: struct dfnstruct {
                   1214:     nltype     *nlentryp;
                   1215:     int                cycletop;
                   1216: };
                   1217: typedef struct dfnstruct       dfntype;
                   1218: 
                   1219: dfntype        dfn_stack[ DFN_DEPTH ];
                   1220: int    dfn_depth = 0;
                   1221: 
                   1222: int    dfn_counter = DFN_NAN;
                   1223: 
                   1224:     /*
                   1225:      * given this parent, depth first number its children.
                   1226:      */
                   1227: dfn( parentp )
                   1228:     nltype     *parentp;
                   1229: {
                   1230:     arctype    *arcp;
                   1231: 
                   1232: #   ifdef DEBUG
                   1233:        if ( debug & DFNDEBUG ) {
                   1234:            printf( "[dfn] dfn(" );
                   1235:            printname( parentp );
                   1236:            printf( ")\n" );
                   1237:        }
                   1238: #   endif DEBUG
                   1239:        /*
                   1240:         *      if we're already numbered, no need to look any furthur.
                   1241:         */
                   1242:     if ( dfn_numbered( parentp ) ) {
                   1243:        return;
                   1244:     }
                   1245:        /*
                   1246:         *      if we're already busy, must be a cycle
                   1247:         */
                   1248:     if ( dfn_busy( parentp ) ) {
                   1249:        dfn_findcycle( parentp );
                   1250:        return;
                   1251:     }
                   1252:        /*
                   1253:         *      visit yourself before your children
                   1254:         */
                   1255:     dfn_pre_visit( parentp );
                   1256:        /*
                   1257:         *      visit children
                   1258:         */
                   1259:     for ( arcp = parentp -> children ; arcp ; arcp = arcp -> arc_childlist ) {
                   1260:            dfn( arcp -> arc_childp );
                   1261:     }
                   1262:        /*
                   1263:         *      visit yourself after your children
                   1264:         */
                   1265:     dfn_post_visit( parentp );
                   1266: }
                   1267: 
                   1268:     /*
                   1269:      * push a parent onto the stack and mark it busy
                   1270:      */
                   1271: dfn_pre_visit( parentp )
                   1272:     nltype     *parentp;
                   1273: {
                   1274: 
                   1275:     dfn_depth += 1;
                   1276:     if ( dfn_depth >= DFN_DEPTH ) {
                   1277:        fprintf( stderr , "[dfn] out of my depth (dfn_stack overflow)\n" );
                   1278:        exit( 1 );
                   1279:     }
                   1280:     dfn_stack[ dfn_depth ].nlentryp = parentp;
                   1281:     dfn_stack[ dfn_depth ].cycletop = dfn_depth;
                   1282:     parentp -> toporder = DFN_BUSY;
                   1283: #   ifdef DEBUG
                   1284:        if ( debug & DFNDEBUG ) {
                   1285:            printf( "[dfn_pre_visit]\t\t%d:" , dfn_depth );
                   1286:            printname( parentp );
                   1287:            printf( "\n" );
                   1288:        }
                   1289: #   endif DEBUG
                   1290: }
                   1291: 
                   1292:     /*
                   1293:      * are we already numbered?
                   1294:      */
                   1295: bool
                   1296: dfn_numbered( childp )
                   1297:     nltype     *childp;
                   1298: {
                   1299:     
                   1300:     return ( childp -> toporder != DFN_NAN && childp -> toporder != DFN_BUSY );
                   1301: }
                   1302: 
                   1303:     /*
                   1304:      * are we already busy?
                   1305:      */
                   1306: bool
                   1307: dfn_busy( childp )
                   1308:     nltype     *childp;
                   1309: {
                   1310: 
                   1311:     if ( childp -> toporder == DFN_NAN ) {
                   1312:        return FALSE;
                   1313:     }
                   1314:     return TRUE;
                   1315: }
                   1316: 
                   1317:     /*
                   1318:      * MISSING: an explanation
                   1319:      */
                   1320: dfn_findcycle( childp )
                   1321:     nltype     *childp;
                   1322: {
                   1323:     int                cycletop;
                   1324:     nltype     *cycleheadp;
                   1325:     nltype     *tailp;
                   1326:     int                index;
                   1327: 
                   1328:     for ( cycletop = dfn_depth ; cycletop > 0 ; cycletop -= 1 ) {
                   1329:        cycleheadp = dfn_stack[ cycletop ].nlentryp;
                   1330:        if ( childp == cycleheadp ) {
                   1331:            break;
                   1332:        }
                   1333:        if ( childp -> cyclehead != childp &&
                   1334:            childp -> cyclehead == cycleheadp ) {
                   1335:            break;
                   1336:        }
                   1337:     }
                   1338:     if ( cycletop <= 0 ) {
                   1339:        fprintf( stderr , "[dfn_findcycle] couldn't find head of cycle\n" );
                   1340:        exit( 1 );
                   1341:     }
                   1342: #   ifdef DEBUG
                   1343:        if ( debug & DFNDEBUG ) {
                   1344:            printf( "[dfn_findcycle] dfn_depth %d cycletop %d " ,
                   1345:                    dfn_depth , cycletop  );
                   1346:            printname( cycleheadp );
                   1347:            printf( "\n" );
                   1348:        }
                   1349: #   endif DEBUG
                   1350:     if ( cycletop == dfn_depth ) {
                   1351:            /*
                   1352:             *  this is previous function, e.g. this calls itself
                   1353:             *  sort of boring
                   1354:             */
                   1355:        dfn_self_cycle( childp );
                   1356:     } else {
                   1357:            /*
                   1358:             *  glom intervening functions that aren't already
                   1359:             *  glommed into this cycle.
                   1360:             *  things have been glommed when their cyclehead field
                   1361:             *  points to the head of the cycle they are glommed into.
                   1362:             */
                   1363:        for ( tailp = cycleheadp ; tailp -> cnext ; tailp = tailp -> cnext ) {
                   1364:            /* void: chase down to tail of things already glommed */
                   1365: #          ifdef DEBUG
                   1366:                if ( debug & DFNDEBUG ) {
                   1367:                    printf( "[dfn_findcycle] tail " );
                   1368:                    printname( tailp );
                   1369:                    printf( "\n" );
                   1370:                }
                   1371: #          endif DEBUG
                   1372:        }
                   1373:            /*
                   1374:             *  if what we think is the top of the cycle
                   1375:             *  has a cyclehead field, then it's not really the
                   1376:             *  head of the cycle, which is really what we want
                   1377:             */ 
                   1378:        if ( cycleheadp -> cyclehead != cycleheadp ) {
                   1379:            cycleheadp = cycleheadp -> cyclehead;
                   1380: #          ifdef DEBUG
                   1381:                if ( debug & DFNDEBUG ) {
                   1382:                    printf( "[dfn_findcycle] new cyclehead " );
                   1383:                    printname( cycleheadp );
                   1384:                    printf( "\n" );
                   1385:                }
                   1386: #          endif DEBUG
                   1387:        }
                   1388:        for ( index = cycletop + 1 ; index <= dfn_depth ; index += 1 ) {
                   1389:            childp = dfn_stack[ index ].nlentryp;
                   1390:            if ( childp -> cyclehead == childp ) {
                   1391:                    /*
                   1392:                     *  not yet glommed anywhere, glom it
                   1393:                     *  and fix any children it has glommed
                   1394:                     */
                   1395:                tailp -> cnext = childp;
                   1396:                childp -> cyclehead = cycleheadp;
                   1397: #              ifdef DEBUG
                   1398:                    if ( debug & DFNDEBUG ) {
                   1399:                        printf( "[dfn_findcycle] glomming " );
                   1400:                        printname( childp );
                   1401:                        printf( " onto " );
                   1402:                        printname( cycleheadp );
                   1403:                        printf( "\n" );
                   1404:                    }
                   1405: #              endif DEBUG
                   1406:                for ( tailp = childp ; tailp->cnext ; tailp = tailp->cnext ) {
                   1407:                    tailp -> cnext -> cyclehead = cycleheadp;
                   1408: #                  ifdef DEBUG
                   1409:                        if ( debug & DFNDEBUG ) {
                   1410:                            printf( "[dfn_findcycle] and its tail " );
                   1411:                            printname( tailp -> cnext );
                   1412:                            printf( " onto " );
                   1413:                            printname( cycleheadp );
                   1414:                            printf( "\n" );
                   1415:                        }
                   1416: #                  endif DEBUG
                   1417:                }
                   1418:            } else if ( childp -> cyclehead != cycleheadp /* firewall */ ) {
                   1419:                fprintf( stderr ,
                   1420:                        "[dfn_busy] glommed, but not to cyclehead\n" );
                   1421:            }
                   1422:        }
                   1423:     }
                   1424: }
                   1425: 
                   1426:     /*
                   1427:      * deal with self-cycles
                   1428:      * for lint: ARGSUSED
                   1429:      */
                   1430: dfn_self_cycle( parentp )
                   1431:     nltype     *parentp;
                   1432: {
                   1433:        /*
                   1434:         *      since we are taking out self-cycles elsewhere
                   1435:         *      no need for the special case, here.
                   1436:         */
                   1437: #   ifdef DEBUG
                   1438:        if ( debug & DFNDEBUG ) {
                   1439:            printf( "[dfn_self_cycle] " );
                   1440:            printname( parentp );
                   1441:            printf( "\n" );
                   1442:        }
                   1443: #   endif DEBUG
                   1444: }
                   1445: 
                   1446:     /*
                   1447:      * visit a node after all its children
                   1448:      * [MISSING: an explanation]
                   1449:      * and pop it off the stack
                   1450:      */
                   1451: dfn_post_visit( parentp )
                   1452:     nltype     *parentp;
                   1453: {
                   1454:     nltype     *memberp;
                   1455: 
                   1456: #   ifdef DEBUG
                   1457:        if ( debug & DFNDEBUG ) {
                   1458:            printf( "[dfn_post_visit]\t%d: " , dfn_depth );
                   1459:            printname( parentp );
                   1460:            printf( "\n" );
                   1461:        }
                   1462: #   endif DEBUG
                   1463:        /*
                   1464:         *      number functions and things in their cycles
                   1465:         *      unless the function is itself part of a cycle
                   1466:         */
                   1467:     if ( parentp -> cyclehead == parentp ) {
                   1468:        dfn_counter += 1;
                   1469:        for ( memberp = parentp ; memberp ; memberp = memberp -> cnext ) {
                   1470:            memberp -> toporder = dfn_counter;
                   1471: #          ifdef DEBUG
                   1472:                if ( debug & DFNDEBUG ) {
                   1473:                    printf( "[dfn_post_visit]\t\tmember " );
                   1474:                    printname( memberp );
                   1475:                    printf( " -> toporder = %d\n" , dfn_counter );
                   1476:                }
                   1477: #          endif DEBUG
                   1478:        }
                   1479:     } else {
                   1480: #      ifdef DEBUG
                   1481:            if ( debug & DFNDEBUG ) {
                   1482:                printf( "[dfn_post_visit]\t\tis part of a cycle\n" );
                   1483:            }
                   1484: #      endif DEBUG
                   1485:     }
                   1486:     dfn_depth -= 1;
                   1487: }
                   1488: cycletop > 0 ; cycletop -= 1 ) {
                   1489:        cycleheadp = dfn_stack[ cycletop ].nlentryp;
                   1490:        if ( childp gprof/arcs.c   444     22     12       35645  4044770454   6330 /*
                   1491:  * Copyright (c) 1983 Regents of the University of California.
                   1492:  * All rights reserved.  The Berkeley software License Agreement
                   1493:  * specifies the terms and conditions for redistribution.
                   1494:  */
                   1495: 
                   1496: #ifndef lint
                   1497: static char sccsid[] = "@(#)arcs.c     5.3 (Berkeley) 1/7/86";
                   1498: #endif not lint
                   1499: 
                   1500: #include "gprof.h"
                   1501: 
                   1502:     /*
                   1503:      * add (or just increment) an arc
                   1504:      */
                   1505: addarc( parentp , childp , count )
                   1506:     nltype     *parentp;
                   1507:     nltype     *childp;
                   1508:     long       count;
                   1509: {
                   1510:     arctype            *calloc();
                   1511:     arctype            *arcp;
                   1512: 
                   1513: #   ifdef DEBUG
                   1514:        if ( debug & TALLYDEBUG ) {
                   1515:            printf( "[addarc] %d arcs from %s to %s\n" ,
                   1516:                    count , parentp -> name , childp -> name );
                   1517:        }
                   1518: #   endif DEBUG
                   1519:     arcp = arclookup( parentp , childp );
                   1520:     if ( arcp != 0 ) {
                   1521:            /*
                   1522:             *  a hit:  just increment the count.
                   1523:             */
                   1524: #      ifdef DEBUG
                   1525:            if ( debug & TALLYDEBUG ) {
                   1526:                printf( "[tally] hit %d += %d\n" ,
                   1527:                        arcp -> arc_count , count );
                   1528:            }
                   1529: #      endif DEBUG
                   1530:        arcp -> arc_count += count;
                   1531:        return;
                   1532:     }
                   1533:     arcp = calloc( 1 , sizeof *arcp );
                   1534:     arcp -> arc_parentp = parentp;
                   1535:     arcp -> arc_childp = childp;
                   1536:     arcp -> arc_count = count;
                   1537:        /*
                   1538:         *      prepend this child to the children of this parent
                   1539:         */
                   1540:     arcp -> arc_childlist = parentp -> children;
                   1541:     parentp -> children = arcp;
                   1542:        /*
                   1543:         *      prepend this parent to the parents of this child
                   1544:         */
                   1545:     arcp -> arc_parentlist = childp -> parents;
                   1546:     childp -> parents = arcp;
                   1547: }
                   1548: 
                   1549:     /*
                   1550:      * the code below topologically sorts the graph (collapsing cycles),
                   1551:      * and propagates time bottom up and flags top down.
                   1552:      */
                   1553: 
                   1554:     /*
                   1555:      * the topologically sorted name list pointers
                   1556:      */
                   1557: nltype **topsortnlp;
                   1558: 
                   1559: topcmp( npp1 , npp2 )
                   1560:     nltype     **npp1;
                   1561:     nltype     **npp2;
                   1562: {
                   1563:     return (*npp1) -> toporder - (*npp2) -> toporder;
                   1564: }
                   1565: 
                   1566: nltype **
                   1567: doarcs()
                   1568: {
                   1569:     nltype     *parentp, **timesortnlp;
                   1570:     arctype    *arcp;
                   1571:     long       index;
                   1572: 
                   1573:        /*
                   1574:         *      initialize various things:
                   1575:         *          zero out child times.
                   1576:         *          count self-recursive calls.
                   1577:         *          indicate that nothing is on cycles.
                   1578:         */
                   1579:     for ( parentp = nl ; parentp < npe ; parentp++ ) {
                   1580:        parentp -> childtime = 0.0;
                   1581:        arcp = arclookup( parentp , parentp );
                   1582:        if ( arcp != 0 ) {
                   1583:            parentp -> ncall -= arcp -> arc_count;
                   1584:            parentp -> selfcalls = arcp -> arc_count;
                   1585:        } else {
                   1586:            parentp -> selfcalls = 0;
                   1587:        }
                   1588:        parentp -> propfraction = 0.0;
                   1589:        parentp -> propself = 0.0;
                   1590:        parentp -> propchild = 0.0;
                   1591:        parentp -> printflag = FALSE;
                   1592:        parentp -> toporder = DFN_NAN;
                   1593:        parentp -> cycleno = 0;
                   1594:        parentp -> cyclehead = parentp;
                   1595:        parentp -> cnext = 0;
                   1596:        if ( cflag ) {
                   1597:            findcall( parentp , parentp -> value , (parentp+1) -> value );
                   1598:        }
                   1599:     }
                   1600:        /*
                   1601:         *      topologically order things
                   1602:         *      if any node is unnumbered,
                   1603:         *          number it and any of its descendents.
                   1604:         */
                   1605:     for ( parentp = nl ; parentp < npe ; parentp++ ) {
                   1606:        if ( parentp -> toporder == DFN_NAN ) {
                   1607:            dfn( parentp );
                   1608:        }
                   1609:     }
                   1610:        /*
                   1611:         *      link together nodes on the same cycle
                   1612:         */
                   1613:     cyclelink();
                   1614:        /*
                   1615:         *      Sort the symbol table in reverse topological order
                   1616:         */
                   1617:     topsortnlp = (nltype **) calloc( nname , sizeof(nltype *) );
                   1618:     if ( topsortnlp == (nltype **) 0 ) {
                   1619:        fprintf( stderr , "[doarcs] ran out of memory for topo sorting\n" );
                   1620:     }
                   1621:     for ( index = 0 ; index < nname ; index += 1 ) {
                   1622:        topsortnlp[ index ] = &nl[ index ];
                   1623:     }
                   1624:     qsort( topsortnlp , nname , sizeof(nltype *) , topcmp );
                   1625: #   ifdef DEBUG
                   1626:        if ( debug & DFNDEBUG ) {
                   1627:            printf( "[doarcs] topological sort listing\n" );
                   1628:            for ( index = 0 ; index < nname ; index += 1 ) {
                   1629:                printf( "[doarcs] " );
                   1630:                printf( "%d:" , topsortnlp[ index ] -> toporder );
                   1631:                printname( topsortnlp[ index ] );
                   1632:                printf( "\n" );
                   1633:            }
                   1634:        }
                   1635: #   endif DEBUG
                   1636:        /*
                   1637:         *      starting from the topological top,
                   1638:         *      propagate print flags to children.
                   1639:         *      also, calculate propagation fractions.
                   1640:         *      this happens before time propagation
                   1641:         *      since time propagation uses the fractions.
                   1642:         */
                   1643:     doflags();
                   1644:        /*
                   1645:         *      starting from the topological bottom, 
                   1646:         *      propogate children times up to parents.
                   1647:         */
                   1648:     dotime();
                   1649:        /*
                   1650:         *      Now, sort by propself + propchild.
                   1651:         *      sorting both the regular function names
                   1652:         *      and cycle headers.
                   1653:         */
                   1654:     timesortnlp = (nltype **) calloc( nname + ncycle , sizeof(nltype *) );
                   1655:     if ( timesortnlp == (nltype **) 0 ) {
                   1656:        fprintf( stderr , "%s: ran out of memory for sorting\n" , whoami );
                   1657:     }
                   1658:     for ( index = 0 ; index < nname ; index++ ) {
                   1659:        timesortnlp[index] = &nl[index];
                   1660:     }
                   1661:     for ( index = 1 ; index <= ncycle ; index++ ) {
                   1662:        timesortnlp[nname+index-1] = &cyclenl[index];
                   1663:     }
                   1664:     qsort( timesortnlp , nname + ncycle , sizeof(nltype *) , totalcmp );
                   1665:     for ( index = 0 ; index < nname + ncycle ; index++ ) {
                   1666:        timesortnlp[ index ] -> index = index + 1;
                   1667:     }
                   1668:     return( timesortnlp );
                   1669: }
                   1670: 
                   1671: dotime()
                   1672: {
                   1673:     int        index;
                   1674: 
                   1675:     cycletime();
                   1676:     for ( index = 0 ; index < nname ; index += 1 ) {
                   1677:        timepropagate( topsortnlp[ index ] );
                   1678:     }
                   1679: }
                   1680: 
                   1681: timepropagate( parentp )
                   1682:     nltype     *parentp;
                   1683: {
                   1684:     arctype    *arcp;
                   1685:     nltype     *childp;
                   1686:     double     share;
                   1687:     double     propshare;
                   1688: 
                   1689:     if ( parentp -> propfraction == 0.0 ) {
                   1690:        return;
                   1691:     }
                   1692:        /*
                   1693:         *      gather time from children of this parent.
                   1694:         */
                   1695:     for ( arcp = parentp -> children ; arcp ; arcp = arcp -> arc_childlist ) {
                   1696:        childp = arcp -> arc_childp;
                   1697:        if ( arcp -> arc_count == 0 ) {
                   1698:            continue;
                   1699:        }
                   1700:        if ( childp == parentp ) {
                   1701:            continue;
                   1702:        }
                   1703:        if ( childp -> propfraction == 0.0 ) {
                   1704:            continue;
                   1705:        }
                   1706:        if ( childp -> cyclehead != childp ) {
                   1707:            if ( parentp -> cycleno == childp -> cycleno ) {
                   1708:                continue;
                   1709:            }
                   1710:            if ( parentp -> toporder <= childp -> toporder ) {
                   1711:                fprintf( stderr , "[propagate] toporder botches\n" );
                   1712:            }
                   1713:            childp = childp -> cyclehead;
                   1714:        } else {
                   1715:            if ( parentp -> toporder <= childp -> toporder ) {
                   1716:                fprintf( stderr , "[propagate] toporder botches\n" );
                   1717:                continue;
                   1718:            }
                   1719:        }
                   1720:        if ( childp -> ncall == 0 ) {
                   1721:            continue;
                   1722:        }
                   1723:            /*
                   1724:             *  distribute time for this arc
                   1725:             */
                   1726:        arcp -> arc_time = childp -> time
                   1727:                                * ( ( (double) arcp -> arc_count ) /
                   1728:                                    ( (double) childp -> ncall ) );
                   1729:        arcp -> arc_childtime = childp -> childtime
                   1730:                                * ( ( (double) arcp -> arc_count ) /
                   1731:                                    ( (double) childp -> ncall ) );
                   1732:        share = arcp -> arc_time + arcp -> arc_childtime;
                   1733:        parentp -> childtime += share;
                   1734:            /*
                   1735:             *  ( 1 - propfraction ) gets lost along the way
                   1736:             */
                   1737:        propshare = parentp -> propfraction * share;
                   1738:            /*
                   1739:             *  fix things for printing
                   1740:             */
                   1741:        parentp -> propchild += propshare;
                   1742:        arcp -> arc_time *= parentp -> propfraction;
                   1743:        arcp -> arc_childtime *= parentp -> propfraction;
                   1744:            /*
                   1745:             *  add this share to the parent's cycle header, if any.
                   1746:             */
                   1747:        if ( parentp -> cyclehead != parentp ) {
                   1748:            parentp -> cyclehead -> childtime += share;
                   1749:            parentp -> cyclehead -> propchild += propshare;
                   1750:        }
                   1751: #      ifdef DEBUG
                   1752:            if ( debug & PROPDEBUG ) {
                   1753:                printf( "[dotime] child \t" );
                   1754:                printname( childp );
                   1755:                printf( " with %f %f %d/%d\n" ,
                   1756:                        childp -> time , childp -> childtime ,
                   1757:                        arcp -> arc_count , childp -> ncall );
                   1758:                printf( "[dotime] parent\t" );
                   1759:                printname( parentp );
                   1760:                printf( "\n[dotime] share %f\n" , share );
                   1761:            }
                   1762: #      endif DEBUG
                   1763:     }
                   1764: }
                   1765: 
                   1766: cyclelink()
                   1767: {
                   1768:     register nltype    *nlp;
                   1769:     register nltype    *cyclenlp;
                   1770:     int                        cycle;
                   1771:     nltype             *memberp;
                   1772:     arctype            *arcp;
                   1773: 
                   1774:        /*
                   1775:         *      Count the number of cycles, and initialze the cycle lists
                   1776:         */
                   1777:     ncycle = 0;
                   1778:     for ( nlp = nl ; nlp < npe ; nlp++ ) {
                   1779:            /*
                   1780:             *  this is how you find unattached cycles
                   1781:             */
                   1782:        if ( nlp -> cyclehead == nlp && nlp -> cnext != 0 ) {
                   1783:            ncycle += 1;
                   1784:        }
                   1785:     }
                   1786:        /*
                   1787:         *      cyclenl is indexed by cycle number:
                   1788:         *      i.e. it is origin 1, not origin 0.
                   1789:         */
                   1790:     cyclenl = (nltype *) calloc( ncycle + 1 , sizeof( nltype ) );
                   1791:     if ( cyclenl == 0 ) {
                   1792:        fprintf( stderr , "%s: No room for %d bytes of cycle headers\n" ,
                   1793:                whoami , ( ncycle + 1 ) * sizeof( nltype ) );
                   1794:        done();
                   1795:     }
                   1796:        /*
                   1797:         *      now link cycles to true cycleheads,
                   1798:         *      number them, accumulate the data for the cycle
                   1799:         */
                   1800:     cycle = 0;
                   1801:     for ( nlp = nl ; nlp < npe ; nlp++ ) {
                   1802:        if ( !( nlp -> cyclehead == nlp && nlp -> cnext != 0 ) ) {
                   1803:            continue;
                   1804:        }
                   1805:        cycle += 1;
                   1806:        cyclenlp = &cyclenl[cycle];
                   1807:         cyclenlp -> name = 0;          /* the name */
                   1808:         cyclenlp -> value = 0;         /* the pc entry point */
                   1809:         cyclenlp -> time = 0.0;                /* ticks in this routine */
                   1810:         cyclenlp -> childtime = 0.0;   /* cumulative ticks in children */
                   1811:        cyclenlp -> ncall = 0;          /* how many times called */
                   1812:        cyclenlp -> selfcalls = 0;      /* how many calls to self */
                   1813:        cyclenlp -> propfraction = 0.0; /* what % of time propagates */
                   1814:        cyclenlp -> propself = 0.0;     /* how much self time propagates */
                   1815:        cyclenlp -> propchild = 0.0;    /* how much child time propagates */
                   1816:        cyclenlp -> printflag = TRUE;   /* should this be printed? */
                   1817:        cyclenlp -> index = 0;          /* index in the graph list */
                   1818:        cyclenlp -> toporder = DFN_NAN; /* graph call chain top-sort order */
                   1819:        cyclenlp -> cycleno = cycle;    /* internal number of cycle on */
                   1820:        cyclenlp -> cyclehead = cyclenlp;       /* pointer to head of cycle */
                   1821:        cyclenlp -> cnext = nlp;        /* pointer to next member of cycle */
                   1822:        cyclenlp -> parents = 0;        /* list of caller arcs */
                   1823:        cyclenlp -> children = 0;       /* list of callee arcs */
                   1824: #      ifdef DEBUG
                   1825:            if ( debug & CYCLEDEBUG ) {
                   1826:                printf( "[cyclelink] " );
                   1827:                printname( nlp );
                   1828:                printf( " is the head of cycle %d\n" , cycle );
                   1829:            }
                   1830: #      endif DEBUG
                   1831:            /*
                   1832:             *  link members to cycle header
                   1833:             */
                   1834:        for ( memberp = nlp ; memberp ; memberp = memberp -> cnext ) { 
                   1835:            memberp -> cycleno = cycle;
                   1836:            memberp -> cyclehead = cyclenlp;
                   1837:        }
                   1838:            /*
                   1839:             *  count calls from outside the cycle
                   1840:             *  and those among cycle members
                   1841:             */
                   1842:        for ( memberp = nlp ; memberp ; memberp = memberp -> cnext ) {
                   1843:            for ( arcp=memberp->parents ; arcp ; arcp=arcp->arc_parentlist ) {
                   1844:                if ( arcp -> arc_parentp == memberp ) {
                   1845:                    continue;
                   1846:                }
                   1847:                if ( arcp -> arc_parentp -> cycleno == cycle ) {
                   1848:                    cyclenlp -> selfcalls += arcp -> arc_count;
                   1849:                } else {
                   1850:                    cyclenlp -> ncall += arcp -> arc_count;
                   1851:                }
                   1852:            }
                   1853:        }
                   1854:     }
                   1855: }
                   1856: 
                   1857: cycletime()
                   1858: {
                   1859:     int                        cycle;
                   1860:     nltype             *cyclenlp;
                   1861:     nltype             *childp;
                   1862: 
                   1863:     for ( cycle = 1 ; cycle <= ncycle ; cycle += 1 ) {
                   1864:        cyclenlp = &cyclenl[ cycle ];
                   1865:        for ( childp = cyclenlp -> cnext ; childp ; childp = childp -> cnext ) {
                   1866:            if ( childp -> propfraction == 0.0 ) {
                   1867:                    /*
                   1868:                     * all members have the same propfraction except those
                   1869:                     *  that were excluded with -E
                   1870:                     */
                   1871:                continue;
                   1872:            }
                   1873:            cyclenlp -> time += childp -> time;
                   1874:        }
                   1875:        cyclenlp -> propself = cyclenlp -> propfraction * cyclenlp -> time;
                   1876:     }
                   1877: }
                   1878: 
                   1879:     /*
                   1880:      * in one top to bottom pass over the topologically sorted namelist
                   1881:      * propagate:
                   1882:      *         printflag as the union of parents' printflags
                   1883:      *         propfraction as the sum of fractional parents' propfractions
                   1884:      * and while we're here, sum time for functions.
                   1885:      */
                   1886: doflags()
                   1887: {
                   1888:     int                index;
                   1889:     nltype     *childp;
                   1890:     nltype     *oldhead;
                   1891: 
                   1892:     oldhead = 0;
                   1893:     for ( index = nname-1 ; index >= 0 ; index -= 1 ) {
                   1894:        childp = topsortnlp[ index ];
                   1895:            /*
                   1896:             *  if we haven't done this function or cycle,
                   1897:             *  inherit things from parent.
                   1898:             *  this way, we are linear in the number of arcs
                   1899:             *  since we do all members of a cycle (and the cycle itself)
                   1900:             *  as we hit the first member of the cycle.
                   1901:             */
                   1902:        if ( childp -> cyclehead != oldhead ) {
                   1903:            oldhead = childp -> cyclehead;
                   1904:            inheritflags( childp );
                   1905:        }
                   1906: #      ifdef DEBUG
                   1907:            if ( debug & PROPDEBUG ) {
                   1908:                printf( "[doflags] " );
                   1909:                printname( childp );
                   1910:                printf( " inherits printflag %d and propfraction %f\n" ,
                   1911:                        childp -> printflag , childp -> propfraction );
                   1912:            }
                   1913: #      endif DEBUG
                   1914:        if ( ! childp -> printflag ) {
                   1915:                /*
                   1916:                 *      printflag is off
                   1917:                 *      it gets turned on by
                   1918:                 *      being on -f list,
                   1919:                 *      or there not being any -f list and not being on -e list.
                   1920:                 */
                   1921:            if (   onlist( flist , childp -> name )
                   1922:                || ( !fflag && !onlist( elist , childp -> name ) ) ) {
                   1923:                childp -> printflag = TRUE;
                   1924:            }
                   1925:        } else {
                   1926:                /*
                   1927:                 *      this function has printing parents:
                   1928:                 *      maybe someone wants to shut it up
                   1929:                 *      by putting it on -e list.  (but favor -f over -e)
                   1930:                 */
                   1931:            if (  ( !onlist( flist , childp -> name ) )
                   1932:                && onlist( elist , childp -> name ) ) {
                   1933:                childp -> printflag = FALSE;
                   1934:            }
                   1935:        }
                   1936:        if ( childp -> propfraction == 0.0 ) {
                   1937:                /*
                   1938:                 *      no parents to pass time to.
                   1939:                 *      collect time from children if
                   1940:                 *      its on -F list,
                   1941:                 *      or there isn't any -F list and its not on -E list.
                   1942:                 */
                   1943:            if ( onlist( Flist , childp -> name )
                   1944:                || ( !Fflag && !onlist( Elist , childp -> name ) ) ) {
                   1945:                    childp -> propfraction = 1.0;
                   1946:            }
                   1947:        } else {
                   1948:                /*
                   1949:                 *      it has parents to pass time to, 
                   1950:                 *      but maybe someone wants to shut it up
                   1951:                 *      by puttting it on -E list.  (but favor -F over -E)
                   1952:                 */
                   1953:            if (  !onlist( Flist , childp -> name )
                   1954:                && onlist( Elist , childp -> name ) ) {
                   1955:                childp -> propfraction = 0.0;
                   1956:            }
                   1957:        }
                   1958:        childp -> propself = childp -> time * childp -> propfraction;
                   1959:        printtime += childp -> propself;
                   1960: #      ifdef DEBUG
                   1961:            if ( debug & PROPDEBUG ) {
                   1962:                printf( "[doflags] " );
                   1963:                printname( childp );
                   1964:                printf( " ends up with printflag %d and propfraction %f\n" ,
                   1965:                        childp -> printflag , childp -> propfraction );
                   1966:                printf( "time %f propself %f printtime %f\n" ,
                   1967:                        childp -> time , childp -> propself , printtime );
                   1968:            }
                   1969: #      endif DEBUG
                   1970:     }
                   1971: }
                   1972: 
                   1973:     /*
                   1974:      * check if any parent of this child
                   1975:      * (or outside parents of this cycle)
                   1976:      * have their print flags on and set the 
                   1977:      * print flag of the child (cycle) appropriately.
                   1978:      * similarly, deal with propagation fractions from parents.
                   1979:      */
                   1980: inheritflags( childp )
                   1981:     nltype     *childp;
                   1982: {
                   1983:     nltype     *headp;
                   1984:     arctype    *arcp;
                   1985:     nltype     *parentp;
                   1986:     nltype     *memp;
                   1987: 
                   1988:     headp = childp -> cyclehead;
                   1989:     if ( childp == headp ) {
                   1990:            /*
                   1991:             *  just a regular child, check its parents
                   1992:             */
                   1993:        childp -> printflag = FALSE;
                   1994:        childp -> propfraction = 0.0;
                   1995:        for (arcp = childp -> parents ; arcp ; arcp = arcp -> arc_parentlist) {
                   1996:            parentp = arcp -> arc_parentp;
                   1997:            if ( childp == parentp ) {
                   1998:                continue;
                   1999:            }
                   2000:            childp -> printflag |= parentp -> printflag;
                   2001:                /*
                   2002:                 *      if the child was never actually called
                   2003:                 *      (e.g. this arc is static (and all others are, too))
                   2004:                 *      no time propagates along this arc.
                   2005:                 */
                   2006:            if ( childp -> ncall ) {
                   2007:                childp -> propfraction += parentp -> propfraction
                   2008:                                            * ( ( (double) arcp -> arc_count )
                   2009:                                              / ( (double) childp -> ncall ) );
                   2010:            }
                   2011:        }
                   2012:     } else {
                   2013:            /*
                   2014:             *  its a member of a cycle, look at all parents from 
                   2015:             *  outside the cycle
                   2016:             */
                   2017:        headp -> printflag = FALSE;
                   2018:        headp -> propfraction = 0.0;
                   2019:        for ( memp = headp -> cnext ; memp ; memp = memp -> cnext ) {
                   2020:            for (arcp = memp->parents ; arcp ; arcp = arcp->arc_parentlist) {
                   2021:                if ( arcp -> arc_parentp -> cyclehead == headp ) {
                   2022:                    continue;
                   2023:                }
                   2024:                parentp = arcp -> arc_parentp;
                   2025:                headp -> printflag |= parentp -> printflag;
                   2026:                    /*
                   2027:                     *  if the cycle was never actually called
                   2028:                     *  (e.g. this arc is static (and all others are, too))
                   2029:                     *  no time propagates along this arc.
                   2030:                     */
                   2031:                if ( headp -> ncall ) {
                   2032:                    headp -> propfraction += parentp -> propfraction
                   2033:                                            * ( ( (double) arcp -> arc_count )
                   2034:                                              / ( (double) headp -> ncall ) );
                   2035:                }
                   2036:            }
                   2037:        }
                   2038:        for ( memp = headp ; memp ; memp = memp -> cnext ) {
                   2039:            memp -> printflag = headp -> printflag;
                   2040:            memp -> propfraction = headp -> propfraction;
                   2041:        }
                   2042:     }
                   2043: }
                   2044: 
                   2045:        if ( childp -> cyclehead != oldhead ) {
                   2046:            oldhead = childp -> cyclehead;
                   2047:            inheritfgprof/printgprof.c   444     22     12       42731  4167372703   7565 /*
                   2048:  * Copyright (c) 1983 Regents of the University of California.
                   2049:  * All rights reserved.  The Berkeley software License Agreement
                   2050:  * specifies the terms and conditions for redistribution.
                   2051:  */
                   2052: 
                   2053: #ifndef lint
                   2054: static char sccsid[] = "@(#)printgprof.c       5.3 (Berkeley) 1/2/88";
                   2055: #endif not lint
                   2056: 
                   2057: #include "gprof.h"
                   2058: 
                   2059: printprof()
                   2060: {
                   2061:     register nltype    *np;
                   2062:     nltype             **sortednlp;
                   2063:     int                        index, timecmp();
                   2064: 
                   2065:     actime = 0.0;
                   2066:     printf( "\f\n" );
                   2067:     flatprofheader();
                   2068:        /*
                   2069:         *      Sort the symbol table in by time
                   2070:         */
                   2071:     sortednlp = (nltype **) calloc( nname , sizeof(nltype *) );
                   2072:     if ( sortednlp == (nltype **) 0 ) {
                   2073:        fprintf( stderr , "[printprof] ran out of memory for time sorting\n" );
                   2074:     }
                   2075:     for ( index = 0 ; index < nname ; index += 1 ) {
                   2076:        sortednlp[ index ] = &nl[ index ];
                   2077:     }
                   2078:     qsort( sortednlp , nname , sizeof(nltype *) , timecmp );
                   2079:     for ( index = 0 ; index < nname ; index += 1 ) {
                   2080:        np = sortednlp[ index ];
                   2081:        flatprofline( np );
                   2082:     }
                   2083:     actime = 0.0;
                   2084:     cfree( sortednlp );
                   2085: }
                   2086: 
                   2087: timecmp( npp1 , npp2 )
                   2088:     nltype **npp1, **npp2;
                   2089: {
                   2090:     double     timediff;
                   2091:     long       calldiff;
                   2092: 
                   2093:     timediff = (*npp2) -> time - (*npp1) -> time;
                   2094:     if ( timediff > 0.0 )
                   2095:        return 1 ;
                   2096:     if ( timediff < 0.0 )
                   2097:        return -1;
                   2098:     calldiff = (*npp2) -> ncall - (*npp1) -> ncall;
                   2099:     if ( calldiff > 0 )
                   2100:        return 1;
                   2101:     if ( calldiff < 0 )
                   2102:        return -1;
                   2103:     return( strcmp( (*npp1) -> name , (*npp2) -> name ) );
                   2104: }
                   2105: 
                   2106:     /*
                   2107:      * header for flatprofline
                   2108:      */
                   2109: flatprofheader()
                   2110: {
                   2111:     
                   2112:     if ( bflag ) {
                   2113:        printblurb( FLAT_BLURB );
                   2114:     }
                   2115:     printf( "\ngranularity: each sample hit covers %d byte(s)" ,
                   2116:            (long) scale * sizeof(UNIT) );
                   2117:     if ( totime > 0.0 ) {
                   2118:        printf( " for %.2f%% of %.2f seconds\n\n" ,
                   2119:                100.0/totime , totime / hz );
                   2120:     } else {
                   2121:        printf( " no time accumulated\n\n" );
                   2122:            /*
                   2123:             *  this doesn't hurt sinc eall the numerators will be zero.
                   2124:             */
                   2125:        totime = 1.0;
                   2126:     }
                   2127:     printf( "%5.5s %10.10s %8.8s %8.8s %8.8s %8.8s  %-8.8s\n" ,
                   2128:            "%  " , "cumulative" , "self  " , "" , "self  " , "total " , "" );
                   2129:     printf( "%5.5s %10.10s %8.8s %8.8s %8.8s %8.8s  %-8.8s\n" ,
                   2130:            "time" , "seconds " , "seconds" , "calls" ,
                   2131:            "ms/call" , "ms/call" , "name" );
                   2132: }
                   2133: 
                   2134: flatprofline( np )
                   2135:     register nltype    *np;
                   2136: {
                   2137: 
                   2138:     if ( zflag == 0 && np -> ncall == 0 && np -> time == 0 ) {
                   2139:        return;
                   2140:     }
                   2141:     actime += np -> time;
                   2142:     printf( "%5.1f %10.2f %8.2f" ,
                   2143:        100 * np -> time / totime , actime / hz , np -> time / hz );
                   2144:     if ( np -> ncall != 0 ) {
                   2145:        printf( " %8d %8.2f %8.2f  " , np -> ncall ,
                   2146:            1000 * np -> time / hz / np -> ncall ,
                   2147:            1000 * ( np -> time + np -> childtime ) / hz / np -> ncall );
                   2148:     } else {
                   2149:        printf( " %8.8s %8.8s %8.8s  " , "" , "" , "" );
                   2150:     }
                   2151:     printname( np );
                   2152:     printf( "\n" );
                   2153: }
                   2154: 
                   2155: gprofheader()
                   2156: {
                   2157: 
                   2158:     if ( bflag ) {
                   2159:        printblurb( CALLG_BLURB );
                   2160:     }
                   2161:     printf( "\ngranularity: each sample hit covers %d byte(s)" ,
                   2162:            (long) scale * sizeof(UNIT) );
                   2163:     if ( printtime > 0.0 ) {
                   2164:        printf( " for %.2f%% of %.2f seconds\n\n" ,
                   2165:                100.0/printtime , printtime / hz );
                   2166:     } else {
                   2167:        printf( " no time propagated\n\n" );
                   2168:            /*
                   2169:             *  this doesn't hurt, since all the numerators will be 0.0
                   2170:             */
                   2171:        printtime = 1.0;
                   2172:     }
                   2173:     printf( "%6.6s %5.5s %7.7s %11.11s %7.7s/%-7.7s     %-8.8s\n" ,
                   2174:        "" , "" , "" , "" , "called" , "total" , "parents");
                   2175:     printf( "%-6.6s %5.5s %7.7s %11.11s %7.7s+%-7.7s %-8.8s\t%5.5s\n" ,
                   2176:        "index" , "%time" , "self" , "descendents" ,
                   2177:        "called" , "self" , "name" , "index" );
                   2178:     printf( "%6.6s %5.5s %7.7s %11.11s %7.7s/%-7.7s     %-8.8s\n" ,
                   2179:        "" , "" , "" , "" , "called" , "total" , "children");
                   2180:     printf( "\n" );
                   2181: }
                   2182: 
                   2183: gprofline( np )
                   2184:     register nltype    *np;
                   2185: {
                   2186:     char       kirkbuffer[ BUFSIZ ];
                   2187: 
                   2188:     sprintf( kirkbuffer , "[%d]" , np -> index );
                   2189:     printf( "%-6.6s %5.1f %7.2f %11.2f" ,
                   2190:            kirkbuffer ,
                   2191:            100 * ( np -> propself + np -> propchild ) / printtime ,
                   2192:            np -> propself / hz ,
                   2193:            np -> propchild / hz );
                   2194:     if ( ( np -> ncall + np -> selfcalls ) != 0 ) {
                   2195:        printf( " %7d" , np -> ncall );
                   2196:        if ( np -> selfcalls != 0 ) {
                   2197:            printf( "+%-7d " , np -> selfcalls );
                   2198:        } else {
                   2199:            printf( " %7.7s " , "" );
                   2200:        }
                   2201:     } else {
                   2202:        printf( " %7.7s %7.7s " , "" , "" );
                   2203:     }
                   2204:     printname( np );
                   2205:     printf( "\n" );
                   2206: }
                   2207: 
                   2208: printgprof(timesortnlp)
                   2209:     nltype     **timesortnlp;
                   2210: {
                   2211:     int                index;
                   2212:     nltype     *parentp;
                   2213: 
                   2214:        /*
                   2215:         *      Print out the structured profiling list
                   2216:         */
                   2217:     gprofheader();
                   2218:     for ( index = 0 ; index < nname + ncycle ; index ++ ) {
                   2219:        parentp = timesortnlp[ index ];
                   2220:        if ( zflag == 0 &&
                   2221:             parentp -> ncall == 0 &&
                   2222:             parentp -> selfcalls == 0 &&
                   2223:             parentp -> propself == 0 &&
                   2224:             parentp -> propchild == 0 ) {
                   2225:            continue;
                   2226:        }
                   2227:        if ( ! parentp -> printflag ) {
                   2228:            continue;
                   2229:        }
                   2230:        if ( parentp -> name == 0 && parentp -> cycleno != 0 ) {
                   2231:                /*
                   2232:                 *      cycle header
                   2233:                 */
                   2234:            printcycle( parentp );
                   2235:            printmembers( parentp );
                   2236:        } else {
                   2237:            printparents( parentp );
                   2238:            gprofline( parentp );
                   2239:            printchildren( parentp );
                   2240:        }
                   2241:        printf( "\n" );
                   2242:        printf( "-----------------------------------------------\n" );
                   2243:        printf( "\n" );
                   2244:     }
                   2245:     cfree( timesortnlp );
                   2246: }
                   2247: 
                   2248:     /*
                   2249:      * sort by decreasing propagated time
                   2250:      * if times are equal, but one is a cycle header,
                   2251:      *         say that's first (e.g. less, i.e. -1).
                   2252:      * if one's name doesn't have an underscore and the other does,
                   2253:      *         say the one is first.
                   2254:      * all else being equal, sort by names.
                   2255:      */
                   2256: int
                   2257: totalcmp( npp1 , npp2 )
                   2258:     nltype     **npp1;
                   2259:     nltype     **npp2;
                   2260: {
                   2261:     register nltype    *np1 = *npp1;
                   2262:     register nltype    *np2 = *npp2;
                   2263:     double             diff;
                   2264: 
                   2265:     diff =    ( np1 -> propself + np1 -> propchild )
                   2266:            - ( np2 -> propself + np2 -> propchild );
                   2267:     if ( diff < 0.0 )
                   2268:            return 1;
                   2269:     if ( diff > 0.0 )
                   2270:            return -1;
                   2271:     if ( np1 -> name == 0 && np1 -> cycleno != 0 ) 
                   2272:        return -1;
                   2273:     if ( np2 -> name == 0 && np2 -> cycleno != 0 )
                   2274:        return 1;
                   2275:     if ( np1 -> name == 0 )
                   2276:        return -1;
                   2277:     if ( np2 -> name == 0 )
                   2278:        return 1;
                   2279:     if ( *(np1 -> name) != '_' && *(np2 -> name) == '_' )
                   2280:        return -1;
                   2281:     if ( *(np1 -> name) == '_' && *(np2 -> name) != '_' )
                   2282:        return 1;
                   2283:     if ( np1 -> ncall > np2 -> ncall )
                   2284:        return -1;
                   2285:     if ( np1 -> ncall < np2 -> ncall ) 
                   2286:        return 1;
                   2287:     return strcmp( np1 -> name , np2 -> name );
                   2288: }
                   2289: 
                   2290: printparents( childp )
                   2291:     nltype     *childp;
                   2292: {
                   2293:     nltype     *parentp;
                   2294:     arctype    *arcp;
                   2295:     nltype     *cycleheadp;
                   2296: 
                   2297:     if ( childp -> cyclehead != 0 ) {
                   2298:        cycleheadp = childp -> cyclehead;
                   2299:     } else {
                   2300:        cycleheadp = childp;
                   2301:     }
                   2302:     if ( childp -> parents == 0 ) {
                   2303:        printf( "%6.6s %5.5s %7.7s %11.11s %7.7s %7.7s     <spontaneous>\n" ,
                   2304:                "" , "" , "" , "" , "" , "" );
                   2305:        return;
                   2306:     }
                   2307:     sortparents( childp );
                   2308:     for ( arcp = childp -> parents ; arcp ; arcp = arcp -> arc_parentlist ) {
                   2309:        parentp = arcp -> arc_parentp;
                   2310:        if ( childp == parentp ||
                   2311:             ( childp->cycleno != 0 && parentp->cycleno == childp->cycleno ) ) {
                   2312:                /*
                   2313:                 *      selfcall or call among siblings
                   2314:                 */
                   2315:            printf( "%6.6s %5.5s %7.7s %11.11s %7d %7.7s     " ,
                   2316:                    "" , "" , "" , "" ,
                   2317:                    arcp -> arc_count , "" );
                   2318:            printname( parentp );
                   2319:            printf( "\n" );
                   2320:        } else {
                   2321:                /*
                   2322:                 *      regular parent of child
                   2323:                 */
                   2324:            printf( "%6.6s %5.5s %7.2f %11.2f %7d/%-7d     " ,
                   2325:                    "" , "" ,
                   2326:                    arcp -> arc_time / hz , arcp -> arc_childtime / hz ,
                   2327:                    arcp -> arc_count , cycleheadp -> ncall );
                   2328:            printname( parentp );
                   2329:            printf( "\n" );
                   2330:        }
                   2331:     }
                   2332: }
                   2333: 
                   2334: printchildren( parentp )
                   2335:     nltype     *parentp;
                   2336: {
                   2337:     nltype     *childp;
                   2338:     arctype    *arcp;
                   2339: 
                   2340:     sortchildren( parentp );
                   2341:     arcp = parentp -> children;
                   2342:     for ( arcp = parentp -> children ; arcp ; arcp = arcp -> arc_childlist ) {
                   2343:        childp = arcp -> arc_childp;
                   2344:        if ( childp == parentp ||
                   2345:            ( childp->cycleno != 0 && childp->cycleno == parentp->cycleno ) ) {
                   2346:                /*
                   2347:                 *      self call or call to sibling
                   2348:                 */
                   2349:            printf( "%6.6s %5.5s %7.7s %11.11s %7d %7.7s     " ,
                   2350:                    "" , "" , "" , "" , arcp -> arc_count , "" );
                   2351:            printname( childp );
                   2352:            printf( "\n" );
                   2353:        } else {
                   2354:                /*
                   2355:                 *      regular child of parent
                   2356:                 */
                   2357:            printf( "%6.6s %5.5s %7.2f %11.2f %7d/%-7d     " ,
                   2358:                    "" , "" ,
                   2359:                    arcp -> arc_time / hz , arcp -> arc_childtime / hz ,
                   2360:                    arcp -> arc_count , childp -> cyclehead -> ncall );
                   2361:            printname( childp );
                   2362:            printf( "\n" );
                   2363:        }
                   2364:     }
                   2365: }
                   2366: 
                   2367: printname( selfp )
                   2368:     nltype     *selfp;
                   2369: {
                   2370: 
                   2371:     if ( selfp -> name != 0 ) {
                   2372:        printf( "%s" , selfp -> name );
                   2373: #      ifdef DEBUG
                   2374:            if ( debug & DFNDEBUG ) {
                   2375:                printf( "{%d} " , selfp -> toporder );
                   2376:            }
                   2377:            if ( debug & PROPDEBUG ) {
                   2378:                printf( "%5.2f%% " , selfp -> propfraction );
                   2379:            }
                   2380: #      endif DEBUG
                   2381:     }
                   2382:     if ( selfp -> cycleno != 0 ) {
                   2383:        printf( " <cycle %d>" , selfp -> cycleno );
                   2384:     }
                   2385:     if ( selfp -> index != 0 ) {
                   2386:        if ( selfp -> printflag ) {
                   2387:            printf( " [%d]" , selfp -> index );
                   2388:        } else {
                   2389:            printf( " (%d)" , selfp -> index );
                   2390:        }
                   2391:     }
                   2392: }
                   2393: 
                   2394: sortchildren( parentp )
                   2395:     nltype     *parentp;
                   2396: {
                   2397:     arctype    *arcp;
                   2398:     arctype    *detachedp;
                   2399:     arctype    sorted;
                   2400:     arctype    *prevp;
                   2401: 
                   2402:        /*
                   2403:         *      unlink children from parent,
                   2404:         *      then insertion sort back on to sorted's children.
                   2405:         *          *arcp       the arc you have detached and are inserting.
                   2406:         *          *detachedp  the rest of the arcs to be sorted.
                   2407:         *          sorted      arc list onto which you insertion sort.
                   2408:         *          *prevp      arc before the arc you are comparing.
                   2409:         */
                   2410:     sorted.arc_childlist = 0;
                   2411:     for (  (arcp = parentp -> children)&&(detachedp = arcp -> arc_childlist);
                   2412:            arcp ;
                   2413:           (arcp = detachedp)&&(detachedp = detachedp -> arc_childlist)) {
                   2414:            /*
                   2415:             *  consider *arcp as disconnected
                   2416:             *  insert it into sorted
                   2417:             */
                   2418:        for (   prevp = &sorted ;
                   2419:                prevp -> arc_childlist ;
                   2420:                prevp = prevp -> arc_childlist ) {
                   2421:            if ( arccmp( arcp , prevp -> arc_childlist ) != LESSTHAN ) {
                   2422:                break;
                   2423:            }
                   2424:        }
                   2425:        arcp -> arc_childlist = prevp -> arc_childlist;
                   2426:        prevp -> arc_childlist = arcp;
                   2427:     }
                   2428:        /*
                   2429:         *      reattach sorted children to parent
                   2430:         */
                   2431:     parentp -> children = sorted.arc_childlist;
                   2432: }
                   2433: 
                   2434: sortparents( childp )
                   2435:     nltype     *childp;
                   2436: {
                   2437:     arctype    *arcp;
                   2438:     arctype    *detachedp;
                   2439:     arctype    sorted;
                   2440:     arctype    *prevp;
                   2441: 
                   2442:        /*
                   2443:         *      unlink parents from child,
                   2444:         *      then insertion sort back on to sorted's parents.
                   2445:         *          *arcp       the arc you have detached and are inserting.
                   2446:         *          *detachedp  the rest of the arcs to be sorted.
                   2447:         *          sorted      arc list onto which you insertion sort.
                   2448:         *          *prevp      arc before the arc you are comparing.
                   2449:         */
                   2450:     sorted.arc_parentlist = 0;
                   2451:     for (  (arcp = childp -> parents)&&(detachedp = arcp -> arc_parentlist);
                   2452:            arcp ;
                   2453:           (arcp = detachedp)&&(detachedp = detachedp -> arc_parentlist)) {
                   2454:            /*
                   2455:             *  consider *arcp as disconnected
                   2456:             *  insert it into sorted
                   2457:             */
                   2458:        for (   prevp = &sorted ;
                   2459:                prevp -> arc_parentlist ;
                   2460:                prevp = prevp -> arc_parentlist ) {
                   2461:            if ( arccmp( arcp , prevp -> arc_parentlist ) != GREATERTHAN ) {
                   2462:                break;
                   2463:            }
                   2464:        }
                   2465:        arcp -> arc_parentlist = prevp -> arc_parentlist;
                   2466:        prevp -> arc_parentlist = arcp;
                   2467:     }
                   2468:        /*
                   2469:         *      reattach sorted arcs to child
                   2470:         */
                   2471:     childp -> parents = sorted.arc_parentlist;
                   2472: }
                   2473: 
                   2474:     /*
                   2475:      * print a cycle header
                   2476:      */
                   2477: printcycle( cyclep )
                   2478:     nltype     *cyclep;
                   2479: {
                   2480:     char       kirkbuffer[ BUFSIZ ];
                   2481: 
                   2482:     sprintf( kirkbuffer , "[%d]" , cyclep -> index );
                   2483:     printf( "%-6.6s %5.1f %7.2f %11.2f %7d" ,
                   2484:            kirkbuffer ,
                   2485:            100 * ( cyclep -> propself + cyclep -> propchild ) / printtime ,
                   2486:            cyclep -> propself / hz ,
                   2487:            cyclep -> propchild / hz ,
                   2488:            cyclep -> ncall );
                   2489:     if ( cyclep -> selfcalls != 0 ) {
                   2490:        printf( "+%-7d" , cyclep -> selfcalls );
                   2491:     } else {
                   2492:        printf( " %7.7s" , "" );
                   2493:     }
                   2494:     printf( " <cycle %d as a whole>\t[%d]\n" ,
                   2495:            cyclep -> cycleno , cyclep -> index );
                   2496: }
                   2497: 
                   2498:     /*
                   2499:      * print the members of a cycle
                   2500:      */
                   2501: printmembers( cyclep )
                   2502:     nltype     *cyclep;
                   2503: {
                   2504:     nltype     *memberp;
                   2505: 
                   2506:     sortmembers( cyclep );
                   2507:     for ( memberp = cyclep -> cnext ; memberp ; memberp = memberp -> cnext ) {
                   2508:        printf( "%6.6s %5.5s %7.2f %11.2f %7d" , 
                   2509:                "" , "" , memberp -> propself / hz , memberp -> propchild / hz ,
                   2510:                memberp -> ncall );
                   2511:        if ( memberp -> selfcalls != 0 ) {
                   2512:            printf( "+%-7d" , memberp -> selfcalls );
                   2513:        } else {
                   2514:            printf( " %7.7s" , "" );
                   2515:        }
                   2516:        printf( "     " );
                   2517:        printname( memberp );
                   2518:        printf( "\n" );
                   2519:     }
                   2520: }
                   2521: 
                   2522:     /*
                   2523:      * sort members of a cycle
                   2524:      */
                   2525: sortmembers( cyclep )
                   2526:     nltype     *cyclep;
                   2527: {
                   2528:     nltype     *todo;
                   2529:     nltype     *doing;
                   2530:     nltype     *prev;
                   2531: 
                   2532:        /*
                   2533:         *      detach cycle members from cyclehead,
                   2534:         *      and insertion sort them back on.
                   2535:         */
                   2536:     todo = cyclep -> cnext;
                   2537:     cyclep -> cnext = 0;
                   2538:     for (  (doing = todo)&&(todo = doing -> cnext);
                   2539:            doing ;
                   2540:           (doing = todo )&&(todo = doing -> cnext )){
                   2541:        for ( prev = cyclep ; prev -> cnext ; prev = prev -> cnext ) {
                   2542:            if ( membercmp( doing , prev -> cnext ) == GREATERTHAN ) {
                   2543:                break;
                   2544:            }
                   2545:        }
                   2546:        doing -> cnext = prev -> cnext;
                   2547:        prev -> cnext = doing;
                   2548:     }
                   2549: }
                   2550: 
                   2551:     /*
                   2552:      * major sort is on propself + propchild,
                   2553:      * next is sort on ncalls + selfcalls.
                   2554:      */
                   2555: int
                   2556: membercmp( this , that )
                   2557:     nltype     *this;
                   2558:     nltype     *that;
                   2559: {
                   2560:     double     thistime = this -> propself + this -> propchild;
                   2561:     double     thattime = that -> propself + that -> propchild;
                   2562:     long       thiscalls = this -> ncall + this -> selfcalls;
                   2563:     long       thatcalls = that -> ncall + that -> selfcalls;
                   2564: 
                   2565:     if ( thistime > thattime ) {
                   2566:        return GREATERTHAN;
                   2567:     }
                   2568:     if ( thistime < thattime ) {
                   2569:        return LESSTHAN;
                   2570:     }
                   2571:     if ( thiscalls > thatcalls ) {
                   2572:        return GREATERTHAN;
                   2573:     }
                   2574:     if ( thiscalls < thatcalls ) {
                   2575:        return LESSTHAN;
                   2576:     }
                   2577:     return EQUALTO;
                   2578: }
                   2579:     /*
                   2580:      * compare two arcs to/from the same child/parent.
                   2581:      * - if one arc is a self arc, it's least.
                   2582:      * - if one arc is within a cycle, it's less than.
                   2583:      * - if both arcs are within a cycle, compare arc counts.
                   2584:      * - if neither arc is within a cycle, compare with
                   2585:      *         arc_time + arc_childtime as major key
                   2586:      *         arc count as minor key
                   2587:      */
                   2588: int
                   2589: arccmp( thisp , thatp )
                   2590:     arctype    *thisp;
                   2591:     arctype    *thatp;
                   2592: {
                   2593:     nltype     *thisparentp = thisp -> arc_parentp;
                   2594:     nltype     *thischildp = thisp -> arc_childp;
                   2595:     nltype     *thatparentp = thatp -> arc_parentp;
                   2596:     nltype     *thatchildp = thatp -> arc_childp;
                   2597:     double     thistime;
                   2598:     double     thattime;
                   2599: 
                   2600: #   ifdef DEBUG
                   2601:        if ( debug & TIMEDEBUG ) {
                   2602:            printf( "[arccmp] " );
                   2603:            printname( thisparentp );
                   2604:            printf( " calls " );
                   2605:            printname ( thischildp );
                   2606:            printf( " %f + %f %d/%d\n" ,
                   2607:                    thisp -> arc_time , thisp -> arc_childtime ,
                   2608:                    thisp -> arc_count , thischildp -> ncall );
                   2609:            printf( "[arccmp] " );
                   2610:            printname( thatparentp );
                   2611:            printf( " calls " );
                   2612:            printname( thatchildp );
                   2613:            printf( " %f + %f %d/%d\n" ,
                   2614:                    thatp -> arc_time , thatp -> arc_childtime ,
                   2615:                    thatp -> arc_count , thatchildp -> ncall );
                   2616:            printf( "\n" );
                   2617:        }
                   2618: #   endif DEBUG
                   2619:     if ( thisparentp == thischildp ) {
                   2620:            /* this is a self call */
                   2621:        return LESSTHAN;
                   2622:     }
                   2623:     if ( thatparentp == thatchildp ) {
                   2624:            /* that is a self call */
                   2625:        return GREATERTHAN;
                   2626:     }
                   2627:     if ( thisparentp -> cycleno != 0 && thischildp -> cycleno != 0 &&
                   2628:        thisparentp -> cycleno == thischildp -> cycleno ) {
                   2629:            /* this is a call within a cycle */
                   2630:        if ( thatparentp -> cycleno != 0 && thatchildp -> cycleno != 0 &&
                   2631:            thatparentp -> cycleno == thatchildp -> cycleno ) {
                   2632:                /* that is a call within the cycle, too */
                   2633:            if ( thisp -> arc_count < thatp -> arc_count ) {
                   2634:                return LESSTHAN;
                   2635:            }
                   2636:            if ( thisp -> arc_count > thatp -> arc_count ) {
                   2637:                return GREATERTHAN;
                   2638:            }
                   2639:            return EQUALTO;
                   2640:        } else {
                   2641:                /* that isn't a call within the cycle */
                   2642:            return LESSTHAN;
                   2643:        }
                   2644:     } else {
                   2645:            /* this isn't a call within a cycle */
                   2646:        if ( thatparentp -> cycleno != 0 && thatchildp -> cycleno != 0 &&
                   2647:            thatparentp -> cycleno == thatchildp -> cycleno ) {
                   2648:                /* that is a call within a cycle */
                   2649:            return GREATERTHAN;
                   2650:        } else {
                   2651:                /* neither is a call within a cycle */
                   2652:            thistime = thisp -> arc_time + thisp -> arc_childtime;
                   2653:            thattime = thatp -> arc_time + thatp -> arc_childtime;
                   2654:            if ( thistime < thattime )
                   2655:                return LESSTHAN;
                   2656:            if ( thistime > thattime )
                   2657:                return GREATERTHAN;
                   2658:            if ( thisp -> arc_count < thatp -> arc_count )
                   2659:                return LESSTHAN;
                   2660:            if ( thisp -> arc_count > thatp -> arc_count )
                   2661:                return GREATERTHAN;
                   2662:            return EQUALTO;
                   2663:        }
                   2664:     }
                   2665: }
                   2666: 
                   2667: printblurb( blurbname )
                   2668:     char       *blurbname;
                   2669: {
                   2670:     FILE       *blurbfile;
                   2671:     int                input;
                   2672: 
                   2673:     blurbfile = fopen( blurbname , "r" );
                   2674:     if ( blurbfile == NULL ) {
                   2675:        perror( blurbname );
                   2676:        return;
                   2677:     }
                   2678:     while ( ( input = getc( blurbfile ) ) != EOF ) {
                   2679:        putchar( input );
                   2680:     }
                   2681:     fclose( blurbfile );
                   2682: }
                   2683: 
                   2684: int
                   2685: namecmp( npp1 , npp2 )
                   2686:     nltype **npp1, **npp2;
                   2687: {
                   2688:     return( strcmp( (*npp1) -> name , (*npp2) -> name ) );
                   2689: }
                   2690: 
                   2691: printindex()
                   2692: {
                   2693:     nltype             **namesortnlp;
                   2694:     register nltype    *nlp;
                   2695:     int                        index, nnames, todo, i, j;
                   2696:     char               peterbuffer[ BUFSIZ ];
                   2697: 
                   2698:        /*
                   2699:         *      Now, sort regular function name alphbetically
                   2700:         *      to create an index.
                   2701:         */
                   2702:     namesortnlp = (nltype **) calloc( nname + ncycle , sizeof(nltype *) );
                   2703:     if ( namesortnlp == (nltype **) 0 ) {
                   2704:        fprintf( stderr , "%s: ran out of memory for sorting\n" , whoami );
                   2705:     }
                   2706:     for ( index = 0 , nnames = 0 ; index < nname ; index++ ) {
                   2707:        if ( zflag == 0 && nl[index].ncall == 0 && nl[index].time == 0 )
                   2708:                continue;
                   2709:        namesortnlp[nnames++] = &nl[index];
                   2710:     }
                   2711:     qsort( namesortnlp , nnames , sizeof(nltype *) , namecmp );
                   2712:     for ( index = 1 , todo = nnames ; index <= ncycle ; index++ ) {
                   2713:        namesortnlp[todo++] = &cyclenl[index];
                   2714:     }
                   2715:     printf( "\f\nIndex by function name\n\n" );
                   2716:     index = ( todo + 2 ) / 3;
                   2717:     for ( i = 0; i < index ; i++ ) {
                   2718:        for ( j = i; j < todo ; j += index ) {
                   2719:            nlp = namesortnlp[ j ];
                   2720:            if ( nlp -> printflag ) {
                   2721:                sprintf( peterbuffer , "[%d]" , nlp -> index );
                   2722:            } else {
                   2723:                sprintf( peterbuffer , "(%d)" , nlp -> index );
                   2724:            }
                   2725:            if ( j < nnames ) {
                   2726:                printf( "%6.6s %-19.19s" , peterbuffer , nlp -> name );
                   2727:            } else {
                   2728:                printf( "%6.6s " , peterbuffer );
                   2729:                sprintf( peterbuffer , "<cycle %d>" , nlp -> cycleno );
                   2730:                printf( "%-19.19s" , peterbuffer );
                   2731:            }
                   2732:        }
                   2733:        printf( "\n" );
                   2734:     }
                   2735:     cfree( namesortnlp );
                   2736: }
                   2737:  thisp -> arc_parentp;
                   2738:     nltype     *thisgprof/hertz.c   444     22     12        1405  3500670604   6467 /*
                   2739:  * Copyright (c) 1983 Regents of the University of California.
                   2740:  * All rights reserved.  The Berkeley software License Agreement
                   2741:  * specifies the terms and conditions for redistribution.
                   2742:  */
                   2743: 
                   2744: #ifndef lint
                   2745: static char sccsid[] = "@(#)hertz.c    5.1 (Berkeley) 6/4/85";
                   2746: #endif not lint
                   2747: 
                   2748: #include <sys/time.h>
                   2749: 
                   2750:     /*
                   2751:      * discover the tick frequency of the machine
                   2752:      * if something goes wrong, we return 0, an impossible hertz.
                   2753:      */
                   2754: #define        HZ_WRONG        0
                   2755: 
                   2756: hertz()
                   2757: {
                   2758:        struct itimerval tim;
                   2759: 
                   2760:        tim.it_interval.tv_sec = 0;
                   2761:        tim.it_interval.tv_usec = 1;
                   2762:        tim.it_value.tv_sec = 0;
                   2763:        tim.it_value.tv_usec = 0;
                   2764:        setitimer(ITIMER_REAL, &tim, 0);
                   2765:        setitimer(ITIMER_REAL, 0, &tim);
                   2766:        if (tim.it_interval.tv_usec < 2)
                   2767:                return(HZ_WRONG);
                   2768:        return (1000000 / tim.it_interval.tv_usec);
                   2769: }
                   2770: gprof/lookup.c   444     22     12        3642  3500670643   6654 /*
                   2771:  * Copyright (c) 1983 Regents of the University of California.
                   2772:  * All rights reserved.  The Berkeley software License Agreement
                   2773:  * specifies the terms and conditions for redistribution.
                   2774:  */
                   2775: 
                   2776: #ifndef lint
                   2777: static char sccsid[] = "@(#)lookup.c   5.1 (Berkeley) 6/4/85";
                   2778: #endif not lint
                   2779: 
                   2780: #include "gprof.h"
                   2781: 
                   2782:     /*
                   2783:      * look up an address in a sorted-by-address namelist
                   2784:      *     this deals with misses by mapping them to the next lower 
                   2785:      *     entry point.
                   2786:      */
                   2787: nltype *
                   2788: nllookup( address )
                   2789:     unsigned long      address;
                   2790: {
                   2791:     register long      low;
                   2792:     register long      middle;
                   2793:     register long      high;
                   2794: #   ifdef DEBUG
                   2795:        register int    probes;
                   2796: 
                   2797:        probes = 0;
                   2798: #   endif DEBUG
                   2799:     for ( low = 0 , high = nname - 1 ; low != high ; ) {
                   2800: #      ifdef DEBUG
                   2801:            probes += 1;
                   2802: #      endif DEBUG
                   2803:        middle = ( high + low ) >> 1;
                   2804:        if ( nl[ middle ].value <= address && nl[ middle+1 ].value > address ) {
                   2805: #          ifdef DEBUG
                   2806:                if ( debug & LOOKUPDEBUG ) {
                   2807:                    printf( "[nllookup] %d (%d) probes\n" , probes , nname-1 );
                   2808:                }
                   2809: #          endif DEBUG
                   2810:            return &nl[ middle ];
                   2811:        }
                   2812:        if ( nl[ middle ].value > address ) {
                   2813:            high = middle;
                   2814:        } else {
                   2815:            low = middle + 1;
                   2816:        }
                   2817:     }
                   2818:     fprintf( stderr , "[nllookup] binary search fails???\n" );
                   2819:     return 0;
                   2820: }
                   2821: 
                   2822: arctype *
                   2823: arclookup( parentp , childp )
                   2824:     nltype     *parentp;
                   2825:     nltype     *childp;
                   2826: {
                   2827:     arctype    *arcp;
                   2828: 
                   2829:     if ( parentp == 0 || childp == 0 ) {
                   2830:        fprintf( "[arclookup] parentp == 0 || childp == 0\n" );
                   2831:        return 0;
                   2832:     }
                   2833: #   ifdef DEBUG
                   2834:        if ( debug & LOOKUPDEBUG ) {
                   2835:            printf( "[arclookup] parent %s child %s\n" ,
                   2836:                    parentp -> name , childp -> name );
                   2837:        }
                   2838: #   endif DEBUG
                   2839:     for ( arcp = parentp -> children ; arcp ; arcp = arcp -> arc_childlist ) {
                   2840: #      ifdef DEBUG
                   2841:            if ( debug & LOOKUPDEBUG ) {
                   2842:                printf( "[arclookup]\t arc_parent %s arc_child %s\n" ,
                   2843:                        arcp -> arc_parentp -> name ,
                   2844:                        arcp -> arc_childp -> name );
                   2845:            }
                   2846: #      endif DEBUG
                   2847:        if ( arcp -> arc_childp == childp ) {
                   2848:            return arcp;
                   2849:        }
                   2850:     }
                   2851:     return 0;
                   2852: }
                   2853: 
                   2854:        }
                   2855:        printf( "\n" );
                   2856:     }
                   2857:     cfree( namesortnlp );
                   2858: }
                   2859:  thisp -> arc_parentp;
                   2860:     nltype     *thisgprof/tahoe.c   444     22     12       16405  3610154261   6457 #ifndef lint
                   2861: static char *sccsid = "@(#)tahoe.c     1.2 (Berkeley) 1/7/86";
                   2862: #endif not lint
                   2863: 
                   2864: #include       "gprof.h"
                   2865: 
                   2866:     /*
                   2867:      * a namelist entry to be the child of indirect callf
                   2868:      */
                   2869: nltype indirectchild = {
                   2870:        "(*)" ,                         /* the name */
                   2871:        (unsigned long) 0 ,             /* the pc entry point */
                   2872:        (unsigned long) 0 ,             /* entry point aligned to histogram */
                   2873:        (double) 0.0 ,                  /* ticks in this routine */
                   2874:        (double) 0.0 ,                  /* cumulative ticks in children */
                   2875:        (long) 0 ,                      /* how many times called */
                   2876:        (long) 0 ,                      /* how many calls to self */
                   2877:        (double) 1.0 ,                  /* propagation fraction */
                   2878:        (double) 0.0 ,                  /* self propagation time */
                   2879:        (double) 0.0 ,                  /* child propagation time */
                   2880:        (bool) 0 ,                      /* print flag */
                   2881:        (int) 0 ,                       /* index in the graph list */
                   2882:        (int) 0 ,                       /* graph call chain top-sort order */
                   2883:        (int) 0 ,                       /* internal number of cycle on */
                   2884:        (struct nl *) &indirectchild ,  /* pointer to head of cycle */
                   2885:        (struct nl *) 0 ,               /* pointer to next member of cycle */
                   2886:        (arctype *) 0 ,                 /* list of caller arcs */
                   2887:        (arctype *) 0                   /* list of callee arcs */
                   2888:     };
                   2889: 
                   2890: operandenum
                   2891: operandmode( modep )
                   2892:     unsigned char      *modep;
                   2893: {
                   2894:     long       usesreg = ((long)*modep) & 0xf;
                   2895:     
                   2896:     switch ( ((long)*modep) >> 4 ) {
                   2897:        case 0:
                   2898:        case 1:
                   2899:        case 2:
                   2900:        case 3:
                   2901:            return literal;
                   2902:        case 4:
                   2903:            return indexed;
                   2904:        case 5:
                   2905:            return reg;
                   2906:        case 6:
                   2907:            return regdef;
                   2908:        case 7:
                   2909:            return autodec;
                   2910:        case 8:
                   2911:            return ( usesreg != 0xe ? autoinc : immediate );
                   2912:        case 9:
                   2913:            return ( usesreg != PC ? autoincdef : absolute );
                   2914:        case 10:
                   2915:            return ( usesreg != PC ? bytedisp : byterel );
                   2916:        case 11:
                   2917:            return ( usesreg != PC ? bytedispdef : bytereldef );
                   2918:        case 12:
                   2919:            return ( usesreg != PC ? worddisp : wordrel );
                   2920:        case 13:
                   2921:            return ( usesreg != PC ? worddispdef : wordreldef );
                   2922:        case 14:
                   2923:            return ( usesreg != PC ? longdisp : longrel );
                   2924:        case 15:
                   2925:            return ( usesreg != PC ? longdispdef : longreldef );
                   2926:     }
                   2927:     /* NOTREACHED */
                   2928: }
                   2929: 
                   2930: char *
                   2931: operandname( mode )
                   2932:     operandenum        mode;
                   2933: {
                   2934:     
                   2935:     switch ( mode ) {
                   2936:        case literal:
                   2937:            return "literal";
                   2938:        case indexed:
                   2939:            return "indexed";
                   2940:        case reg:
                   2941:            return "register";
                   2942:        case regdef:
                   2943:            return "register deferred";
                   2944:        case autodec:
                   2945:            return "autodecrement";
                   2946:        case autoinc:
                   2947:            return "autoincrement";
                   2948:        case autoincdef:
                   2949:            return "autoincrement deferred";
                   2950:        case bytedisp:
                   2951:            return "byte displacement";
                   2952:        case bytedispdef:
                   2953:            return "byte displacement deferred";
                   2954:        case byterel:
                   2955:            return "byte relative";
                   2956:        case bytereldef:
                   2957:            return "byte relative deferred";
                   2958:        case worddisp:
                   2959:            return "word displacement";
                   2960:        case worddispdef:
                   2961:            return "word displacement deferred";
                   2962:        case wordrel:
                   2963:            return "word relative";
                   2964:        case wordreldef:
                   2965:            return "word relative deferred";
                   2966:        case immediate:
                   2967:            return "immediate";
                   2968:        case absolute:
                   2969:            return "absolute";
                   2970:        case longdisp:
                   2971:            return "long displacement";
                   2972:        case longdispdef:
                   2973:            return "long displacement deferred";
                   2974:        case longrel:
                   2975:            return "long relative";
                   2976:        case longreldef:
                   2977:            return "long relative deferred";
                   2978:     }
                   2979:     /* NOTREACHED */
                   2980: }
                   2981: 
                   2982: long
                   2983: operandlength( modep )
                   2984:     unsigned char      *modep;
                   2985: {
                   2986:     
                   2987:     switch ( operandmode( modep ) ) {
                   2988:        case literal:
                   2989:        case reg:
                   2990:        case regdef:
                   2991:        case autodec:
                   2992:        case autoinc:
                   2993:        case autoincdef:
                   2994:            return 1;
                   2995:        case bytedisp:
                   2996:        case bytedispdef:
                   2997:        case byterel:
                   2998:        case bytereldef:
                   2999:            return 2;
                   3000:        case worddisp:
                   3001:        case worddispdef:
                   3002:        case wordrel:
                   3003:        case wordreldef:
                   3004:            return 3;
                   3005:        case immediate:
                   3006:        case absolute:
                   3007:        case longdisp:
                   3008:        case longdispdef:
                   3009:        case longrel:
                   3010:        case longreldef:
                   3011:            return 5;
                   3012:        case indexed:
                   3013:            return 1+operandlength( modep + 1 );
                   3014:     }
                   3015:     /* NOTREACHED */
                   3016: }
                   3017: 
                   3018: unsigned long
                   3019: reladdr( modep )
                   3020:     char       *modep;
                   3021: {
                   3022:     operandenum        mode = operandmode( modep );
                   3023:     char       *cp;
                   3024:     short      *sp;
                   3025:     long       *lp;
                   3026:     int                i;
                   3027:     long       value = 0;
                   3028: 
                   3029:     cp = modep;
                   3030:     cp += 1;                   /* skip over the mode */
                   3031:     switch ( mode ) {
                   3032:        default:
                   3033:            fprintf( stderr , "[reladdr] not relative address\n" );
                   3034:            return (unsigned long) modep;
                   3035:        case byterel:
                   3036:            return (unsigned long) ( cp + sizeof *cp + *cp );
                   3037:        case wordrel:
                   3038:            for (i = 0; i < sizeof *sp; i++)
                   3039:                value = (value << 8) + (cp[i] & 0xff);
                   3040:            return (unsigned long) ( cp + sizeof *sp + value );
                   3041:        case longrel:
                   3042:            for (i = 0; i < sizeof *lp; i++)
                   3043:                value = (value << 8) + (cp[i] & 0xff);
                   3044:            return (unsigned long) ( cp + sizeof *lp + value );
                   3045:     }
                   3046: }
                   3047: 
                   3048: findcall( parentp , p_lowpc , p_highpc )
                   3049:     nltype             *parentp;
                   3050:     unsigned long      p_lowpc;
                   3051:     unsigned long      p_highpc;
                   3052: {
                   3053:     unsigned char      *instructp;
                   3054:     long               length;
                   3055:     nltype             *childp;
                   3056:     operandenum                mode;
                   3057:     operandenum                firstmode;
                   3058:     unsigned long      destpc;
                   3059: 
                   3060:     if ( textspace == 0 ) {
                   3061:        return;
                   3062:     }
                   3063:     if ( p_lowpc < s_lowpc ) {
                   3064:        p_lowpc = s_lowpc;
                   3065:     }
                   3066:     if ( p_highpc > s_highpc ) {
                   3067:        p_highpc = s_highpc;
                   3068:     }
                   3069: #   ifdef DEBUG
                   3070:        if ( debug & CALLDEBUG ) {
                   3071:            printf( "[findcall] %s: 0x%x to 0x%x\n" ,
                   3072:                    parentp -> name , p_lowpc , p_highpc );
                   3073:        }
                   3074: #   endif DEBUG
                   3075:     for (   instructp = textspace + p_lowpc ;
                   3076:            instructp < textspace + p_highpc ;
                   3077:            instructp += length ) {
                   3078:        length = 1;
                   3079:        if ( *instructp == CALLF ) {
                   3080:                /*
                   3081:                 *      maybe a callf, better check it out.
                   3082:                 *      skip the count of the number of arguments.
                   3083:                 */
                   3084: #          ifdef DEBUG
                   3085:                if ( debug & CALLDEBUG ) {
                   3086:                    printf( "[findcall]\t0x%x:callf" , instructp - textspace );
                   3087:                }
                   3088: #          endif DEBUG
                   3089:            firstmode = operandmode( instructp+length );
                   3090:            switch ( firstmode ) {
                   3091:                case literal:
                   3092:                case immediate:
                   3093:                    break;
                   3094:                default:
                   3095:                    goto botched;
                   3096:            }
                   3097:            length += operandlength( instructp+length );
                   3098:            mode = operandmode( instructp + length );
                   3099: #          ifdef DEBUG
                   3100:                if ( debug & CALLDEBUG ) {
                   3101:                    printf( "\tfirst operand is %s", operandname( firstmode ) );
                   3102:                    printf( "\tsecond operand is %s\n" , operandname( mode ) );
                   3103:                }
                   3104: #          endif DEBUG
                   3105:            switch ( mode ) {
                   3106:                case regdef:
                   3107:                case bytedispdef:
                   3108:                case worddispdef:
                   3109:                case longdispdef:
                   3110:                case bytereldef:
                   3111:                case wordreldef:
                   3112:                case longreldef:
                   3113:                        /*
                   3114:                         *      indirect call: call through pointer
                   3115:                         *      either  *d(r)   as a parameter or local
                   3116:                         *              (r)     as a return value
                   3117:                         *              *f      as a global pointer
                   3118:                         *      [are there others that we miss?,
                   3119:                         *       e.g. arrays of pointers to functions???]
                   3120:                         */
                   3121:                    addarc( parentp , &indirectchild , (long) 0 );
                   3122:                    length += operandlength( instructp + length );
                   3123:                    continue;
                   3124:                case byterel:
                   3125:                case wordrel:
                   3126:                case longrel:
                   3127:                        /*
                   3128:                         *      regular pc relative addressing
                   3129:                         *      check that this is the address of 
                   3130:                         *      a function.
                   3131:                         */
                   3132:                    destpc = reladdr( instructp+length )
                   3133:                                - (unsigned long) textspace;
                   3134:                    if ( destpc >= s_lowpc && destpc <= s_highpc ) {
                   3135:                        childp = nllookup( destpc );
                   3136: #                      ifdef DEBUG
                   3137:                            if ( debug & CALLDEBUG ) {
                   3138:                                printf( "[findcall]\tdestpc 0x%x" , destpc );
                   3139:                                printf( " childp->name %s" , childp -> name );
                   3140:                                printf( " childp->value 0x%x\n" ,
                   3141:                                        childp -> value );
                   3142:                            }
                   3143: #                      endif DEBUG
                   3144:                        if ( childp -> value == destpc ) {
                   3145:                                /*
                   3146:                                 *      a hit
                   3147:                                 */
                   3148:                            addarc( parentp , childp , (long) 0 );
                   3149:                            length += operandlength( instructp + length );
                   3150:                            continue;
                   3151:                        }
                   3152:                        goto botched;
                   3153:                    }
                   3154:                        /*
                   3155:                         *      else:
                   3156:                         *      it looked like a callf,
                   3157:                         *      but it wasn't to anywhere.
                   3158:                         */
                   3159:                    goto botched;
                   3160:                default:
                   3161:                botched:
                   3162:                        /*
                   3163:                         *      something funny going on.
                   3164:                         */
                   3165: #                  ifdef DEBUG
                   3166:                        if ( debug & CALLDEBUG ) {
                   3167:                            printf( "[findcall]\tbut it's a botch\n" );
                   3168:                        }
                   3169: #                  endif DEBUG
                   3170:                    length = 1;
                   3171:                    continue;
                   3172:            }
                   3173:        }
                   3174:     }
                   3175: }
                   3176: rddisp:
                   3177:        case worddispdef:
                   3178:        case wordrel:
                   3179:        case wordreldef:
                   3180:            return 3;
                   3181:        case immediate:
                   3182:        case absolute:
                   3183:        case longdisp:
                   3184:        case longdispdef:
                   3185:        case longrel:
                   3186:        case longreldef:
                   3187:            return 5;
                   3188:        case indexed:
                   3189:            return 1+operandlength( modep + 1 );
                   3190:    gprof/gprof.flat   444     22     12        2050  3335276057   7163 
                   3191: 
                   3192: 
                   3193: flat profile:
                   3194: 
                   3195:  %         the percentage of the total running time of the
                   3196: time       program used by this function.
                   3197: 
                   3198: cumulative a running sum of the number of seconds accounted
                   3199:  seconds   for by this function and those listed above it.
                   3200: 
                   3201:  self      the number of seconds accounted for by this
                   3202: seconds    function alone.  This is the major sort for this
                   3203:            listing.
                   3204: 
                   3205: calls      the number of times this function was invoked, if
                   3206:            this function is profiled, else blank.
                   3207:  
                   3208:  self      the average number of milliseconds spent in this
                   3209: ms/call    function per call, if this function is profiled,
                   3210:           else blank.
                   3211: 
                   3212:  total     the average number of milliseconds spent in this
                   3213: ms/call    function and its descendents per call, if this 
                   3214:           function is profiled, else blank.
                   3215: 
                   3216: name       the name of the function.  This is the minor sort
                   3217:            for this listing. The index shows the location of
                   3218:           the function in the gprof listing. If the index is
                   3219:           in parenthesis it shows where it would appear in
                   3220:           the gprof listing if it were to be printed.
                   3221: 
                   3222: all]\tdestpc 0x%x" , destpc );
                   3223:                                printf( " childp->name %s" , childp -> name );
                   3224:                                printf( " childp->value 0x%x\n" ,
                   3225:                                        childp -> value );
                   3226:                            }
                   3227: #                      endif DEBUG
                   3228:                        if ( childp -> value == destpc ) {
                   3229:                                /*
                   3230:                                 *      a hit
                   3231:                                 */
                   3232:                            addarc( parentp , childp , (long) 0 );
                   3233:                            length += operandlength( instructp + length );
                   3234:                            continue;
                   3235:                        }
                   3236:                        goto botched;
                   3237:                    }
                   3238:                        /*
                   3239:                         *      else:
                   3240:                         *      it looked like a callf,
                   3241:                         *      but it wasn't to anywhere.
                   3242:                         */
                   3243:                gprof/vax.h   444     22     12        1711  3500671075   6141 /*
                   3244:  * Copyright (c) 1983 Regents of the University of California.
                   3245:  * All rights reserved.  The Berkeley software License Agreement
                   3246:  * specifies the terms and conditions for redistribution.
                   3247:  *
                   3248:  *     @(#)vax.h       5.1 (Berkeley) 6/4/85
                   3249:  */
                   3250: 
                   3251:     /*
                   3252:      * opcode of the `calls' instruction
                   3253:      */
                   3254: #define        CALLS   0xfb
                   3255: 
                   3256:     /*
                   3257:      * offset (in bytes) of the code from the entry address of a routine.
                   3258:      * (see asgnsamples for use and explanation.)
                   3259:      */
                   3260: #define OFFSET_OF_CODE 2
                   3261: #define        UNITS_TO_CODE   (OFFSET_OF_CODE / sizeof(UNIT))
                   3262: 
                   3263:     /*
                   3264:      * register for pc relative addressing
                   3265:      */
                   3266: #define        PC      0xf
                   3267: 
                   3268: enum opermodes {
                   3269:     literal, indexed, reg, regdef, autodec, autoinc, autoincdef, 
                   3270:     bytedisp, bytedispdef, worddisp, worddispdef, longdisp, longdispdef,
                   3271:     immediate, absolute, byterel, bytereldef, wordrel, wordreldef,
                   3272:     longrel, longreldef
                   3273: };
                   3274: typedef enum opermodes operandenum;
                   3275: 
                   3276: struct modebyte {
                   3277:     unsigned int       regfield:4;
                   3278:     unsigned int       modefield:4;
                   3279: };
                   3280: 
                   3281: gprof/gprof.callg   444     22     12        6303  3002376446   7316 
                   3282: 
                   3283: 
                   3284: call graph profile:
                   3285:           The sum of self and descendents is the major sort
                   3286:           for this listing.
                   3287: 
                   3288:           function entries:
                   3289: 
                   3290: index     the index of the function in the call graph
                   3291:           listing, as an aid to locating it (see below).
                   3292: 
                   3293: %time     the percentage of the total time of the program
                   3294:           accounted for by this function and its
                   3295:           descendents.
                   3296: 
                   3297: self      the number of seconds spent in this function
                   3298:           itself.
                   3299: 
                   3300: descendents
                   3301:           the number of seconds spent in the descendents of
                   3302:           this function on behalf of this function.
                   3303: 
                   3304: called    the number of times this function is called (other
                   3305:           than recursive calls).
                   3306: 
                   3307: self      the number of times this function calls itself
                   3308:           recursively.
                   3309: 
                   3310: name      the name of the function, with an indication of
                   3311:           its membership in a cycle, if any.
                   3312: 
                   3313: index     the index of the function in the call graph
                   3314:           listing, as an aid to locating it.
                   3315: 
                   3316: 
                   3317: 
                   3318:           parent listings:
                   3319: 
                   3320: self*     the number of seconds of this function's self time
                   3321:           which is due to calls from this parent.
                   3322: 
                   3323: descendents*
                   3324:           the number of seconds of this function's
                   3325:           descendent time which is due to calls from this
                   3326:           parent.
                   3327: 
                   3328: called**  the number of times this function is called by
                   3329:           this parent.  This is the numerator of the
                   3330:           fraction which divides up the function's time to
                   3331:           its parents.
                   3332: 
                   3333: total*    the number of times this function was called by
                   3334:           all of its parents.  This is the denominator of
                   3335:           the propagation fraction.
                   3336: 
                   3337: parents   the name of this parent, with an indication of the
                   3338:           parent's membership in a cycle, if any.
                   3339: 
                   3340: index     the index of this parent in the call graph
                   3341:           listing, as an aid in locating it.
                   3342: 
                   3343: 
                   3344: 
                   3345:           children listings:
                   3346: 
                   3347: self*     the number of seconds of this child's self time
                   3348:           which is due to being called by this function.
                   3349: 
                   3350: descendent*
                   3351:           the number of seconds of this child's descendent's
                   3352:           time which is due to being called by this
                   3353:           function.
                   3354: 
                   3355: called**  the number of times this child is called by this
                   3356:           function.  This is the numerator of the
                   3357:           propagation fraction for this child.
                   3358: 
                   3359: total*    the number of times this child is called by all
                   3360:           functions.  This is the denominator of the
                   3361:           propagation fraction.
                   3362: 
                   3363: children  the name of this child, and an indication of its
                   3364:           membership in a cycle, if any.
                   3365: 
                   3366: index     the index of this child in the call graph listing,
                   3367:           as an aid to locating it.
                   3368: 
                   3369: 
                   3370: 
                   3371:           * these fields are omitted for parents (or
                   3372:           children) in the same cycle as the function.  If
                   3373:           the function (or child) is a member of a cycle,
                   3374:           the propagated times and propagation denominator
                   3375:           represent the self time and descendent time of the
                   3376:           cycle as a whole.
                   3377: 
                   3378:           ** static-only parents and children are indicated
                   3379:           by a call count of 0.
                   3380: 
                   3381: 
                   3382: 
                   3383:           cycle listings:
                   3384:           the cycle as a whole is listed with the same
                   3385:           fields as a function entry.  Below it are listed
                   3386:           the members of the cycle, and their contributions
                   3387:           to the time and call counts of the cycle.
                   3388: 
                   3389: om this
                   3390:           parent.
                   3391: 
                   3392: called**  the number of times this function is called by
                   3393:           this parent.  This is the numerator of the
                   3394:           fraction which divides up the function's time to
                   3395:           its parents.
                   3396: 
                   3397: total*    the number of times this function was called by
                   3398:           all of its parents.  This is gprof/tahoe.h   444     22     12        1253  3610153710   6435 /*      tahoe.h 1.1     86/01/07        */
                   3399: 
                   3400:     /*
                   3401:      * opcode of the `callf' instruction
                   3402:      */
                   3403: #define        CALLF   0xfe
                   3404: 
                   3405:     /*
                   3406:      * offset (in bytes) of the code from the entry address of a routine.
                   3407:      * (see asgnsamples for use and explanation.)
                   3408:      */
                   3409: #define OFFSET_OF_CODE 2
                   3410: #define        UNITS_TO_CODE   (OFFSET_OF_CODE / sizeof(UNIT))
                   3411: 
                   3412:     /*
                   3413:      * register for pc relative addressing
                   3414:      */
                   3415: #define        PC      0xf
                   3416: 
                   3417: enum opermodes {
                   3418:     literal, indexed, reg, regdef, autodec, autoinc, autoincdef, 
                   3419:     bytedisp, bytedispdef, worddisp, worddispdef, longdisp, longdispdef,
                   3420:     immediate, absolute, byterel, bytereldef, wordrel, wordreldef,
                   3421:     longrel, longreldef
                   3422: };
                   3423: typedef enum opermodes operandenum;
                   3424: gprof/vax.c   444     22     12       16774  3610154261   6166 /*
                   3425:  * Copyright (c) 1983 Regents of the University of California.
                   3426:  * All rights reserved.  The Berkeley software License Agreement
                   3427:  * specifies the terms and conditions for redistribution.
                   3428:  */
                   3429: 
                   3430: #ifndef lint
                   3431: static char sccsid[] = "@(#)vax.c      5.3 (Berkeley) 1/7/86";
                   3432: #endif not lint
                   3433: 
                   3434: #include       "gprof.h"
                   3435: 
                   3436:     /*
                   3437:      * a namelist entry to be the child of indirect calls
                   3438:      */
                   3439: nltype indirectchild = {
                   3440:        "(*)" ,                         /* the name */
                   3441:        (unsigned long) 0 ,             /* the pc entry point */
                   3442:        (unsigned long) 0 ,             /* entry point aligned to histogram */
                   3443:        (double) 0.0 ,                  /* ticks in this routine */
                   3444:        (double) 0.0 ,                  /* cumulative ticks in children */
                   3445:        (long) 0 ,                      /* how many times called */
                   3446:        (long) 0 ,                      /* how many calls to self */
                   3447:        (double) 1.0 ,                  /* propagation fraction */
                   3448:        (double) 0.0 ,                  /* self propagation time */
                   3449:        (double) 0.0 ,                  /* child propagation time */
                   3450:        (bool) 0 ,                      /* print flag */
                   3451:        (int) 0 ,                       /* index in the graph list */
                   3452:        (int) 0 ,                       /* graph call chain top-sort order */
                   3453:        (int) 0 ,                       /* internal number of cycle on */
                   3454:        (struct nl *) &indirectchild ,  /* pointer to head of cycle */
                   3455:        (struct nl *) 0 ,               /* pointer to next member of cycle */
                   3456:        (arctype *) 0 ,                 /* list of caller arcs */
                   3457:        (arctype *) 0                   /* list of callee arcs */
                   3458:     };
                   3459: 
                   3460: operandenum
                   3461: operandmode( modep )
                   3462:     struct modebyte    *modep;
                   3463: {
                   3464:     long       usesreg = modep -> regfield;
                   3465:     
                   3466:     switch ( modep -> modefield ) {
                   3467:        case 0:
                   3468:        case 1:
                   3469:        case 2:
                   3470:        case 3:
                   3471:            return literal;
                   3472:        case 4:
                   3473:            return indexed;
                   3474:        case 5:
                   3475:            return reg;
                   3476:        case 6:
                   3477:            return regdef;
                   3478:        case 7:
                   3479:            return autodec;
                   3480:        case 8:
                   3481:            return ( usesreg != PC ? autoinc : immediate );
                   3482:        case 9:
                   3483:            return ( usesreg != PC ? autoincdef : absolute );
                   3484:        case 10:
                   3485:            return ( usesreg != PC ? bytedisp : byterel );
                   3486:        case 11:
                   3487:            return ( usesreg != PC ? bytedispdef : bytereldef );
                   3488:        case 12:
                   3489:            return ( usesreg != PC ? worddisp : wordrel );
                   3490:        case 13:
                   3491:            return ( usesreg != PC ? worddispdef : wordreldef );
                   3492:        case 14:
                   3493:            return ( usesreg != PC ? longdisp : longrel );
                   3494:        case 15:
                   3495:            return ( usesreg != PC ? longdispdef : longreldef );
                   3496:     }
                   3497:     /* NOTREACHED */
                   3498: }
                   3499: 
                   3500: char *
                   3501: operandname( mode )
                   3502:     operandenum        mode;
                   3503: {
                   3504:     
                   3505:     switch ( mode ) {
                   3506:        case literal:
                   3507:            return "literal";
                   3508:        case indexed:
                   3509:            return "indexed";
                   3510:        case reg:
                   3511:            return "register";
                   3512:        case regdef:
                   3513:            return "register deferred";
                   3514:        case autodec:
                   3515:            return "autodecrement";
                   3516:        case autoinc:
                   3517:            return "autoincrement";
                   3518:        case autoincdef:
                   3519:            return "autoincrement deferred";
                   3520:        case bytedisp:
                   3521:            return "byte displacement";
                   3522:        case bytedispdef:
                   3523:            return "byte displacement deferred";
                   3524:        case byterel:
                   3525:            return "byte relative";
                   3526:        case bytereldef:
                   3527:            return "byte relative deferred";
                   3528:        case worddisp:
                   3529:            return "word displacement";
                   3530:        case worddispdef:
                   3531:            return "word displacement deferred";
                   3532:        case wordrel:
                   3533:            return "word relative";
                   3534:        case wordreldef:
                   3535:            return "word relative deferred";
                   3536:        case immediate:
                   3537:            return "immediate";
                   3538:        case absolute:
                   3539:            return "absolute";
                   3540:        case longdisp:
                   3541:            return "long displacement";
                   3542:        case longdispdef:
                   3543:            return "long displacement deferred";
                   3544:        case longrel:
                   3545:            return "long relative";
                   3546:        case longreldef:
                   3547:            return "long relative deferred";
                   3548:     }
                   3549:     /* NOTREACHED */
                   3550: }
                   3551: 
                   3552: long
                   3553: operandlength( modep )
                   3554:     struct modebyte    *modep;
                   3555: {
                   3556:     
                   3557:     switch ( operandmode( modep ) ) {
                   3558:        case literal:
                   3559:        case reg:
                   3560:        case regdef:
                   3561:        case autodec:
                   3562:        case autoinc:
                   3563:        case autoincdef:
                   3564:            return 1;
                   3565:        case bytedisp:
                   3566:        case bytedispdef:
                   3567:        case byterel:
                   3568:        case bytereldef:
                   3569:            return 2;
                   3570:        case worddisp:
                   3571:        case worddispdef:
                   3572:        case wordrel:
                   3573:        case wordreldef:
                   3574:            return 3;
                   3575:        case immediate:
                   3576:        case absolute:
                   3577:        case longdisp:
                   3578:        case longdispdef:
                   3579:        case longrel:
                   3580:        case longreldef:
                   3581:            return 5;
                   3582:        case indexed:
                   3583:            return 1+operandlength( (struct modebyte *) ((char *) modep) + 1 );
                   3584:     }
                   3585:     /* NOTREACHED */
                   3586: }
                   3587: 
                   3588: unsigned long
                   3589: reladdr( modep )
                   3590:     struct modebyte    *modep;
                   3591: {
                   3592:     operandenum        mode = operandmode( modep );
                   3593:     char       *cp;
                   3594:     short      *sp;
                   3595:     long       *lp;
                   3596: 
                   3597:     cp = (char *) modep;
                   3598:     cp += 1;                   /* skip over the mode */
                   3599:     switch ( mode ) {
                   3600:        default:
                   3601:            fprintf( stderr , "[reladdr] not relative address\n" );
                   3602:            return (unsigned long) modep;
                   3603:        case byterel:
                   3604:            return (unsigned long) ( cp + sizeof *cp + *cp );
                   3605:        case wordrel:
                   3606:            sp = (short *) cp;
                   3607:            return (unsigned long) ( cp + sizeof *sp + *sp );
                   3608:        case longrel:
                   3609:            lp = (long *) cp;
                   3610:            return (unsigned long) ( cp + sizeof *lp + *lp );
                   3611:     }
                   3612: }
                   3613: 
                   3614: findcall( parentp , p_lowpc , p_highpc )
                   3615:     nltype             *parentp;
                   3616:     unsigned long      p_lowpc;
                   3617:     unsigned long      p_highpc;
                   3618: {
                   3619:     unsigned char      *instructp;
                   3620:     long               length;
                   3621:     nltype             *childp;
                   3622:     operandenum                mode;
                   3623:     operandenum                firstmode;
                   3624:     unsigned long      destpc;
                   3625: 
                   3626:     if ( textspace == 0 ) {
                   3627:        return;
                   3628:     }
                   3629:     if ( p_lowpc < s_lowpc ) {
                   3630:        p_lowpc = s_lowpc;
                   3631:     }
                   3632:     if ( p_highpc > s_highpc ) {
                   3633:        p_highpc = s_highpc;
                   3634:     }
                   3635: #   ifdef DEBUG
                   3636:        if ( debug & CALLDEBUG ) {
                   3637:            printf( "[findcall] %s: 0x%x to 0x%x\n" ,
                   3638:                    parentp -> name , p_lowpc , p_highpc );
                   3639:        }
                   3640: #   endif DEBUG
                   3641:     for (   instructp = textspace + p_lowpc ;
                   3642:            instructp < textspace + p_highpc ;
                   3643:            instructp += length ) {
                   3644:        length = 1;
                   3645:        if ( *instructp == CALLS ) {
                   3646:                /*
                   3647:                 *      maybe a calls, better check it out.
                   3648:                 *      skip the count of the number of arguments.
                   3649:                 */
                   3650: #          ifdef DEBUG
                   3651:                if ( debug & CALLDEBUG ) {
                   3652:                    printf( "[findcall]\t0x%x:calls" , instructp - textspace );
                   3653:                }
                   3654: #          endif DEBUG
                   3655:            firstmode = operandmode( (struct modebyte *) (instructp+length) );
                   3656:            switch ( firstmode ) {
                   3657:                case literal:
                   3658:                case immediate:
                   3659:                    break;
                   3660:                default:
                   3661:                    goto botched;
                   3662:            }
                   3663:            length += operandlength( (struct modebyte *) (instructp+length) );
                   3664:            mode = operandmode( (struct modebyte *) ( instructp + length ) );
                   3665: #          ifdef DEBUG
                   3666:                if ( debug & CALLDEBUG ) {
                   3667:                    printf( "\tfirst operand is %s", operandname( firstmode ) );
                   3668:                    printf( "\tsecond operand is %s\n" , operandname( mode ) );
                   3669:                }
                   3670: #          endif DEBUG
                   3671:            switch ( mode ) {
                   3672:                case regdef:
                   3673:                case bytedispdef:
                   3674:                case worddispdef:
                   3675:                case longdispdef:
                   3676:                case bytereldef:
                   3677:                case wordreldef:
                   3678:                case longreldef:
                   3679:                        /*
                   3680:                         *      indirect call: call through pointer
                   3681:                         *      either  *d(r)   as a parameter or local
                   3682:                         *              (r)     as a return value
                   3683:                         *              *f      as a global pointer
                   3684:                         *      [are there others that we miss?,
                   3685:                         *       e.g. arrays of pointers to functions???]
                   3686:                         */
                   3687:                    addarc( parentp , &indirectchild , (long) 0 );
                   3688:                    length += operandlength(
                   3689:                                (struct modebyte *) ( instructp + length ) );
                   3690:                    continue;
                   3691:                case byterel:
                   3692:                case wordrel:
                   3693:                case longrel:
                   3694:                        /*
                   3695:                         *      regular pc relative addressing
                   3696:                         *      check that this is the address of 
                   3697:                         *      a function.
                   3698:                         */
                   3699:                    destpc = reladdr( (struct modebyte *) (instructp+length) )
                   3700:                                - (unsigned long) textspace;
                   3701:                    if ( destpc >= s_lowpc && destpc <= s_highpc ) {
                   3702:                        childp = nllookup( destpc );
                   3703: #                      ifdef DEBUG
                   3704:                            if ( debug & CALLDEBUG ) {
                   3705:                                printf( "[findcall]\tdestpc 0x%x" , destpc );
                   3706:                                printf( " childp->name %s" , childp -> name );
                   3707:                                printf( " childp->value 0x%x\n" ,
                   3708:                                        childp -> value );
                   3709:                            }
                   3710: #                      endif DEBUG
                   3711:                        if ( childp -> value == destpc ) {
                   3712:                                /*
                   3713:                                 *      a hit
                   3714:                                 */
                   3715:                            addarc( parentp , childp , (long) 0 );
                   3716:                            length += operandlength( (struct modebyte *)
                   3717:                                            ( instructp + length ) );
                   3718:                            continue;
                   3719:                        }
                   3720:                        goto botched;
                   3721:                    }
                   3722:                        /*
                   3723:                         *      else:
                   3724:                         *      it looked like a calls,
                   3725:                         *      but it wasn't to anywhere.
                   3726:                         */
                   3727:                    goto botched;
                   3728:                default:
                   3729:                botched:
                   3730:                        /*
                   3731:                         *      something funny going on.
                   3732:                         */
                   3733: #                  ifdef DEBUG
                   3734:                        if ( debug & CALLDEBUG ) {
                   3735:                            printf( "[findcall]\tbut it's a botch\n" );
                   3736:                        }
                   3737: #                  endif DEBUG
                   3738:                    length = 1;
                   3739:                    continue;
                   3740:            }
                   3741:        }
                   3742:     }
                   3743: }
                   3744: def:gprof/hp300.h   444     22     12         465  4230222453   6153 /* hp300.h 1.1     88/04/08        */
                   3745: 
                   3746:     /*
                   3747:      * offset (in bytes) of the code from the entry address of a routine.
                   3748:      * (see asgnsamples for use and explanation.)
                   3749:      */
                   3750: #define OFFSET_OF_CODE 0
                   3751: #define        UNITS_TO_CODE   (OFFSET_OF_CODE / sizeof(UNIT))
                   3752: 
                   3753: enum opermodes { dummy };
                   3754: typedef enum opermodes operandenum;
                   3755: �Dhp300.hr3RCS�Emakefile�Fhp300.c�G�gcrt0.hägprof.oåarcs.oædfn.oçlookup.oèhp300.oéhertz.oêprintgprof.ogprof/RCS/   775     14     12           0  4436154436   5547 gprof/RCS/Makefile,v   444     14     12       12541  4341434416   7547 head     1.3;
                   3756: access   ;
                   3757: symbols  ;
                   3758: locks    ; strict;
                   3759: comment  @# @;
                   3760: 
                   3761: 
                   3762: 1.3
                   3763: date     88.04.14.00.19.51;  author lepreau;  state Exp;
                   3764: branches ;
                   3765: next     1.2;
                   3766: 
                   3767: 1.2
                   3768: date     88.04.11.21.50.07;  author donn;  state Exp;
                   3769: branches ;
                   3770: next     1.1;
                   3771: 
                   3772: 1.1
                   3773: date     88.04.08.16.53.49;  author donn;  state Rel;
                   3774: branches 1.1.1.1;
                   3775: next     ;
                   3776: 
                   3777: 1.1.1.1
                   3778: date     88.11.19.20.14.41;  author lepreau;  state Exp;
                   3779: branches ;
                   3780: next     ;
                   3781: 
                   3782: 
                   3783: desc
                   3784: @Makefile for gprof, 4.3a BSD.
                   3785: @
                   3786: 
                   3787: 
                   3788: 1.3
                   3789: log
                   3790: @We don't have a group "bin" yet
                   3791: @
                   3792: text
                   3793: @#
                   3794: # Copyright (c) 1987 Regents of the University of California.
                   3795: # All rights reserved.
                   3796: #
                   3797: # Redistribution and use in source and binary forms are permitted
                   3798: # provided that this notice is preserved and that due credit is given
                   3799: # to the University of California at Berkeley. The name of the University
                   3800: # may not be used to endorse or promote products derived from this
                   3801: # software without specific written prior permission. This software
                   3802: # is provided ``as is'' without express or implied warranty.
                   3803: #
                   3804: #      @@(#)Makefile   5.10 (Berkeley) 1/2/88
                   3805: #
                   3806: CFLAGS=        -O
                   3807: LIBC=  /lib/libc.a
                   3808: HDRS=  gprof.h ${MACHINE}.h
                   3809: SRCS=  gprof.c arcs.c dfn.c lookup.c ${MACHINE}.c hertz.c \
                   3810:        printgprof.c printlist.c
                   3811: OBJS=  gprof.o arcs.o dfn.o lookup.o ${MACHINE}.o hertz.o \
                   3812:        printgprof.o printlist.o
                   3813: LIBDIR=        ../../lib
                   3814: 
                   3815: all: gprof
                   3816: 
                   3817: gprof: ${OBJS} ${LIBC}
                   3818:        ${CC} -o $@@ ${CFLAGS} ${OBJS}
                   3819: 
                   3820: gcrt0.h: FRC
                   3821:        -if [ -r gcrt0.h ] && \
                   3822:                cmp -s gcrt0.h ${LIBDIR}/libc/${MACHINE}/csu/gmon.h; then \
                   3823:                :; \
                   3824:        else \
                   3825:                rm -f gcrt0.h; \
                   3826:                cp ${LIBDIR}/libc/${MACHINE}/csu/gmon.h gcrt0.h; \
                   3827:        fi
                   3828: 
                   3829: clean: FRC
                   3830:        rm -f ${OBJS} core gprof
                   3831: 
                   3832: depend: FRC
                   3833:        mkdep ${CFLAGS} ${SRCS}
                   3834: 
                   3835: install: FRC
                   3836:        install -s -m 755 gprof ${DESTDIR}/usr/ucb/gprof
                   3837:        install -c -m 644 gprof.flat ${DESTDIR}/usr/lib
                   3838:        install -c -m 644 gprof.callg ${DESTDIR}/usr/lib
                   3839: 
                   3840: lint: FRC
                   3841:        lint ${CFLAGS} ${SRCS}
                   3842: 
                   3843: tags: FRC
                   3844:        ctags ${SRCS}
                   3845: 
                   3846: FRC:
                   3847: 
                   3848: # DO NOT DELETE THIS LINE -- mkdep uses it.
                   3849: # DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY.
                   3850: 
                   3851: gprof.o: gprof.c gprof.h /usr/include/stdio.h /usr/include/sys/types.h
                   3852: gprof.o: /usr/include/sys/stat.h /usr/include/a.out.h /usr/include/sys/exec.h
                   3853: gprof.o: gcrt0.h tahoe.h
                   3854: arcs.o: arcs.c gprof.h /usr/include/stdio.h /usr/include/sys/types.h
                   3855: arcs.o: /usr/include/sys/stat.h /usr/include/a.out.h /usr/include/sys/exec.h
                   3856: arcs.o: gcrt0.h tahoe.h
                   3857: dfn.o: dfn.c /usr/include/stdio.h gprof.h /usr/include/stdio.h
                   3858: dfn.o: /usr/include/sys/types.h /usr/include/sys/stat.h /usr/include/a.out.h
                   3859: dfn.o: /usr/include/sys/exec.h gcrt0.h tahoe.h
                   3860: lookup.o: lookup.c gprof.h /usr/include/stdio.h /usr/include/sys/types.h
                   3861: lookup.o: /usr/include/sys/stat.h /usr/include/a.out.h /usr/include/sys/exec.h
                   3862: lookup.o: gcrt0.h tahoe.h
                   3863: tahoe.o: tahoe.c gprof.h /usr/include/stdio.h /usr/include/sys/types.h
                   3864: tahoe.o: /usr/include/sys/stat.h /usr/include/a.out.h /usr/include/sys/exec.h
                   3865: tahoe.o: gcrt0.h tahoe.h
                   3866: hertz.o: hertz.c /usr/include/sys/time.h /usr/include/time.h
                   3867: printgprof.o: printgprof.c gprof.h /usr/include/stdio.h
                   3868: printgprof.o: /usr/include/sys/types.h /usr/include/sys/stat.h
                   3869: printgprof.o: /usr/include/a.out.h /usr/include/sys/exec.h gcrt0.h tahoe.h
                   3870: printlist.o: printlist.c gprof.h /usr/include/stdio.h /usr/include/sys/types.h
                   3871: printlist.o: /usr/include/sys/stat.h /usr/include/a.out.h
                   3872: printlist.o: /usr/include/sys/exec.h gcrt0.h tahoe.h
                   3873: 
                   3874: # IF YOU PUT ANYTHING HERE IT WILL GO AWAY
                   3875: @
                   3876: 
                   3877: 
                   3878: 1.2
                   3879: log
                   3880: @Make it possible to build gprof outside /usr/src.
                   3881: @
                   3882: text
                   3883: @d44 3
                   3884: a46 3
                   3885:        install -s -o bin -g bin -m 755 gprof ${DESTDIR}/usr/ucb/gprof
                   3886:        install -c -o bin -g bin -m 644 gprof.flat ${DESTDIR}/usr/lib
                   3887:        install -c -o bin -g bin -m 644 gprof.callg ${DESTDIR}/usr/lib
                   3888: @
                   3889: 
                   3890: 
                   3891: 1.1
                   3892: log
                   3893: @ucb sid 5.10, 1/2/88.
                   3894: @
                   3895: text
                   3896: @d21 1
                   3897: d30 1
                   3898: a30 1
                   3899:                cmp -s gcrt0.h ../../lib/libc/${MACHINE}/csu/gmon.h; then \
                   3900: d34 1
                   3901: a34 1
                   3902:                cp ../../lib/libc/${MACHINE}/csu/gmon.h gcrt0.h; \
                   3903: @
                   3904: 
                   3905: 
                   3906: 1.1.1.1
                   3907: log
                   3908: @4.3 release, sid 5.2, 6/18/85.
                   3909: The odd placement of this rev is because it got left out earlier.
                   3910: @
                   3911: text
                   3912: @d2 2
                   3913: a3 3
                   3914: # Copyright (c) 1983 Regents of the University of California.
                   3915: # All rights reserved.  The Berkeley software License Agreement
                   3916: # specifies the terms and conditions for redistribution.
                   3917: d5 6
                   3918: a10 1
                   3919: #      @@(#)Makefile   5.2 (Berkeley) 6/18/85
                   3920: d12 9
                   3921: a20 1
                   3922: SCCSID = @@(#)Makefile 5.2 (Berkeley) 6/18/85
                   3923: d22 1
                   3924: a22 3
                   3925: DFLAGS = 
                   3926: CFLAGS = -O ${DFLAGS}
                   3927: LINTFLAGS = -x -a -n ${DFLAGS}
                   3928: d24 2
                   3929: a25 3
                   3930: RM=    /bin/rm -f
                   3931: INSTALL=install
                   3932: PR=pr
                   3933: d27 8
                   3934: a34 5
                   3935: GPROFHDRS =    gprof.h vax.h
                   3936: GPROFSRCS =    gprof.c arcs.c dfn.c lookup.c calls.c hertz.c \
                   3937:                printgprof.c printlist.c
                   3938: GPROFOBJS =    gprof.o arcs.o dfn.o lookup.o calls.o hertz.o \
                   3939:                printgprof.o printlist.o
                   3940: d36 2
                   3941: a37 2
                   3942: gprof: ${GPROFOBJS}
                   3943:        cc -o gprof ${CFLAGS} ${GPROFOBJS}
                   3944: d39 2
                   3945: a40 4
                   3946: install: gprof gprof.flat gprof.callg
                   3947:        install -s -g kmem -m 2755 gprof ${DESTDIR}/usr/ucb/gprof
                   3948:        install -c -m 644 gprof.flat ${DESTDIR}/usr/lib
                   3949:        install -c -m 644 gprof.callg ${DESTDIR}/usr/lib
                   3950: d42 4
                   3951: a45 2
                   3952: clean:
                   3953:        ${RM} ${GPROFOBJS} errs gprof
                   3954: d47 2
                   3955: a48 2
                   3956: gcrt0.h:
                   3957:        cp /usr/src/libc/csu/gcrt0.h gcrt0.h
                   3958: d50 2
                   3959: a51 6
                   3960: print:
                   3961:        @@ ls -l | ${PR}
                   3962:        @@ ${PR} makefile
                   3963:        @@ ${PR} gcrt0.h
                   3964:        @@ ${PR} ${GPROFHDRS} ${GPROFSRCS}
                   3965:        @@ ${PR} gprof.flat gprof.callg
                   3966: d53 1
                   3967: a53 2
                   3968: lint:
                   3969:        lint ${LINTFLAGS} ${DFLAGS} ${GPROFSRCS}
                   3970: d55 27
                   3971: a81 8
                   3972: gprof.o: gprof.c gprof.h vax.h gcrt0.h
                   3973: arcs.o: arcs.c gprof.h vax.h gcrt0.h
                   3974: lookup.o: lookup.c gprof.h vax.h gcrt0.h
                   3975: dfn.o: dfn.c gprof.h vax.h gcrt0.h
                   3976: calls.o: calls.c gprof.h vax.h gcrt0.h
                   3977: hertz.o: gprof.h vax.h hertz.c
                   3978: printgprof.o: printgprof.c gprof.h vax.h gcrt0.h
                   3979: printlist.o: printlist.c gprof.h vax.h gcrt0.h
                   3980: @
                   3981: r/include/sys/stat.h /usr/include/a.out.h
                   3982: dfn.o: /usr/include/sys/exec.h gcrt0.h tahoe.h
                   3983: lookup.o: lookup.c gprof.h /usr/include/stdio.h /usr/include/sys/typesgprof/RCS/arcs.c,v   444     14     12       36636  4341433707   7220 head     1.2;
                   3984: access   ;
                   3985: symbols  ;
                   3986: locks    ; strict;
                   3987: comment  @ * @;
                   3988: 
                   3989: 
                   3990: 1.2
                   3991: date     88.11.19.20.10.46;  author lepreau;  state Exp;
                   3992: branches ;
                   3993: next     1.1;
                   3994: 
                   3995: 1.1
                   3996: date     88.11.19.19.57.28;  author lepreau;  state Rel;
                   3997: branches ;
                   3998: next     ;
                   3999: 
                   4000: 
                   4001: desc
                   4002: @@
                   4003: 
                   4004: 
                   4005: 1.2
                   4006: log
                   4007: @ucb sid 5.3, 1/7/86. Went out in hpbsd 1.0.
                   4008: @
                   4009: text
                   4010: @/*
                   4011:  * Copyright (c) 1983 Regents of the University of California.
                   4012:  * All rights reserved.  The Berkeley software License Agreement
                   4013:  * specifies the terms and conditions for redistribution.
                   4014:  */
                   4015: 
                   4016: #ifndef lint
                   4017: static char sccsid[] = "@@(#)arcs.c    5.3 (Berkeley) 1/7/86";
                   4018: #endif not lint
                   4019: 
                   4020: #include "gprof.h"
                   4021: 
                   4022:     /*
                   4023:      * add (or just increment) an arc
                   4024:      */
                   4025: addarc( parentp , childp , count )
                   4026:     nltype     *parentp;
                   4027:     nltype     *childp;
                   4028:     long       count;
                   4029: {
                   4030:     arctype            *calloc();
                   4031:     arctype            *arcp;
                   4032: 
                   4033: #   ifdef DEBUG
                   4034:        if ( debug & TALLYDEBUG ) {
                   4035:            printf( "[addarc] %d arcs from %s to %s\n" ,
                   4036:                    count , parentp -> name , childp -> name );
                   4037:        }
                   4038: #   endif DEBUG
                   4039:     arcp = arclookup( parentp , childp );
                   4040:     if ( arcp != 0 ) {
                   4041:            /*
                   4042:             *  a hit:  just increment the count.
                   4043:             */
                   4044: #      ifdef DEBUG
                   4045:            if ( debug & TALLYDEBUG ) {
                   4046:                printf( "[tally] hit %d += %d\n" ,
                   4047:                        arcp -> arc_count , count );
                   4048:            }
                   4049: #      endif DEBUG
                   4050:        arcp -> arc_count += count;
                   4051:        return;
                   4052:     }
                   4053:     arcp = calloc( 1 , sizeof *arcp );
                   4054:     arcp -> arc_parentp = parentp;
                   4055:     arcp -> arc_childp = childp;
                   4056:     arcp -> arc_count = count;
                   4057:        /*
                   4058:         *      prepend this child to the children of this parent
                   4059:         */
                   4060:     arcp -> arc_childlist = parentp -> children;
                   4061:     parentp -> children = arcp;
                   4062:        /*
                   4063:         *      prepend this parent to the parents of this child
                   4064:         */
                   4065:     arcp -> arc_parentlist = childp -> parents;
                   4066:     childp -> parents = arcp;
                   4067: }
                   4068: 
                   4069:     /*
                   4070:      * the code below topologically sorts the graph (collapsing cycles),
                   4071:      * and propagates time bottom up and flags top down.
                   4072:      */
                   4073: 
                   4074:     /*
                   4075:      * the topologically sorted name list pointers
                   4076:      */
                   4077: nltype **topsortnlp;
                   4078: 
                   4079: topcmp( npp1 , npp2 )
                   4080:     nltype     **npp1;
                   4081:     nltype     **npp2;
                   4082: {
                   4083:     return (*npp1) -> toporder - (*npp2) -> toporder;
                   4084: }
                   4085: 
                   4086: nltype **
                   4087: doarcs()
                   4088: {
                   4089:     nltype     *parentp, **timesortnlp;
                   4090:     arctype    *arcp;
                   4091:     long       index;
                   4092: 
                   4093:        /*
                   4094:         *      initialize various things:
                   4095:         *          zero out child times.
                   4096:         *          count self-recursive calls.
                   4097:         *          indicate that nothing is on cycles.
                   4098:         */
                   4099:     for ( parentp = nl ; parentp < npe ; parentp++ ) {
                   4100:        parentp -> childtime = 0.0;
                   4101:        arcp = arclookup( parentp , parentp );
                   4102:        if ( arcp != 0 ) {
                   4103:            parentp -> ncall -= arcp -> arc_count;
                   4104:            parentp -> selfcalls = arcp -> arc_count;
                   4105:        } else {
                   4106:            parentp -> selfcalls = 0;
                   4107:        }
                   4108:        parentp -> propfraction = 0.0;
                   4109:        parentp -> propself = 0.0;
                   4110:        parentp -> propchild = 0.0;
                   4111:        parentp -> printflag = FALSE;
                   4112:        parentp -> toporder = DFN_NAN;
                   4113:        parentp -> cycleno = 0;
                   4114:        parentp -> cyclehead = parentp;
                   4115:        parentp -> cnext = 0;
                   4116:        if ( cflag ) {
                   4117:            findcall( parentp , parentp -> value , (parentp+1) -> value );
                   4118:        }
                   4119:     }
                   4120:        /*
                   4121:         *      topologically order things
                   4122:         *      if any node is unnumbered,
                   4123:         *          number it and any of its descendents.
                   4124:         */
                   4125:     for ( parentp = nl ; parentp < npe ; parentp++ ) {
                   4126:        if ( parentp -> toporder == DFN_NAN ) {
                   4127:            dfn( parentp );
                   4128:        }
                   4129:     }
                   4130:        /*
                   4131:         *      link together nodes on the same cycle
                   4132:         */
                   4133:     cyclelink();
                   4134:        /*
                   4135:         *      Sort the symbol table in reverse topological order
                   4136:         */
                   4137:     topsortnlp = (nltype **) calloc( nname , sizeof(nltype *) );
                   4138:     if ( topsortnlp == (nltype **) 0 ) {
                   4139:        fprintf( stderr , "[doarcs] ran out of memory for topo sorting\n" );
                   4140:     }
                   4141:     for ( index = 0 ; index < nname ; index += 1 ) {
                   4142:        topsortnlp[ index ] = &nl[ index ];
                   4143:     }
                   4144:     qsort( topsortnlp , nname , sizeof(nltype *) , topcmp );
                   4145: #   ifdef DEBUG
                   4146:        if ( debug & DFNDEBUG ) {
                   4147:            printf( "[doarcs] topological sort listing\n" );
                   4148:            for ( index = 0 ; index < nname ; index += 1 ) {
                   4149:                printf( "[doarcs] " );
                   4150:                printf( "%d:" , topsortnlp[ index ] -> toporder );
                   4151:                printname( topsortnlp[ index ] );
                   4152:                printf( "\n" );
                   4153:            }
                   4154:        }
                   4155: #   endif DEBUG
                   4156:        /*
                   4157:         *      starting from the topological top,
                   4158:         *      propagate print flags to children.
                   4159:         *      also, calculate propagation fractions.
                   4160:         *      this happens before time propagation
                   4161:         *      since time propagation uses the fractions.
                   4162:         */
                   4163:     doflags();
                   4164:        /*
                   4165:         *      starting from the topological bottom, 
                   4166:         *      propogate children times up to parents.
                   4167:         */
                   4168:     dotime();
                   4169:        /*
                   4170:         *      Now, sort by propself + propchild.
                   4171:         *      sorting both the regular function names
                   4172:         *      and cycle headers.
                   4173:         */
                   4174:     timesortnlp = (nltype **) calloc( nname + ncycle , sizeof(nltype *) );
                   4175:     if ( timesortnlp == (nltype **) 0 ) {
                   4176:        fprintf( stderr , "%s: ran out of memory for sorting\n" , whoami );
                   4177:     }
                   4178:     for ( index = 0 ; index < nname ; index++ ) {
                   4179:        timesortnlp[index] = &nl[index];
                   4180:     }
                   4181:     for ( index = 1 ; index <= ncycle ; index++ ) {
                   4182:        timesortnlp[nname+index-1] = &cyclenl[index];
                   4183:     }
                   4184:     qsort( timesortnlp , nname + ncycle , sizeof(nltype *) , totalcmp );
                   4185:     for ( index = 0 ; index < nname + ncycle ; index++ ) {
                   4186:        timesortnlp[ index ] -> index = index + 1;
                   4187:     }
                   4188:     return( timesortnlp );
                   4189: }
                   4190: 
                   4191: dotime()
                   4192: {
                   4193:     int        index;
                   4194: 
                   4195:     cycletime();
                   4196:     for ( index = 0 ; index < nname ; index += 1 ) {
                   4197:        timepropagate( topsortnlp[ index ] );
                   4198:     }
                   4199: }
                   4200: 
                   4201: timepropagate( parentp )
                   4202:     nltype     *parentp;
                   4203: {
                   4204:     arctype    *arcp;
                   4205:     nltype     *childp;
                   4206:     double     share;
                   4207:     double     propshare;
                   4208: 
                   4209:     if ( parentp -> propfraction == 0.0 ) {
                   4210:        return;
                   4211:     }
                   4212:        /*
                   4213:         *      gather time from children of this parent.
                   4214:         */
                   4215:     for ( arcp = parentp -> children ; arcp ; arcp = arcp -> arc_childlist ) {
                   4216:        childp = arcp -> arc_childp;
                   4217:        if ( arcp -> arc_count == 0 ) {
                   4218:            continue;
                   4219:        }
                   4220:        if ( childp == parentp ) {
                   4221:            continue;
                   4222:        }
                   4223:        if ( childp -> propfraction == 0.0 ) {
                   4224:            continue;
                   4225:        }
                   4226:        if ( childp -> cyclehead != childp ) {
                   4227:            if ( parentp -> cycleno == childp -> cycleno ) {
                   4228:                continue;
                   4229:            }
                   4230:            if ( parentp -> toporder <= childp -> toporder ) {
                   4231:                fprintf( stderr , "[propagate] toporder botches\n" );
                   4232:            }
                   4233:            childp = childp -> cyclehead;
                   4234:        } else {
                   4235:            if ( parentp -> toporder <= childp -> toporder ) {
                   4236:                fprintf( stderr , "[propagate] toporder botches\n" );
                   4237:                continue;
                   4238:            }
                   4239:        }
                   4240:        if ( childp -> ncall == 0 ) {
                   4241:            continue;
                   4242:        }
                   4243:            /*
                   4244:             *  distribute time for this arc
                   4245:             */
                   4246:        arcp -> arc_time = childp -> time
                   4247:                                * ( ( (double) arcp -> arc_count ) /
                   4248:                                    ( (double) childp -> ncall ) );
                   4249:        arcp -> arc_childtime = childp -> childtime
                   4250:                                * ( ( (double) arcp -> arc_count ) /
                   4251:                                    ( (double) childp -> ncall ) );
                   4252:        share = arcp -> arc_time + arcp -> arc_childtime;
                   4253:        parentp -> childtime += share;
                   4254:            /*
                   4255:             *  ( 1 - propfraction ) gets lost along the way
                   4256:             */
                   4257:        propshare = parentp -> propfraction * share;
                   4258:            /*
                   4259:             *  fix things for printing
                   4260:             */
                   4261:        parentp -> propchild += propshare;
                   4262:        arcp -> arc_time *= parentp -> propfraction;
                   4263:        arcp -> arc_childtime *= parentp -> propfraction;
                   4264:            /*
                   4265:             *  add this share to the parent's cycle header, if any.
                   4266:             */
                   4267:        if ( parentp -> cyclehead != parentp ) {
                   4268:            parentp -> cyclehead -> childtime += share;
                   4269:            parentp -> cyclehead -> propchild += propshare;
                   4270:        }
                   4271: #      ifdef DEBUG
                   4272:            if ( debug & PROPDEBUG ) {
                   4273:                printf( "[dotime] child \t" );
                   4274:                printname( childp );
                   4275:                printf( " with %f %f %d/%d\n" ,
                   4276:                        childp -> time , childp -> childtime ,
                   4277:                        arcp -> arc_count , childp -> ncall );
                   4278:                printf( "[dotime] parent\t" );
                   4279:                printname( parentp );
                   4280:                printf( "\n[dotime] share %f\n" , share );
                   4281:            }
                   4282: #      endif DEBUG
                   4283:     }
                   4284: }
                   4285: 
                   4286: cyclelink()
                   4287: {
                   4288:     register nltype    *nlp;
                   4289:     register nltype    *cyclenlp;
                   4290:     int                        cycle;
                   4291:     nltype             *memberp;
                   4292:     arctype            *arcp;
                   4293: 
                   4294:        /*
                   4295:         *      Count the number of cycles, and initialze the cycle lists
                   4296:         */
                   4297:     ncycle = 0;
                   4298:     for ( nlp = nl ; nlp < npe ; nlp++ ) {
                   4299:            /*
                   4300:             *  this is how you find unattached cycles
                   4301:             */
                   4302:        if ( nlp -> cyclehead == nlp && nlp -> cnext != 0 ) {
                   4303:            ncycle += 1;
                   4304:        }
                   4305:     }
                   4306:        /*
                   4307:         *      cyclenl is indexed by cycle number:
                   4308:         *      i.e. it is origin 1, not origin 0.
                   4309:         */
                   4310:     cyclenl = (nltype *) calloc( ncycle + 1 , sizeof( nltype ) );
                   4311:     if ( cyclenl == 0 ) {
                   4312:        fprintf( stderr , "%s: No room for %d bytes of cycle headers\n" ,
                   4313:                whoami , ( ncycle + 1 ) * sizeof( nltype ) );
                   4314:        done();
                   4315:     }
                   4316:        /*
                   4317:         *      now link cycles to true cycleheads,
                   4318:         *      number them, accumulate the data for the cycle
                   4319:         */
                   4320:     cycle = 0;
                   4321:     for ( nlp = nl ; nlp < npe ; nlp++ ) {
                   4322:        if ( !( nlp -> cyclehead == nlp && nlp -> cnext != 0 ) ) {
                   4323:            continue;
                   4324:        }
                   4325:        cycle += 1;
                   4326:        cyclenlp = &cyclenl[cycle];
                   4327:         cyclenlp -> name = 0;          /* the name */
                   4328:         cyclenlp -> value = 0;         /* the pc entry point */
                   4329:         cyclenlp -> time = 0.0;                /* ticks in this routine */
                   4330:         cyclenlp -> childtime = 0.0;   /* cumulative ticks in children */
                   4331:        cyclenlp -> ncall = 0;          /* how many times called */
                   4332:        cyclenlp -> selfcalls = 0;      /* how many calls to self */
                   4333:        cyclenlp -> propfraction = 0.0; /* what % of time propagates */
                   4334:        cyclenlp -> propself = 0.0;     /* how much self time propagates */
                   4335:        cyclenlp -> propchild = 0.0;    /* how much child time propagates */
                   4336:        cyclenlp -> printflag = TRUE;   /* should this be printed? */
                   4337:        cyclenlp -> index = 0;          /* index in the graph list */
                   4338:        cyclenlp -> toporder = DFN_NAN; /* graph call chain top-sort order */
                   4339:        cyclenlp -> cycleno = cycle;    /* internal number of cycle on */
                   4340:        cyclenlp -> cyclehead = cyclenlp;       /* pointer to head of cycle */
                   4341:        cyclenlp -> cnext = nlp;        /* pointer to next member of cycle */
                   4342:        cyclenlp -> parents = 0;        /* list of caller arcs */
                   4343:        cyclenlp -> children = 0;       /* list of callee arcs */
                   4344: #      ifdef DEBUG
                   4345:            if ( debug & CYCLEDEBUG ) {
                   4346:                printf( "[cyclelink] " );
                   4347:                printname( nlp );
                   4348:                printf( " is the head of cycle %d\n" , cycle );
                   4349:            }
                   4350: #      endif DEBUG
                   4351:            /*
                   4352:             *  link members to cycle header
                   4353:             */
                   4354:        for ( memberp = nlp ; memberp ; memberp = memberp -> cnext ) { 
                   4355:            memberp -> cycleno = cycle;
                   4356:            memberp -> cyclehead = cyclenlp;
                   4357:        }
                   4358:            /*
                   4359:             *  count calls from outside the cycle
                   4360:             *  and those among cycle members
                   4361:             */
                   4362:        for ( memberp = nlp ; memberp ; memberp = memberp -> cnext ) {
                   4363:            for ( arcp=memberp->parents ; arcp ; arcp=arcp->arc_parentlist ) {
                   4364:                if ( arcp -> arc_parentp == memberp ) {
                   4365:                    continue;
                   4366:                }
                   4367:                if ( arcp -> arc_parentp -> cycleno == cycle ) {
                   4368:                    cyclenlp -> selfcalls += arcp -> arc_count;
                   4369:                } else {
                   4370:                    cyclenlp -> ncall += arcp -> arc_count;
                   4371:                }
                   4372:            }
                   4373:        }
                   4374:     }
                   4375: }
                   4376: 
                   4377: cycletime()
                   4378: {
                   4379:     int                        cycle;
                   4380:     nltype             *cyclenlp;
                   4381:     nltype             *childp;
                   4382: 
                   4383:     for ( cycle = 1 ; cycle <= ncycle ; cycle += 1 ) {
                   4384:        cyclenlp = &cyclenl[ cycle ];
                   4385:        for ( childp = cyclenlp -> cnext ; childp ; childp = childp -> cnext ) {
                   4386:            if ( childp -> propfraction == 0.0 ) {
                   4387:                    /*
                   4388:                     * all members have the same propfraction except those
                   4389:                     *  that were excluded with -E
                   4390:                     */
                   4391:                continue;
                   4392:            }
                   4393:            cyclenlp -> time += childp -> time;
                   4394:        }
                   4395:        cyclenlp -> propself = cyclenlp -> propfraction * cyclenlp -> time;
                   4396:     }
                   4397: }
                   4398: 
                   4399:     /*
                   4400:      * in one top to bottom pass over the topologically sorted namelist
                   4401:      * propagate:
                   4402:      *         printflag as the union of parents' printflags
                   4403:      *         propfraction as the sum of fractional parents' propfractions
                   4404:      * and while we're here, sum time for functions.
                   4405:      */
                   4406: doflags()
                   4407: {
                   4408:     int                index;
                   4409:     nltype     *childp;
                   4410:     nltype     *oldhead;
                   4411: 
                   4412:     oldhead = 0;
                   4413:     for ( index = nname-1 ; index >= 0 ; index -= 1 ) {
                   4414:        childp = topsortnlp[ index ];
                   4415:            /*
                   4416:             *  if we haven't done this function or cycle,
                   4417:             *  inherit things from parent.
                   4418:             *  this way, we are linear in the number of arcs
                   4419:             *  since we do all members of a cycle (and the cycle itself)
                   4420:             *  as we hit the first member of the cycle.
                   4421:             */
                   4422:        if ( childp -> cyclehead != oldhead ) {
                   4423:            oldhead = childp -> cyclehead;
                   4424:            inheritflags( childp );
                   4425:        }
                   4426: #      ifdef DEBUG
                   4427:            if ( debug & PROPDEBUG ) {
                   4428:                printf( "[doflags] " );
                   4429:                printname( childp );
                   4430:                printf( " inherits printflag %d and propfraction %f\n" ,
                   4431:                        childp -> printflag , childp -> propfraction );
                   4432:            }
                   4433: #      endif DEBUG
                   4434:        if ( ! childp -> printflag ) {
                   4435:                /*
                   4436:                 *      printflag is off
                   4437:                 *      it gets turned on by
                   4438:                 *      being on -f list,
                   4439:                 *      or there not being any -f list and not being on -e list.
                   4440:                 */
                   4441:            if (   onlist( flist , childp -> name )
                   4442:                || ( !fflag && !onlist( elist , childp -> name ) ) ) {
                   4443:                childp -> printflag = TRUE;
                   4444:            }
                   4445:        } else {
                   4446:                /*
                   4447:                 *      this function has printing parents:
                   4448:                 *      maybe someone wants to shut it up
                   4449:                 *      by putting it on -e list.  (but favor -f over -e)
                   4450:                 */
                   4451:            if (  ( !onlist( flist , childp -> name ) )
                   4452:                && onlist( elist , childp -> name ) ) {
                   4453:                childp -> printflag = FALSE;
                   4454:            }
                   4455:        }
                   4456:        if ( childp -> propfraction == 0.0 ) {
                   4457:                /*
                   4458:                 *      no parents to pass time to.
                   4459:                 *      collect time from children if
                   4460:                 *      its on -F list,
                   4461:                 *      or there isn't any -F list and its not on -E list.
                   4462:                 */
                   4463:            if ( onlist( Flist , childp -> name )
                   4464:                || ( !Fflag && !onlist( Elist , childp -> name ) ) ) {
                   4465:                    childp -> propfraction = 1.0;
                   4466:            }
                   4467:        } else {
                   4468:                /*
                   4469:                 *      it has parents to pass time to, 
                   4470:                 *      but maybe someone wants to shut it up
                   4471:                 *      by puttting it on -E list.  (but favor -F over -E)
                   4472:                 */
                   4473:            if (  !onlist( Flist , childp -> name )
                   4474:                && onlist( Elist , childp -> name ) ) {
                   4475:                childp -> propfraction = 0.0;
                   4476:            }
                   4477:        }
                   4478:        childp -> propself = childp -> time * childp -> propfraction;
                   4479:        printtime += childp -> propself;
                   4480: #      ifdef DEBUG
                   4481:            if ( debug & PROPDEBUG ) {
                   4482:                printf( "[doflags] " );
                   4483:                printname( childp );
                   4484:                printf( " ends up with printflag %d and propfraction %f\n" ,
                   4485:                        childp -> printflag , childp -> propfraction );
                   4486:                printf( "time %f propself %f printtime %f\n" ,
                   4487:                        childp -> time , childp -> propself , printtime );
                   4488:            }
                   4489: #      endif DEBUG
                   4490:     }
                   4491: }
                   4492: 
                   4493:     /*
                   4494:      * check if any parent of this child
                   4495:      * (or outside parents of this cycle)
                   4496:      * have their print flags on and set the 
                   4497:      * print flag of the child (cycle) appropriately.
                   4498:      * similarly, deal with propagation fractions from parents.
                   4499:      */
                   4500: inheritflags( childp )
                   4501:     nltype     *childp;
                   4502: {
                   4503:     nltype     *headp;
                   4504:     arctype    *arcp;
                   4505:     nltype     *parentp;
                   4506:     nltype     *memp;
                   4507: 
                   4508:     headp = childp -> cyclehead;
                   4509:     if ( childp == headp ) {
                   4510:            /*
                   4511:             *  just a regular child, check its parents
                   4512:             */
                   4513:        childp -> printflag = FALSE;
                   4514:        childp -> propfraction = 0.0;
                   4515:        for (arcp = childp -> parents ; arcp ; arcp = arcp -> arc_parentlist) {
                   4516:            parentp = arcp -> arc_parentp;
                   4517:            if ( childp == parentp ) {
                   4518:                continue;
                   4519:            }
                   4520:            childp -> printflag |= parentp -> printflag;
                   4521:                /*
                   4522:                 *      if the child was never actually called
                   4523:                 *      (e.g. this arc is static (and all others are, too))
                   4524:                 *      no time propagates along this arc.
                   4525:                 */
                   4526:            if ( childp -> ncall ) {
                   4527:                childp -> propfraction += parentp -> propfraction
                   4528:                                            * ( ( (double) arcp -> arc_count )
                   4529:                                              / ( (double) childp -> ncall ) );
                   4530:            }
                   4531:        }
                   4532:     } else {
                   4533:            /*
                   4534:             *  its a member of a cycle, look at all parents from 
                   4535:             *  outside the cycle
                   4536:             */
                   4537:        headp -> printflag = FALSE;
                   4538:        headp -> propfraction = 0.0;
                   4539:        for ( memp = headp -> cnext ; memp ; memp = memp -> cnext ) {
                   4540:            for (arcp = memp->parents ; arcp ; arcp = arcp->arc_parentlist) {
                   4541:                if ( arcp -> arc_parentp -> cyclehead == headp ) {
                   4542:                    continue;
                   4543:                }
                   4544:                parentp = arcp -> arc_parentp;
                   4545:                headp -> printflag |= parentp -> printflag;
                   4546:                    /*
                   4547:                     *  if the cycle was never actually called
                   4548:                     *  (e.g. this arc is static (and all others are, too))
                   4549:                     *  no time propagates along this arc.
                   4550:                     */
                   4551:                if ( headp -> ncall ) {
                   4552:                    headp -> propfraction += parentp -> propfraction
                   4553:                                            * ( ( (double) arcp -> arc_count )
                   4554:                                              / ( (double) headp -> ncall ) );
                   4555:                }
                   4556:            }
                   4557:        }
                   4558:        for ( memp = headp ; memp ; memp = memp -> cnext ) {
                   4559:            memp -> printflag = headp -> printflag;
                   4560:            memp -> propfraction = headp -> propfraction;
                   4561:        }
                   4562:     }
                   4563: }
                   4564: @
                   4565: 
                   4566: 
                   4567: 1.1
                   4568: log
                   4569: @4.3 release
                   4570: @
                   4571: text
                   4572: @d8 1
                   4573: a8 1
                   4574: static char sccsid[] = "@@(#)arcs.c    5.2 (Berkeley) 6/4/85";
                   4575: d108 1
                   4576: a108 1
                   4577:            findcalls( parentp , parentp -> value , (parentp+1) -> value );
                   4578: @
                   4579: tname( childp );
                   4580:                printf( " inherits printflag %d and propfraction %f\n" ,
                   4581:                        childp -> printflaggprof/RCS/gprof.c,v   444     33     12       42045  4436154434   7377 head     1.4;
                   4582: access   ;
                   4583: symbols  ;
                   4584: locks    ; strict;
                   4585: comment  @ * @;
                   4586: 
                   4587: 
                   4588: 1.4
                   4589: date     89.05.22.22.07.18;  author mike;  state Exp;
                   4590: branches ;
                   4591: next     1.3;
                   4592: 
                   4593: 1.3
                   4594: date     88.11.19.20.20.04;  author lepreau;  state Exp;
                   4595: branches ;
                   4596: next     1.2;
                   4597: 
                   4598: 1.2
                   4599: date     88.11.19.20.18.45;  author lepreau;  state Exp;
                   4600: branches ;
                   4601: next     1.1;
                   4602: 
                   4603: 1.1
                   4604: date     88.11.19.19.57.30;  author lepreau;  state Rel;
                   4605: branches ;
                   4606: next     ;
                   4607: 
                   4608: 
                   4609: desc
                   4610: @@
                   4611: 
                   4612: 
                   4613: 1.4
                   4614: log
                   4615: @added -H option to specify hertz value for machine with alternate
                   4616: profiling timer running at a rate different from the default clock
                   4617: @
                   4618: text
                   4619: @/*
                   4620:  * Copyright (c) 1983 Regents of the University of California.
                   4621:  * All rights reserved.  The Berkeley software License Agreement
                   4622:  * specifies the terms and conditions for redistribution.
                   4623:  */
                   4624: 
                   4625: #ifndef lint
                   4626: char copyright[] =
                   4627: "@@(#) Copyright (c) 1983 Regents of the University of California.\n\
                   4628:  All rights reserved.\n";
                   4629: #endif not lint
                   4630: 
                   4631: #ifndef lint
                   4632: static char sccsid[] = "@@(#)gprof.c   5.3 (Berkeley) 1/2/88";
                   4633: #endif not lint
                   4634: 
                   4635: #include "gprof.h"
                   4636: 
                   4637: char   *whoami = "gprof";
                   4638: 
                   4639:     /*
                   4640:      * things which get -E excluded by default.
                   4641:      */
                   4642: char   *defaultEs[] = { "mcount" , "__mcleanup" , 0 };
                   4643: 
                   4644: main(argc, argv)
                   4645:     int argc;
                   4646:     char **argv;
                   4647: {
                   4648:     char       **sp;
                   4649:     nltype     **timesortnlp;
                   4650: 
                   4651:     --argc;
                   4652:     argv++;
                   4653:     debug = 0;
                   4654:     bflag = TRUE;
                   4655:     while ( *argv != 0 && **argv == '-' ) {
                   4656:        (*argv)++;
                   4657:        switch ( **argv ) {
                   4658:        case 'a':
                   4659:            aflag = TRUE;
                   4660:            break;
                   4661:        case 'b':
                   4662:            bflag = FALSE;
                   4663:            break;
                   4664:        case 'c':
                   4665: #if hp300
                   4666:            fprintf(stderr, "gprof -c isn't supported on hp300s yet\n");
                   4667:            exit(1);
                   4668: #endif
                   4669:            cflag = TRUE;
                   4670:            break;
                   4671:        case 'd':
                   4672:            dflag = TRUE;
                   4673:            (*argv)++;
                   4674:            debug |= atoi( *argv );
                   4675:            debug |= ANYDEBUG;
                   4676: #          ifdef DEBUG
                   4677:                printf("[main] debug = %d\n", debug);
                   4678: #          else not DEBUG
                   4679:                printf("%s: -d ignored\n", whoami);
                   4680: #          endif DEBUG
                   4681:            break;
                   4682:        case 'E':
                   4683:            ++argv;
                   4684:            addlist( Elist , *argv );
                   4685:            Eflag = TRUE;
                   4686:            addlist( elist , *argv );
                   4687:            eflag = TRUE;
                   4688:            break;
                   4689:        case 'e':
                   4690:            addlist( elist , *++argv );
                   4691:            eflag = TRUE;
                   4692:            break;
                   4693:        case 'F':
                   4694:            ++argv;
                   4695:            addlist( Flist , *argv );
                   4696:            Fflag = TRUE;
                   4697:            addlist( flist , *argv );
                   4698:            fflag = TRUE;
                   4699:            break;
                   4700:        case 'f':
                   4701:            addlist( flist , *++argv );
                   4702:            fflag = TRUE;
                   4703:            break;
                   4704:        case 'H':
                   4705:            hz = atoi( *++argv );
                   4706:            if (hz < 0 || hz > 100000) {
                   4707:                fprintf(stderr, "unreasonable HZ value, using default\n");
                   4708:                hz = 0;
                   4709:            }
                   4710:            break;
                   4711:        case 'k':
                   4712:            addlist( kfromlist , *++argv );
                   4713:            addlist( ktolist , *++argv );
                   4714:            kflag = TRUE;
                   4715:            break;
                   4716:        case 's':
                   4717:            sflag = TRUE;
                   4718:            break;
                   4719:        case 'z':
                   4720:            zflag = TRUE;
                   4721:            break;
                   4722:        }
                   4723:        argv++;
                   4724:     }
                   4725:     if ( *argv != 0 ) {
                   4726:        a_outname  = *argv;
                   4727:        argv++;
                   4728:     } else {
                   4729:        a_outname  = A_OUTNAME;
                   4730:     }
                   4731:     if ( *argv != 0 ) {
                   4732:        gmonname = *argv;
                   4733:        argv++;
                   4734:     } else {
                   4735:        gmonname = GMONNAME;
                   4736:     }
                   4737:        /*
                   4738:         *      turn off default functions
                   4739:         */
                   4740:     for ( sp = &defaultEs[0] ; *sp ; sp++ ) {
                   4741:        Eflag = TRUE;
                   4742:        addlist( Elist , *sp );
                   4743:        eflag = TRUE;
                   4744:        addlist( elist , *sp );
                   4745:     }
                   4746:        /*
                   4747:         *      how many ticks per second?
                   4748:         *      if we can't tell, report time in ticks.
                   4749:         */
                   4750:     if (hz == 0)
                   4751:        hz = hertz();
                   4752:     if (hz == 0) {
                   4753:        hz = 1;
                   4754:        fprintf(stderr, "time is in ticks, not seconds\n");
                   4755:     }
                   4756:        /*
                   4757:         *      get information about a.out file.
                   4758:         */
                   4759:     getnfile();
                   4760:        /*
                   4761:         *      get information about mon.out file(s).
                   4762:         */
                   4763:     do {
                   4764:        getpfile( gmonname );
                   4765:        if ( *argv != 0 ) {
                   4766:            gmonname = *argv;
                   4767:        }
                   4768:     } while ( *argv++ != 0 );
                   4769:        /*
                   4770:         *      dump out a gmon.sum file if requested
                   4771:         */
                   4772:     if ( sflag ) {
                   4773:        dumpsum( GMONSUM );
                   4774:     }
                   4775:        /*
                   4776:         *      assign samples to procedures
                   4777:         */
                   4778:     asgnsamples();
                   4779:        /*
                   4780:         *      assemble the dynamic profile
                   4781:         */
                   4782:     timesortnlp = doarcs();
                   4783:        /*
                   4784:         *      print the dynamic profile
                   4785:         */
                   4786:     printgprof( timesortnlp ); 
                   4787:        /*
                   4788:         *      print the flat profile
                   4789:         */
                   4790:     printprof();       
                   4791:        /*
                   4792:         *      print the index
                   4793:         */
                   4794:     printindex();      
                   4795:     done();
                   4796: }
                   4797: 
                   4798:     /*
                   4799:      * Set up string and symbol tables from a.out.
                   4800:      * and optionally the text space.
                   4801:      * On return symbol table is sorted by value.
                   4802:      */
                   4803: getnfile()
                   4804: {
                   4805:     FILE       *nfile;
                   4806:     int                valcmp();
                   4807: 
                   4808:     nfile = fopen( a_outname ,"r");
                   4809:     if (nfile == NULL) {
                   4810:        perror( a_outname );
                   4811:        done();
                   4812:     }
                   4813:     fread(&xbuf, 1, sizeof(xbuf), nfile);
                   4814:     if (N_BADMAG(xbuf)) {
                   4815:        fprintf(stderr, "%s: %s: bad format\n", whoami , a_outname );
                   4816:        done();
                   4817:     }
                   4818:     getstrtab(nfile);
                   4819:     getsymtab(nfile);
                   4820:     gettextspace( nfile );
                   4821:     qsort(nl, nname, sizeof(nltype), valcmp);
                   4822:     fclose(nfile);
                   4823: #   ifdef DEBUG
                   4824:        if ( debug & AOUTDEBUG ) {
                   4825:            register int j;
                   4826: 
                   4827:            for (j = 0; j < nname; j++){
                   4828:                printf("[getnfile] 0X%08x\t%s\n", nl[j].value, nl[j].name);
                   4829:            }
                   4830:        }
                   4831: #   endif DEBUG
                   4832: }
                   4833: 
                   4834: getstrtab(nfile)
                   4835:     FILE       *nfile;
                   4836: {
                   4837: 
                   4838:     fseek(nfile, (long)(N_SYMOFF(xbuf) + xbuf.a_syms), 0);
                   4839:     if (fread(&ssiz, sizeof (ssiz), 1, nfile) == 0) {
                   4840:        fprintf(stderr, "%s: %s: no string table (old format?)\n" ,
                   4841:                whoami , a_outname );
                   4842:        done();
                   4843:     }
                   4844:     strtab = (char *)calloc(ssiz, 1);
                   4845:     if (strtab == NULL) {
                   4846:        fprintf(stderr, "%s: %s: no room for %d bytes of string table",
                   4847:                whoami , a_outname , ssiz);
                   4848:        done();
                   4849:     }
                   4850:     if (fread(strtab+sizeof(ssiz), ssiz-sizeof(ssiz), 1, nfile) != 1) {
                   4851:        fprintf(stderr, "%s: %s: error reading string table\n",
                   4852:                whoami , a_outname );
                   4853:        done();
                   4854:     }
                   4855: }
                   4856: 
                   4857:     /*
                   4858:      * Read in symbol table
                   4859:      */
                   4860: getsymtab(nfile)
                   4861:     FILE       *nfile;
                   4862: {
                   4863:     register long      i;
                   4864:     int                        askfor;
                   4865:     struct nlist       nbuf;
                   4866: 
                   4867:     /* pass1 - count symbols */
                   4868:     fseek(nfile, (long)N_SYMOFF(xbuf), 0);
                   4869:     nname = 0;
                   4870:     for (i = xbuf.a_syms; i > 0; i -= sizeof(struct nlist)) {
                   4871:        fread(&nbuf, sizeof(nbuf), 1, nfile);
                   4872:        if ( ! funcsymbol( &nbuf ) ) {
                   4873:            continue;
                   4874:        }
                   4875:        nname++;
                   4876:     }
                   4877:     if (nname == 0) {
                   4878:        fprintf(stderr, "%s: %s: no symbols\n", whoami , a_outname );
                   4879:        done();
                   4880:     }
                   4881:     askfor = nname + 1;
                   4882:     nl = (nltype *) calloc( askfor , sizeof(nltype) );
                   4883:     if (nl == 0) {
                   4884:        fprintf(stderr, "%s: No room for %d bytes of symbol table\n",
                   4885:                whoami, askfor * sizeof(nltype) );
                   4886:        done();
                   4887:     }
                   4888: 
                   4889:     /* pass2 - read symbols */
                   4890:     fseek(nfile, (long)N_SYMOFF(xbuf), 0);
                   4891:     npe = nl;
                   4892:     nname = 0;
                   4893:     for (i = xbuf.a_syms; i > 0; i -= sizeof(struct nlist)) {
                   4894:        fread(&nbuf, sizeof(nbuf), 1, nfile);
                   4895:        if ( ! funcsymbol( &nbuf ) ) {
                   4896: #          ifdef DEBUG
                   4897:                if ( debug & AOUTDEBUG ) {
                   4898:                    printf( "[getsymtab] rejecting: 0x%x %s\n" ,
                   4899:                            nbuf.n_type , strtab + nbuf.n_un.n_strx );
                   4900:                }
                   4901: #          endif DEBUG
                   4902:            continue;
                   4903:        }
                   4904:        npe->value = nbuf.n_value;
                   4905:        npe->name = strtab+nbuf.n_un.n_strx;
                   4906: #      ifdef DEBUG
                   4907:            if ( debug & AOUTDEBUG ) {
                   4908:                printf( "[getsymtab] %d %s 0x%08x\n" ,
                   4909:                        nname , npe -> name , npe -> value );
                   4910:            }
                   4911: #      endif DEBUG
                   4912:        npe++;
                   4913:        nname++;
                   4914:     }
                   4915:     npe->value = -1;
                   4916: }
                   4917: 
                   4918:     /*
                   4919:      * read in the text space of an a.out file
                   4920:      */
                   4921: gettextspace( nfile )
                   4922:     FILE       *nfile;
                   4923: {
                   4924:     char       *malloc();
                   4925:     
                   4926:     if ( cflag == 0 ) {
                   4927:        return;
                   4928:     }
                   4929:     textspace = (u_char *) malloc( xbuf.a_text );
                   4930:     if ( textspace == 0 ) {
                   4931:        fprintf( stderr , "%s: ran out room for %d bytes of text space:  " ,
                   4932:                        whoami , xbuf.a_text );
                   4933:        fprintf( stderr , "can't do -c\n" );
                   4934:        return;
                   4935:     }
                   4936:     (void) fseek( nfile , N_TXTOFF( xbuf ) , 0 );
                   4937:     if ( fread( textspace , 1 , xbuf.a_text , nfile ) != xbuf.a_text ) {
                   4938:        fprintf( stderr , "%s: couldn't read text space:  " , whoami );
                   4939:        fprintf( stderr , "can't do -c\n" );
                   4940:        free( textspace );
                   4941:        textspace = 0;
                   4942:        return;
                   4943:     }
                   4944: }
                   4945:     /*
                   4946:      * information from a gmon.out file is in two parts:
                   4947:      * an array of sampling hits within pc ranges,
                   4948:      * and the arcs.
                   4949:      */
                   4950: getpfile(filename)
                   4951:     char *filename;
                   4952: {
                   4953:     FILE               *pfile;
                   4954:     FILE               *openpfile();
                   4955:     struct rawarc      arc;
                   4956: 
                   4957:     pfile = openpfile(filename);
                   4958:     readsamples(pfile);
                   4959:        /*
                   4960:         *      the rest of the file consists of
                   4961:         *      a bunch of <from,self,count> tuples.
                   4962:         */
                   4963:     while ( fread( &arc , sizeof arc , 1 , pfile ) == 1 ) {
                   4964: #      ifdef DEBUG
                   4965:            if ( debug & SAMPLEDEBUG ) {
                   4966:                printf( "[getpfile] frompc 0x%x selfpc 0x%x count %d\n" ,
                   4967:                        arc.raw_frompc , arc.raw_selfpc , arc.raw_count );
                   4968:            }
                   4969: #      endif DEBUG
                   4970:            /*
                   4971:             *  add this arc
                   4972:             */
                   4973:        tally( &arc );
                   4974:     }
                   4975:     fclose(pfile);
                   4976: }
                   4977: 
                   4978: FILE *
                   4979: openpfile(filename)
                   4980:     char *filename;
                   4981: {
                   4982:     struct hdr tmp;
                   4983:     FILE       *pfile;
                   4984: 
                   4985:     if((pfile = fopen(filename, "r")) == NULL) {
                   4986:        perror(filename);
                   4987:        done();
                   4988:     }
                   4989:     fread(&tmp, sizeof(struct hdr), 1, pfile);
                   4990:     if ( s_highpc != 0 && ( tmp.lowpc != h.lowpc ||
                   4991:         tmp.highpc != h.highpc || tmp.ncnt != h.ncnt ) ) {
                   4992:        fprintf(stderr, "%s: incompatible with first gmon file\n", filename);
                   4993:        done();
                   4994:     }
                   4995:     h = tmp;
                   4996:     s_lowpc = (unsigned long) h.lowpc;
                   4997:     s_highpc = (unsigned long) h.highpc;
                   4998:     lowpc = (unsigned long)h.lowpc / sizeof(UNIT);
                   4999:     highpc = (unsigned long)h.highpc / sizeof(UNIT);
                   5000:     sampbytes = h.ncnt - sizeof(struct hdr);
                   5001:     nsamples = sampbytes / sizeof (UNIT);
                   5002: #   ifdef DEBUG
                   5003:        if ( debug & SAMPLEDEBUG ) {
                   5004:            printf( "[openpfile] hdr.lowpc 0x%x hdr.highpc 0x%x hdr.ncnt %d\n",
                   5005:                h.lowpc , h.highpc , h.ncnt );
                   5006:            printf( "[openpfile]   s_lowpc 0x%x   s_highpc 0x%x\n" ,
                   5007:                s_lowpc , s_highpc );
                   5008:            printf( "[openpfile]     lowpc 0x%x     highpc 0x%x\n" ,
                   5009:                lowpc , highpc );
                   5010:            printf( "[openpfile] sampbytes %d nsamples %d\n" ,
                   5011:                sampbytes , nsamples );
                   5012:        }
                   5013: #   endif DEBUG
                   5014:     return(pfile);
                   5015: }
                   5016: 
                   5017: tally( rawp )
                   5018:     struct rawarc      *rawp;
                   5019: {
                   5020:     nltype             *parentp;
                   5021:     nltype             *childp;
                   5022: 
                   5023:     parentp = nllookup( rawp -> raw_frompc );
                   5024:     childp = nllookup( rawp -> raw_selfpc );
                   5025:     if ( kflag
                   5026:         && onlist( kfromlist , parentp -> name )
                   5027:         && onlist( ktolist , childp -> name ) ) {
                   5028:        return;
                   5029:     }
                   5030:     childp -> ncall += rawp -> raw_count;
                   5031: #   ifdef DEBUG
                   5032:        if ( debug & TALLYDEBUG ) {
                   5033:            printf( "[tally] arc from %s to %s traversed %d times\n" ,
                   5034:                    parentp -> name , childp -> name , rawp -> raw_count );
                   5035:        }
                   5036: #   endif DEBUG
                   5037:     addarc( parentp , childp , rawp -> raw_count );
                   5038: }
                   5039: 
                   5040: /*
                   5041:  * dump out the gmon.sum file
                   5042:  */
                   5043: dumpsum( sumfile )
                   5044:     char *sumfile;
                   5045: {
                   5046:     register nltype *nlp;
                   5047:     register arctype *arcp;
                   5048:     struct rawarc arc;
                   5049:     FILE *sfile;
                   5050: 
                   5051:     if ( ( sfile = fopen ( sumfile , "w" ) ) == NULL ) {
                   5052:        perror( sumfile );
                   5053:        done();
                   5054:     }
                   5055:     /*
                   5056:      * dump the header; use the last header read in
                   5057:      */
                   5058:     if ( fwrite( &h , sizeof h , 1 , sfile ) != 1 ) {
                   5059:        perror( sumfile );
                   5060:        done();
                   5061:     }
                   5062:     /*
                   5063:      * dump the samples
                   5064:      */
                   5065:     if (fwrite(samples, sizeof (UNIT), nsamples, sfile) != nsamples) {
                   5066:        perror( sumfile );
                   5067:        done();
                   5068:     }
                   5069:     /*
                   5070:      * dump the normalized raw arc information
                   5071:      */
                   5072:     for ( nlp = nl ; nlp < npe ; nlp++ ) {
                   5073:        for ( arcp = nlp -> children ; arcp ; arcp = arcp -> arc_childlist ) {
                   5074:            arc.raw_frompc = arcp -> arc_parentp -> value;
                   5075:            arc.raw_selfpc = arcp -> arc_childp -> value;
                   5076:            arc.raw_count = arcp -> arc_count;
                   5077:            if ( fwrite ( &arc , sizeof arc , 1 , sfile ) != 1 ) {
                   5078:                perror( sumfile );
                   5079:                done();
                   5080:            }
                   5081: #          ifdef DEBUG
                   5082:                if ( debug & SAMPLEDEBUG ) {
                   5083:                    printf( "[dumpsum] frompc 0x%x selfpc 0x%x count %d\n" ,
                   5084:                            arc.raw_frompc , arc.raw_selfpc , arc.raw_count );
                   5085:                }
                   5086: #          endif DEBUG
                   5087:        }
                   5088:     }
                   5089:     fclose( sfile );
                   5090: }
                   5091: 
                   5092: valcmp(p1, p2)
                   5093:     nltype *p1, *p2;
                   5094: {
                   5095:     if ( p1 -> value < p2 -> value ) {
                   5096:        return LESSTHAN;
                   5097:     }
                   5098:     if ( p1 -> value > p2 -> value ) {
                   5099:        return GREATERTHAN;
                   5100:     }
                   5101:     return EQUALTO;
                   5102: }
                   5103: 
                   5104: readsamples(pfile)
                   5105:     FILE       *pfile;
                   5106: {
                   5107:     register i;
                   5108:     UNIT       sample;
                   5109:     
                   5110:     if (samples == 0) {
                   5111:        samples = (UNIT *) calloc(sampbytes, sizeof (UNIT));
                   5112:        if (samples == 0) {
                   5113:            fprintf( stderr , "%s: No room for %d sample pc's\n", 
                   5114:                whoami , sampbytes / sizeof (UNIT));
                   5115:            done();
                   5116:        }
                   5117:     }
                   5118:     for (i = 0; i < nsamples; i++) {
                   5119:        fread(&sample, sizeof (UNIT), 1, pfile);
                   5120:        if (feof(pfile))
                   5121:                break;
                   5122:        samples[i] += sample;
                   5123:     }
                   5124:     if (i != nsamples) {
                   5125:        fprintf(stderr,
                   5126:            "%s: unexpected EOF after reading %d/%d samples\n",
                   5127:                whoami , --i , nsamples );
                   5128:        done();
                   5129:     }
                   5130: }
                   5131: 
                   5132: /*
                   5133:  *     Assign samples to the procedures to which they belong.
                   5134:  *
                   5135:  *     There are three cases as to where pcl and pch can be
                   5136:  *     with respect to the routine entry addresses svalue0 and svalue1
                   5137:  *     as shown in the following diagram.  overlap computes the
                   5138:  *     distance between the arrows, the fraction of the sample
                   5139:  *     that is to be credited to the routine which starts at svalue0.
                   5140:  *
                   5141:  *         svalue0                                         svalue1
                   5142:  *            |                                               |
                   5143:  *            v                                               v
                   5144:  *
                   5145:  *            +-----------------------------------------------+
                   5146:  *            |                                               |
                   5147:  *       |  ->|    |<-         ->|         |<-         ->|    |<-  |
                   5148:  *       |         |             |         |             |         |
                   5149:  *       +---------+             +---------+             +---------+
                   5150:  *
                   5151:  *       ^         ^             ^         ^             ^         ^
                   5152:  *       |         |             |         |             |         |
                   5153:  *      pcl       pch           pcl       pch           pcl       pch
                   5154:  *
                   5155:  *     For the vax we assert that samples will never fall in the first
                   5156:  *     two bytes of any routine, since that is the entry mask,
                   5157:  *     thus we give call alignentries() to adjust the entry points if
                   5158:  *     the entry mask falls in one bucket but the code for the routine
                   5159:  *     doesn't start until the next bucket.  In conjunction with the
                   5160:  *     alignment of routine addresses, this should allow us to have
                   5161:  *     only one sample for every four bytes of text space and never
                   5162:  *     have any overlap (the two end cases, above).
                   5163:  */
                   5164: asgnsamples()
                   5165: {
                   5166:     register int       j;
                   5167:     UNIT               ccnt;
                   5168:     double             time;
                   5169:     unsigned long      pcl, pch;
                   5170:     register int       i;
                   5171:     unsigned long      overlap;
                   5172:     unsigned long      svalue0, svalue1;
                   5173: 
                   5174:     /* read samples and assign to namelist symbols */
                   5175:     scale = highpc - lowpc;
                   5176:     scale /= nsamples;
                   5177:     alignentries();
                   5178:     for (i = 0, j = 1; i < nsamples; i++) {
                   5179:        ccnt = samples[i];
                   5180:        if (ccnt == 0)
                   5181:                continue;
                   5182:        pcl = lowpc + scale * i;
                   5183:        pch = lowpc + scale * (i + 1);
                   5184:        time = ccnt;
                   5185: #      ifdef DEBUG
                   5186:            if ( debug & SAMPLEDEBUG ) {
                   5187:                printf( "[asgnsamples] pcl 0x%x pch 0x%x ccnt %d\n" ,
                   5188:                        pcl , pch , ccnt );
                   5189:            }
                   5190: #      endif DEBUG
                   5191:        totime += time;
                   5192:        for (j = j - 1; j < nname; j++) {
                   5193:            svalue0 = nl[j].svalue;
                   5194:            svalue1 = nl[j+1].svalue;
                   5195:                /*
                   5196:                 *      if high end of tick is below entry address, 
                   5197:                 *      go for next tick.
                   5198:                 */
                   5199:            if (pch < svalue0)
                   5200:                    break;
                   5201:                /*
                   5202:                 *      if low end of tick into next routine,
                   5203:                 *      go for next routine.
                   5204:                 */
                   5205:            if (pcl >= svalue1)
                   5206:                    continue;
                   5207:            overlap = min(pch, svalue1) - max(pcl, svalue0);
                   5208:            if (overlap > 0) {
                   5209: #              ifdef DEBUG
                   5210:                    if (debug & SAMPLEDEBUG) {
                   5211:                        printf("[asgnsamples] (0x%x->0x%x-0x%x) %s gets %f ticks %d overlap\n",
                   5212:                                nl[j].value/sizeof(UNIT), svalue0, svalue1,
                   5213:                                nl[j].name, 
                   5214:                                overlap * time / scale, overlap);
                   5215:                    }
                   5216: #              endif DEBUG
                   5217:                nl[j].time += overlap * time / scale;
                   5218:            }
                   5219:        }
                   5220:     }
                   5221: #   ifdef DEBUG
                   5222:        if (debug & SAMPLEDEBUG) {
                   5223:            printf("[asgnsamples] totime %f\n", totime);
                   5224:        }
                   5225: #   endif DEBUG
                   5226: }
                   5227: 
                   5228: 
                   5229: unsigned long
                   5230: min(a, b)
                   5231:     unsigned long a,b;
                   5232: {
                   5233:     if (a<b)
                   5234:        return(a);
                   5235:     return(b);
                   5236: }
                   5237: 
                   5238: unsigned long
                   5239: max(a, b)
                   5240:     unsigned long a,b;
                   5241: {
                   5242:     if (a>b)
                   5243:        return(a);
                   5244:     return(b);
                   5245: }
                   5246: 
                   5247:     /*
                   5248:      * calculate scaled entry point addresses (to save time in asgnsamples),
                   5249:      * and possibly push the scaled entry points over the entry mask,
                   5250:      * if it turns out that the entry point is in one bucket and the code
                   5251:      * for a routine is in the next bucket.
                   5252:      */
                   5253: alignentries()
                   5254: {
                   5255:     register struct nl *nlp;
                   5256:     unsigned long      bucket_of_entry;
                   5257:     unsigned long      bucket_of_code;
                   5258: 
                   5259:     for (nlp = nl; nlp < npe; nlp++) {
                   5260:        nlp -> svalue = nlp -> value / sizeof(UNIT);
                   5261:        bucket_of_entry = (nlp->svalue - lowpc) / scale;
                   5262:        bucket_of_code = (nlp->svalue + UNITS_TO_CODE - lowpc) / scale;
                   5263:        if (bucket_of_entry < bucket_of_code) {
                   5264: #          ifdef DEBUG
                   5265:                if (debug & SAMPLEDEBUG) {
                   5266:                    printf("[alignentries] pushing svalue 0x%x to 0x%x\n",
                   5267:                            nlp->svalue, nlp->svalue + UNITS_TO_CODE);
                   5268:                }
                   5269: #          endif DEBUG
                   5270:            nlp->svalue += UNITS_TO_CODE;
                   5271:        }
                   5272:     }
                   5273: }
                   5274: 
                   5275: bool
                   5276: funcsymbol( nlistp )
                   5277:     struct nlist       *nlistp;
                   5278: {
                   5279:     extern char        *strtab;        /* string table from a.out */
                   5280:     extern int aflag;          /* if static functions aren't desired */
                   5281:     char       *name;
                   5282: 
                   5283:        /*
                   5284:         *      must be a text symbol,
                   5285:         *      and static text symbols don't qualify if aflag set.
                   5286:         */
                   5287:     if ( ! (  ( nlistp -> n_type == ( N_TEXT | N_EXT ) )
                   5288:           || ( ( nlistp -> n_type == N_TEXT ) && ( aflag == 0 ) ) ) ) {
                   5289:        return FALSE;
                   5290:     }
                   5291:        /*
                   5292:         *      can't have any `funny' characters in name,
                   5293:         *      where `funny' includes  `.', .o file names
                   5294:         *                      and     `$', pascal labels.
                   5295:         */
                   5296:     for ( name = strtab + nlistp -> n_un.n_strx ; *name ; name += 1 ) {
                   5297:        if ( *name == '.' || *name == '$' ) {
                   5298:            return FALSE;
                   5299:        }
                   5300:     }
                   5301:     return TRUE;
                   5302: }
                   5303: 
                   5304: done()
                   5305: {
                   5306: 
                   5307:     exit(0);
                   5308: }
                   5309: @
                   5310: 
                   5311: 
                   5312: 1.3
                   5313: log
                   5314: @orignally done by donn, ifdef'ed on hp300, went out with hpbsd 1.0.
                   5315: date: 88/04/11 21:50:52;  author: donn;  state: Exp;  lines added/del: 4/0
                   5316: It'd take a hell of a lot of work to get gprof -c working, probably not
                   5317: worth the effort.
                   5318: @
                   5319: text
                   5320: @d86 7
                   5321: d132 2
                   5322: a133 1
                   5323:     hz = hertz();
                   5324: @
                   5325: 
                   5326: 
                   5327: 1.2
                   5328: log
                   5329: @ucb sid 5.3, 1/2/88.
                   5330: @
                   5331: text
                   5332: @d47 4
                   5333: @
                   5334: 
                   5335: 
                   5336: 1.1
                   5337: log
                   5338: @4.3 release
                   5339: @
                   5340: text
                   5341: @d14 1
                   5342: a14 1
                   5343: static char sccsid[] = "@@(#)gprof.c   5.1 (Berkeley) 6/4/85";
                   5344: d82 5
                   5345: d176 1
                   5346: d294 1
                   5347: a294 1
                   5348:     unsigned char      *malloc();
                   5349: d299 1
                   5350: a299 1
                   5351:     textspace = malloc( xbuf.a_text );
                   5352: d371 1
                   5353: a371 1
                   5354:     nsamples = sampbytes / sizeof (unsigned UNIT);
                   5355: d395 5
                   5356: d435 1
                   5357: a435 1
                   5358:     if (fwrite(samples, sizeof(unsigned UNIT), nsamples, sfile) != nsamples) {
                   5359: d478 1
                   5360: a478 1
                   5361:     unsigned UNIT      sample;
                   5362: d481 1
                   5363: a481 1
                   5364:        samples = (unsigned UNIT *) calloc(sampbytes, sizeof (unsigned UNIT));
                   5365: d484 1
                   5366: a484 1
                   5367:                whoami , sampbytes / sizeof (unsigned UNIT));
                   5368: d489 1
                   5369: a489 1
                   5370:        fread(&sample, sizeof (unsigned UNIT), 1, pfile);
                   5371: d537 1
                   5372: a537 1
                   5373:     unsigned UNIT      ccnt;
                   5374: @
                   5375: 
                   5376: 
                   5377:     /* read samples and assign to namelist symbols */
                   5378:     scale = highpc - lowpc;
                   5379:     scale /= nsamples;
                   5380:     alignentries();
                   5381:     for (i = 0, j = 1; i < nsamples; i++) {
                   5382:        ccnt = samples[i];
                   5383:        if (ccnt == 0)
                   5384:                continue;
                   5385:        pcl = lowpc + scale * i;
                   5386:        pch = lowpc + scale * (i + 1);
                   5387:        time = ccnt;
                   5388: #      ifdef DEBUG
                   5389:            if ( debug & SAMPLEDEBUG ) {
                   5390:                printf( "[asgnsamples] pcl 0x%x pch 0x%x ccnt %d\n" ,
                   5391:                        pcl , pch , ccnt );
                   5392:            }
                   5393: #      endif DEBUG
                   5394:        totime += time;
                   5395:        for (j = j - 1; j gprof/RCS/gprof.h,v   444     14     12       17117  4341435175   7404 head     1.3;
                   5396: access   ;
                   5397: symbols  ;
                   5398: locks    ; strict;
                   5399: comment  @ * @;
                   5400: 
                   5401: 
                   5402: 1.3
                   5403: date     88.11.19.20.22.09;  author lepreau;  state Exp;
                   5404: branches ;
                   5405: next     1.2;
                   5406: 
                   5407: 1.2
                   5408: date     88.11.19.20.21.29;  author lepreau;  state Exp;
                   5409: branches ;
                   5410: next     1.1;
                   5411: 
                   5412: 1.1
                   5413: date     88.11.19.19.57.31;  author lepreau;  state Rel;
                   5414: branches ;
                   5415: next     ;
                   5416: 
                   5417: 
                   5418: desc
                   5419: @@
                   5420: 
                   5421: 
                   5422: 1.3
                   5423: log
                   5424: @add hp300.h, originally done by Donn on 4/11/88; went out with hpbsd 1.0.
                   5425: @
                   5426: text
                   5427: @/*
                   5428:  * Copyright (c) 1983 Regents of the University of California.
                   5429:  * All rights reserved.  The Berkeley software License Agreement
                   5430:  * specifies the terms and conditions for redistribution.
                   5431:  *
                   5432:  *     @@(#)gprof.h    5.4 (Berkeley) 1/2/88
                   5433:  */
                   5434: 
                   5435: #include <stdio.h>
                   5436: #include <sys/types.h>
                   5437: #include <sys/stat.h>
                   5438: #include <a.out.h>
                   5439: #include "gcrt0.h"
                   5440: 
                   5441: #if vax
                   5442: #   include "vax.h"
                   5443: #endif
                   5444: #if sun
                   5445: #   include "sun.h"
                   5446: #endif
                   5447: #if tahoe
                   5448: #   include "tahoe.h"
                   5449: #endif
                   5450: #if hp300
                   5451: #   include "hp300.h"
                   5452: #endif
                   5453: 
                   5454: 
                   5455:     /*
                   5456:      * who am i, for error messages.
                   5457:      */
                   5458: char   *whoami;
                   5459: 
                   5460:     /*
                   5461:      * booleans
                   5462:      */
                   5463: typedef int    bool;
                   5464: #define        FALSE   0
                   5465: #define        TRUE    1
                   5466: 
                   5467:     /*
                   5468:      * ticks per second
                   5469:      */
                   5470: long   hz;
                   5471: 
                   5472: typedef        u_short UNIT;           /* unit of profiling */
                   5473: char   *a_outname;
                   5474: #define        A_OUTNAME               "a.out"
                   5475: 
                   5476: char   *gmonname;
                   5477: #define        GMONNAME                "gmon.out"
                   5478: #define        GMONSUM                 "gmon.sum"
                   5479: 
                   5480:     /*
                   5481:      * blurbs on the flat and graph profiles.
                   5482:      */
                   5483: #define        FLAT_BLURB      "/usr/lib/gprof.flat"
                   5484: #define        CALLG_BLURB     "/usr/lib/gprof.callg"
                   5485: 
                   5486:     /*
                   5487:      * a constructed arc,
                   5488:      *     with pointers to the namelist entry of the parent and the child,
                   5489:      *     a count of how many times this arc was traversed,
                   5490:      *     and pointers to the next parent of this child and
                   5491:      *         the next child of this parent.
                   5492:      */
                   5493: struct arcstruct {
                   5494:     struct nl          *arc_parentp;   /* pointer to parent's nl entry */
                   5495:     struct nl          *arc_childp;    /* pointer to child's nl entry */
                   5496:     long               arc_count;      /* how calls from parent to child */
                   5497:     double             arc_time;       /* time inherited along arc */
                   5498:     double             arc_childtime;  /* childtime inherited along arc */
                   5499:     struct arcstruct   *arc_parentlist; /* parents-of-this-child list */
                   5500:     struct arcstruct   *arc_childlist; /* children-of-this-parent list */
                   5501: };
                   5502: typedef struct arcstruct       arctype;
                   5503: 
                   5504:     /*
                   5505:      * The symbol table;
                   5506:      * for each external in the specified file we gather
                   5507:      * its address, the number of calls and compute its share of cpu time.
                   5508:      */
                   5509: struct nl {
                   5510:     char               *name;          /* the name */
                   5511:     unsigned long      value;          /* the pc entry point */
                   5512:     unsigned long      svalue;         /* entry point aligned to histograms */
                   5513:     double             time;           /* ticks in this routine */
                   5514:     double             childtime;      /* cumulative ticks in children */
                   5515:     long               ncall;          /* how many times called */
                   5516:     long               selfcalls;      /* how many calls to self */
                   5517:     double             propfraction;   /* what % of time propagates */
                   5518:     double             propself;       /* how much self time propagates */
                   5519:     double             propchild;      /* how much child time propagates */
                   5520:     bool               printflag;      /* should this be printed? */
                   5521:     int                        index;          /* index in the graph list */
                   5522:     int                        toporder;       /* graph call chain top-sort order */
                   5523:     int                        cycleno;        /* internal number of cycle on */
                   5524:     struct nl          *cyclehead;     /* pointer to head of cycle */
                   5525:     struct nl          *cnext;         /* pointer to next member of cycle */
                   5526:     arctype            *parents;       /* list of caller arcs */
                   5527:     arctype            *children;      /* list of callee arcs */
                   5528: };
                   5529: typedef struct nl      nltype;
                   5530: 
                   5531: nltype *nl;                    /* the whole namelist */
                   5532: nltype *npe;                   /* the virtual end of the namelist */
                   5533: int    nname;                  /* the number of function names */
                   5534: 
                   5535:     /*
                   5536:      * flag which marks a nl entry as topologically ``busy''
                   5537:      * flag which marks a nl entry as topologically ``not_numbered''
                   5538:      */
                   5539: #define        DFN_BUSY        -1
                   5540: #define        DFN_NAN         0
                   5541: 
                   5542:     /* 
                   5543:      * namelist entries for cycle headers.
                   5544:      * the number of discovered cycles.
                   5545:      */
                   5546: nltype *cyclenl;               /* cycle header namelist */
                   5547: int    ncycle;                 /* number of cycles discovered */
                   5548: 
                   5549:     /*
                   5550:      * The header on the gmon.out file.
                   5551:      * gmon.out consists of one of these headers,
                   5552:      * and then an array of ncnt samples
                   5553:      * representing the discretized program counter values.
                   5554:      * this should be a struct phdr, but since everything is done
                   5555:      * as UNITs, this is in UNITs too.
                   5556:      */
                   5557: struct hdr {
                   5558:     UNIT       *lowpc;
                   5559:     UNIT       *highpc;
                   5560:     int        ncnt;
                   5561: };
                   5562: 
                   5563: struct hdr     h;
                   5564: 
                   5565: int    debug;
                   5566: 
                   5567:     /*
                   5568:      * Each discretized pc sample has
                   5569:      * a count of the number of samples in its range
                   5570:      */
                   5571: UNIT   *samples;
                   5572: 
                   5573: unsigned long  s_lowpc;        /* lowpc from the profile file */
                   5574: unsigned long  s_highpc;       /* highpc from the profile file */
                   5575: unsigned lowpc, highpc;                /* range profiled, in UNIT's */
                   5576: unsigned sampbytes;            /* number of bytes of samples */
                   5577: int    nsamples;               /* number of samples */
                   5578: double actime;                 /* accumulated time thus far for putprofline */
                   5579: double totime;                 /* total time for all routines */
                   5580: double printtime;              /* total of time being printed */
                   5581: double scale;                  /* scale factor converting samples to pc
                   5582:                                   values: each sample covers scale bytes */
                   5583: char   *strtab;                /* string table in core */
                   5584: off_t  ssiz;                   /* size of the string table */
                   5585: struct exec xbuf;              /* exec header of a.out */
                   5586: unsigned char  *textspace;             /* text space of a.out in core */
                   5587: 
                   5588:     /*
                   5589:      * option flags, from a to z.
                   5590:      */
                   5591: bool   aflag;                          /* suppress static functions */
                   5592: bool   bflag;                          /* blurbs, too */
                   5593: bool   cflag;                          /* discovered call graph, too */
                   5594: bool   dflag;                          /* debugging options */
                   5595: bool   eflag;                          /* specific functions excluded */
                   5596: bool   Eflag;                          /* functions excluded with time */
                   5597: bool   fflag;                          /* specific functions requested */
                   5598: bool   Fflag;                          /* functions requested with time */
                   5599: bool   kflag;                          /* arcs to be deleted */
                   5600: bool   sflag;                          /* sum multiple gmon.out files */
                   5601: bool   zflag;                          /* zero time/called functions, too */
                   5602: 
                   5603:     /*
                   5604:      * structure for various string lists
                   5605:      */
                   5606: struct stringlist {
                   5607:     struct stringlist  *next;
                   5608:     char               *string;
                   5609: };
                   5610: struct stringlist      *elist;
                   5611: struct stringlist      *Elist;
                   5612: struct stringlist      *flist;
                   5613: struct stringlist      *Flist;
                   5614: struct stringlist      *kfromlist;
                   5615: struct stringlist      *ktolist;
                   5616: 
                   5617:     /*
                   5618:      * function declarations
                   5619:      */
                   5620: /*
                   5621:                addarc();
                   5622: */
                   5623: int            arccmp();
                   5624: arctype                *arclookup();
                   5625: /*
                   5626:                asgnsamples();
                   5627:                printblurb();
                   5628:                cyclelink();
                   5629:                dfn();
                   5630: */
                   5631: bool           dfn_busy();
                   5632: /*
                   5633:                dfn_findcycle();
                   5634: */
                   5635: bool           dfn_numbered();
                   5636: /*
                   5637:                dfn_post_visit();
                   5638:                dfn_pre_visit();
                   5639:                dfn_self_cycle();
                   5640: */
                   5641: nltype         **doarcs();
                   5642: /*
                   5643:                done();
                   5644:                findcalls();
                   5645:                flatprofheader();
                   5646:                flatprofline();
                   5647: */
                   5648: bool           funcsymbol();
                   5649: /*
                   5650:                getnfile();
                   5651:                getpfile();
                   5652:                getstrtab();
                   5653:                getsymtab();
                   5654:                gettextspace();
                   5655:                gprofheader();
                   5656:                gprofline();
                   5657:                main();
                   5658: */
                   5659: unsigned long  max();
                   5660: int            membercmp();
                   5661: unsigned long  min();
                   5662: nltype         *nllookup();
                   5663: FILE           *openpfile();
                   5664: long           operandlength();
                   5665: operandenum    operandmode();
                   5666: char           *operandname();
                   5667: /*
                   5668:                printchildren();
                   5669:                printcycle();
                   5670:                printgprof();
                   5671:                printmembers();
                   5672:                printname();
                   5673:                printparents();
                   5674:                printprof();
                   5675:                readsamples();
                   5676: */
                   5677: unsigned long  reladdr();
                   5678: /*
                   5679:                sortchildren();
                   5680:                sortmembers();
                   5681:                sortparents();
                   5682:                tally();
                   5683:                timecmp();
                   5684:                topcmp();
                   5685: */
                   5686: int            totalcmp();
                   5687: /*
                   5688:                valcmp();
                   5689: */
                   5690: 
                   5691: #define        LESSTHAN        -1
                   5692: #define        EQUALTO         0
                   5693: #define        GREATERTHAN     1
                   5694: 
                   5695: #define        DFNDEBUG        1
                   5696: #define        CYCLEDEBUG      2
                   5697: #define        ARCDEBUG        4
                   5698: #define        TALLYDEBUG      8
                   5699: #define        TIMEDEBUG       16
                   5700: #define        SAMPLEDEBUG     32
                   5701: #define        AOUTDEBUG       64
                   5702: #define        CALLDEBUG       128
                   5703: #define        LOOKUPDEBUG     256
                   5704: #define        PROPDEBUG       512
                   5705: #define        ANYDEBUG        1024
                   5706: @
                   5707: 
                   5708: 
                   5709: 1.2
                   5710: log
                   5711: @ucb sid 5.4, 1/2/88.
                   5712: @
                   5713: text
                   5714: @d24 3
                   5715: @
                   5716: 
                   5717: 
                   5718: 1.1
                   5719: log
                   5720: @4.3 release
                   5721: @
                   5722: text
                   5723: @d6 1
                   5724: a6 1
                   5725:  *     @@(#)gprof.h    5.1 (Berkeley) 6/4/85
                   5726: d19 1
                   5727: a19 1
                   5728: #    include "sun.h"
                   5729: d21 3
                   5730: d43 1
                   5731: a43 1
                   5732: typedef        short UNIT;             /* unit of profiling */
                   5733: d50 1
                   5734: a50 1
                   5735:        
                   5736: d142 1
                   5737: a142 1
                   5738: unsigned UNIT  *samples;
                   5739: d170 1
                   5740: d185 2
                   5741: d191 1
                   5742: d193 1
                   5743: d196 1
                   5744: d201 1
                   5745: d203 1
                   5746: d205 1
                   5747: d207 1
                   5748: d211 1
                   5749: d213 1
                   5750: d218 1
                   5751: d220 1
                   5752: d229 1
                   5753: d238 1
                   5754: d247 1
                   5755: d249 1
                   5756: d256 1
                   5757: d258 1
                   5758: d260 1
                   5759: d273 1
                   5760: a273 1
                   5761: #define        CALLSDEBUG      128
                   5762: @
                   5763: */
                   5764: #define        DFN_BUSY        -1
                   5765: #define        DFN_NAN         0
                   5766: 
                   5767:     /* 
                   5768:      * namelist entries for cycle headers.
                   5769:      * the number of discovered cycles.
                   5770:      */
                   5771: nltype *cyclenl;               /* cycle header namelist */
                   5772: int    ncycle;                 /* number of cycles discovered */
                   5773: 
                   5774:     /*
                   5775:      * The header on the gmon.out file.
                   5776:      * gmon.out consists of one of these headers,
                   5777:      * and then an array of ncnt samples
                   5778:      * representing the discretized program counter valuesgprof/RCS/printgprof.c,v   444     14     12       44067  4341433537  10460 head     1.2;
                   5779: access   ;
                   5780: symbols  ;
                   5781: locks    ; strict;
                   5782: comment  @ * @;
                   5783: 
                   5784: 
                   5785: 1.2
                   5786: date     88.11.19.20.08.36;  author lepreau;  state Exp;
                   5787: branches ;
                   5788: next     1.1;
                   5789: 
                   5790: 1.1
                   5791: date     88.11.19.19.57.32;  author lepreau;  state Rel;
                   5792: branches ;
                   5793: next     ;
                   5794: 
                   5795: 
                   5796: desc
                   5797: @@
                   5798: 
                   5799: 
                   5800: 1.2
                   5801: log
                   5802: @ucb sid 5.3, 1/2/88.  went out in hpbsd 1.0
                   5803: @
                   5804: text
                   5805: @/*
                   5806:  * Copyright (c) 1983 Regents of the University of California.
                   5807:  * All rights reserved.  The Berkeley software License Agreement
                   5808:  * specifies the terms and conditions for redistribution.
                   5809:  */
                   5810: 
                   5811: #ifndef lint
                   5812: static char sccsid[] = "@@(#)printgprof.c      5.3 (Berkeley) 1/2/88";
                   5813: #endif not lint
                   5814: 
                   5815: #include "gprof.h"
                   5816: 
                   5817: printprof()
                   5818: {
                   5819:     register nltype    *np;
                   5820:     nltype             **sortednlp;
                   5821:     int                        index, timecmp();
                   5822: 
                   5823:     actime = 0.0;
                   5824:     printf( "\f\n" );
                   5825:     flatprofheader();
                   5826:        /*
                   5827:         *      Sort the symbol table in by time
                   5828:         */
                   5829:     sortednlp = (nltype **) calloc( nname , sizeof(nltype *) );
                   5830:     if ( sortednlp == (nltype **) 0 ) {
                   5831:        fprintf( stderr , "[printprof] ran out of memory for time sorting\n" );
                   5832:     }
                   5833:     for ( index = 0 ; index < nname ; index += 1 ) {
                   5834:        sortednlp[ index ] = &nl[ index ];
                   5835:     }
                   5836:     qsort( sortednlp , nname , sizeof(nltype *) , timecmp );
                   5837:     for ( index = 0 ; index < nname ; index += 1 ) {
                   5838:        np = sortednlp[ index ];
                   5839:        flatprofline( np );
                   5840:     }
                   5841:     actime = 0.0;
                   5842:     cfree( sortednlp );
                   5843: }
                   5844: 
                   5845: timecmp( npp1 , npp2 )
                   5846:     nltype **npp1, **npp2;
                   5847: {
                   5848:     double     timediff;
                   5849:     long       calldiff;
                   5850: 
                   5851:     timediff = (*npp2) -> time - (*npp1) -> time;
                   5852:     if ( timediff > 0.0 )
                   5853:        return 1 ;
                   5854:     if ( timediff < 0.0 )
                   5855:        return -1;
                   5856:     calldiff = (*npp2) -> ncall - (*npp1) -> ncall;
                   5857:     if ( calldiff > 0 )
                   5858:        return 1;
                   5859:     if ( calldiff < 0 )
                   5860:        return -1;
                   5861:     return( strcmp( (*npp1) -> name , (*npp2) -> name ) );
                   5862: }
                   5863: 
                   5864:     /*
                   5865:      * header for flatprofline
                   5866:      */
                   5867: flatprofheader()
                   5868: {
                   5869:     
                   5870:     if ( bflag ) {
                   5871:        printblurb( FLAT_BLURB );
                   5872:     }
                   5873:     printf( "\ngranularity: each sample hit covers %d byte(s)" ,
                   5874:            (long) scale * sizeof(UNIT) );
                   5875:     if ( totime > 0.0 ) {
                   5876:        printf( " for %.2f%% of %.2f seconds\n\n" ,
                   5877:                100.0/totime , totime / hz );
                   5878:     } else {
                   5879:        printf( " no time accumulated\n\n" );
                   5880:            /*
                   5881:             *  this doesn't hurt sinc eall the numerators will be zero.
                   5882:             */
                   5883:        totime = 1.0;
                   5884:     }
                   5885:     printf( "%5.5s %10.10s %8.8s %8.8s %8.8s %8.8s  %-8.8s\n" ,
                   5886:            "%  " , "cumulative" , "self  " , "" , "self  " , "total " , "" );
                   5887:     printf( "%5.5s %10.10s %8.8s %8.8s %8.8s %8.8s  %-8.8s\n" ,
                   5888:            "time" , "seconds " , "seconds" , "calls" ,
                   5889:            "ms/call" , "ms/call" , "name" );
                   5890: }
                   5891: 
                   5892: flatprofline( np )
                   5893:     register nltype    *np;
                   5894: {
                   5895: 
                   5896:     if ( zflag == 0 && np -> ncall == 0 && np -> time == 0 ) {
                   5897:        return;
                   5898:     }
                   5899:     actime += np -> time;
                   5900:     printf( "%5.1f %10.2f %8.2f" ,
                   5901:        100 * np -> time / totime , actime / hz , np -> time / hz );
                   5902:     if ( np -> ncall != 0 ) {
                   5903:        printf( " %8d %8.2f %8.2f  " , np -> ncall ,
                   5904:            1000 * np -> time / hz / np -> ncall ,
                   5905:            1000 * ( np -> time + np -> childtime ) / hz / np -> ncall );
                   5906:     } else {
                   5907:        printf( " %8.8s %8.8s %8.8s  " , "" , "" , "" );
                   5908:     }
                   5909:     printname( np );
                   5910:     printf( "\n" );
                   5911: }
                   5912: 
                   5913: gprofheader()
                   5914: {
                   5915: 
                   5916:     if ( bflag ) {
                   5917:        printblurb( CALLG_BLURB );
                   5918:     }
                   5919:     printf( "\ngranularity: each sample hit covers %d byte(s)" ,
                   5920:            (long) scale * sizeof(UNIT) );
                   5921:     if ( printtime > 0.0 ) {
                   5922:        printf( " for %.2f%% of %.2f seconds\n\n" ,
                   5923:                100.0/printtime , printtime / hz );
                   5924:     } else {
                   5925:        printf( " no time propagated\n\n" );
                   5926:            /*
                   5927:             *  this doesn't hurt, since all the numerators will be 0.0
                   5928:             */
                   5929:        printtime = 1.0;
                   5930:     }
                   5931:     printf( "%6.6s %5.5s %7.7s %11.11s %7.7s/%-7.7s     %-8.8s\n" ,
                   5932:        "" , "" , "" , "" , "called" , "total" , "parents");
                   5933:     printf( "%-6.6s %5.5s %7.7s %11.11s %7.7s+%-7.7s %-8.8s\t%5.5s\n" ,
                   5934:        "index" , "%time" , "self" , "descendents" ,
                   5935:        "called" , "self" , "name" , "index" );
                   5936:     printf( "%6.6s %5.5s %7.7s %11.11s %7.7s/%-7.7s     %-8.8s\n" ,
                   5937:        "" , "" , "" , "" , "called" , "total" , "children");
                   5938:     printf( "\n" );
                   5939: }
                   5940: 
                   5941: gprofline( np )
                   5942:     register nltype    *np;
                   5943: {
                   5944:     char       kirkbuffer[ BUFSIZ ];
                   5945: 
                   5946:     sprintf( kirkbuffer , "[%d]" , np -> index );
                   5947:     printf( "%-6.6s %5.1f %7.2f %11.2f" ,
                   5948:            kirkbuffer ,
                   5949:            100 * ( np -> propself + np -> propchild ) / printtime ,
                   5950:            np -> propself / hz ,
                   5951:            np -> propchild / hz );
                   5952:     if ( ( np -> ncall + np -> selfcalls ) != 0 ) {
                   5953:        printf( " %7d" , np -> ncall );
                   5954:        if ( np -> selfcalls != 0 ) {
                   5955:            printf( "+%-7d " , np -> selfcalls );
                   5956:        } else {
                   5957:            printf( " %7.7s " , "" );
                   5958:        }
                   5959:     } else {
                   5960:        printf( " %7.7s %7.7s " , "" , "" );
                   5961:     }
                   5962:     printname( np );
                   5963:     printf( "\n" );
                   5964: }
                   5965: 
                   5966: printgprof(timesortnlp)
                   5967:     nltype     **timesortnlp;
                   5968: {
                   5969:     int                index;
                   5970:     nltype     *parentp;
                   5971: 
                   5972:        /*
                   5973:         *      Print out the structured profiling list
                   5974:         */
                   5975:     gprofheader();
                   5976:     for ( index = 0 ; index < nname + ncycle ; index ++ ) {
                   5977:        parentp = timesortnlp[ index ];
                   5978:        if ( zflag == 0 &&
                   5979:             parentp -> ncall == 0 &&
                   5980:             parentp -> selfcalls == 0 &&
                   5981:             parentp -> propself == 0 &&
                   5982:             parentp -> propchild == 0 ) {
                   5983:            continue;
                   5984:        }
                   5985:        if ( ! parentp -> printflag ) {
                   5986:            continue;
                   5987:        }
                   5988:        if ( parentp -> name == 0 && parentp -> cycleno != 0 ) {
                   5989:                /*
                   5990:                 *      cycle header
                   5991:                 */
                   5992:            printcycle( parentp );
                   5993:            printmembers( parentp );
                   5994:        } else {
                   5995:            printparents( parentp );
                   5996:            gprofline( parentp );
                   5997:            printchildren( parentp );
                   5998:        }
                   5999:        printf( "\n" );
                   6000:        printf( "-----------------------------------------------\n" );
                   6001:        printf( "\n" );
                   6002:     }
                   6003:     cfree( timesortnlp );
                   6004: }
                   6005: 
                   6006:     /*
                   6007:      * sort by decreasing propagated time
                   6008:      * if times are equal, but one is a cycle header,
                   6009:      *         say that's first (e.g. less, i.e. -1).
                   6010:      * if one's name doesn't have an underscore and the other does,
                   6011:      *         say the one is first.
                   6012:      * all else being equal, sort by names.
                   6013:      */
                   6014: int
                   6015: totalcmp( npp1 , npp2 )
                   6016:     nltype     **npp1;
                   6017:     nltype     **npp2;
                   6018: {
                   6019:     register nltype    *np1 = *npp1;
                   6020:     register nltype    *np2 = *npp2;
                   6021:     double             diff;
                   6022: 
                   6023:     diff =    ( np1 -> propself + np1 -> propchild )
                   6024:            - ( np2 -> propself + np2 -> propchild );
                   6025:     if ( diff < 0.0 )
                   6026:            return 1;
                   6027:     if ( diff > 0.0 )
                   6028:            return -1;
                   6029:     if ( np1 -> name == 0 && np1 -> cycleno != 0 ) 
                   6030:        return -1;
                   6031:     if ( np2 -> name == 0 && np2 -> cycleno != 0 )
                   6032:        return 1;
                   6033:     if ( np1 -> name == 0 )
                   6034:        return -1;
                   6035:     if ( np2 -> name == 0 )
                   6036:        return 1;
                   6037:     if ( *(np1 -> name) != '_' && *(np2 -> name) == '_' )
                   6038:        return -1;
                   6039:     if ( *(np1 -> name) == '_' && *(np2 -> name) != '_' )
                   6040:        return 1;
                   6041:     if ( np1 -> ncall > np2 -> ncall )
                   6042:        return -1;
                   6043:     if ( np1 -> ncall < np2 -> ncall ) 
                   6044:        return 1;
                   6045:     return strcmp( np1 -> name , np2 -> name );
                   6046: }
                   6047: 
                   6048: printparents( childp )
                   6049:     nltype     *childp;
                   6050: {
                   6051:     nltype     *parentp;
                   6052:     arctype    *arcp;
                   6053:     nltype     *cycleheadp;
                   6054: 
                   6055:     if ( childp -> cyclehead != 0 ) {
                   6056:        cycleheadp = childp -> cyclehead;
                   6057:     } else {
                   6058:        cycleheadp = childp;
                   6059:     }
                   6060:     if ( childp -> parents == 0 ) {
                   6061:        printf( "%6.6s %5.5s %7.7s %11.11s %7.7s %7.7s     <spontaneous>\n" ,
                   6062:                "" , "" , "" , "" , "" , "" );
                   6063:        return;
                   6064:     }
                   6065:     sortparents( childp );
                   6066:     for ( arcp = childp -> parents ; arcp ; arcp = arcp -> arc_parentlist ) {
                   6067:        parentp = arcp -> arc_parentp;
                   6068:        if ( childp == parentp ||
                   6069:             ( childp->cycleno != 0 && parentp->cycleno == childp->cycleno ) ) {
                   6070:                /*
                   6071:                 *      selfcall or call among siblings
                   6072:                 */
                   6073:            printf( "%6.6s %5.5s %7.7s %11.11s %7d %7.7s     " ,
                   6074:                    "" , "" , "" , "" ,
                   6075:                    arcp -> arc_count , "" );
                   6076:            printname( parentp );
                   6077:            printf( "\n" );
                   6078:        } else {
                   6079:                /*
                   6080:                 *      regular parent of child
                   6081:                 */
                   6082:            printf( "%6.6s %5.5s %7.2f %11.2f %7d/%-7d     " ,
                   6083:                    "" , "" ,
                   6084:                    arcp -> arc_time / hz , arcp -> arc_childtime / hz ,
                   6085:                    arcp -> arc_count , cycleheadp -> ncall );
                   6086:            printname( parentp );
                   6087:            printf( "\n" );
                   6088:        }
                   6089:     }
                   6090: }
                   6091: 
                   6092: printchildren( parentp )
                   6093:     nltype     *parentp;
                   6094: {
                   6095:     nltype     *childp;
                   6096:     arctype    *arcp;
                   6097: 
                   6098:     sortchildren( parentp );
                   6099:     arcp = parentp -> children;
                   6100:     for ( arcp = parentp -> children ; arcp ; arcp = arcp -> arc_childlist ) {
                   6101:        childp = arcp -> arc_childp;
                   6102:        if ( childp == parentp ||
                   6103:            ( childp->cycleno != 0 && childp->cycleno == parentp->cycleno ) ) {
                   6104:                /*
                   6105:                 *      self call or call to sibling
                   6106:                 */
                   6107:            printf( "%6.6s %5.5s %7.7s %11.11s %7d %7.7s     " ,
                   6108:                    "" , "" , "" , "" , arcp -> arc_count , "" );
                   6109:            printname( childp );
                   6110:            printf( "\n" );
                   6111:        } else {
                   6112:                /*
                   6113:                 *      regular child of parent
                   6114:                 */
                   6115:            printf( "%6.6s %5.5s %7.2f %11.2f %7d/%-7d     " ,
                   6116:                    "" , "" ,
                   6117:                    arcp -> arc_time / hz , arcp -> arc_childtime / hz ,
                   6118:                    arcp -> arc_count , childp -> cyclehead -> ncall );
                   6119:            printname( childp );
                   6120:            printf( "\n" );
                   6121:        }
                   6122:     }
                   6123: }
                   6124: 
                   6125: printname( selfp )
                   6126:     nltype     *selfp;
                   6127: {
                   6128: 
                   6129:     if ( selfp -> name != 0 ) {
                   6130:        printf( "%s" , selfp -> name );
                   6131: #      ifdef DEBUG
                   6132:            if ( debug & DFNDEBUG ) {
                   6133:                printf( "{%d} " , selfp -> toporder );
                   6134:            }
                   6135:            if ( debug & PROPDEBUG ) {
                   6136:                printf( "%5.2f%% " , selfp -> propfraction );
                   6137:            }
                   6138: #      endif DEBUG
                   6139:     }
                   6140:     if ( selfp -> cycleno != 0 ) {
                   6141:        printf( " <cycle %d>" , selfp -> cycleno );
                   6142:     }
                   6143:     if ( selfp -> index != 0 ) {
                   6144:        if ( selfp -> printflag ) {
                   6145:            printf( " [%d]" , selfp -> index );
                   6146:        } else {
                   6147:            printf( " (%d)" , selfp -> index );
                   6148:        }
                   6149:     }
                   6150: }
                   6151: 
                   6152: sortchildren( parentp )
                   6153:     nltype     *parentp;
                   6154: {
                   6155:     arctype    *arcp;
                   6156:     arctype    *detachedp;
                   6157:     arctype    sorted;
                   6158:     arctype    *prevp;
                   6159: 
                   6160:        /*
                   6161:         *      unlink children from parent,
                   6162:         *      then insertion sort back on to sorted's children.
                   6163:         *          *arcp       the arc you have detached and are inserting.
                   6164:         *          *detachedp  the rest of the arcs to be sorted.
                   6165:         *          sorted      arc list onto which you insertion sort.
                   6166:         *          *prevp      arc before the arc you are comparing.
                   6167:         */
                   6168:     sorted.arc_childlist = 0;
                   6169:     for (  (arcp = parentp -> children)&&(detachedp = arcp -> arc_childlist);
                   6170:            arcp ;
                   6171:           (arcp = detachedp)&&(detachedp = detachedp -> arc_childlist)) {
                   6172:            /*
                   6173:             *  consider *arcp as disconnected
                   6174:             *  insert it into sorted
                   6175:             */
                   6176:        for (   prevp = &sorted ;
                   6177:                prevp -> arc_childlist ;
                   6178:                prevp = prevp -> arc_childlist ) {
                   6179:            if ( arccmp( arcp , prevp -> arc_childlist ) != LESSTHAN ) {
                   6180:                break;
                   6181:            }
                   6182:        }
                   6183:        arcp -> arc_childlist = prevp -> arc_childlist;
                   6184:        prevp -> arc_childlist = arcp;
                   6185:     }
                   6186:        /*
                   6187:         *      reattach sorted children to parent
                   6188:         */
                   6189:     parentp -> children = sorted.arc_childlist;
                   6190: }
                   6191: 
                   6192: sortparents( childp )
                   6193:     nltype     *childp;
                   6194: {
                   6195:     arctype    *arcp;
                   6196:     arctype    *detachedp;
                   6197:     arctype    sorted;
                   6198:     arctype    *prevp;
                   6199: 
                   6200:        /*
                   6201:         *      unlink parents from child,
                   6202:         *      then insertion sort back on to sorted's parents.
                   6203:         *          *arcp       the arc you have detached and are inserting.
                   6204:         *          *detachedp  the rest of the arcs to be sorted.
                   6205:         *          sorted      arc list onto which you insertion sort.
                   6206:         *          *prevp      arc before the arc you are comparing.
                   6207:         */
                   6208:     sorted.arc_parentlist = 0;
                   6209:     for (  (arcp = childp -> parents)&&(detachedp = arcp -> arc_parentlist);
                   6210:            arcp ;
                   6211:           (arcp = detachedp)&&(detachedp = detachedp -> arc_parentlist)) {
                   6212:            /*
                   6213:             *  consider *arcp as disconnected
                   6214:             *  insert it into sorted
                   6215:             */
                   6216:        for (   prevp = &sorted ;
                   6217:                prevp -> arc_parentlist ;
                   6218:                prevp = prevp -> arc_parentlist ) {
                   6219:            if ( arccmp( arcp , prevp -> arc_parentlist ) != GREATERTHAN ) {
                   6220:                break;
                   6221:            }
                   6222:        }
                   6223:        arcp -> arc_parentlist = prevp -> arc_parentlist;
                   6224:        prevp -> arc_parentlist = arcp;
                   6225:     }
                   6226:        /*
                   6227:         *      reattach sorted arcs to child
                   6228:         */
                   6229:     childp -> parents = sorted.arc_parentlist;
                   6230: }
                   6231: 
                   6232:     /*
                   6233:      * print a cycle header
                   6234:      */
                   6235: printcycle( cyclep )
                   6236:     nltype     *cyclep;
                   6237: {
                   6238:     char       kirkbuffer[ BUFSIZ ];
                   6239: 
                   6240:     sprintf( kirkbuffer , "[%d]" , cyclep -> index );
                   6241:     printf( "%-6.6s %5.1f %7.2f %11.2f %7d" ,
                   6242:            kirkbuffer ,
                   6243:            100 * ( cyclep -> propself + cyclep -> propchild ) / printtime ,
                   6244:            cyclep -> propself / hz ,
                   6245:            cyclep -> propchild / hz ,
                   6246:            cyclep -> ncall );
                   6247:     if ( cyclep -> selfcalls != 0 ) {
                   6248:        printf( "+%-7d" , cyclep -> selfcalls );
                   6249:     } else {
                   6250:        printf( " %7.7s" , "" );
                   6251:     }
                   6252:     printf( " <cycle %d as a whole>\t[%d]\n" ,
                   6253:            cyclep -> cycleno , cyclep -> index );
                   6254: }
                   6255: 
                   6256:     /*
                   6257:      * print the members of a cycle
                   6258:      */
                   6259: printmembers( cyclep )
                   6260:     nltype     *cyclep;
                   6261: {
                   6262:     nltype     *memberp;
                   6263: 
                   6264:     sortmembers( cyclep );
                   6265:     for ( memberp = cyclep -> cnext ; memberp ; memberp = memberp -> cnext ) {
                   6266:        printf( "%6.6s %5.5s %7.2f %11.2f %7d" , 
                   6267:                "" , "" , memberp -> propself / hz , memberp -> propchild / hz ,
                   6268:                memberp -> ncall );
                   6269:        if ( memberp -> selfcalls != 0 ) {
                   6270:            printf( "+%-7d" , memberp -> selfcalls );
                   6271:        } else {
                   6272:            printf( " %7.7s" , "" );
                   6273:        }
                   6274:        printf( "     " );
                   6275:        printname( memberp );
                   6276:        printf( "\n" );
                   6277:     }
                   6278: }
                   6279: 
                   6280:     /*
                   6281:      * sort members of a cycle
                   6282:      */
                   6283: sortmembers( cyclep )
                   6284:     nltype     *cyclep;
                   6285: {
                   6286:     nltype     *todo;
                   6287:     nltype     *doing;
                   6288:     nltype     *prev;
                   6289: 
                   6290:        /*
                   6291:         *      detach cycle members from cyclehead,
                   6292:         *      and insertion sort them back on.
                   6293:         */
                   6294:     todo = cyclep -> cnext;
                   6295:     cyclep -> cnext = 0;
                   6296:     for (  (doing = todo)&&(todo = doing -> cnext);
                   6297:            doing ;
                   6298:           (doing = todo )&&(todo = doing -> cnext )){
                   6299:        for ( prev = cyclep ; prev -> cnext ; prev = prev -> cnext ) {
                   6300:            if ( membercmp( doing , prev -> cnext ) == GREATERTHAN ) {
                   6301:                break;
                   6302:            }
                   6303:        }
                   6304:        doing -> cnext = prev -> cnext;
                   6305:        prev -> cnext = doing;
                   6306:     }
                   6307: }
                   6308: 
                   6309:     /*
                   6310:      * major sort is on propself + propchild,
                   6311:      * next is sort on ncalls + selfcalls.
                   6312:      */
                   6313: int
                   6314: membercmp( this , that )
                   6315:     nltype     *this;
                   6316:     nltype     *that;
                   6317: {
                   6318:     double     thistime = this -> propself + this -> propchild;
                   6319:     double     thattime = that -> propself + that -> propchild;
                   6320:     long       thiscalls = this -> ncall + this -> selfcalls;
                   6321:     long       thatcalls = that -> ncall + that -> selfcalls;
                   6322: 
                   6323:     if ( thistime > thattime ) {
                   6324:        return GREATERTHAN;
                   6325:     }
                   6326:     if ( thistime < thattime ) {
                   6327:        return LESSTHAN;
                   6328:     }
                   6329:     if ( thiscalls > thatcalls ) {
                   6330:        return GREATERTHAN;
                   6331:     }
                   6332:     if ( thiscalls < thatcalls ) {
                   6333:        return LESSTHAN;
                   6334:     }
                   6335:     return EQUALTO;
                   6336: }
                   6337:     /*
                   6338:      * compare two arcs to/from the same child/parent.
                   6339:      * - if one arc is a self arc, it's least.
                   6340:      * - if one arc is within a cycle, it's less than.
                   6341:      * - if both arcs are within a cycle, compare arc counts.
                   6342:      * - if neither arc is within a cycle, compare with
                   6343:      *         arc_time + arc_childtime as major key
                   6344:      *         arc count as minor key
                   6345:      */
                   6346: int
                   6347: arccmp( thisp , thatp )
                   6348:     arctype    *thisp;
                   6349:     arctype    *thatp;
                   6350: {
                   6351:     nltype     *thisparentp = thisp -> arc_parentp;
                   6352:     nltype     *thischildp = thisp -> arc_childp;
                   6353:     nltype     *thatparentp = thatp -> arc_parentp;
                   6354:     nltype     *thatchildp = thatp -> arc_childp;
                   6355:     double     thistime;
                   6356:     double     thattime;
                   6357: 
                   6358: #   ifdef DEBUG
                   6359:        if ( debug & TIMEDEBUG ) {
                   6360:            printf( "[arccmp] " );
                   6361:            printname( thisparentp );
                   6362:            printf( " calls " );
                   6363:            printname ( thischildp );
                   6364:            printf( " %f + %f %d/%d\n" ,
                   6365:                    thisp -> arc_time , thisp -> arc_childtime ,
                   6366:                    thisp -> arc_count , thischildp -> ncall );
                   6367:            printf( "[arccmp] " );
                   6368:            printname( thatparentp );
                   6369:            printf( " calls " );
                   6370:            printname( thatchildp );
                   6371:            printf( " %f + %f %d/%d\n" ,
                   6372:                    thatp -> arc_time , thatp -> arc_childtime ,
                   6373:                    thatp -> arc_count , thatchildp -> ncall );
                   6374:            printf( "\n" );
                   6375:        }
                   6376: #   endif DEBUG
                   6377:     if ( thisparentp == thischildp ) {
                   6378:            /* this is a self call */
                   6379:        return LESSTHAN;
                   6380:     }
                   6381:     if ( thatparentp == thatchildp ) {
                   6382:            /* that is a self call */
                   6383:        return GREATERTHAN;
                   6384:     }
                   6385:     if ( thisparentp -> cycleno != 0 && thischildp -> cycleno != 0 &&
                   6386:        thisparentp -> cycleno == thischildp -> cycleno ) {
                   6387:            /* this is a call within a cycle */
                   6388:        if ( thatparentp -> cycleno != 0 && thatchildp -> cycleno != 0 &&
                   6389:            thatparentp -> cycleno == thatchildp -> cycleno ) {
                   6390:                /* that is a call within the cycle, too */
                   6391:            if ( thisp -> arc_count < thatp -> arc_count ) {
                   6392:                return LESSTHAN;
                   6393:            }
                   6394:            if ( thisp -> arc_count > thatp -> arc_count ) {
                   6395:                return GREATERTHAN;
                   6396:            }
                   6397:            return EQUALTO;
                   6398:        } else {
                   6399:                /* that isn't a call within the cycle */
                   6400:            return LESSTHAN;
                   6401:        }
                   6402:     } else {
                   6403:            /* this isn't a call within a cycle */
                   6404:        if ( thatparentp -> cycleno != 0 && thatchildp -> cycleno != 0 &&
                   6405:            thatparentp -> cycleno == thatchildp -> cycleno ) {
                   6406:                /* that is a call within a cycle */
                   6407:            return GREATERTHAN;
                   6408:        } else {
                   6409:                /* neither is a call within a cycle */
                   6410:            thistime = thisp -> arc_time + thisp -> arc_childtime;
                   6411:            thattime = thatp -> arc_time + thatp -> arc_childtime;
                   6412:            if ( thistime < thattime )
                   6413:                return LESSTHAN;
                   6414:            if ( thistime > thattime )
                   6415:                return GREATERTHAN;
                   6416:            if ( thisp -> arc_count < thatp -> arc_count )
                   6417:                return LESSTHAN;
                   6418:            if ( thisp -> arc_count > thatp -> arc_count )
                   6419:                return GREATERTHAN;
                   6420:            return EQUALTO;
                   6421:        }
                   6422:     }
                   6423: }
                   6424: 
                   6425: printblurb( blurbname )
                   6426:     char       *blurbname;
                   6427: {
                   6428:     FILE       *blurbfile;
                   6429:     int                input;
                   6430: 
                   6431:     blurbfile = fopen( blurbname , "r" );
                   6432:     if ( blurbfile == NULL ) {
                   6433:        perror( blurbname );
                   6434:        return;
                   6435:     }
                   6436:     while ( ( input = getc( blurbfile ) ) != EOF ) {
                   6437:        putchar( input );
                   6438:     }
                   6439:     fclose( blurbfile );
                   6440: }
                   6441: 
                   6442: int
                   6443: namecmp( npp1 , npp2 )
                   6444:     nltype **npp1, **npp2;
                   6445: {
                   6446:     return( strcmp( (*npp1) -> name , (*npp2) -> name ) );
                   6447: }
                   6448: 
                   6449: printindex()
                   6450: {
                   6451:     nltype             **namesortnlp;
                   6452:     register nltype    *nlp;
                   6453:     int                        index, nnames, todo, i, j;
                   6454:     char               peterbuffer[ BUFSIZ ];
                   6455: 
                   6456:        /*
                   6457:         *      Now, sort regular function name alphbetically
                   6458:         *      to create an index.
                   6459:         */
                   6460:     namesortnlp = (nltype **) calloc( nname + ncycle , sizeof(nltype *) );
                   6461:     if ( namesortnlp == (nltype **) 0 ) {
                   6462:        fprintf( stderr , "%s: ran out of memory for sorting\n" , whoami );
                   6463:     }
                   6464:     for ( index = 0 , nnames = 0 ; index < nname ; index++ ) {
                   6465:        if ( zflag == 0 && nl[index].ncall == 0 && nl[index].time == 0 )
                   6466:                continue;
                   6467:        namesortnlp[nnames++] = &nl[index];
                   6468:     }
                   6469:     qsort( namesortnlp , nnames , sizeof(nltype *) , namecmp );
                   6470:     for ( index = 1 , todo = nnames ; index <= ncycle ; index++ ) {
                   6471:        namesortnlp[todo++] = &cyclenl[index];
                   6472:     }
                   6473:     printf( "\f\nIndex by function name\n\n" );
                   6474:     index = ( todo + 2 ) / 3;
                   6475:     for ( i = 0; i < index ; i++ ) {
                   6476:        for ( j = i; j < todo ; j += index ) {
                   6477:            nlp = namesortnlp[ j ];
                   6478:            if ( nlp -> printflag ) {
                   6479:                sprintf( peterbuffer , "[%d]" , nlp -> index );
                   6480:            } else {
                   6481:                sprintf( peterbuffer , "(%d)" , nlp -> index );
                   6482:            }
                   6483:            if ( j < nnames ) {
                   6484:                printf( "%6.6s %-19.19s" , peterbuffer , nlp -> name );
                   6485:            } else {
                   6486:                printf( "%6.6s " , peterbuffer );
                   6487:                sprintf( peterbuffer , "<cycle %d>" , nlp -> cycleno );
                   6488:                printf( "%-19.19s" , peterbuffer );
                   6489:            }
                   6490:        }
                   6491:        printf( "\n" );
                   6492:     }
                   6493:     cfree( namesortnlp );
                   6494: }
                   6495: @
                   6496: 
                   6497: 
                   6498: 1.1
                   6499: log
                   6500: @4.3 release
                   6501: @
                   6502: text
                   6503: @d8 1
                   6504: a8 1
                   6505: static char sccsid[] = "@@(#)printgprof.c      5.1 (Berkeley) 6/4/85";
                   6506: d17 1
                   6507: a17 1
                   6508:     int                        index;
                   6509: d128 1
                   6510: a128 1
                   6511:        "" , "" , "" , "" , "called" , "total" , "parents" , "" );
                   6512: d133 1
                   6513: a133 1
                   6514:        "" , "" , "" , "" , "called" , "total" , "children" , "" );
                   6515: @
                   6516: ame( thisparentp );
                   6517:            printf( " calls " );
                   6518:            printname ( thischildp );
                   6519:            printf( " %f + %f %d/%d\n" ,
                   6520:                    thisp -> arc_time , thisp -> arc_childtime ,
                   6521:                    thisp -> arc_count , thischildp -> ncall );
                   6522:            printf( "[arccmp] " );
                   6523:            printname( thatparentp );
                   6524:            printf( " calls " );
                   6525:            printname( thatchildp );
                   6526:            printf( " %f + %f %d/%d\n" ,
                   6527:                    thatp -> arc_time , thatp -> arc_childtime ,
                   6528:                    thatp -> arc_count , thatchildp -> ncalgprof/RCS/printlist.c,v   444     14     12        4133  4341433623  10260 head     1.2;
                   6529: access   ;
                   6530: symbols  ;
                   6531: locks    ; strict;
                   6532: comment  @ * @;
                   6533: 
                   6534: 
                   6535: 1.2
                   6536: date     88.11.19.20.09.47;  author lepreau;  state Exp;
                   6537: branches ;
                   6538: next     1.1;
                   6539: 
                   6540: 1.1
                   6541: date     88.11.19.19.57.33;  author lepreau;  state Rel;
                   6542: branches ;
                   6543: next     ;
                   6544: 
                   6545: 
                   6546: desc
                   6547: @@
                   6548: 
                   6549: 
                   6550: 1.2
                   6551: log
                   6552: @ucb sid 5.2, 4/27/87.  Went out in hpbsd 1.0.
                   6553: @
                   6554: text
                   6555: @/*
                   6556:  * Copyright (c) 1983 Regents of the University of California.
                   6557:  * All rights reserved.  The Berkeley software License Agreement
                   6558:  * specifies the terms and conditions for redistribution.
                   6559:  */
                   6560: 
                   6561: #ifndef lint
                   6562: static char sccsid[] = "@@(#)printlist.c       5.2 (Berkeley) 4/27/87";
                   6563: #endif not lint
                   6564: 
                   6565: #include "gprof.h"
                   6566: 
                   6567:     /*
                   6568:      * these are the lists of names:
                   6569:      * there is the list head and then the listname
                   6570:      * is a pointer to the list head
                   6571:      * (for ease of passing to stringlist functions).
                   6572:      */
                   6573: struct stringlist      kfromhead = { 0 , 0 };
                   6574: struct stringlist      *kfromlist = &kfromhead;
                   6575: struct stringlist      ktohead = { 0 , 0 };
                   6576: struct stringlist      *ktolist = &ktohead;
                   6577: struct stringlist      fhead = { 0 , 0 };
                   6578: struct stringlist      *flist = &fhead;
                   6579: struct stringlist      Fhead = { 0 , 0 };
                   6580: struct stringlist      *Flist = &Fhead;
                   6581: struct stringlist      ehead = { 0 , 0 };
                   6582: struct stringlist      *elist = &ehead;
                   6583: struct stringlist      Ehead = { 0 , 0 };
                   6584: struct stringlist      *Elist = &Ehead;
                   6585: 
                   6586: addlist( listp , funcname )
                   6587:     struct stringlist  *listp;
                   6588:     char               *funcname;
                   6589: {
                   6590:     struct stringlist  *slp;
                   6591: 
                   6592:     slp = (struct stringlist *) malloc( sizeof(struct stringlist));
                   6593:     if ( slp == (struct stringlist *) 0 ) {
                   6594:        fprintf( stderr, "gprof: ran out room for printlist\n" );
                   6595:        done();
                   6596:     }
                   6597:     slp -> next = listp -> next;
                   6598:     slp -> string = funcname;
                   6599:     listp -> next = slp;
                   6600: }
                   6601: 
                   6602: bool
                   6603: onlist( listp , funcname )
                   6604:     struct stringlist  *listp;
                   6605:     char               *funcname;
                   6606: {
                   6607:     struct stringlist  *slp;
                   6608: 
                   6609:     for ( slp = listp -> next ; slp ; slp = slp -> next ) {
                   6610:        if ( ! strcmp( slp -> string , funcname ) ) {
                   6611:            return TRUE;
                   6612:        }
                   6613:        if ( funcname[0] == '_' && ! strcmp( slp -> string , &funcname[1] ) ) {
                   6614:            return TRUE;
                   6615:        }
                   6616:     }
                   6617:     return FALSE;
                   6618: }
                   6619: @
                   6620: 
                   6621: 
                   6622: 1.1
                   6623: log
                   6624: @4.3 release
                   6625: @
                   6626: text
                   6627: @d8 1
                   6628: a8 1
                   6629: static char sccsid[] = "@@(#)printlist.c       5.1 (Berkeley) 6/4/85";
                   6630: d19 4
                   6631: @
                   6632: y
                   6633:         *      to create an index.
                   6634:         */
                   6635:     namesortnlp = (nltype **) calloc( nname + ncycle , sizeof(nltype *) );
                   6636:     if ( namesortnlp == (nltype **) 0 ) {
                   6637:        fprintf( stderr , "%s: ran out of memory for sorting\n" , whoami );
                   6638:     }
                   6639:     for ( index = 0 , nnames = 0 ; index < nname ; index++ ) {
                   6640:        if ( zflag == 0 && nl[index].ncall == 0 && nl[index].time == 0 )
                   6641:                continue;
                   6642:        namesortnlp[nnames++] = &nl[index];
                   6643:     }
                   6644:     qsort( namgprof/RCS/vax.c,v   444     14     12       20716  4341433744   7057 head     1.2;
                   6645: access   ;
                   6646: symbols  ;
                   6647: locks    ; strict;
                   6648: comment  @ * @;
                   6649: 
                   6650: 
                   6651: 1.2
                   6652: date     88.11.19.20.11.13;  author lepreau;  state Exp;
                   6653: branches ;
                   6654: next     1.1;
                   6655: 
                   6656: 1.1
                   6657: date     88.11.19.19.57.29;  author lepreau;  state Rel;
                   6658: branches ;
                   6659: next     ;
                   6660: 
                   6661: 
                   6662: desc
                   6663: @In 4.3bsd called "calls.c", now renamed to <machine>.c
                   6664: @
                   6665: 
                   6666: 
                   6667: 1.2
                   6668: log
                   6669: @ucb sid 5.3. 1/7/86.  went out in hpbsd 1.0.
                   6670: @
                   6671: text
                   6672: @/*
                   6673:  * Copyright (c) 1983 Regents of the University of California.
                   6674:  * All rights reserved.  The Berkeley software License Agreement
                   6675:  * specifies the terms and conditions for redistribution.
                   6676:  */
                   6677: 
                   6678: #ifndef lint
                   6679: static char sccsid[] = "@@(#)vax.c     5.3 (Berkeley) 1/7/86";
                   6680: #endif not lint
                   6681: 
                   6682: #include       "gprof.h"
                   6683: 
                   6684:     /*
                   6685:      * a namelist entry to be the child of indirect calls
                   6686:      */
                   6687: nltype indirectchild = {
                   6688:        "(*)" ,                         /* the name */
                   6689:        (unsigned long) 0 ,             /* the pc entry point */
                   6690:        (unsigned long) 0 ,             /* entry point aligned to histogram */
                   6691:        (double) 0.0 ,                  /* ticks in this routine */
                   6692:        (double) 0.0 ,                  /* cumulative ticks in children */
                   6693:        (long) 0 ,                      /* how many times called */
                   6694:        (long) 0 ,                      /* how many calls to self */
                   6695:        (double) 1.0 ,                  /* propagation fraction */
                   6696:        (double) 0.0 ,                  /* self propagation time */
                   6697:        (double) 0.0 ,                  /* child propagation time */
                   6698:        (bool) 0 ,                      /* print flag */
                   6699:        (int) 0 ,                       /* index in the graph list */
                   6700:        (int) 0 ,                       /* graph call chain top-sort order */
                   6701:        (int) 0 ,                       /* internal number of cycle on */
                   6702:        (struct nl *) &indirectchild ,  /* pointer to head of cycle */
                   6703:        (struct nl *) 0 ,               /* pointer to next member of cycle */
                   6704:        (arctype *) 0 ,                 /* list of caller arcs */
                   6705:        (arctype *) 0                   /* list of callee arcs */
                   6706:     };
                   6707: 
                   6708: operandenum
                   6709: operandmode( modep )
                   6710:     struct modebyte    *modep;
                   6711: {
                   6712:     long       usesreg = modep -> regfield;
                   6713:     
                   6714:     switch ( modep -> modefield ) {
                   6715:        case 0:
                   6716:        case 1:
                   6717:        case 2:
                   6718:        case 3:
                   6719:            return literal;
                   6720:        case 4:
                   6721:            return indexed;
                   6722:        case 5:
                   6723:            return reg;
                   6724:        case 6:
                   6725:            return regdef;
                   6726:        case 7:
                   6727:            return autodec;
                   6728:        case 8:
                   6729:            return ( usesreg != PC ? autoinc : immediate );
                   6730:        case 9:
                   6731:            return ( usesreg != PC ? autoincdef : absolute );
                   6732:        case 10:
                   6733:            return ( usesreg != PC ? bytedisp : byterel );
                   6734:        case 11:
                   6735:            return ( usesreg != PC ? bytedispdef : bytereldef );
                   6736:        case 12:
                   6737:            return ( usesreg != PC ? worddisp : wordrel );
                   6738:        case 13:
                   6739:            return ( usesreg != PC ? worddispdef : wordreldef );
                   6740:        case 14:
                   6741:            return ( usesreg != PC ? longdisp : longrel );
                   6742:        case 15:
                   6743:            return ( usesreg != PC ? longdispdef : longreldef );
                   6744:     }
                   6745:     /* NOTREACHED */
                   6746: }
                   6747: 
                   6748: char *
                   6749: operandname( mode )
                   6750:     operandenum        mode;
                   6751: {
                   6752:     
                   6753:     switch ( mode ) {
                   6754:        case literal:
                   6755:            return "literal";
                   6756:        case indexed:
                   6757:            return "indexed";
                   6758:        case reg:
                   6759:            return "register";
                   6760:        case regdef:
                   6761:            return "register deferred";
                   6762:        case autodec:
                   6763:            return "autodecrement";
                   6764:        case autoinc:
                   6765:            return "autoincrement";
                   6766:        case autoincdef:
                   6767:            return "autoincrement deferred";
                   6768:        case bytedisp:
                   6769:            return "byte displacement";
                   6770:        case bytedispdef:
                   6771:            return "byte displacement deferred";
                   6772:        case byterel:
                   6773:            return "byte relative";
                   6774:        case bytereldef:
                   6775:            return "byte relative deferred";
                   6776:        case worddisp:
                   6777:            return "word displacement";
                   6778:        case worddispdef:
                   6779:            return "word displacement deferred";
                   6780:        case wordrel:
                   6781:            return "word relative";
                   6782:        case wordreldef:
                   6783:            return "word relative deferred";
                   6784:        case immediate:
                   6785:            return "immediate";
                   6786:        case absolute:
                   6787:            return "absolute";
                   6788:        case longdisp:
                   6789:            return "long displacement";
                   6790:        case longdispdef:
                   6791:            return "long displacement deferred";
                   6792:        case longrel:
                   6793:            return "long relative";
                   6794:        case longreldef:
                   6795:            return "long relative deferred";
                   6796:     }
                   6797:     /* NOTREACHED */
                   6798: }
                   6799: 
                   6800: long
                   6801: operandlength( modep )
                   6802:     struct modebyte    *modep;
                   6803: {
                   6804:     
                   6805:     switch ( operandmode( modep ) ) {
                   6806:        case literal:
                   6807:        case reg:
                   6808:        case regdef:
                   6809:        case autodec:
                   6810:        case autoinc:
                   6811:        case autoincdef:
                   6812:            return 1;
                   6813:        case bytedisp:
                   6814:        case bytedispdef:
                   6815:        case byterel:
                   6816:        case bytereldef:
                   6817:            return 2;
                   6818:        case worddisp:
                   6819:        case worddispdef:
                   6820:        case wordrel:
                   6821:        case wordreldef:
                   6822:            return 3;
                   6823:        case immediate:
                   6824:        case absolute:
                   6825:        case longdisp:
                   6826:        case longdispdef:
                   6827:        case longrel:
                   6828:        case longreldef:
                   6829:            return 5;
                   6830:        case indexed:
                   6831:            return 1+operandlength( (struct modebyte *) ((char *) modep) + 1 );
                   6832:     }
                   6833:     /* NOTREACHED */
                   6834: }
                   6835: 
                   6836: unsigned long
                   6837: reladdr( modep )
                   6838:     struct modebyte    *modep;
                   6839: {
                   6840:     operandenum        mode = operandmode( modep );
                   6841:     char       *cp;
                   6842:     short      *sp;
                   6843:     long       *lp;
                   6844: 
                   6845:     cp = (char *) modep;
                   6846:     cp += 1;                   /* skip over the mode */
                   6847:     switch ( mode ) {
                   6848:        default:
                   6849:            fprintf( stderr , "[reladdr] not relative address\n" );
                   6850:            return (unsigned long) modep;
                   6851:        case byterel:
                   6852:            return (unsigned long) ( cp + sizeof *cp + *cp );
                   6853:        case wordrel:
                   6854:            sp = (short *) cp;
                   6855:            return (unsigned long) ( cp + sizeof *sp + *sp );
                   6856:        case longrel:
                   6857:            lp = (long *) cp;
                   6858:            return (unsigned long) ( cp + sizeof *lp + *lp );
                   6859:     }
                   6860: }
                   6861: 
                   6862: findcall( parentp , p_lowpc , p_highpc )
                   6863:     nltype             *parentp;
                   6864:     unsigned long      p_lowpc;
                   6865:     unsigned long      p_highpc;
                   6866: {
                   6867:     unsigned char      *instructp;
                   6868:     long               length;
                   6869:     nltype             *childp;
                   6870:     operandenum                mode;
                   6871:     operandenum                firstmode;
                   6872:     unsigned long      destpc;
                   6873: 
                   6874:     if ( textspace == 0 ) {
                   6875:        return;
                   6876:     }
                   6877:     if ( p_lowpc < s_lowpc ) {
                   6878:        p_lowpc = s_lowpc;
                   6879:     }
                   6880:     if ( p_highpc > s_highpc ) {
                   6881:        p_highpc = s_highpc;
                   6882:     }
                   6883: #   ifdef DEBUG
                   6884:        if ( debug & CALLDEBUG ) {
                   6885:            printf( "[findcall] %s: 0x%x to 0x%x\n" ,
                   6886:                    parentp -> name , p_lowpc , p_highpc );
                   6887:        }
                   6888: #   endif DEBUG
                   6889:     for (   instructp = textspace + p_lowpc ;
                   6890:            instructp < textspace + p_highpc ;
                   6891:            instructp += length ) {
                   6892:        length = 1;
                   6893:        if ( *instructp == CALLS ) {
                   6894:                /*
                   6895:                 *      maybe a calls, better check it out.
                   6896:                 *      skip the count of the number of arguments.
                   6897:                 */
                   6898: #          ifdef DEBUG
                   6899:                if ( debug & CALLDEBUG ) {
                   6900:                    printf( "[findcall]\t0x%x:calls" , instructp - textspace );
                   6901:                }
                   6902: #          endif DEBUG
                   6903:            firstmode = operandmode( (struct modebyte *) (instructp+length) );
                   6904:            switch ( firstmode ) {
                   6905:                case literal:
                   6906:                case immediate:
                   6907:                    break;
                   6908:                default:
                   6909:                    goto botched;
                   6910:            }
                   6911:            length += operandlength( (struct modebyte *) (instructp+length) );
                   6912:            mode = operandmode( (struct modebyte *) ( instructp + length ) );
                   6913: #          ifdef DEBUG
                   6914:                if ( debug & CALLDEBUG ) {
                   6915:                    printf( "\tfirst operand is %s", operandname( firstmode ) );
                   6916:                    printf( "\tsecond operand is %s\n" , operandname( mode ) );
                   6917:                }
                   6918: #          endif DEBUG
                   6919:            switch ( mode ) {
                   6920:                case regdef:
                   6921:                case bytedispdef:
                   6922:                case worddispdef:
                   6923:                case longdispdef:
                   6924:                case bytereldef:
                   6925:                case wordreldef:
                   6926:                case longreldef:
                   6927:                        /*
                   6928:                         *      indirect call: call through pointer
                   6929:                         *      either  *d(r)   as a parameter or local
                   6930:                         *              (r)     as a return value
                   6931:                         *              *f      as a global pointer
                   6932:                         *      [are there others that we miss?,
                   6933:                         *       e.g. arrays of pointers to functions???]
                   6934:                         */
                   6935:                    addarc( parentp , &indirectchild , (long) 0 );
                   6936:                    length += operandlength(
                   6937:                                (struct modebyte *) ( instructp + length ) );
                   6938:                    continue;
                   6939:                case byterel:
                   6940:                case wordrel:
                   6941:                case longrel:
                   6942:                        /*
                   6943:                         *      regular pc relative addressing
                   6944:                         *      check that this is the address of 
                   6945:                         *      a function.
                   6946:                         */
                   6947:                    destpc = reladdr( (struct modebyte *) (instructp+length) )
                   6948:                                - (unsigned long) textspace;
                   6949:                    if ( destpc >= s_lowpc && destpc <= s_highpc ) {
                   6950:                        childp = nllookup( destpc );
                   6951: #                      ifdef DEBUG
                   6952:                            if ( debug & CALLDEBUG ) {
                   6953:                                printf( "[findcall]\tdestpc 0x%x" , destpc );
                   6954:                                printf( " childp->name %s" , childp -> name );
                   6955:                                printf( " childp->value 0x%x\n" ,
                   6956:                                        childp -> value );
                   6957:                            }
                   6958: #                      endif DEBUG
                   6959:                        if ( childp -> value == destpc ) {
                   6960:                                /*
                   6961:                                 *      a hit
                   6962:                                 */
                   6963:                            addarc( parentp , childp , (long) 0 );
                   6964:                            length += operandlength( (struct modebyte *)
                   6965:                                            ( instructp + length ) );
                   6966:                            continue;
                   6967:                        }
                   6968:                        goto botched;
                   6969:                    }
                   6970:                        /*
                   6971:                         *      else:
                   6972:                         *      it looked like a calls,
                   6973:                         *      but it wasn't to anywhere.
                   6974:                         */
                   6975:                    goto botched;
                   6976:                default:
                   6977:                botched:
                   6978:                        /*
                   6979:                         *      something funny going on.
                   6980:                         */
                   6981: #                  ifdef DEBUG
                   6982:                        if ( debug & CALLDEBUG ) {
                   6983:                            printf( "[findcall]\tbut it's a botch\n" );
                   6984:                        }
                   6985: #                  endif DEBUG
                   6986:                    length = 1;
                   6987:                    continue;
                   6988:            }
                   6989:        }
                   6990:     }
                   6991: }
                   6992: @
                   6993: 
                   6994: 
                   6995: 1.1
                   6996: log
                   6997: @4.3 release
                   6998: @
                   6999: text
                   7000: @d8 1
                   7001: a8 1
                   7002: static char sccsid[] = "@@(#)calls.c   5.1 (Berkeley) 6/4/85";
                   7003: d191 1
                   7004: a191 1
                   7005: findcalls( parentp , p_lowpc , p_highpc )
                   7006: d213 2
                   7007: a214 2
                   7008:        if ( debug & CALLSDEBUG ) {
                   7009:            printf( "[findcalls] %s: 0x%x to 0x%x\n" ,
                   7010: d228 2
                   7011: a229 2
                   7012:                if ( debug & CALLSDEBUG ) {
                   7013:                    printf( "[findcalls]\t0x%x:calls" , instructp - textspace );
                   7014: d243 1
                   7015: a243 1
                   7016:                if ( debug & CALLSDEBUG ) {
                   7017: d281 2
                   7018: a282 2
                   7019:                            if ( debug & CALLSDEBUG ) {
                   7020:                                printf( "[findcalls]\tdestpc 0x%x" , destpc );
                   7021: d311 2
                   7022: a312 2
                   7023:                        if ( debug & CALLSDEBUG ) {
                   7024:                            printf( "[findcalls]\tbut it's a botch\n" );
                   7025: @
                   7026: terel:
                   7027:            return (unsigned long) ( cp + sizeof *gprof/makefile   444     22     12         770  4227233605   6656 #
                   7028: # Copyright (c) 1983 Regents of the University of California.
                   7029: # All rights reserved.  The Berkeley software License Agreement
                   7030: # specifies the terms and conditions for redistribution.
                   7031: #
                   7032: #      @(#)makefile    5.1 (Berkeley) 10/14/86
                   7033: #
                   7034: DESTDIR= 
                   7035: MACHINE=`machine`
                   7036: 
                   7037: .c.o:
                   7038:        make -f Makefile ${MFLAGS} MACHINE=${MACHINE} $*.o
                   7039: 
                   7040: all:   FRC
                   7041:        make -f Makefile ${MFLAGS} MACHINE=${MACHINE}
                   7042: 
                   7043: FRC:
                   7044: 
                   7045: install:
                   7046:        make -f Makefile ${MFLAGS} MACHINE=${MACHINE} install
                   7047: 
                   7048: clean:
                   7049:        make -f Makefile ${MFLAGS} MACHINE=${MACHINE} clean
                   7050: of.ogprof/hp300.c   444     22     12         276  4230223517   6150 #include "gprof.h"
                   7051: 
                   7052: /*
                   7053:  * gprof -c isn't currently supported...
                   7054:  */
                   7055: findcall( parentp , p_lowpc , p_highpc )
                   7056:     nltype             *parentp;
                   7057:     unsigned long      p_lowpc;
                   7058:     unsigned long      p_highpc;
                   7059: {
                   7060: }
                   7061: lookup.c�>tahoe.c�?
                   7062: gprof.flat�@vax.h�Agprof.callg�Btahoe.h�Cvax.c�Dhp300.hr3RCS�Emakefile�Fhp300.c�G�gcrt0.hägprof.oåarcs.oædfn.oçlookup.oèhp300.oéhertz.oêprintgprof.ogprof/gcrt0.h   444     22     12        3637  4231040575   6370 /*
                   7063:  * Copyright (c) 1980 Regents of the University of California.
                   7064:  * All rights reserved.  The Berkeley software License Agreement
                   7065:  * specifies the terms and conditions for redistribution.
                   7066:  *
                   7067:  *     @(#)gmon.h      5.1 (Berkeley) 5/30/85
                   7068:  */
                   7069: 
                   7070: struct phdr {
                   7071:     char       *lpc;
                   7072:     char       *hpc;
                   7073:     int                ncnt;
                   7074: };
                   7075: 
                   7076:     /*
                   7077:      * histogram counters are unsigned shorts (according to the kernel).
                   7078:      */
                   7079: #define        HISTCOUNTER     unsigned short
                   7080: 
                   7081:     /*
                   7082:      * fraction of text space to allocate for histogram counters
                   7083:      * here, 1/2
                   7084:      */
                   7085: #define        HISTFRACTION    2
                   7086: 
                   7087:     /*
                   7088:      * Fraction of text space to allocate for from hash buckets.
                   7089:      * The value of HASHFRACTION is based on the minimum number of bytes
                   7090:      * of separation between two subroutine call points in the object code.
                   7091:      * Given MIN_SUBR_SEPARATION bytes of separation the value of
                   7092:      * HASHFRACTION is calculated as:
                   7093:      *
                   7094:      *         HASHFRACTION = MIN_SUBR_SEPARATION / (2 * sizeof(short) - 1);
                   7095:      *
                   7096:      * For the VAX, the shortest two call sequence is:
                   7097:      *
                   7098:      *         calls   $0,(r0)
                   7099:      *         calls   $0,(r0)
                   7100:      *
                   7101:      * which is separated by only three bytes, thus HASHFRACTION is 
                   7102:      * calculated as:
                   7103:      *
                   7104:      *         HASHFRACTION = 3 / (2 * 2 - 1) = 1
                   7105:      *
                   7106:      * Note that the division above rounds down, thus if MIN_SUBR_FRACTION
                   7107:      * is less than three, this algorithm will not work!
                   7108:      */
                   7109: #define        HASHFRACTION    1
                   7110: 
                   7111:     /*
                   7112:      * percent of text space to allocate for tostructs
                   7113:      * with a minimum.
                   7114:      */
                   7115: #define ARCDENSITY     2
                   7116: #define MINARCS                50
                   7117: 
                   7118: struct tostruct {
                   7119:     char               *selfpc;
                   7120:     long               count;
                   7121:     unsigned short     link;
                   7122: };
                   7123: 
                   7124:     /*
                   7125:      * a raw arc,
                   7126:      *     with pointers to the calling site and the called site
                   7127:      *     and a count.
                   7128:      */
                   7129: struct rawarc {
                   7130:     unsigned long      raw_frompc;
                   7131:     unsigned long      raw_selfpc;
                   7132:     long               raw_count;
                   7133: };
                   7134: 
                   7135:     /*
                   7136:      * general rounding functions.
                   7137:      */
                   7138: #define ROUNDDOWN(x,y) (((x)/(y))*(y))
                   7139: #define ROUNDUP(x,y)   ((((x)+(y)-1)/(y))*(y))
                   7140: hort
                   7141: 
                   7142:     /*
                   7143:      * fraction of text space to allocate for histogram counters
                   7144:      * here, 1/2
                   7145:   #include "gprof.h"
                   7146: 
                   7147: /*
                   7148:  * gprof -c isn't currently supported...
                   7149:  */
                   7150: findcall( parentp , p_lowpc , p_highpc )
                   7151:     nltype             *parentp;
                   7152:     unsigned long      p_lowpc;
                   7153:     unsigned long      p_highpc;
                   7154: {
                   7155: }
                   7156: lookup.c�>tahoe.c�?
                   7157: gprof.flat�@vax.h�Agprof.callg�Btahoe.h�Cvax.c�Dhp300.hr3RCS�Emakefile�Fhp300.c�G�gcrt0.hägprof.oåarcs.oædfn.oçlookup.oèhp300.oéhertz.oêprintgprof.ogprof/gcrt0.h   444     22     12        3637  4231040575   6370 /*
                   7158:  * Copyright (c) 1980 Regents of the University of California.
                   7159:  * All rights reserved.  The Berkeley software License Agreement
                   7160:  * specifies the terms and conditions for redistribution.
                   7161:  *
                   7162:  *     @(#)gmon.h      5.1 (Berkeley) 5/30/85
                   7163:  */
                   7164: 
                   7165: struct phdr {
                   7166:     char       *lpc;
                   7167:     char       *hpc;
                   7168:     int                ncnt;
                   7169: };
                   7170: 
                   7171:     /*
                   7172:      * histogram counters are unsigned shorts (according to the kernel).
                   7173:      */
                   7174: #define        HISTCOUNTER     unsigned short
                   7175: 
                   7176:     /*
                   7177:      * fraction of text space to allocate for histogram counters
                   7178:      * here, 1/2
                   7179:      */
                   7180: #define        HISTFRACTION    2
                   7181: 
                   7182:     /*
                   7183:      * Fraction of text space to allocate for from hash buckets.
                   7184:      * The value of HASHFRACTION is based on the minimum number of bytes
                   7185:      * of separation between two subroutine call points in the object code.
                   7186:      * Given MIN_SUBR_SEPARATION bytes of separation the value of
                   7187:      * HASHFRACTION is calculated as:
                   7188:      *
                   7189:      *         HASHFRACTION = MIN_SUBR_SEPARATION / (2 * sizeof(short) - 1);
                   7190:      *
                   7191:      * For the VAX, the shortest two call sequence is:
                   7192:      *
                   7193:      *         calls   $0,(r0)
                   7194:      *         calls   $0,(r0)
                   7195:      *
                   7196:      * which is separated by only three bytes, thus HASHFRACTION is 
                   7197:      * calculated as:
                   7198:      *
                   7199:      *         HASHFRACTION = 3 / (2 * 2 - 1) = 1
                   7200:      *
                   7201:      * Note that the division above rounds down, thus if MIN_SUBR_FRACTION
                   7202:      * is less than three, this algorithm will not work!
                   7203:      */
                   7204: #define        HASHFRACTION    1
                   7205: 
                   7206:     /*
                   7207:      * percent of text space to allocate for tostructs
                   7208:      * with a minimum.
                   7209:      */
                   7210: #define ARCDENSITY     2
                   7211: #define MINARCS                50
                   7212: 
                   7213: struct tostruct {
                   7214:     cha

unix.superglobalmegacorp.com

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