fgetws implementation.
[kopensolaris-gnu/glibc.git] / elf / sprof.c
index f54a616..b4711e9 100644 (file)
@@ -1,5 +1,5 @@
 /* Read and display shared object profiling data.
-   Copyright (C) 1997, 1998 Free Software Foundation, Inc.
+   Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
 
 #include <sys/param.h>
 #include <sys/stat.h>
 
-/* Undefine the following line line in the production version.  */
-/* #define _NDEBUG 1 */
-#include <assert.h>
-
 /* Get libc version number.  */
 #include "../version.h"
 
@@ -74,6 +70,8 @@ void (*argp_program_version_hook) (FILE *, struct argp_state *) = print_version;
 static const struct argp_option options[] =
 {
   { NULL, 0, NULL, 0, N_("Output selection:") },
+  { "call-pairs", 'c', NULL, 0,
+    N_("print list of count paths and their number of use") },
   { "flat-profile", 'p', NULL, 0,
     N_("generate flat profile with counts and ticks") },
   { "graph", 'q', NULL, 0, N_("generate call graph") },
@@ -104,6 +102,7 @@ static enum
   NONE = 0,
   FLAT_MODE = 1 << 0,
   CALL_GRAPH_MODE = 1 << 1,
+  CALL_PAIRS = 1 << 2,
 
   DEFAULT_MODE = FLAT_MODE | CALL_GRAPH_MODE
 } mode;
@@ -218,6 +217,7 @@ static void read_symbols (struct shobj *shobj);
 static void add_arcs (struct profdata *profdata);
 static void generate_flat_profile (struct profdata *profdata);
 static void generate_call_graph (struct profdata *profdata);
+static void generate_call_pair_list (struct profdata *profdata);
 
 
 int
@@ -311,6 +311,9 @@ no filename for profiling data given and shared object `%s' has no soname"),
   if (mode & CALL_GRAPH_MODE)
     generate_call_graph (profdata_handle);
 
+  if (mode & CALL_PAIRS)
+    generate_call_pair_list (profdata_handle);
+
   /* Free the resources.  */
   unload_shobj (shobj_handle);
   unload_profdata (profdata_handle);
@@ -325,6 +328,9 @@ parse_opt (int key, char *arg, struct argp_state *state)
 {
   switch (key)
     {
+    case 'c':
+      mode |= CALL_PAIRS;
+      break;
     case 'p':
       mode |= FLAT_MODE;
       break;
@@ -351,7 +357,7 @@ Copyright (C) %s Free Software Foundation, Inc.\n\
 This is free software; see the source for copying conditions.  There is NO\n\
 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
 "),
-          "1997, 1998");
+          "1999");
   fprintf (stream, gettext ("Written by %s.\n"), "Ulrich Drepper");
 }
 
@@ -449,7 +455,7 @@ load_shobj (const char *name)
   else
     log_hashfraction = -1;
   if (do_test)
-    printf ("hashfraction = %d\ndivider = %d\n",
+    printf ("hashfraction = %d\ndivider = %Zu\n",
            result->hashfraction,
            result->hashfraction * sizeof (struct here_fromstruct));
   result->tossize = textsize / HASHFRACTION;
@@ -677,7 +683,8 @@ load_profdata (const char *name, struct shobj *shobj)
 
   if (st.st_size != shobj->expected_size)
     {
-      error (0, 0, _("profiling data file `%s' does match shared object `%s'"),
+      error (0, 0,
+            _("profiling data file `%s' does not match shared object `%s'"),
             name, shobj->name);
       close (fd);
       return NULL;
@@ -1184,7 +1191,7 @@ generate_call_graph (struct profdata *profdata)
            printf ("            %8.2f%8.2f%9" PRIdMAX "/%-9" PRIdMAX "   %s",
                    (runp->idx != (size_t) -1l
                     ? sortsym[runp->idx]->ticks * tick_unit : 0.0),
-                   0.0, /* FIXME: what's time for the childern, recursive */
+                   0.0, /* FIXME: what's time for the children, recursive */
                    runp->count, sortsym[cnt]->calls,
                    (runp->idx != (size_t) -1l ?
                     sortsym[runp->idx]->name : "<UNKNOWN>"));
@@ -1197,12 +1204,12 @@ generate_call_graph (struct profdata *profdata)
          }
 
        /* Info abount the function itself.  */
-       n = printf ("[%d]", cnt);
+       n = printf ("[%Zu]", cnt);
        printf ("%*s%5.1f%8.2f%8.2f%9" PRIdMAX "         %s [%Zd]\n",
                7 - n, " ",
                total_ticks ? (100.0 * sortsym[cnt]->ticks) / total_ticks : 0,
                sortsym[cnt]->ticks * tick_unit,
-               0.0, /* FIXME: what's time for the childern, recursive */
+               0.0, /* FIXME: what's time for the children, recursive */
                sortsym[cnt]->calls,
                sortsym[cnt]->name, cnt);
 
@@ -1213,7 +1220,7 @@ generate_call_graph (struct profdata *profdata)
            printf ("            %8.2f%8.2f%9" PRIdMAX "/",
                    (runp->idx != (size_t) -1l
                     ? sortsym[runp->idx]->ticks * tick_unit : 0.0),
-                   0.0, /* FIXME: what's time for the childern, recursive */
+                   0.0, /* FIXME: what's time for the children, recursive */
                    runp->count);
 
            if (runp->idx != (size_t) -1l)
@@ -1230,3 +1237,39 @@ generate_call_graph (struct profdata *profdata)
        fputs ("-----------------------------------------------\n", stdout);
       }
 }
+
+
+static void
+generate_call_pair_list (struct profdata *profdata)
+{
+  size_t cnt;
+
+  for (cnt = 0; cnt < symidx; ++cnt)
+    if (sortsym[cnt]->froms != NULL || sortsym[cnt]->tos != NULL)
+      {
+       struct arc_list *runp;
+
+       /* First print the incoming arcs.  */
+       runp = sortsym[cnt]->froms;
+       while (runp != NULL)
+         {
+           if (runp->idx == (size_t) -1l)
+             printf ("\
+<UNKNOWN>                          %-34s %9" PRIdMAX "\n",
+                     sortsym[cnt]->name, runp->count);
+           runp = runp->next;
+         }
+
+       /* Next the outgoing arcs.  */
+       runp = sortsym[cnt]->tos;
+       while (runp != NULL)
+         {
+           printf ("%-34s %-34s %9" PRIdMAX "\n",
+                   sortsym[cnt]->name,
+                   (runp->idx != (size_t) -1l
+                    ? sortsym[runp->idx]->name : "<UNKNOWN>"),
+                   runp->count);
+           runp = runp->next;
+         }
+      }
+}