[RFC] Cross-gprof cleanup in gmon_io

Jason R Thorpe thorpej@wasabisystems.com
Sat Jan 26 16:25:00 GMT 2002


On Sat, Jan 26, 2002 at 02:35:50PM -0800, Jason R Thorpe wrote:

 > 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.

...okay, since the patch I posted pretty much applied as-is to
binutils-current, I'll go ahead and post a proposed patch now :-)

	* TODO: Remove "host architecture pointer size" item.
	* acconfig.h: Remove.
	* gconfig.in: Regenerate.
	* configure.in: Remove check for gmon pointer size.
	* configure: Regenerate.
	* gmon.h (GMON_HDRSIZE_BSD44_32): Define.
	(GMON_HDRSIZE_BSD44_64): Ditto.
	(GMON_HDRSIZE_OLDBSD_32): Ditto.
	(GMON_HDRSIZE_OLDBSD_64): Ditto.
	(struct raw_phdr): Wrap in #if 0, keeping it for
	documentation purposes only.
	(struct old_raw_phdr): Likewise.
	(struct raw_arc): Likewise.  Change type/size of
	"count" member to long match 4.4BSD.
	* gmon_io: Update copyright years.
	(gmon_io_read_64): New function.
	(gmon_io_read_vma): Use bfd_arch_bits_per_address to
	determine target pointer size.  Use gmon_io_read_32
	and gmon_io_read_64.
	(gmon_io_write_64): New function.
	(gmon_io_write_vma): Use bfd_arch_bits_per_address to
	determine target pointer size.  Use gmon_io_write_32
	and gmon_io_write_64.
	(get_vma): Remove.
	(put_vma): Ditto.
	(gmon_read_raw_arc): New function.
	(gmon_write_raw_arc): New function.
	(gmon_out_read): Do not use struct raw_phdr or
	struct old_raw_phdr to read the gmon header.  Use
	gmon_read_raw_arc to read call graph records.
	(gmon_out_write): Do not use struct raw_phdr or
	struct old_raw_phdr to write the gmon header.  Use
	gmon_write_raw_arc to write call graph records.

-- 
        -- Jason R. Thorpe <thorpej@wasabisystems.com>
-------------- next part --------------
Index: TODO
===================================================================
RCS file: /cvs/src/src/gprof/TODO,v
retrieving revision 1.1.1.1
diff -c -r1.1.1.1 TODO
*** TODO	1999/05/03 07:29:11	1.1.1.1
--- TODO	2002/01/26 23:14:30
***************
*** 1,7 ****
  
- - gmon_io.c cannot deal with target architecture that have a pointer size
-   that is different from the host architectures pointer size---fix this
-   (gmon_out.h, and gmon_io.c)
  - add support for prof file format so that prof files can be displayed
    at the line-level (this is useful for the uprofile tool under DEC's
    OSF/1)
--- 1,4 ----
Index: acconfig.h
===================================================================
RCS file: acconfig.h
diff -N acconfig.h
*** /sourceware/cvs-tmp/cvsKUqZpU	Sat Jan 26 15:14:40 2002
--- /dev/null	Tue May  5 13:32:27 1998
***************
*** 1,2 ****
- /* Define as the size of a pointer in the target profile file format.  */
- #undef GMON_PTR_SIZE
--- 0 ----
Index: configure.in
===================================================================
RCS file: /cvs/src/src/gprof/configure.in,v
retrieving revision 1.13
diff -c -r1.13 configure.in
*** configure.in	2002/01/07 17:37:54	1.13
--- configure.in	2002/01/26 23:14:39
***************
*** 31,61 ****
  
  AC_CHECK_HEADERS(sys/gmon_out.h)
  
- AC_MSG_CHECKING(the size of gmon pointers)
- AC_TRY_RUN([#include <stdio.h>
- #include <stdlib.h>
- #if HAVE_SYS_GMON_OUT_H
- #include <sys/gmon_out.h>
- #endif
- main()
- {
- #if HAVE_SYS_GMON_OUT_H
-   struct gmon_cg_arc_record arc;
-   FILE *f=fopen("conftestval", "w");
-   if (!f) exit(1);
-   fprintf(f, "%d\n", sizeof(arc.from_pc));
-   exit(0);
- #else
-   FILE *f=fopen("conftestval", "w");
-   if (!f) exit(1);
-   fprintf(f, "%d\n", (int) sizeof(char *));
-   exit(1);
- #endif
- }], gmon_ptr_size=`cat conftestval`, gmon_ptr_size=4, gmon_ptr_size=4)
- AC_MSG_RESULT($gmon_ptr_size)
- 
- AC_DEFINE_UNQUOTED(GMON_PTR_SIZE, $gmon_ptr_size)
- 
  build_warnings="-W -Wall"
  AC_ARG_ENABLE(build-warnings,
  [  --enable-build-warnings Enable build-time compiler warnings if gcc is used],
--- 31,36 ----
Index: gmon.h
===================================================================
RCS file: /cvs/src/src/gprof/gmon.h,v
retrieving revision 1.2
diff -c -r1.2 gmon.h
*** gmon.h	2001/03/14 03:14:56	1.2
--- gmon.h	2002/01/26 23:14:40
***************
*** 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(long)];
!     };
! #endif
  
  /*
   * General rounding functions:
Index: gmon_io.c
===================================================================
RCS file: /cvs/src/src/gprof/gmon_io.c,v
retrieving revision 1.10
diff -c -r1.10 gmon_io.c
*** gmon_io.c	2002/01/03 21:32:36	1.10
--- gmon_io.c	2002/01/26 23:14:40
***************
*** 1,6 ****
  /* gmon_io.c - Input and output from/to gmon.out files.
  
!    Copyright 2000, 2001 Free Software Foundation, Inc.
  
     This file is part of GNU Binutils.
  
--- 1,6 ----
  /* gmon_io.c - Input and output from/to gmon.out files.
  
!    Copyright 2000, 2001, 2002 Free Software Foundation, Inc.
  
     This file is part of GNU Binutils.
  
***************
*** 36,84 ****
  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;
    return 0;
  }
  
  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;
  }
--- 36,116 ----
  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)
! {
!   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;
!       *valp = val32;
        break;
  
!     case 64:
!       if (gmon_io_read_64 (ifp, &val64))
  	return 1;
!       *valp = 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);
      }
    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;
! }
! 
! 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;
  }
***************
*** 86,127 ****
  int
  DEFUN (gmon_io_write_vma, (ofp, val), FILE * ofp AND bfd_vma val)
  {
-   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];
--- 118,145 ----
  int
  DEFUN (gmon_io_write_vma, (ofp, val), FILE * ofp AND bfd_vma val)
  {
  
!   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
--- 157,221 ----
      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.  */
--- 317,326 ----
        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;
--- 335,363 ----
  	  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;
***************
*** 322,329 ****
  		       filename);
  	      done (1);
  	    }
  
! 	  header_size = sizeof (struct raw_phdr);
  	}
        else
  	{
--- 368,390 ----
  		       filename);
  	      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
--- 396,424 ----
  	      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,417 ****
  
        /* 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);
- 	  count = bfd_get_32 (core_bfd, (bfd_byte *) raw_arc.count);
  
  	  DBG (SAMPLEDEBUG,
  	     printf ("[gmon_out_read] frompc 0x%lx selfpc 0x%lx count %lu\n",
--- 483,491 ----
  
        /* 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",
***************
*** 501,543 ****
      }
    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)
  	{
--- 575,669 ----
      }
    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)
  	{
***************
*** 554,565 ****
  	{
  	  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);
--- 680,687 ----
  	{
  	  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