[RFC] Cross-gprof cleanup in gmon_io

Jason R Thorpe thorpej@wasabisystems.com
Sat Jan 26 15:51:00 GMT 2002


Hi folks...

I was recently looking into some problems with binutils 2.11.2 gprof
on NetBSD/alpha, and in the process of fixing it (binutils gprof gets
the size of the "count" member wrong in the "raw_arc" structure on
LP64 platforms -- it uses u_int, even though 4.4BSD used u_long),
eliminated the GMON_PTR_SIZE constant in favor of using the
bits-per-address info in the bfd arch info.  This appears to be
something in the binutils-current gprof TODO list.

Before I port this stuff forward to binutils-current, I would like
some feedback on how I implemented it.

The following patch is against binutils 2.11.2 -- when I'm ready to
officially submit it to the master binutils sources, I'll post an
updated patch with a ChangeLog entry describing it in detail.

-- 
        -- Jason R. Thorpe <thorpej@wasabisystems.com>
-------------- next part --------------
Index: gmon.h
===================================================================
RCS file: /cvsroot/gnusrc/gnu/dist/toolchain/gprof/gmon.h,v
retrieving revision 1.3
diff -c -r1.3 gmon.h
*** gmon.h	2001/08/14 04:43:11	1.3
--- gmon.h	2002/01/26 22:34:23
***************
*** 35,71 ****
  #ifndef gmon_h
  #define gmon_h
  
! struct raw_phdr
!   {
!     /* FIXME: Checking a host compiler define means that we can't use
!        a cross gprof to the alpha.  */
!     char low_pc[GMON_PTR_SIZE];	/* base pc address of sample buffer */
!     char high_pc[GMON_PTR_SIZE];/* max pc address of sampled buffer */
!     char ncnt[4];		/* size of sample buffer (plus this header) */
! 
!     char version[4];		/* version number */
!     char profrate[4];		/* profiling clock rate */
!     char spare[3*4];		/* reserved */
!   };
  
  #define GMONVERSION     0x00051879
  
! struct old_raw_phdr
!   {
!     char low_pc[GMON_PTR_SIZE];	/* base pc address of sample buffer */
!     char high_pc[GMON_PTR_SIZE];/* max pc address of sampled buffer */
!     char ncnt[4];		/* size of sample buffer (plus this header) */
  
!     /* FIXME: Checking host compiler defines here means that we can't
!        use a cross gprof alpha OSF.  */
  #if defined (__alpha__) && defined (__osf__)
!     /*
!      * DEC's OSF v3.0 uses 4 bytes of padding to bring the header to
!      * a size that is a multiple of 8.
!      */
!     char pad[4];
  #endif
!   };
  
  /*
   * Histogram counters are unsigned shorts:
--- 35,87 ----
  #ifndef gmon_h
  #define gmon_h
  
! /* Size of the 4.4BSD gmon header */
! #define GMON_HDRSIZE_BSD44_32 (4 + 4 + 4 + 4 + 4 + (3 * 4))
! #define GMON_HDRSIZE_BSD44_64 (8 + 8 + 4 + 4 + 4 + (3 * 4))
! 
! #if 0 /* For documentation purposes only.  */
!   struct raw_phdr
!     {
!       char low_pc[sizeof(void *)]; /* base pc address of sample buffer */
!       char high_pc[sizeof(void *)];/* max pc address of sampled buffer */
!       char ncnt[4];		   /* size of sample buffer (plus this
! 				      header) */
! 
!       char version[4];		   /* version number */
!       char profrate[4];		   /* profiling clock rate */
!       char spare[3*4];		   /* reserved */
!     };
!  #endif
  
  #define GMONVERSION     0x00051879
  
! /* Size of the old BSD gmon header */
! #define GMON_HDRSIZE_OLDBSD_32 (4 + 4 + 4)
! 
! /* FIXME: Checking host compiler defines here means that we can't
!    use a cross gprof alpha OSF.  */
! #if defined(__alpha__) && defined (__osf__)
! #define GMON_HDRSIZE_OLDBSD_64 (8 + 8 + 4 + 4)
! #else
! #define GMON_HDRSIZE_OLDBSD_64 (8 + 8 + 4)
! #endif
  
