* gmon_io.h: Don't include sysdep.h here.
[binutils-gdb.git] / gprof / gmon_io.c
index 46c6f9b5b74d8ebac3590540721723018c3a0554..bf74c263bd0ee6b1f1e251593a4e466346b79471 100644 (file)
@@ -1,12 +1,13 @@
 /* gmon_io.c - Input and output from/to gmon.out files.
 
 /* gmon_io.c - Input and output from/to gmon.out files.
 
-   Copyright 2000, 2001, 2002 Free Software Foundation, Inc.
+   Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008
+   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"
 #include "hist.h"
 #include "libiberty.h"
 
 #include "hist.h"
 #include "libiberty.h"
 
-static int gmon_io_read_64 PARAMS ((FILE *, BFD_HOST_U_64_BIT *));
-static int gmon_io_write_64 PARAMS ((FILE *, BFD_HOST_U_64_BIT));
+enum gmon_ptr_size {
+  ptr_32bit,
+  ptr_64bit
+};
+
+enum gmon_ptr_signedness {
+  ptr_signed,
+  ptr_unsigned
+};
+
+static enum gmon_ptr_size gmon_get_ptr_size (void);
+static enum gmon_ptr_signedness gmon_get_ptr_signedness (void);
+
+#ifdef BFD_HOST_U_64_BIT
+static int gmon_io_read_64 (FILE *, BFD_HOST_U_64_BIT *);
+static int gmon_io_write_64 (FILE *, BFD_HOST_U_64_BIT);
+#endif
 static int gmon_read_raw_arc
 static int gmon_read_raw_arc
-  PARAMS ((FILE *, bfd_vma *, bfd_vma *, unsigned long *));
+  (FILE *, bfd_vma *, bfd_vma *, unsigned long *);
 static int gmon_write_raw_arc
 static int gmon_write_raw_arc
-  PARAMS ((FILE *, bfd_vma, bfd_vma, unsigned long));
+  (FILE *, bfd_vma, bfd_vma, unsigned long);
 
 int gmon_input = 0;
 int gmon_file_version = 0;     /* 0 == old (non-versioned) file format.  */
 
 
 int gmon_input = 0;
 int gmon_file_version = 0;     /* 0 == old (non-versioned) file format.  */
 
+static enum gmon_ptr_size
+gmon_get_ptr_size ()
+{
+  int size;
+
+  /* Pick best size for pointers.  Start with the ELF size, and if not
+     elf go with the architecture's address size.  */
+  size = bfd_get_arch_size (core_bfd);
+  if (size == -1)
+    size = bfd_arch_bits_per_address (core_bfd);
+
+  switch (size)
+    {
+    case 32:
+      return ptr_32bit;
+
+    case 64:
+      return ptr_64bit;
+
+    default:
+      fprintf (stderr, _("%s: address size has unexpected value of %u\n"),
+              whoami, size);
+      done (1);
+    }
+}
+
+static enum gmon_ptr_signedness
+gmon_get_ptr_signedness ()
+{
+  int sext;
+
+  /* Figure out whether to sign extend.  If BFD doesn't know, assume no.  */
+  sext = bfd_get_sign_extend_vma (core_bfd);
+  if (sext == -1)
+    return ptr_unsigned;
+  return (sext ? ptr_signed : ptr_unsigned);
+}
+
 int
 int
-gmon_io_read_32 (ifp, valp)
-     FILE *ifp;
-     unsigned int *valp;
+gmon_io_read_32 (FILE *ifp, unsigned int *valp)
 {
   char buf[4];
 
 {
   char buf[4];
 
@@ -57,10 +110,9 @@ gmon_io_read_32 (ifp, valp)
   return 0;
 }
 
   return 0;
 }
 
+#ifdef BFD_HOST_U_64_BIT
 static int
 static int
-gmon_io_read_64 (ifp, valp)
-     FILE *ifp;
-     BFD_HOST_U_64_BIT *valp;
+gmon_io_read_64 (FILE *ifp, BFD_HOST_U_64_BIT *valp)
 {
   char buf[8];
 
 {
   char buf[8];
 
@@ -69,42 +121,45 @@ gmon_io_read_64 (ifp, valp)
   *valp = bfd_get_64 (core_bfd, buf);
   return 0;
 }
   *valp = bfd_get_64 (core_bfd, buf);
   return 0;
 }
