OSDN Git Service

Add Zem as Objective-C++ maintainer per Joe Buck.
[pf3gnuchains/gcc-fork.git] / gcc / gcov-io.h
index 35c31b9..2b49dcf 100644 (file)
@@ -1,6 +1,6 @@
 /* File format for coverage information
    Copyright (C) 1996, 1997, 1998, 2000, 2002,
-   2003 Free Software Foundation, Inc.
+   2003, 2004 Free Software Foundation, Inc.
    Contributed by Bob Manson <manson@cygnus.com>.
    Completely remangled by Nathan Sidwell <nathan@codesourcery.com>.
 
@@ -29,21 +29,21 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
    the executable file might be covered by the GNU General Public License.  */
 
 /* Coverage information is held in two files.  A notes file, which is
-   generated by the compiler, and a data file, which is generated
-   by the program under test.  Both files use a similar structure.  We
-   do not attempt to make these files backwards compatible with
-   previous versions, as you only need coverage information when
-   developing a program.  We do hold version information, so that
-   mismatches can be detected, and we use a format that allows tools
-   to skip information they do not understand or are not interested
-   in.
+   generated by the compiler, and a data file, which is generated by
+   the program under test.  Both files use a similar structure.  We do
+   not attempt to make these files backwards compatible with previous
+   versions, as you only need coverage information when developing a
+   program.  We do hold version information, so that mismatches can be
+   detected, and we use a format that allows tools to skip information
+   they do not understand or are not interested in.
 
    Numbers are recorded in the 32 bit unsigned binary form of the
    endianness of the machine generating the file. 64 bit numbers are
    stored as two 32 bit numbers, the low part first.  Strings are
-   stored as length rounded up to 4 followed by the string and then 1
-   to 4 NUL bytes.  Zero length and NULL strings are simply stored as
-   a length of zero (they have no trailing NUL or padding).
+   padded with 1 to 4 NUL bytes, to bring the length up to a multiple
+   of 4. The number of 4 bytes is stored, followed by the padded
+   string. Zero length and NULL strings are simply stored as a length
+   of zero (they have no trailing NUL or padding).
 
        int32:  byte3 byte2 byte1 byte0 | byte0 byte1 byte2 byte3
        int64:  int32:low int32:high
@@ -89,16 +89,17 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
    Records are not nested, but there is a record hierarchy.  Tag
    numbers reflect this hierarchy.  Tags are unique across note and
    data files.  Some record types have a varying amount of data.  The
-   LENGTH is usually used to determine how much data.  The tag value
-   is split into 4 8-bit fields, one for each of four possible levels.
-   The most significant is allocated first.  Unused levels are zero.
-   Active levels are odd-valued, so that the LSB of the level is one.
-   A sub-level incorporates the values of its superlevels.  This
-   formatting allows you to determine the tag hierarchy, without
-   understanding the tags themselves, and is similar to the standard
-   section numbering used in technical documents.  Level values
-   [1..3f] are used for common tags, values [41..9f] for the notes
-   file and [a1..ff] for the data file.
+   LENGTH is the number of 4bytes that follow and is usually used to
+   determine how much data.  The tag value is split into 4 8-bit
+   fields, one for each of four possible levels.  The most significant
+   is allocated first.  Unused levels are zero.  Active levels are
+   odd-valued, so that the LSB of the level is one.  A sub-level
+   incorporates the values of its superlevels.  This formatting allows
+   you to determine the tag hierarchy, without understanding the tags
+   themselves, and is similar to the standard section numbering used
+   in technical documents.  Level values [1..3f] are used for common
+   tags, values [41..9f] for the notes file and [a1..ff] for the data
+   file.
 
    The basic block graph file contains the following records
        note: unit function-graph*
@@ -146,7 +147,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
    program.  The checksum is used for whole program summaries, and
    disambiguates different programs which include the same
    instrumented object file.  There may be several program summaries,
-   each with a unique checksum.  The object summary's checkum is zero.
+   each with a unique checksum.  The object summary's checksum is zero.
    Note that the data file might contain information from several runs
    concatenated, or the data might be merged.
 
@@ -165,6 +166,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #if IN_LIBGCOV
 /* About the target */
 