! #if 0 /* For documentation purposes only.  */
!   struct old_raw_phdr
!     {
!       char low_pc[sizeof(void *)]; /* base pc address of sample buffer */
!       char high_pc[sizeof(void *)];/* max pc address of sampled buffer */
!       char ncnt[4];		   /* size of sample buffer (plus this
! 				      header) */
  #if defined (__alpha__) && defined (__osf__)
!       /*
!        * DEC's OSF v3.0 uses 4 bytes of padding to bring the header to
!        * a size that is a multiple of 8.
!        */
!       char pad[4];
  #endif
!     };
! #endif
  
  /*
   * Histogram counters are unsigned shorts:
***************
*** 120,131 ****
   * as to get a packed representation (otherwise, different compilers
   * might introduce different padding):
   */
! struct raw_arc
!   {
!     char from_pc[GMON_PTR_SIZE];
!     char self_pc[GMON_PTR_SIZE];
!     char count[4];
!   };
  
  /*
   * General rounding functions:
--- 136,149 ----
   * as to get a packed representation (otherwise, different compilers
   * might introduce different padding):
   */
! #if 0 /* For documentation purposes only.  */
!    struct raw_arc
!      {
!        char from_pc[sizeof(void *)];
!        char self_pc[sizeof(void *)];
!        char count[sizeof(u_long)];
!      };
! #endif
  
  /*
   * General rounding functions:
Index: gmon_io.c
===================================================================
RCS file: /cvsroot/gnusrc/gnu/dist/toolchain/gprof/gmon_io.c,v
retrieving revision 1.4
diff -c -r1.4 gmon_io.c
*** gmon_io.c	2001/08/14 04:43:11	1.4
--- gmon_io.c	2002/01/26 22:34:23
***************
*** 36,63 ****
  int gmon_file_version = 0;	/* 0 == old (non-versioned) file format.  */
  
  int
  DEFUN (gmon_io_read_vma, (ifp, valp), FILE * ifp AND bfd_vma *valp)
  {
    char buf[8];
    bfd_vma val;
  
!   switch (GMON_PTR_SIZE)
      {
!     case 4:
!       if (fread (buf, 1, 4, ifp) != 4)
  	return 1;
!       val = bfd_get_32 (core_bfd, buf);
        break;
  
!     case 8:
!       if (fread (buf, 1, 8, ifp) != 8)
  	return 1;
!       val = bfd_get_64 (core_bfd, buf);
        break;
  
      default:
!       fprintf (stderr, _("%s: GMON_PTR_SIZE has unexpected value of %u\n"),
! 	       whoami, GMON_PTR_SIZE);
        done (1);
      }
    *valp = val;
--- 36,87 ----
  int gmon_file_version = 0;	/* 0 == old (non-versioned) file format.  */
  
  int
+ DEFUN (gmon_io_read_32, (ifp, valp), FILE * ifp AND unsigned int *valp)
+ {
+   char buf[4];
+ 
+   if (fread (buf, 1, 4, ifp) != 4)
+     return 1;
+   *valp = bfd_get_32 (core_bfd, buf);
+   return 0;
+ }
+ 
+ int
+ DEFUN (gmon_io_read_64, (ifp, valp), FILE * ifp AND BFD_HOST_U_64_BIT *valp)
+ {
+   char buf[8];
+ 
+   if (fread (buf, 1, 8, ifp) != 8)
+     return 1;
+   *valp = bfd_get_64 (core_bfd, buf);
+   return 0;
+ }
+ 
+ int
  DEFUN (gmon_io_read_vma, (ifp, valp), FILE * ifp AND bfd_vma *valp)
  {
    char buf[8];
    bfd_vma val;
+   unsigned int val32;
+   BFD_HOST_U_64_BIT val64;
  
!   switch (bfd_arch_bits_per_address (core_bfd))
      {
!     case 32:
!       if (gmon_io_read_32 (ifp, &val32))
  	return 1;
!       val = val32;
        break;
  
!     case 64:
!       if (gmon_io_read_64 (ifp, &val64))
  	return 1;
!       val = val64;
        break;
  
      default:
!       fprintf (stderr, _("%s: bits per address has unexpected value of %u\n"),
! 	       whoami, bfd_arch_bits_per_address (core_bfd));
        done (1);
      }
    *valp = val;
***************
*** 65,84 ****
  }
  
  int
! DEFUN (gmon_io_read_32, (ifp, valp), FILE * ifp AND unsigned int *valp)
  {
    char buf[4];
  
!   if (fread (buf, 1, 4, ifp) != 4)
      return 1;
-   *valp = bfd_get_32 (core_bfd, buf);
    return 0;
  }
  
  int
! DEFUN (gmon_io_read, (ifp, buf, n), FILE * ifp AND char *buf AND size_t n)
  {
!   if (fread (buf, 1, n, ifp) != n)
      return 1;
    return 0;
  }
--- 89,119 ----
  }
  
  int