+#endif
 
 int
 
 int
-gmon_io_read_vma (ifp, valp)
-     FILE *ifp;
-     bfd_vma *valp;
+gmon_io_read_vma (FILE *ifp, bfd_vma *valp)
 {
   unsigned int val32;
 {
   unsigned int val32;
+#ifdef BFD_HOST_U_64_BIT
   BFD_HOST_U_64_BIT val64;
   BFD_HOST_U_64_BIT val64;
+#endif
 
 
-  switch (bfd_arch_bits_per_address (core_bfd))
+  switch (gmon_get_ptr_size ())
     {
     {
-    case 32:
+    case ptr_32bit:
       if (gmon_io_read_32 (ifp, &val32))
        return 1;
       if (gmon_io_read_32 (ifp, &val32))
        return 1;
-      *valp = val32;
+      if (gmon_get_ptr_signedness () == ptr_signed)
+        *valp = (int) val32;
+      else
+        *valp = val32;
       break;
 
       break;
 
-    case 64:
+#ifdef BFD_HOST_U_64_BIT
+    case ptr_64bit:
       if (gmon_io_read_64 (ifp, &val64))
        return 1;
       if (gmon_io_read_64 (ifp, &val64))
        return 1;
-      *valp = val64;
+#ifdef BFD_HOST_64_BIT
+      if (gmon_get_ptr_signedness () == ptr_signed)
+        *valp = (BFD_HOST_64_BIT) val64;
+      else
+#endif
+        *valp = val64;
       break;
       break;
-
-    default:
-      fprintf (stderr, _("%s: bits per address has unexpected value of %u\n"),
-              whoami, bfd_arch_bits_per_address (core_bfd));
-      done (1);
+#endif
     }
   return 0;
 }
 
 int
     }
   return 0;
 }
 
 int
-gmon_io_read (ifp, buf, n)
-     FILE *ifp;
-     char *buf;
-     size_t n;
+gmon_io_read (FILE *ifp, char *buf, size_t n)
 {
   if (fread (buf, 1, n, ifp) != n)
     return 1;
 {
   if (fread (buf, 1, n, ifp) != n)
     return 1;
@@ -112,9 +167,7 @@ gmon_io_read (ifp, buf, n)
 }
 
 int
 }
 
 int
-gmon_io_write_32 (ofp, val)
-     FILE *ofp;
-     unsigned int val;
+gmon_io_write_32 (FILE *ofp, unsigned int val)
 {
   char buf[4];
 
 {
   char buf[4];
 
@@ -124,10 +177,9 @@ gmon_io_write_32 (ofp, val)
   return 0;
 }
 
   return 0;
 }
 
+#ifdef BFD_HOST_U_64_BIT
 static int
 static int
-gmon_io_write_64 (ofp, val)
-     FILE *ofp;        
-     BFD_HOST_U_64_BIT val;
+gmon_io_write_64 (FILE *ofp, BFD_HOST_U_64_BIT val)
 {
   char buf[8];
 
 {
   char buf[8];
 
@@ -136,37 +188,31 @@ gmon_io_write_64 (ofp, val)
     return 1;
   return 0;
 }
     return 1;
   return 0;
 }
+#endif
 
 int
 
 int
-gmon_io_write_vma (ofp, val)
-     FILE *ofp;
-     bfd_vma val;
+gmon_io_write_vma (FILE *ofp, bfd_vma val)
 {
 
 {
 
-  switch (bfd_arch_bits_per_address (core_bfd))
+  switch (gmon_get_ptr_size ())
     {
     {
-    case 32:
+    case ptr_32bit:
       if (gmon_io_write_32 (ofp, (unsigned int) val))
        return 1;
       break;
 
       if (gmon_io_write_32 (ofp, (unsigned int) val))
        return 1;
       break;
 
-    case 64:
+#ifdef BFD_HOST_U_64_BIT
+    case ptr_64bit:
       if (gmon_io_write_64 (ofp, (BFD_HOST_U_64_BIT) val))
        return 1;
       break;
       if (gmon_io_write_64 (ofp, (BFD_HOST_U_64_BIT) val))
        return 1;
       break;
-
-    default:
-      fprintf (stderr, _("%s: bits per address has unexpected value of %u\n"),
-              whoami, bfd_arch_bits_per_address (core_bfd));
-      done (1);
+#endif
     }
   return 0;
 }
 
 int
     }
   return 0;
 }
 
 int
