Commit 94de45d9 by Nathan Sidwell Committed by Nathan Sidwell

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
parent 7a615b25
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> 2003-04-11 Alexandre Oliva <aoliva@redhat.com>
* Makefile.in (fixinc.sh): Pass BUILD_LIBERTY as LIBERTY to * Makefile.in (fixinc.sh): Pass BUILD_LIBERTY as LIBERTY to
......
...@@ -1652,8 +1652,8 @@ cfgloopanal.o : cfgloopanal.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) \ ...@@ -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) $(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) \ 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) $(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 \ loop-init.o : loop-init.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) \
gcov-iov.h $(BASIC_BLOCK_H) hard-reg-set.h cfgloop.h cfglayout.h profile.h \ $(BASIC_BLOCK_H) hard-reg-set.h cfgloop.h cfglayout.h profile.h \
coretypes.h $(TM_H) coretypes.h $(TM_H)
loop-unswitch.o : loop-unswitch.c $(CONFIG_H) $(SYSTEM_H) $(RTL_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 \ $(BASIC_BLOCK_H) hard-reg-set.h cfgloop.h cfglayout.h params.h \
......
...@@ -30,19 +30,19 @@ static void dump_file PARAMS ((const char *)); ...@@ -30,19 +30,19 @@ static void dump_file PARAMS ((const char *));
static void print_prefix PARAMS ((const char *, unsigned)); static void print_prefix PARAMS ((const char *, unsigned));
static void print_usage PARAMS ((void)); static void print_usage PARAMS ((void));
static void print_version PARAMS ((void)); static void print_version PARAMS ((void));
static int tag_function PARAMS ((const char *, unsigned, unsigned)); static void tag_function PARAMS ((const char *, unsigned, unsigned));
static int tag_blocks PARAMS ((const char *, unsigned, unsigned)); static void tag_blocks PARAMS ((const char *, unsigned, unsigned));
static int tag_arcs PARAMS ((const char *, unsigned, unsigned)); static void tag_arcs PARAMS ((const char *, unsigned, unsigned));
static int tag_lines PARAMS ((const char *, unsigned, unsigned)); static void tag_lines PARAMS ((const char *, unsigned, unsigned));
static int tag_arc_counts PARAMS ((const char *, unsigned, unsigned)); static void tag_arc_counts PARAMS ((const char *, unsigned, unsigned));
static int tag_summary PARAMS ((const char *, unsigned, unsigned)); static void tag_summary PARAMS ((const char *, unsigned, unsigned));
extern int main PARAMS ((int, char **)); extern int main PARAMS ((int, char **));
typedef struct tag_format typedef struct tag_format
{ {
unsigned tag; unsigned tag;
char const *name; char const *name;
int (*proc) (const char *, unsigned, unsigned); void (*proc) (const char *, unsigned, unsigned);
} tag_format_t; } tag_format_t;
static int flag_dump_contents = 0; static int flag_dump_contents = 0;
...@@ -140,8 +140,6 @@ dump_file (filename) ...@@ -140,8 +140,6 @@ dump_file (filename)
{ {
unsigned tags[4]; unsigned tags[4];
unsigned depth = 0; unsigned depth = 0;
unsigned magic, version;
unsigned tag, length;
if (!gcov_open (filename, 1)) if (!gcov_open (filename, 1))
{ {
...@@ -149,16 +147,10 @@ dump_file (filename) ...@@ -149,16 +147,10 @@ dump_file (filename)
return; 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 */ /* magic */
{ {
unsigned magic = gcov_read_unsigned ();
unsigned version = gcov_read_unsigned ();
const char *type = NULL; const char *type = NULL;
char e[4], v[4], m[4]; char e[4], v[4], m[4];
unsigned expected = GCOV_VERSION; unsigned expected = GCOV_VERSION;
...@@ -187,13 +179,14 @@ dump_file (filename) ...@@ -187,13 +179,14 @@ dump_file (filename)
printf ("%s:warning:current version is `%.4s'\n", filename, e); 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; tag_format_t const *format;
unsigned tag_depth; unsigned tag_depth;
long base, end; int error;
base = gcov_save_position ();
if (!tag) if (!tag)
tag_depth = depth; tag_depth = depth;
...@@ -231,57 +224,53 @@ dump_file (filename) ...@@ -231,57 +224,53 @@ dump_file (filename)
print_prefix (filename, tag_depth); print_prefix (filename, tag_depth);
printf ("%08x:%4u:%s", tag, length, format->name); printf ("%08x:%4u:%s", tag, length, format->name);
if (format->proc) if (format->proc)
if ((*format->proc) (filename, tag, length)) (*format->proc) (filename, tag, length);
goto read_error;
printf ("\n"); printf ("\n");
end = gcov_save_position (); if (flag_dump_contents && format->proc)
gcov_resync (base, length);
if (format->proc && end != base + (long)length)
{ {
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", printf ("%s:record size mismatch %lu bytes overread\n",
filename, (end - base) - length); filename, actual_length - length);
else else if (length > actual_length)
printf ("%s:record size mismatch %lu bytes unread\n", 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 (); gcov_close ();
} }
static int static void
tag_function (filename, tag, length) tag_function (filename, tag, length)
const char *filename ATTRIBUTE_UNUSED; const char *filename ATTRIBUTE_UNUSED;
unsigned tag ATTRIBUTE_UNUSED; unsigned tag ATTRIBUTE_UNUSED;
unsigned length ATTRIBUTE_UNUSED; unsigned length ATTRIBUTE_UNUSED;
{ {
char *name = NULL; const char *name;
unsigned checksum; unsigned long pos = gcov_position ();
char *src = NULL;
unsigned lineno = 0;
unsigned long pos = gcov_save_position ();
if (gcov_read_string (&name) name = gcov_read_string ();
|| gcov_read_unsigned (&checksum)) printf (" `%s'", name ? name : "NULL");
return 1; 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 (gcov_position () - pos < length)
if (src) {
printf (" %s:%u", src, lineno); name = gcov_read_string ();
free (name); printf (" %s", name ? name : "NULL");
free (src); printf (":%u", gcov_read_unsigned ());
}
return 0;
} }
static int static void
tag_blocks (filename, tag, length) tag_blocks (filename, tag, length)
const char *filename ATTRIBUTE_UNUSED; const char *filename ATTRIBUTE_UNUSED;
unsigned tag ATTRIBUTE_UNUSED; unsigned tag ATTRIBUTE_UNUSED;
...@@ -297,22 +286,14 @@ tag_blocks (filename, tag, length) ...@@ -297,22 +286,14 @@ tag_blocks (filename, tag, length)
for (ix = 0; ix != n_blocks; ix++) for (ix = 0; ix != n_blocks; ix++)
{ {
unsigned flags;
if (gcov_read_unsigned (&flags))
return 1;
if (!(ix & 7)) if (!(ix & 7))
printf ("\n%s:\t\t%u", filename, ix); 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) tag_arcs (filename, tag, length)
const char *filename ATTRIBUTE_UNUSED; const char *filename ATTRIBUTE_UNUSED;
unsigned tag ATTRIBUTE_UNUSED; unsigned tag ATTRIBUTE_UNUSED;
...@@ -324,29 +305,21 @@ tag_arcs (filename, tag, length) ...@@ -324,29 +305,21 @@ tag_arcs (filename, tag, length)
if (flag_dump_contents) if (flag_dump_contents)
{ {
unsigned ix; unsigned ix;
unsigned blockno; unsigned blockno = gcov_read_unsigned ();
if (gcov_read_unsigned (&blockno))
return 1;
for (ix = 0; ix != n_arcs; ix++) 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)) if (!(ix & 3))
printf ("\n%s:\t\t%u:", filename, blockno); printf ("\n%s:\tblock %u:", filename, blockno);
printf (" %u:%04x", dst, flags); printf (" %u:%04x", dst, flags);
} }
} }
else
gcov_skip (4 + n_arcs * 8);
return 0;
} }
static int static void
tag_lines (filename, tag, length) tag_lines (filename, tag, length)
const char *filename ATTRIBUTE_UNUSED; const char *filename ATTRIBUTE_UNUSED;
unsigned tag ATTRIBUTE_UNUSED; unsigned tag ATTRIBUTE_UNUSED;
...@@ -354,26 +327,17 @@ tag_lines (filename, tag, length) ...@@ -354,26 +327,17 @@ tag_lines (filename, tag, length)
{ {
if (flag_dump_contents) if (flag_dump_contents)
{ {
char *source = NULL; unsigned blockno = gcov_read_unsigned ();
unsigned blockno;
char const *sep = NULL; char const *sep = NULL;
if (gcov_read_unsigned (&blockno))
return 1;
while (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 (!lineno)
{ {
if (gcov_read_string (&source)) source = gcov_read_string ();
return 1;
if (!source) if (!source)
break; break;
sep = NULL; sep = NULL;
...@@ -381,7 +345,7 @@ tag_lines (filename, tag, length) ...@@ -381,7 +345,7 @@ tag_lines (filename, tag, length)
if (!sep) if (!sep)
{ {
printf ("\n%s:\t\t%u:", filename, blockno); printf ("\n%s:\tblock %u:", filename, blockno);
sep = ""; sep = "";
} }
if (lineno) if (lineno)
...@@ -396,13 +360,9 @@ tag_lines (filename, tag, length) ...@@ -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) tag_arc_counts (filename, tag, length)
const char *filename ATTRIBUTE_UNUSED; const char *filename ATTRIBUTE_UNUSED;
unsigned tag ATTRIBUTE_UNUSED; unsigned tag ATTRIBUTE_UNUSED;
...@@ -417,23 +377,17 @@ tag_arc_counts (filename, tag, length) ...@@ -417,23 +377,17 @@ tag_arc_counts (filename, tag, length)
for (ix = 0; ix != n_counts; ix++) 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)) if (!(ix & 7))
printf ("\n%s:\t\t%u", filename, ix); printf ("\n%s:\t\t%u", filename, ix);
printf (" "); printf (" ");
printf (HOST_WIDEST_INT_PRINT_DEC, count); printf (HOST_WIDEST_INT_PRINT_DEC, count);
} }
} }
else
gcov_skip (n_counts * 8);
return 0;
} }
static int static void
tag_summary (filename, tag, length) tag_summary (filename, tag, length)
const char *filename ATTRIBUTE_UNUSED; const char *filename ATTRIBUTE_UNUSED;
unsigned tag ATTRIBUTE_UNUSED; unsigned tag ATTRIBUTE_UNUSED;
...@@ -441,8 +395,8 @@ tag_summary (filename, tag, length) ...@@ -441,8 +395,8 @@ tag_summary (filename, tag, length)
{ {
struct gcov_summary summary; struct gcov_summary summary;
if (gcov_read_summary (&summary)) gcov_read_summary (&summary);
return 1;
printf (" checksum=0x%08x", summary.checksum); printf (" checksum=0x%08x", summary.checksum);
printf ("\n%s:\t\truns=%u, arcs=%u", filename, printf ("\n%s:\t\truns=%u, arcs=%u", filename,
...@@ -459,5 +413,4 @@ tag_summary (filename, tag, length) ...@@ -459,5 +413,4 @@ tag_summary (filename, tag, length)
printf (", sum_max="); printf (", sum_max=");
printf (HOST_WIDEST_INT_PRINT_DEC, printf (HOST_WIDEST_INT_PRINT_DEC,
(HOST_WIDEST_INT)summary.arc_sum_max); (HOST_WIDEST_INT)summary.arc_sum_max);
return 0;
} }
...@@ -287,45 +287,44 @@ extern void __gcov_flush (void); ...@@ -287,45 +287,44 @@ extern void __gcov_flush (void);
/* Because small reads and writes, interspersed with seeks cause lots /* Because small reads and writes, interspersed with seeks cause lots
of disk activity, we buffer the entire count files. */ of disk activity, we buffer the entire count files. */
static FILE *gcov_file; static struct gcov_var
static size_t gcov_position; {
static size_t gcov_length; FILE *file;
static unsigned char *gcov_buffer; size_t position;
static size_t gcov_alloc; size_t length;
static int gcov_modified; size_t alloc;
static int gcov_errored = 1; unsigned modified;
int error;
unsigned char *buffer;
} gcov_var;
/* Functions for reading and writing gcov files. */ /* Functions for reading and writing gcov files. */
static int gcov_open (const char */*name*/, int /*truncate*/); static int gcov_open (const char */*name*/, int /*truncate*/);
static int gcov_close (void); static int gcov_close (void);
#if !IN_GCOV #if !IN_GCOV
static unsigned char *gcov_write_bytes (unsigned); static unsigned char *gcov_write_bytes (unsigned);
static int gcov_write_unsigned (unsigned); static void gcov_write_unsigned (unsigned);
#if IN_LIBGCOV #if IN_LIBGCOV
static int gcov_write_counter (gcov_type); static void gcov_write_counter (gcov_type);
#endif #endif
static int gcov_write_string (const char *); static void gcov_write_string (const char *);
static unsigned long gcov_reserve_length (void); static unsigned long gcov_write_tag (unsigned);
static int gcov_write_length (unsigned long /*position*/); static void gcov_write_length (unsigned long /*position*/);
#if IN_LIBGCOV #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
#endif /* !IN_GCOV */ #endif /* !IN_GCOV */
static const unsigned char *gcov_read_bytes (unsigned); static const unsigned char *gcov_read_bytes (unsigned);
static int gcov_read_unsigned (unsigned *); static unsigned gcov_read_unsigned (void);
static int gcov_read_counter (gcov_type *); static gcov_type gcov_read_counter (void);
#if !IN_LIBGCOV static const char *gcov_read_string (void);
static int gcov_read_string (char **); static void gcov_read_summary (struct gcov_summary *);
#endif
static int gcov_read_summary (struct gcov_summary *); static unsigned long gcov_position (void);
static unsigned long gcov_save_position (void); static void gcov_seek (unsigned long /*base*/, unsigned /*length */);
static int gcov_resync (unsigned long /*base*/, unsigned /*length */);
static unsigned long gcov_seek_end (void); static unsigned long gcov_seek_end (void);
static int gcov_skip (unsigned /*length*/); static int gcov_is_eof (void);
static int gcov_skip_string (unsigned /*length*/); static int gcov_is_error (void);
static int gcov_ok (void);
static int gcov_error (void);
static int gcov_eof (void);
#if IN_GCOV > 0 #if IN_GCOV > 0
static time_t gcov_time (void); static time_t gcov_time (void);
#endif #endif
...@@ -353,62 +352,63 @@ gcov_open (const char *name, int mode) ...@@ -353,62 +352,63 @@ gcov_open (const char *name, int mode)
s_flock.l_pid = getpid (); s_flock.l_pid = getpid ();
#endif #endif
if (gcov_file) if (gcov_var.file)
abort (); abort ();
gcov_position = gcov_length = 0; gcov_var.position = gcov_var.length = 0;
gcov_errored = gcov_modified = 0; gcov_var.error = gcov_var.modified = 0;
if (mode >= 0) if (mode >= 0)
gcov_file = fopen (name, "r+b"); gcov_var.file = fopen (name, "r+b");
if (!gcov_file && mode <= 0) if (!gcov_var.file && mode <= 0)
{ {
result = -1; result = -1;
gcov_file = fopen (name, "w+b"); gcov_var.file = fopen (name, "w+b");
} }
if (!gcov_file) if (!gcov_var.file)
return 0; return 0;
#if defined (TARGET_HAS_F_SETLKW) && IN_LIBGCOV #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) && errno == EINTR)
continue; continue;
#endif #endif
if (result >= 0) if (result >= 0)
{ {
if (fseek (gcov_file, 0, SEEK_END)) if (fseek (gcov_var.file, 0, SEEK_END))
{ {
fclose (gcov_file); fclose (gcov_var.file);
gcov_file = 0; gcov_var.file = 0;
return 0; return 0;
} }
gcov_length = ftell (gcov_file); gcov_var.length = ftell (gcov_var.file);
fseek (gcov_file, 0, SEEK_SET); fseek (gcov_var.file, 0, SEEK_SET);
alloc += gcov_length; alloc += gcov_var.length;
} }
if (alloc > gcov_alloc) if (alloc > gcov_var.alloc)
{ {
if (gcov_buffer) if (gcov_var.buffer)
free (gcov_buffer); free (gcov_var.buffer);
gcov_alloc = alloc; gcov_var.alloc = alloc;
#if IN_LIBGCOV #if IN_LIBGCOV
gcov_buffer = malloc (gcov_alloc); gcov_var.buffer = malloc (gcov_var.alloc);
if (!gcov_buffer) if (!gcov_var.buffer)
{ {
fclose (gcov_file); fclose (gcov_var.file);
gcov_file = 0; gcov_var.file = 0;
gcov_length = 0; gcov_var.length = 0;
gcov_alloc = 0; gcov_var.alloc = 0;
return 0; return 0;
} }
#else #else
gcov_buffer = xmalloc (gcov_alloc); gcov_var.buffer = xmalloc (gcov_var.alloc);
#endif #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); fclose (gcov_var.file);
gcov_file = 0; gcov_var.file = 0;
gcov_length = 0; gcov_var.length = 0;
return 0; return 0;
} }
return result; return result;
...@@ -422,17 +422,23 @@ gcov_close () ...@@ -422,17 +422,23 @@ gcov_close ()
{ {
int result = 0; int result = 0;
if (gcov_file) if (gcov_var.file)
{ {
if (gcov_modified if (gcov_var.modified
&& (fseek (gcov_file, 0, SEEK_SET) && (fseek (gcov_var.file, 0, SEEK_SET)
|| fwrite (gcov_buffer, gcov_length, 1, gcov_file) != 1)) || fwrite (gcov_var.buffer, gcov_var.length,
result = -1; 1, gcov_var.file) != 1))
fclose (gcov_file); result = 1;
gcov_file = 0; fclose (gcov_var.file);
gcov_length = 0; 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 #if !IN_GCOV
...@@ -444,167 +450,177 @@ gcov_write_bytes (unsigned bytes) ...@@ -444,167 +450,177 @@ gcov_write_bytes (unsigned bytes)
{ {
char unsigned *result; 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; return 0;
#if IN_LIBGCOV #if IN_LIBGCOV
result = realloc (gcov_buffer, new_size); result = realloc (gcov_var.buffer, new_size);
if (!result) if (!result)
{ {
free (gcov_buffer); free (gcov_var.buffer);
gcov_buffer = 0; gcov_var.buffer = 0;
gcov_alloc = 0; gcov_var.alloc = 0;
gcov_position = gcov_length = 0; gcov_var.position = gcov_var.length = 0;
gcov_var.error = 1;
return 0; return 0;
} }
#else #else
result = xrealloc (gcov_buffer, new_size); result = xrealloc (gcov_var.buffer, new_size);
#endif #endif
gcov_alloc = new_size; gcov_var.alloc = new_size;
gcov_buffer = result; gcov_var.buffer = result;
} }
result = &gcov_buffer[gcov_position]; result = &gcov_var.buffer[gcov_var.position];
gcov_position += bytes; gcov_var.position += bytes;
gcov_modified = 1; gcov_var.modified = 1;
if (gcov_position > gcov_length) if (gcov_var.position > gcov_var.length)
gcov_length = gcov_position; gcov_var.length = gcov_var.position;
return result; return result;
} }
/* Write VALUE to coverage file. Return nonzero if failed due to /* Write unsigned VALUE to coverage file. Sets error flag
file i/o error, or value error. */ appropriately. */
static int static void
gcov_write_unsigned (unsigned value) gcov_write_unsigned (unsigned value)
{ {
unsigned char *buffer = gcov_write_bytes (4); unsigned char *buffer = gcov_write_bytes (4);
unsigned ix; unsigned ix;
if (!buffer) if (!buffer)
return 1; return;
for (ix = 4; ix--; ) for (ix = 4; ix--; )
{ {
buffer[ix] = value; buffer[ix] = value;
value >>= 8; 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 /* Write counter VALUE to coverage file. Sets error flag
file i/o error, or value error. Negative values are not checked appropriately. */
here -- they are checked in gcov_read_counter. */
#if IN_LIBGCOV #if IN_LIBGCOV
static int static void
gcov_write_counter (gcov_type value) gcov_write_counter (gcov_type value)
{ {
unsigned char *buffer = gcov_write_bytes (8); unsigned char *buffer = gcov_write_bytes (8);
unsigned ix; unsigned ix;
if (!buffer) if (!buffer)
return 1; return;
for (ix = 8; ix--; ) for (ix = 8; ix--; )
{ {
buffer[ix] = value; buffer[ix] = value;
value >>= 8; value >>= 8;
} }
return sizeof (value) > 8 && value; if ((sizeof (value) > 8 && value) || value < 0)
gcov_var.error = -1;
return;
} }
#endif /* IN_LIBGCOV */ #endif /* IN_LIBGCOV */
/* Write VALUE to coverage file. Return nonzero if failed due to /* Write STRING to coverage file. Sets error flag on file
file i/o error, or value error. */ error, overflow flag on overflow */
static int static void
gcov_write_string (const char *string) gcov_write_string (const char *string)
{ {
unsigned length = 0;
unsigned pad = 0;
unsigned rem = 0;
unsigned char *buffer;
if (string) if (string)
{ {
unsigned length = strlen (string); length = strlen (string);
unsigned pad = 0; rem = 4 - (length & 3);
unsigned rem = 4 - (length & 3); }
unsigned char *buffer;
buffer = gcov_write_bytes (4 + length + rem);
if (gcov_write_unsigned (length)) if (buffer)
return 1; {
buffer = gcov_write_bytes (length + rem); unsigned ix;
if (!buffer) unsigned value = length;
return 1;
memcpy (buffer, string, length); for (ix = 4; ix--; )
memcpy (buffer + length, &pad, rem); {
return 0; 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 /* Write a tag TAG and reserve space for the record length. Return a
used for gcov_write_length. */ value to be used for gcov_write_length. */
static unsigned long static unsigned long
gcov_reserve_length (void) gcov_write_tag (unsigned tag)
{ {
unsigned long result = gcov_position; unsigned long result = gcov_var.position;
unsigned char *buffer = gcov_write_bytes (4); unsigned char *buffer = gcov_write_bytes (8);
unsigned ix;
if (!buffer) if (!buffer)
return 0; return 0;
memset (buffer, 0, 4); for (ix = 4; ix--; )
{
buffer[ix] = tag;
tag >>= 8;
}
memset (buffer + 4, 0, 4);
return result; return result;
} }
/* Write a record length at PLACE. The current file position is the /* Write a record length using POSITION, which was returned by
end of the record, and is restored before returning. Returns gcov_write_tag. The current file position is the end of the
nonzero on failure. */ record, and is restored before returning. Returns nonzero on
overflow. */
static int static void
gcov_write_length (unsigned long position) gcov_write_length (unsigned long position)
{ {
unsigned length = gcov_position - position - 4; if (position)
unsigned char *buffer = &gcov_buffer[position];
unsigned ix;
if (!position)
return 1;
for (ix = 4; ix--; )
{ {
buffer[ix] = length; unsigned length = gcov_var.position - position - 8;
length >>= 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 #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) gcov_write_summary (unsigned tag, const struct gcov_summary *summary)
{ {
volatile unsigned long base; /* volatile is necessary to work around unsigned long base;
a compiler bug. */
base = gcov_write_tag (tag);
if (gcov_write_unsigned (tag)) gcov_write_unsigned (summary->checksum);
return 1; gcov_write_unsigned (summary->runs);
base = gcov_reserve_length (); gcov_write_unsigned (summary->arcs);
if (gcov_write_unsigned (summary->checksum)) gcov_write_counter (summary->arc_sum);
return 1; gcov_write_counter (summary->arc_max_one);
if (gcov_write_unsigned (summary->runs) gcov_write_counter (summary->arc_max_sum);
|| gcov_write_unsigned (summary->arcs)) gcov_write_counter (summary->arc_sum_max);
return 1; gcov_write_length (base);
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;
} }
#endif /* IN_LIBGCOV */ #endif /* IN_LIBGCOV */
...@@ -618,127 +634,118 @@ gcov_read_bytes (unsigned bytes) ...@@ -618,127 +634,118 @@ gcov_read_bytes (unsigned bytes)
{ {
const unsigned char *result; const unsigned char *result;
if (gcov_position + bytes > gcov_length) if (gcov_var.position + bytes > gcov_var.length)
return 0; {
result = &gcov_buffer[gcov_position]; gcov_var.error = 1;
gcov_position += bytes; return 0;
}
result = &gcov_var.buffer[gcov_var.position];
gcov_var.position += bytes;
return result; return result;
} }
/* Read *VALUE_P from coverage file. Return nonzero if failed /* Read unsigned value from a coverage file. Sets error flag on file
due to file i/o error, or range error. */ error, overflow flag on overflow */
static int static unsigned
gcov_read_unsigned (unsigned *value_p) gcov_read_unsigned ()
{ {
unsigned value = 0; unsigned value = 0;
unsigned ix; unsigned ix;
const unsigned char *buffer = gcov_read_bytes (4); const unsigned char *buffer = gcov_read_bytes (4);
if (!buffer) if (!buffer)
return 1; return 0;
for (ix = sizeof (value); ix < 4; ix++) for (ix = sizeof (value); ix < 4; ix++)
if (buffer[ix]) if (buffer[ix])
return 1; gcov_var.error = -1;
for (ix = 0; ix != 4; ix++) for (ix = 0; ix != 4; ix++)
{ {
value <<= 8; value <<= 8;
value |= buffer[ix]; value |= buffer[ix];
} }
*value_p = value; return value;
return 0;
} }
/* Read *VALUE_P from coverage file. Return nonzero if failed /* Read counter value from a coverage file. Sets error flag on file
due to file i/o error, or range error. */ error, overflow flag on overflow */
static int static gcov_type
gcov_read_counter (gcov_type *value_p) gcov_read_counter ()
{ {
gcov_type value = 0; gcov_type value = 0;
unsigned ix; unsigned ix;
const unsigned char *buffer = gcov_read_bytes (8); const unsigned char *buffer = gcov_read_bytes (8);
if (!buffer) if (!buffer)
return 1; return 0;
for (ix = sizeof (value); ix < 8; ix++) for (ix = sizeof (value); ix < 8; ix++)
if (buffer[ix]) if (buffer[ix])
return 1; gcov_var.error = -1;
for (ix = 0; ix != 8; ix++) for (ix = 0; ix != 8; ix++)
{ {
value <<= 8; value <<= 8;
value |= buffer[ix]; value |= buffer[ix];
} }
if (value < 0)
*value_p = value; gcov_var.error = -1;
return value < 0; 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
/* Read string from coverage file. A buffer is allocated and returned calling another gcov function. */
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 static const char *
gcov_read_string (char **string_p) gcov_read_string ()
{ {
unsigned length; unsigned length = gcov_read_unsigned ();
const unsigned char *buffer;
if (gcov_read_unsigned (&length))
return 1;
free (*string_p);
*string_p = NULL;
if (!length) if (!length)
return 0; return 0;
length += 4 - (length & 3); length += 4 - (length & 3);
buffer = gcov_read_bytes (length); return (const char *) gcov_read_bytes (length);
if (!buffer)
return 1;
*string_p = xmalloc (length);
if (!*string_p)
return 1;
memcpy (*string_p, buffer, length);
return 0;
} }
#endif /* !IN_LIBGCOV */
#define GCOV_SUMMARY_LENGTH 44 #define GCOV_SUMMARY_LENGTH 44
static int static void
gcov_read_summary (struct gcov_summary *summary) gcov_read_summary (struct gcov_summary *summary)
{ {
return (gcov_read_unsigned (&summary->checksum) summary->checksum = gcov_read_unsigned ();
|| gcov_read_unsigned (&summary->runs) summary->runs = gcov_read_unsigned ();
|| gcov_read_unsigned (&summary->arcs) summary->arcs = gcov_read_unsigned ();
|| gcov_read_counter (&summary->arc_sum) summary->arc_sum = gcov_read_counter ();
|| gcov_read_counter (&summary->arc_max_one) summary->arc_max_one = gcov_read_counter ();
|| gcov_read_counter (&summary->arc_max_sum) summary->arc_max_sum = gcov_read_counter ();
|| gcov_read_counter (&summary->arc_sum_max)); summary->arc_sum_max = gcov_read_counter ();
} }
/* Save the current position in the gcov file. */ /* Save the current position in the gcov file. */
static inline unsigned long 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 /* Reset to a known position. BASE should have been obtained from
gcov_save_position, LENGTH should be a record length, or zero. */ gcov_save_position, LENGTH should be a record length, or zero. */
static inline int static inline void
gcov_resync (unsigned long base, unsigned length) gcov_seek (unsigned long base, unsigned length)
{ {
if (gcov_buffer) if (gcov_var.buffer)
gcov_position = base + length; {
return 0; 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. */ /* Move to the end of the gcov file. */
...@@ -746,53 +753,24 @@ gcov_resync (unsigned long base, unsigned length) ...@@ -746,53 +753,24 @@ gcov_resync (unsigned long base, unsigned length)
static inline unsigned long static inline unsigned long
gcov_seek_end () gcov_seek_end ()
{ {
gcov_position = gcov_length; gcov_var.position = gcov_var.length;
return gcov_position; return gcov_var.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));
} }
/* Tests whether we have reached end of .da file. */ /* Tests whether we have reached end of .da file. */
static inline int 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. */ /* Return non-zero if the error flag is set. */
static inline int static inline int
gcov_ok () gcov_is_error ()
{ {
return gcov_file != 0 && !gcov_errored; return gcov_var.file ? gcov_var.error : 1;
}
/* Set the error flag. */
static inline int
gcov_error ()
{
int error = gcov_errored;
gcov_errored = 1;
return error;
} }
#if IN_GCOV > 0 #if IN_GCOV > 0
...@@ -803,7 +781,7 @@ gcov_time () ...@@ -803,7 +781,7 @@ gcov_time ()
{ {
struct stat status; struct stat status;
if (fstat (fileno (gcov_file), &status)) if (fstat (fileno (gcov_var.file), &status))
return 0; return 0;
else else
return status.st_mtime; return status.st_mtime;
......
...@@ -321,7 +321,7 @@ static void print_usage PARAMS ((int)) ATTRIBUTE_NORETURN; ...@@ -321,7 +321,7 @@ static void print_usage PARAMS ((int)) ATTRIBUTE_NORETURN;
static void print_version PARAMS ((void)) ATTRIBUTE_NORETURN; static void print_version PARAMS ((void)) ATTRIBUTE_NORETURN;
static void process_file PARAMS ((const char *)); static void process_file PARAMS ((const char *));
static void create_file_names 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_graph_file PARAMS ((void));
static int read_count_file PARAMS ((void)); static int read_count_file PARAMS ((void));
static void solve_flow_graph PARAMS ((function_t *)); static void solve_flow_graph PARAMS ((function_t *));
...@@ -673,31 +673,29 @@ create_file_names (file_name) ...@@ -673,31 +673,29 @@ create_file_names (file_name)
return; return;
} }
/* Find or create a source file structure for FILE_NAME. Free /* Find or create a source file structure for FILE_NAME. Copies
FILE_NAME appropriately */ FILE_NAME on creation */
static source_t * static source_t *
find_source (file_name) find_source (file_name)
char *file_name; const char *file_name;
{ {
source_t *src; source_t *src;
if (!file_name)
file_name = "<unknown>";
for (src = sources; src; src = src->next) for (src = sources; src; src = src->next)
if (!strcmp (file_name, src->name)) if (!strcmp (file_name, src->name))
{ return src;
free (file_name);
break; src = (source_t *)xcalloc (1, sizeof (source_t));
} src->name = xstrdup (file_name);
if (!src) src->coverage.name = src->name;
{ src->index = sources ? sources->index + 1 : 1;
src = (source_t *)xcalloc (1, sizeof (source_t)); src->next = sources;
src->name = file_name; sources = src;
src->coverage.name = file_name;
src->index = sources ? sources->index + 1 : 1;
src->next = sources;
sources = src;
}
return src; return src;
} }
...@@ -706,9 +704,8 @@ find_source (file_name) ...@@ -706,9 +704,8 @@ find_source (file_name)
static int static int
read_graph_file () read_graph_file ()
{ {
unsigned magic, version; unsigned version;
unsigned current_tag = 0; unsigned current_tag = 0;
unsigned tag;
struct function_info *fn = NULL; struct function_info *fn = NULL;
source_t *src = NULL; source_t *src = NULL;
unsigned ix; unsigned ix;
...@@ -719,52 +716,46 @@ read_graph_file () ...@@ -719,52 +716,46 @@ read_graph_file ()
return 1; return 1;
} }
bbg_file_time = gcov_time (); 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); fnotice (stderr, "%s:not a gcov graph file\n", bbg_file_name);
gcov_close (); gcov_close ();
return 1; return 1;
} }
if (gcov_read_unsigned (&version) || version != GCOV_VERSION) version = gcov_read_unsigned ();
if (version != GCOV_VERSION)
{ {
char v[4], e[4]; char v[4], e[4];
unsigned required = GCOV_VERSION;
magic = GCOV_VERSION;
for (ix = 4; ix--; magic >>= 8, version >>= 8) for (ix = 4; ix--; required >>= 8, version >>= 8)
{ {
v[ix] = version; v[ix] = version;
e[ix] = magic; e[ix] = required;
} }
fnotice (stderr, "%s:version `%.4s', prefer `%.4s'\n", fnotice (stderr, "%s:version `%.4s', prefer `%.4s'\n",
bbg_file_name, v, e); bbg_file_name, v, e);
} }
while (!gcov_read_unsigned (&tag)) while (!gcov_is_eof ())
{ {
unsigned length; unsigned tag = gcov_read_unsigned ();
long base; unsigned length = gcov_read_unsigned ();
unsigned long base = gcov_position ();
if (gcov_read_unsigned (&length))
goto corrupt;
base = gcov_save_position ();
if (tag == GCOV_TAG_FUNCTION) if (tag == GCOV_TAG_FUNCTION)
{ {
char *function_name = NULL; char *function_name;
char *function_file = NULL;
unsigned checksum, lineno; unsigned checksum, lineno;
source_t *src; source_t *src;
function_t *probe, *prev; function_t *probe, *prev;
if (gcov_read_string (&function_name) function_name = xstrdup (gcov_read_string ());
|| gcov_read_unsigned (&checksum) checksum = gcov_read_unsigned ();
|| gcov_read_string (&function_file) src = find_source (gcov_read_string ());
|| gcov_read_unsigned (&lineno)) lineno = gcov_read_unsigned ();
goto corrupt;
src = find_source (function_file);
fn = (function_t *)xcalloc (1, sizeof (function_t)); fn = (function_t *)xcalloc (1, sizeof (function_t));
fn->name = function_name; fn->name = function_name;
fn->checksum = checksum; fn->checksum = checksum;
...@@ -803,33 +794,24 @@ read_graph_file () ...@@ -803,33 +794,24 @@ read_graph_file ()
fn->blocks fn->blocks
= (block_t *)xcalloc (fn->num_blocks, sizeof (block_t)); = (block_t *)xcalloc (fn->num_blocks, sizeof (block_t));
for (ix = 0; ix != num_blocks; ix++) for (ix = 0; ix != num_blocks; ix++)
{ fn->blocks[ix].flags = gcov_read_unsigned ();
unsigned flags;
if (gcov_read_unsigned (&flags))
goto corrupt;
fn->blocks[ix].flags = flags;
}
} }
} }
else if (fn && tag == GCOV_TAG_ARCS) else if (fn && tag == GCOV_TAG_ARCS)
{ {
unsigned src; unsigned src = gcov_read_unsigned ();
unsigned num_dests = (length - 4) / 8; unsigned num_dests = (length - 4) / 8;
unsigned dest, flags;
if (gcov_read_unsigned (&src) if (src >= fn->num_blocks || fn->blocks[src].succ)
|| src >= fn->num_blocks
|| fn->blocks[src].succ)
goto corrupt; goto corrupt;
while (num_dests--) while (num_dests--)
{ {
struct arc_info *arc; struct arc_info *arc;
unsigned dest = gcov_read_unsigned ();
unsigned flags = gcov_read_unsigned ();
if (gcov_read_unsigned (&dest) if (dest >= fn->num_blocks)
|| gcov_read_unsigned (&flags)
|| dest >= fn->num_blocks)
goto corrupt; goto corrupt;
arc = (arc_t *) xcalloc (1, sizeof (arc_t)); arc = (arc_t *) xcalloc (1, sizeof (arc_t));
...@@ -875,21 +857,17 @@ read_graph_file () ...@@ -875,21 +857,17 @@ read_graph_file ()
} }
else if (fn && tag == GCOV_TAG_LINES) else if (fn && tag == GCOV_TAG_LINES)
{ {
unsigned blockno; unsigned blockno = gcov_read_unsigned ();
unsigned *line_nos unsigned *line_nos
= (unsigned *)xcalloc ((length - 4) / 4, sizeof (unsigned)); = (unsigned *)xcalloc ((length - 4) / 4, sizeof (unsigned));
if (gcov_read_unsigned (&blockno) if (blockno >= fn->num_blocks || fn->blocks[blockno].u.line.encoding)
|| blockno >= fn->num_blocks
|| fn->blocks[blockno].u.line.encoding)
goto corrupt; goto corrupt;
for (ix = 0; ; ) for (ix = 0; ; )
{ {
unsigned lineno; unsigned lineno = gcov_read_unsigned ();
if (gcov_read_unsigned (&lineno))
goto corrupt;
if (lineno) if (lineno)
{ {
if (!ix) if (!ix)
...@@ -903,10 +881,8 @@ read_graph_file () ...@@ -903,10 +881,8 @@ read_graph_file ()
} }
else else
{ {
char *file_name = NULL; const char *file_name = gcov_read_string ();
if (gcov_read_string (&file_name))
goto corrupt;
if (!file_name) if (!file_name)
break; break;
src = find_source (file_name); src = find_source (file_name);
...@@ -924,7 +900,8 @@ read_graph_file () ...@@ -924,7 +900,8 @@ read_graph_file ()
fn = NULL; fn = NULL;
current_tag = 0; current_tag = 0;
} }
if (gcov_resync (base, length)) gcov_seek (base, length);
if (gcov_is_error ())
{ {
corrupt:; corrupt:;
fnotice (stderr, "%s:corrupted\n", bbg_file_name); fnotice (stderr, "%s:corrupted\n", bbg_file_name);
...@@ -994,8 +971,7 @@ static int ...@@ -994,8 +971,7 @@ static int
read_count_file () read_count_file ()
{ {
unsigned ix; unsigned ix;
char *function_name_buffer = NULL; unsigned version;
unsigned magic, version;
function_t *fn = NULL; function_t *fn = NULL;
if (!gcov_open (da_file_name, 1)) if (!gcov_open (da_file_name, 1))
...@@ -1003,63 +979,44 @@ read_count_file () ...@@ -1003,63 +979,44 @@ read_count_file ()
fnotice (stderr, "%s:cannot open data file\n", da_file_name); fnotice (stderr, "%s:cannot open data file\n", da_file_name);
return 1; 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); fnotice (stderr, "%s:not a gcov data file\n", da_file_name);
cleanup:; cleanup:;
free (function_name_buffer);
gcov_close (); gcov_close ();
return 1; return 1;
} }
if (gcov_read_unsigned (&version) || version != GCOV_VERSION) version = gcov_read_unsigned ();
if (version != GCOV_VERSION)
{ {
char v[4], e[4]; char v[4], e[4];
unsigned desired = GCOV_VERSION;
magic = GCOV_VERSION; for (ix = 4; ix--; desired >>= 8, version >>= 8)
for (ix = 4; ix--; magic >>= 8, version >>= 8)
{ {
v[ix] = version; v[ix] = version;
e[ix] = magic; e[ix] = desired;
} }
fnotice (stderr, "%s:version `%.4s', prefer version `%.4s'\n", fnotice (stderr, "%s:version `%.4s', prefer version `%.4s'\n",
da_file_name, v, e); da_file_name, v, e);
} }
while (1) while (!gcov_is_eof ())
{ {
unsigned tag, length; unsigned tag = gcov_read_unsigned ();
long base; unsigned length = gcov_read_unsigned ();
unsigned long base = gcov_position ();
if (gcov_read_unsigned (&tag) int error;
|| gcov_read_unsigned (&length))
{
if (gcov_eof ())
break;
corrupt:;
fnotice (stderr, "%s:corrupted\n", da_file_name);
goto cleanup;
}
base = gcov_save_position ();
if (tag == GCOV_TAG_OBJECT_SUMMARY) if (tag == GCOV_TAG_OBJECT_SUMMARY)
{ gcov_read_summary (&object_summary);
if (gcov_read_summary (&object_summary))
goto corrupt;
}
else if (tag == GCOV_TAG_PROGRAM_SUMMARY else if (tag == GCOV_TAG_PROGRAM_SUMMARY
|| tag == GCOV_TAG_INCORRECT_SUMMARY) || tag == GCOV_TAG_INCORRECT_SUMMARY)
{ program_count++;
program_count++;
gcov_resync (base, length);
}
else if (tag == GCOV_TAG_FUNCTION) else if (tag == GCOV_TAG_FUNCTION)
{ {
unsigned checksum; const char *function_name = gcov_read_string ();
struct function_info *fn_n = functions; 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) for (fn = fn ? fn->next : NULL; ; fn = fn->next)
{ {
...@@ -1070,20 +1027,20 @@ read_count_file () ...@@ -1070,20 +1027,20 @@ read_count_file ()
else else
{ {
fnotice (stderr, "%s:unknown function `%s'\n", fnotice (stderr, "%s:unknown function `%s'\n",
da_file_name, function_name_buffer); da_file_name, function_name);
break; break;
} }
if (!strcmp (fn->name, function_name_buffer)) if (!strcmp (fn->name, function_name))
break; break;
} }
if (!fn) if (!fn)
; ;
else if (checksum != fn->checksum) else if (gcov_read_unsigned () != fn->checksum)
{ {
mismatch:; mismatch:;
fnotice (stderr, "%s:profile mismatch for `%s'\n", fnotice (stderr, "%s:profile mismatch for `%s'\n",
da_file_name, function_name_buffer); da_file_name, fn->name);
goto cleanup; goto cleanup;
} }
} }
...@@ -1097,20 +1054,18 @@ read_count_file () ...@@ -1097,20 +1054,18 @@ read_count_file ()
= (gcov_type *)xcalloc (fn->num_counts, sizeof (gcov_type)); = (gcov_type *)xcalloc (fn->num_counts, sizeof (gcov_type));
for (ix = 0; ix != fn->num_counts; ix++) for (ix = 0; ix != fn->num_counts; ix++)
{ fn->counts[ix] += gcov_read_counter ();
gcov_type count; }
gcov_seek (base, length);
if (gcov_read_counter (&count)) if ((error = gcov_is_error ()))
goto corrupt; {
fn->counts[ix] += count; fnotice (stderr, error < 0
} ? "%s:overflowed\n" : "%s:corrupted\n", da_file_name);
goto cleanup;
} }
else
gcov_resync (base, length);
} }
gcov_close (); gcov_close ();
free (function_name_buffer);
return 0; return 0;
} }
......
...@@ -110,14 +110,14 @@ gcov_exit (void) ...@@ -110,14 +110,14 @@ gcov_exit (void)
{ {
struct gcov_summary object; struct gcov_summary object;
struct gcov_summary local_prg; struct gcov_summary local_prg;
int error;
int merging; int merging;
long base; unsigned long base;
const struct function_info *fn_info; const struct function_info *fn_info;
gcov_type **counters; gcov_type **counters;
gcov_type *count_ptr; gcov_type *count_ptr;
gcov_type object_max_one = 0; gcov_type object_max_one = 0;
gcov_type count; unsigned tag, length;
unsigned tag, length, flength, checksum;
unsigned arc_data_index, f_sect_index, sect_index; unsigned arc_data_index, f_sect_index, sect_index;
ptr->wkspc = 0; ptr->wkspc = 0;
...@@ -167,7 +167,7 @@ gcov_exit (void) ...@@ -167,7 +167,7 @@ gcov_exit (void)
if (merging > 0) if (merging > 0)
{ {
/* Merge data from file. */ /* 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", fprintf (stderr, "profiling:%s:Not a gcov data file\n",
ptr->filename); ptr->filename);
...@@ -176,7 +176,8 @@ gcov_exit (void) ...@@ -176,7 +176,8 @@ gcov_exit (void)
ptr->filename = 0; ptr->filename = 0;
continue; continue;
} }
if (gcov_read_unsigned (&length) || length != GCOV_VERSION) length = gcov_read_unsigned ();
if (length != GCOV_VERSION)
{ {
gcov_version_mismatch (ptr, length); gcov_version_mismatch (ptr, length);
goto read_fatal; goto read_fatal;
...@@ -186,13 +187,8 @@ gcov_exit (void) ...@@ -186,13 +187,8 @@ gcov_exit (void)
for (ix = ptr->n_functions, fn_info = ptr->functions; for (ix = ptr->n_functions, fn_info = ptr->functions;
ix--; fn_info++) ix--; fn_info++)
{ {
if (gcov_read_unsigned (&tag) || gcov_read_unsigned (&length)) tag = gcov_read_unsigned ();
{ length = gcov_read_unsigned ();
read_error:;
fprintf (stderr, "profiling:%s:Error merging\n",
ptr->filename);
goto read_fatal;
}
/* Check function */ /* Check function */
if (tag != GCOV_TAG_FUNCTION) if (tag != GCOV_TAG_FUNCTION)
...@@ -203,12 +199,8 @@ gcov_exit (void) ...@@ -203,12 +199,8 @@ gcov_exit (void)
goto read_fatal; goto read_fatal;
} }
if (gcov_read_unsigned (&flength) if (strcmp (gcov_read_string (), fn_info->name)
|| gcov_skip_string (flength) || gcov_read_unsigned () != fn_info->checksum)
|| gcov_read_unsigned (&checksum))
goto read_error;
if (flength != strlen (fn_info->name)
|| checksum != fn_info->checksum)
goto read_mismatch; goto read_mismatch;
/* Counters. */ /* Counters. */
...@@ -218,9 +210,9 @@ gcov_exit (void) ...@@ -218,9 +210,9 @@ gcov_exit (void)
{ {
unsigned n_counters; unsigned n_counters;
if (gcov_read_unsigned (&tag) tag = gcov_read_unsigned ();
|| gcov_read_unsigned (&length)) length = gcov_read_unsigned ();
goto read_error;
for (sect_index = 0; for (sect_index = 0;
sect_index < ptr->n_counter_sections; sect_index < ptr->n_counter_sections;
sect_index++) sect_index++)
...@@ -235,40 +227,42 @@ gcov_exit (void) ...@@ -235,40 +227,42 @@ gcov_exit (void)
goto read_mismatch; goto read_mismatch;
for (jx = 0; jx < n_counters; jx++) for (jx = 0; jx < n_counters; jx++)
if (gcov_read_counter (&count)) counters[sect_index][jx] += gcov_read_counter ();
goto read_error;
else
counters[sect_index][jx] += count;
counters[sect_index] += n_counters; counters[sect_index] += n_counters;
} }
if ((error = gcov_is_error ()))
goto read_error;
} }
/* Check object summary */ /* Check object summary */
if (gcov_read_unsigned (&tag) || gcov_read_unsigned (&length)) if (gcov_read_unsigned () != GCOV_TAG_OBJECT_SUMMARY)
goto read_error;
if (tag != GCOV_TAG_OBJECT_SUMMARY)
goto read_mismatch; goto read_mismatch;
if (gcov_read_summary (&object)) gcov_read_unsigned ();
goto read_error; gcov_read_summary (&object);
/* Check program summary */ /* Check program summary */
while (1) while (!gcov_is_eof ())
{ {
long base = gcov_save_position (); unsigned long base = gcov_position ();
if (gcov_read_unsigned (&tag) tag = gcov_read_unsigned ();
|| gcov_read_unsigned (&length)) gcov_read_unsigned ();
{
if (gcov_eof ())
break;
goto read_error;
}
if (tag != GCOV_TAG_PROGRAM_SUMMARY if (tag != GCOV_TAG_PROGRAM_SUMMARY
&& tag != GCOV_TAG_PLACEHOLDER_SUMMARY && tag != GCOV_TAG_PLACEHOLDER_SUMMARY
&& tag != GCOV_TAG_INCORRECT_SUMMARY) && tag != GCOV_TAG_INCORRECT_SUMMARY)
goto read_mismatch; goto read_mismatch;
if (gcov_read_summary (&local_prg)) gcov_read_summary (&local_prg);
goto read_error; 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) if (local_prg.checksum != program.checksum)
continue; continue;
if (tag == GCOV_TAG_PLACEHOLDER_SUMMARY) if (tag == GCOV_TAG_PLACEHOLDER_SUMMARY)
...@@ -294,7 +288,7 @@ gcov_exit (void) ...@@ -294,7 +288,7 @@ gcov_exit (void)
ptr->wkspc = base; ptr->wkspc = base;
break; break;
} }
gcov_resync (0, 0); gcov_seek (0, 0);
} }
object.runs++; object.runs++;
...@@ -305,17 +299,8 @@ gcov_exit (void) ...@@ -305,17 +299,8 @@ gcov_exit (void)
object.arc_sum_max += object_max_one; object.arc_sum_max += object_max_one;
/* Write out the data. */ /* Write out the data. */
if (/* magic */ gcov_write_unsigned (GCOV_DATA_MAGIC);
gcov_write_unsigned (GCOV_DATA_MAGIC) gcov_write_unsigned (GCOV_VERSION);
/* version number */
|| gcov_write_unsigned (GCOV_VERSION))
{
write_error:;
gcov_close ();
fprintf (stderr, "profiling:%s:Error writing\n", ptr->filename);
ptr->filename = 0;
continue;
}
/* Write execution counts for each function. */ /* Write execution counts for each function. */
for (ix = 0; ix < ptr->n_counter_sections; ix++) for (ix = 0; ix < ptr->n_counter_sections; ix++)
...@@ -323,14 +308,10 @@ gcov_exit (void) ...@@ -323,14 +308,10 @@ gcov_exit (void)
for (ix = ptr->n_functions, fn_info = ptr->functions; ix--; fn_info++) for (ix = ptr->n_functions, fn_info = ptr->functions; ix--; fn_info++)
{ {
/* Announce function. */ /* Announce function. */
if (gcov_write_unsigned (GCOV_TAG_FUNCTION) base = gcov_write_tag (GCOV_TAG_FUNCTION);
|| !(base = gcov_reserve_length ()) gcov_write_string (fn_info->name);
/* function name */ gcov_write_unsigned (fn_info->checksum);
|| gcov_write_string (fn_info->name) gcov_write_length (base);
/* function checksum */
|| gcov_write_unsigned (fn_info->checksum)
|| gcov_write_length (base))
goto write_error;
/* counters. */ /* counters. */
for (f_sect_index = 0; for (f_sect_index = 0;
...@@ -346,10 +327,7 @@ gcov_exit (void) ...@@ -346,10 +327,7 @@ gcov_exit (void)
if (sect_index == ptr->n_counter_sections) if (sect_index == ptr->n_counter_sections)
abort (); abort ();
if (gcov_write_unsigned (tag) base = gcov_write_tag (tag);
|| !(base = gcov_reserve_length ()))
goto write_error;
for (jx = fn_info->counter_sections[f_sect_index].n_counters; jx--;) for (jx = fn_info->counter_sections[f_sect_index].n_counters; jx--;)
{ {
gcov_type count = *counters[sect_index]++; gcov_type count = *counters[sect_index]++;
...@@ -360,41 +338,33 @@ gcov_exit (void) ...@@ -360,41 +338,33 @@ gcov_exit (void)
if (object.arc_max_sum < count) if (object.arc_max_sum < count)
object.arc_max_sum = count; object.arc_max_sum = count;
} }
if (gcov_write_counter (count)) gcov_write_counter (count);
goto write_error; /* RIP Edsger Dijkstra */
} }
if (gcov_write_length (base)) gcov_write_length (base);
goto write_error;
} }
} }
/* Object file summary. */ /* Object file summary. */
if (gcov_write_summary (GCOV_TAG_OBJECT_SUMMARY, &object)) gcov_write_summary (GCOV_TAG_OBJECT_SUMMARY, &object);
goto write_error;
if (merging) if (merging)
{ {
ptr->wkspc = gcov_seek_end (); ptr->wkspc = gcov_seek_end ();
if (gcov_write_summary (GCOV_TAG_PLACEHOLDER_SUMMARY, gcov_write_summary (GCOV_TAG_PLACEHOLDER_SUMMARY, &program);
&program))
goto write_error;
} }
else if (ptr->wkspc) else if (ptr->wkspc)
{ {
/* Zap trailing program summary */ /* Zap trailing program summary */
if (gcov_resync (ptr->wkspc, 0)) gcov_seek (ptr->wkspc, 0);
goto write_error;
if (!local_prg.runs) if (!local_prg.runs)
ptr->wkspc = 0; ptr->wkspc = 0;
if (gcov_write_unsigned (local_prg.runs gcov_write_unsigned (local_prg.runs
? GCOV_TAG_PLACEHOLDER_SUMMARY ? GCOV_TAG_PLACEHOLDER_SUMMARY
: GCOV_TAG_INCORRECT_SUMMARY)) : GCOV_TAG_INCORRECT_SUMMARY);
goto write_error;
} }
if (gcov_close ()) if (gcov_close ())
{ {
fprintf (stderr, "profiling:%s:Error closing\n", ptr->filename); fprintf (stderr, "profiling:%s:Error writing\n", ptr->filename);
ptr->filename = 0; ptr->filename = 0;
} }
else else
...@@ -427,11 +397,10 @@ gcov_exit (void) ...@@ -427,11 +397,10 @@ gcov_exit (void)
continue; continue;
} }
if (gcov_resync (ptr->wkspc, 0) gcov_seek (ptr->wkspc, 0);
|| gcov_write_summary (GCOV_TAG_PROGRAM_SUMMARY, &program)) gcov_write_summary (GCOV_TAG_PROGRAM_SUMMARY, &program);
fprintf (stderr, "profiling:%s:Error writing\n", ptr->filename);
if (gcov_close ()) if (gcov_close ())
fprintf (stderr, "profiling:%s:Error closing\n", ptr->filename); fprintf (stderr, "profiling:%s:Error writing\n", ptr->filename);
} }
} }
......
...@@ -274,7 +274,7 @@ static void ...@@ -274,7 +274,7 @@ static void
read_counts_file (const char *name) read_counts_file (const char *name)
{ {
char *function_name_buffer = NULL; char *function_name_buffer = NULL;
unsigned magic, version, ix, checksum; unsigned version, ix, checksum;
counts_entry_t *summaried = NULL; counts_entry_t *summaried = NULL;
unsigned seen_summary = 0; unsigned seen_summary = 0;
...@@ -284,21 +284,21 @@ read_counts_file (const char *name) ...@@ -284,21 +284,21 @@ read_counts_file (const char *name)
return; 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); warning ("`%s' is not a gcov data file", name);
gcov_close (); gcov_close ();
return; return;
} }
else if (gcov_read_unsigned (&version) || version != GCOV_VERSION) else if ((version = gcov_read_unsigned ()) != GCOV_VERSION)
{ {
char v[4], e[4]; 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; v[ix] = version;
e[ix] = magic; e[ix] = required;
} }
warning ("`%s' is version `%.4s', expected version `%.4s'", name, v, e); warning ("`%s' is version `%.4s', expected version `%.4s'", name, v, e);
gcov_close (); gcov_close ();
...@@ -308,27 +308,21 @@ read_counts_file (const char *name) ...@@ -308,27 +308,21 @@ read_counts_file (const char *name)
counts_hash = htab_create (10, counts_hash = htab_create (10,
htab_counts_entry_hash, htab_counts_entry_eq, htab_counts_entry_hash, htab_counts_entry_eq,
htab_counts_entry_del); htab_counts_entry_del);
while (1) while (!gcov_is_eof ())
{ {
unsigned tag, length; unsigned tag, length;
long offset; unsigned long offset;
int error;
offset = gcov_save_position (); tag = gcov_read_unsigned ();
if (gcov_read_unsigned (&tag) || gcov_read_unsigned (&length)) length = gcov_read_unsigned ();
{ offset = gcov_position ();
if (gcov_eof ())
break;
corrupt:;
warning ("`%s' is corrupted", name);
cleanup:
htab_delete (counts_hash);
break;
}
if (tag == GCOV_TAG_FUNCTION) if (tag == GCOV_TAG_FUNCTION)
{ {
if (gcov_read_string (&function_name_buffer) const char *string = gcov_read_string ();
|| gcov_read_unsigned (&checksum)) free (function_name_buffer);
goto corrupt; function_name_buffer = string ? xstrdup (string) : NULL;
checksum = gcov_read_unsigned ();
if (seen_summary) if (seen_summary)
{ {
/* We have already seen a summary, this means that this /* We have already seen a summary, this means that this
...@@ -352,10 +346,7 @@ read_counts_file (const char *name) ...@@ -352,10 +346,7 @@ read_counts_file (const char *name)
counts_entry_t *entry; counts_entry_t *entry;
struct gcov_summary summary; struct gcov_summary summary;
if (length != GCOV_SUMMARY_LENGTH gcov_read_summary (&summary);
|| gcov_read_summary (&summary))
goto corrupt;
seen_summary = 1; seen_summary = 1;
for (entry = summaried; entry; entry = entry->chain) for (entry = summaried; entry; entry = entry->chain)
{ {
...@@ -370,7 +361,6 @@ read_counts_file (const char *name) ...@@ -370,7 +361,6 @@ read_counts_file (const char *name)
counts_entry_t **slot, *entry, elt; counts_entry_t **slot, *entry, elt;
unsigned n_counts = length / 8; unsigned n_counts = length / 8;
unsigned ix; unsigned ix;
gcov_type count;
elt.function_name = function_name_buffer; elt.function_name = function_name_buffer;
elt.section = tag; elt.section = tag;
...@@ -390,7 +380,8 @@ read_counts_file (const char *name) ...@@ -390,7 +380,8 @@ read_counts_file (const char *name)
else if (entry->checksum != checksum || entry->n_counts != n_counts) else if (entry->checksum != checksum || entry->n_counts != n_counts)
{ {
warning ("profile mismatch for `%s'", function_name_buffer); 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, /* This should always be true for a just allocated entry,
...@@ -402,15 +393,16 @@ read_counts_file (const char *name) ...@@ -402,15 +393,16 @@ read_counts_file (const char *name)
summaried = entry; summaried = entry;
} }
for (ix = 0; ix != n_counts; ix++) for (ix = 0; ix != n_counts; ix++)
{ entry->counts[ix] += gcov_read_counter ();
if (gcov_read_counter (&count)) }
goto corrupt; gcov_seek (offset, length);
entry->counts[ix] += count; 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); free (function_name_buffer);
...@@ -1007,42 +999,34 @@ branch_prob () ...@@ -1007,42 +999,34 @@ branch_prob ()
edge output the source and target basic block numbers. edge output the source and target basic block numbers.
NOTE: The format of this file must be compatible with gcov. */ NOTE: The format of this file must be compatible with gcov. */
if (gcov_ok ()) if (!gcov_is_error ())
{ {
long offset; long offset;
const char *file = DECL_SOURCE_FILE (current_function_decl); const char *file = DECL_SOURCE_FILE (current_function_decl);
unsigned line = DECL_SOURCE_LINE (current_function_decl); unsigned line = DECL_SOURCE_LINE (current_function_decl);
/* Announce function */ /* Announce function */
if (gcov_write_unsigned (GCOV_TAG_FUNCTION) offset = gcov_write_tag (GCOV_TAG_FUNCTION);
|| !(offset = gcov_reserve_length ()) gcov_write_string (name);
|| gcov_write_string (name) gcov_write_unsigned (profile_info.current_function_cfg_checksum);
|| gcov_write_unsigned (profile_info.current_function_cfg_checksum) gcov_write_string (file);
|| gcov_write_string (file) gcov_write_unsigned (line);
|| gcov_write_unsigned (line) gcov_write_length (offset);
|| gcov_write_length (offset))
goto bbg_error;
/* Basic block flags */ /* Basic block flags */
if (gcov_write_unsigned (GCOV_TAG_BLOCKS) offset = gcov_write_tag (GCOV_TAG_BLOCKS);
|| !(offset = gcov_reserve_length ()))
goto bbg_error;
for (i = 0; i != (unsigned) (n_basic_blocks + 2); i++) for (i = 0; i != (unsigned) (n_basic_blocks + 2); i++)
if (gcov_write_unsigned (0)) gcov_write_unsigned (0);
goto bbg_error; gcov_write_length (offset);
if (gcov_write_length (offset))
goto bbg_error;
/* Arcs */ /* Arcs */
FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, next_bb) FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, next_bb)
{ {
edge e; edge e;
if (gcov_write_unsigned (GCOV_TAG_ARCS) offset = gcov_write_tag (GCOV_TAG_ARCS);
|| !(offset = gcov_reserve_length ()) gcov_write_unsigned (BB_TO_GCOV_INDEX (bb));
|| gcov_write_unsigned (BB_TO_GCOV_INDEX (bb)))
goto bbg_error;
for (e = bb->succ; e; e = e->succ_next) for (e = bb->succ; e; e = e->succ_next)
{ {
struct edge_info *i = EDGE_INFO (e); struct edge_info *i = EDGE_INFO (e);
...@@ -1057,14 +1041,12 @@ branch_prob () ...@@ -1057,14 +1041,12 @@ branch_prob ()
if (e->flags & EDGE_FALLTHRU) if (e->flags & EDGE_FALLTHRU)
flag_bits |= GCOV_ARC_FALLTHROUGH; flag_bits |= GCOV_ARC_FALLTHROUGH;
if (gcov_write_unsigned (BB_TO_GCOV_INDEX (e->dest)) gcov_write_unsigned (BB_TO_GCOV_INDEX (e->dest));
|| gcov_write_unsigned (flag_bits)) gcov_write_unsigned (flag_bits);
goto bbg_error;
} }
} }
if (gcov_write_length (offset)) gcov_write_length (offset);
goto bbg_error;
} }
/* Output line number information about each basic block for /* Output line number information about each basic block for
...@@ -1104,13 +1086,12 @@ branch_prob () ...@@ -1104,13 +1086,12 @@ branch_prob ()
ignore_next_note = 0; ignore_next_note = 0;
else else
{ {
if (offset) if (!offset)
/*NOP*/; {
else if (gcov_write_unsigned (GCOV_TAG_LINES) offset = gcov_write_tag (GCOV_TAG_LINES);
|| !(offset = gcov_reserve_length ()) gcov_write_unsigned (BB_TO_GCOV_INDEX (bb));
|| (gcov_write_unsigned }
(BB_TO_GCOV_INDEX (bb))))
goto bbg_error;
/* If this is a new source file, then output /* If this is a new source file, then output
the file's name to the .bb file. */ the file's name to the .bb file. */
if (!prev_file_name if (!prev_file_name
...@@ -1118,12 +1099,10 @@ branch_prob () ...@@ -1118,12 +1099,10 @@ branch_prob ()
prev_file_name)) prev_file_name))
{ {
prev_file_name = NOTE_SOURCE_FILE (insn); prev_file_name = NOTE_SOURCE_FILE (insn);
if (gcov_write_unsigned (0) gcov_write_unsigned (0);
|| gcov_write_string (prev_file_name)) gcov_write_string (prev_file_name);
goto bbg_error;
} }
if (gcov_write_unsigned (NOTE_LINE_NUMBER (insn))) gcov_write_unsigned (NOTE_LINE_NUMBER (insn));
goto bbg_error;
} }
} }
insn = NEXT_INSN (insn); insn = NEXT_INSN (insn);
...@@ -1131,15 +1110,13 @@ branch_prob () ...@@ -1131,15 +1110,13 @@ branch_prob ()
if (offset) if (offset)
{ {
if (gcov_write_unsigned (0) /* A file of NULL indicates the end of run. */
|| gcov_write_string (NULL) gcov_write_unsigned (0);
|| gcov_write_length (offset)) gcov_write_string (NULL);
{ gcov_write_length (offset);
bbg_error:;
warning ("error writing `%s'", bbg_file_name);
gcov_error ();
}
} }
if (gcov_is_error ())
warning ("error writing `%s'", bbg_file_name);
} }
} }
} }
...@@ -1328,13 +1305,9 @@ init_branch_prob (filename) ...@@ -1328,13 +1305,9 @@ init_branch_prob (filename)
strcpy (bbg_file_name, filename); strcpy (bbg_file_name, filename);
strcat (bbg_file_name, GCOV_GRAPH_SUFFIX); strcat (bbg_file_name, GCOV_GRAPH_SUFFIX);
if (!gcov_open (bbg_file_name, -1)) if (!gcov_open (bbg_file_name, -1))
{ error ("cannot open %s", bbg_file_name);
error ("cannot open %s", bbg_file_name); gcov_write_unsigned (GCOV_GRAPH_MAGIC);
gcov_error (); gcov_write_unsigned (GCOV_VERSION);
}
else if (gcov_write_unsigned (GCOV_GRAPH_MAGIC)
|| gcov_write_unsigned (GCOV_VERSION))
gcov_error ();
} }
if (profile_arc_flag) if (profile_arc_flag)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment