gcov-io.h (GCOV_LOCKED): New #define.
authorNathan Sidwell <nathan@codesourcery.com>
Wed, 7 May 2003 10:40:09 +0000 (10:40 +0000)
committerNathan Sidwell <nathan@gcc.gnu.org>
Wed, 7 May 2003 10:40:09 +0000 (10:40 +0000)
* 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

gcc/ChangeLog
gcc/coverage.c
gcc/gcov-dump.c
gcc/gcov-io.c
gcc/gcov-io.h
gcc/gcov.c
gcc/libgcov.c

index 8a17bda..7b93205 100644 (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
index 36400f3..00da73c 100644 (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",
index 818c6ef..fb64243 100644 (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" :
index 2f2a87f..188d27a 100644 (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 */
 
index 19b43ab..2cad103 100644 (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 */
index 40e16cf..2225f02 100644 (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
index b85e09e..ed2d3d7 100644 (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;
-       }
     }
 }