gather and use static call graph from a.out file.
authorPeter B. Kessler <peter@ucbvax.Berkeley.EDU>
Tue, 3 Nov 1981 06:32:37 +0000 (22:32 -0800)
committerPeter B. Kessler <peter@ucbvax.Berkeley.EDU>
Tue, 3 Nov 1981 06:32:37 +0000 (22:32 -0800)
SCCS-vsn: usr.bin/gprof/gprof.c 1.3
SCCS-vsn: usr.bin/gprof/arcs.c 1.3
SCCS-vsn: usr.bin/gprof/gprof.h 1.3
SCCS-vsn: usr.bin/gprof/lookup.c 1.3
SCCS-vsn: usr.bin/gprof/Makefile 1.4

usr/src/usr.bin/gprof/Makefile
usr/src/usr.bin/gprof/arcs.c
usr/src/usr.bin/gprof/gprof.c
usr/src/usr.bin/gprof/gprof.h
usr/src/usr.bin/gprof/lookup.c

index 5fecdc2..c6c999b 100644 (file)
@@ -1,11 +1,11 @@
-SCCSID = @(#)Makefile  1.3 (Berkeley) %G%
+SCCSID = @(#)Makefile  1.4 (Berkeley) %G%
 
 
-CFLAGS =
 DFLAGS = 
 DFLAGS = 
+CFLAGS = ${DFLAGS}
 
 
-GPROFHDRS =    gprof.h
-GPROFSRCS =    gprof.c arcs.c dfn.c lookup.c printgprof.c
-GPROFOBJS =    gprof.o arcs.o dfn.o lookup.o printgprof.o
+GPROFHDRS =    gprof.h calls.h
+GPROFSRCS =    gprof.c arcs.c dfn.c lookup.c printgprof.c calls.c
+GPROFOBJS =    gprof.o arcs.o dfn.o lookup.o printgprof.o calls.o
 OTHERS =       gmcrt0.c gmcrt0.h gmcrt0.ex
 
 gprof: ${GPROFOBJS}
 OTHERS =       gmcrt0.c gmcrt0.h gmcrt0.ex
 
 gprof: ${GPROFOBJS}
@@ -31,8 +31,9 @@ arcs.o: arcs.c gprof.h
 lookup.o: lookup.c gprof.h
 dfn.o: dfn.c gprof.h
 printgprof.o: printgprof.c gprof.h
 lookup.o: lookup.c gprof.h
 dfn.o: dfn.c gprof.h
 printgprof.o: printgprof.c gprof.h
+calls.o: calls.c calls.h gprof.h
 
 
-PGPROF = p.gprof.o p.arcs.o p.dfn.o p.lookup.o p.printgprof.o
+PGPROF = p.gprof.o p.arcs.o p.dfn.o p.lookup.o p.printgprof.o p.calls.o
 
 p.gprof: ${PGPROF}
        /bin/ld -X gmcrt0.o -o p.gprof ${PGPROF} -lcp
 
 p.gprof: ${PGPROF}
        /bin/ld -X gmcrt0.o -o p.gprof ${PGPROF} -lcp
@@ -62,9 +63,14 @@ p.printgprof.o: printgprof.c gprof.h
        cc -c -p ${CFLAGS} p.printgprof.c
        rm p.printgprof.c
 
        cc -c -p ${CFLAGS} p.printgprof.c
        rm p.printgprof.c
 
+p.calls.o: calls.c calls.h gprof.h
+       ln calls.c p.calls.c
+       cc -c -p ${CFLAGS} p.calls.c
+       rm p.calls.c
+
 LINTFLAGS = -x -a -n
 lint:
 LINTFLAGS = -x -a -n
 lint:
-       lint ${CFLAGS} ${LINTFLAGS} gprof.c arcs.c dfn.c lookup.c printgprof.c
+       lint ${CFLAGS} ${LINTFLAGS} ${GPROFSRCS}
 
 ${GPROFHDRS} ${GPROFSRCS} ${OTHERS}:
        sccs get $@
 
 ${GPROFHDRS} ${GPROFSRCS} ${OTHERS}:
        sccs get $@
index 5920c83..450a48a 100644 (file)
@@ -1,9 +1,56 @@
 #ifndef lint
 #ifndef lint
-    static     char *sccsid = "@(#)arcs.c      1.2 (Berkeley) %G%";
+    static     char *sccsid = "@(#)arcs.c      1.3 (Berkeley) %G%";
 #endif lint
 
 #include "gprof.h"
 
 #endif lint
 
 #include "gprof.h"
 
+    /*
+     * add (or just increment) an arc
+     */
+addarc( parentp , childp , count )
+    nltype     *parentp;
+    nltype     *childp;
+    long       count;
+{
+    arctype            *malloc();
+    arctype            *arcp;
+
+#   ifdef DEBUG
+       if ( debug & TALLYDEBUG ) {
+           printf( "[addarc] %d arcs from %s to %s\n" ,
+                   count , parentp -> name , childp -> name );
+       }
+#   endif DEBUG
+    arcp = arclookup( parentp , childp );
+    if ( arcp != 0 ) {
+           /*
+            *  a hit:  just increment the count.
+            */
+#      ifdef DEBUG
+           if ( debug & TALLYDEBUG ) {
+               printf( "[tally] hit %d += %d\n" ,
+                       arcp -> arc_count , count );
+           }
+#      endif DEBUG
+       arcp -> arc_count += count;
+       return;
+    }
+    arcp = malloc( sizeof *arcp );
+    arcp -> arc_parentp = parentp;
+    arcp -> arc_childp = childp;
+    arcp -> arc_count = count;
+       /*
+        *      prepend this child to the children of this parent
+        */
+    arcp -> arc_childlist = parentp -> children;
+    parentp -> children = arcp;
+       /*
+        *      prepend this parent to the parents of this child
+        */
+    arcp -> arc_parentlist = childp -> parents;
+    childp -> parents = arcp;
+}
+
 topcmp( npp1 , npp2 )
     nltype     **npp1;
     nltype     **npp2;
 topcmp( npp1 , npp2 )
     nltype     **npp1;
     nltype     **npp2;
@@ -62,6 +109,9 @@ doarcs()
        } else {
            parentp -> selfcalls = 0;
        }
        } else {
            parentp -> selfcalls = 0;
        }