-gmon_io_write_8 (ofp, val)
-     FILE *ofp;        
-     unsigned int val;
+gmon_io_write_8 (FILE *ofp, unsigned int val)
 {
   char buf[1];
 
 {
   char buf[1];
 
@@ -177,10 +223,7 @@ gmon_io_write_8 (ofp, val)
 }
 
 int
 }
 
 int
-gmon_io_write (ofp, buf, n)
-     FILE *ofp;        
-     char *buf;
-     size_t n;
+gmon_io_write (FILE *ofp, char *buf, size_t n)
 {
   if (fwrite (buf, 1, n, ofp) != n)
     return 1;
 {
   if (fwrite (buf, 1, n, ofp) != n)
     return 1;
@@ -188,76 +231,66 @@ gmon_io_write (ofp, buf, n)
 }
 
 static int
 }
 
 static int
-gmon_read_raw_arc (ifp, fpc, spc, cnt)
-     FILE *ifp;
-     bfd_vma *fpc;
-     bfd_vma *spc;
-     unsigned long *cnt;
+gmon_read_raw_arc (FILE *ifp, bfd_vma *fpc, bfd_vma *spc, unsigned long *cnt)
 {
 {
+#ifdef BFD_HOST_U_64_BIT
   BFD_HOST_U_64_BIT cnt64;
   BFD_HOST_U_64_BIT cnt64;
+#endif
   unsigned int cnt32;
 
   if (gmon_io_read_vma (ifp, fpc)
       || gmon_io_read_vma (ifp, spc))
     return 1;
 
   unsigned int cnt32;
 
   if (gmon_io_read_vma (ifp, fpc)
       || gmon_io_read_vma (ifp, spc))
     return 1;
 
-  switch (bfd_arch_bits_per_address (core_bfd))
+  switch (gmon_get_ptr_size ())
     {
     {
-    case 32:
+    case ptr_32bit:
       if (gmon_io_read_32 (ifp, &cnt32))
        return 1;
       *cnt = cnt32;
       break;
 
       if (gmon_io_read_32 (ifp, &cnt32))
        return 1;
       *cnt = cnt32;
       break;
 
-    case 64:
+#ifdef BFD_HOST_U_64_BIT
+    case ptr_64bit:
       if (gmon_io_read_64 (ifp, &cnt64))
        return 1;
       *cnt = cnt64;
       break;
       if (gmon_io_read_64 (ifp, &cnt64))
        return 1;
       *cnt = cnt64;
       break;
+#endif
 
     default:
 
     default:
-      fprintf (stderr, _("%s: bits per address has unexpected value of %u\n"),
-              whoami, bfd_arch_bits_per_address (core_bfd));
-      done (1);
+      return 1;
     }
   return 0;
 }
 
 static int
     }
   return 0;
 }
 
 static int
