* gprof.h, gprof.c, printfgprof.c: Add support for two
authorPer Bothner <per@bothner.com>
Mon, 31 Aug 1992 03:34:15 +0000 (03:34 +0000)
committerPer Bothner <per@bothner.com>
Mon, 31 Aug 1992 03:34:15 +0000 (03:34 +0000)
output styles:  The default is similar to the old FSF gprof,
while -T sets the variable bsd_style_output, which causes
output matching Berkeley's gprof.  The biggest differences
are that with the FSF style output, the flat profile comes
before the call graph; numbers come before explanations;
and there is less gratuitous white space.
* gprof.h, gprof.c, printfgprof.c:  New discard_underscores
variable causes discarding of initial underscores when
printing symbol names.  It is set unless there is a "main"
symbol (without an underscore).
* printfgprof.c:  New function printnameonly(), called
by printname().  It handles stripping of initial '_',
as well as C++ name-demangling.
* gprof.callg, gprof.flat, make-c-prog.awk:  Removed.
It is just as convenient to edit blurbs.c directly.
* Makefile.in:  Removed rule for making blurbs.c.
* blurbs.c:  This is now a true source file (as opposed
to being generated from gprof.callg and gprof.flat).
Change style to use one long string literal, instead of
one literal per output line.  Add FSF-style blurb for call graph.

gprof/.Sanitize
gprof/ChangeLog
gprof/Makefile.in
gprof/blurbs.c
gprof/gprof.c
gprof/gprof.h
gprof/printgprof.c

index 2ee9399171f376bb15d2ebfe1e7433a76d4bff22..2afc0bbd2505c0b4b45499a1eb082b207de91ab6 100644 (file)
@@ -36,14 +36,11 @@ dummy.h
 gmon.h
 gprof.1
 gprof.c
-gprof.callg
-gprof.flat
 gprof.h
 hertz.c
 i386.c
 i386.h
 lookup.c
-make-c-prog.awk
 printgprof.c
 printlist.c
 sparc.c
index c84cf6946a9f3f2133940e9b63845f48a8c8c084..4277dfcc9e4ee2ec65804787508a887bc79806c9 100644 (file)
@@ -1,3 +1,27 @@
+Sun Aug 30 19:54:53 1992  Per Bothner  (bothner@rtl.cygnus.com)
+
+       * gprof.h, gprof.c, printfgprof.c:  Add support for two
+       output styles:  The default is similar to the old FSF gprof,
+       while -T sets the variable bsd_style_output, which causes
+       output matching Berkeley's gprof.  The biggest differences
+       are that with the FSF style output, the flat profile comes
+       before the call graph; numbers come before explanations;
+       and there is less gratuitous white space.
+       * gprof.h, gprof.c, printfgprof.c:  New discard_underscores
+       variable causes discarding of initial underscores when
+       printing symbol names.  It is set unless there is a "main"
+       symbol (without an underscore).
+       * printfgprof.c:  New function printnameonly(), called
+       by printname().  It handles stripping of initial '_',
+       as well as C++ name-demangling.
+       * gprof.callg, gprof.flat, make-c-prog.awk:  Removed.
+       It is just as convenient to edit blurbs.c directly.
+       * Makefile.in:  Removed rule for making blurbs.c.
+       * blurbs.c:  This is now a true source file (as opposed
+       to being generated from gprof.callg and gprof.flat).
+       Change style to use one long string literal, instead of
+       one literal per output line.  Add FSF-style blurb for call graph.
+
 Wed Aug 19 14:36:39 1992  Ian Lance Taylor  (ian@cygnus.com)
 
        * Makefile.in: always create installation directories.
index caf20773fc5a0aa5cab5c88ac9e444d36db9e866..26ef25abe6dc53e22ebab3cc7998bd4474924305 100644 (file)
@@ -53,12 +53,6 @@ install: all
 $(PROG):       $(OBJS)
        $(CC) $(CFLAGS) $(OBJS) -o $(PROG) $(LIBS)
 
-# Make blurbs.c from gprof.callg and gprof.flat
-blurbs.c: $(srcdir)/gprof.callg $(srcdir)/gprof.flat $(srcdir)/make-c-prog.awk
-       awk -f $(srcdir)/make-c-prog.awk > ./blurbs.c \
-               FUNCTION=flat_blurb  $(srcdir)/gprof.flat \
-               FUNCTION=callg_blurb $(srcdir)/gprof.callg \
-
 clean:
        -rm -f $(OBJS) core gprof nohup.out
 
index 1a2d3a956dfc6db508a7f4d14b648b3ef7ef9c9e..e586fa2d43cf29176936ffab87c42d2220d29138 100644 (file)
-/* ==> Do not modify this file!!  It is created automatically
-   by make-c-prog.awk; modify make-c-prog.awk instead.  <== */
-
 #include <stdio.h>
