Home | History | Annotate | Download | only in gcov-src
      1 /* File format for coverage information
      2    Copyright (C) 1996-2014 Free Software Foundation, Inc.
      3    Contributed by Bob Manson <manson (at) cygnus.com>.
      4    Completely remangled by Nathan Sidwell <nathan (at) codesourcery.com>.
      5 
      6 This file is part of GCC.
      7 
      8 GCC is free software; you can redistribute it and/or modify it under
      9 the terms of the GNU General Public License as published by the Free
     10 Software Foundation; either version 3, or (at your option) any later
     11 version.
     12 
     13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
     14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
     15 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     16 for more details.
     17 
     18 Under Section 7 of GPL version 3, you are granted additional
     19 permissions described in the GCC Runtime Library Exception, version
     20 3.1, as published by the Free Software Foundation.
     21 
     22 You should have received a copy of the GNU General Public License and
     23 a copy of the GCC Runtime Library Exception along with this program;
     24 see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
     25 <http://www.gnu.org/licenses/>.  */
     26 
     27 /* Routines declared in gcov-io.h.  This file should be #included by
     28    another source file, after having #included gcov-io.h.  */
     29 
     30 #if !IN_GCOV
     31 static void gcov_write_block (unsigned);
     32 static gcov_unsigned_t *gcov_write_words (unsigned);
     33 #endif
     34 static const gcov_unsigned_t *gcov_read_words (unsigned);
     35 #if !IN_LIBGCOV
     36 static void gcov_allocate (unsigned);
     37 #endif
     38 
     39 /* Optimum number of gcov_unsigned_t's read from or written to disk.  */
     40 #define GCOV_BLOCK_SIZE (1 << 10)
     41 
     42 GCOV_LINKAGE struct gcov_var
     43 {
     44   FILE *file;
     45   gcov_position_t start;	/* Position of first byte of block */
     46   unsigned offset;		/* Read/write position within the block.  */
     47   unsigned length;		/* Read limit in the block.  */
     48   unsigned overread;		/* Number of words overread.  */
     49   int error;			/* < 0 overflow, > 0 disk error.  */
     50   int mode;	                /* < 0 writing, > 0 reading */
     51 #if IN_LIBGCOV
     52   /* Holds one block plus 4 bytes, thus all coverage reads & writes
     53      fit within this buffer and we always can transfer GCOV_BLOCK_SIZE
     54      to and from the disk. libgcov never backtracks and only writes 4
     55      or 8 byte objects.  */
     56   gcov_unsigned_t buffer[GCOV_BLOCK_SIZE + 1];
     57 #else
     58   int endian;			/* Swap endianness.  */
     59   /* Holds a variable length block, as the compiler can write
     60      strings and needs to backtrack.  */
     61   size_t alloc;
     62   gcov_unsigned_t *buffer;
     63 #endif
     64 } gcov_var;
     65 
     66 /* Save the current position in the gcov file.  */
     67 /* We need to expose this function when compiling for gcov-tool.  */
     68 #ifndef IN_GCOV_TOOL
     69 static inline
     70 #endif
     71 gcov_position_t
     72 gcov_position (void)
     73 {
     74   return gcov_var.start + gcov_var.offset;
     75 }
     76 
     77 /* Return nonzero if the error flag is set.  */
     78 /* We need to expose this function when compiling for gcov-tool.  */
     79 #ifndef IN_GCOV_TOOL
     80 static inline
     81 #endif
     82 int
     83 gcov_is_error (void)
     84 {
     85   return gcov_var.file ? gcov_var.error : 1;
     86 }
     87 
     88 #if IN_LIBGCOV
     89 /* Move to beginning of file and initialize for writing.  */
     90 GCOV_LINKAGE inline void
     91 gcov_rewrite (void)
     92 {
     93   gcc_assert (gcov_var.mode > 0);
     94   gcov_var.mode = -1;
     95   gcov_var.start = 0;
     96   gcov_var.offset = 0;
     97   fseek (gcov_var.file, 0L, SEEK_SET);
     98 }
     99 #endif
    100 
    101 static inline gcov_unsigned_t from_file (gcov_unsigned_t value)
    102 {
    103 #if !IN_LIBGCOV
    104   if (gcov_var.endian)
    105     {
    106       value = (value >> 16) | (value << 16);
    107       value = ((value & 0xff00ff) << 8) | ((value >> 8) & 0xff00ff);
    108     }
    109 #endif
    110   return value;
    111 }
    112 
    113 /* Open a gcov file. NAME is the name of the file to open and MODE
    114    indicates whether a new file should be created, or an existing file
    115    opened. If MODE is >= 0 an existing file will be opened, if
    116    possible, and if MODE is <= 0, a new file will be created. Use
    117    MODE=0 to attempt to reopen an existing file and then fall back on
    118    creating a new one.  If MODE < 0, the file will be opened in
    119    read-only mode.  Otherwise it will be opened for modification.
    120    Return zero on failure, >0 on opening an existing file and <0 on
    121    creating a new one.  */
    122 
    123 GCOV_LINKAGE int
    124 #if IN_LIBGCOV
    125 gcov_open (const char *name)
    126 #else
    127 gcov_open (const char *name, int mode)
    128 #endif
    129 {
    130 #if IN_LIBGCOV
    131   const int mode = 0;
    132 #endif
    133 #if GCOV_LOCKED
    134   struct flock s_flock;
    135   int fd;
    136 
    137   s_flock.l_whence = SEEK_SET;
    138   s_flock.l_start = 0;
    139   s_flock.l_len = 0; /* Until EOF.  */
    140   s_flock.l_pid = getpid ();
    141 #endif
    142 
    143   gcc_assert (!gcov_var.file);
    144   gcov_var.start = 0;
    145   gcov_var.offset = gcov_var.length = 0;
    146   gcov_var.overread = -1u;
    147   gcov_var.error = 0;
    148 #if !IN_LIBGCOV
    149   gcov_var.endian = 0;
    150 #endif
    151 #if GCOV_LOCKED
    152   if (mode > 0)
    153     {
    154       /* Read-only mode - acquire a read-lock.  */
    155       s_flock.l_type = F_RDLCK;
    156       /* pass mode (ignored) for compatibility */
    157       fd = open (name, O_RDONLY, S_IRUSR | S_IWUSR);
    158     }
    159   else if (mode < 0)
    160      {
    161        /* Write mode - acquire a write-lock.  */
    162        s_flock.l_type = F_WRLCK;
    163       fd = open (name, O_RDWR | O_CREAT | O_TRUNC, 0666);
    164     }
    165   else /* mode == 0 */
    166     {
    167       /* Read-Write mode - acquire a write-lock.  */
    168       s_flock.l_type = F_WRLCK;
    169       fd = open (name, O_RDWR | O_CREAT, 0666);
    170     }
    171   if (fd < 0)
    172     return 0;
    173 
    174   while (fcntl (fd, F_SETLKW, &s_flock) && errno == EINTR)
    175     continue;
    176 
    177   gcov_var.file = fdopen (fd, (mode > 0) ? "rb" : "r+b");
    178 
    179   if (!gcov_var.file)
    180     {
    181       close (fd);
    182       return 0;
    183     }
    184 
    185   if (mode > 0)
    186     gcov_var.mode = 1;
    187   else if (mode == 0)
    188     {
    189       struct stat st;
    190 
    191       if (fstat (fd, &st) < 0)
    192 	{
    193 	  fclose (gcov_var.file);
    194 	  gcov_var.file = 0;
    195 	  return 0;
    196 	}
    197       if (st.st_size != 0)
    198 	gcov_var.mode = 1;
    199       else
    200 	gcov_var.mode = mode * 2 + 1;
    201     }
    202   else
    203     gcov_var.mode = mode * 2 + 1;
    204 #else
    205   if (mode >= 0)
    206     gcov_var.file = fopen (name, (mode > 0) ? "rb" : "r+b");
    207 
    208   if (gcov_var.file)
    209     gcov_var.mode = 1;
    210   else if (mode <= 0)
    211     {
    212       gcov_var.file = fopen (name, "w+b");
    213       if (gcov_var.file)
    214 	gcov_var.mode = mode * 2 + 1;
    215     }
    216   if (!gcov_var.file)
    217     return 0;
    218 #endif
    219 
    220   setbuf (gcov_var.file, (char *)0);
    221 
    222   return 1;
    223 }
    224 
    225 /* Close the current gcov file. Flushes data to disk. Returns nonzero
    226    on failure or error flag set.  */
    227 
    228 GCOV_LINKAGE int
    229 gcov_close (void)
    230 {
    231   if (gcov_var.file)
    232     {
    233 #if !IN_GCOV
    234       if (gcov_var.offset && gcov_var.mode < 0)
    235 	gcov_write_block (gcov_var.offset);
    236 #endif
    237       fclose (gcov_var.file);
    238       gcov_var.file = 0;
    239       gcov_var.length = 0;
    240     }
    241 #if !IN_LIBGCOV
    242   free (gcov_var.buffer);
    243   gcov_var.alloc = 0;
    244   gcov_var.buffer = 0;
    245 #endif
    246   gcov_var.mode = 0;
    247   return gcov_var.error;
    248 }
    249 
    250 #if !IN_LIBGCOV
    251 /* Check if MAGIC is EXPECTED. Use it to determine endianness of the
    252    file. Returns +1 for same endian, -1 for other endian and zero for
    253    not EXPECTED.  */
    254 
    255 GCOV_LINKAGE int
    256 gcov_magic (gcov_unsigned_t magic, gcov_unsigned_t expected)
    257 {
    258   if (magic == expected)
    259     return 1;
    260   magic = (magic >> 16) | (magic << 16);
    261   magic = ((magic & 0xff00ff) << 8) | ((magic >> 8) & 0xff00ff);
    262   if (magic == expected)
    263     {
    264       gcov_var.endian = 1;
    265       return -1;
    266     }
    267   return 0;
    268 }
    269 #endif
    270 
    271 #if !IN_LIBGCOV
    272 static void
    273 gcov_allocate (unsigned length)
    274 {
    275   size_t new_size = gcov_var.alloc;
    276 
    277   if (!new_size)
    278     new_size = GCOV_BLOCK_SIZE;
    279   new_size += length;
    280   new_size *= 2;
    281 
    282   gcov_var.alloc = new_size;
    283   gcov_var.buffer = XRESIZEVAR (gcov_unsigned_t, gcov_var.buffer, new_size << 2);
    284 }
    285 #endif
    286 
    287 #if !IN_GCOV
    288 /* Write out the current block, if needs be.  */
    289 
    290 static void
    291 gcov_write_block (unsigned size)
    292 {
    293   if (fwrite (gcov_var.buffer, size << 2, 1, gcov_var.file) != 1)
    294     gcov_var.error = 1;
    295   gcov_var.start += size;
    296   gcov_var.offset -= size;
    297 }
    298 
    299 /* Allocate space to write BYTES bytes to the gcov file. Return a
    300    pointer to those bytes, or NULL on failure.  */
    301 
    302 static gcov_unsigned_t *
    303 gcov_write_words (unsigned words)
    304 {
    305   gcov_unsigned_t *result;
    306 
    307   gcc_assert (gcov_var.mode < 0);
    308 #if IN_LIBGCOV
    309   if (gcov_var.offset >= GCOV_BLOCK_SIZE)
    310     {
    311       gcov_write_block (GCOV_BLOCK_SIZE);
    312       if (gcov_var.offset)
    313 	{
    314 	  gcc_assert (gcov_var.offset == 1);
    315 	  memcpy (gcov_var.buffer, gcov_var.buffer + GCOV_BLOCK_SIZE, 4);
    316 	}
    317     }
    318 #else
    319   if (gcov_var.offset + words > gcov_var.alloc)
    320     gcov_allocate (gcov_var.offset + words);
    321 #endif
    322   result = &gcov_var.buffer[gcov_var.offset];
    323   gcov_var.offset += words;
    324 
    325   return result;
    326 }
    327 
    328 /* Write unsigned VALUE to coverage file.  Sets error flag
    329    appropriately.  */
    330 
    331 GCOV_LINKAGE void
    332 gcov_write_unsigned (gcov_unsigned_t value)
    333 {
    334   gcov_unsigned_t *buffer = gcov_write_words (1);
    335 
    336   buffer[0] = value;
    337 }
    338 
    339 /* Write counter VALUE to coverage file.  Sets error flag
    340    appropriately.  */
    341 
    342 #if IN_LIBGCOV
    343 GCOV_LINKAGE void
    344 gcov_write_counter (gcov_type value)
    345 {
    346   gcov_unsigned_t *buffer = gcov_write_words (2);
    347 
    348   buffer[0] = (gcov_unsigned_t) value;
    349   if (sizeof (value) > sizeof (gcov_unsigned_t))
    350     buffer[1] = (gcov_unsigned_t) (value >> 32);
    351   else
    352     buffer[1] = 0;
    353 }
    354 #endif /* IN_LIBGCOV */
    355 
    356 #if !IN_LIBGCOV
    357 /* Write STRING to coverage file.  Sets error flag on file
    358    error, overflow flag on overflow */
    359 
    360 GCOV_LINKAGE void
    361 gcov_write_string (const char *string)
    362 {
    363   unsigned length = 0;
    364   unsigned alloc = 0;
    365   gcov_unsigned_t *buffer;
    366 
    367   if (string)
    368     {
    369       length = strlen (string);
    370       alloc = (length + 4) >> 2;
    371     }
    372 
    373   buffer = gcov_write_words (1 + alloc);
    374 
    375   buffer[0] = alloc;
    376   buffer[alloc] = 0;
    377   memcpy (&buffer[1], string, length);
    378 }
    379 #endif
    380 
    381 #if !IN_LIBGCOV
    382 /* Write a tag TAG and reserve space for the record length. Return a
    383    value to be used for gcov_write_length.  */
    384 
    385 GCOV_LINKAGE gcov_position_t
    386 gcov_write_tag (gcov_unsigned_t tag)
    387 {
    388   gcov_position_t result = gcov_var.start + gcov_var.offset;
    389   gcov_unsigned_t *buffer = gcov_write_words (2);
    390 
    391   buffer[0] = tag;
    392   buffer[1] = 0;
    393 
    394   return result;
    395 }
    396 
    397 /* Write a record length using POSITION, which was returned by
    398    gcov_write_tag.  The current file position is the end of the
    399    record, and is restored before returning.  Returns nonzero on
    400    overflow.  */
    401 
    402 GCOV_LINKAGE void
    403 gcov_write_length (gcov_position_t position)
    404 {
    405   unsigned offset;
    406   gcov_unsigned_t length;
    407   gcov_unsigned_t *buffer;
    408 
    409   gcc_assert (gcov_var.mode < 0);
    410   gcc_assert (position + 2 <= gcov_var.start + gcov_var.offset);
    411   gcc_assert (position >= gcov_var.start);
    412   offset = position - gcov_var.start;
    413   length = gcov_var.offset - offset - 2;
    414   buffer = (gcov_unsigned_t *) &gcov_var.buffer[offset];
    415   buffer[1] = length;
    416   if (gcov_var.offset >= GCOV_BLOCK_SIZE)
    417     gcov_write_block (gcov_var.offset);
    418 }
    419 
    420 #else /* IN_LIBGCOV */
    421 
    422 /* Write a tag TAG and length LENGTH.  */
    423 
    424 GCOV_LINKAGE void
    425 gcov_write_tag_length (gcov_unsigned_t tag, gcov_unsigned_t length)
    426 {
    427   gcov_unsigned_t *buffer = gcov_write_words (2);
    428 
    429   buffer[0] = tag;
    430   buffer[1] = length;
    431 }
    432 
    433 /* Write a summary structure to the gcov file.  Return nonzero on
    434    overflow.  */
    435 
    436 GCOV_LINKAGE void
    437 gcov_write_summary (gcov_unsigned_t tag, const struct gcov_summary *summary)
    438 {
    439   unsigned ix, h_ix, bv_ix, h_cnt = 0;
    440   const struct gcov_ctr_summary *csum;
    441   unsigned histo_bitvector[GCOV_HISTOGRAM_BITVECTOR_SIZE];
    442 
    443   /* Count number of non-zero histogram entries, and fill in a bit vector
    444      of non-zero indices. The histogram is only currently computed for arc
    445      counters.  */
    446   for (bv_ix = 0; bv_ix < GCOV_HISTOGRAM_BITVECTOR_SIZE; bv_ix++)
    447     histo_bitvector[bv_ix] = 0;
    448   csum = &summary->ctrs[GCOV_COUNTER_ARCS];
    449   for (h_ix = 0; h_ix < GCOV_HISTOGRAM_SIZE; h_ix++)
    450     {
    451       if (csum->histogram[h_ix].num_counters > 0)
    452         {
    453           histo_bitvector[h_ix / 32] |= 1 << (h_ix % 32);
    454           h_cnt++;
    455         }
    456     }
    457   gcov_write_tag_length (tag, GCOV_TAG_SUMMARY_LENGTH (h_cnt));
    458   gcov_write_unsigned (summary->checksum);
    459   for (csum = summary->ctrs, ix = GCOV_COUNTERS_SUMMABLE; ix--; csum++)
    460     {
    461       gcov_write_unsigned (csum->num);
    462       gcov_write_unsigned (csum->runs);
    463       gcov_write_counter (csum->sum_all);
    464       gcov_write_counter (csum->run_max);
    465       gcov_write_counter (csum->sum_max);
    466       if (ix != GCOV_COUNTER_ARCS)
    467         {
    468           for (bv_ix = 0; bv_ix < GCOV_HISTOGRAM_BITVECTOR_SIZE; bv_ix++)
    469             gcov_write_unsigned (0);
    470           continue;
    471         }
    472       for (bv_ix = 0; bv_ix < GCOV_HISTOGRAM_BITVECTOR_SIZE; bv_ix++)
    473         gcov_write_unsigned (histo_bitvector[bv_ix]);
    474       for (h_ix = 0; h_ix < GCOV_HISTOGRAM_SIZE; h_ix++)
    475         {
    476           if (!csum->histogram[h_ix].num_counters)
    477             continue;
    478           gcov_write_unsigned (csum->histogram[h_ix].num_counters);
    479           gcov_write_counter (csum->histogram[h_ix].min_value);
    480           gcov_write_counter (csum->histogram[h_ix].cum_value);
    481         }
    482     }
    483 }
    484 #endif /* IN_LIBGCOV */
    485 
    486 #endif /*!IN_GCOV */
    487 
    488 /* Return a pointer to read BYTES bytes from the gcov file. Returns
    489    NULL on failure (read past EOF).  */
    490 
    491 static const gcov_unsigned_t *
    492 gcov_read_words (unsigned words)
    493 {
    494   const gcov_unsigned_t *result;
    495   unsigned excess = gcov_var.length - gcov_var.offset;
    496 
    497   gcc_assert (gcov_var.mode > 0);
    498   if (excess < words)
    499     {
    500       gcov_var.start += gcov_var.offset;
    501 #if IN_LIBGCOV
    502       if (excess)
    503 	{
    504 	  gcc_assert (excess == 1);
    505 	  memcpy (gcov_var.buffer, gcov_var.buffer + gcov_var.offset, 4);
    506 	}
    507 #else
    508       memmove (gcov_var.buffer, gcov_var.buffer + gcov_var.offset, excess * 4);
    509 #endif
    510       gcov_var.offset = 0;
    511       gcov_var.length = excess;
    512 #if IN_LIBGCOV
    513       gcc_assert (!gcov_var.length || gcov_var.length == 1);
    514       excess = GCOV_BLOCK_SIZE;
    515 #else
    516       if (gcov_var.length + words > gcov_var.alloc)
    517 	gcov_allocate (gcov_var.length + words);
    518       excess = gcov_var.alloc - gcov_var.length;
    519 #endif
    520       excess = fread (gcov_var.buffer + gcov_var.length,
    521 		      1, excess << 2, gcov_var.file) >> 2;
    522       gcov_var.length += excess;
    523       if (gcov_var.length < words)
    524 	{
    525 	  gcov_var.overread += words - gcov_var.length;
    526 	  gcov_var.length = 0;
    527 	  return 0;
    528 	}
    529     }
    530   result = &gcov_var.buffer[gcov_var.offset];
    531   gcov_var.offset += words;
    532   return result;
    533 }
    534 
    535 /* Read unsigned value from a coverage file. Sets error flag on file
    536    error, overflow flag on overflow */
    537 
    538 GCOV_LINKAGE gcov_unsigned_t
    539 gcov_read_unsigned (void)
    540 {
    541   gcov_unsigned_t value;
    542   const gcov_unsigned_t *buffer = gcov_read_words (1);
    543 
    544   if (!buffer)
    545     return 0;
    546   value = from_file (buffer[0]);
    547   return value;
    548 }
    549 
    550 /* Read counter value from a coverage file. Sets error flag on file
    551    error, overflow flag on overflow */
    552 
    553 GCOV_LINKAGE gcov_type
    554 gcov_read_counter (void)
    555 {
    556   gcov_type value;
    557   const gcov_unsigned_t *buffer = gcov_read_words (2);
    558 
    559   if (!buffer)
    560     return 0;
    561   value = from_file (buffer[0]);
    562   if (sizeof (value) > sizeof (gcov_unsigned_t))
    563     value |= ((gcov_type) from_file (buffer[1])) << 32;
    564   else if (buffer[1])
    565     gcov_var.error = -1;
    566 
    567   return value;
    568 }
    569 
    570 /* We need to expose the below function when compiling for gcov-tool.  */
    571 
    572 #if !IN_LIBGCOV || defined (IN_GCOV_TOOL)
    573 /* Read string from coverage file. Returns a pointer to a static
    574    buffer, or NULL on empty string. You must copy the string before
    575    calling another gcov function.  */
    576 
    577 GCOV_LINKAGE const char *
    578 gcov_read_string (void)
    579 {
    580   unsigned length = gcov_read_unsigned ();
    581 
    582   if (!length)
    583     return 0;
    584 
    585   return (const char *) gcov_read_words (length);
    586 }
    587 #endif
    588 
    589 GCOV_LINKAGE void
    590 gcov_read_summary (struct gcov_summary *summary)
    591 {
    592   unsigned ix, h_ix, bv_ix, h_cnt = 0;
    593   struct gcov_ctr_summary *csum;
    594   unsigned histo_bitvector[GCOV_HISTOGRAM_BITVECTOR_SIZE];
    595   unsigned cur_bitvector;
    596 
    597   summary->checksum = gcov_read_unsigned ();
    598   for (csum = summary->ctrs, ix = GCOV_COUNTERS_SUMMABLE; ix--; csum++)
    599     {
    600       csum->num = gcov_read_unsigned ();
    601       csum->runs = gcov_read_unsigned ();
    602       csum->sum_all = gcov_read_counter ();
    603       csum->run_max = gcov_read_counter ();
    604       csum->sum_max = gcov_read_counter ();
    605       memset (csum->histogram, 0,
    606               sizeof (gcov_bucket_type) * GCOV_HISTOGRAM_SIZE);
    607       for (bv_ix = 0; bv_ix < GCOV_HISTOGRAM_BITVECTOR_SIZE; bv_ix++)
    608         {
    609           histo_bitvector[bv_ix] = gcov_read_unsigned ();
    610 #if IN_LIBGCOV
    611           /* When building libgcov we don't include system.h, which includes
    612              hwint.h (where popcount_hwi is declared). However, libgcov.a
    613              is built by the bootstrapped compiler and therefore the builtins
    614              are always available.  */
    615           h_cnt += __builtin_popcount (histo_bitvector[bv_ix]);
    616 #else
    617           h_cnt += popcount_hwi (histo_bitvector[bv_ix]);
    618 #endif
    619         }
    620       bv_ix = 0;
    621       h_ix = 0;
    622       cur_bitvector = 0;
    623       while (h_cnt--)
    624         {
    625           /* Find the index corresponding to the next entry we will read in.
    626              First find the next non-zero bitvector and re-initialize
    627              the histogram index accordingly, then right shift and increment
    628              the index until we find a set bit.  */
    629           while (!cur_bitvector)
    630             {
    631               h_ix = bv_ix * 32;
    632               gcc_assert (bv_ix < GCOV_HISTOGRAM_BITVECTOR_SIZE);
    633               cur_bitvector = histo_bitvector[bv_ix++];
    634             }
    635           while (!(cur_bitvector & 0x1))
    636             {
    637               h_ix++;
    638               cur_bitvector >>= 1;
    639             }
    640           gcc_assert (h_ix < GCOV_HISTOGRAM_SIZE);
    641 
    642           csum->histogram[h_ix].num_counters = gcov_read_unsigned ();
    643           csum->histogram[h_ix].min_value = gcov_read_counter ();
    644           csum->histogram[h_ix].cum_value = gcov_read_counter ();
    645           /* Shift off the index we are done with and increment to the
    646              corresponding next histogram entry.  */
    647           cur_bitvector >>= 1;
    648           h_ix++;
    649         }
    650     }
    651 }
    652 
    653 #if (!IN_LIBGCOV && IN_GCOV != 1) || defined (IN_GCOV_TOOL)
    654 /* Read LEN words (unsigned type) and construct MOD_INFO.  */
    655 
    656 GCOV_LINKAGE void
    657 gcov_read_module_info (struct gcov_module_info *mod_info,
    658                        gcov_unsigned_t len)
    659 {
    660   gcov_unsigned_t src_filename_len, filename_len, i, j, num_strings;
    661   mod_info->ident = gcov_read_unsigned ();
    662   mod_info->is_primary = gcov_read_unsigned ();
    663   mod_info->flags = gcov_read_unsigned ();
    664   mod_info->lang = gcov_read_unsigned ();
    665   mod_info->ggc_memory = gcov_read_unsigned ();
    666   mod_info->num_quote_paths = gcov_read_unsigned ();
    667   mod_info->num_bracket_paths = gcov_read_unsigned ();
    668   mod_info->num_system_paths = gcov_read_unsigned ();
    669   mod_info->num_cpp_defines = gcov_read_unsigned ();
    670   mod_info->num_cpp_includes = gcov_read_unsigned ();
    671   mod_info->num_cl_args = gcov_read_unsigned ();
    672   len -= 11;
    673 
    674   filename_len = gcov_read_unsigned ();
    675   mod_info->da_filename = (char *) xmalloc (filename_len *
    676                                             sizeof (gcov_unsigned_t));
    677   for (i = 0; i < filename_len; i++)
    678     ((gcov_unsigned_t *) mod_info->da_filename)[i] = gcov_read_unsigned ();
    679   len -= (filename_len + 1);
    680 
    681   src_filename_len = gcov_read_unsigned ();
    682   mod_info->source_filename = (char *) xmalloc (src_filename_len *
    683 						sizeof (gcov_unsigned_t));
    684   for (i = 0; i < src_filename_len; i++)
    685     ((gcov_unsigned_t *) mod_info->source_filename)[i] = gcov_read_unsigned ();
    686   len -= (src_filename_len + 1);
    687 
    688   num_strings = mod_info->num_quote_paths + mod_info->num_bracket_paths
    689     + mod_info->num_system_paths
    690     + mod_info->num_cpp_defines + mod_info->num_cpp_includes
    691     + mod_info->num_cl_args;
    692   for (j = 0; j < num_strings; j++)
    693    {
    694      gcov_unsigned_t string_len = gcov_read_unsigned ();
    695      mod_info->string_array[j] =
    696        (char *) xmalloc (string_len * sizeof (gcov_unsigned_t));
    697      for (i = 0; i < string_len; i++)
    698        ((gcov_unsigned_t *) mod_info->string_array[j])[i] =
    699 	 gcov_read_unsigned ();
    700      len -= (string_len + 1);
    701    }
    702   gcc_assert (!len);
    703 }
    704 #endif
    705 
    706 /* We need to expose the below function when compiling for gcov-tool.  */
    707 
    708 #if !IN_LIBGCOV || defined (IN_GCOV_TOOL)
    709 /* Reset to a known position.  BASE should have been obtained from
    710    gcov_position, LENGTH should be a record length.  */
    711 
    712 GCOV_LINKAGE void
    713 gcov_sync (gcov_position_t base, gcov_unsigned_t length)
    714 {
    715   gcc_assert (gcov_var.mode > 0);
    716   base += length;
    717   if (base - gcov_var.start <= gcov_var.length)
    718     gcov_var.offset = base - gcov_var.start;
    719   else
    720     {
    721       gcov_var.offset = gcov_var.length = 0;
    722       fseek (gcov_var.file, base << 2, SEEK_SET);
    723       gcov_var.start = ftell (gcov_var.file) >> 2;
    724     }
    725 }
    726 #endif
    727 
    728 #if IN_LIBGCOV
    729 /* Move to a given position in a gcov file.  */
    730 
    731 GCOV_LINKAGE void
    732 gcov_seek (gcov_position_t base)
    733 {
    734   gcc_assert (gcov_var.mode < 0);
    735   if (gcov_var.offset)
    736     gcov_write_block (gcov_var.offset);
    737   fseek (gcov_var.file, base << 2, SEEK_SET);
    738   gcov_var.start = ftell (gcov_var.file) >> 2;
    739 }
    740 
    741 /* Truncate the gcov file at the current position.  */
    742 
    743 GCOV_LINKAGE void
    744 gcov_truncate (void)
    745 {
    746   long offs;
    747   int filenum;
    748   gcc_assert (gcov_var.mode < 0);
    749   if (gcov_var.offset)
    750     gcov_write_block (gcov_var.offset);
    751   offs = ftell (gcov_var.file);
    752   filenum = fileno (gcov_var.file);
    753   if (offs == -1 || filenum == -1 || ftruncate (filenum, offs))
    754     gcov_var.error = 1;
    755 }
    756 #endif
    757 
    758 #if IN_GCOV > 0
    759 /* Return the modification time of the current gcov file.  */
    760 
    761 GCOV_LINKAGE time_t
    762 gcov_time (void)
    763 {
    764   struct stat status;
    765 
    766   if (fstat (fileno (gcov_var.file), &status))
    767     return 0;
    768   else
    769     return status.st_mtime;
    770 }
    771 #endif /* IN_GCOV */
    772 
    773 #if !IN_GCOV
    774 /* Determine the index into histogram for VALUE. */
    775 
    776 #if IN_LIBGCOV
    777 static unsigned
    778 #else
    779 GCOV_LINKAGE unsigned
    780 #endif
    781 gcov_histo_index (gcov_type value)
    782 {
    783   gcov_type_unsigned v = (gcov_type_unsigned)value;
    784   unsigned r = 0;
    785   unsigned prev2bits = 0;
    786 
    787   /* Find index into log2 scale histogram, where each of the log2
    788      sized buckets is divided into 4 linear sub-buckets for better
    789      focus in the higher buckets.  */
    790 
    791   /* Find the place of the most-significant bit set.  */
    792   if (v > 0)
    793     {
    794 #if IN_LIBGCOV
    795       /* When building libgcov we don't include system.h, which includes
    796          hwint.h (where floor_log2 is declared). However, libgcov.a
    797          is built by the bootstrapped compiler and therefore the builtins
    798          are always available.  */
    799       r = sizeof (long long) * __CHAR_BIT__ - 1 - __builtin_clzll (v);
    800 #else
    801       /* We use floor_log2 from hwint.c, which takes a HOST_WIDE_INT
    802          that is either 32 or 64 bits, and gcov_type_unsigned may be 64 bits.
    803          Need to check for the case where gcov_type_unsigned is 64 bits
    804          and HOST_WIDE_INT is 32 bits and handle it specially.  */
    805 #if HOST_BITS_PER_WIDEST_INT == HOST_BITS_PER_WIDE_INT
    806       r = floor_log2 (v);
    807 #elif HOST_BITS_PER_WIDEST_INT == 2 * HOST_BITS_PER_WIDE_INT
    808       HOST_WIDE_INT hwi_v = v >> HOST_BITS_PER_WIDE_INT;
    809       if (hwi_v)
    810         r = floor_log2 (hwi_v) + HOST_BITS_PER_WIDE_INT;
    811       else
    812         r = floor_log2 ((HOST_WIDE_INT)v);
    813 #else
    814       gcc_unreachable ();
    815 #endif
    816 #endif
    817     }
    818 
    819   /* If at most the 2 least significant bits are set (value is
    820      0 - 3) then that value is our index into the lowest set of
    821      four buckets.  */
    822   if (r < 2)
    823     return (unsigned)value;
    824 
    825   gcc_assert (r < 64);
    826 
    827   /* Find the two next most significant bits to determine which
    828      of the four linear sub-buckets to select.  */
    829   prev2bits = (v >> (r - 2)) & 0x3;
    830   /* Finally, compose the final bucket index from the log2 index and
    831      the next 2 bits. The minimum r value at this point is 2 since we
    832      returned above if r was 2 or more, so the minimum bucket at this
    833      point is 4.  */
    834   return (r - 1) * 4 + prev2bits;
    835 }
    836 
    837 /* Merge SRC_HISTO into TGT_HISTO. The counters are assumed to be in
    838    the same relative order in both histograms, and are matched up
    839    and merged in reverse order. Each counter is assigned an equal portion of
    840    its entry's original cumulative counter value when computing the
    841    new merged cum_value.  */
    842 
    843 static void gcov_histogram_merge (gcov_bucket_type *tgt_histo,
    844                                   gcov_bucket_type *src_histo)
    845 {
    846   int src_i, tgt_i, tmp_i = 0;
    847   unsigned src_num, tgt_num, merge_num;
    848   gcov_type src_cum, tgt_cum, merge_src_cum, merge_tgt_cum, merge_cum;
    849   gcov_type merge_min;
    850   gcov_bucket_type tmp_histo[GCOV_HISTOGRAM_SIZE];
    851   int src_done = 0;
    852 
    853   memset (tmp_histo, 0, sizeof (gcov_bucket_type) * GCOV_HISTOGRAM_SIZE);
    854 
    855   /* Assume that the counters are in the same relative order in both
    856      histograms. Walk the histograms from largest to smallest entry,
    857      matching up and combining counters in order.  */
    858   src_num = 0;
    859   src_cum = 0;
    860   src_i = GCOV_HISTOGRAM_SIZE - 1;
    861   for (tgt_i = GCOV_HISTOGRAM_SIZE - 1; tgt_i >= 0 && !src_done; tgt_i--)
    862     {
    863       tgt_num = tgt_histo[tgt_i].num_counters;
    864       tgt_cum = tgt_histo[tgt_i].cum_value;
    865       /* Keep going until all of the target histogram's counters at this
    866          position have been matched and merged with counters from the
    867          source histogram.  */
    868       while (tgt_num > 0 && !src_done)
    869         {
    870           /* If this is either the first time through this loop or we just
    871              exhausted the previous non-zero source histogram entry, look
    872              for the next non-zero source histogram entry.  */
    873           if (!src_num)
    874             {
    875               /* Locate the next non-zero entry.  */
    876               while (src_i >= 0 && !src_histo[src_i].num_counters)
    877                 src_i--;
    878               /* If source histogram has fewer counters, then just copy over the
    879                  remaining target counters and quit.  */
    880               if (src_i < 0)
    881                 {
    882                   tmp_histo[tgt_i].num_counters += tgt_num;
    883                   tmp_histo[tgt_i].cum_value += tgt_cum;
    884                   if (!tmp_histo[tgt_i].min_value ||
    885                       tgt_histo[tgt_i].min_value < tmp_histo[tgt_i].min_value)
    886                     tmp_histo[tgt_i].min_value = tgt_histo[tgt_i].min_value;
    887                   while (--tgt_i >= 0)
    888                     {
    889                       tmp_histo[tgt_i].num_counters
    890                           += tgt_histo[tgt_i].num_counters;
    891                       tmp_histo[tgt_i].cum_value += tgt_histo[tgt_i].cum_value;
    892                       if (!tmp_histo[tgt_i].min_value ||
    893                           tgt_histo[tgt_i].min_value
    894                           < tmp_histo[tgt_i].min_value)
    895                         tmp_histo[tgt_i].min_value = tgt_histo[tgt_i].min_value;
    896                     }
    897 
    898                   src_done = 1;
    899                   break;
    900                 }
    901 
    902               src_num = src_histo[src_i].num_counters;
    903               src_cum = src_histo[src_i].cum_value;
    904             }
    905 
    906           /* The number of counters to merge on this pass is the minimum
    907              of the remaining counters from the current target and source
    908              histogram entries.  */
    909           merge_num = tgt_num;
    910           if (src_num < merge_num)
    911             merge_num = src_num;
    912 
    913           /* The merged min_value is the sum of the min_values from target
    914              and source.  */
    915           merge_min = tgt_histo[tgt_i].min_value + src_histo[src_i].min_value;
    916 
    917           /* Compute the portion of source and target entries' cum_value
    918              that will be apportioned to the counters being merged.
    919              The total remaining cum_value from each entry is divided
    920              equally among the counters from that histogram entry if we
    921              are not merging all of them.  */
    922           merge_src_cum = src_cum;
    923           if (merge_num < src_num)
    924             merge_src_cum = merge_num * src_cum / src_num;
    925           merge_tgt_cum = tgt_cum;
    926           if (merge_num < tgt_num)
    927             merge_tgt_cum = merge_num * tgt_cum / tgt_num;
    928           /* The merged cum_value is the sum of the source and target
    929              components.  */
    930           merge_cum = merge_src_cum + merge_tgt_cum;
    931 
    932           /* Update the remaining number of counters and cum_value left
    933              to be merged from this source and target entry.  */
    934           src_cum -= merge_src_cum;
    935           tgt_cum -= merge_tgt_cum;
    936           src_num -= merge_num;
    937           tgt_num -= merge_num;
    938 
    939           /* The merged counters get placed in the new merged histogram
    940              at the entry for the merged min_value.  */
    941           tmp_i = gcov_histo_index (merge_min);
    942           gcc_assert (tmp_i < GCOV_HISTOGRAM_SIZE);
    943           tmp_histo[tmp_i].num_counters += merge_num;
    944           tmp_histo[tmp_i].cum_value += merge_cum;
    945           if (!tmp_histo[tmp_i].min_value ||
    946               merge_min < tmp_histo[tmp_i].min_value)
    947             tmp_histo[tmp_i].min_value = merge_min;
    948 
    949           /* Ensure the search for the next non-zero src_histo entry starts
    950              at the next smallest histogram bucket.  */
    951           if (!src_num)
    952             src_i--;
    953         }
    954     }
    955 
    956   gcc_assert (tgt_i < 0);
    957 
    958   /* In the case where there were more counters in the source histogram,
    959      accumulate the remaining unmerged cumulative counter values. Add
    960      those to the smallest non-zero target histogram entry. Otherwise,
    961      the total cumulative counter values in the histogram will be smaller
    962      than the sum_all stored in the summary, which will complicate
    963      computing the working set information from the histogram later on.  */
    964   if (src_num)
    965     src_i--;
    966   while (src_i >= 0)
    967     {
    968       src_cum += src_histo[src_i].cum_value;
    969       src_i--;
    970     }
    971   /* At this point, tmp_i should be the smallest non-zero entry in the
    972      tmp_histo.  */
    973   gcc_assert (tmp_i >= 0 && tmp_i < GCOV_HISTOGRAM_SIZE
    974 	      && tmp_histo[tmp_i].num_counters > 0);
    975   tmp_histo[tmp_i].cum_value += src_cum;
    976 
    977   /* Finally, copy the merged histogram into tgt_histo.  */
    978   memcpy (tgt_histo, tmp_histo,
    979 	  sizeof (gcov_bucket_type) * GCOV_HISTOGRAM_SIZE);
    980 }
    981 #endif /* !IN_GCOV */
    982 
    983 /* This is used by gcov-dump (IN_GCOV == -1) and in the compiler
    984    (!IN_GCOV && !IN_LIBGCOV).  */
    985 #if IN_GCOV <= 0 && !IN_LIBGCOV
    986 /* Compute the working set information from the counter histogram in
    987    the profile summary. This is an array of information corresponding to a
    988    range of percentages of the total execution count (sum_all), and includes
    989    the number of counters required to cover that working set percentage and
    990    the minimum counter value in that working set.  */
    991 
    992 GCOV_LINKAGE void
    993 compute_working_sets (const struct gcov_ctr_summary *summary,
    994                       gcov_working_set_t *gcov_working_sets)
    995 {
    996   gcov_type working_set_cum_values[NUM_GCOV_WORKING_SETS];
    997   gcov_type ws_cum_hotness_incr;
    998   gcov_type cum, tmp_cum;
    999   const gcov_bucket_type *histo_bucket;
   1000   unsigned ws_ix, c_num, count;
   1001   int h_ix;
   1002 
   1003   /* Compute the amount of sum_all that the cumulative hotness grows
   1004      by in each successive working set entry, which depends on the
   1005      number of working set entries.  */
   1006   ws_cum_hotness_incr = summary->sum_all / NUM_GCOV_WORKING_SETS;
   1007 
   1008   /* Next fill in an array of the cumulative hotness values corresponding
   1009      to each working set summary entry we are going to compute below.
   1010      Skip 0% statistics, which can be extrapolated from the
   1011      rest of the summary data.  */
   1012   cum = ws_cum_hotness_incr;
   1013   for (ws_ix = 0; ws_ix < NUM_GCOV_WORKING_SETS;
   1014        ws_ix++, cum += ws_cum_hotness_incr)
   1015     working_set_cum_values[ws_ix] = cum;
   1016   /* The last summary entry is reserved for (roughly) 99.9% of the
   1017      working set. Divide by 1024 so it becomes a shift, which gives
   1018      almost exactly 99.9%.  */
   1019   working_set_cum_values[NUM_GCOV_WORKING_SETS-1]
   1020       = summary->sum_all - summary->sum_all/1024;
   1021 
   1022   /* Next, walk through the histogram in decending order of hotness
   1023      and compute the statistics for the working set summary array.
   1024      As histogram entries are accumulated, we check to see which
   1025      working set entries have had their expected cum_value reached
   1026      and fill them in, walking the working set entries in increasing
   1027      size of cum_value.  */
   1028   ws_ix = 0; /* The current entry into the working set array.  */
   1029   cum = 0; /* The current accumulated counter sum.  */
   1030   count = 0; /* The current accumulated count of block counters.  */
   1031   for (h_ix = GCOV_HISTOGRAM_SIZE - 1;
   1032        h_ix >= 0 && ws_ix < NUM_GCOV_WORKING_SETS; h_ix--)
   1033     {
   1034       histo_bucket = &summary->histogram[h_ix];
   1035 
   1036       /* If we haven't reached the required cumulative counter value for
   1037          the current working set percentage, simply accumulate this histogram
   1038          entry into the running sums and continue to the next histogram
   1039          entry.  */
   1040       if (cum + histo_bucket->cum_value < working_set_cum_values[ws_ix])
   1041         {
   1042           cum += histo_bucket->cum_value;
   1043           count += histo_bucket->num_counters;
   1044           continue;
   1045         }
   1046 
   1047       /* If adding the current histogram entry's cumulative counter value
   1048          causes us to exceed the current working set size, then estimate
   1049          how many of this histogram entry's counter values are required to
   1050          reach the working set size, and fill in working set entries
   1051          as we reach their expected cumulative value.  */
   1052       for (c_num = 0, tmp_cum = cum;
   1053            c_num < histo_bucket->num_counters && ws_ix < NUM_GCOV_WORKING_SETS;
   1054            c_num++)
   1055         {
   1056           count++;
   1057           /* If we haven't reached the last histogram entry counter, add
   1058              in the minimum value again. This will underestimate the
   1059              cumulative sum so far, because many of the counter values in this
   1060              entry may have been larger than the minimum. We could add in the
   1061              average value every time, but that would require an expensive
   1062              divide operation.  */
   1063           if (c_num + 1 < histo_bucket->num_counters)
   1064             tmp_cum += histo_bucket->min_value;
   1065           /* If we have reached the last histogram entry counter, then add
   1066              in the entire cumulative value.  */
   1067           else
   1068             tmp_cum = cum + histo_bucket->cum_value;
   1069 
   1070 	  /* Next walk through successive working set entries and fill in
   1071 	     the statistics for any whose size we have reached by accumulating
   1072 	     this histogram counter.  */
   1073 	  while (ws_ix < NUM_GCOV_WORKING_SETS
   1074 		 && tmp_cum >= working_set_cum_values[ws_ix])
   1075             {
   1076               gcov_working_sets[ws_ix].num_counters = count;
   1077               gcov_working_sets[ws_ix].min_counter
   1078                   = histo_bucket->min_value;
   1079               ws_ix++;
   1080             }
   1081         }
   1082       /* Finally, update the running cumulative value since we were
   1083          using a temporary above.  */
   1084       cum += histo_bucket->cum_value;
   1085     }
   1086   gcc_assert (ws_ix == NUM_GCOV_WORKING_SETS);
   1087 }
   1088 #endif /* IN_GCOV <= 0 && !IN_LIBGCOV */
   1089