-gmon_write_raw_arc (ofp, fpc, spc, cnt)
-     FILE *ofp;
-     bfd_vma fpc;
-     bfd_vma spc;
-     unsigned long cnt;
+gmon_write_raw_arc (FILE *ofp, bfd_vma fpc, bfd_vma spc, unsigned long cnt)
 {
 
   if (gmon_io_write_vma (ofp, fpc)
       || gmon_io_write_vma (ofp, spc))
     return 1;
 
 {
 
   if (gmon_io_write_vma (ofp, fpc)
       || gmon_io_write_vma (ofp, spc))
     return 1;
 
-  switch (bfd_arch_bits_per_address (core_bfd))
+  switch (gmon_get_ptr_size ())
     {
     {
-    case 32:
+    case ptr_32bit:
       if (gmon_io_write_32 (ofp, (unsigned int) cnt))
        return 1;
       break;
 
       if (gmon_io_write_32 (ofp, (unsigned int) cnt))
        return 1;
       break;
 
-    case 64:
+#ifdef BFD_HOST_U_64_BIT
+    case ptr_64bit:
       if (gmon_io_write_64 (ofp, (BFD_HOST_U_64_BIT) cnt))
        return 1;
       break;
       if (gmon_io_write_64 (ofp, (BFD_HOST_U_64_BIT) cnt))
        return 1;
       break;
-
-    default:
-      fprintf (stderr, _("%s: bits per address has unexpected value of %u\n"),
-              whoami, bfd_arch_bits_per_address (core_bfd));
-      done (1);
+#endif
     }
   return 0;
 }
 
 void
     }
   return 0;
 }
 
 void
-gmon_out_read (filename)
-     const char *filename;
+gmon_out_read (const char *filename)
 {
   FILE *ifp;
   struct gmon_hdr ghdr;
 {
   FILE *ifp;
   struct gmon_hdr ghdr;
@@ -268,9 +301,7 @@ gmon_out_read (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
     {
@@ -350,15 +381,16 @@ gmon_out_read (filename)
       {
        bfd_vma low_pc;
        bfd_vma high_pc;
       {
        bfd_vma low_pc;
        bfd_vma high_pc;
-       int ncnt;
+       unsigned int ncnt;
       };
       };
-      int i, samp_bytes, header_size = 0;
+      unsigned int i;
+      int samp_bytes, header_size = 0;
       unsigned long count;
       bfd_vma from_pc, self_pc;
       unsigned long count;
       bfd_vma from_pc, self_pc;
-      static struct hdr h;
       UNIT raw_bin_count;
       struct hdr tmp;
       UNIT raw_bin_count;
       struct hdr tmp;
-      int version;
+      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.  */
@@ -391,15 +423,15 @@ gmon_out_read (filename)
 
       if (version == GMONVERSION)
        {
 
       if (version == GMONVERSION)
        {
-         int profrate;
+         unsigned int profrate;
 
          /* 4.4BSD format header.  */
           if (gmon_io_read_32 (ifp, &profrate))
            goto bad_gmon_file;
 
 
          /* 4.4BSD format header.  */
           if (gmon_io_read_32 (ifp, &profrate))
            goto bad_gmon_file;
 
-         if (!s_highpc)
+         if (!histograms)
            hz = profrate;
            hz = profrate;
-         else if (hz != profrate)
+         else if (hz != (int) profrate)
            {
              fprintf (stderr,
                       _("%s: profiling rate incompatible with first gmon file\n"),
            {
              fprintf (stderr,
                       _("%s: profiling rate incompatible with first gmon file\n"),
@@ -407,21 +439,15 @@ gmon_out_read (filename)
              done (1);
            }
 
              done (1);
            }
 
-         switch (bfd_arch_bits_per_address (core_bfd))
+         switch (gmon_get_ptr_size ())
            {
            {
-           case 32:
+           case ptr_32bit:
              header_size = GMON_HDRSIZE_BSD44_32;
              break;
 
              header_size = GMON_HDRSIZE_BSD44_32;
              break;
 
-           case 64:
+           case ptr_64bit:
              header_size = GMON_HDRSIZE_BSD44_64;
              break;
              header_size = GMON_HDRSIZE_BSD44_64;
              break;
-
-           default:
-              fprintf (stderr,
-                       _("%s: bits per address has unexpected value of %u\n"),
-                      whoami, bfd_arch_bits_per_address (core_bfd));
-              done (1);
            }
        }
       else
            }
        }
       else
@@ -434,21 +460,15 @@ gmon_out_read (filename)
              done (1);
            }
 
              done (1);
            }
 
-         switch (bfd_arch_bits_per_address (core_bfd))
+         switch (gmon_get_ptr_size ())
            {
            {
-           case 32:
+           case ptr_32bit:
              header_size = GMON_HDRSIZE_OLDBSD_32;
              break;
 
              header_size = GMON_HDRSIZE_OLDBSD_32;
              break;
 
-           case 64:
+           case ptr_64bit:
              header_size = GMON_HDRSIZE_OLDBSD_64;
              break;
              header_size = GMON_HDRSIZE_OLDBSD_64;
              break;
-
-           default:
-              fprintf (stderr,
-                       _("%s: bits per address has unexpected value of %u\n"),
-                      whoami, bfd_arch_bits_per_address (core_bfd));
-              done (1);
            }
        }
 
            }
        }
 
@@ -459,35 +479,40 @@ gmon_out_read (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 = 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 = 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"),
@@ -498,14 +523,6 @@ gmon_out_read (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)
@@ -516,7 +533,8 @@ gmon_out_read (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
@@ -568,14 +586,13 @@ gmon_out_read (filename)
       printf (nbbs == 1 ?
              _("\t%d basic-block count record\n") :
              _("\t%d basic-block count records\n"), nbbs);
       printf (nbbs == 1 ?
              _("\t%d basic-block count record\n") :
              _("\t%d basic-block count records\n"), nbbs);
-      first_output = false;
+      first_output = FALSE;
     }
 }
 
 
 void
     }
 }
 
 
 void