+#include "gprof.h"
 
 void
 flat_blurb (file)
      FILE *file;
 {
-  fputs ("\n", file);
-  fputs ("\n", file);
-  fputs ("\n", file);
-  fputs ("flat profile:\n", file);
-  fputs ("\n", file);
-  fputs (" %         the percentage of the total running time of the\n", file);
-  fputs ("time       program used by this function.\n", file);
-  fputs ("\n", file);
-  fputs ("cumulative a running sum of the number of seconds accounted\n", file);
-  fputs (" seconds   for by this function and those listed above it.\n", file);
-  fputs ("\n", file);
-  fputs (" self      the number of seconds accounted for by this\n", file);
-  fputs ("seconds    function alone.  This is the major sort for this\n", file);
-  fputs ("           listing.\n", file);
-  fputs ("\n", file);
-  fputs ("calls      the number of times this function was invoked, if\n", file);
-  fputs ("           this function is profiled, else blank.\n", file);
-  fputs (" \n", file);
-  fputs (" self      the average number of milliseconds spent in this\n", file);
-  fputs ("ms/call    function per call, if this function is profiled,\n", file);
-  fputs ("        else blank.\n", file);
-  fputs ("\n", file);
-  fputs (" total     the average number of milliseconds spent in this\n", file);
-  fputs ("ms/call    function and its descendents per call, if this \n", file);
-  fputs ("        function is profiled, else blank.\n", file);
-  fputs ("\n", file);
-  fputs ("name       the name of the function.  This is the minor sort\n", file);
-  fputs ("           for this listing. The index shows the location of\n", file);
-  fputs ("        the function in the gprof listing. If the index is\n", file);
-  fputs ("        in parenthesis it shows where it would appear in\n", file);
-  fputs ("        the gprof listing if it were to be printed.\n", file);
-  fputs ("\f\n", file);
+   fputs("\n\
+ %         the percentage of the total running time of the\n\
+time       program used by this function.\n\
+\n\
+cumulative a running sum of the number of seconds accounted\n\
+ seconds   for by this function and those listed above it.\n\
+\n\
+ self      the number of seconds accounted for by this\n\
+seconds    function alone.  This is the major sort for this\n\
+           listing.\n\
+\n\
+calls      the number of times this function was invoked, if\n\
+           this function is profiled, else blank.\n\
+ \n\
+ self      the average number of milliseconds spent in this\n\
+ms/call    function per call, if this function is profiled,\n\
+          else blank.\n\
+\n\
+ total     the average number of milliseconds spent in this\n\
+ms/call    function and its descendents per call, if this \n\
+          function is profiled, else blank.\n\
+\n\
+name       the name of the function.  This is the minor sort\n\
+           for this listing. The index shows the location of\n\
+          the function in the gprof listing. If the index is\n\
+          in parenthesis it shows where it would appear in\n\
+          the gprof listing if it were to be printed.\n\
+\f\n", file);
 }
 