! DEFUN (gmon_io_read, (ifp, buf, n), FILE * ifp AND char *buf AND size_t n)
  {
+   if (fread (buf, 1, n, ifp) != n)
+     return 1;
+   return 0;
+ }
+ 
+ int
+ DEFUN (gmon_io_write_32, (ofp, val), FILE * ofp AND unsigned int val)
+ {
    char buf[4];
  
!   bfd_put_32 (core_bfd, val, buf);
!   if (fwrite (buf, 1, 4, ofp) != 4)
      return 1;
    return 0;
  }
  
  int
! DEFUN (gmon_io_write_64, (ofp, val), FILE * ofp AND BFD_HOST_U_64_BIT val)
  {
!   char buf[8];
! 
!   bfd_put_64 (core_bfd, val, buf);
!   if (fwrite (buf, 1, 8, ofp) != 8)
      return 1;
    return 0;
  }
***************
*** 88,127 ****
  {
    char buf[8];
  
!   switch (GMON_PTR_SIZE)
      {
!     case 4:
!       bfd_put_32 (core_bfd, val, buf);
!       if (fwrite (buf, 1, 4, ofp) != 4)
  	return 1;
        break;
  
!     case 8:
!       bfd_put_64 (core_bfd, val, buf);
!       if (fwrite (buf, 1, 8, ofp) != 8)
  	return 1;
        break;
  
      default:
!       fprintf (stderr, _("%s: GMON_PTR_SIZE has unexpected value of %u\n"),
! 	       whoami, GMON_PTR_SIZE);
        done (1);
      }
    return 0;
  }
  
  int
- DEFUN (gmon_io_write_32, (ofp, val), FILE * ofp AND unsigned int val)
- {
-   char buf[4];
- 
-   bfd_put_32 (core_bfd, val, buf);
-   if (fwrite (buf, 1, 4, ofp) != 4)
-     return 1;
-   return 0;
- }
- 
- int
  DEFUN (gmon_io_write_8, (ofp, val), FILE * ofp AND unsigned char val)
  {
    char buf[1];
--- 123,149 ----
  {
    char buf[8];
  
!   switch (bfd_arch_bits_per_address (core_bfd))
      {
!     case 32:
!       if (gmon_io_write_32 (ofp, (unsigned int) val))
  	return 1;
        break;
  
!     case 64:
!       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);
      }
    return 0;
  }
  
  int
  DEFUN (gmon_io_write_8, (ofp, val), FILE * ofp AND unsigned char val)
  {
    char buf[1];
***************
*** 139,178 ****
      return 1;
    return 0;
  }
  
! /* get_vma and put_vma are for backwards compatibility only */
! static bfd_vma
! DEFUN (get_vma, (abfd, addr), bfd * abfd AND bfd_byte * addr)
! {
!   switch (sizeof (char*))
!     {
!     case 4:
!       return bfd_get_32 (abfd, addr);
!     case 8:
!       return bfd_get_64 (abfd, addr);
      default:
!       fprintf (stderr, _("%s: bfd_vma has unexpected size of %ld bytes\n"),
! 	       whoami, (long) sizeof (char*));
        done (1);
      }
  }
  
