Annotation of 43BSDReno/pgrm/gprof/hp.gprof.tar, revision 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.