aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog34
-rw-r--r--gcc/Makefile.in4
-rw-r--r--gcc/gcov-dump.c167
-rw-r--r--gcc/gcov-io.h480
-rw-r--r--gcc/gcov.c193
-rw-r--r--gcc/libgcov.c141
-rw-r--r--gcc/profile.c151
7 files changed, 516 insertions, 654 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 0277521..ca55295 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 6b9e64f..1ab232f 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -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 \
diff --git a/gcc/gcov-dump.c b/gcc/gcov-dump.c
index 5ca64a4..ba56fee 100644
--- a/gcc/gcov-dump.c
+++ b/gcc/gcov-dump.c
@@ -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;
-
- if (gcov_save_position () - pos != length
- && (gcov_read_string (&src)
- || gcov_read_unsigned (&lineno)))
- return 1;
+ name = gcov_read_string ();
+ printf (" `%s'", name ? name : "NULL");
+ printf (" checksum=0x%08x", gcov_read_unsigned ());
- 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;
}
diff --git a/gcc/gcov-io.h b/gcc/gcov-io.h
index 04a01ac..3bd2729 100644
--- a/gcc/gcov-io.h
+++ b/gcc/gcov-io.h
@@ -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. */
-
- 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;
+ unsigned long base;
+
+ 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. 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. */
+/* 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. */
-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;
diff --git a/gcc/gcov.c b/gcc/gcov.c
index 5a2f429..b6cbbc8 100644
--- a/gcc/gcov.c
+++ b/gcc/gcov.c
@@ -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;
}
diff --git a/gcc/libgcov.c b/gcc/libgcov.c
index 37d3e80..ea197f8 100644
--- a/gcc/libgcov.c
+++ b/gcc/libgcov.c
@@ -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);
}
}
diff --git a/gcc/profile.c b/gcc/profile.c
index ec53065..7593144 100644
--- a/gcc/profile.c
+++ b/gcc/profile.c
@@ -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)