summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog26
-rw-r--r--gcc/coverage.c2
-rw-r--r--gcc/gcov-dump.c2
-rw-r--r--gcc/gcov-io.c33
-rw-r--r--gcc/gcov-io.h68
-rw-r--r--gcc/gcov.c4
-rw-r--r--gcc/libgcov.c110
7 files changed, 152 insertions, 93 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 8a17bdadeaa..7b932059cfa 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,29 @@
+2003-05-07 Nathan Sidwell <nathan@codesourcery.com>
+
+ * gcov-io.h (GCOV_LOCKED): New #define.
+ (GCOV_LINKAGE): Make sure it is #defined.
+ (gcov_write_string, gcov_write_tag, gcov_write_length,
+ gcov_read_string, gcov_time): Poison in libgcov.
+ (gcov_seek_end): Remove.
+ (gcov_write_tag_length, gcov_sync, gcov_rewrite): New.
+ (GCOV_TAG_FUNCTION_LENGTH, GCOV_TAG_BLOCKS_LENGTH,
+ GCOV_TAG_ARCS_LENGTH, GCOV_TAG_COUNTER_LENGTH,
+ GCOV_TAG_SUMMARY_LENGTH): New #defines.
+ (gcov_write_tag, gcov_write_length): Not in libgcov.
+ * gcov-io.c (gcov_open): Use GCOV_LOCKED.
+ (gcov_write_tag, gcov_write_length): Not in libgcov.
+ (gcov_write_tag_length): New.
+ (gcov_write_summary): Use gcov_write_tag_length.
+ * libgcov.c: Always #include gcov-io.h.
+ (IN_LIBGCOV): -1 for inhibit_libc, +1 otherwise.
+ (GCOV_LINKAGE): Define to nothing for L_gcov.
+ (gcov_exit): Replace gcov_write_tag, gcov_write_length with
+ gcov_write_tag_length. Use gcov_rewrite & gcov_seek.
+ * gcov.c (read_graph_file): Replace gcov_seek by gcov_sync.
+ (read_count_file): Likewise.
+ * gcov-dump.c (dump_file): Likewise.
+ * coverag.c (read_counts_file): Likewise.
+
2003-05-06 Mark Mitchell <mark@codesourcery.com>
PR other/10658
diff --git a/gcc/coverage.c b/gcc/coverage.c
index 36400f32e9c..00da73c7d12 100644
--- a/gcc/coverage.c
+++ b/gcc/coverage.c
@@ -271,7 +271,7 @@ read_counts_file ()
for (ix = 0; ix != n_counts; ix++)
entry->counts[ix] += gcov_read_counter ();
}
- gcov_seek (offset, length);
+ gcov_sync (offset, length);
if ((error = gcov_is_error ()))
{
warning (error < 0 ? "`%s' has overflowed" : "`%s' is corrupted",
diff --git a/gcc/gcov-dump.c b/gcc/gcov-dump.c
index 818c6efed11..fb64243ab83 100644
--- a/gcc/gcov-dump.c
+++ b/gcc/gcov-dump.c
@@ -237,7 +237,7 @@ dump_file (filename)
printf ("%s:record size mismatch %lu bytes unread\n",
filename, length - actual_length);
}
- gcov_seek (base, length);
+ gcov_sync (base, length);
if ((error = gcov_is_error ()))
{
printf (error < 0 ? "%s:counter overflow at %lu\n" :
diff --git a/gcc/gcov-io.c b/gcc/gcov-io.c
index 2f2a87fdb21..188d27a1bc4 100644
--- a/gcc/gcov-io.c
+++ b/gcc/gcov-io.c
@@ -37,7 +37,7 @@ gcov_open (const char *name, int mode)
{
int result = 1;
size_t alloc = 1024;
-#if defined (TARGET_HAS_F_SETLKW) && IN_LIBGCOV
+#if GCOV_LOCKED
struct flock s_flock;
s_flock.l_type = F_WRLCK;
@@ -61,7 +61,7 @@ gcov_open (const char *name, int mode)
if (!gcov_var.file)
return 0;
-#if defined (TARGET_HAS_F_SETLKW) && IN_LIBGCOV
+#if GCOV_LOCKED
while (fcntl (fileno (gcov_var.file), F_SETLKW, &s_flock)
&& errno == EINTR)
continue;
@@ -257,6 +257,7 @@ gcov_write_string (const char *string)
}
#endif
+#if !IN_LIBGCOV
/* Write a tag TAG and reserve space for the record length. Return a
value to be used for gcov_write_length. */
@@ -299,6 +300,30 @@ gcov_write_length (unsigned long position)
}
}
}
+#endif
+
+/* Write a tag TAG and length LENGTH. */
+
+GCOV_LINKAGE void
+gcov_write_tag_length (unsigned tag, unsigned length)
+{
+ unsigned char *buffer = gcov_write_bytes (8);
+ unsigned ix;
+
+ if (!buffer)
+ return;
+ for (ix = 4; ix--; )
+ {
+ buffer[ix] = tag;
+ tag >>= 8;
+ }
+ for (ix = 4; ix--; )
+ {
+ buffer[ix + 4] = length;
+ length >>= 8;
+ }
+ return;
+}
#if IN_LIBGCOV
/* Write a summary structure to the gcov file. Return non-zero on
@@ -309,9 +334,8 @@ gcov_write_summary (unsigned tag, const struct gcov_summary *summary)
{
unsigned ix;
const struct gcov_ctr_summary *csum;
- unsigned long base;
- base = gcov_write_tag (tag);
+ gcov_write_tag_length (tag, GCOV_TAG_SUMMARY_LENGTH);
gcov_write_unsigned (summary->checksum);
for (csum = summary->ctrs, ix = GCOV_COUNTERS; ix--; csum++)
{
@@ -321,7 +345,6 @@ gcov_write_summary (unsigned tag, const struct gcov_summary *summary)
gcov_write_counter (csum->run_max);
gcov_write_counter (csum->sum_max);
}
- gcov_write_length (base);
}
#endif /* IN_LIBGCOV */
diff --git a/gcc/gcov-io.h b/gcc/gcov-io.h
index 19b43aba35f..2cad103f231 100644
--- a/gcc/gcov-io.h
+++ b/gcc/gcov-io.h
@@ -168,13 +168,20 @@ typedef long long gcov_type;
#else
#define GCOV_LOCKED 0
#endif
-#endif /* IN_LIBGCOV */
+#else /* !IN_LIBGCOV */
+#if defined (HOST_HAS_F_SETLKW)
+#define GCOV_LOCKED 1
+#else
+#define GCOV_LOCKED 0
+#endif
#if IN_GCOV
+#define GCOV_LINKAGE static
typedef HOST_WIDEST_INT gcov_type;
#if IN_GCOV > 0
#include <sys/types.h>
#endif
#endif
+#endif /* !IN_LIBGCOV */
/* In gcov we want function linkage to be static, so we do not
polute the global namespace. In libgcov we need these functions
@@ -182,42 +189,35 @@ typedef HOST_WIDEST_INT gcov_type;
In the compiler we want it extern, so that they can be accessed from
elsewhere. */
#if IN_LIBGCOV
-
-#define GCOV_LINKAGE /* nothing */
#define gcov_var __gcov_var
#define gcov_open __gcov_open
#define gcov_close __gcov_close
#define gcov_write_bytes __gcov_write_bytes
#define gcov_write_unsigned __gcov_write_unsigned
#define gcov_write_counter __gcov_write_counter
-#define gcov_write_string __gcov_write_string
-#define gcov_write_tag __gcov_write_tag
-#define gcov_write_length __gcov_write_length
+#pragma GCC poison gcov_write_string
+#pragma GCC poison gcov_write_tag
+#pragma GCC poison gcov_write_length
+#define gcov_write_tag_length __gcov_write_tag_length
#define gcov_write_summary __gcov_write_summary
#define gcov_read_bytes __gcov_read_bytes
#define gcov_read_unsigned __gcov_read_unsigned
#define gcov_read_counter __gcov_read_counter
-#define gcov_read_string __gcov_read_string
+#pragma GCC poison gcov_read_string
#define gcov_read_summary __gcov_read_summary
#define gcov_position __gcov_position
+#define gcov_sync __gcov_sync
#define gcov_seek __gcov_seek
-#define gcov_seek_end __gcov_seek_end
+#define gcov_rewrite __gcov_rewrite
#define gcov_is_eof __gcov_is_eof
#define gcov_is_error __gcov_is_error
-#define gcov_time __gcov_time
-
-#elif IN_GCOV
-
-#define GCOV_LINKAGE static
-
-#else /* !IN_LIBGCOV && !IN_GCOV */
+#pragma GCC poison gcov_time
+#endif
#ifndef GCOV_LINKAGE
#define GCOV_LINKAGE extern
#endif
-#endif
-
/* File suffixes. */
#define GCOV_DATA_SUFFIX ".da"
#define GCOV_GRAPH_SUFFIX ".bbg"
@@ -237,12 +237,17 @@ typedef HOST_WIDEST_INT gcov_type;
the data file. */
#define GCOV_TAG_FUNCTION ((unsigned)0x01000000)
+#define GCOV_TAG_FUNCTION_LENGTH (2 * 4)
#define GCOV_TAG_BLOCKS ((unsigned)0x01410000)
+#define GCOV_TAG_BLOCKS_LENGTH(NUM) ((NUM) * 4)
#define GCOV_TAG_ARCS ((unsigned)0x01430000)
+#define GCOV_TAG_ARCS_LENGTH(NUM) (1 * 4 + (NUM) * (2 * 4))
#define GCOV_TAG_LINES ((unsigned)0x01450000)
#define GCOV_TAG_COUNTER_BASE ((unsigned)0x01a10000) /* First counter */
+#define GCOV_TAG_COUNTER_LENGTH(NUM) ((NUM) * 8)
#define GCOV_TAG_OBJECT_SUMMARY ((unsigned)0xa1000000)
#define GCOV_TAG_PROGRAM_SUMMARY ((unsigned)0xa3000000)
+#define GCOV_TAG_SUMMARY_LENGTH (1 * 4 + GCOV_COUNTERS * (2 * 4 + 3 * 8))
/* Counters that are collected. */
#define GCOV_COUNTER_ARCS 0 /* Arc transitions. */
@@ -359,6 +364,8 @@ extern void __gcov_flush (void);
extern void __gcov_merge_add (gcov_type *, unsigned);
#endif /* IN_LIBGCOV */
+#if IN_LIBGCOV >= 0
+
/* Because small reads and writes, interspersed with seeks cause lots
of disk activity, we buffer the entire count files. */
@@ -384,8 +391,11 @@ GCOV_LINKAGE void gcov_write_counter (gcov_type);
#else
GCOV_LINKAGE void gcov_write_string (const char *);
#endif
+#if !IN_LIBGCOV
GCOV_LINKAGE unsigned long gcov_write_tag (unsigned);
GCOV_LINKAGE void gcov_write_length (unsigned long /*position*/);
+#endif
+GCOV_LINKAGE void gcov_write_tag_length (unsigned, unsigned);
#if IN_LIBGCOV
GCOV_LINKAGE void gcov_write_summary (unsigned, const struct gcov_summary *);
#endif
@@ -398,8 +408,9 @@ GCOV_LINKAGE const char *gcov_read_string (void);
#endif
GCOV_LINKAGE 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 void gcov_sync (unsigned long /*base*/, unsigned /*length */);
+static void gcov_seek (unsigned long /*position*/);
+static void gcov_rewrite (void);
static int gcov_is_eof (void);
static int gcov_is_error (void);
#if IN_GCOV > 0
@@ -418,7 +429,7 @@ gcov_position (void)
gcov_save_position, LENGTH should be a record length, or zero. */
static inline void
-gcov_seek (unsigned long base, unsigned length)
+gcov_sync (unsigned long base, unsigned length)
{
if (gcov_var.buffer)
{
@@ -434,11 +445,18 @@ gcov_seek (unsigned long base, unsigned length)
/* Move to the end of the gcov file. */
-static inline unsigned long
-gcov_seek_end ()
+static inline void
+gcov_seek (unsigned long base)
{
- gcov_var.position = gcov_var.length;
- return gcov_var.position;
+ gcov_var.position = base < gcov_var.length ? base : gcov_var.length;
+}
+
+/* Move to beginning of file and intialize for writing. */
+
+static inline void
+gcov_rewrite (void)
+{
+ gcov_var.position = 0;
}
/* Tests whether we have reached end of .da file. */
@@ -457,4 +475,6 @@ gcov_is_error ()
return gcov_var.file ? gcov_var.error : 1;
}
+#endif /* IN_LIBGCOV >= 0 */
+
#endif /* GCC_GCOV_IO_H */
diff --git a/gcc/gcov.c b/gcc/gcov.c
index 40e16cf92ed..2225f02f9ab 100644
--- a/gcc/gcov.c
+++ b/gcc/gcov.c
@@ -904,7 +904,7 @@ read_graph_file ()
fn = NULL;
current_tag = 0;
}
- gcov_seek (base, length);
+ gcov_sync (base, length);
if (gcov_is_error ())
{
corrupt:;
@@ -1059,7 +1059,7 @@ read_count_file ()
for (ix = 0; ix != fn->num_counts; ix++)
fn->counts[ix] += gcov_read_counter ();
}
- gcov_seek (base, length);
+ gcov_sync (base, length);
if ((error = gcov_is_error ()))
{
fnotice (stderr, error < 0
diff --git a/gcc/libgcov.c b/gcc/libgcov.c
index b85e09e1ada..ed2d3d7d1d7 100644
--- a/gcc/libgcov.c
+++ b/gcc/libgcov.c
@@ -29,25 +29,6 @@ along with GCC; see the file COPYING. If not, write to the Free
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
-#if defined(inhibit_libc)
-/* If libc and its header files are not available, provide dummy functions. */
-
-#ifdef L_gcov
-void __gcov_init (void *p);
-void __gcov_flush (void);
-
-void __gcov_init (void *p) { }
-void __gcov_flush (void) { }
-#endif
-
-#ifdef L_gcov_merge_add
-void __gcov_merge_add (void *, unsigned);
-
-void __gcov_merge_add (void *counters, unsigned n_counters) { }
-#endif
-
-#else
-
/* It is incorrect to include config.h here, because this file is being
compiled for the target, and hence definitions concerning only the host
do not apply. */
@@ -57,16 +38,38 @@ void __gcov_merge_add (void *counters, unsigned n_counters) { }
#include "coretypes.h"
#include "tm.h"
+#if defined(inhibit_libc)
+#define IN_LIBGCOV (-1)
+#else
#undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
#include <stdio.h>
+#define IN_LIBGCOV 1
+#if defined(L_gcov)
+#define GCOV_LINKAGE /* nothing */
+#endif
+#endif
+#include "gcov-io.h"
+
+#if defined(inhibit_libc)
+/* If libc and its header files are not available, provide dummy functions. */
+
+#ifdef L_gcov
+void __gcov_init (struct gcov_info *p __attribute__ ((unused))) {}
+void __gcov_flush (void) {}
+#endif
+
+#ifdef L_gcov_merge_add
+void __gcov_merge_add (gcov_type *counters __attribute__ ((unused)),
+ unsigned n_counters __attribute__ ((unused))) {}
+#endif
+
+#else
#include <string.h>
-#if defined (TARGET_HAS_F_SETLKW)
+#if GCOV_LOCKED
#include <fcntl.h>
#include <errno.h>
#endif
-#define IN_LIBGCOV 1
-#include "gcov-io.h"
#ifdef L_gcov
#include "gcov-io.c"
@@ -151,9 +154,8 @@ gcov_exit (void)
struct gcov_ctr_summary *cs_obj, *cs_tobj, *cs_prg, *cs_tprg, *cs_all;
int error;
int merging;
- unsigned long base;
unsigned tag, length;
- unsigned long summary_pos = 0;
+ unsigned long summary_pos = ~0UL;
/* Totals for this object file. */
memset (&this_object, 0, sizeof (this_object));
@@ -223,6 +225,7 @@ gcov_exit (void)
/* Check function */
if (tag != GCOV_TAG_FUNCTION
+ || length != GCOV_TAG_FUNCTION_LENGTH
|| gcov_read_unsigned () != fi_ptr->ident
|| gcov_read_unsigned () != fi_ptr->checksum)
{
@@ -236,17 +239,14 @@ gcov_exit (void)
for (c_ix = t_ix = 0; t_ix != GCOV_COUNTERS; t_ix++)
if ((1 << t_ix) & gi_ptr->ctr_mask)
{
- unsigned n_counts;
- gcov_merge_fn merge;
+ unsigned n_counts = fi_ptr->n_ctrs[c_ix];
+ gcov_merge_fn merge = gi_ptr->counts[c_ix].merge;
tag = gcov_read_unsigned ();
length = gcov_read_unsigned ();
-
if (tag != GCOV_TAG_FOR_COUNTER (t_ix)
- || fi_ptr->n_ctrs[c_ix] * 8 != length)
+ || length != GCOV_TAG_COUNTER_LENGTH (n_counts))
goto read_mismatch;
- n_counts = fi_ptr->n_ctrs[c_ix];
- merge = gi_ptr->counts[c_ix].merge;
(*merge) (values[c_ix], n_counts);
values[c_ix] += n_counts;
c_ix++;
@@ -255,41 +255,38 @@ gcov_exit (void)
goto read_error;
}
- /* Check object summary */
- if (gcov_read_unsigned () != GCOV_TAG_OBJECT_SUMMARY)
- goto read_mismatch;
- gcov_read_unsigned ();
- gcov_read_summary (&object);
-
- /* Check program summary */
+ /* Check program & object summary */
while (!gcov_is_eof ())
{
- base = gcov_position ();
+ unsigned long base = gcov_position ();
+ int is_program;
+
tag = gcov_read_unsigned ();
- gcov_read_unsigned ();
- if (tag != GCOV_TAG_PROGRAM_SUMMARY)
+ length = gcov_read_unsigned ();
+ is_program = tag == GCOV_TAG_PROGRAM_SUMMARY;
+ if (length != GCOV_TAG_SUMMARY_LENGTH
+ || (!is_program && tag != GCOV_TAG_OBJECT_SUMMARY))
goto read_mismatch;
- gcov_read_summary (&program);
+ gcov_read_summary (is_program ? &program : &object);
if ((error = gcov_is_error ()))
{
read_error:;
fprintf (stderr, error < 0 ?
"profiling:%s:Overflow merging\n" :
- "profiling:%s:Error merging\n",
- gi_ptr->filename);
+ "profiling:%s:Error merging\n", gi_ptr->filename);
goto read_fatal;
}
- if (program.checksum != gcov_crc32)
+ if (!is_program || program.checksum != gcov_crc32)
continue;
summary_pos = base;
break;
}
- gcov_seek (0, 0);
+ gcov_rewrite ();
}
else
memset (&object, 0, sizeof (object));
- if (!summary_pos)
+ if (!(summary_pos + 1))
memset (&program, 0, sizeof (program));
/* Merge the summaries. */
@@ -352,23 +349,22 @@ gcov_exit (void)
((const char *) fi_ptr + fi_stride))
{
/* Announce function. */
- base = gcov_write_tag (GCOV_TAG_FUNCTION);
+ gcov_write_tag_length (GCOV_TAG_FUNCTION, GCOV_TAG_FUNCTION_LENGTH);
gcov_write_unsigned (fi_ptr->ident);
gcov_write_unsigned (fi_ptr->checksum);
- gcov_write_length (base);
for (c_ix = t_ix = 0; t_ix != GCOV_COUNTERS; t_ix++)
if ((1 << t_ix) & gi_ptr->ctr_mask)
{
- unsigned n_counts;
+ unsigned n_counts = fi_ptr->n_ctrs[c_ix];
gcov_type *c_ptr;
- base = gcov_write_tag (GCOV_TAG_FOR_COUNTER (t_ix));
+ gcov_write_tag_length (GCOV_TAG_FOR_COUNTER (t_ix),
+ GCOV_TAG_COUNTER_LENGTH (n_counts));
c_ptr = values[c_ix];
- for (n_counts = fi_ptr->n_ctrs[c_ix]; n_counts--; c_ptr++)
- gcov_write_counter (*c_ptr);
+ while (n_counts--)
+ gcov_write_counter (*c_ptr++);
values[c_ix] = c_ptr;
- gcov_write_length (base);
c_ix++;
}
}
@@ -377,19 +373,13 @@ gcov_exit (void)
gcov_write_summary (GCOV_TAG_OBJECT_SUMMARY, &object);
/* Generate whole program statistics. */
- if (summary_pos)
- gcov_seek (summary_pos, 0);
- else
- gcov_seek_end ();
+ gcov_seek (summary_pos);
gcov_write_summary (GCOV_TAG_PROGRAM_SUMMARY, &program);
if ((error = gcov_close ()))
- {
fprintf (stderr, error < 0 ?
"profiling:%s:Overflow writing\n" :
"profiling:%s:Error writing\n",
gi_ptr->filename);
- gi_ptr->filename = 0;
- }
}
}