gcore, handle exited threads better
[deliverable/binutils-gdb.git] / gprof / gmon_io.c
index 7218cee5fe911c0057b3f07c1ca3bde2234302ca..5686ebb6b99d679babd6374e012a97c10c2bae76 100644 (file)
@@ -1,13 +1,12 @@
 /* gmon_io.c - Input and output from/to gmon.out files.
 
 /* gmon_io.c - Input and output from/to gmon.out files.
 
-   Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005
-   Free Software Foundation, Inc.
+   Copyright (C) 1999-2020 Free Software Foundation, Inc.
 
    This file is part of GNU Binutils.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
 
    This file is part of GNU Binutils.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-   02111-1307, USA.  */
+   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+   02110-1301, USA.  */
 \f
 #include "gprof.h"
 \f
 #include "gprof.h"
+#include "binary-io.h"
 #include "search_list.h"
 #include "source.h"
 #include "symtab.h"
 #include "search_list.h"
 #include "source.h"
 #include "symtab.h"
@@ -61,7 +61,7 @@ int gmon_input = 0;
 int gmon_file_version = 0;     /* 0 == old (non-versioned) file format.  */
 
 static enum gmon_ptr_size
 int gmon_file_version = 0;     /* 0 == old (non-versioned) file format.  */
 
 static enum gmon_ptr_size
-gmon_get_ptr_size ()
+gmon_get_ptr_size (void)
 {
   int size;
 
 {
   int size;
 
@@ -87,7 +87,7 @@ gmon_get_ptr_size ()
 }
 
 static enum gmon_ptr_signedness
 }
 
 static enum gmon_ptr_signedness
-gmon_get_ptr_signedness ()
+gmon_get_ptr_signedness (void)
 {
   int sext;
 
 {
   int sext;
 
@@ -256,6 +256,9 @@ gmon_read_raw_arc (FILE *ifp, bfd_vma *fpc, bfd_vma *spc, unsigned long *cnt)
       *cnt = cnt64;
       break;
 #endif
       *cnt = cnt64;
       break;
 #endif
+
+    default:
+      return 1;
     }
   return 0;
 }
     }
   return 0;
 }
