Makefile.in (loop-init.o): Do not depend on gcov-io.h, gcov-iov.h.

* Makefile.in (loop-init.o): Do not depend on gcov-io.h,
	gcov-iov.h.

	Simplify interface to gcov reading and writing.
	* gcov-io.h (gcov_file, gcov_position, gcov_length, gcov_buffer,
	gcov_alloc, gcov_modified, gcov_errored): Move into ...
	(struct gcov_var gcov_var): ... this static structure.
	(gcov_write_unsigned, gcov_write_counter, gcov_write_string):
	Return void.
	(gcov_read_unsigned, gcov_read_couter, gcov_read_string): Return
	read object.
	(gcov_read_bytes, gcov_write_bytes): Set error flag on error.
	(gcov_reserve_length): Remove.
	(gcov_write_tag): New.
	(gcov_write_length): Adjust.
	(gcov_read_summary, gcov_write_summary): Adjust.
	(gcov_eof, gcov_ok): Rename to ...
	(gcov_is_eof, gcov_is_error): ... here. Return error code.
	(gcov_save_position, gcov_resync): Rename to ...
	(gcov_position, gcov_seek): ... here.
	(gcov_skip, gcov_skip_string): Remove.
	(gcov_error): Remove.
	(gcov_open, gcov_close): Adjust.
	* gcov.c (find_source): Take const char *, copy it on allocation.
	(read_graph_file): Adjust.
	(read_count_file): Adjust.
	* libgcov.c (gcov_exit): Adjust.
	* gcov-dump.c (tag_function, tag_blocks, tag_arcs, tag_lines,
	tag_arc_counts, tag_summary): Return void. Adjust.
	(struct tag_format): Adjust proc member.
	(dump_file): Adjust gcov calls.

From-SVN: r65464
This commit is contained in:
Nathan Sidwell 2003-04-11 10:38:57 +00:00 committed by Nathan Sidwell
parent 7a615b2579
commit 94de45d9fe
7 changed files with 515 additions and 653 deletions

View File

@ -1,3 +1,37 @@
2003-04-11 Nathan Sidwell <nathan@codesourcery.com>
* Makefile.in (loop-init.o): Do not depend on gcov-io.h,
gcov-iov.h.
Simplify interface to gcov reading and writing.
* gcov-io.h (gcov_file, gcov_position, gcov_length, gcov_buffer,
gcov_alloc, gcov_modified, gcov_errored): Move into ...
(struct gcov_var gcov_var): ... this static structure.
(gcov_write_unsigned, gcov_write_counter, gcov_write_string):
Return void.
(gcov_read_unsigned, gcov_read_couter, gcov_read_string): Return
read object.
(gcov_read_bytes, gcov_write_bytes): Set error flag on error.
(gcov_reserve_length): Remove.
(gcov_write_tag): New.
(gcov_write_length): Adjust.
(gcov_read_summary, gcov_write_summary): Adjust.
(gcov_eof, gcov_ok): Rename to ...
(gcov_is_eof, gcov_is_error): ... here. Return error code.
(gcov_save_position, gcov_resync): Rename to ...
(gcov_position, gcov_seek): ... here.
(gcov_skip, gcov_skip_string): Remove.
(gcov_error): Remove.
(gcov_open, gcov_close): Adjust.
* gcov.c (find_source): Take const char *, copy it on allocation.
(read_graph_file): Adjust.
(read_count_file): Adjust.
* libgcov.c (gcov_exit): Adjust.
* gcov-dump.c (tag_function, tag_blocks, tag_arcs, tag_lines,
tag_arc_counts, tag_summary): Return void. Adjust.
(struct tag_format): Adjust proc member.
(dump_file): Adjust gcov calls.
2003-04-11 Alexandre Oliva <aoliva@redhat.com>
* Makefile.in (fixinc.sh): Pass BUILD_LIBERTY as LIBERTY to

View File

@ -1652,8 +1652,8 @@ cfgloopanal.o : cfgloopanal.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) \
$(BASIC_BLOCK_H) hard-reg-set.h cfgloop.h $(EXPR_H) coretypes.h $(TM_H)
cfgloopmanip.o : cfgloopmanip.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) \
$(BASIC_BLOCK_H) hard-reg-set.h cfgloop.h cfglayout.h output.h coretypes.h $(TM_H)
loop-init.o : loop-init.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) gcov-io.h \
gcov-iov.h $(BASIC_BLOCK_H) hard-reg-set.h cfgloop.h cfglayout.h profile.h \
loop-init.o : loop-init.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) \
$(BASIC_BLOCK_H) hard-reg-set.h cfgloop.h cfglayout.h profile.h \
coretypes.h $(TM_H)
loop-unswitch.o : loop-unswitch.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TM_H) \
$(BASIC_BLOCK_H) hard-reg-set.h cfgloop.h cfglayout.h params.h \

View File