+static char *callg_blurb_bsd = "\n\
+\n\
+\n\
+call graph profile:\n\
+          The sum of self and descendents is the major sort\n\
+          for this listing.\n\
+\n\
+          function entries:\n\
+\n\
+index     the index of the function in the call graph\n\
+          listing, as an aid to locating it (see below).\n\
+\n\
+%time     the percentage of the total time of the program\n\
+          accounted for by this function and its\n\
+          descendents.\n\
+\n\
+self      the number of seconds spent in this function\n\
+          itself.\n\
+\n\
+descendents\n\
+          the number of seconds spent in the descendents of\n\
+          this function on behalf of this function.\n\
+\n\
+called    the number of times this function is called (other\n\
+          than recursive calls).\n\
+\n\
+self      the number of times this function calls itself\n\
+          recursively.\n\
+\n\
+name      the name of the function, with an indication of\n\
+          its membership in a cycle, if any.\n\
+\n\
+index     the index of the function in the call graph\n\
+          listing, as an aid to locating it.\n\
+\n\
+\n\
+\n\
+          parent listings:\n\
+\n\
+self*     the number of seconds of this function's self time\n\
+          which is due to calls from this parent.\n\
+\n\
+descendents*\n\
+          the number of seconds of this function's\n\
+          descendent time which is due to calls from this\n\
+          parent.\n\
+\n\
+called**  the number of times this function is called by\n\
+          this parent.  This is the numerator of the\n\
+          fraction which divides up the function's time to\n\
+          its parents.\n\
+\n\
+total*    the number of times this function was called by\n\
+          all of its parents.  This is the denominator of\n\
+          the propagation fraction.\n\
+\n\
+parents   the name of this parent, with an indication of the\n\
+          parent's membership in a cycle, if any.\n\
+\n\
+index     the index of this parent in the call graph\n\
+          listing, as an aid in locating it.\n\
+\n\
+\n\
+\n\
+          children listings:\n\
+\n\
+self*     the number of seconds of this child's self time\n\
+          which is due to being called by this function.\n\
+\n\
+descendent*\n\
+          the number of seconds of this child's descendent's\n\
+          time which is due to being called by this\n\
+          function.\n\
+\n\
+called**  the number of times this child is called by this\n\
+          function.  This is the numerator of the\n\
+          propagation fraction for this child.\n\
+\n\
+total*    the number of times this child is called by all\n\
+          functions.  This is the denominator of the\n\
+          propagation fraction.\n\
+\n\
+children  the name of this child, and an indication of its\n\
+          membership in a cycle, if any.\n\
+\n\
+index     the index of this child in the call graph listing,\n\
+          as an aid to locating it.\n\
+\n\
+\n\
+\n\
+          * these fields are omitted for parents (or\n\
+          children) in the same cycle as the function.  If\n\
+          the function (or child) is a member of a cycle,\n\
+          the propagated times and propagation denominator\n\
+          represent the self time and descendent time of the\n\
+          cycle as a whole.\n\
+\n\
+          ** static-only parents and children are indicated\n\
+          by a call count of 0.\n\
+\n\
+\n\
+\n\
+          cycle listings:\n\
+          the cycle as a whole is listed with the same\n\
+          fields as a function entry.  Below it are listed\n\
+          the members of the cycle, and their contributions\n\
+          to the time and call counts of the cycle.\n\
+\f\n";
+
+static char *callg_blurb_fsf = "\n\
+ This table describes the call tree of the program, and was sorted by\n\
+ the total amount of time spent in each function and its children.\n\n\
+ Each entry in this table consists of several lines.  The line with the\n\
+ index number at the left hand margin lists the current function.\n\
+ The lines above it list the functions that called this function,\n\
+ and the lines below it list the functions this one called.\n\
+ This line lists:\n\
+     index     A unique number given to each element of the table.\n\
+               Index numbers are sorted numerically.\n\
+               The index number is printed next to every function name so\n\
+               it is easier to look up where the function in the table.\n\n\
+     % time    This is the percentage of the `total' time that was spent\n\
+               in this function and its children.  Note that due to\n\
+               different viewpoints, functions excluded by options, etc,\n\
+               these numbers will NOT add up to 100%.\n\n\
+     self      This is the total amount of time spent in this function.\n\n\
+     children  This is the total amount of time propagated into this\n\
+               function by its children.\n\n\
+     called    This is the number of times the function was called.\n\
+               If the function called itself recursively, the number\n\
+               only includes non-recursive calls, and is followed by\n\
+               a `+' and the number of recursive calls.\n\n\
+     name      The name of the current function.  The index number is\n\
+               printed after it.  If the function is a member of a\n\
+               cycle, the cycle number is printed between the\n\
+               function's name and the index number.\n\n\n\
+ For the function's parents, the fields have the following meanings:\n\n\
+     self      This is the amount of time that was propagated directly\n\
+               from the function into this parent.\n\n\
+     children  This is the amount of time that was propagated from\n\
+               the function's children into this parent.\n\n\
+     called    This is the number of times this parent called the\n\
+               function `/' the total number of times the function\n\
+               was called.  Recursive calls to the function are not\n\
+               included in the number after the `/'.\n\n\
+     name      This is the name of the parent.  The parent's index\n\
+               number is printed after it.  If the parent is a\n\
+               member of a cycle, the cycle number is printed between\n\
+               the name and the index number.\n\n\
+ If the parents of the function cannot be determined, the word\n\
+ `<spontaneous>' is printed in the `name' field, and all the other\n\
+ fields are blank.\n\n\
+ For the function's children, the fields have the following meanings:\n\n\
+     self      This is the amount of time that was propagated directly\n\
+               from the child into the function.\n\n\
+     children  This is the amount of time that was propagated from the\n\
+               child's children to the function.\n\n\
+     called    This is the number of times the function called\n\
+               this child `/' the total number of times the child\n\
+               was called.  Recursive calls by the child are not\n\
+               listed in the number after the `/'.\n\n\
+     name      This is the name of the child.  The child's index\n\
+               number is printed after it.  If the child is a\n\
+               member of a cycle, the cycle number is printed\n\
+               between the name and the index number.\n\n\
+ If there are any cycles (circles) in the call graph, there is an\n\
+ entry for the cycle-as-a-whole.  This entry shows who called the\n\
+ cycle (as parents) and the members of the cycle (as children.)\n\
+ The `+' recursive calls entry shows the number of function calls that\n\
+ were internal to the cycle, and the calls entry for each member shows,\n\
+ for that member, how many times it was called from other members of\n\
+ the cycle.\n\n";
+
 void
 callg_blurb (file)
      FILE *file;
 {
-  fputs ("\n", file);
-  fputs ("\n", file);
-  fputs ("\n", file);
-  fputs ("call graph profile:\n", file);
-  fputs ("          The sum of self and descendents is the major sort\n", file);
-  fputs ("          for this listing.\n", file);
-  fputs ("\n", file);
-  fputs ("          function entries:\n", file);
-  fputs ("\n", file);
-  fputs ("index     the index of the function in the call graph\n", file);
-  fputs ("          listing, as an aid to locating it (see below).\n", file);
-  fputs ("\n", file);
-  fputs ("%time     the percentage of the total time of the program\n", file);
-  fputs ("          accounted for by this function and its\n", file);
-  fputs ("          descendents.\n", file);
-  fputs ("\n", file);
-  fputs ("self      the number of seconds spent in this function\n", file);
-  fputs ("          itself.\n", file);
-  fputs ("\n", file);
-  fputs ("descendents\n", file);
-  fputs ("          the number of seconds spent in the descendents of\n", file);
-  fputs ("          this function on behalf of this function.\n", file);
-  fputs ("\n", file);
-  fputs ("called    the number of times this function is called (other\n", file);
-  fputs ("          than recursive calls).\n", file);
-  fputs ("\n", file);
-  fputs ("self      the number of times this function calls itself\n", file);
-  fputs ("          recursively.\n", file);
-  fputs ("\n", file);
-  fputs ("name      the name of the function, with an indication of\n", file);
-  fputs ("          its membership in a cycle, if any.\n", file);
-  fputs ("\n", file);
-  fputs ("index     the index of the function in the call graph\n", file);
-  fputs ("          listing, as an aid to locating it.\n", file);
-  fputs ("\n", file);
-  fputs ("\n", file);
-  fputs ("\n", file);
-  fputs ("          parent listings:\n", file);
-  fputs ("\n", file);
-  fputs ("self*     the number of seconds of this function's self time\n", file);
-  fputs ("          which is due to calls from this parent.\n", file);
-  fputs ("\n", file);
-  fputs ("descendents*\n", file);
-  fputs ("          the number of seconds of this function's\n", file);
-  fputs ("          descendent time which is due to calls from this\n", file);
-  fputs ("          parent.\n", file);
-  fputs ("\n", file);
-  fputs ("called**  the number of times this function is called by\n", file);
-  fputs ("          this parent.  This is the numerator of the\n", file);
-  fputs ("          fraction which divides up the function's time to\n", file);
-  fputs ("          its parents.\n", file);
-  fputs ("\n", file);
-  fputs ("total*    the number of times this function was called by\n", file);
-  fputs ("          all of its parents.  This is the denominator of\n", file);
-  fputs ("          the propagation fraction.\n", file);
-  fputs ("\n", file);
-  fputs ("parents   the name of this parent, with an indication of the\n", file);
-  fputs ("          parent's membership in a cycle, if any.\n", file);
-  fputs ("\n", file);
-  fputs ("index     the index of this parent in the call graph\n", file);
-  fputs ("          listing, as an aid in locating it.\n", file);
-  fputs ("\n", file);
-  fputs ("\n", file);
-  fputs ("\n", file);
-  fputs ("          children listings:\n", file);
-  fputs ("\n", file);
-  fputs ("self*     the number of seconds of this child's self time\n", file);
-  fputs ("          which is due to being called by this function.\n", file);
-  fputs ("\n", file);
-  fputs ("descendent*\n", file);
-  fputs ("          the number of seconds of this child's descendent's\n", file);
-  fputs ("          time which is due to being called by this\n", file);
-  fputs ("          function.\n", file);
-  fputs ("\n", file);
-  fputs ("called**  the number of times this child is called by this\n", file);
-  fputs ("          function.  This is the numerator of the\n", file);
-  fputs ("          propagation fraction for this child.\n", file);
-  fputs ("\n", file);
-  fputs ("total*    the number of times this child is called by all\n", file);
-  fputs ("          functions.  This is the denominator of the\n", file);
-  fputs ("          propagation fraction.\n", file);
-  fputs ("\n", file);
-  fputs ("children  the name of this child, and an indication of its\n", file);
-  fputs ("          membership in a cycle, if any.\n", file);
-  fputs ("\n", file);
-  fputs ("index     the index of this child in the call graph listing,\n", file);
-  fputs ("          as an aid to locating it.\n", file);
-  fputs ("\n", file);
-  fputs ("\n", file);
-  fputs ("\n", file);
-  fputs ("          * these fields are omitted for parents (or\n", file);
-  fputs ("          children) in the same cycle as the function.  If\n", file);
-  fputs ("          the function (or child) is a member of a cycle,\n", file);
-  fputs ("          the propagated times and propagation denominator\n", file);
-  fputs ("          represent the self time and descendent time of the\n", file);
-  fputs ("          cycle as a whole.\n", file);
-  fputs ("\n", file);
-  fputs ("          ** static-only parents and children are indicated\n", file);
-  fputs ("          by a call count of 0.\n", file);
-  fputs ("\n", file);
-  fputs ("\n", file);
-  fputs ("\n", file);
-  fputs ("          cycle listings:\n", file);
-  fputs ("          the cycle as a whole is listed with the same\n", file);
-  fputs ("          fields as a function entry.  Below it are listed\n", file);
-  fputs ("          the members of the cycle, and their contributions\n", file);
-  fputs ("          to the time and call counts of the cycle.\n", file);
-  fputs ("\f\n", file);
+    if (bsd_style_output)
+       fputs(callg_blurb_bsd, file);
+    else
+       fputs(callg_blurb_fsf, file);
 }
