gcov-io.h (GCOV_LOCKED): New #define.

* 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.

From-SVN: r66555
This commit is contained in:
Nathan Sidwell 2003-05-07 10:40:09 +00:00 committed by Nathan Sidwell
parent 6cbeaa7e52
commit 474f141e8d
7 changed files with 152 additions and 93 deletions

View File

@ -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

View File

@ -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",

View File

@ -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" :

View File

@ -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 */

View File

@ -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 */

View File

@ -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

View File

@ -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;
}
}
}