fixed a bug in multi-subscript calculation
[unix-history] / usr / src / usr.bin / gprof / gprof.c
index 670b2bc..87b8407 100644 (file)
@@ -1,13 +1,21 @@
 #ifndef lint
 #ifndef lint
-    static     char *sccsid = "@(#)gprof.c     1.10 (Berkeley) %G%";
+    static     char *sccsid = "@(#)gprof.c     1.19 (Berkeley) %G%";
 #endif lint
 
 #include "gprof.h"
 
 #endif lint
 
 #include "gprof.h"
 
+char   *whoami = "gprof";
+
+    /*
+     * things which get -E excluded by default.
+     */
+char   *defaultEs[] = { "mcount" , "__mcleanup" , 0 };
+
 main(argc, argv)
 main(argc, argv)
-       int argc;
-       char **argv;
+    int argc;
+    char **argv;
 {
 {
+    char       **sp;
 
     --argc;
     argv++;
 
     --argc;
     argv++;
@@ -15,7 +23,17 @@ main(argc, argv)
     while ( *argv != 0 && **argv == '-' ) {
        (*argv)++;
        switch ( **argv ) {
     while ( *argv != 0 && **argv == '-' ) {
        (*argv)++;
        switch ( **argv ) {
+       case 'a':
+           aflag = TRUE;
+           break;
+       case 'b':
+           bflag = TRUE;
+           break;
+       case 'c':
+           cflag = TRUE;
+           break;
        case 'd':
        case 'd':
+           dflag = TRUE;
            (*argv)++;
            debug |= atoi( *argv );
            debug |= ANYDEBUG;
            (*argv)++;
            debug |= atoi( *argv );
            debug |= ANYDEBUG;
@@ -23,20 +41,33 @@ main(argc, argv)
                printf( "[main] debug = %d\n" , debug );
 #          endif DEBUG
            break;
                printf( "[main] debug = %d\n" , debug );
 #          endif DEBUG
            break;
-       case 'a':
-           aflag++;
+       case 'E':
+           ++argv;
+           addlist( Elist , *argv );
+           Eflag = TRUE;
+           addlist( elist , *argv );
+           eflag = TRUE;
            break;
            break;
-       case 'b':
-           bflag++;
+       case 'e':
+           addlist( elist , *++argv );
+           eflag = TRUE;
            break;
            break;
-       case 'c':
-           cflag++;
+       case 'F':
+           ++argv;
+           addlist( Flist , *argv );
+           Fflag = TRUE;
+           addlist( flist , *argv );
+           fflag = TRUE;
+           break;
+       case 'f':
+           addlist( flist , *++argv );
+           fflag = TRUE;
            break;
        case 's':
            break;
        case 's':
-           sflag++;
+           sflag = TRUE;
            break;
        case 'z':
            break;
        case 'z':
-           zflag++;
+           zflag = TRUE;
            break;
        }
        argv++;
            break;
        }
        argv++;
@@ -53,6 +84,19 @@ main(argc, argv)
     } else {
        gmonname = GMONNAME;
     }
     } else {
        gmonname = GMONNAME;
     }
+       /*
+        *      turn off default functions
+        */
+    for ( sp = &defaultEs[0] ; *sp ; sp++ ) {
+       Eflag = TRUE;
+       addlist( Elist , *sp );
+       eflag = TRUE;
+       addlist( elist , *sp );
+    }
+       /*
+        *      how long is a clock tick?
+        */
+    hz = hertz();
        /*
         *      get information about a.out file.
         */
        /*
         *      get information about a.out file.
         */
@@ -65,13 +109,13 @@ main(argc, argv)
        if ( *argv != 0 ) {
            gmonname = *argv;
        }
        if ( *argv != 0 ) {
            gmonname = *argv;
        }
-    } while ( sflag && *argv++ != 0 );
+    } while ( *argv++ != 0 );
        /*
         *      dump out a gmon.sum file if requested
         */
        /*
         *      dump out a gmon.sum file if requested
         */
-       if ( sflag ) {
-           dumpsum( GMONSUM );
-       }
+    if ( sflag ) {
+       dumpsum( GMONSUM );
+    }
        /*
         *      assign samples to procedures
         */
        /*
         *      assign samples to procedures
         */
@@ -87,11 +131,11 @@ main(argc, argv)
     done();
 }
 
     done();
 }
 