index 5061efa56ed86f857fa40a1dc3f0eaece6a4d782..6994d8f5cb6f4585248b8ce5c00fc1fd219ff9a5 100644 (file)
@@ -38,6 +38,9 @@ char  *whoami = "gprof";
      */
 char   *defaultEs[] = { "mcount" , "__mcleanup" , 0 };
 
+int discard_underscores = 1; /* Should we discard initial underscores? */
+int bsd_style_output = 0; /* As opposed to FSF style output */
+
 main(argc, argv)
     int argc;
     char **argv;
@@ -102,6 +105,9 @@ main(argc, argv)
        case 's':
            sflag = TRUE;
            break;
+       case 'T': /* "Traditional" output format */
+           bsd_style_output = 1;
+           break;
        case 'z':
            zflag = TRUE;
            break;
@@ -165,14 +171,14 @@ main(argc, argv)
         *      assemble the dynamic profile
         */
     timesortnlp = doarcs();
-       /*
-        *      print the dynamic profile
-        */
-    printgprof( timesortnlp ); 
-       /*
-        *      print the flat profile
-        */
-    printprof();       
+       
+    if (bsd_style_output) {
+       printgprof( timesortnlp );      /* print the dynamic profile */
+       printprof();  /* print the flat profile */
+    } else {
+       printprof();  /* print the flat profile */
+       printgprof( timesortnlp );      /* print the dynamic profile */
+    }
        /*
         *      print the index
         */
