This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[gcov patch]: Use a smaller buffer


Hi,
I've installed this patch which changes gcov from slurping in whole
gcov files into a malloc'd buffer, into using a smaller window. In libgcov
it is a fixed size of 4K, elsewhere is is a small malloc'd buffer.
The reason whole files were slurped was to avoid poor disk performance with
seeks that cause flushes. This patch preserves the high performance of
an in-memory scheme, but reduces the memory requirements.

booted & tested on i686-pc-linux-gnu, with & wothout --enable-coverage

nathan
--
Nathan Sidwell    ::   http://www.codesourcery.com   ::     CodeSourcery LLC
         The voices in my head said this was stupid too
nathan@codesourcery.com    ::     http://www.planetfall.pwp.blueyonder.co.uk

2003-05-14  Nathan Sidwell  <nathan@codesourcery.com>

	* gcov-io.h (gcov_write_bytes, gcov_read_bytes): Remove here.
	(GCOV_TAG_*) Force type to gcov_unsigned_t.
	(GCOV_CHECK, GCOV_CHECK_READING, GCOV_CHECK_WRITING): New.
	(struct gcov_var): Remove modified. Add start, length, offset,
	overread. Have buffer array for libgcov.
	(gcov_sync, gcov_seek): Definitions moved to gcov-io.c.
	(gcov_position, gcov_rewrite, gcov_is_eof): Adjust.
	* gcov-io.c (gcov_open): Set mode, do not read anything.
	(gcov_close): Write final block.
	 (gcov_write_block, gcov_allocate): New.
	(gcov_write_bytes): Make static. Write or allocate buffer.
	(gcov_write_unsigned, gcov_write_counter): Buffer can never be
	null.
	(gcov_write_string): Adjust.
	(gcov_write_tag)
	(gcov_write_length): Adjust. Flush the block.
	(gcov_write_tag_length): Buffer can never be null.
	(gcov_read_bytes): Make static. Read in block.
	(gcov_sync): Moved here. Adjust.
	(gcov_seek): Moved here. Adjust.
	* coverage.c (read_counts_file): Adjust.
	* gcov-dump.c (print_prefix): Add position parameter.
	(flag_dump_positions): New flag.
	(options, main, print_usage): Add it.
	(dump_file, tag_blocks, tag_arcs, tag_lines, tag_counters,
	tag_summary): Adjust.
	* gcov.c (read_graph_file, read_count_file): Adjust.
	* libgcov.c (gcov_exit): Adjust.

Index: coverage.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/coverage.c,v
retrieving revision 1.8
diff -c -3 -p -r1.8 coverage.c
*** coverage.c	11 May 2003 19:21:30 -0000	1.8
--- coverage.c	13 May 2003 18:20:06 -0000
*************** read_counts_file ()
*** 158,164 ****
    unsigned ix;
    counts_entry_t *summaried = NULL;
    unsigned seen_summary = 0;
!   
    if (!gcov_open (da_file_name, 1))
      return;
    
--- 158,166 ----
    unsigned ix;
    counts_entry_t *summaried = NULL;
    unsigned seen_summary = 0;
!   gcov_unsigned_t tag;
!   int error = 0;
! 
    if (!gcov_open (da_file_name, 1))
      return;
    
*************** read_counts_file ()
*** 187,199 ****
    counts_hash = htab_create (10,
  			     htab_counts_entry_hash, htab_counts_entry_eq,
  			     htab_counts_entry_del);
!   while (!gcov_is_eof ())
      {
!       gcov_unsigned_t tag, length;
        gcov_position_t offset;
-       int error;
        
-       tag = gcov_read_unsigned ();
        length = gcov_read_unsigned ();
        offset = gcov_position ();
        if (tag == GCOV_TAG_FUNCTION)
--- 189,199 ----
    counts_hash = htab_create (10,
  			     htab_counts_entry_hash, htab_counts_entry_eq,
  			     htab_counts_entry_del);
!   while ((tag = gcov_read_unsigned ()))
      {
!       gcov_unsigned_t length;
        gcov_position_t offset;
        
        length = gcov_read_unsigned ();
        offset = gcov_position ();
        if (tag == GCOV_TAG_FUNCTION)
*************** read_counts_file ()
*** 284,297 ****
  	}
        gcov_sync (offset, length);
        if ((error = gcov_is_error ()))
! 	{
! 	  warning (error < 0 ? "`%s' has overflowed" : "`%s' is corrupted",
! 		   da_file_name);
! 	  htab_delete (counts_hash);
! 	  break;
! 	}
      }
  
    gcov_close ();
  }
  
--- 284,299 ----
  	}
        gcov_sync (offset, length);
        if ((error = gcov_is_error ()))
! 	break;
      }
  
+   if (!gcov_is_eof ())
+     {
+       warning (error < 0 ? "`%s' has overflowed" : "`%s' is corrupted",
+ 	       da_file_name);
+       htab_delete (counts_hash);
+     }
+   
    gcov_close ();
  }
  
Index: gcov-dump.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/gcov-dump.c,v
retrieving revision 1.12
diff -c -3 -p -r1.12 gcov-dump.c
*** gcov-dump.c	10 May 2003 19:02:21 -0000	1.12
--- gcov-dump.c	13 May 2003 18:20:07 -0000
*************** Boston, MA 02111-1307, USA.  */
*** 28,34 ****
  #include "gcov-io.c"
  
  static void dump_file PARAMS ((const char *));
! static void print_prefix PARAMS ((const char *, unsigned));
  static void print_usage PARAMS ((void));
  static void print_version PARAMS ((void));
  static void tag_function PARAMS ((const char *, unsigned, unsigned));
--- 28,34 ----
  #include "gcov-io.c"
  
  static void dump_file PARAMS ((const char *));
! static void print_prefix PARAMS ((const char *, unsigned, gcov_position_t));
  static void print_usage PARAMS ((void));
  static void print_version PARAMS ((void));
  static void tag_function PARAMS ((const char *, unsigned, unsigned));
*************** typedef struct tag_format
*** 47,58 ****
--- 47,60 ----
  } tag_format_t;
  
  static int flag_dump_contents = 0;
+ static int flag_dump_positions = 0;
  
  static const struct option options[] =
  {
    { "help",                 no_argument,       NULL, 'h' },
    { "version",              no_argument,       NULL, 'v' },
    { "long",                 no_argument,       NULL, 'l' },
+   { "positions",	    no_argument,       NULL, 'o' },
  };
  
  static const tag_format_t tag_table[] =