-/*
- * Set up string and symbol tables from a.out.
*     and optionally the text space.
- * On return symbol table is sorted by value.
- */
+    /*
    * Set up string and symbol tables from a.out.
    * and optionally the text space.
    * On return symbol table is sorted by value.
    */
 getnfile()
 {
     FILE       *nfile;
 getnfile()
 {
     FILE       *nfile;
@@ -103,7 +147,7 @@ getnfile()
     }
     fread(&xbuf, 1, sizeof(xbuf), nfile);
     if (N_BADMAG(xbuf)) {
     }
     fread(&xbuf, 1, sizeof(xbuf), nfile);
     if (N_BADMAG(xbuf)) {
-       fprintf(stderr, "%s: bad format\n", a_outname );
+       fprintf(stderr, "%s: %s: bad format\n", whoami , a_outname );
        done();
     }
     getstrtab(nfile);
        done();
     }
     getstrtab(nfile);
@@ -128,17 +172,19 @@ getstrtab(nfile)
 
     fseek(nfile, (long)(N_SYMOFF(xbuf) + xbuf.a_syms), 0);
     if (fread(&ssiz, sizeof (ssiz), 1, nfile) == 0) {
 
     fseek(nfile, (long)(N_SYMOFF(xbuf) + xbuf.a_syms), 0);
     if (fread(&ssiz, sizeof (ssiz), 1, nfile) == 0) {
-       fprintf(stderr, "%s: no string table (old format?)\n", a_outname );
+       fprintf(stderr, "%s: %s: no string table (old format?)\n" ,
+               whoami , a_outname );
        done();
     }
     strtab = (char *)calloc(ssiz, 1);
     if (strtab == NULL) {
        done();
     }
     strtab = (char *)calloc(ssiz, 1);
     if (strtab == NULL) {
-       fprintf(stderr, "%s: no room for %d bytes of string table",
-               a_outname , ssiz);
+       fprintf(stderr, "%s: %s: no room for %d bytes of string table",
+               whoami , a_outname , ssiz);
        done();
     }
     if (fread(strtab+sizeof(ssiz), ssiz-sizeof(ssiz), 1, nfile) != 1) {
        done();
     }
     if (fread(strtab+sizeof(ssiz), ssiz-sizeof(ssiz), 1, nfile) != 1) {
-       fprintf(stderr, "%s: error reading string table\n", a_outname );
+       fprintf(stderr, "%s: %s: error reading string table\n",
+               whoami , a_outname );
        done();
     }
 }
        done();
     }
 }
@@ -164,21 +210,14 @@ getsymtab(nfile)
        nname++;
     }
     if (nname == 0) {
        nname++;
     }
     if (nname == 0) {
-       fprintf(stderr, "%s: no symbols\n", a_outname );
+       fprintf(stderr, "%s: %s: no symbols\n", whoami , a_outname );
        done();
     }
        done();
     }
-       /*
-        *      ask also for CYCLEFRACTION extra namelist entries for 
-        *      cycle entries.  these hide out at the end of the namelist
-        *      and aren't accessed unless the whole namelist (nname+ncycles)
-        *      is sorted and searched.
-        */
-    ncycles = nname * CYCLEFRACTION;
-    askfor = nname + 1 + ncycles;
+    askfor = nname + 1;
     nl = (nltype *) calloc( askfor , sizeof(nltype) );
     if (nl == 0) {
     nl = (nltype *) calloc( askfor , sizeof(nltype) );
     if (nl == 0) {
-       fprintf(stderr, "prof: No room for %d bytes of symbol table\n",
-               askfor * sizeof(nltype) );
+       fprintf(stderr, "%s: No room for %d bytes of symbol table\n",
+               whoami, askfor * sizeof(nltype) );
        done();
     }
 
        done();
     }
 