-gmon_out_write (filename)
-     const char *filename;
+gmon_out_write (const char *filename)
 {
   FILE *ofp;
   struct gmon_hdr ghdr;
 {
   FILE *ofp;
   struct gmon_hdr ghdr;
@@ -615,7 +632,7 @@ gmon_out_write (filename)
   else if (file_format == FF_BSD || file_format == FF_BSD44)
     {
       UNIT raw_bin_count;
   else if (file_format == FF_BSD || file_format == FF_BSD44)
     {
       UNIT raw_bin_count;
-      int i, hdrsize;
+      unsigned int i, hdrsize;
       unsigned padsize;
       char pad[3*4];
       Arc *arc;
       unsigned padsize;
       char pad[3*4];
       Arc *arc;
@@ -631,33 +648,27 @@ gmon_out_write (filename)
          || hz != hertz())
        {
          padsize = 3*4;
          || hz != hertz())
        {
          padsize = 3*4;
-         switch (bfd_arch_bits_per_address (core_bfd))
+         switch (gmon_get_ptr_size ())
            {
            {
-           case 32:
+           case ptr_32bit:
              hdrsize = GMON_HDRSIZE_BSD44_32;
              break;
 
              hdrsize = GMON_HDRSIZE_BSD44_32;
              break;
 
-           case 64:
+           case ptr_64bit:
              hdrsize = GMON_HDRSIZE_BSD44_64;
              break;
              hdrsize = GMON_HDRSIZE_BSD44_64;
              break;
-
-           default:
-              fprintf (stderr,
-                       _("%s: bits per address has unexpected value of %u\n"),
-                      whoami, bfd_arch_bits_per_address (core_bfd));
-              done (1);
            }
        }
       else
        {
          padsize = 0;
            }
        }
       else
        {
          padsize = 0;
-         switch (bfd_arch_bits_per_address (core_bfd))
+         switch (gmon_get_ptr_size ())
            {
            {
-           case 32:
+           case ptr_32bit:
              hdrsize = GMON_HDRSIZE_OLDBSD_32;
              break;
 
              hdrsize = GMON_HDRSIZE_OLDBSD_32;
              break;
 
-           case 64:
+           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.  */ 
              hdrsize = GMON_HDRSIZE_OLDBSD_64;
              /* FIXME: Checking host compiler defines here means that we can't
                 use a cross gprof alpha OSF.  */ 
@@ -665,20 +676,15 @@ gmon_out_write (filename)
              padsize = 4;
 #endif
              break;
              padsize = 4;
 #endif
              break;
-
-           default:
-              fprintf (stderr,
-                       _("%s: bits per address has unexpected value of %u\n"),
-                      whoami, bfd_arch_bits_per_address (core_bfd));
-              done (1);
            }
        }
 
       /* 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);
@@ -706,9 +712,9 @@ gmon_out_write (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)
            {