+       if ( cflag ) {
+           findcalls( parentp , parentp -> value , (parentp+1) -> value );
+       }
        parentp -> toporder = 0;
        parentp -> cycleno = 0;
        parentp -> cyclehead = parentp;
        parentp -> toporder = 0;
        parentp -> cycleno = 0;
        parentp -> cyclehead = parentp;
index eb255cf..324e3c4 100644 (file)
@@ -1,5 +1,5 @@
 #ifndef lint
 #ifndef lint
-    static     char *sccsid = "@(#)gprof.c     1.2 (Berkeley) %G%";
+    static     char *sccsid = "@(#)gprof.c     1.3 (Berkeley) %G%";
 #endif lint
 
 #include "gprof.h"
 #endif lint
 
 #include "gprof.h"
@@ -23,6 +23,8 @@ main(argc, argv)
 #          endif DEBUG
        } else if ( **argv == 'z' ) {
            zflg++;
 #          endif DEBUG
        } else if ( **argv == 'z' ) {
            zflg++;
+       } else if ( **argv == 'c' ) {
+           cflag++;
        }
        argv++;
     }
        }
        argv++;
     }
@@ -144,6 +146,7 @@ putprofheader()
 
 /*
  * Set up string and symbol tables from a.out.
 
 /*
  * Set up string and symbol tables from a.out.
+ *     and optionally the text space.
  * On return symbol table is sorted by value.
  */
 getnfile()
  * On return symbol table is sorted by value.
  */
 getnfile()
@@ -162,6 +165,7 @@ getnfile()
     }
     getstrtab(nfile);
     getsymtab(nfile);
     }
     getstrtab(nfile);
     getsymtab(nfile);
+    gettextspace( nfile );
     qsort(nl, nname, sizeof(nltype), valcmp);
     fclose(nfile);
 #   ifdef DEBUG
     qsort(nl, nname, sizeof(nltype), valcmp);
     fclose(nfile);
 #   ifdef DEBUG
@@ -259,6 +263,32 @@ getsymtab(nfile)
     npe++;
 }
 
     npe++;
 }
 
+    /*
+     * read in the text space of an a.out file
+     */
+gettextspace( nfile )
+    FILE       *nfile;
+{
+    unsigned char      *malloc();
+    
+    if ( cflag == 0 ) {
+       return;
+    }
+    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 );
+       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 );
+       free( textspace );
+       textspace = 0;
+       return;
+    }
+}
     /*
      * information from a gmon.out file is in two parts:
      * an array of sampling hits within pc ranges,
     /*
      * information from a gmon.out file is in two parts:
      * an array of sampling hits within pc ranges,
@@ -314,8 +344,6 @@ tally( rawp )
 {
     nltype             *parentp;
     nltype             *childp;
 {
     nltype             *parentp;
     nltype             *childp;
-    arctype            *arcp;
-    arctype            *malloc();
 
     parentp = nllookup( rawp -> raw_frompc );
     childp = nllookup( rawp -> raw_selfpc );
 
     parentp = nllookup( rawp -> raw_frompc );
     childp = nllookup( rawp -> raw_selfpc );
@@ -326,34 +354,7 @@ tally( rawp )
                    parentp -> name , childp -> name , rawp -> raw_count );
        }
 #   endif DEBUG
                    parentp -> name , childp -> name , rawp -> raw_count );
        }
 #   endif DEBUG
-    arcp = arclookup( parentp , childp );
-    if ( arcp != 0 ) {
-           /*
-            *  a hit:  just increment the count.
-            */
-#      ifdef DEBUG
-           if ( debug & TALLYDEBUG ) {
-               printf( "[tally] hit %d += %d\n" ,
-                       arcp -> arc_count , rawp -> raw_count );
-           }
-#      endif DEBUG
-       arcp -> arc_count += rawp -> raw_count;
-       return;
-    }
-    arcp = malloc( sizeof *arcp );
-    arcp -> arc_parentp = parentp;
-    arcp -> arc_childp = childp;
-    arcp -> arc_count = rawp -> raw_count;
-       /*
-        *      prepend this child to the children of this parent
-        */
-    arcp -> arc_childlist = parentp -> children;
-    parentp -> children = arcp;
-       /*
-        *      prepend this parent to the parents of this child
-        */
-    arcp -> arc_parentlist = childp -> parents;
-    childp -> parents = arcp;
+    addarc( parentp , childp , rawp -> raw_count );
 }
 
 valcmp(p1, p2)
 }
 
 valcmp(p1, p2)
