This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[gcov patch]: Use a smaller buffer
- From: Nathan Sidwell <nathan at codesourcery dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Wed, 14 May 2003 17:03:56 +0100
- Subject: [gcov patch]: Use a smaller buffer
- Organization: Codesourcery LLC
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. */