*************** int main (argc, argv)
*** 75,81 ****
  {
    int opt;
  
!   while ((opt = getopt_long (argc, argv, "hlv", options, NULL)) != -1)
      {
        switch (opt)
  	{
--- 77,83 ----
  {
    int opt;
  
!   while ((opt = getopt_long (argc, argv, "hlpv", options, NULL)) != -1)
      {
        switch (opt)
  	{
*************** int main (argc, argv)
*** 88,93 ****
--- 90,98 ----
  	case 'l':
  	  flag_dump_contents = 1;
  	  break;
+ 	case 'p':
+ 	  flag_dump_positions = 1;
+ 	  break;
  	default:
  	  fprintf (stderr, "unknown flag `%c'\n", opt);
  	}
*************** print_usage ()
*** 106,111 ****
--- 111,117 ----
    printf ("  -h, --help           Print this help\n");
    printf ("  -v, --version        Print version number\n");
    printf ("  -l, --long           Dump record contents too\n");
+   printf ("  -p, --positions      Dump record positions\n");
  }
  
  static void
*************** warranty; not even for MERCHANTABILITY o
*** 124,136 ****
  }
  
  static void
! print_prefix (filename, depth)
       const char *filename;
       unsigned depth;
  {
    static const char prefix[] = "    ";
    
!   printf ("%s:%.*s", filename, (int) depth, prefix);
  }
  
  static void
--- 130,146 ----
  }
  
  static void
! print_prefix (filename, depth, position)
       const char *filename;
       unsigned depth;
+      gcov_position_t position;
  {
    static const char prefix[] = "    ";
    
!   printf ("%s:", filename);
!   if (flag_dump_positions)
!     printf ("%lu:", (unsigned long) position);
!   printf ("%.*s", (int) depth, prefix);
  }
  
  static void
*************** dump_file (filename)
*** 178,207 ****
        printf ("%s:warning:current version is `%.4s'\n", filename, e);
    }
  
!   while (!gcov_is_eof ())
      {
!       unsigned tag = gcov_read_unsigned ();
!       unsigned length = gcov_read_unsigned ();
!       unsigned long base = gcov_position ();
        tag_format_t const *format;
        unsigned tag_depth;
        int error;
!       
        if (!tag)
! 	tag_depth = depth;
!       else
  	{
! 	  unsigned mask = GCOV_TAG_MASK (tag) >> 1;
! 	  
! 	  for (tag_depth = 4; mask; mask >>= 8)
  	    {
! 	      if ((mask & 0xff) != 0xff)
! 		{
! 		  printf ("%s:tag `%08x' is invalid\n", filename, tag);
! 		  break;
! 		}
! 	      tag_depth--;
  	    }
  	}
        for (format = tag_table; format->name; format++)
  	if (format->tag == tag)
--- 188,216 ----
        printf ("%s:warning:current version is `%.4s'\n", filename, e);
    }
  
!   while (1)
      {
!       gcov_position_t base, position = gcov_position ();
!       unsigned tag, length;
        tag_format_t const *format;
        unsigned tag_depth;
        int error;
!       unsigned mask;
! 
!       tag = gcov_read_unsigned ();
        if (!tag)
! 	break;
!       length = gcov_read_unsigned ();
!       base = gcov_position ();
!       mask = GCOV_TAG_MASK (tag) >> 1;
!       for (tag_depth = 4; mask; mask >>= 8)
  	{
! 	  if ((mask & 0xff) != 0xff)
  	    {
! 	      printf ("%s:tag `%08x' is invalid\n", filename, tag);
! 	      break;
  	    }
+ 	  tag_depth--;
  	}
        for (format = tag_table; format->name; format++)
  	if (format->tag == tag)
*************** dump_file (filename)
*** 220,226 ****
  	  tags[depth - 1] = tag;
  	}
        
!       print_prefix (filename, tag_depth);
        printf ("%08x:%4u:%s", tag, length, format->name);
        if (format->proc)
  	(*format->proc) (filename, tag, length);
--- 229,235 ----
  	  tags[depth - 1] = tag;
  	}
        
!       print_prefix (filename, tag_depth, position);
        printf ("%08x:%4u:%s", tag, length, format->name);
        if (format->proc)
  	(*format->proc) (filename, tag, length);
*************** dump_file (filename)
*** 246,251 ****
--- 255,262 ----
  	  break;
  	}
      }
+   if (!gcov_is_eof ())
+     printf ("%s:early end of file\n", filename);
    gcov_close ();
  }
  
*************** tag_blocks (filename, tag, length)
*** 289,295 ****
        for (ix = 0; ix != n_blocks; ix++)
  	{
  	  if (!(ix & 7))
! 	    printf ("\n%s:\t\t%u", filename, ix);
  	  printf (" %04x", gcov_read_unsigned ());
  	}
      }
--- 300,310 ----
        for (ix = 0; ix != n_blocks; ix++)
  	{
  	  if (!(ix & 7))
! 	    {
! 	      printf ("\n");
! 	      print_prefix (filename, 0, gcov_position ());
! 	      printf ("\t\t%u", ix);
! 	    }
  	  printf (" %04x", gcov_read_unsigned ());
  	}
      }
*************** tag_arcs (filename, tag, length)
*** 311,321 ****
  
        for (ix = 0; ix != n_arcs; ix++)
  	{
! 	  unsigned dst = gcov_read_unsigned ();
! 	  unsigned flags = gcov_read_unsigned ();
  	  
  	  if (!(ix & 3))
! 	    printf ("\n%s:\tblock %u:", filename, blockno);
  	  printf (" %u:%04x", dst, flags);
  	}
      }
--- 326,341 ----
  
        for (ix = 0; ix != n_arcs; ix++)
  	{
! 	  unsigned dst, flags;
  	  
  	  if (!(ix & 3))
! 	    {
! 	      printf ("\n");
! 	      print_prefix (filename, 0, gcov_position ());
! 	      printf ("\tblock %u:", blockno);
! 	    }
! 	  dst = gcov_read_unsigned ();
! 	  flags = gcov_read_unsigned ();
  	  printf (" %u:%04x", dst, flags);
  	}
      }