index 8584c35..b0724bf 100644 (file)
@@ -1,4 +1,4 @@
-    /* sccsid:  @(#)gprof.h    1.2 (Berkeley) %G% */
+    /* sccsid:  @(#)gprof.h    1.3 (Berkeley) %G% */
 
 #include <stdio.h>
 #include <sys/types.h>
 
 #include <stdio.h>
 #include <sys/types.h>
@@ -121,8 +121,10 @@ double     scale;                  /* scale factor converting samples to pc
 char   *strtab;                /* string table in core */
 off_t  ssiz;                   /* size of the string table */
 struct exec xbuf;              /* exec header of a.out */
 char   *strtab;                /* string table in core */
 off_t  ssiz;                   /* size of the string table */
 struct exec xbuf;              /* exec header of a.out */
+unsigned char  *textspace;             /* text space of a.out in core */
 
 int    zflg;
 
 int    zflg;
+int    cflag;
 
     /*
      * booleans
 
     /*
      * booleans
@@ -150,4 +152,6 @@ bool                dfn_busy();
 #define        TIMEDEBUG       16
 #define        SAMPLEDEBUG     32
 #define        AOUTDEBUG       64
 #define        TIMEDEBUG       16
 #define        SAMPLEDEBUG     32
 #define        AOUTDEBUG       64
-#define        ANYDEBUG        128
+#define        CALLSDEBUG      128
+#define        LOOKUPDEBUG     256
+#define        ANYDEBUG        512
index 2471456..fd7ac44 100644 (file)
@@ -1,5 +1,5 @@
 #ifndef lint
 #ifndef lint
-    static     char *sccsid = "@(#)lookup.c    1.2 (Berkeley) %G%";
+    static     char *sccsid = "@(#)lookup.c    1.3 (Berkeley) %G%";
 #endif lint
 
 #include "gprof.h"
 #endif lint
 
 #include "gprof.h"
@@ -28,7 +28,7 @@ nllookup( address )
        middle = ( high + low ) >> 1;
        if ( nl[ middle ].value <= address && nl[ middle+1 ].value > address ) {
 #          ifdef DEBUG
        middle = ( high + low ) >> 1;
        if ( nl[ middle ].value <= address && nl[ middle+1 ].value > address ) {
 #          ifdef DEBUG
-               if ( debug & TALLYDEBUG ) {
+               if ( debug & LOOKUPDEBUG ) {
                    printf( "[nllookup] %d (%d) probes\n" , probes , nname-1 );
                }
 #          endif DEBUG
                    printf( "[nllookup] %d (%d) probes\n" , probes , nname-1 );
                }
 #          endif DEBUG
@@ -56,14 +56,14 @@ arclookup( parentp , childp )
        return 0;
     }
 #   ifdef DEBUG
        return 0;
     }
 #   ifdef DEBUG
-       if ( debug & TALLYDEBUG ) {
+       if ( debug & LOOKUPDEBUG ) {
            printf( "[arclookup] parent %s child %s\n" ,
                    parentp -> name , childp -> name );
        }
 #   endif DEBUG
     for ( arcp = parentp -> children ; arcp ; arcp = arcp -> arc_childlist ) {
 #      ifdef DEBUG
            printf( "[arclookup] parent %s child %s\n" ,
                    parentp -> name , childp -> name );
        }
 #   endif DEBUG
     for ( arcp = parentp -> children ; arcp ; arcp = arcp -> arc_childlist ) {
 #      ifdef DEBUG
-           if ( debug & TALLYDEBUG ) {
+           if ( debug & LOOKUPDEBUG ) {
                printf( "[arclookup]\t arc_parent %s arc_child %s\n" ,
                        arcp -> arc_parentp -> name ,
                        arcp -> arc_childp -> name );
                printf( "[arclookup]\t arc_parent %s arc_child %s\n" ,
                        arcp -> arc_parentp -> name ,
                        arcp -> arc_childp -> name );