@@ -225,14 +264,15 @@ gettextspace( nfile )
     }
     textspace = malloc( xbuf.a_text );
     if ( textspace == 0 ) {
     }
     textspace = malloc( xbuf.a_text );
     if ( textspace == 0 ) {
-       fprintf( stderr , "gprof: ran out room for %d bytes of text space:  " );
-       fprintf( stderr , "can't do -c\n" , xbuf.a_text );
+       fprintf( stderr , "%s: ran out room for %d bytes of text space:  " ,
+                       whoami , xbuf.a_text );
+       fprintf( stderr , "can't do -c\n" );
        return;
     }
     (void) fseek( nfile , N_TXTOFF( xbuf ) , 0 );
     if ( fread( textspace , 1 , xbuf.a_text , nfile ) != xbuf.a_text ) {
        return;
     }
     (void) fseek( nfile , N_TXTOFF( xbuf ) , 0 );
     if ( fread( textspace , 1 , xbuf.a_text , nfile ) != xbuf.a_text ) {
-       fprintf( stderr , "couldn't read text space:  " );
-       fprintf( stderr , "can't do -c\n" , xbuf.a_text );
+       fprintf( stderr , "%s: couldn't read text space:  " , whoami );
+       fprintf( stderr , "can't do -c\n" );
        free( textspace );
        textspace = 0;
        return;
        free( textspace );
        textspace = 0;
        return;
@@ -291,10 +331,22 @@ openpfile(filename)
     h = tmp;
     s_lowpc = (unsigned long) h.lowpc;
     s_highpc = (unsigned long) h.highpc;
     h = tmp;
     s_lowpc = (unsigned long) h.lowpc;
     s_highpc = (unsigned long) h.highpc;
-    lowpc = h.lowpc - (UNIT *)0;
-    highpc = h.highpc - (UNIT *)0;
+    lowpc = (unsigned long)h.lowpc / sizeof(UNIT);
+    highpc = (unsigned long)h.highpc / sizeof(UNIT);
     sampbytes = h.ncnt - sizeof(struct hdr);
     nsamples = sampbytes / sizeof (unsigned UNIT);
     sampbytes = h.ncnt - sizeof(struct hdr);
     nsamples = sampbytes / sizeof (unsigned UNIT);
+#   ifdef DEBUG
+       if ( debug & SAMPLEDEBUG ) {
+           printf( "[openpfile] hdr.lowpc 0x%x hdr.highpc 0x%x hdr.ncnt %d\n",
+               h.lowpc , h.highpc , h.ncnt );
+           printf( "[openpfile]   s_lowpc 0x%x   s_highpc 0x%x\n" ,
+               s_lowpc , s_highpc );
+           printf( "[openpfile]     lowpc 0x%x     highpc 0x%x\n" ,
+               lowpc , highpc );
+           printf( "[openpfile] sampbytes %d nsamples %d\n" ,
+               sampbytes , nsamples );
+       }
+#   endif DEBUG
     return(pfile);
 }
 
     return(pfile);
 }
 
@@ -389,8 +441,8 @@ readsamples(pfile)
     if (samples == 0) {
        samples = (unsigned UNIT *) calloc(sampbytes, sizeof (unsigned UNIT));
        if (samples == 0) {
     if (samples == 0) {
        samples = (unsigned UNIT *) calloc(sampbytes, sizeof (unsigned UNIT));
        if (samples == 0) {
-           fprintf( stderr , "prof: No room for %d sample pc's\n", 
-               sampbytes / sizeof (unsigned UNIT));
+           fprintf( stderr , "%s: No room for %d sample pc's\n", 
+               whoami , sampbytes / sizeof (unsigned UNIT));
            done();
        }
     }
            done();
        }
     }
@@ -402,8 +454,8 @@ readsamples(pfile)
     }
     if (i != nsamples) {
        fprintf(stderr,
     }
     if (i != nsamples) {
        fprintf(stderr,
-           "prof: unexpected EOF after reading %d/%d samples\n",
-               --i, nsamples);
+           "%s: unexpected EOF after reading %d/%d samples\n",
+               whoami , --i , nsamples );
        done();
     }
 }
        done();
     }
 }
@@ -424,7 +476,7 @@ asgnsamples()
     /* read samples and assign to namelist symbols */
     scale = highpc - lowpc;
     scale /= nsamples;
     /* read samples and assign to namelist symbols */
     scale = highpc - lowpc;
     scale /= nsamples;
-    for (i=0; i < nsamples; i++) {
+    for (i = 0, j = 1; i < nsamples; i++) {
        ccnt = samples[i];
        if (ccnt == 0)
                continue;
        ccnt = samples[i];
        if (ccnt == 0)
                continue;
@@ -438,7 +490,7 @@ asgnsamples()
            }
 #      endif DEBUG
        totime += time;
            }
 #      endif DEBUG
        totime += time;
-       for (j=0; j<nname; j++) {
+       for (j = j - 1; j < nname; j++) {
            svalue0 = nl[j].value / sizeof(UNIT);
            svalue1 = nl[j+1].value / sizeof(UNIT);
            if (pch < svalue0)
            svalue0 = nl[j].value / sizeof(UNIT);
            svalue1 = nl[j+1].value / sizeof(UNIT);
            if (pch < svalue0)
@@ -463,10 +515,6 @@ asgnsamples()
            printf( "[asgnsamples] totime %f\n" , totime );
        }
 #   endif DEBUG
            printf( "[asgnsamples] totime %f\n" , totime );
        }
 #   endif DEBUG
-    if (totime==0.0) {
-       fprintf( stderr , "No time accumulated\n" );
-       totime=1.0;
-    }
 }
 
 
 }
 
 
@@ -505,7 +553,7 @@ funcsymbol( nlistp )
        return FALSE;
     }
        /*
        return FALSE;
     }
        /*
-        *      can't have any `funny characters in name,
+        *      can't have any `funny' characters in name,
         *      where `funny' includes  `.', .o file names
         *                      and     `$', pascal labels.
         */
         *      where `funny' includes  `.', .o file names
         *                      and     `$', pascal labels.
         */