*************** tag_lines (filename, tag, length)
*** 334,339 ****
--- 354,360 ----
  
        while (1)
  	{
+ 	  gcov_position_t position = gcov_position ();
  	  const char *source = NULL;
  	  unsigned lineno = gcov_read_unsigned ();
  	  
*************** tag_lines (filename, tag, length)
*** 347,353 ****
  	  
  	  if (!sep)
  	    {
! 	      printf ("\n%s:\tblock %u:", filename, blockno);
  	      sep = "";
  	    }
  	  if (lineno)
--- 368,376 ----
  	  
  	  if (!sep)
  	    {
! 	      printf ("\n");
! 	      print_prefix (filename, 0, position);
! 	      printf ("\tblock %u:", blockno);
  	      sep = "";
  	    }
  	  if (lineno)
*************** tag_counters (filename, tag, length)
*** 381,390 ****
  
        for (ix = 0; ix != n_counts; ix++)
  	{
! 	  gcov_type count = gcov_read_counter ();
  	  
  	  if (!(ix & 7))
! 	    printf ("\n%s:\t\t%u", filename, ix);
  	  printf (" ");
  	  printf (HOST_WIDEST_INT_PRINT_DEC, count);
  	}
--- 404,419 ----
  
        for (ix = 0; ix != n_counts; ix++)
  	{
! 	  gcov_type count;
  	  
  	  if (!(ix & 7))
! 	    {
! 	      printf ("\n");
! 	      print_prefix (filename, 0, gcov_position ());
! 	      printf ("\t\t%u", ix);
! 	    }
! 	  
! 	  count = gcov_read_counter ();
  	  printf (" ");
  	  printf (HOST_WIDEST_INT_PRINT_DEC, count);
  	}
*************** tag_summary (filename, tag, length)
*** 405,411 ****
    
    for (ix = 0; ix != GCOV_COUNTERS; ix++)
      {
!       printf ("\n%sL\t\tcounts=%u, runs=%u", filename,
  	      summary.ctrs[ix].num, summary.ctrs[ix].runs);
        
        printf (", sum_all=" HOST_WIDEST_INT_PRINT_DEC,
--- 434,442 ----
    
    for (ix = 0; ix != GCOV_COUNTERS; ix++)
      {
!       printf ("\n");
!       print_prefix (filename, 0, 0);
!       printf ("\t\tcounts=%u, runs=%u",
  	      summary.ctrs[ix].num, summary.ctrs[ix].runs);
        
        printf (", sum_all=" HOST_WIDEST_INT_PRINT_DEC,
Index: gcov-io.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/gcov-io.c,v
retrieving revision 1.5
diff -c -3 -p -r1.5 gcov-io.c
*** gcov-io.c	10 May 2003 19:02:21 -0000	1.5
--- gcov-io.c	13 May 2003 18:20:08 -0000
*************** Software Foundation, 59 Temple Place - S
*** 24,29 ****
--- 24,38 ----
  /* Routines declared in gcov-io.h.  This file should be #included by
     another source file, after having #included gcov-io.h.  */
  
+ #if !IN_GCOV
+ static void gcov_write_block (unsigned);
+ static unsigned char *gcov_write_bytes (unsigned);
+ #endif
+ static const unsigned char *gcov_read_bytes (unsigned);
+ #if !IN_LIBGCOV
+ static void gcov_allocate (unsigned);
+ #endif
+ 
  /* Open a gcov file. NAME is the name of the file to open and MODE
     indicates whether a new file should be created, or an existing file
     opened for modification. If MODE is >= 0 an existing file will be
*************** GCOV_LINKAGE int
*** 36,42 ****
  gcov_open (const char *name, int mode)
  {
    int result = 1;
-   size_t alloc = 1024;
  #if GCOV_LOCKED
    struct flock s_flock;
  
--- 45,50 ----
*************** gcov_open (const char *name, int mode)
*** 49,111 ****
    
    if (gcov_var.file)
      abort ();
!   gcov_var.position = gcov_var.length = 0;
!   gcov_var.error = gcov_var.modified = 0;
    if (mode >= 0)
      gcov_var.file = fopen (name, "r+b");
!   if (!gcov_var.file && mode <= 0)
      {
        result = -1;
        gcov_var.file = fopen (name, "w+b");
      }
    if (!gcov_var.file)
      return 0;
  
  #if GCOV_LOCKED
    while (fcntl (fileno (gcov_var.file), F_SETLKW, &s_flock)
  	 && errno == EINTR)
      continue;
  #endif
  
-   if (result >= 0)
-     {
-       if (fseek (gcov_var.file, 0, SEEK_END))
- 	{
- 	  fclose (gcov_var.file);
- 	  gcov_var.file = 0;
- 	  return 0;
- 	}
-       gcov_var.length = ftell (gcov_var.file);
-       fseek (gcov_var.file, 0, SEEK_SET);
-       alloc += gcov_var.length;
-     }
-   if (alloc > gcov_var.alloc)
-     {
-       if (gcov_var.buffer)
- 	free (gcov_var.buffer);
-       gcov_var.alloc = alloc;
- #if IN_LIBGCOV
-       gcov_var.buffer = malloc (gcov_var.alloc);
-       if (!gcov_var.buffer)
- 	{
- 	  fclose (gcov_var.file);
- 	  gcov_var.file = 0;
- 	  gcov_var.length = 0;
- 	  gcov_var.alloc = 0;
- 	  return 0;
- 	}
- #else
-       gcov_var.buffer = xmalloc (gcov_var.alloc);
- #endif
-     }
-   if (result >= 0
-       && fread (gcov_var.buffer, gcov_var.length, 1, gcov_var.file) != 1)
-     {
-       fclose (gcov_var.file);
-       gcov_var.file = 0;
-       gcov_var.length = 0;
-       return 0;
-     }
    return result;
  }
  
--- 57,88 ----
    
    if (gcov_var.file)
      abort ();
!   gcov_var.start = 0;
!   gcov_var.offset = gcov_var.length = 0;
!   gcov_var.overread = -4u;
!   gcov_var.error = 0;
    if (mode >= 0)
      gcov_var.file = fopen (name, "r+b");
!   if (gcov_var.file)
!     gcov_var.mode = 1;
!   else if (mode <= 0)
      {
        result = -1;
        gcov_var.file = fopen (name, "w+b");
+       if (gcov_var.file)
+ 	gcov_var.mode = -1;
      }
    if (!gcov_var.file)
      return 0;
  
+   setbuf (gcov_var.file, (char *)0);
+   
  #if GCOV_LOCKED
    while (fcntl (fileno (gcov_var.file), F_SETLKW, &s_flock)
  	 && errno == EINTR)
      continue;
  #endif
  
    return result;
  }
  
*************** gcov_open (const char *name, int mode)
*** 115,129 ****
  GCOV_LINKAGE int
  gcov_close ()
  {
-   int result = 0;
-   
    if (gcov_var.file)
      {
!       if (gcov_var.modified
! 	  && (fseek (gcov_var.file, 0, SEEK_SET)
! 	      || fwrite (gcov_var.buffer, gcov_var.length,
! 			 1, gcov_var.file) != 1))
! 	result = 1;
        fclose (gcov_var.file);
        gcov_var.file = 0;
        gcov_var.length = 0;
--- 92,103 ----
  GCOV_LINKAGE int
  gcov_close ()
  {
    if (gcov_var.file)
      {
! #if !IN_GCOV
!       if (gcov_var.offset && gcov_var.mode < 0)
! 	gcov_write_block (gcov_var.offset);
! #endif
        fclose (gcov_var.file);
        gcov_var.file = 0;
        gcov_var.length = 0;
*************** gcov_close ()
*** 133,179 ****
    gcov_var.alloc = 0;
    gcov_var.buffer = 0;
  #endif
!   return result ? 1 : gcov_var.error;
  }
  
  #if !IN_GCOV
  /* Allocate space to write BYTES bytes to the gcov file. Return a
     pointer to those bytes, or NULL on failure.  */
  
! GCOV_LINKAGE unsigned char *
  gcov_write_bytes (unsigned bytes)
  {
    char unsigned *result;
  
!   if (gcov_var.position + bytes > gcov_var.alloc)
!     {
!       size_t new_size = (gcov_var.alloc + bytes) * 3 / 2;
! 
!       if (!gcov_var.buffer)
! 	return 0;
  #if IN_LIBGCOV
!       result = realloc (gcov_var.buffer, new_size);
!       if (!result)
  	{
! 	  free (gcov_var.buffer);
! 	  gcov_var.buffer = 0;
! 	  gcov_var.alloc = 0;
! 	  gcov_var.position = gcov_var.length = 0;
! 	  gcov_var.error = 1;
! 	  return 0;
  	}
  #else
!       result = xrealloc (gcov_var.buffer, new_size);
  #endif
!       gcov_var.alloc = new_size;
!       gcov_var.buffer = result;
!     }
    
-   result = &gcov_var.buffer[gcov_var.position];
-   gcov_var.position += bytes;
-   gcov_var.modified = 1;
-   if (gcov_var.position > gcov_var.length)
-     gcov_var.length = gcov_var.position;
    return result;
  }
  
--- 107,170 ----
    gcov_var.alloc = 0;
    gcov_var.buffer = 0;
  #endif
!   gcov_var.mode = 0;
!   return gcov_var.error;
! }
! 
! #if !IN_LIBGCOV
! static void
! gcov_allocate (unsigned length)
! {
!   size_t new_size = gcov_var.alloc;
!   
!   if (!new_size)
!     new_size = GCOV_BLOCK_SIZE;
!   new_size += length;
!   new_size *= 2;
!   
!   gcov_var.alloc = new_size;
!   gcov_var.buffer = xrealloc (gcov_var.buffer, new_size);
  }
+ #endif
  
  #if !IN_GCOV
+ /* Write out the current block, if needs be.  */
+ 
+ static void
+ gcov_write_block (unsigned size)
+ {
+   if (fwrite (gcov_var.buffer, size, 1, gcov_var.file) != 1)
+     gcov_var.error = 1;
+   gcov_var.start += size;
+   gcov_var.offset -= size;
+ }
+ 
  /* Allocate space to write BYTES bytes to the gcov file. Return a
     pointer to those bytes, or NULL on failure.  */
  
! static unsigned char *
  gcov_write_bytes (unsigned bytes)
  {
    char unsigned *result;
  
!   GCOV_CHECK_WRITING ();
  #if IN_LIBGCOV
!   if (gcov_var.offset >= GCOV_BLOCK_SIZE)
!     {
!       gcov_write_block (GCOV_BLOCK_SIZE);
!       if (gcov_var.offset)
  	{
! 	  GCOV_CHECK (gcov_var.offset == 4);
! 	  memcpy (gcov_var.buffer, gcov_var.buffer + GCOV_BLOCK_SIZE, 4);
  	}
+     }
  #else
!   if (gcov_var.offset + bytes > gcov_var.alloc)
!     gcov_allocate (gcov_var.offset + bytes);
  #endif
!   result = &gcov_var.buffer[gcov_var.offset];
!   gcov_var.offset += bytes;
    
    return result;
  }
  
*************** gcov_write_unsigned (gcov_unsigned_t val
*** 186,193 ****
    unsigned char *buffer = gcov_write_bytes (4);
    unsigned ix;
  
-   if (!buffer)
-     return;
    for (ix = 4; ix--; )
      {
        buffer[ix] = value;
--- 177,182 ----
*************** gcov_write_counter (gcov_type value)
*** 209,216 ****
    unsigned char *buffer = gcov_write_bytes (8);
    unsigned ix;
  
-   if (!buffer)
-     return;
    for (ix = 8; ix--; )
      {
        buffer[ix] = value;
--- 198,203 ----
*************** gcov_write_string (const char *string)
*** 233,238 ****
--- 220,227 ----
    unsigned pad = 0;
    unsigned rem = 0;
    unsigned char *buffer;
+   unsigned ix;
+   unsigned value;
  
    if (string)
      {
*************** gcov_write_string (const char *string)
*** 241,259 ****
      }
    
    buffer = gcov_write_bytes (4 + length + rem);
!   if (buffer)
      {
!       unsigned ix;
!       unsigned value = length;
!       
!       for (ix = 4; ix--; )
! 	{
! 	  buffer[ix] = value;
! 	  value >>= 8;
! 	}
!       memcpy (buffer + 4, string, length);
!       memcpy (buffer + 4 + length, &pad, rem);
      }
  }
  #endif
  
--- 230,244 ----
      }
    
    buffer = gcov_write_bytes (4 + length + rem);
! 
!   value = length;
!   for (ix = 4; ix--; )
      {
!       buffer[ix] = value;
!       value >>= 8;
      }
+   memcpy (buffer + 4, string, length);
+   memcpy (buffer + 4 + length, &pad, rem);
  }
  #endif
  
*************** gcov_write_string (const char *string)
*** 264,275 ****
  GCOV_LINKAGE gcov_position_t
  gcov_write_tag (gcov_unsigned_t tag)
  {
!   gcov_position_t result = gcov_var.position;
    unsigned char *buffer = gcov_write_bytes (8);
    unsigned ix;
  
-   if (!buffer)
-     return 0;
    for (ix = 4; ix--; )
      {
        buffer[ix] = tag;
--- 249,258 ----
  GCOV_LINKAGE gcov_position_t
  gcov_write_tag (gcov_unsigned_t tag)
  {
!   gcov_position_t result = gcov_var.start + gcov_var.offset;
    unsigned char *buffer = gcov_write_bytes (8);
    unsigned ix;
  
    for (ix = 4; ix--; )
      {
        buffer[ix] = tag;
*************** gcov_write_tag (gcov_unsigned_t tag)
*** 287,304 ****
  GCOV_LINKAGE void
  gcov_write_length (gcov_position_t position)
  {
!   if (position)
      {
!       gcov_unsigned_t length = gcov_var.position - position - 8;
!       unsigned char *buffer = &gcov_var.buffer[position + 4];
!       unsigned ix;
!       
!       for (ix = 4; ix--; )
! 	{
! 	  buffer[ix] = length;
! 	  length >>= 8;
! 	}
      }
  }
  
  #else /* IN_LIBGCOV */
--- 270,293 ----
  GCOV_LINKAGE void
  gcov_write_length (gcov_position_t position)
  {
!   unsigned offset;
!   gcov_unsigned_t length;
!   unsigned char *buffer;
!   unsigned ix;
! 
!   GCOV_CHECK_WRITING ();
!   GCOV_CHECK (position + 8 <= gcov_var.start + gcov_var.offset);
!   GCOV_CHECK (position >= gcov_var.start);
!   offset = position - gcov_var.start;
!   length = gcov_var.offset - offset - 8;
!   buffer = &gcov_var.buffer[offset + 4];
!   for (ix = 4; ix--; )
      {
!       buffer[ix] = length;
!       length >>= 8;
      }
+   if (gcov_var.offset >= GCOV_BLOCK_SIZE)
+     gcov_write_block (gcov_var.offset);
  }
  
  #else /* IN_LIBGCOV */
*************** gcov_write_tag_length (gcov_unsigned_t t
*** 311,318 ****
    unsigned char *buffer = gcov_write_bytes (8);
    unsigned ix;
  
-   if (!buffer)
-     return;
    for (ix = 4; ix--; )
      {
        buffer[ix] = tag;
--- 300,305 ----
*************** gcov_write_summary (gcov_unsigned_t tag,
*** 353,371 ****
  /* Return a pointer to read BYTES bytes from the gcov file. Returns
     NULL on failure (read past EOF). */
  
! GCOV_LINKAGE const unsigned char *
  gcov_read_bytes (unsigned bytes)
  {
    const unsigned char *result;
    
!   if (gcov_var.position + bytes > gcov_var.length)
      {
!       gcov_var.error = 1;
!       return 0;
      }
!   
!   result = &gcov_var.buffer[gcov_var.position];
!   gcov_var.position += bytes;
    return result;
  }
  
--- 340,386 ----
  /* Return a pointer to read BYTES bytes from the gcov file. Returns
     NULL on failure (read past EOF). */
  
! static const unsigned char *
  gcov_read_bytes (unsigned bytes)
  {
    const unsigned char *result;
+   unsigned excess = gcov_var.length - gcov_var.offset;
    
!   GCOV_CHECK_READING ();
!   if (excess < bytes)
      {
!       gcov_var.start += gcov_var.offset;
! #if IN_LIBGCOV
!       if (excess)
! 	{
! 	  GCOV_CHECK (excess == 4);
! 	  memcpy (gcov_var.buffer, gcov_var.buffer + gcov_var.offset, 4);
! 	}
! #else
!       memmove (gcov_var.buffer, gcov_var.buffer + gcov_var.offset, excess);
! #endif
!       gcov_var.offset = 0;
!       gcov_var.length = excess;
! #if IN_LIBGCOV
!       GCOV_CHECK (!gcov_var.length || gcov_var.length == 4);
!       excess = GCOV_BLOCK_SIZE;
! #else
!       if (gcov_var.length + bytes > gcov_var.alloc)
! 	gcov_allocate (gcov_var.length + bytes);
!       excess = gcov_var.alloc - gcov_var.length;
! #endif
!       excess = fread (gcov_var.buffer + gcov_var.offset,
! 		      1, excess, gcov_var.file);
!       gcov_var.length += excess;
!       if (gcov_var.length < bytes)
! 	{
! 	  gcov_var.overread += bytes - gcov_var.length;
! 	  gcov_var.length = 0;
! 	  return 0;
! 	}
      }
!   result = &gcov_var.buffer[gcov_var.offset];
!   gcov_var.offset += bytes;
    return result;
  }
  
*************** gcov_read_summary (struct gcov_summary *
*** 451,456 ****
--- 466,506 ----
        csum->sum_max = gcov_read_counter ();
      }
  }
+ 
+ #if !IN_LIBGCOV
+ /* Reset to a known position.  BASE should have been obtained from
+    gcov_position, LENGTH should be a record length.  */
+ 
+ GCOV_LINKAGE void
+ gcov_sync (gcov_position_t base, gcov_unsigned_t length)
+ {
+   GCOV_CHECK_READING ();
+   base += length;
+   if (base - gcov_var.start <= gcov_var.length)
+     gcov_var.offset = base - gcov_var.start;
+   else
+     {
+       gcov_var.offset = gcov_var.length = 0;
+       fseek (gcov_var.file, base, SEEK_SET);
+       gcov_var.start = ftell (gcov_var.file);
+     }
+ }
+ #endif
+ 
+ #if IN_LIBGCOV
+ /* Move to the a set position in a gcov file.  BASE is zero to move to
+    the end, and non-zero to move to that position. */
+ 
+ GCOV_LINKAGE void
+ gcov_seek (gcov_position_t base)
+ {
+   GCOV_CHECK_WRITING ();
+   if (gcov_var.offset)
+     gcov_write_block (gcov_var.offset);
+   fseek (gcov_var.file, base, base ? SEEK_SET : SEEK_END);
+   gcov_var.start = ftell (gcov_var.file);
+ }
+ #endif
  
  #if IN_GCOV > 0
  /* Return the modification time of the current gcov file.  */
Index: gcov-io.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/gcov-io.h,v
retrieving revision 1.33
diff -c -3 -p -r1.33 gcov-io.h
*** gcov-io.h	10 May 2003 19:02:21 -0000	1.33
--- gcov-io.h	13 May 2003 18:20:09 -0000
*************** typedef HOST_WIDEST_INT gcov_type;
*** 202,236 ****
  
  #endif /* !IN_LIBGCOV */
  
! /* In gcov we want function linkage to be static, so we do not
!    polute the global namespace. In libgcov we need these functions
!    to be extern, so prefix them with __gcov so that we do not conflict.
!    In the compiler we want it extern, so that they can be accessed from
     elsewhere.  */
  #if IN_LIBGCOV
  #define gcov_var __gcov_var
  #define gcov_open __gcov_open
  #define gcov_close __gcov_close
! #define gcov_write_bytes __gcov_write_bytes
  #define gcov_write_unsigned __gcov_write_unsigned
  #define gcov_write_counter __gcov_write_counter
- #pragma GCC poison gcov_write_string
- #pragma GCC poison gcov_write_tag
- #pragma GCC poison gcov_write_length
- #define gcov_write_tag_length __gcov_write_tag_length
  #define gcov_write_summary __gcov_write_summary
- #define gcov_read_bytes __gcov_read_bytes
  #define gcov_read_unsigned __gcov_read_unsigned
  #define gcov_read_counter __gcov_read_counter
- #pragma GCC poison gcov_read_string
  #define gcov_read_summary __gcov_read_summary
! #define gcov_position __gcov_position
! #define gcov_sync __gcov_sync
! #define gcov_seek __gcov_seek
! #define gcov_rewrite __gcov_rewrite
! #define gcov_is_eof __gcov_is_eof
! #define gcov_is_error __gcov_is_error
! #pragma GCC poison gcov_time
  #endif
  
  #ifndef GCOV_LINKAGE
--- 202,232 ----
  
  #endif /* !IN_LIBGCOV */
  
! /* In gcov we want function linkage to be static. In libgcov we need
!    these functions to be extern, so prefix them with __gcov.  In the
!    compiler we want it extern, so that they can be accessed from
     elsewhere.  */
  #if IN_LIBGCOV
  #define gcov_var __gcov_var
  #define gcov_open __gcov_open
  #define gcov_close __gcov_close
! #define gcov_write_tag_length __gcov_write_tag_length
! #define gcov_position __gcov_position
! #define gcov_seek __gcov_seek
! #define gcov_rewrite __gcov_rewrite
! #define gcov_is_error __gcov_is_error
! #define gcov_is_eof __gcov_is_eof
  #define gcov_write_unsigned __gcov_write_unsigned
  #define gcov_write_counter __gcov_write_counter
  #define gcov_write_summary __gcov_write_summary
  #define gcov_read_unsigned __gcov_read_unsigned
  #define gcov_read_counter __gcov_read_counter
  #define gcov_read_summary __gcov_read_summary
! 
! /* Poison these, so they don't accidentally slip in. */
! #pragma GCC poison gcov_write_string gcov_write_tag gcov_write_length
! #pragma GCC poison gcov_read_string gcov_sync gcov_time
! 
  #endif
  
  #ifndef GCOV_LINKAGE
*************** typedef HOST_WIDEST_INT gcov_type;
*** 255,272 ****
     file.  Values [41..9f] for those in the bbg file and [a1..ff] for
     the data file.  */
  
! #define GCOV_TAG_FUNCTION	 ((unsigned)0x01000000)
  #define GCOV_TAG_FUNCTION_LENGTH (2 * 4)
! #define GCOV_TAG_BLOCKS		 ((unsigned)0x01410000)
  #define GCOV_TAG_BLOCKS_LENGTH(NUM) ((NUM) * 4)
! #define GCOV_TAG_ARCS		 ((unsigned)0x01430000)
  #define GCOV_TAG_ARCS_LENGTH(NUM)  (1 * 4 + (NUM) * (2 * 4))
! #define GCOV_TAG_LINES		 ((unsigned)0x01450000)
! #define GCOV_TAG_COUNTER_BASE 	 ((unsigned)0x01a10000) /* First counter */
  #define GCOV_TAG_COUNTER_LENGTH(NUM) ((NUM) * 8)
! #define GCOV_TAG_OBJECT_SUMMARY  ((unsigned)0xa1000000)
! #define GCOV_TAG_PROGRAM_SUMMARY ((unsigned)0xa3000000)
! #define GCOV_TAG_SUMMARY_LENGTH  (1 * 4 + GCOV_COUNTERS_SUMMABLE * (2 * 4 + 3 * 8))
  
  /* Counters that are collected.  */
  #define GCOV_COUNTER_ARCS 	0  /* Arc transitions.  */
--- 251,269 ----
     file.  Values [41..9f] for those in the bbg file and [a1..ff] for
     the data file.  */
  
! #define GCOV_TAG_FUNCTION	 ((gcov_unsigned_t)0x01000000)
  #define GCOV_TAG_FUNCTION_LENGTH (2 * 4)
! #define GCOV_TAG_BLOCKS		 ((gcov_unsigned_t)0x01410000)
  #define GCOV_TAG_BLOCKS_LENGTH(NUM) ((NUM) * 4)
! #define GCOV_TAG_ARCS		 ((gcov_unsigned_t)0x01430000)
  #define GCOV_TAG_ARCS_LENGTH(NUM)  (1 * 4 + (NUM) * (2 * 4))
! #define GCOV_TAG_LINES		 ((gcov_unsigned_t)0x01450000)
! #define GCOV_TAG_COUNTER_BASE 	 ((gcov_unsigned_t)0x01a10000)
  #define GCOV_TAG_COUNTER_LENGTH(NUM) ((NUM) * 8)
! #define GCOV_TAG_OBJECT_SUMMARY  ((gcov_unsigned_t)0xa1000000)
! #define GCOV_TAG_PROGRAM_SUMMARY ((gcov_unsigned_t)0xa3000000)
! #define GCOV_TAG_SUMMARY_LENGTH  \
! 	(1 * 4 + GCOV_COUNTERS_SUMMABLE * (2 * 4 + 3 * 8))
  
  /* Counters that are collected.  */
  #define GCOV_COUNTER_ARCS 	0  /* Arc transitions.  */
*************** typedef HOST_WIDEST_INT gcov_type;
*** 282,291 ****
  
  /* Convert a counter index to a tag. */
  #define GCOV_TAG_FOR_COUNTER(COUNT)				\
! 	(GCOV_TAG_COUNTER_BASE + ((COUNT) << 17))
  /* Convert a tag to a counter.  */
  #define GCOV_COUNTER_FOR_TAG(TAG)					\
! 	(((TAG) - GCOV_TAG_COUNTER_BASE) >> 17)
  /* Check whether a tag is a counter tag.  */
  #define GCOV_TAG_IS_COUNTER(TAG)				\
  	(!((TAG) & 0xFFFF) && GCOV_COUNTER_FOR_TAG (TAG) < GCOV_COUNTERS)
--- 279,288 ----
  
  /* Convert a counter index to a tag. */
  #define GCOV_TAG_FOR_COUNTER(COUNT)				\
! 	(GCOV_TAG_COUNTER_BASE + ((gcov_unsigned_t)(COUNT) << 17))
  /* Convert a tag to a counter.  */
  #define GCOV_COUNTER_FOR_TAG(TAG)					\
! 	((unsigned)(((TAG) - GCOV_TAG_COUNTER_BASE) >> 17))
  /* Check whether a tag is a counter tag.  */
  #define GCOV_TAG_IS_COUNTER(TAG)				\
  	(!((TAG) & 0xFFFF) && GCOV_COUNTER_FOR_TAG (TAG) < GCOV_COUNTERS)
*************** extern void __gcov_merge_add (gcov_type 
*** 387,500 ****
  
  #if IN_LIBGCOV >= 0
  
! /* Because small reads and writes, interspersed with seeks cause lots
!    of disk activity, we buffer the entire count files.  */
  
  GCOV_LINKAGE struct gcov_var
  {
    FILE *file;
!   gcov_position_t position;
!   gcov_position_t length;
    size_t alloc;
-   unsigned modified;
-   int error;
    unsigned char *buffer;
  } gcov_var;
  
! /* Functions for reading and writing gcov files.  */
  GCOV_LINKAGE int gcov_open (const char */*name*/, int /*truncate*/);
  GCOV_LINKAGE int gcov_close (void);
! #if !IN_GCOV
! GCOV_LINKAGE unsigned char *gcov_write_bytes (unsigned);
! GCOV_LINKAGE void gcov_write_unsigned (gcov_unsigned_t);
  #if IN_LIBGCOV
  GCOV_LINKAGE void gcov_write_counter (gcov_type);
- #else
- GCOV_LINKAGE void gcov_write_string (const char *);
- #endif
- #if !IN_LIBGCOV
- GCOV_LINKAGE gcov_position_t gcov_write_tag (gcov_unsigned_t);
- GCOV_LINKAGE void gcov_write_length (gcov_position_t /*position*/);
- #else
  GCOV_LINKAGE void gcov_write_tag_length (gcov_unsigned_t, gcov_unsigned_t);
  GCOV_LINKAGE void gcov_write_summary (gcov_unsigned_t /*tag*/,
  				      const struct gcov_summary *);
! #endif
! #endif /* !IN_GCOV */
! GCOV_LINKAGE const unsigned char *gcov_read_bytes (unsigned);
! GCOV_LINKAGE gcov_unsigned_t gcov_read_unsigned (void);
! GCOV_LINKAGE gcov_type gcov_read_counter (void);
! #if !IN_LIBGCOV
  GCOV_LINKAGE const char *gcov_read_string (void);
  #endif
! GCOV_LINKAGE void gcov_read_summary (struct gcov_summary *);
! static gcov_position_t gcov_position (void);
! static void gcov_sync (gcov_position_t /*base*/, gcov_unsigned_t /*length */);
! static void gcov_seek (gcov_position_t /*position*/);
! static void gcov_rewrite (void);
! static int gcov_is_eof (void);
! static int gcov_is_error (void);
  #if IN_GCOV > 0
  GCOV_LINKAGE time_t gcov_time (void);
  #endif
  
  /* Save the current position in the gcov file.  */
  
  static inline gcov_position_t
  gcov_position (void)
  {
!   return gcov_var.position;
  }
  
! /* Reset to a known position.  BASE should have been obtained from
!    gcov_save_position, LENGTH should be a record length, or zero.  */
  
! static inline void
! gcov_sync (gcov_position_t base, gcov_unsigned_t length)
  {
!   if (gcov_var.buffer)
!     {
!       base += length;
!       if (gcov_var.length < base)
! 	{
! 	  gcov_var.error = 1;
! 	  base = gcov_var.length;
! 	}
!       gcov_var.position = base;
!     }
  }
  
! /* Move to the end of the gcov file.  */
  
! static inline void
! gcov_seek (gcov_position_t base)
  {
!   gcov_var.position = base < gcov_var.length ? base : gcov_var.length;
  }
  
  /* Move to beginning of file and intialize for writing.  */
  
  static inline void
  gcov_rewrite (void)
  {
!   gcov_var.position = 0;
! }
! 
! /* Tests whether we have reached end of .da file.  */
! 
! static inline int
! gcov_is_eof ()
! {
!   return gcov_var.position == gcov_var.length;
! }
! 
! /* Return non-zero if the error flag is set.  */
! 
! static inline int
! gcov_is_error ()
! {
!   return gcov_var.file ? gcov_var.error : 1;
  }
  
  #endif /* IN_LIBGCOV >= 0 */
  
--- 384,514 ----
  
  #if IN_LIBGCOV >= 0
  
! /* Optimum size read from or written to disk.  */
! #define GCOV_BLOCK_SIZE (1 << 12)
  
  GCOV_LINKAGE struct gcov_var
  {
    FILE *file;
!   gcov_position_t start;	/* Position of first byte of block */
!   unsigned offset;		/* Read/write position within the block. */
!   unsigned length;		/* Read limit in the block. */
!   unsigned overread;		/* Number of bytes overread.  */
!   int error;			/* < 0 overflow, > 0 disk error.  */
!   int mode;	                /* < 0 writing, > 0 reading */
! #if IN_LIBGCOV
!   /* Holds one block plus 4 bytes, thus all coverage reads & writes
!      fit within this buffer and we always can transfer GCOV_BLOCK_SIZE
!      to and from the disk. libgcov never backtracks and only writes 4
!      or 8 byte objects.  */
!   unsigned char buffer[GCOV_BLOCK_SIZE + 4];
! #else
!   /* Holds a variable length block, as the compiler can write
!      strings and needs to backtrack.  */
    size_t alloc;
    unsigned char *buffer;
+ #endif
  } gcov_var;
  
! /* Functions for reading and writing gcov files. You can open a file
!    for (1) reading or (2) writing or (3) reading then rewriting. When
!    reading a file you may use the gcov_read_* functions, gcov_sync,
!    gcov_position, & gcov_error. When writing a file you
!    may use the gcov_write functions, gcov_seek & gcov_error. When a
!    file is to be rewritten you use the functions for reading, then
!    gcov_rewrite then the functions for writing.  Your file may become
!    corrupted if you break these invariants. */
  GCOV_LINKAGE int gcov_open (const char */*name*/, int /*truncate*/);
  GCOV_LINKAGE int gcov_close (void);
! 
! /* Available everywhere.  */
! static gcov_position_t gcov_position (void);
! static int gcov_is_error (void);
! static int gcov_is_eof (void);
! 
! GCOV_LINKAGE gcov_unsigned_t gcov_read_unsigned (void);
! GCOV_LINKAGE gcov_type gcov_read_counter (void);
! GCOV_LINKAGE void gcov_read_summary (struct gcov_summary *);
! 
  #if IN_LIBGCOV
+ /* Available only in libgcov */
  GCOV_LINKAGE void gcov_write_counter (gcov_type);
  GCOV_LINKAGE void gcov_write_tag_length (gcov_unsigned_t, gcov_unsigned_t);
  GCOV_LINKAGE void gcov_write_summary (gcov_unsigned_t /*tag*/,
  				      const struct gcov_summary *);
! static void gcov_rewrite (void);
! GCOV_LINKAGE void gcov_seek (gcov_position_t /*position*/);
! #else
! /* Available outside libgcov */
  GCOV_LINKAGE const char *gcov_read_string (void);
+ GCOV_LINKAGE void gcov_sync (gcov_position_t /*base*/,
+ 			     gcov_unsigned_t /*length */);
  #endif
! 
! #if !IN_GCOV
! /* Available outside gcov */
! GCOV_LINKAGE void gcov_write_unsigned (gcov_unsigned_t);
! #endif
! 
! #if !IN_GCOV && !IN_LIBGCOV
! /* Available only in compiler */
! GCOV_LINKAGE void gcov_write_string (const char *);
! GCOV_LINKAGE gcov_position_t gcov_write_tag (gcov_unsigned_t);
! GCOV_LINKAGE void gcov_write_length (gcov_position_t /*position*/);
! #endif
! 
  #if IN_GCOV > 0
+ /* Available in gcov */
  GCOV_LINKAGE time_t gcov_time (void);
  #endif
  
+ /* Make sure the library is used correctly.  */
+ #if ENABLE_CHECKING
+ #define GCOV_CHECK(expr) ((expr) ? (void)0 : (void)abort ())
+ #else
+ #define GCOV_CHECK(expr)
+ #endif
+ #define GCOV_CHECK_READING() GCOV_CHECK(gcov_var.mode > 0)
+ #define GCOV_CHECK_WRITING() GCOV_CHECK(gcov_var.mode < 0)
+ 
  /* Save the current position in the gcov file.  */
  
  static inline gcov_position_t
  gcov_position (void)
  {
!   GCOV_CHECK_READING ();
!   return gcov_var.start + gcov_var.offset;
  }
  
! /* Return non-zero if we read to end of file.  */
  
! static inline int
! gcov_is_eof ()
  {
!   return !gcov_var.overread;
  }
  
! /* Return non-zero if the error flag is set.  */
  
! static inline int
! gcov_is_error ()
  {
!   return gcov_var.file ? gcov_var.error : 1;
  }
  
+ #if IN_LIBGCOV
  /* Move to beginning of file and intialize for writing.  */
  
  static inline void
  gcov_rewrite (void)
  {
!   GCOV_CHECK_READING ();
!   gcov_var.mode = -1;
!   gcov_var.start = 0;
!   gcov_var.offset = 0;
!   fseek (gcov_var.file, 0L, SEEK_SET);
  }
+ #endif
  
  #endif /* IN_LIBGCOV >= 0 */
  
Index: gcov.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/gcov.c,v
retrieving revision 1.63
diff -c -3 -p -r1.63 gcov.c
*** gcov.c	7 May 2003 10:40:08 -0000	1.63
--- gcov.c	13 May 2003 18:20:14 -0000
*************** read_graph_file ()
*** 711,717 ****
    struct function_info *fn = NULL;
    source_t *src = NULL;
    unsigned ix;
! 
    if (!gcov_open (bbg_file_name, 1))
      {
        fnotice (stderr, "%s:cannot open graph file\n", bbg_file_name);
--- 711,718 ----
    struct function_info *fn = NULL;
    source_t *src = NULL;
    unsigned ix;
!   unsigned tag;
!   
    if (!gcov_open (bbg_file_name, 1))
      {
        fnotice (stderr, "%s:cannot open graph file\n", bbg_file_name);
*************** read_graph_file ()
*** 740,750 ****
  	       bbg_file_name, v, e);
      }
    
!   while (!gcov_is_eof ())
      {
-       unsigned tag = gcov_read_unsigned ();
        unsigned length = gcov_read_unsigned ();
!       unsigned long base = gcov_position ();
  
        if (tag == GCOV_TAG_FUNCTION)
  	{
--- 741,750 ----
  	       bbg_file_name, v, e);
      }
    
!   while ((tag = gcov_read_unsigned ()))
      {
        unsigned length = gcov_read_unsigned ();
!       gcov_position_t base = gcov_position ();
  
        if (tag == GCOV_TAG_FUNCTION)
  	{
*************** read_graph_file ()
*** 906,917 ****
  	}
        gcov_sync (base, length);
        if (gcov_is_error ())
! 	{
! 	corrupt:;
! 	  fnotice (stderr, "%s:corrupted\n", bbg_file_name);
! 	  gcov_close ();
! 	  return 1;
! 	}
      }
    gcov_close ();
    
--- 906,919 ----
  	}
        gcov_sync (base, length);
        if (gcov_is_error ())
! 	break;
!     }
!   if (!gcov_is_eof ())
!     {
!     corrupt:;
!       fnotice (stderr, "%s:corrupted\n", bbg_file_name);
!       gcov_close ();
!       return 1;
      }
    gcov_close ();
    
*************** read_count_file ()
*** 976,982 ****
--- 978,986 ----
  {
    unsigned ix;
    unsigned version;
+   unsigned tag;
    function_t *fn = NULL;
+   int error = 0;
  
    if (!gcov_open (da_file_name, 1))
      {
*************** read_count_file ()
*** 1005,1016 ****
  	       da_file_name, v, e);
      }
    
!   while (!gcov_is_eof ())
      {
-       unsigned tag = gcov_read_unsigned ();
        unsigned length = gcov_read_unsigned ();
        unsigned long base = gcov_position ();
-       int error;
  
        if (tag == GCOV_TAG_OBJECT_SUMMARY)
  	gcov_read_summary (&object_summary);
--- 1009,1018 ----
  	       da_file_name, v, e);
      }
    
!   while ((tag = gcov_read_unsigned ()))
      {
        unsigned length = gcov_read_unsigned ();
        unsigned long base = gcov_position ();
  
        if (tag == GCOV_TAG_OBJECT_SUMMARY)
  	gcov_read_summary (&object_summary);
*************** read_count_file ()
*** 1061,1073 ****
  	}
        gcov_sync (base, length);
        if ((error = gcov_is_error ()))
! 	{
! 	  fnotice (stderr, error < 0
! 		   ? "%s:overflowed\n" : "%s:corrupted\n", da_file_name);
! 	  goto cleanup;
! 	}
      }
  
    gcov_close ();
    return 0;
  }
--- 1063,1078 ----
  	}
        gcov_sync (base, length);
        if ((error = gcov_is_error ()))
! 	break;
      }
  
+   if (!gcov_is_eof ())
+     {
+       fnotice (stderr, error < 0 ? "%s:overflowed\n" : "%s:corrupted\n",
+ 	       da_file_name);
+       goto cleanup;
+     }
+   
    gcov_close ();
    return 0;
  }
Index: libgcov.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/libgcov.c,v
retrieving revision 1.14
diff -c -3 -p -r1.14 libgcov.c
*** libgcov.c	10 May 2003 19:02:21 -0000	1.14
--- libgcov.c	13 May 2003 18:20:14 -0000
*************** gcov_exit (void)
*** 152,161 ****
        const struct gcov_ctr_info *ci_ptr;
        struct gcov_ctr_summary *cs_ptr;
        struct gcov_ctr_summary *cs_obj, *cs_tobj, *cs_prg, *cs_tprg, *cs_all;
!       int error;
        int merging;
        gcov_unsigned_t tag, length;
!       gcov_position_t summary_pos = ~(gcov_position_t)0;
  
        /* Totals for this object file.  */
        memset (&this_object, 0, sizeof (this_object));
--- 152,161 ----
        const struct gcov_ctr_info *ci_ptr;
        struct gcov_ctr_summary *cs_ptr;
        struct gcov_ctr_summary *cs_obj, *cs_tobj, *cs_prg, *cs_tprg, *cs_all;
!       int error = 0;
        int merging;
        gcov_unsigned_t tag, length;
!       gcov_position_t summary_pos = 0;
  
        /* Totals for this object file.  */
        memset (&this_object, 0, sizeof (this_object));
*************** gcov_exit (void)
*** 256,267 ****
  	    }
  
  	  /* Check program & object summary */
! 	  while (!gcov_is_eof ())
  	    {
  	      gcov_position_t base = gcov_position ();
  	      int is_program;
  	      
  	      tag = gcov_read_unsigned ();
  	      length = gcov_read_unsigned ();
  	      is_program = tag == GCOV_TAG_PROGRAM_SUMMARY;
  	      if (length != GCOV_TAG_SUMMARY_LENGTH
--- 256,269 ----
  	    }
  
  	  /* Check program & object summary */
! 	  while (1)
  	    {
  	      gcov_position_t base = gcov_position ();
  	      int is_program;
  	      
  	      tag = gcov_read_unsigned ();
+ 	      if (!tag)
+ 		break;
  	      length = gcov_read_unsigned ();
  	      is_program = tag == GCOV_TAG_PROGRAM_SUMMARY;
  	      if (length != GCOV_TAG_SUMMARY_LENGTH
*************** gcov_exit (void)
*** 269,292 ****
  		goto read_mismatch;
  	      gcov_read_summary (is_program ? &program : &object);
  	      if ((error = gcov_is_error ()))
  		{
! 		read_error:;
! 		  fprintf (stderr, error < 0 ?
! 			   "profiling:%s:Overflow merging\n" :
! 			   "profiling:%s:Error merging\n", gi_ptr->filename);
! 		  goto read_fatal;
  		}
- 	      
- 	      if (!is_program || program.checksum != gcov_crc32)
- 		continue;
- 	      summary_pos = base;
- 	      break;
  	    }
  	  gcov_rewrite ();
  	}
        else
  	memset (&object, 0, sizeof (object));
!       if (!(summary_pos + 1))
  	memset (&program, 0, sizeof (program));
  
        /* Merge the summaries.  */
--- 271,296 ----
  		goto read_mismatch;
  	      gcov_read_summary (is_program ? &program : &object);
  	      if ((error = gcov_is_error ()))
+ 		goto read_error;
+ 	      if (is_program && program.checksum == gcov_crc32)
  		{
! 		  summary_pos = base;
! 		  goto rewrite;
  		}
  	    }
+ 	  if (!gcov_is_eof ())
+ 	    {
+ 	    read_error:;
+ 	      fprintf (stderr, error < 0 ? "profiling:%s:Overflow merging\n"
+ 		       : "profiling:%s:Error merging\n", gi_ptr->filename);
+ 	      goto read_fatal;
+ 	    }
+ 	rewrite:;
  	  gcov_rewrite ();
  	}
        else
  	memset (&object, 0, sizeof (object));
!       if (!summary_pos)
  	memset (&program, 0, sizeof (program));
  
        /* Merge the summaries.  */

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]