+#if BITS_PER_UNIT == 8
 typedef unsigned gcov_unsigned_t __attribute__ ((mode (SI)));
 typedef unsigned gcov_position_t __attribute__ ((mode (SI)));
 #if LONG_LONG_TYPE_SIZE > 32
@@ -172,6 +174,26 @@ typedef signed gcov_type __attribute__ ((mode (DI)));
 #else
 typedef signed gcov_type __attribute__ ((mode (SI)));
 #endif
+#else
+#if BITS_PER_UNIT == 16
+typedef unsigned gcov_unsigned_t __attribute__ ((mode (HI)));
+typedef unsigned gcov_position_t __attribute__ ((mode (HI)));
+#if LONG_LONG_TYPE_SIZE > 32
+typedef signed gcov_type __attribute__ ((mode (SI)));
+#else
+typedef signed gcov_type __attribute__ ((mode (HI)));
+#endif
+#else
+typedef unsigned gcov_unsigned_t __attribute__ ((mode (QI)));
+typedef unsigned gcov_position_t __attribute__ ((mode (QI)));
+#if LONG_LONG_TYPE_SIZE > 32
+typedef signed gcov_type __attribute__ ((mode (HI)));
+#else
+typedef signed gcov_type __attribute__ ((mode (QI)));
+#endif
+#endif
+#endif
+
 
 #if defined (TARGET_HAS_F_SETLKW)
 #define GCOV_LOCKED 1
@@ -192,11 +214,7 @@ typedef HOST_WIDEST_INT gcov_type;
 #include <sys/types.h>
 #endif
 #else /*!IN_GCOV */
-#if LONG_LONG_TYPE_SIZE > 32
-#define GCOV_TYPE_NODE intDI_type_node
-#else
-#define GCOV_TYPE_NODE intSI_type_node
-#endif
+#define GCOV_TYPE_SIZE (LONG_LONG_TYPE_SIZE > 32 ? 64 : 32)
 #endif
 
 #if defined (HOST_HAS_F_SETLKW)
@@ -220,7 +238,6 @@ typedef HOST_WIDEST_INT gcov_type;
 #define gcov_seek __gcov_seek
 #define gcov_rewrite __gcov_rewrite
 #define gcov_is_error __gcov_is_error
-#define gcov_is_eof __gcov_is_eof
 #define gcov_write_unsigned __gcov_write_unsigned
 #define gcov_write_counter __gcov_write_counter
 #define gcov_write_summary __gcov_write_summary
@@ -252,35 +269,57 @@ typedef HOST_WIDEST_INT gcov_type;
 */
 #include "gcov-iov.h"
 
+/* Convert a magic or version number to a 4 character string.  */
+#define GCOV_UNSIGNED2STRING(ARRAY,VALUE)      \
+  ((ARRAY)[0] = (char)((VALUE) >> 24),         \
+   (ARRAY)[1] = (char)((VALUE) >> 16),         \
+   (ARRAY)[2] = (char)((VALUE) >> 8),          \
+   (ARRAY)[3] = (char)((VALUE) >> 0))
+
 /* The record tags.  Values [1..3f] are for tags which may be in either
    file.  Values [41..9f] for those in the note file and [a1..ff] for
-   the data file.  */
+   the data file.  The tag value zero is used as an explicit end of
+   file marker -- it is not required to be present.  */
 
 #define GCOV_TAG_FUNCTION       ((gcov_unsigned_t)0x01000000)
-#define GCOV_TAG_FUNCTION_LENGTH (2 * 4)
+#define GCOV_TAG_FUNCTION_LENGTH (2)
 #define GCOV_TAG_BLOCKS                 ((gcov_unsigned_t)0x01410000)
-#define GCOV_TAG_BLOCKS_LENGTH(NUM) ((NUM) * 4)
+#define GCOV_TAG_BLOCKS_LENGTH(NUM) (NUM)
+#define GCOV_TAG_BLOCKS_NUM(LENGTH) (LENGTH)
 #define GCOV_TAG_ARCS           ((gcov_unsigned_t)0x01430000)