! static void
! DEFUN (put_vma, (abfd, val, addr), bfd * abfd AND bfd_vma val AND bfd_byte * addr)
  {
!   switch (sizeof (char*))
      {
!     case 4:
!       bfd_put_32 (abfd, val, addr);
        break;
!     case 8:
!       bfd_put_64 (abfd, val, addr);
        break;
      default:
!       fprintf (stderr, _("%s: bfd_vma has unexpected size of %ld bytes\n"),
! 	       whoami, (long) sizeof (char*));
        done (1);
      }
  }
  
  void
--- 161,225 ----
      return 1;
    return 0;
  }
+ 
+ int
+ DEFUN (gmon_read_raw_arc, (ifp, fpc, spc, cnt), FILE * ifp AND bfd_vma *fpc AND bfd_vma *spc AND unsigned long *cnt)
+ {
+   BFD_HOST_U_64_BIT cnt64;
+   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))
!     {
!     case 32:
!       if (gmon_io_read_32 (ifp, &cnt32))
! 	return 1;
!       *cnt = cnt32;
!       break;
! 
!     case 64:
!       if (gmon_io_read_64 (ifp, &cnt64))
! 	return 1;
!       *cnt = cnt64;
!       break;
! 
      default:
!       fprintf (stderr, _("%s: bits per address has unexpected value of %u\n"),
! 	       whoami, bfd_arch_bits_per_address (core_bfd));
        done (1);
      }
+   return 0;
  }
  
! int
! DEFUN (gmon_write_raw_arc, (ofp, fpc, spc, cnt), FILE * ofp AND bfd_vma fpc AND bfd_vma spc AND unsigned long cnt)
  {
! 
!   if (gmon_io_write_vma (ofp, fpc)
!       || gmon_io_write_vma (ofp, spc))
!     return 1;
! 
!   switch (bfd_arch_bits_per_address (core_bfd))
      {
!     case 32:
!       if (gmon_io_write_32 (ofp, (unsigned int) cnt))
! 	return 1;
        break;
! 
!     case 64:
!       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);
      }
+   return 0;
  }
  
  void
***************
*** 274,284 ****
        int i, samp_bytes, header_size;
        unsigned long count;
        bfd_vma from_pc, self_pc;
-       struct raw_arc raw_arc;
-       struct raw_phdr raw;
        static struct hdr h;
        UNIT raw_bin_count;
        struct hdr tmp;
  
        /* Information from a gmon.out file is in two parts: an array of
  	 sampling hits within pc ranges, and the arcs.  */
--- 321,330 ----
        int i, samp_bytes, header_size;
        unsigned long count;
        bfd_vma from_pc, self_pc;
        static struct hdr h;
        UNIT raw_bin_count;
        struct hdr tmp;
+       int version;
  
        /* Information from a gmon.out file is in two parts: an array of
  	 sampling hits within pc ranges, and the arcs.  */
***************
*** 293,317 ****
  	  done (1);
  	}
  
!       if (fread (&raw, 1, sizeof (struct raw_phdr), ifp)
! 	  != sizeof (struct raw_phdr))
  	{
! 	  fprintf (stderr, _("%s: file too short to be a gmon file\n"),
  		   filename);
  	  done (1);
  	}
  
!       tmp.low_pc = get_vma (core_bfd, (bfd_byte *) &raw.low_pc[0]);
!       tmp.high_pc = get_vma (core_bfd, (bfd_byte *) &raw.high_pc[0]);
!       tmp.ncnt = bfd_get_32 (core_bfd, (bfd_byte *) &raw.ncnt[0]);
  
!       if (bfd_get_32 (core_bfd, (bfd_byte *) &raw.version[0])
! 	  == GMONVERSION)
  	{
  	  int profrate;
  
  	  /* 4.4BSD format header.  */
! 	  profrate = bfd_get_32 (core_bfd, (bfd_byte *) &raw.profrate[0]);
  
  	  if (!s_highpc)
  	    hz = profrate;
--- 339,367 ----
  	  done (1);
  	}
  
!       /* The beginning of the old BSD header and the 4.4BSD header
! 	 are the same: lowpc, highpc, ncnt  */
!       if (gmon_io_read_vma (ifp, &tmp.low_pc)
!           || gmon_io_read_vma (ifp, &tmp.high_pc)
!           || gmon_io_read_32 (ifp, &tmp.ncnt))
  	{
!  bad_gmon_file:
!           fprintf (stderr, _("%s: file too short to be a gmon file\n"),
  		   filename);
  	  done (1);
  	}
  
