diff options
-rw-r--r-- | gcc/ChangeLog | 34 | ||||
-rw-r--r-- | gcc/Makefile.in | 4 | ||||
-rw-r--r-- | gcc/gcov-dump.c | 167 | ||||
-rw-r--r-- | gcc/gcov-io.h | 480 | ||||
-rw-r--r-- | gcc/gcov.c | 193 | ||||
-rw-r--r-- | gcc/libgcov.c | 141 | ||||
-rw-r--r-- | gcc/profile.c | 151 |
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; @@ -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) |