-#define GCOV_TAG_ARCS_LENGTH(NUM)  (1 * 4 + (NUM) * (2 * 4))
+#define GCOV_TAG_ARCS_LENGTH(NUM)  (1 + (NUM) * 2)
+#define GCOV_TAG_ARCS_NUM(LENGTH)  (((LENGTH) - 1) / 2)
 #define GCOV_TAG_LINES          ((gcov_unsigned_t)0x01450000)
 #define GCOV_TAG_COUNTER_BASE   ((gcov_unsigned_t)0x01a10000)
-#define GCOV_TAG_COUNTER_LENGTH(NUM) ((NUM) * 8)
+#define GCOV_TAG_COUNTER_LENGTH(NUM) ((NUM) * 2)
+#define GCOV_TAG_COUNTER_NUM(LENGTH) ((LENGTH) / 2)
 #define GCOV_TAG_OBJECT_SUMMARY  ((gcov_unsigned_t)0xa1000000)
 #define GCOV_TAG_PROGRAM_SUMMARY ((gcov_unsigned_t)0xa3000000)
 #define GCOV_TAG_SUMMARY_LENGTH  \
-       (1 * 4 + GCOV_COUNTERS_SUMMABLE * (2 * 4 + 3 * 8))
+       (1 + GCOV_COUNTERS_SUMMABLE * (2 + 3 * 2))
 
 /* Counters that are collected.  */
 #define GCOV_COUNTER_ARCS      0  /* Arc transitions.  */
 #define GCOV_COUNTERS_SUMMABLE 1  /* Counters which can be
                                      summaried.  */
+#define GCOV_FIRST_VALUE_COUNTER 1 /* The first of counters used for value
+                                     profiling.  They must form a consecutive
+                                     interval and their order must match
+                                     the order of HIST_TYPEs in
+                                     value-prof.h.  */
 #define GCOV_COUNTER_V_INTERVAL        1  /* Histogram of value inside an interval.  */
 #define GCOV_COUNTER_V_POW2    2  /* Histogram of exact power2 logarithm
                                      of a value.  */
 #define GCOV_COUNTER_V_SINGLE  3  /* The most common value of expression.  */
 #define GCOV_COUNTER_V_DELTA   4  /* The most common difference between
                                      consecutive values of expression.  */
+#define GCOV_LAST_VALUE_COUNTER 4  /* The last of counters used for value
+                                     profiling.  */
 #define GCOV_COUNTERS          5
+
+/* Number of counters used for value profiling.  */
+#define GCOV_N_VALUE_COUNTERS \
+  (GCOV_LAST_VALUE_COUNTER - GCOV_FIRST_VALUE_COUNTER + 1)
   
   /* A list of human readable names of the counters */
 #define GCOV_COUNTER_NAMES     {"arcs", "interval", "pow2", "single", "delta"}
@@ -403,12 +442,29 @@ extern void __gcov_merge_single (gcov_type *, unsigned);
 /* The merge function to choose the most common difference between
    consecutive values.  */
 extern void __gcov_merge_delta (gcov_type *, unsigned);
+
+/* The profiler functions.  */
+extern void __gcov_interval_profiler (gcov_type *, gcov_type, int, unsigned); 
+extern void __gcov_pow2_profiler (gcov_type *, gcov_type);
+extern void __gcov_one_value_profiler (gcov_type *, gcov_type);
+
+#ifndef inhibit_libc
+/* The wrappers around some library functions..  */
+extern pid_t __gcov_fork (void);
+extern int __gcov_execl (const char *, const char *, ...);
+extern int __gcov_execlp (const char *, const char *, ...);
+extern int __gcov_execle (const char *,  const char *, ...);
+extern int __gcov_execv (const char *, char *const []);
+extern int __gcov_execvp (const char *, char *const []);
+extern int __gcov_execve (const char *, char  *const [], char *const []);
+#endif
+
 #endif /* IN_LIBGCOV */
 
 #if IN_LIBGCOV >= 0
 