!       /* Check to see if this a 4.4BSD-style header.  */
!       if (gmon_io_read_32 (ifp, &version))
! 	goto bad_gmon_file;
  
!       if (version == GMONVERSION)
  	{
  	  int profrate;
  
  	  /* 4.4BSD format header.  */
!           if (gmon_io_read_32 (ifp, &profrate))
! 	    goto bad_gmon_file;
  
  	  if (!s_highpc)
  	    hz = profrate;
***************
*** 323,329 ****
  	      done (1);
  	    }
  
! 	  header_size = sizeof (struct raw_phdr);
  	}
        else
  	{
--- 373,394 ----
  	      done (1);
  	    }
  
! 	  switch (bfd_arch_bits_per_address (core_bfd))
! 	    {
! 	    case 32:
! 	      header_size = GMON_HDRSIZE_BSD44_32;
! 	      break;
! 
! 	    case 64:
! 	      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
  	{
***************
*** 335,347 ****
  	      done (1);
  	    }
  
! 	  if (fseek (ifp, sizeof (struct old_raw_phdr), SEEK_SET) < 0)
  	    {
! 	      perror (filename);
! 	      done (1);
  	    }
  
! 	  header_size = sizeof (struct old_raw_phdr);
  	}
  
        if (s_highpc && (tmp.low_pc != h.low_pc
--- 400,428 ----
  	      done (1);
  	    }
  
! 	  switch (bfd_arch_bits_per_address (core_bfd))
  	    {
! 	    case 32:
! 	      header_size = GMON_HDRSIZE_OLDBSD_32;
! 	      break;
! 
! 	    case 64:
! 	      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);
  	    }
+ 	}
  