@ -30,19 +30,19 @@ 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 int tag_function PARAMS ((const char *, unsigned, unsigned));
static int tag_blocks PARAMS ((const char *, unsigned, unsigned));
static int tag_arcs PARAMS ((const char *, unsigned, unsigned));
static int tag_lines PARAMS ((const char *, unsigned, unsigned));
static int tag_arc_counts PARAMS ((const char *, unsigned, unsigned));
static int tag_summary PARAMS ((const char *, unsigned, unsigned));
static void tag_function PARAMS ((const char *, unsigned, unsigned));
static void tag_blocks PARAMS ((const char *, unsigned, unsigned));
static void tag_arcs PARAMS ((const char *, unsigned, unsigned));
static void tag_lines PARAMS ((const char *, unsigned, unsigned));
static void tag_arc_counts PARAMS ((const char *, unsigned, unsigned));
static void tag_summary PARAMS ((const char *, unsigned, unsigned));
extern int main PARAMS ((int, char **));
typedef struct tag_format
{
unsigned tag;
char const *name;
int (*proc) (const char *, unsigned, unsigned);
void (*proc) (const char *, unsigned, unsigned);
} tag_format_t;
static int flag_dump_contents = 0;
@ -140,8 +140,6 @@ dump_file (filename)
{
unsigned tags[4];
unsigned depth = 0;
unsigned magic, version;
unsigned tag, length;
if (!gcov_open (filename, 1))
{
@ -149,16 +147,10 @@ dump_file (filename)
return;
}
if (gcov_read_unsigned (&magic) || gcov_read_unsigned (&version))
{
read_error:;
printf ("%s:read error at %lu\n", filename, gcov_save_position ());
gcov_close ();
return;
}
/* magic */
{
unsigned magic = gcov_read_unsigned ();
unsigned version = gcov_read_unsigned ();
const char *type = NULL;
char e[4], v[4], m[4];
unsigned expected = GCOV_VERSION;
@ -187,13 +179,14 @@ dump_file (filename)
printf ("%s:warning:current version is `%.4s'\n", filename, e);
}
while (!gcov_read_unsigned (&tag) && !gcov_read_unsigned (&length))
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;
long base, end;
base = gcov_save_position ();
int error;
if (!tag)
tag_depth = depth;
@ -231,57 +224,53 @@ dump_file (filename)
print_prefix (filename, tag_depth);
printf ("%08x:%4u:%s", tag, length, format->name);
if (format->proc)
if ((*format->proc) (filename, tag, length))
goto read_error;
(*format->proc) (filename, tag, length);
printf ("\n");
end = gcov_save_position ();
gcov_resync (base, length);
if (format->proc && end != base + (long)length)
if (flag_dump_contents && format->proc)
{
if (end > base + (long)length)
unsigned long actual_length = gcov_position () - base;
if (actual_length > length)
printf ("%s:record size mismatch %lu bytes overread\n",
filename, (end - base) - length);
else
filename, actual_length - length);
else if (length > actual_length)
printf ("%s:record size mismatch %lu bytes unread\n",
filename, length - (end - base));
filename, length - actual_length);
}
gcov_seek (base, length);
if ((error = gcov_is_error ()))
{
printf (error < 0 ? "%s:counter overflow at %lu\n" :
"%s:read error at %lu\n", filename, gcov_position ());
break;
}
}
if (!gcov_eof ())
goto read_error;
gcov_close ();
}
static int
static void
tag_function (filename, tag, length)
const char *filename ATTRIBUTE_UNUSED;
unsigned tag ATTRIBUTE_UNUSED;
unsigned length ATTRIBUTE_UNUSED;
{
char *name = NULL;
unsigned checksum;
char *src = NULL;
unsigned lineno = 0;
unsigned long pos = gcov_save_position ();
const char *name;
unsigned long pos = gcov_position ();
if (gcov_read_string (&name)
|| gcov_read_unsigned (&checksum))
return 1;
name = gcov_read_string ();
printf (" `%s'", name ? name : "NULL");
printf (" checksum=0x%08x", gcov_read_unsigned ());
if (gcov_save_position () - pos != length
&& (gcov_read_string (&src)
|| gcov_read_unsigned (&lineno)))
return 1;
printf (" `%s' checksum=0x%08x", name, checksum);
if (src)
printf (" %s:%u", src, lineno);
free (name);
free (src);
return 0;
if (gcov_position () - pos < length)
{
name = gcov_read_string ();
printf (" %s", name ? name : "NULL");
printf (":%u", gcov_read_unsigned ());
}
}
static int
static void
tag_blocks (filename, tag, length)
const char *filename ATTRIBUTE_UNUSED;
unsigned tag ATTRIBUTE_UNUSED;
@ -297,22 +286,14 @@ tag_blocks (filename, tag, length)
for (ix = 0; ix != n_blocks; ix++)
{
unsigned flags;
if (gcov_read_unsigned (&flags))
return 1;
if (!(ix & 7))
printf ("\n%s:\t\t%u", filename, ix);
printf (" %04x", flags);
printf (" %04x", gcov_read_unsigned ());
}
}
else
gcov_skip (n_blocks * 4);
return 0;
}
static int
static void
tag_arcs (filename, tag, length)
const char *filename ATTRIBUTE_UNUSED;
unsigned tag ATTRIBUTE_UNUSED;
@ -324,29 +305,21 @@ tag_arcs (filename, tag, length)
if (flag_dump_contents)
{
unsigned ix;
unsigned blockno;
if (gcov_read_unsigned (&blockno))
return 1;
unsigned blockno = gcov_read_unsigned ();
for (ix = 0; ix != n_arcs; ix++)
{
unsigned dst, flags;
unsigned dst = gcov_read_unsigned ();
unsigned flags = gcov_read_unsigned ();
if (gcov_read_unsigned (&dst) || gcov_read_unsigned (&flags))
return 1;
if (!(ix & 3))
printf ("\n%s:\t\t%u:", filename, blockno);
printf ("\n%s:\tblock %u:", filename, blockno);
printf (" %u:%04x", dst, flags);
}
}
else
gcov_skip (4 + n_arcs * 8);
return 0;
}
static int
static void
tag_lines (filename, tag, length)
const char *filename ATTRIBUTE_UNUSED;
unsigned tag ATTRIBUTE_UNUSED;
@ -354,26 +327,17 @@ tag_lines (filename, tag, length)
{
if (flag_dump_contents)
{
char *source = NULL;
unsigned blockno;
unsigned blockno = gcov_read_unsigned ();
char const *sep = NULL;
if (gcov_read_unsigned (&blockno))
return 1;
while (1)
{
unsigned lineno;
const char *source = NULL;
unsigned lineno = gcov_read_unsigned ();
if (gcov_read_unsigned (&lineno))
{
free (source);
return 1;
}
if (!lineno)
{
if (gcov_read_string (&source))
return 1;
source = gcov_read_string ();
if (!source)
break;
sep = NULL;
@ -381,7 +345,7 @@ tag_lines (filename, tag, length)
if (!sep)
{
printf ("\n%s:\t\t%u:", filename, blockno);
printf ("\n%s:\tblock %u:", filename, blockno);
sep = "";
}
if (lineno)
@ -396,13 +360,9 @@ tag_lines (filename, tag, length)
}
}
}
else
gcov_skip (length);
return 0;
}
static int
static void
tag_arc_counts (filename, tag, length)
const char *filename ATTRIBUTE_UNUSED;
unsigned tag ATTRIBUTE_UNUSED;
@ -417,23 +377,17 @@ tag_arc_counts (filename, tag, length)
for (ix = 0; ix != n_counts; ix++)
{
gcov_type count;
gcov_type count = gcov_read_counter ();
if (gcov_read_counter (&count))
return 1;
if (!(ix & 7))
printf ("\n%s:\t\t%u", filename, ix);
printf (" ");
printf (HOST_WIDEST_INT_PRINT_DEC, count);
}
}
else
gcov_skip (n_counts * 8);
return 0;
}
static int
static void
tag_summary (filename, tag, length)
const char *filename ATTRIBUTE_UNUSED;
unsigned tag ATTRIBUTE_UNUSED;
@ -441,8 +395,8 @@ tag_summary (filename, tag, length)
{
struct gcov_summary summary;
if (gcov_read_summary (&summary))
return 1;
gcov_read_summary (&summary);
printf (" checksum=0x%08x", summary.checksum);
printf ("\n%s:\t\truns=%u, arcs=%u", filename,
@ -459,5 +413,4 @@ tag_summary (filename, tag, length)
printf (", sum_max=");
printf (HOST_WIDEST_INT_PRINT_DEC,
(HOST_WIDEST_INT)summary.arc_sum_max);
return 0;
}

View File

@ -287,45 +287,44 @@ extern void __gcov_flush (void);
/* Because small reads and writes, interspersed with seeks cause lots
of disk activity, we buffer the entire count files. */
static FILE *gcov_file;
static size_t gcov_position;
static size_t gcov_length;
static unsigned char *gcov_buffer;
static size_t gcov_alloc;
static int gcov_modified;
static int gcov_errored = 1;
static struct gcov_var
{
FILE *file;
size_t position;
size_t length;
size_t alloc;
unsigned modified;
int error;
unsigned char *buffer;
} gcov_var;
/* Functions for reading and writing gcov files. */
static int gcov_open (const char */*name*/, int /*truncate*/);
static int gcov_close (void);
#if !IN_GCOV
static unsigned char *gcov_write_bytes (unsigned);
static int gcov_write_unsigned (unsigned);
static void gcov_write_unsigned (unsigned);
#if IN_LIBGCOV
static int gcov_write_counter (gcov_type);
static void gcov_write_counter (gcov_type);
#endif
static int gcov_write_string (const char *);
static unsigned long gcov_reserve_length (void);
static int gcov_write_length (unsigned long /*position*/);
static void gcov_write_string (const char *);
static unsigned long gcov_write_tag (unsigned);
static void gcov_write_length (unsigned long /*position*/);
#if IN_LIBGCOV
static int gcov_write_summary (unsigned, const struct gcov_summary *);
static void gcov_write_summary (unsigned, const struct gcov_summary *);
#endif
#endif /* !IN_GCOV */
static const unsigned char *gcov_read_bytes (unsigned);
static int gcov_read_unsigned (unsigned *);
static int gcov_read_counter (gcov_type *);
#if !IN_LIBGCOV
static int gcov_read_string (char **);
#endif
static int gcov_read_summary (struct gcov_summary *);
static unsigned long gcov_save_position (void);
static int gcov_resync (unsigned long /*base*/, unsigned /*length */);
static unsigned gcov_read_unsigned (void);
static gcov_type gcov_read_counter (void);
static const char *gcov_read_string (void);
static void gcov_read_summary (struct gcov_summary *);
static unsigned long gcov_position (void);
static void gcov_seek (unsigned long /*base*/, unsigned /*length */);
static unsigned long gcov_seek_end (void);
static int gcov_skip (unsigned /*length*/);
static int gcov_skip_string (unsigned /*length*/);
static int gcov_ok (void);
static int gcov_error (void);
static int gcov_eof (void);
static int gcov_is_eof (void);
static int gcov_is_error (void);
#if IN_GCOV > 0
static time_t gcov_time (void);
#endif
@ -353,62 +352,63 @@ gcov_open (const char *name, int mode)
s_flock.l_pid = getpid ();
#endif
if (gcov_file)
if (gcov_var.file)
abort ();
gcov_position = gcov_length = 0;
gcov_errored = gcov_modified = 0;
gcov_var.position = gcov_var.length = 0;
gcov_var.error = gcov_var.modified = 0;
if (mode >= 0)
gcov_file = fopen (name, "r+b");
if (!gcov_file && mode <= 0)
gcov_var.file = fopen (name, "r+b");
if (!gcov_var.file && mode <= 0)
{
result = -1;
gcov_file = fopen (name, "w+b");
gcov_var.file = fopen (name, "w+b");
}
if (!gcov_file)
if (!gcov_var.file)
return 0;
#if defined (TARGET_HAS_F_SETLKW) && IN_LIBGCOV
while (fcntl (fileno (gcov_file), F_SETLKW, &s_flock)
while (fcntl (fileno (gcov_var.file), F_SETLKW, &s_flock)
&& errno == EINTR)
continue;
#endif
if (result >= 0)
{
if (fseek (gcov_file, 0, SEEK_END))
if (fseek (gcov_var.file, 0, SEEK_END))
{
fclose (gcov_file);
gcov_file = 0;
fclose (gcov_var.file);
gcov_var.file = 0;
return 0;
}
gcov_length = ftell (gcov_file);
fseek (gcov_file, 0, SEEK_SET);
alloc += gcov_length;
gcov_var.length = ftell (gcov_var.file);
fseek (gcov_var.file, 0, SEEK_SET);
alloc += gcov_var.length;
}
if (alloc > gcov_alloc)
if (alloc > gcov_var.alloc)
{
if (gcov_buffer)
free (gcov_buffer);
gcov_alloc = alloc;
if (gcov_var.buffer)
free (gcov_var.buffer);
gcov_var.alloc = alloc;
#if IN_LIBGCOV
gcov_buffer = malloc (gcov_alloc);
if (!gcov_buffer)
gcov_var.buffer = malloc (gcov_var.alloc);
if (!gcov_var.buffer)
{
fclose (gcov_file);
gcov_file = 0;
gcov_length = 0;
gcov_alloc = 0;
fclose (gcov_var.file);
gcov_var.file = 0;
gcov_var.length = 0;
gcov_var.alloc = 0;
return 0;
}
#else
gcov_buffer = xmalloc (gcov_alloc);
gcov_var.buffer = xmalloc (gcov_var.alloc);
#endif
}
if (result >= 0 && fread (gcov_buffer, gcov_length, 1, gcov_file) != 1)
if (result >= 0
&& fread (gcov_var.buffer, gcov_var.length, 1, gcov_var.file) != 1)
{
fclose (gcov_file);
gcov_file = 0;
gcov_length = 0;
fclose (gcov_var.file);
gcov_var.file = 0;
gcov_var.length = 0;
return 0;
}
return result;
@ -422,17 +422,23 @@ gcov_close ()
{
int result = 0;
if (gcov_file)
if (gcov_var.file)
{
if (gcov_modified
&& (fseek (gcov_file, 0, SEEK_SET)
|| fwrite (gcov_buffer, gcov_length, 1, gcov_file) != 1))
result = -1;
fclose (gcov_file);
gcov_file = 0;
gcov_length = 0;
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;
}
return result || gcov_errored;
#if !IN_LIBGCOV
free (gcov_var.buffer);
gcov_var.alloc = 0;
gcov_var.buffer = 0;
#endif
return result ? 1 : gcov_var.error;
}
#if !IN_GCOV
@ -444,167 +450,177 @@ gcov_write_bytes (unsigned bytes)
{
char unsigned *result;
if (gcov_position + bytes > gcov_alloc)
if (gcov_var.position + bytes > gcov_var.alloc)
{
size_t new_size = (gcov_alloc + bytes) * 3 / 2;
size_t new_size = (gcov_var.alloc + bytes) * 3 / 2;
if (!gcov_buffer)
if (!gcov_var.buffer)
return 0;
#if IN_LIBGCOV
result = realloc (gcov_buffer, new_size);
result = realloc (gcov_var.buffer, new_size);
if (!result)
{
free (gcov_buffer);
gcov_buffer = 0;
gcov_alloc = 0;
gcov_position = gcov_length = 0;
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_buffer, new_size);
result = xrealloc (gcov_var.buffer, new_size);
#endif
gcov_alloc = new_size;
gcov_buffer = result;
gcov_var.alloc = new_size;
gcov_var.buffer = result;
}
result = &gcov_buffer[gcov_position];
gcov_position += bytes;
gcov_modified = 1;
if (gcov_position > gcov_length)
gcov_length = gcov_position;
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;
}
/* Write VALUE to coverage file. Return nonzero if failed due to
file i/o error, or value error. */
/* Write unsigned VALUE to coverage file. Sets error flag
appropriately. */
static int
static void
gcov_write_unsigned (unsigned value)
{
unsigned char *buffer = gcov_write_bytes (4);
unsigned ix;
if (!buffer)
return 1;
return;
for (ix = 4; ix--; )
{
buffer[ix] = value;
value >>= 8;
}
return sizeof (value) > 4 && value;
if (sizeof (value) > 4 && value)
gcov_var.error = -1;
return;
}
/* Write VALUE to coverage file. Return nonzero if failed due to
file i/o error, or value error. Negative values are not checked
here -- they are checked in gcov_read_counter. */
/* Write counter VALUE to coverage file. Sets error flag
appropriately. */
#if IN_LIBGCOV
static int
static void
gcov_write_counter (gcov_type value)
{
unsigned char *buffer = gcov_write_bytes (8);
unsigned ix;
if (!buffer)
return 1;
return;
for (ix = 8; ix--; )
{
buffer[ix] = value;
value >>= 8;
}
return sizeof (value) > 8 && value;
if ((sizeof (value) > 8 && value) || value < 0)
gcov_var.error = -1;
return;
}
#endif /* IN_LIBGCOV */
/* Write VALUE to coverage file. Return nonzero if failed due to
file i/o error, or value error. */
/* Write STRING to coverage file. Sets error flag on file
error, overflow flag on overflow */
static int
static void
gcov_write_string (const char *string)
{
unsigned length = 0;
unsigned pad = 0;
unsigned rem = 0;
unsigned char *buffer;
if (string)
{
unsigned length = strlen (string);
unsigned pad = 0;
unsigned rem = 4 - (length & 3);
unsigned char *buffer;
if (gcov_write_unsigned (length))
return 1;
buffer = gcov_write_bytes (length + rem);
if (!buffer)
return 1;
memcpy (buffer, string, length);
memcpy (buffer + length, &pad, rem);
return 0;
length = strlen (string);
rem = 4 - (length & 3);
}
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);
}
else
return gcov_write_unsigned (0);
}
/* Allocate space to write a record tag length. Return a value to be
used for gcov_write_length. */
/* Write a tag TAG and reserve space for the record length. Return a
value to be used for gcov_write_length. */
static unsigned long
gcov_reserve_length (void)
gcov_write_tag (unsigned tag)
{
unsigned long result = gcov_position;
unsigned char *buffer = gcov_write_bytes (4);
unsigned long result = gcov_var.position;
unsigned char *buffer = gcov_write_bytes (8);
unsigned ix;
if (!buffer)
return 0;
memset (buffer, 0, 4);
for (ix = 4; ix--; )
{
buffer[ix] = tag;
tag >>= 8;
}
memset (buffer + 4, 0, 4);
return result;
}
/* Write a record length at PLACE. The current file position is the
end of the record, and is restored before returning. Returns
nonzero on failure. */
/* Write a record length using POSITION, which was returned by
gcov_write_tag. The current file position is the end of the
record, and is restored before returning. Returns nonzero on
overflow. */
static int
static void
gcov_write_length (unsigned long position)
{
unsigned length = gcov_position - position - 4;
unsigned char *buffer = &gcov_buffer[position];
unsigned ix;
if (!position)
return 1;
for (ix = 4; ix--; )
if (position)
{
buffer[ix] = length;
length >>= 8;
unsigned 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;
}
}
return 0;
}
#if IN_LIBGCOV
/* Write a summary structure to the gcov file. */
/* Write a summary structure to the gcov file. Return non-zero on
overflow. */
static int
static void
gcov_write_summary (unsigned tag, const struct gcov_summary *summary)
{
volatile unsigned long base; /* volatile is necessary to work around
a compiler bug. */
unsigned long base;
if (gcov_write_unsigned (tag))
return 1;
base = gcov_reserve_length ();
if (gcov_write_unsigned (summary->checksum))
return 1;
if (gcov_write_unsigned (summary->runs)
|| gcov_write_unsigned (summary->arcs))
return 1;
if (gcov_write_counter (summary->arc_sum)
|| gcov_write_counter (summary->arc_max_one)
|| gcov_write_counter (summary->arc_max_sum)
|| gcov_write_counter (summary->arc_sum_max))
return 1;
if (gcov_write_length (base))
return 1;
return 0;
base = gcov_write_tag (tag);
gcov_write_unsigned (summary->checksum);
gcov_write_unsigned (summary->runs);
gcov_write_unsigned (summary->arcs);
gcov_write_counter (summary->arc_sum);
gcov_write_counter (summary->arc_max_one);
gcov_write_counter (summary->arc_max_sum);
gcov_write_counter (summary->arc_sum_max);
gcov_write_length (base);
}
#endif /* IN_LIBGCOV */
@ -618,127 +634,118 @@ gcov_read_bytes (unsigned bytes)
{
const unsigned char *result;
if (gcov_position + bytes > gcov_length)
return 0;
result = &gcov_buffer[gcov_position];
gcov_position += bytes;
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;
}
/* Read *VALUE_P from coverage file. Return nonzero if failed
due to file i/o error, or range error. */
/* Read unsigned value from a coverage file. Sets error flag on file
error, overflow flag on overflow */
static int
gcov_read_unsigned (unsigned *value_p)
static unsigned
gcov_read_unsigned ()
{
unsigned value = 0;
unsigned ix;
const unsigned char *buffer = gcov_read_bytes (4);
if (!buffer)
return 1;
return 0;
for (ix = sizeof (value); ix < 4; ix++)
if (buffer[ix])
return 1;
gcov_var.error = -1;
for (ix = 0; ix != 4; ix++)
{
value <<= 8;
value |= buffer[ix];
}
*value_p = value;
return 0;
return value;
}
/* Read *VALUE_P from coverage file. Return nonzero if failed
due to file i/o error, or range error. */
/* Read counter value from a coverage file. Sets error flag on file
error, overflow flag on overflow */
static int
gcov_read_counter (gcov_type *value_p)
static gcov_type
gcov_read_counter ()
{
gcov_type value = 0;
unsigned ix;
const unsigned char *buffer = gcov_read_bytes (8);
if (!buffer)
return 1;
return 0;
for (ix = sizeof (value); ix < 8; ix++)
if (buffer[ix])
return 1;
gcov_var.error = -1;
for (ix = 0; ix != 8; ix++)
{
value <<= 8;
value |= buffer[ix];
}
*value_p = value;
return value < 0;
if (value < 0)
gcov_var.error = -1;
return value;
}
#if !IN_LIBGCOV
/* Read string from coverage file. Returns a pointer to a static
buffer, or NULL on empty string. You must copy the string before
calling another gcov function. */
/* Read string from coverage file. A buffer is allocated and returned
in *STRING_P. Return nonzero if failed due to file i/o error, or
range error. Uses xmalloc to allocate the string buffer. */
static int
gcov_read_string (char **string_p)
static const char *
gcov_read_string ()
{
unsigned length;
const unsigned char *buffer;
if (gcov_read_unsigned (&length))
return 1;
free (*string_p);
*string_p = NULL;
unsigned length = gcov_read_unsigned ();
if (!length)
return 0;
length += 4 - (length & 3);
buffer = gcov_read_bytes (length);
if (!buffer)
return 1;
*string_p = xmalloc (length);
if (!*string_p)
return 1;
memcpy (*string_p, buffer, length);
return 0;
return (const char *) gcov_read_bytes (length);
}
#endif /* !IN_LIBGCOV */
#define GCOV_SUMMARY_LENGTH 44
static int
static void
gcov_read_summary (struct gcov_summary *summary)
{
return (gcov_read_unsigned (&summary->checksum)
|| gcov_read_unsigned (&summary->runs)
|| gcov_read_unsigned (&summary->arcs)
|| gcov_read_counter (&summary->arc_sum)
|| gcov_read_counter (&summary->arc_max_one)
|| gcov_read_counter (&summary->arc_max_sum)
|| gcov_read_counter (&summary->arc_sum_max));
summary->checksum = gcov_read_unsigned ();
summary->runs = gcov_read_unsigned ();
summary->arcs = gcov_read_unsigned ();
summary->arc_sum = gcov_read_counter ();
summary->arc_max_one = gcov_read_counter ();
summary->arc_max_sum = gcov_read_counter ();
summary->arc_sum_max = gcov_read_counter ();
}
/* Save the current position in the gcov file. */
static inline unsigned long
gcov_save_position (void)
gcov_position (void)
{
return gcov_position;
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 int
gcov_resync (unsigned long base, unsigned length)
static inline void
gcov_seek (unsigned long base, unsigned length)
{
if (gcov_buffer)
gcov_position = base + length;
return 0;
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. */
@ -746,53 +753,24 @@ gcov_resync (unsigned long base, unsigned length)
static inline unsigned long
gcov_seek_end ()
{
gcov_position = gcov_length;
return gcov_position;
}
/* Skip LENGTH bytes in the file. */
static inline int
gcov_skip (unsigned length)
{
if (gcov_length < gcov_position + length)
return 1;
gcov_position += length;
return 0;
}
/* Skip a string of LENGTH bytes. */
static inline int
gcov_skip_string (unsigned length)
{
return gcov_skip (length + 4 - (length & 3));
gcov_var.position = gcov_var.length;
return gcov_var.position;
}
/* Tests whether we have reached end of .da file. */
static inline int
gcov_eof ()
gcov_is_eof ()
{
return gcov_position == gcov_length;
return gcov_var.position == gcov_var.length;
}
/* Return non-zero if the error flag is set. */
static inline int
gcov_ok ()
gcov_is_error ()
{
return gcov_file != 0 && !gcov_errored;
}
/* Set the error flag. */
static inline int
gcov_error ()
{
int error = gcov_errored;
gcov_errored = 1;
return error;
return gcov_var.file ? gcov_var.error : 1;
}
#if IN_GCOV > 0
@ -803,7 +781,7 @@ gcov_time ()
{
struct stat status;
if (fstat (fileno (gcov_file), &status))
if (fstat (fileno (gcov_var.file), &status))
return 0;
else
return status.st_mtime;

View File

@ -321,7 +321,7 @@ static void print_usage PARAMS ((int)) ATTRIBUTE_NORETURN;
static void print_version PARAMS ((void)) ATTRIBUTE_NORETURN;
static void process_file PARAMS ((const char *));
static void create_file_names PARAMS ((const char *));
static source_t *find_source PARAMS ((char *));
static source_t *find_source PARAMS ((const char *));
static int read_graph_file PARAMS ((void));
static int read_count_file PARAMS ((void));
static void solve_flow_graph PARAMS ((function_t *));
@ -673,31 +673,29 @@ create_file_names (file_name)
return;
}
/* Find or create a source file structure for FILE_NAME. Free
FILE_NAME appropriately */
/* Find or create a source file structure for FILE_NAME. Copies
FILE_NAME on creation */
static source_t *
find_source (file_name)
char *file_name;
const char *file_name;
{
source_t *src;
if (!file_name)
file_name = "<unknown>";
for (src = sources; src; src = src->next)
if (!strcmp (file_name, src->name))
{
free (file_name);
break;
}
if (!src)
{
src = (source_t *)xcalloc (1, sizeof (source_t));
src->name = file_name;
src->coverage.name = file_name;
src->index = sources ? sources->index + 1 : 1;
src->next = sources;
sources = src;
}
return src;
src = (source_t *)xcalloc (1, sizeof (source_t));
src->name = xstrdup (file_name);
src->coverage.name = src->name;
src->index = sources ? sources->index + 1 : 1;
src->next = sources;
sources = src;
return src;
}
@ -706,9 +704,8 @@ find_source (file_name)
static int
read_graph_file ()
{
unsigned magic, version;
unsigned version;
unsigned current_tag = 0;
unsigned tag;
struct function_info *fn = NULL;
source_t *src = NULL;
unsigned ix;
@ -719,52 +716,46 @@ read_graph_file ()
return 1;
}
bbg_file_time = gcov_time ();
if (gcov_read_unsigned (&magic) || magic != GCOV_GRAPH_MAGIC)
if (gcov_read_unsigned () != GCOV_GRAPH_MAGIC)
{
fnotice (stderr, "%s:not a gcov graph file\n", bbg_file_name);
gcov_close ();
return 1;
}
if (gcov_read_unsigned (&version) || version != GCOV_VERSION)
version = gcov_read_unsigned ();
if (version != GCOV_VERSION)
{
char v[4], e[4];
magic = GCOV_VERSION;
unsigned required = GCOV_VERSION;
for (ix = 4; ix--; magic >>= 8, version >>= 8)
for (ix = 4; ix--; required >>= 8, version >>= 8)
{
v[ix] = version;
e[ix] = magic;
e[ix] = required;
}
fnotice (stderr, "%s:version `%.4s', prefer `%.4s'\n",
bbg_file_name, v, e);
}
while (!gcov_read_unsigned (&tag))
while (!gcov_is_eof ())
{
unsigned length;
long base;
if (gcov_read_unsigned (&length))
goto corrupt;
base = gcov_save_position ();
unsigned tag = gcov_read_unsigned ();
unsigned length = gcov_read_unsigned ();
unsigned long base = gcov_position ();
if (tag == GCOV_TAG_FUNCTION)
{
char *function_name = NULL;
char *function_file = NULL;
char *function_name;
unsigned checksum, lineno;
source_t *src;
function_t *probe, *prev;
if (gcov_read_string (&function_name)
|| gcov_read_unsigned (&checksum)
|| gcov_read_string (&function_file)
|| gcov_read_unsigned (&lineno))
goto corrupt;
src = find_source (function_file);
function_name = xstrdup (gcov_read_string ());
checksum = gcov_read_unsigned ();
src = find_source (gcov_read_string ());
lineno = gcov_read_unsigned ();
fn = (function_t *)xcalloc (1, sizeof (function_t));
fn->name = function_name;
fn->checksum = checksum;
@ -803,33 +794,24 @@ read_graph_file ()
fn->blocks
= (block_t *)xcalloc (fn->num_blocks, sizeof (block_t));
for (ix = 0; ix != num_blocks; ix++)
{
unsigned flags;
if (gcov_read_unsigned (&flags))
goto corrupt;
fn->blocks[ix].flags = flags;
}
fn->blocks[ix].flags = gcov_read_unsigned ();
}
}
else if (fn && tag == GCOV_TAG_ARCS)
{
unsigned src;
unsigned src = gcov_read_unsigned ();
unsigned num_dests = (length - 4) / 8;
unsigned dest, flags;
if (gcov_read_unsigned (&src)
|| src >= fn->num_blocks
|| fn->blocks[src].succ)
if (src >= fn->num_blocks || fn->blocks[src].succ)
goto corrupt;
while (num_dests--)
{
struct arc_info *arc;
unsigned dest = gcov_read_unsigned ();
unsigned flags = gcov_read_unsigned ();
if (gcov_read_unsigned (&dest)
|| gcov_read_unsigned (&flags)
|| dest >= fn->num_blocks)
if (dest >= fn->num_blocks)
goto corrupt;
arc = (arc_t *) xcalloc (1, sizeof (arc_t));
@ -875,21 +857,17 @@ read_graph_file ()
}
else if (fn && tag == GCOV_TAG_LINES)
{
unsigned blockno;
unsigned blockno = gcov_read_unsigned ();
unsigned *line_nos
= (unsigned *)xcalloc ((length - 4) / 4, sizeof (unsigned));
if (gcov_read_unsigned (&blockno)
|| blockno >= fn->num_blocks
|| fn->blocks[blockno].u.line.encoding)
if (blockno >= fn->num_blocks || fn->blocks[blockno].u.line.encoding)
goto corrupt;
for (ix = 0; ; )
{
unsigned lineno;
unsigned lineno = gcov_read_unsigned ();
if (gcov_read_unsigned (&lineno))
goto corrupt;
if (lineno)
{
if (!ix)
@ -903,10 +881,8 @@ read_graph_file ()
}
else
{
char *file_name = NULL;
const char *file_name = gcov_read_string ();
if (gcov_read_string (&file_name))
goto corrupt;
if (!file_name)
break;
src = find_source (file_name);
@ -924,7 +900,8 @@ read_graph_file ()
fn = NULL;
current_tag = 0;
}
if (gcov_resync (base, length))
gcov_seek (base, length);
if (gcov_is_error ())
{
corrupt:;
fnotice (stderr, "%s:corrupted\n", bbg_file_name);
@ -994,8 +971,7 @@ static int
read_count_file ()
{
unsigned ix;
char *function_name_buffer = NULL;
unsigned magic, version;
unsigned version;
function_t *fn = NULL;
if (!gcov_open (da_file_name, 1))
@ -1003,63 +979,44 @@ read_count_file ()
fnotice (stderr, "%s:cannot open data file\n", da_file_name);
return 1;
}
if (gcov_read_unsigned (&magic) || magic != GCOV_DATA_MAGIC)
if (gcov_read_unsigned () != GCOV_DATA_MAGIC)
{
fnotice (stderr, "%s:not a gcov data file\n", da_file_name);
cleanup:;
free (function_name_buffer);
gcov_close ();
return 1;
}
if (gcov_read_unsigned (&version) || version != GCOV_VERSION)
version = gcov_read_unsigned ();
if (version != GCOV_VERSION)
{
char v[4], e[4];
unsigned desired = GCOV_VERSION;
magic = GCOV_VERSION;
for (ix = 4; ix--; magic >>= 8, version >>= 8)
for (ix = 4; ix--; desired >>= 8, version >>= 8)
{
v[ix] = version;
e[ix] = magic;
e[ix] = desired;
}
fnotice (stderr, "%s:version `%.4s', prefer version `%.4s'\n",
da_file_name, v, e);
}
while (1)
while (!gcov_is_eof ())
{
unsigned tag, length;
long base;
if (gcov_read_unsigned (&tag)
|| gcov_read_unsigned (&length))
{
if (gcov_eof ())
break;
corrupt:;
fnotice (stderr, "%s:corrupted\n", da_file_name);
goto cleanup;
}
base = gcov_save_position ();
unsigned tag = gcov_read_unsigned ();
unsigned length = gcov_read_unsigned ();
unsigned long base = gcov_position ();
int error;
if (tag == GCOV_TAG_OBJECT_SUMMARY)
{
if (gcov_read_summary (&object_summary))
goto corrupt;
}
gcov_read_summary (&object_summary);
else if (tag == GCOV_TAG_PROGRAM_SUMMARY
|| tag == GCOV_TAG_INCORRECT_SUMMARY)
{
program_count++;
gcov_resync (base, length);
}
program_count++;
else if (tag == GCOV_TAG_FUNCTION)
{
unsigned checksum;
const char *function_name = gcov_read_string ();
struct function_info *fn_n = functions;
if (gcov_read_string (&function_name_buffer)
|| gcov_read_unsigned (&checksum))
goto corrupt;
for (fn = fn ? fn->next : NULL; ; fn = fn->next)
{
@ -1070,20 +1027,20 @@ read_count_file ()
else
{
fnotice (stderr, "%s:unknown function `%s'\n",
da_file_name, function_name_buffer);
da_file_name, function_name);
break;
}
if (!strcmp (fn->name, function_name_buffer))
if (!strcmp (fn->name, function_name))
break;
}
if (!fn)
;
else if (checksum != fn->checksum)
else if (gcov_read_unsigned () != fn->checksum)
{
mismatch:;
fnotice (stderr, "%s:profile mismatch for `%s'\n",
da_file_name, function_name_buffer);
da_file_name, fn->name);
goto cleanup;
}
}
@ -1097,20 +1054,18 @@ read_count_file ()
= (gcov_type *)xcalloc (fn->num_counts, sizeof (gcov_type));
for (ix = 0; ix != fn->num_counts; ix++)
{
gcov_type count;
if (gcov_read_counter (&count))
goto corrupt;
fn->counts[ix] += count;
}
fn->counts[ix] += gcov_read_counter ();
}
gcov_seek (base, length);
if ((error = gcov_is_error ()))
{
fnotice (stderr, error < 0
? "%s:overflowed\n" : "%s:corrupted\n", da_file_name);
goto cleanup;
}
else
gcov_resync (base, length);
}
gcov_close ();
free (function_name_buffer);
return 0;
}

View File

@ -110,14 +110,14 @@ gcov_exit (void)
{
struct gcov_summary object;
struct gcov_summary local_prg;
int error;
int merging;
long base;
unsigned long base;
const struct function_info *fn_info;
gcov_type **counters;
gcov_type *count_ptr;
gcov_type object_max_one = 0;
gcov_type count;
unsigned tag, length, flength, checksum;
unsigned tag, length;
unsigned arc_data_index, f_sect_index, sect_index;
ptr->wkspc = 0;
@ -167,7 +167,7 @@ gcov_exit (void)
if (merging > 0)
{
/* Merge data from file. */
if (gcov_read_unsigned (&tag) || tag != GCOV_DATA_MAGIC)
if (gcov_read_unsigned () != GCOV_DATA_MAGIC)
{
fprintf (stderr, "profiling:%s:Not a gcov data file\n",
ptr->filename);
@ -176,7 +176,8 @@ gcov_exit (void)
ptr->filename = 0;
continue;
}
if (gcov_read_unsigned (&length) || length != GCOV_VERSION)
length = gcov_read_unsigned ();
if (length != GCOV_VERSION)
{
gcov_version_mismatch (ptr, length);
goto read_fatal;
@ -186,13 +187,8 @@ gcov_exit (void)
for (ix = ptr->n_functions, fn_info = ptr->functions;
ix--; fn_info++)
{
if (gcov_read_unsigned (&tag) || gcov_read_unsigned (&length))
{
read_error:;
fprintf (stderr, "profiling:%s:Error merging\n",
ptr->filename);
goto read_fatal;
}
tag = gcov_read_unsigned ();
length = gcov_read_unsigned ();
/* Check function */
if (tag != GCOV_TAG_FUNCTION)
@ -203,12 +199,8 @@ gcov_exit (void)
goto read_fatal;
}
if (gcov_read_unsigned (&flength)
|| gcov_skip_string (flength)
|| gcov_read_unsigned (&checksum))
goto read_error;
if (flength != strlen (fn_info->name)
|| checksum != fn_info->checksum)
if (strcmp (gcov_read_string (), fn_info->name)
|| gcov_read_unsigned () != fn_info->checksum)
goto read_mismatch;
/* Counters. */
@ -218,9 +210,9 @@ gcov_exit (void)
{
unsigned n_counters;
if (gcov_read_unsigned (&tag)
|| gcov_read_unsigned (&length))
goto read_error;
tag = gcov_read_unsigned ();
length = gcov_read_unsigned ();
for (sect_index = 0;
sect_index < ptr->n_counter_sections;
sect_index++)
@ -235,40 +227,42 @@ gcov_exit (void)
goto read_mismatch;
for (jx = 0; jx < n_counters; jx++)
if (gcov_read_counter (&count))
goto read_error;
else
counters[sect_index][jx] += count;
counters[sect_index][jx] += gcov_read_counter ();
counters[sect_index] += n_counters;
}
if ((error = gcov_is_error ()))
goto read_error;
}
/* Check object summary */
if (gcov_read_unsigned (&tag) || gcov_read_unsigned (&length))
goto read_error;
if (tag != GCOV_TAG_OBJECT_SUMMARY)
if (gcov_read_unsigned () != GCOV_TAG_OBJECT_SUMMARY)
goto read_mismatch;
if (gcov_read_summary (&object))
goto read_error;
gcov_read_unsigned ();
gcov_read_summary (&object);
/* Check program summary */
while (1)
while (!gcov_is_eof ())
{
long base = gcov_save_position ();
unsigned long base = gcov_position ();
if (gcov_read_unsigned (&tag)
|| gcov_read_unsigned (&length))
{
if (gcov_eof ())
break;
goto read_error;
}
tag = gcov_read_unsigned ();
gcov_read_unsigned ();
if (tag != GCOV_TAG_PROGRAM_SUMMARY
&& tag != GCOV_TAG_PLACEHOLDER_SUMMARY
&& tag != GCOV_TAG_INCORRECT_SUMMARY)
goto read_mismatch;
if (gcov_read_summary (&local_prg))
goto read_error;
gcov_read_summary (&local_prg);
if ((error = gcov_is_error ()))
{
read_error:;
fprintf (stderr, error < 0 ?
"profiling:%s:Overflow merging\n" :
"profiling:%s:Error merging\n",
ptr->filename);
goto read_fatal;
}
if (local_prg.checksum != program.checksum)
continue;
if (tag == GCOV_TAG_PLACEHOLDER_SUMMARY)
@ -294,7 +288,7 @@ gcov_exit (void)
ptr->wkspc = base;
break;
}
gcov_resync (0, 0);
gcov_seek (0, 0);
}
object.runs++;
@ -305,17 +299,8 @@ gcov_exit (void)
object.arc_sum_max += object_max_one;
/* Write out the data. */
if (/* magic */
gcov_write_unsigned (GCOV_DATA_MAGIC)
/* version number */
|| gcov_write_unsigned (GCOV_VERSION))
{
write_error:;
gcov_close ();
fprintf (stderr, "profiling:%s:Error writing\n", ptr->filename);
ptr->filename = 0;
continue;
}
gcov_write_unsigned (GCOV_DATA_MAGIC);
gcov_write_unsigned (GCOV_VERSION);
/* Write execution counts for each function. */
for (ix = 0; ix < ptr->n_counter_sections; ix++)
@ -323,14 +308,10 @@ gcov_exit (void)
for (ix = ptr->n_functions, fn_info = ptr->functions; ix--; fn_info++)
{
/* Announce function. */
if (gcov_write_unsigned (GCOV_TAG_FUNCTION)
|| !(base = gcov_reserve_length ())
/* function name */
|| gcov_write_string (fn_info->name)
/* function checksum */
|| gcov_write_unsigned (fn_info->checksum)
|| gcov_write_length (base))
goto write_error;
base = gcov_write_tag (GCOV_TAG_FUNCTION);
gcov_write_string (fn_info->name);
gcov_write_unsigned (fn_info->checksum);
gcov_write_length (base);
/* counters. */
for (f_sect_index = 0;
@ -346,10 +327,7 @@ gcov_exit (void)
if (sect_index == ptr->n_counter_sections)
abort ();
if (gcov_write_unsigned (tag)
|| !(base = gcov_reserve_length ()))
goto write_error;
base = gcov_write_tag (tag);
for (jx = fn_info->counter_sections[f_sect_index].n_counters; jx--;)
{
gcov_type count = *counters[sect_index]++;
@ -360,41 +338,33 @@ gcov_exit (void)
if (object.arc_max_sum < count)
object.arc_max_sum = count;
}
if (gcov_write_counter (count))
goto write_error; /* RIP Edsger Dijkstra */
gcov_write_counter (count);
}
if (gcov_write_length (base))
goto write_error;
gcov_write_length (base);
}
}
/* Object file summary. */
if (gcov_write_summary (GCOV_TAG_OBJECT_SUMMARY, &object))
goto write_error;
gcov_write_summary (GCOV_TAG_OBJECT_SUMMARY, &object);
if (merging)
{
ptr->wkspc = gcov_seek_end ();
if (gcov_write_summary (GCOV_TAG_PLACEHOLDER_SUMMARY,
&program))
goto write_error;
gcov_write_summary (GCOV_TAG_PLACEHOLDER_SUMMARY, &program);
}
else if (ptr->wkspc)
{
/* Zap trailing program summary */
if (gcov_resync (ptr->wkspc, 0))
goto write_error;
gcov_seek (ptr->wkspc, 0);
if (!local_prg.runs)
ptr->wkspc = 0;
if (gcov_write_unsigned (local_prg.runs
? GCOV_TAG_PLACEHOLDER_SUMMARY
: GCOV_TAG_INCORRECT_SUMMARY))
goto write_error;
gcov_write_unsigned (local_prg.runs
? GCOV_TAG_PLACEHOLDER_SUMMARY
: GCOV_TAG_INCORRECT_SUMMARY);
}
if (gcov_close ())
{
fprintf (stderr, "profiling:%s:Error closing\n", ptr->filename);
fprintf (stderr, "profiling:%s:Error writing\n", ptr->filename);
ptr->filename = 0;
}
else
@ -427,11 +397,10 @@ gcov_exit (void)
continue;
}
if (gcov_resync (ptr->wkspc, 0)
|| gcov_write_summary (GCOV_TAG_PROGRAM_SUMMARY, &program))
fprintf (stderr, "profiling:%s:Error writing\n", ptr->filename);
gcov_seek (ptr->wkspc, 0);
gcov_write_summary (GCOV_TAG_PROGRAM_SUMMARY, &program);
if (gcov_close ())
fprintf (stderr, "profiling:%s:Error closing\n", ptr->filename);
fprintf (stderr, "profiling:%s:Error writing\n", ptr->filename);
}
}