-/* Optimum size read from or written to disk.  */
-#define GCOV_BLOCK_SIZE (1 << 12)
+/* Optimum number of gcov_unsigned_t's read from or written to disk.  */
+#define GCOV_BLOCK_SIZE (1 << 10)
 
 GCOV_LINKAGE struct gcov_var
 {
@@ -416,7 +472,7 @@ GCOV_LINKAGE struct gcov_var
   gcov_position_t start;       /* Position of first byte of block */
   unsigned offset;             /* Read/write position within the block.  */
   unsigned length;             /* Read limit in the block.  */
-  unsigned overread;           /* Number of bytes overread.  */
+  unsigned overread;           /* Number of words overread.  */
   int error;                   /* < 0 overflow, > 0 disk error.  */
   int mode;                    /* < 0 writing, > 0 reading */
 #if IN_LIBGCOV
@@ -424,13 +480,13 @@ GCOV_LINKAGE struct gcov_var
      fit within this buffer and we always can transfer GCOV_BLOCK_SIZE
      to and from the disk. libgcov never backtracks and only writes 4
      or 8 byte objects.  */
-  char buffer[GCOV_BLOCK_SIZE + 4] __attribute__ ((aligned (4)));
+  gcov_unsigned_t buffer[GCOV_BLOCK_SIZE + 1];
 #else
   int endian;                  /* Swap endianness.  */
   /* Holds a variable length block, as the compiler can write
      strings and needs to backtrack.  */
   size_t alloc;
-  char *buffer;
+  gcov_unsigned_t *buffer;
 #endif
 } gcov_var;
 
@@ -442,7 +498,7 @@ GCOV_LINKAGE struct gcov_var
    functions, gcov_seek & gcov_error. When a file is to be rewritten
    you use the functions for reading, then gcov_rewrite then the
    functions for writing.  Your file may become corrupted if you break
-   these invariants. */
+   these invariants.  */
 #if IN_LIBGCOV
 GCOV_LINKAGE int gcov_open (const char */*name*/);
 #else
@@ -454,7 +510,6 @@ GCOV_LINKAGE int gcov_close (void);
 /* Available everywhere.  */
 static gcov_position_t gcov_position (void);
 static int gcov_is_error (void);
-static int gcov_is_eof (void);
 
 GCOV_LINKAGE gcov_unsigned_t gcov_read_unsigned (void);
 GCOV_LINKAGE gcov_type gcov_read_counter (void);
@@ -466,7 +521,6 @@ 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
@@ -493,32 +547,15 @@ GCOV_LINKAGE void gcov_write_length (gcov_position_t /*position*/);
 GCOV_LINKAGE time_t gcov_time (void);
 #endif
 
-/* Make sure the library is used correctly.  */
-#if ENABLE_CHECKING
-#define GCOV_CHECK(expr) ((expr) ? (void)0 : (void)abort ())
-#else
-#define GCOV_CHECK(expr)
-#endif
-#define GCOV_CHECK_READING() GCOV_CHECK(gcov_var.mode > 0)
-#define GCOV_CHECK_WRITING() GCOV_CHECK(gcov_var.mode < 0)
-
 /* Save the current position in the gcov file.  */
 
 static inline gcov_position_t
 gcov_position (void)
 {
-  GCOV_CHECK_READING ();
+  gcc_assert (gcov_var.mode > 0);
   return gcov_var.start + gcov_var.offset;
 }
 
-/* Return nonzero if we read to end of file.  */
-
-static inline int
-gcov_is_eof (void)
-{
-  return !gcov_var.overread;
-}
-
 /* Return nonzero if the error flag is set.  */
 
 static inline int
@@ -533,18 +570,12 @@ gcov_is_error (void)
 static inline void
 gcov_rewrite (void)
 {
-  GCOV_CHECK_READING ();
+  gcc_assert (gcov_var.mode > 0);
   gcov_var.mode = -1;
   gcov_var.start = 0;
   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 */