!       /* Position the file to after the header.  */
!       if (fseek (ifp, header_size, SEEK_SET) < 0)
! 	{
! 	  perror (filename);
! 	  done (1);
  	}
  
        if (s_highpc && (tmp.low_pc != h.low_pc
***************
*** 406,421 ****
  
        /* The rest of the file consists of a bunch of
  	 <from,self,count> tuples.  */
!       while (fread (&raw_arc, sizeof (raw_arc), 1, ifp) == 1)
  	{
  	  ++narcs;
- 	  from_pc = get_vma (core_bfd, (bfd_byte *) raw_arc.from_pc);
- 	  self_pc = get_vma (core_bfd, (bfd_byte *) raw_arc.self_pc);
- #if defined(__arch64__)
- 	  count = bfd_get_64 (core_bfd, (bfd_byte *) raw_arc.count);
- #else
- 	  count = bfd_get_32 (core_bfd, (bfd_byte *) raw_arc.count);
- #endif
  
  	  DBG (SAMPLEDEBUG,
  	     printf ("[gmon_out_read] frompc 0x%lx selfpc 0x%lx count %lu\n",
--- 487,495 ----
  
        /* The rest of the file consists of a bunch of
  	 <from,self,count> tuples.  */
!       while (gmon_read_raw_arc (ifp, &from_pc, &self_pc, &count) == 0)
  	{
  	  ++narcs;
  
  	  DBG (SAMPLEDEBUG,
  	     printf ("[gmon_out_read] frompc 0x%lx selfpc 0x%lx count %lu\n",
***************
*** 502,544 ****
      }
    else if (file_format == FF_BSD || file_format == FF_BSD44)
      {
-       struct raw_arc raw_arc;
        UNIT raw_bin_count;
!       struct raw_phdr h;
!       int i;
        Arc *arc;
        Sym *sym;
  
!       memset (&h, 0, sizeof h);
!       put_vma (core_bfd, s_lowpc, (bfd_byte *) &h.low_pc);
!       put_vma (core_bfd, s_highpc, (bfd_byte *) &h.high_pc);
!       bfd_put_32 (core_bfd,
! 		  hist_num_bins * sizeof (UNIT) + sizeof (struct raw_phdr),
! 		  (bfd_byte *) &h.ncnt);
! 
!       /* Write header.  Use new style BSD format is explicitly
! 	 specified, or if the profiling rate is non-standard;
! 	 otherwise, use the old BSD format.  */
        if (file_format == FF_BSD44
! 	  || hz != hertz ())
  	{
! 	  bfd_put_32 (core_bfd, GMONVERSION, (bfd_byte *) &h.version);
! 	  bfd_put_32 (core_bfd, hz, (bfd_byte *) &h.profrate);
! 	  if (fwrite (&h, sizeof (struct raw_phdr), 1, ofp) != 1)
  	    {
! 	      perror (filename);
! 	      done (1);
  	    }
  	}
        else
  	{
! 	  if (fwrite (&h, sizeof (struct old_raw_phdr), 1, ofp) != 1)
  	    {
  	      perror (filename);
  	      done (1);
  	    }
  	}
  
        /* Dump the samples.  */
        for (i = 0; i < hist_num_bins; ++i)
  	{
--- 576,670 ----
      }
    else if (file_format == FF_BSD || file_format == FF_BSD44)
      {
        UNIT raw_bin_count;
!       int i, hdrsize, padsize;
!       char pad[3*4];
        Arc *arc;
        Sym *sym;
+ 
+       memset (pad, 0, sizeof (pad));
  
!       /* Decide how large the header will be.  Use the 4.4BSD format
!          header if explicitly specified, or if the profiling rate is
!          non-standard.  Otherwise, use the old BSD format.  */
        if (file_format == FF_BSD44
! 	  || hz != hertz())
  	{
! 	  padsize = 3*4;
! 	  switch (bfd_arch_bits_per_address (core_bfd))
  	    {
! 	    case 32:
! 	      hdrsize = GMON_HDRSIZE_BSD44_32;
! 	      break;
! 
! 	    case 64:
! 	      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;
! 	  switch (bfd_arch_bits_per_address (core_bfd))
  	    {
+ 	    case 32:
+ 	      hdrsize = GMON_HDRSIZE_OLDBSD_32;
+ 	      break;
+ 
+ 	    case 64:
+ 	      hdrsize = GMON_HDRSIZE_OLDBSD_64;
+ 	      /* FIXME: Checking host compiler defines here means that we can't
+ 		 use a cross gprof alpha OSF.  */ 
+ #if defined(__alpha__) && defined (__osf__)
+ 	      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.  */
+       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))
+ 	{
+ 	  perror (filename);
+ 	  done (1);
+ 	}
+ 
+       /* Write out the 4.4BSD header bits, if that's what we're using.  */
+       if (file_format == FF_BSD44
+ 	  || hz != hertz())
+ 	{
+           if (gmon_io_write_32 (ofp, GMONVERSION)
+ 	      || gmon_io_write_32 (ofp, hz))
+ 	    {
  	      perror (filename);
  	      done (1);
  	    }
  	}
  
+       /* Now write out any necessary padding after the meaningful
+ 	 header bits.  */
+       if (padsize != 0
+           && fwrite (pad, 1, padsize, ofp) != padsize)
+         {
+           perror (filename);
+ 	  done (1);
+ 	}
+ 
        /* Dump the samples.  */
        for (i = 0; i < hist_num_bins; ++i)
  	{
***************
*** 555,566 ****
  	{
  	  for (arc = sym->cg.children; arc; arc = arc->next_child)
  	    {
! 	      put_vma (core_bfd, arc->parent->addr,
! 		       (bfd_byte *) raw_arc.from_pc);
! 	      put_vma (core_bfd, arc->child->addr,
! 		       (bfd_byte *) raw_arc.self_pc);
! 	      bfd_put_32 (core_bfd, arc->count, (bfd_byte *) raw_arc.count);
! 	      if (fwrite (&raw_arc, sizeof (raw_arc), 1, ofp) != 1)
  		{
  		  perror (filename);
  		  done (1);
--- 681,688 ----
  	{
  	  for (arc = sym->cg.children; arc; arc = arc->next_child)
  	    {
! 	      if (gmon_write_raw_arc (ofp, arc->parent->addr,
! 				      arc->child->addr, arc->count))
  		{
  		  perror (filename);
  		  done (1);


More information about the Binutils mailing list