View File

@ -274,7 +274,7 @@ static void
read_counts_file (const char *name)
{
char *function_name_buffer = NULL;
unsigned magic, version, ix, checksum;
unsigned version, ix, checksum;
counts_entry_t *summaried = NULL;
unsigned seen_summary = 0;
@ -284,21 +284,21 @@ read_counts_file (const char *name)
return;
}
if (gcov_read_unsigned (&magic) || magic != GCOV_DATA_MAGIC)
if (gcov_read_unsigned () != GCOV_DATA_MAGIC)
{
warning ("`%s' is not a gcov data file", name);
gcov_close ();
return;
}
else if (gcov_read_unsigned (&version) || version != GCOV_VERSION)
else if ((version = gcov_read_unsigned ()) != GCOV_VERSION)
{
char v[4], e[4];
magic = GCOV_VERSION;
unsigned required = GCOV_VERSION;
for (ix = 4; ix--; magic >>= 8, version >>= 8)
for (ix = 4; ix--; required >>= 8, version >>= 8)
{
v[ix] = version;
e[ix] = magic;
e[ix] = required;
}
warning ("`%s' is version `%.4s', expected version `%.4s'", name, v, e);
gcov_close ();
@ -308,27 +308,21 @@ read_counts_file (const char *name)
counts_hash = htab_create (10,
htab_counts_entry_hash, htab_counts_entry_eq,
htab_counts_entry_del);
while (1)
while (!gcov_is_eof ())
{
unsigned tag, length;
long offset;
unsigned long offset;
int error;
offset = gcov_save_position ();
if (gcov_read_unsigned (&tag) || gcov_read_unsigned (&length))
{
if (gcov_eof ())
break;
corrupt:;
warning ("`%s' is corrupted", name);
cleanup:
htab_delete (counts_hash);
break;
}
tag = gcov_read_unsigned ();
length = gcov_read_unsigned ();
offset = gcov_position ();
if (tag == GCOV_TAG_FUNCTION)
{
if (gcov_read_string (&function_name_buffer)
|| gcov_read_unsigned (&checksum))
goto corrupt;
const char *string = gcov_read_string ();
free (function_name_buffer);
function_name_buffer = string ? xstrdup (string) : NULL;
checksum = gcov_read_unsigned ();
if (seen_summary)
{
/* We have already seen a summary, this means that this
@ -352,10 +346,7 @@ read_counts_file (const char *name)
counts_entry_t *entry;
struct gcov_summary summary;
if (length != GCOV_SUMMARY_LENGTH
|| gcov_read_summary (&summary))
goto corrupt;
gcov_read_summary (&summary);
seen_summary = 1;
for (entry = summaried; entry; entry = entry->chain)
{
@ -370,7 +361,6 @@ read_counts_file (const char *name)
counts_entry_t **slot, *entry, elt;
unsigned n_counts = length / 8;
unsigned ix;
gcov_type count;
elt.function_name = function_name_buffer;
elt.section = tag;
@ -390,7 +380,8 @@ read_counts_file (const char *name)
else if (entry->checksum != checksum || entry->n_counts != n_counts)
{
warning ("profile mismatch for `%s'", function_name_buffer);
goto cleanup;
htab_delete (counts_hash);
break;
}
/* This should always be true for a just allocated entry,
@ -402,15 +393,16 @@ read_counts_file (const char *name)
summaried = entry;
}
for (ix = 0; ix != n_counts; ix++)
{
if (gcov_read_counter (&count))
goto corrupt;
entry->counts[ix] += count;
}
entry->counts[ix] += gcov_read_counter ();
}
gcov_seek (offset, length);
if ((error = gcov_is_error ()))
{
warning (error < 0 ? "`%s' has overflowed" : "`%s' is corrupted",
name);
htab_delete (counts_hash);
break;
}
else
if (gcov_skip (length))
goto corrupt;
}
free (function_name_buffer);
@ -1007,42 +999,34 @@ branch_prob ()
edge output the source and target basic block numbers.
NOTE: The format of this file must be compatible with gcov. */
if (gcov_ok ())
if (!gcov_is_error ())
{
long offset;
const char *file = DECL_SOURCE_FILE (current_function_decl);
unsigned line = DECL_SOURCE_LINE (current_function_decl);
/* Announce function */
if (gcov_write_unsigned (GCOV_TAG_FUNCTION)
|| !(offset = gcov_reserve_length ())
|| gcov_write_string (name)
|| gcov_write_unsigned (profile_info.current_function_cfg_checksum)
|| gcov_write_string (file)
|| gcov_write_unsigned (line)
|| gcov_write_length (offset))
goto bbg_error;
offset = gcov_write_tag (GCOV_TAG_FUNCTION);
gcov_write_string (name);
gcov_write_unsigned (profile_info.current_function_cfg_checksum);
gcov_write_string (file);
gcov_write_unsigned (line);
gcov_write_length (offset);
/* Basic block flags */
if (gcov_write_unsigned (GCOV_TAG_BLOCKS)
|| !(offset = gcov_reserve_length ()))
goto bbg_error;
offset = gcov_write_tag (GCOV_TAG_BLOCKS);
for (i = 0; i != (unsigned) (n_basic_blocks + 2); i++)
if (gcov_write_unsigned (0))
goto bbg_error;
if (gcov_write_length (offset))
goto bbg_error;
gcov_write_unsigned (0);
gcov_write_length (offset);
/* Arcs */
FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, next_bb)
{
edge e;
if (gcov_write_unsigned (GCOV_TAG_ARCS)
|| !(offset = gcov_reserve_length ())
|| gcov_write_unsigned (BB_TO_GCOV_INDEX (bb)))
goto bbg_error;
offset = gcov_write_tag (GCOV_TAG_ARCS);
gcov_write_unsigned (BB_TO_GCOV_INDEX (bb));
for (e = bb->succ; e; e = e->succ_next)
{
struct edge_info *i = EDGE_INFO (e);
@ -1057,14 +1041,12 @@ branch_prob ()
if (e->flags & EDGE_FALLTHRU)
flag_bits |= GCOV_ARC_FALLTHROUGH;
if (gcov_write_unsigned (BB_TO_GCOV_INDEX (e->dest))
|| gcov_write_unsigned (flag_bits))
goto bbg_error;
gcov_write_unsigned (BB_TO_GCOV_INDEX (e->dest));
gcov_write_unsigned (flag_bits);
}
}
if (gcov_write_length (offset))
goto bbg_error;
gcov_write_length (offset);
}
/* Output line number information about each basic block for
@ -1104,13 +1086,12 @@ branch_prob ()
ignore_next_note = 0;
else
{
if (offset)
/*NOP*/;
else if (gcov_write_unsigned (GCOV_TAG_LINES)
|| !(offset = gcov_reserve_length ())
|| (gcov_write_unsigned
(BB_TO_GCOV_INDEX (bb))))
goto bbg_error;
if (!offset)
{
offset = gcov_write_tag (GCOV_TAG_LINES);
gcov_write_unsigned (BB_TO_GCOV_INDEX (bb));
}
/* If this is a new source file, then output
the file's name to the .bb file. */
if (!prev_file_name
@ -1118,12 +1099,10 @@ branch_prob ()
prev_file_name))
{
prev_file_name = NOTE_SOURCE_FILE (insn);
if (gcov_write_unsigned (0)
|| gcov_write_string (prev_file_name))
goto bbg_error;
gcov_write_unsigned (0);
gcov_write_string (prev_file_name);
}
if (gcov_write_unsigned (NOTE_LINE_NUMBER (insn)))
goto bbg_error;
gcov_write_unsigned (NOTE_LINE_NUMBER (insn));
}
}
insn = NEXT_INSN (insn);
@ -1131,15 +1110,13 @@ branch_prob ()
if (offset)
{
if (gcov_write_unsigned (0)
|| gcov_write_string (NULL)
|| gcov_write_length (offset))
{
bbg_error:;
warning ("error writing `%s'", bbg_file_name);
gcov_error ();
}
/* A file of NULL indicates the end of run. */
gcov_write_unsigned (0);
gcov_write_string (NULL);
gcov_write_length (offset);
}
if (gcov_is_error ())
warning ("error writing `%s'", bbg_file_name);
}
}
}
@ -1328,13 +1305,9 @@ init_branch_prob (filename)
strcpy (bbg_file_name, filename);
strcat (bbg_file_name, GCOV_GRAPH_SUFFIX);
if (!gcov_open (bbg_file_name, -1))
{
error ("cannot open %s", bbg_file_name);
gcov_error ();
}
else if (gcov_write_unsigned (GCOV_GRAPH_MAGIC)
|| gcov_write_unsigned (GCOV_VERSION))
gcov_error ();
error ("cannot open %s", bbg_file_name);
gcov_write_unsigned (GCOV_GRAPH_MAGIC);
gcov_write_unsigned (GCOV_VERSION);
}
if (profile_arc_flag)