@@ -230,7 +236,7 @@ bfd *abfd;
     i = get_symtab_upper_bound (abfd); /* This will probably give us more
                                         * than we need, but that's ok.
                                         */
-    syms = (asymbol**)malloc (i);
+    syms = (asymbol**)xmalloc (i);
     nosyms = bfd_canonicalize_symtab (abfd, syms);
 
     nname = 0;
@@ -265,8 +271,16 @@ bfd        *abfd;
 #          endif DEBUG
        continue;
       }
+      /* Symbol offsets are always section-relative. */
       npe->value = syms[i]->value + syms[i]->section->vma;
       npe->name = syms[i]->name;
+
+      /* If we see "main" without an initial '_', we assume
+        names are *not* prefixed by '_'. */
+      if (npe->name[0] == 'm' && discard_underscores
+         && strcmp(npe->name, "main") == 0)
+         discard_underscores = 0;
+
 #      ifdef DEBUG
       if ( debug & AOUTDEBUG ) {
        printf( "[getsymtab] %d %s 0x%08x\n" ,
index 52cf896567bf7a390e9c9b89e32f40e2d7838906..28813a3011d675266aa706e3ae5ad75ced768ad7 100644 (file)
@@ -68,6 +68,9 @@ char  *gmonname;
 #define        GMONNAME                "gmon.out"
 #define        GMONSUM                 "gmon.sum"
 
+extern int bsd_style_output;
+extern int discard_underscores;
+
     /*
      * a constructed arc,
      *     with pointers to the namelist entry of the parent and the child,
@@ -92,7 +95,7 @@ typedef struct arcstruct      arctype;
      * its address, the number of calls and compute its share of cpu time.
      */
 struct nl {
-    char               *name;          /* the name */
+    CONST char         *name;          /* the name */
     unsigned long      value;          /* the pc entry point */
     unsigned long      svalue;         /* entry point aligned to histograms */
     double             time;           /* ticks in this routine */
@@ -255,6 +258,7 @@ FILE                *openpfile();
                printprof();
                readsamples();
 */
+int            printnameonly();
 unsigned long  reladdr();
 /*
                sortchildren();
index 5ef0c87b8cddd428f30f55ec5a7543fed1f03df7..868d647c3ad9ff3af6bbf33432b8284b12ea6053 100644 (file)
@@ -22,6 +22,7 @@ static char sccsid[] = "@(#)printgprof.c      5.7 (Berkeley) 6/1/90";
 #endif /* not lint */
 
 #include "gprof.h"
+#include <demangle.h>
 
 printprof()
 {
@@ -30,7 +31,15 @@ printprof()
     int                        index, timecmp();
 
     actime = 0.0;
-    printf( "\f\n" );
+    if ( bsd_style_output ) {
+       printf( "\f\n" );
+       if ( bflag) {
+           printf( "\n\n\nflat profile:\n" );
+           flat_blurb(stdout);
+       }
+    }
+    else
+       printf ("Flat profile:\n");
     flatprofheader();
        /*
         *      Sort the symbol table in by time
@@ -49,6 +58,9 @@ printprof()
     }
     actime = 0.0;
     cfree( sortednlp );
+    if ( bflag && !bsd_style_output ) {
+       flat_blurb(stdout);
+    }
 }
 
 timecmp( npp1 , npp2 )
@@ -76,20 +88,23 @@ timecmp( npp1 , npp2 )
 flatprofheader()
 {
     
-    if ( bflag ) {
-       flat_blurb(stdout);
-    }
-    printf( "\ngranularity: each sample hit covers %d byte(s)" ,
-           (long) scale * sizeof(UNIT) );
-    if ( totime > 0.0 ) {
-       printf( " for %.2f%% of %.2f seconds\n\n" ,
-               100.0/totime , totime / hz );
-    } else {
-       printf( " no time accumulated\n\n" );
+    if (bsd_style_output) {
+       printf( "\ngranularity: each sample hit covers %d byte(s)" ,
+              (long) scale * sizeof(UNIT) );
+       if ( totime > 0.0 ) {
+           printf( " for %.2f%% of %.2f seconds\n\n" ,
+                  100.0/totime , totime / hz );
+       } else {
+           printf( " no time accumulated\n\n" );
            /*
             *  this doesn't hurt since all the numerators will be zero.
             */
-       totime = 1.0;
+           totime = 1.0;
+       }
+    }
+    else {
+       printf( "\nEach sample counts as %g seconds.\n",
+              1.0 / hz);
     }
     printf( "%5.5s %10.10s %8.8s %8.8s %8.8s %8.8s  %-8.8s\n" ,
            "%  " , "cumulative" , "self  " , "" , "self  " , "total " , "" );
@@ -106,8 +121,12 @@ flatprofline( np )
        return;
     }
     actime += np -> time;
-    printf( "%5.1f %10.2f %8.2f" ,
-       100 * np -> time / totime , actime / hz , np -> time / hz );
+    if (bsd_style_output)
+       printf( "%5.1f %10.2f %8.2f" ,
+              100 * np -> time / totime , actime / hz , np -> time / hz );
+    else
+       printf( "%6.2f %9.2f %8.2f" ,
+              100 * np -> time / totime , actime / hz , np -> time / hz );
     if ( np -> ncall != 0 ) {
        printf( " %8d %8.2f %8.2f  " , np -> ncall ,
            1000 * np -> time / hz / np -> ncall ,
@@ -115,16 +134,21 @@ flatprofline( np )
     } else {
        printf( " %8.8s %8.8s %8.8s  " , "" , "" , "" );
     }
-    printname( np );
+    if (bsd_style_output)
+       printname( np );
+    else
+       printnameonly( np );
     printf( "\n" );
 }
 
 gprofheader()
 {
 
-    if ( bflag ) {
-       callg_blurb(stdout);
-    }
+    if (!bsd_style_output)
+       if (bflag)
+           printf ("\t\t     Call graph (explanation follows)\n\n");
+       else
+           printf ("\t\t\tCall graph\n\n");
     printf( "\ngranularity: each sample hit covers %d byte(s)" ,
            (long) scale * sizeof(UNIT) );
     if ( printtime > 0.0 ) {
@@ -137,14 +161,18 @@ gprofheader()
             */
        printtime = 1.0;
     }
-    printf( "%6.6s %5.5s %7.7s %11.11s %7.7s/%-7.7s     %-8.8s\n" ,
-       "" , "" , "" , "" , "called" , "total" , "parents");
-    printf( "%-6.6s %5.5s %7.7s %11.11s %7.7s+%-7.7s %-8.8s\t%5.5s\n" ,
-       "index" , "%time" , "self" , "descendents" ,
-       "called" , "self" , "name" , "index" );
-    printf( "%6.6s %5.5s %7.7s %11.11s %7.7s/%-7.7s     %-8.8s\n" ,
-       "" , "" , "" , "" , "called" , "total" , "children");
-    printf( "\n" );
+    if (bsd_style_output) {
+       printf( "%6.6s %5.5s %7.7s %11.11s %7.7s/%-7.7s     %-8.8s\n" ,
+              "" , "" , "" , "" , "called" , "total" , "parents");
+       printf( "%-6.6s %5.5s %7.7s %11.11s %7.7s+%-7.7s %-8.8s\t%5.5s\n" ,
+              "index" , "%time" , "self" , "descendents" ,
+              "called" , "self" , "name" , "index" );
+       printf( "%6.6s %5.5s %7.7s %11.11s %7.7s/%-7.7s     %-8.8s\n" ,
+              "" , "" , "" , "" , "called" , "total" , "children");
+       printf( "\n" );
+    } else {
+       printf( "index %% time    self  children    called     name\n" );
+    }
 }
 
 gprofline( np )
@@ -153,11 +181,13 @@ gprofline( np )
     char       kirkbuffer[ BUFSIZ ];
 
     sprintf( kirkbuffer , "[%d]" , np -> index );
-    printf( "%-6.6s %5.1f %7.2f %11.2f" ,
-           kirkbuffer ,
-           100 * ( np -> propself + np -> propchild ) / printtime ,
-           np -> propself / hz ,
-           np -> propchild / hz );
+    printf(bsd_style_output
+          ? "%-6.6s %5.1f %7.2f %11.2f"
+          : "%-6.6s %5.1f %7.2f %7.2f" ,
+          kirkbuffer ,
+          100 * ( np -> propself + np -> propchild ) / printtime ,
+          np -> propself / hz ,
+          np -> propchild / hz );
     if ( ( np -> ncall + np -> selfcalls ) != 0 ) {
        printf( " %7d" , np -> ncall );
        if ( np -> selfcalls != 0 ) {
@@ -181,6 +211,9 @@ printgprof(timesortnlp)
        /*
         *      Print out the structured profiling list
         */
+    if ( bflag && bsd_style_output ) {
+       callg_blurb(stdout);
+    }
     gprofheader();
     for ( index = 0 ; index < nname + ncycle ; index ++ ) {
        parentp = timesortnlp[ index ];
@@ -205,11 +238,16 @@ printgprof(timesortnlp)
            gprofline( parentp );
            printchildren( parentp );
        }
-       printf( "\n" );
+       if (bsd_style_output)
+           printf( "\n" );
        printf( "-----------------------------------------------\n" );
-       printf( "\n" );
+       if (bsd_style_output)
+           printf( "\n" );
     }
     cfree( timesortnlp );
+    if ( bflag && !bsd_style_output) {
+       callg_blurb(stdout);
+    }
 }
 
     /*
@@ -267,7 +305,9 @@ printparents( childp )
        cycleheadp = childp;
     }
     if ( childp -> parents == 0 ) {
-       printf( "%6.6s %5.5s %7.7s %11.11s %7.7s %7.7s     <spontaneous>\n" ,
+       printf(bsd_style_output 
+              ? "%6.6s %5.5s %7.7s %11.11s %7.7s %7.7s     <spontaneous>\n"
+              : "%6.6s %5.5s %7.7s %7.7s %7.7s %7.7s     <spontaneous>\n" ,
                "" , "" , "" , "" , "" , "" );
        return;
     }
@@ -279,7 +319,9 @@ printparents( childp )
                /*
                 *      selfcall or call among siblings
                 */
-           printf( "%6.6s %5.5s %7.7s %11.11s %7d %7.7s     " ,
+           printf(bsd_style_output
+                  ? "%6.6s %5.5s %7.7s %11.11s %7d %7.7s     "
+                  : "%6.6s %5.5s %7.7s %7.7s %7d %7.7s     " ,
                    "" , "" , "" , "" ,
                    arcp -> arc_count , "" );
            printname( parentp );
@@ -288,7 +330,9 @@ printparents( childp )
                /*
                 *      regular parent of child
                 */
-           printf( "%6.6s %5.5s %7.2f %11.2f %7d/%-7d     " ,
+           printf(bsd_style_output
+                  ? "%6.6s %5.5s %7.2f %11.2f %7d/%-7d     "
+                  : "%6.6s %5.5s %7.2f %7.2f %7d/%-7d     ",
                    "" , "" ,
                    arcp -> arc_time / hz , arcp -> arc_childtime / hz ,
                    arcp -> arc_count , cycleheadp -> ncall );
@@ -313,39 +357,66 @@ printchildren( parentp )
                /*
                 *      self call or call to sibling
                 */
-           printf( "%6.6s %5.5s %7.7s %11.11s %7d %7.7s     " ,
-                   "" , "" , "" , "" , arcp -> arc_count , "" );
+           printf(bsd_style_output
+                  ? "%6.6s %5.5s %7.7s %11.11s %7d %7.7s     "
+                  : "%6.6s %5.5s %7.7s %7.7s %7d %7.7s     " ,
+                  "" , "" , "" , "" , arcp -> arc_count , "" );
            printname( childp );
            printf( "\n" );
        } else {
                /*
                 *      regular child of parent
                 */
-           printf( "%6.6s %5.5s %7.2f %11.2f %7d/%-7d     " ,
-                   "" , "" ,
-                   arcp -> arc_time / hz , arcp -> arc_childtime / hz ,
-                   arcp -> arc_count , childp -> cyclehead -> ncall );
+           printf(bsd_style_output
+                  ? "%6.6s %5.5s %7.2f %11.2f %7d/%-7d     "
+                  : "%6.6s %5.5s %7.2f %7.2f %7d/%-7d     " ,
+                  "" , "" ,
+                  arcp -> arc_time / hz , arcp -> arc_childtime / hz ,
+                  arcp -> arc_count , childp -> cyclehead -> ncall );
            printname( childp );
            printf( "\n" );
        }
     }
 }
 