@@ -297,9 +300,7 @@ gmon_out_read (const char *filename)
   if (strcmp (filename, "-") == 0)
     {
       ifp = stdin;
   if (strcmp (filename, "-") == 0)
     {
       ifp = stdin;
-#ifdef SET_BINARY
       SET_BINARY (fileno (stdin));
       SET_BINARY (fileno (stdin));
-#endif
     }
   else
     {
     }
   else
     {
@@ -385,10 +386,10 @@ gmon_out_read (const char *filename)
       int samp_bytes, header_size = 0;
       unsigned long count;
       bfd_vma from_pc, self_pc;
       int samp_bytes, header_size = 0;
       unsigned long count;
       bfd_vma from_pc, self_pc;
-      static struct hdr h;
       UNIT raw_bin_count;
       struct hdr tmp;
       unsigned int version;
       UNIT raw_bin_count;
       struct hdr tmp;
       unsigned int version;
+      unsigned int hist_num_bins;
 
       /* Information from a gmon.out file is in two parts: an array of
         sampling hits within pc ranges, and the arcs.  */
 
       /* Information from a gmon.out file is in two parts: an array of
         sampling hits within pc ranges, and the arcs.  */
@@ -427,7 +428,7 @@ gmon_out_read (const char *filename)
           if (gmon_io_read_32 (ifp, &profrate))
            goto bad_gmon_file;
 
           if (gmon_io_read_32 (ifp, &profrate))
            goto bad_gmon_file;
 
-         if (!s_highpc)
+         if (!histograms)
            hz = profrate;
          else if (hz != (int) profrate)
            {
            hz = profrate;
          else if (hz != (int) profrate)
            {
@@ -477,35 +478,40 @@ gmon_out_read (const char *filename)
          done (1);
        }
 
          done (1);
        }
 
-      if (s_highpc && (tmp.low_pc != h.low_pc
-                      || tmp.high_pc != h.high_pc || tmp.ncnt != h.ncnt))
+      samp_bytes = tmp.ncnt - header_size;
+      hist_num_bins = samp_bytes / sizeof (UNIT);
+      if (histograms && (tmp.low_pc != histograms->lowpc
+                        || tmp.high_pc != histograms->highpc
+                        || (hist_num_bins != histograms->num_bins)))
        {
          fprintf (stderr, _("%s: incompatible with first gmon file\n"),
                   filename);
          done (1);
        }
 
        {
          fprintf (stderr, _("%s: incompatible with first gmon file\n"),
                   filename);
          done (1);
        }
 
-      h = tmp;
-      s_lowpc = (bfd_vma) h.low_pc;
-      s_highpc = (bfd_vma) h.high_pc;
-      lowpc = (bfd_vma) h.low_pc / sizeof (UNIT);
-      highpc = (bfd_vma) h.high_pc / sizeof (UNIT);
-      samp_bytes = h.ncnt - header_size;
-      hist_num_bins = samp_bytes / sizeof (UNIT);
+      if (!histograms)
+       {
+         num_histograms = 1;
+         histograms = (struct histogram *) xmalloc (sizeof (struct histogram));
+         histograms->lowpc = tmp.low_pc;
+         histograms->highpc = tmp.high_pc;
+         histograms->num_bins = hist_num_bins;
+         hist_scale = (double)((tmp.high_pc - tmp.low_pc) / sizeof (UNIT))
+           / hist_num_bins;
+         histograms->sample = (int *) xmalloc (hist_num_bins * sizeof (int));
+         memset (histograms->sample, 0,
+                 hist_num_bins * sizeof (int));
+       }
 
       DBG (SAMPLEDEBUG,
           printf ("[gmon_out_read] lowpc 0x%lx highpc 0x%lx ncnt %d\n",
 
       DBG (SAMPLEDEBUG,
           printf ("[gmon_out_read] lowpc 0x%lx highpc 0x%lx ncnt %d\n",
-                  (unsigned long) h.low_pc, (unsigned long) h.high_pc,
-                  h.ncnt);
-          printf ("[gmon_out_read]   s_lowpc 0x%lx   s_highpc 0x%lx\n",
-                  (unsigned long) s_lowpc, (unsigned long) s_highpc);
-          printf ("[gmon_out_read]     lowpc 0x%lx     highpc 0x%lx\n",
-                  (unsigned long) lowpc, (unsigned long) highpc);
+                  (unsigned long) tmp.low_pc, (unsigned long) tmp.high_pc,
+                  tmp.ncnt);
           printf ("[gmon_out_read] samp_bytes %d hist_num_bins %d\n",
                   samp_bytes, hist_num_bins));
 
       /* Make sure that we have sensible values.  */
           printf ("[gmon_out_read] samp_bytes %d hist_num_bins %d\n",
                   samp_bytes, hist_num_bins));
 
       /* Make sure that we have sensible values.  */
-      if (samp_bytes < 0 || lowpc > highpc)
+      if (samp_bytes < 0 || histograms->lowpc > histograms->highpc)
        {
          fprintf (stderr,
            _("%s: file '%s' does not appear to be in gmon.out format\n"),
        {
          fprintf (stderr,
            _("%s: file '%s' does not appear to be in gmon.out format\n"),
@@ -516,14 +522,6 @@ gmon_out_read (const char *filename)
       if (hist_num_bins)
        ++nhist;
 
       if (hist_num_bins)
        ++nhist;
 
-      if (!hist_sample)
-       {
-         hist_sample =
-           (int *) xmalloc (hist_num_bins * sizeof (hist_sample[0]));
-
-         memset (hist_sample, 0, hist_num_bins * sizeof (hist_sample[0]));
-       }
-
       for (i = 0; i < hist_num_bins; ++i)
        {
          if (fread (raw_bin_count, sizeof (raw_bin_count), 1, ifp) != 1)
       for (i = 0; i < hist_num_bins; ++i)
        {
          if (fread (raw_bin_count, sizeof (raw_bin_count), 1, ifp) != 1)
@@ -534,7 +532,8 @@ gmon_out_read (const char *filename)
              done (1);
            }
 
              done (1);
            }
 
-         hist_sample[i] += bfd_get_16 (core_bfd, (bfd_byte *) raw_bin_count);
+         histograms->sample[i]
+           += bfd_get_16 (core_bfd, (bfd_byte *) raw_bin_count);
        }
 
       /* The rest of the file consists of a bunch of
        }
 
       /* The rest of the file consists of a bunch of
@@ -551,8 +550,6 @@ gmon_out_read (const char *filename)
          cg_tally (from_pc, self_pc, count);
        }
 
          cg_tally (from_pc, self_pc, count);
        }
 
-      fclose (ifp);
-
       if (hz == HZ_WRONG)
        {
          /* How many ticks per second?  If we can't tell, report
       if (hz == HZ_WRONG)
        {
          /* How many ticks per second?  If we can't tell, report
@@ -573,6 +570,9 @@ gmon_out_read (const char *filename)
       done (1);
     }
 
       done (1);
     }
 
+  if (ifp != stdin)
+    fclose (ifp);
+
   if (output_style & STYLE_GMON_INFO)
     {
       printf (_("File `%s' (version %d) contains:\n"),
   if (output_style & STYLE_GMON_INFO)
     {
       printf (_("File `%s' (version %d) contains:\n"),
@@ -671,7 +671,7 @@ gmon_out_write (const char *filename)
            case ptr_64bit:
              hdrsize = GMON_HDRSIZE_OLDBSD_64;
              /* FIXME: Checking host compiler defines here means that we can't
            case ptr_64bit:
              hdrsize = GMON_HDRSIZE_OLDBSD_64;
              /* FIXME: Checking host compiler defines here means that we can't
-                use a cross gprof alpha OSF.  */ 
+                use a cross gprof alpha OSF.  */
 #if defined(__alpha__) && defined (__osf__)
              padsize = 4;
 #endif
 #if defined(__alpha__) && defined (__osf__)
              padsize = 4;
 #endif
@@ -681,9 +681,10 @@ gmon_out_write (const char *filename)
 
       /* Write the parts of the headers that are common to both the
         old BSD and 4.4BSD formats.  */
 
       /* Write the parts of the headers that are common to both the
         old BSD and 4.4BSD formats.  */
-      if (gmon_io_write_vma (ofp, s_lowpc)
-          || gmon_io_write_vma (ofp, s_highpc)
-          || gmon_io_write_32 (ofp, hist_num_bins * sizeof (UNIT) + hdrsize))
+      if (gmon_io_write_vma (ofp, histograms->lowpc)
+          || gmon_io_write_vma (ofp, histograms->highpc)
+          || gmon_io_write_32 (ofp, histograms->num_bins
+                              * sizeof (UNIT) + hdrsize))
        {
          perror (filename);
          done (1);
        {
          perror (filename);
          done (1);
@@ -711,9 +712,9 @@ gmon_out_write (const char *filename)
        }
 
       /* Dump the samples.  */
        }
 
       /* Dump the samples.  */
-      for (i = 0; i < hist_num_bins; ++i)
+      for (i = 0; i < histograms->num_bins; ++i)
        {
        {
-         bfd_put_16 (core_bfd, (bfd_vma) hist_sample[i],
+         bfd_put_16 (core_bfd, (bfd_vma) histograms->sample[i],
                      (bfd_byte *) &raw_bin_count[0]);
          if (fwrite (&raw_bin_count[0], sizeof (raw_bin_count), 1, ofp) != 1)
            {
                      (bfd_byte *) &raw_bin_count[0]);
          if (fwrite (&raw_bin_count[0], sizeof (raw_bin_count), 1, ofp) != 1)
            {
This page took 0.030954 seconds and 4 git commands to generate.