diff options
-rw-r--r-- | gcc/ChangeLog | 16 | ||||
-rw-r--r-- | gcc/coverage.c | 22 | ||||
-rw-r--r-- | gcc/gcov-dump.c | 7 | ||||
-rw-r--r-- | gcc/gcov-io.h | 20 | ||||
-rw-r--r-- | gcc/gcov.c | 13 | ||||
-rw-r--r-- | gcc/libgcov.c | 16 |
6 files changed, 80 insertions, 14 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index da3621f5076..5fa2546a82b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,21 @@ 2003-07-06 Nathan Sidwell <nathan@codesourcery.com> + * gcov-io.h: Add a local time stamp. + (struct gcov_info): Add stamp field. + (gcov_truncate): New. + * coverage.c (read_counts_file): Skip the stamp. + (coverage_begin_output): Write the stamp. + (build_gcov_info): Declare and init the stamp. + (coverage_finish): Only unlink data file, if stamp is zero. + * gcov-dump.c (dump_file): Dump the stamp. + * gcov.c (bbg_stamp): New. + (release_structures): Clear bbg_stamp. + (read_graph_file): Read stamp. + (read_count_file): Check stamp. + * libgcov.c (gcov_exit): Check stamp and truncate if needed. + +2003-07-06 Nathan Sidwell <nathan@codesourcery.com> + * tree.h (default_flag_random_seed): Remove. * toplev.h (local_tick): Declare. * tree.c (flag_random_seed, default_flag_random_seed): Move to diff --git a/gcc/coverage.c b/gcc/coverage.c index 7f0aa8da012..4a0033247ad 100644 --- a/gcc/coverage.c +++ b/gcc/coverage.c @@ -182,6 +182,9 @@ read_counts_file (void) return; } + /* Read and discard the stamp. */ + gcov_read_unsigned (); + counts_hash = htab_create (10, htab_counts_entry_hash, htab_counts_entry_eq, htab_counts_entry_del); @@ -445,6 +448,7 @@ coverage_begin_output (void) { gcov_write_unsigned (GCOV_GRAPH_MAGIC); gcov_write_unsigned (GCOV_VERSION); + gcov_write_unsigned (local_tick); } bbg_file_opened = 1; } @@ -708,6 +712,14 @@ build_gcov_info (void) fields = field; value = tree_cons (field, null_pointer_node, value); + /* stamp */ + field = build_decl (FIELD_DECL, NULL_TREE, unsigned_intSI_type_node); + TREE_CHAIN (field) = fields; + fields = field; + value = tree_cons (field, convert (unsigned_intSI_type_node, + build_int_2 (local_tick, 0)), + value); + /* Filename */ string_type = build_pointer_type (build_qualified_type (char_type_node, TYPE_QUAL_CONST)); @@ -905,13 +917,9 @@ coverage_finish (void) if (error) unlink (bbg_file_name); -#if SELF_COVERAGE - /* If the compiler is instrumented, we should not - unconditionally remove the counts file, because we might be - recompiling ourselves. The .da files are all removed during - copying the stage1 files. */ - if (error) -#endif + if (!local_tick) + /* Only remove the da file, if we cannot stamp it. If we can + stamp it, libgcov will DTRT. */ unlink (da_file_name); } } diff --git a/gcc/gcov-dump.c b/gcc/gcov-dump.c index 86834e25b7b..67a34dcfff7 100644 --- a/gcc/gcov-dump.c +++ b/gcc/gcov-dump.c @@ -184,6 +184,13 @@ dump_file (const char *filename) printf ("%s:warning:current version is `%.4s'\n", filename, e); } + /* stamp */ + { + unsigned stamp = gcov_read_unsigned (); + + printf ("%s:stamp %lu\n", filename, (unsigned long)stamp); + } + while (1) { gcov_position_t base, position = gcov_position (); diff --git a/gcc/gcov-io.h b/gcc/gcov-io.h index 5d0b716c7f1..999d07eea08 100644 --- a/gcc/gcov-io.h +++ b/gcc/gcov-io.h @@ -52,11 +52,17 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA The basic format of the files is - file : int32:magic int32:version record* + file : int32:magic int32:version int32:stamp record* The magic ident is different for the bbg and the counter files. The version is the same for both files and is derived from gcc's - version number. Although the ident and version are formally 32 bit + version number. The stamp value is used to synchronize bbg and + counter files and to synchronize merging within a counter file. It + need not be an absolute time stamp, merely a ticker that increments + fast enough and cycles slow enough to distinguish different + compile/run/compile cycles. + + Although the ident and version are formally 32 bit numbers, they are derived from 4 character ASCII strings. The version number consists of the single character major version number, a two character minor version number (leading zero for @@ -370,8 +376,9 @@ struct gcov_info gcov_unsigned_t version; /* expected version number */ struct gcov_info *next; /* link to next, used by libgcc */ + gcov_unsigned_t stamp; /* uniquifying time stamp */ const char *filename; /* output file name */ - + unsigned n_functions; /* number of functions */ const struct gcov_fn_info *functions; /* table of functions */ @@ -453,6 +460,7 @@ GCOV_LINKAGE void gcov_write_counter (gcov_type); GCOV_LINKAGE void gcov_write_tag_length (gcov_unsigned_t, gcov_unsigned_t); GCOV_LINKAGE void gcov_write_summary (gcov_unsigned_t /*tag*/, const struct gcov_summary *); +static void gcov_truncate (void); static void gcov_rewrite (void); GCOV_LINKAGE void gcov_seek (gcov_position_t /*position*/); #else @@ -525,6 +533,12 @@ gcov_rewrite (void) gcov_var.offset = 0; fseek (gcov_var.file, 0L, SEEK_SET); } + +static inline void +gcov_truncate (void) +{ + ftruncate (fileno (gcov_var.file), 0L); +} #endif #endif /* IN_LIBGCOV >= 0 */ diff --git a/gcc/gcov.c b/gcc/gcov.c index c671599c886..c8fc6ad5d31 100644 --- a/gcc/gcov.c +++ b/gcc/gcov.c @@ -269,6 +269,9 @@ static time_t bbg_file_time; static char *bbg_file_name; +/* Stamp of the bbg file */ +static unsigned bbg_stamp; + /* Name and file pointer of the input file for the arc count data. */ static char *da_file_name; @@ -583,6 +586,7 @@ release_structures () free (da_file_name); da_file_name = bbg_file_name = NULL; bbg_file_time = 0; + bbg_stamp = 0; while ((src = sources)) { @@ -740,7 +744,8 @@ read_graph_file () fnotice (stderr, "%s:version `%.4s', prefer `%.4s'\n", bbg_file_name, v, e); } - + bbg_stamp = gcov_read_unsigned (); + while ((tag = gcov_read_unsigned ())) { unsigned length = gcov_read_unsigned (); @@ -1008,6 +1013,12 @@ read_count_file () fnotice (stderr, "%s:version `%.4s', prefer version `%.4s'\n", da_file_name, v, e); } + tag = gcov_read_unsigned (); + if (tag != bbg_stamp) + { + fnotice (stderr, "%s:stamp mismatch with graph file\n", da_file_name); + goto cleanup; + } while ((tag = gcov_read_unsigned ())) { diff --git a/gcc/libgcov.c b/gcc/libgcov.c index 74d830dc1b0..72126466f66 100644 --- a/gcc/libgcov.c +++ b/gcc/libgcov.c @@ -167,8 +167,10 @@ gcov_exit (void) gcov_unsigned_t tag, length; gcov_position_t summary_pos = 0; - /* Totals for this object file. */ memset (&this_object, 0, sizeof (this_object)); + memset (&object, 0, sizeof (object)); + + /* Totals for this object file. */ for (t_ix = c_ix = 0, ci_ptr = gi_ptr->counts, cs_ptr = this_object.ctrs; t_ix != GCOV_COUNTERS_SUMMABLE; t_ix++, cs_ptr++) @@ -223,6 +225,15 @@ gcov_exit (void) gcov_version_mismatch (gi_ptr, length); goto read_fatal; } + + length = gcov_read_unsigned (); + if (length != gi_ptr->stamp) + { + /* Read from a different compilation. Overwrite the + file. */ + gcov_truncate (); + goto rewrite; + } /* Merge execution counts for each function. */ for (f_ix = gi_ptr->n_functions, fi_ptr = gi_ptr->functions; @@ -298,8 +309,6 @@ gcov_exit (void) rewrite:; gcov_rewrite (); } - else - memset (&object, 0, sizeof (object)); if (!summary_pos) memset (&program, 0, sizeof (program)); @@ -355,6 +364,7 @@ gcov_exit (void) /* Write out the data. */ gcov_write_tag_length (GCOV_DATA_MAGIC, GCOV_VERSION); + gcov_write_unsigned (gi_ptr->stamp); /* Write execution counts for each function. */ for (f_ix = gi_ptr->n_functions, fi_ptr = gi_ptr->functions; f_ix--; |