+/* Print name of symbol.  Return number of characters printed. */
+
+int
+printnameonly ( selfp )
+    nltype     *selfp;
+{
+    int size = 0;
+    CONST char *name = selfp->name;
+    if (name != NULL) {
+       char *demangled = NULL;
+       if (!bsd_style_output) {
+           if (name[0] == '_' && name[1] && discard_underscores)
+               name++;
+           demangled = cplus_demangle (name, DMGL_ANSI|DMGL_PARAMS);
+           if (demangled)
+               name = demangled;
+       }
+       printf( "%s" , name );
+       size = strlen (name);
+       if (demangled)
+           free (demangled);
+#ifdef DEBUG
+       if ( debug & DFNDEBUG ) {
+           printf( "{%d} " , selfp -> toporder );
+       }
+       if ( debug & PROPDEBUG ) {
+           printf( "%5.2f%% " , selfp -> propfraction );
+       }
+#endif DEBUG
+    }
+    return size;
+}
+
 printname( selfp )
     nltype     *selfp;
 {
+    printnameonly (selfp);
 
-    if ( selfp -> name != 0 ) {
-       printf( "%s" , selfp -> name );
-#      ifdef DEBUG
-           if ( debug & DFNDEBUG ) {
-               printf( "{%d} " , selfp -> toporder );
-           }
-           if ( debug & PROPDEBUG ) {
-               printf( "%5.2f%% " , selfp -> propfraction );
-           }
-#      endif DEBUG
-    }
     if ( selfp -> cycleno != 0 ) {
        printf( " <cycle %d>" , selfp -> cycleno );
     }
@@ -643,7 +714,7 @@ printindex()
     nltype             **namesortnlp;
     register nltype    *nlp;
     int                        index, nnames, todo, i, j;
-    char               peterbuffer[ BUFSIZ ];
+    char               peterbuffer[20];
 
        /*
         *      Now, sort regular function name alphbetically
@@ -673,7 +744,13 @@ printindex()
                sprintf( peterbuffer , "(%d)" , nlp -> index );
            }
            if ( j < nnames ) {
-               printf( "%6.6s %-19.19s" , peterbuffer , nlp -> name );
+               printf( "%6.6s " , peterbuffer );
+               if (bsd_style_output)
+                   printf ("%-19.19s" , nlp->name);
+               else {
+                   int size = printnameonly(nlp);
+                   for ( ; size < 19; size++) putchar(' ');
+               }
            } else {
                printf( "%6.6s " , peterbuffer );
                sprintf( peterbuffer , "<cycle %d>" , nlp -> cycleno );
@@ -684,3 +761,29 @@ printindex()
     }
     cfree( namesortnlp );
 }
+
+PTR
+xmalloc (size)
+     long size;
+{
+    PTR val = malloc (size);
+    if (val == NULL) {
+       fprintf (stderr, "virtual memory exhaused\n");
+       exit (1);
+    }
+    return val;
+}
+
+PTR
+xrealloc (oldval, size)
+     PTR oldval;
+     long size;
+{
+    PTR val = realloc (oldval, size);
+    if (val == NULL) {
+       fprintf (stderr, "virtual memory exhaused\n");
+       exit (1);
+    }
+    return val;
+}
+