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   _GCOV_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   _GCOV_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 #ifndef __KERNEL__
    124 GCOV_LINKAGE int
    125 #if IN_LIBGCOV
    126 gcov_open (const char *name)
    127 #else
    128 gcov_open (const char *name, int mode)
    129 #endif
    130 {
    131 #if IN_LIBGCOV
    132   const int mode = 0;
    133 #endif
    134 #if GCOV_LOCKED
    135   struct flock s_flock;
    136   int fd;
    137 
    138   s_flock.l_whence = SEEK_SET;
    139   s_flock.l_start = 0;
    140   s_flock.l_len = 0; /* Until EOF.  */
    141   s_flock.l_pid = getpid ();
    142 #endif
    143 
    144   gcc_assert (!gcov_var.file);
    145   gcov_var.start = 0;
    146   gcov_var.offset = gcov_var.length = 0;
    147   gcov_var.overread = -1u;
    148   gcov_var.error = 0;
    149 #if !IN_LIBGCOV
    150   gcov_var.endian = 0;
    151 #endif
    152 #if GCOV_LOCKED
    153   if (mode > 0)
    154     {
    155       /* Read-only mode - acquire a read-lock.  */
    156       s_flock.l_type = F_RDLCK;
    157       /* pass mode (ignored) for compatibility */
    158       fd = open (name, O_RDONLY, S_IRUSR | S_IWUSR);
    159     }
    160   else if (mode < 0)
    161      {
    162        /* Write mode - acquire a write-lock.  */
    163        s_flock.l_type = F_WRLCK;
    164       fd = open (name, O_RDWR | O_CREAT | O_TRUNC, 0666);
    165     }
    166   else /* mode == 0 */
    167     {
    168       /* Read-Write mode - acquire a write-lock.  */
    169       s_flock.l_type = F_WRLCK;
    170       fd = open (name, O_RDWR | O_CREAT, 0666);
    171     }
    172   if (fd < 0)
    173     return 0;
    174 
    175   while (fcntl (fd, F_SETLKW, &s_flock) && errno == EINTR)
    176     continue;
    177 
    178   gcov_var.file = fdopen (fd, (mode > 0) ? "rb" : "r+b");
    179 
    180   if (!gcov_var.file)
    181     {
    182       close (fd);
    183       return 0;
    184     }
    185 
    186   if (mode > 0)
    187     gcov_var.mode = 1;
    188   else if (mode == 0)
    189     {
    190       struct stat st;
    191 
    192       if (fstat (fd, &st) < 0)
    193 	{
    194 	  _GCOV_fclose (gcov_var.file);
    195 	  gcov_var.file = 0;
    196 	  return 0;
    197 	}
    198       if (st.st_size != 0)
    199 	gcov_var.mode = 1;
    200       else
    201 	gcov_var.mode = mode * 2 + 1;
    202     }
    203   else
    204     gcov_var.mode = mode * 2 + 1;
    205 #else
    206   if (mode >= 0)
    207     gcov_var.file = _GCOV_fopen (name, (mode > 0) ? "rb" : "r+b");
    208 
    209   if (gcov_var.file)
    210     gcov_var.mode = 1;
    211   else if (mode <= 0)
    212     {
    213       gcov_var.file = _GCOV_fopen (name, "w+b");
    214       if (gcov_var.file)
    215 	gcov_var.mode = mode * 2 + 1;
    216     }
    217   if (!gcov_var.file)
    218     return 0;
    219 #endif
    220 
    221   setbuf (gcov_var.file, (char *)0);
    222 
    223   return 1;
    224 }
    225 #else /* __KERNEL__ */
    226 
    227 extern _GCOV_FILE *gcov_current_file;
    228 
    229 GCOV_LINKAGE int
    230 gcov_open (const char *name)
    231 {
    232   gcov_var.start = 0;
    233   gcov_var.offset = gcov_var.length = 0;
    234   gcov_var.overread = -1u;
    235   gcov_var.error = 0;
    236   gcov_var.file = gcov_current_file;
    237   gcov_var.mode = 1;
    238 
    239   return 1;
    240 }
    241 #endif /* __KERNEL__ */
    242 
    243 
    244 /* Close the current gcov file. Flushes data to disk. Returns nonzero
    245    on failure or error flag set.  */
    246 
    247 GCOV_LINKAGE int
    248 gcov_close (void)
    249 {
    250   if (gcov_var.file)
    251     {
    252 #if !IN_GCOV
    253       if (gcov_var.offset && gcov_var.mode < 0)
    254 	gcov_write_block (gcov_var.offset);
    255 #endif
    256       _GCOV_fclose (gcov_var.file);
    257       gcov_var.file = 0;
    258       gcov_var.length = 0;
    259     }
    260 #if !IN_LIBGCOV
    261   free (gcov_var.buffer);
    262   gcov_var.alloc = 0;
    263   gcov_var.buffer = 0;
    264 #endif
    265   gcov_var.mode = 0;
    266   return gcov_var.error;
    267 }
    268 
    269 #if !IN_LIBGCOV
    270 /* Check if MAGIC is EXPECTED. Use it to determine endianness of the
    271    file. Returns +1 for same endian, -1 for other endian and zero for
    272    not EXPECTED.  */
    273 
    274 GCOV_LINKAGE int
    275 gcov_magic (gcov_unsigned_t magic, gcov_unsigned_t expected)
    276 {
    277   if (magic == expected)
    278     return 1;
    279   magic = (magic >> 16) | (magic << 16);
    280   magic = ((magic & 0xff00ff) << 8) | ((magic >> 8) & 0xff00ff);
    281   if (magic == expected)
    282     {
    283       gcov_var.endian = 1;
    284       return -1;
    285     }
    286   return 0;
    287 }
    288 #endif
    289 
    290 #if !IN_LIBGCOV
    291 static void
    292 gcov_allocate (unsigned length)
    293 {
    294   size_t new_size = gcov_var.alloc;
    295 
    296   if (!new_size)
    297     new_size = GCOV_BLOCK_SIZE;
    298   new_size += length;
    299   new_size *= 2;
    300 
    301   gcov_var.alloc = new_size;
    302   gcov_var.buffer = XRESIZEVAR (gcov_unsigned_t, gcov_var.buffer, new_size << 2);
    303 }
    304 #endif
    305 
    306 #if !IN_GCOV
    307 /* Write out the current block, if needs be.  */
    308 
    309 static void
    310 gcov_write_block (unsigned size)
    311 {
    312   if (_GCOV_fwrite (gcov_var.buffer, size << 2, 1, gcov_var.file) != 1)
    313     gcov_var.error = 1;
    314   gcov_var.start += size;
    315   gcov_var.offset -= size;
    316 }
    317 
    318 /* Allocate space to write BYTES bytes to the gcov file. Return a
    319    pointer to those bytes, or NULL on failure.  */
    320 
    321 static gcov_unsigned_t *
    322 gcov_write_words (unsigned words)
    323 {
    324   gcov_unsigned_t *result;
    325 
    326   gcc_assert (gcov_var.mode < 0);
    327 #if IN_LIBGCOV
    328   if (gcov_var.offset >= GCOV_BLOCK_SIZE)
    329     {
    330       gcov_write_block (GCOV_BLOCK_SIZE);
    331       if (gcov_var.offset)
    332 	{
    333 	  gcc_assert (gcov_var.offset == 1);
    334 	  memcpy (gcov_var.buffer, gcov_var.buffer + GCOV_BLOCK_SIZE, 4);
    335 	}
    336     }
    337 #else
    338   if (gcov_var.offset + words > gcov_var.alloc)
    339     gcov_allocate (gcov_var.offset + words);
    340 #endif
    341   result = &gcov_var.buffer[gcov_var.offset];
    342   gcov_var.offset += words;
    343 
    344   return result;
    345 }
    346 
    347 /* Write unsigned VALUE to coverage file.  Sets error flag
    348    appropriately.  */
    349 
    350 GCOV_LINKAGE void
    351 gcov_write_unsigned (gcov_unsigned_t value)
    352 {
    353   gcov_unsigned_t *buffer = gcov_write_words (1);
    354 
    355   buffer[0] = value;
    356 }
    357 
    358 /* Compute the total length in words required to write NUM_STRINGS
    359    in STRING_ARRAY as unsigned.  */
    360 
    361 GCOV_LINKAGE gcov_unsigned_t
    362 gcov_compute_string_array_len (char **string_array,
    363                                gcov_unsigned_t num_strings)
    364 {
    365   gcov_unsigned_t len = 0, i;
    366   for (i = 0; i < num_strings; i++)
    367     {
    368       gcov_unsigned_t string_len
    369           = (strlen (string_array[i]) + sizeof (gcov_unsigned_t))
    370           / sizeof (gcov_unsigned_t);
    371       len += string_len;
    372       len += 1; /* Each string is lead by a length.  */
    373     }
    374   return len;
    375 }
    376 
    377 /* Write NUM_STRINGS in STRING_ARRAY as unsigned.  */
    378 
    379 GCOV_LINKAGE void
    380 gcov_write_string_array (char **string_array, gcov_unsigned_t num_strings)
    381 {
    382   gcov_unsigned_t i, j;
    383   for (j = 0; j < num_strings; j++)
    384     {
    385       gcov_unsigned_t *aligned_string;
    386       gcov_unsigned_t string_len =
    387 	(strlen (string_array[j]) + sizeof (gcov_unsigned_t)) /
    388 	sizeof (gcov_unsigned_t);
    389       aligned_string = (gcov_unsigned_t *)
    390 	alloca ((string_len + 1) * sizeof (gcov_unsigned_t));
    391       memset (aligned_string, 0, (string_len + 1) * sizeof (gcov_unsigned_t));
    392       aligned_string[0] = string_len;
    393       strcpy ((char*) (aligned_string + 1), string_array[j]);
    394       for (i = 0; i < (string_len + 1); i++)
    395         gcov_write_unsigned (aligned_string[i]);
    396     }
    397 }
    398 
    399 /* Write counter VALUE to coverage file.  Sets error flag
    400    appropriately.  */
    401 
    402 #if IN_LIBGCOV
    403 GCOV_LINKAGE void
    404 gcov_write_counter (gcov_type value)
    405 {
    406   gcov_unsigned_t *buffer = gcov_write_words (2);
    407 
    408   buffer[0] = (gcov_unsigned_t) value;
    409   if (sizeof (value) > sizeof (gcov_unsigned_t))
    410     buffer[1] = (gcov_unsigned_t) (value >> 32);
    411   else
    412     buffer[1] = 0;
    413 }
    414 #endif /* IN_LIBGCOV */
    415 
    416 #if !IN_LIBGCOV
    417 /* Write STRING to coverage file.  Sets error flag on file
    418    error, overflow flag on overflow */
    419 
    420 GCOV_LINKAGE void
    421 gcov_write_string (const char *string)
    422 {
    423   unsigned length = 0;
    424   unsigned alloc = 0;
    425   gcov_unsigned_t *buffer;
    426 
    427   if (string)
    428     {
    429       length = strlen (string);
    430       alloc = (length + 4) >> 2;
    431     }
    432 
    433   buffer = gcov_write_words (1 + alloc);
    434 
    435   buffer[0] = alloc;
    436   buffer[alloc] = 0;
    437   memcpy (&buffer[1], string, length);
    438 }
    439 #endif
    440 
    441 #if !IN_LIBGCOV
    442 /* Write a tag TAG and reserve space for the record length. Return a
    443    value to be used for gcov_write_length.  */
    444 
    445 GCOV_LINKAGE gcov_position_t
    446 gcov_write_tag (gcov_unsigned_t tag)
    447 {
    448   gcov_position_t result = gcov_var.start + gcov_var.offset;
    449   gcov_unsigned_t *buffer = gcov_write_words (2);
    450 
    451   buffer[0] = tag;
    452   buffer[1] = 0;
    453 
    454   return result;
    455 }
    456 
    457 /* Write a record length using POSITION, which was returned by
    458    gcov_write_tag.  The current file position is the end of the
    459    record, and is restored before returning.  Returns nonzero on
    460    overflow.  */
    461 
    462 GCOV_LINKAGE void
    463 gcov_write_length (gcov_position_t position)
    464 {
    465   unsigned offset;
    466   gcov_unsigned_t length;
    467   gcov_unsigned_t *buffer;
    468 
    469   gcc_assert (gcov_var.mode < 0);
    470   gcc_assert (position + 2 <= gcov_var.start + gcov_var.offset);
    471   gcc_assert (position >= gcov_var.start);
    472   offset = position - gcov_var.start;
    473   length = gcov_var.offset - offset - 2;
    474   buffer = (gcov_unsigned_t *) &gcov_var.buffer[offset];
    475   buffer[1] = length;
    476   if (gcov_var.offset >= GCOV_BLOCK_SIZE)
    477     gcov_write_block (gcov_var.offset);
    478 }
    479 
    480 #else /* IN_LIBGCOV */
    481 
    482 /* Write a tag TAG and length LENGTH.  */
    483 
    484 GCOV_LINKAGE void
    485 gcov_write_tag_length (gcov_unsigned_t tag, gcov_unsigned_t length)
    486 {
    487   gcov_unsigned_t *buffer = gcov_write_words (2);
    488 
    489   buffer[0] = tag;
    490   buffer[1] = length;
    491 }
    492 
    493 /* Write a summary structure to the gcov file.  Return nonzero on
    494    overflow.  */
    495 
    496 GCOV_LINKAGE void
    497 gcov_write_summary (gcov_unsigned_t tag, const struct gcov_summary *summary)
    498 {
    499   unsigned ix, h_ix, bv_ix, h_cnt = 0;
    500   const struct gcov_ctr_summary *csum;
    501   unsigned histo_bitvector[GCOV_HISTOGRAM_BITVECTOR_SIZE];
    502 
    503   /* Count number of non-zero histogram entries, and fill in a bit vector
    504      of non-zero indices. The histogram is only currently computed for arc
    505      counters.  */
    506   for (bv_ix = 0; bv_ix < GCOV_HISTOGRAM_BITVECTOR_SIZE; bv_ix++)
    507     histo_bitvector[bv_ix] = 0;
    508   csum = &summary->ctrs[GCOV_COUNTER_ARCS];
    509   for (h_ix = 0; h_ix < GCOV_HISTOGRAM_SIZE; h_ix++)
    510     {
    511       if (csum->histogram[h_ix].num_counters > 0)
    512         {
    513           histo_bitvector[h_ix / 32] |= 1 << (h_ix % 32);
    514           h_cnt++;
    515         }
    516     }
    517   gcov_write_tag_length (tag, GCOV_TAG_SUMMARY_LENGTH (h_cnt));
    518   gcov_write_unsigned (summary->checksum);
    519   for (csum = summary->ctrs, ix = GCOV_COUNTERS_SUMMABLE; ix--; csum++)
    520     {
    521       gcov_write_unsigned (csum->num);
    522       gcov_write_unsigned (csum->runs);
    523       gcov_write_counter (csum->sum_all);
    524       gcov_write_counter (csum->run_max);
    525       gcov_write_counter (csum->sum_max);
    526       if (ix != GCOV_COUNTER_ARCS)
    527         {
    528           for (bv_ix = 0; bv_ix < GCOV_HISTOGRAM_BITVECTOR_SIZE; bv_ix++)
    529             gcov_write_unsigned (0);
    530           continue;
    531         }
    532       for (bv_ix = 0; bv_ix < GCOV_HISTOGRAM_BITVECTOR_SIZE; bv_ix++)
    533         gcov_write_unsigned (histo_bitvector[bv_ix]);
    534       for (h_ix = 0; h_ix < GCOV_HISTOGRAM_SIZE; h_ix++)
    535         {
    536           if (!csum->histogram[h_ix].num_counters)
    537             continue;
    538           gcov_write_unsigned (csum->histogram[h_ix].num_counters);
    539           gcov_write_counter (csum->histogram[h_ix].min_value);
    540           gcov_write_counter (csum->histogram[h_ix].cum_value);
    541         }
    542     }
    543 }
    544 #endif /* IN_LIBGCOV */
    545 
    546 #endif /*!IN_GCOV */
    547 
    548 /* Return a pointer to read BYTES bytes from the gcov file. Returns
    549    NULL on failure (read past EOF).  */
    550 
    551 static const gcov_unsigned_t *
    552 gcov_read_words (unsigned words)
    553 {
    554   const gcov_unsigned_t *result;
    555   unsigned excess = gcov_var.length - gcov_var.offset;
    556 
    557   gcc_assert (gcov_var.mode > 0);
    558   if (excess < words)
    559     {
    560       gcov_var.start += gcov_var.offset;
    561 #if IN_LIBGCOV
    562       if (excess)
    563 	{
    564 	  gcc_assert (excess == 1);
    565 	  memcpy (gcov_var.buffer, gcov_var.buffer + gcov_var.offset, 4);
    566 	}
    567 #else
    568       memmove (gcov_var.buffer, gcov_var.buffer + gcov_var.offset, excess * 4);
    569 #endif
    570       gcov_var.offset = 0;
    571       gcov_var.length = excess;
    572 #if IN_LIBGCOV
    573       gcc_assert (!gcov_var.length || gcov_var.length == 1);
    574       excess = GCOV_BLOCK_SIZE;
    575 #else
    576       if (gcov_var.length + words > gcov_var.alloc)
    577 	gcov_allocate (gcov_var.length + words);
    578       excess = gcov_var.alloc - gcov_var.length;
    579 #endif
    580       excess = _GCOV_fread (gcov_var.buffer + gcov_var.length,
    581 		      1, excess << 2, gcov_var.file) >> 2;
    582       gcov_var.length += excess;
    583       if (gcov_var.length < words)
    584 	{
    585 	  gcov_var.overread += words - gcov_var.length;
    586 	  gcov_var.length = 0;
    587 	  return 0;
    588 	}
    589     }
    590   result = &gcov_var.buffer[gcov_var.offset];
    591   gcov_var.offset += words;
    592   return result;
    593 }
    594 
    595 /* Read unsigned value from a coverage file. Sets error flag on file
    596    error, overflow flag on overflow */
    597 
    598 GCOV_LINKAGE gcov_unsigned_t
    599 gcov_read_unsigned (void)
    600 {
    601   gcov_unsigned_t value;
    602   const gcov_unsigned_t *buffer = gcov_read_words (1);
    603 
    604   if (!buffer)
    605     return 0;
    606   value = from_file (buffer[0]);
    607   return value;
    608 }
    609 
    610 /* Read counter value from a coverage file. Sets error flag on file
    611    error, overflow flag on overflow */
    612 
    613 GCOV_LINKAGE gcov_type
    614 gcov_read_counter (void)
    615 {
    616   gcov_type value;
    617   const gcov_unsigned_t *buffer = gcov_read_words (2);
    618 
    619   if (!buffer)
    620     return 0;
    621   value = from_file (buffer[0]);
    622   if (sizeof (value) > sizeof (gcov_unsigned_t))
    623     value |= ((gcov_type) from_file (buffer[1])) << 32;
    624   else if (buffer[1])
    625     gcov_var.error = -1;
    626 
    627   return value;
    628 }
    629 
    630 /* We need to expose the below function when compiling for gcov-tool.  */
    631 
    632 #if !IN_LIBGCOV || defined (IN_GCOV_TOOL)
    633 /* Read string from coverage file. Returns a pointer to a static
    634    buffer, or NULL on empty string. You must copy the string before
    635    calling another gcov function.  */
    636 
    637 GCOV_LINKAGE const char *
    638 gcov_read_string (void)
    639 {
    640   unsigned length = gcov_read_unsigned ();
    641 
    642   if (!length)
    643     return 0;
    644 
    645   return (const char *) gcov_read_words (length);
    646 }
    647 #endif
    648 
    649 #ifdef __KERNEL__
    650 static int
    651 k_popcountll (long long x)
    652 {
    653   int c = 0;
    654   while (x)
    655     {
    656       c++;
    657       x &= (x-1);
    658     }
    659   return c;
    660 }
    661 #endif
    662 
    663 GCOV_LINKAGE void
    664 gcov_read_summary (struct gcov_summary *summary)
    665 {
    666   unsigned ix, h_ix, bv_ix, h_cnt = 0;
    667   struct gcov_ctr_summary *csum;
    668   unsigned histo_bitvector[GCOV_HISTOGRAM_BITVECTOR_SIZE];
    669   unsigned cur_bitvector;
    670 
    671   summary->checksum = gcov_read_unsigned ();
    672   for (csum = summary->ctrs, ix = GCOV_COUNTERS_SUMMABLE; ix--; csum++)
    673     {
    674       csum->num = gcov_read_unsigned ();
    675       csum->runs = gcov_read_unsigned ();
    676       csum->sum_all = gcov_read_counter ();
    677       csum->run_max = gcov_read_counter ();
    678       csum->sum_max = gcov_read_counter ();
    679       memset (csum->histogram, 0,
    680               sizeof (gcov_bucket_type) * GCOV_HISTOGRAM_SIZE);
    681       for (bv_ix = 0; bv_ix < GCOV_HISTOGRAM_BITVECTOR_SIZE; bv_ix++)
    682         {
    683           histo_bitvector[bv_ix] = gcov_read_unsigned ();
    684 #if IN_LIBGCOV
    685           /* When building libgcov we don't include system.h, which includes
    686              hwint.h (where popcount_hwi is declared). However, libgcov.a
    687              is built by the bootstrapped compiler and therefore the builtins
    688              are always available.  */
    689 #ifndef __KERNEL__
    690           h_cnt += __builtin_popcount (histo_bitvector[bv_ix]);
    691 #else
    692           h_cnt += k_popcountll (histo_bitvector[bv_ix]);
    693 #endif
    694 #else
    695           h_cnt += popcount_hwi (histo_bitvector[bv_ix]);
    696 #endif
    697         }
    698       bv_ix = 0;
    699       h_ix = 0;
    700       cur_bitvector = 0;
    701       while (h_cnt--)
    702         {
    703           /* Find the index corresponding to the next entry we will read in.
    704              First find the next non-zero bitvector and re-initialize
    705              the histogram index accordingly, then right shift and increment
    706              the index until we find a set bit.  */
    707           while (!cur_bitvector)
    708             {
    709               h_ix = bv_ix * 32;
    710               gcc_assert (bv_ix < GCOV_HISTOGRAM_BITVECTOR_SIZE);
    711               cur_bitvector = histo_bitvector[bv_ix++];
    712             }
    713           while (!(cur_bitvector & 0x1))
    714             {
    715               h_ix++;
    716               cur_bitvector >>= 1;
    717             }
    718           gcc_assert (h_ix < GCOV_HISTOGRAM_SIZE);
    719 
    720           csum->histogram[h_ix].num_counters = gcov_read_unsigned ();
    721           csum->histogram[h_ix].min_value = gcov_read_counter ();
    722           csum->histogram[h_ix].cum_value = gcov_read_counter ();
    723           /* Shift off the index we are done with and increment to the
    724              corresponding next histogram entry.  */
    725           cur_bitvector >>= 1;
    726           h_ix++;
    727         }
    728     }
    729 }
    730 
    731 /* Read LENGTH words (unsigned type) from a zero profile fixup record with the
    732    number of function flags saved in NUM_FNS.  Returns the int flag array, which
    733    should be deallocated by caller, or NULL on error.  */
    734 
    735 GCOV_LINKAGE int *
    736 gcov_read_comdat_zero_fixup (gcov_unsigned_t length,
    737                              gcov_unsigned_t *num_fns)
    738 {
    739 #ifndef __KERNEL__
    740   unsigned ix, f_ix;
    741   gcov_unsigned_t num = gcov_read_unsigned ();
    742   /* The length consists of 1 word to hold the number of functions,
    743      plus enough 32-bit words to hold 1 bit/function.  */
    744   gcc_assert ((num + 31) / 32 + 1 == length);
    745   int *zero_fixup_flags = (int *) xcalloc (num, sizeof (int));
    746   for (ix = 0; ix < length - 1; ix++)
    747     {
    748       gcov_unsigned_t bitvector = gcov_read_unsigned ();
    749       f_ix = ix * 32;
    750       while (bitvector)
    751         {
    752           if (bitvector & 0x1)
    753             zero_fixup_flags[f_ix] = 1;
    754           f_ix++;
    755           bitvector >>= 1;
    756         }
    757     }
    758   *num_fns = num;
    759   return zero_fixup_flags;
    760 #else
    761   return NULL;
    762 #endif
    763 }
    764 
    765 /* Read NUM_STRINGS strings (as an unsigned array) in STRING_ARRAY, and return
    766    the number of words read.  */
    767 
    768 GCOV_LINKAGE gcov_unsigned_t
    769 gcov_read_string_array (char **string_array, gcov_unsigned_t num_strings)
    770 {
    771   gcov_unsigned_t i, j, len = 0;
    772 
    773   for (j = 0; j < num_strings; j++)
    774    {
    775      gcov_unsigned_t string_len = gcov_read_unsigned ();
    776      string_array[j] =
    777        (char *) xmalloc (string_len * sizeof (gcov_unsigned_t));
    778      for (i = 0; i < string_len; i++)
    779        ((gcov_unsigned_t *) string_array[j])[i] = gcov_read_unsigned ();
    780      len += (string_len + 1);
    781    }
    782   return len;
    783 }
    784 
    785 /* Read LENGTH words (unsigned type) from a build info record with the number
    786    of strings read saved in NUM_STRINGS.  Returns the string array, which
    787    should be deallocated by caller, or NULL on error.  */
    788 
    789 GCOV_LINKAGE char **
    790 gcov_read_build_info (gcov_unsigned_t length, gcov_unsigned_t *num_strings)
    791 {
    792   gcov_unsigned_t num = gcov_read_unsigned ();
    793   char **build_info_strings = (char **)
    794       xmalloc (sizeof (char *) * num);
    795   gcov_unsigned_t len = gcov_read_string_array (build_info_strings,
    796                                                 num);
    797   if (len != length - 1)
    798     return NULL;
    799   *num_strings = num;
    800   return build_info_strings;
    801 }
    802 
    803 #if (!IN_LIBGCOV && IN_GCOV != 1) || defined (IN_GCOV_TOOL)
    804 /* Read LEN words (unsigned type) and construct MOD_INFO.  */
    805 
    806 GCOV_LINKAGE void
    807 gcov_read_module_info (struct gcov_module_info *mod_info,
    808                        gcov_unsigned_t len)
    809 {
    810   gcov_unsigned_t src_filename_len, filename_len, i, num_strings;
    811   mod_info->ident = gcov_read_unsigned ();
    812   mod_info->is_primary = gcov_read_unsigned ();
    813   mod_info->flags = gcov_read_unsigned ();
    814   mod_info->lang = gcov_read_unsigned ();
    815   mod_info->ggc_memory = gcov_read_unsigned ();
    816   mod_info->num_quote_paths = gcov_read_unsigned ();
    817   mod_info->num_bracket_paths = gcov_read_unsigned ();
    818   mod_info->num_system_paths = gcov_read_unsigned ();
    819   mod_info->num_cpp_defines = gcov_read_unsigned ();
    820   mod_info->num_cpp_includes = gcov_read_unsigned ();
    821   mod_info->num_cl_args = gcov_read_unsigned ();
    822   len -= 11;
    823 
    824   filename_len = gcov_read_unsigned ();
    825   mod_info->da_filename = (char *) xmalloc (filename_len *
    826                                             sizeof (gcov_unsigned_t));
    827   for (i = 0; i < filename_len; i++)
    828     ((gcov_unsigned_t *) mod_info->da_filename)[i] = gcov_read_unsigned ();
    829   len -= (filename_len + 1);
    830 
    831   src_filename_len = gcov_read_unsigned ();
    832   mod_info->source_filename = (char *) xmalloc (src_filename_len *
    833 						sizeof (gcov_unsigned_t));
    834   for (i = 0; i < src_filename_len; i++)
    835     ((gcov_unsigned_t *) mod_info->source_filename)[i] = gcov_read_unsigned ();
    836   len -= (src_filename_len + 1);
    837 
    838   num_strings = mod_info->num_quote_paths + mod_info->num_bracket_paths
    839     + mod_info->num_system_paths
    840     + mod_info->num_cpp_defines + mod_info->num_cpp_includes
    841     + mod_info->num_cl_args;
    842   len -= gcov_read_string_array (mod_info->string_array, num_strings);
    843   gcc_assert (!len);
    844 }
    845 #endif
    846 
    847 /* We need to expose the below function when compiling for gcov-tool.  */
    848 
    849 #if !IN_LIBGCOV || defined (IN_GCOV_TOOL)
    850 /* Reset to a known position.  BASE should have been obtained from
    851    gcov_position, LENGTH should be a record length.  */
    852 
    853 GCOV_LINKAGE void
    854 gcov_sync (gcov_position_t base, gcov_unsigned_t length)
    855 {
    856   gcc_assert (gcov_var.mode > 0);
    857   base += length;
    858   if (base - gcov_var.start <= gcov_var.length)
    859     gcov_var.offset = base - gcov_var.start;
    860   else
    861     {
    862       gcov_var.offset = gcov_var.length = 0;
    863       _GCOV_fseek (gcov_var.file, base << 2, SEEK_SET);
    864       gcov_var.start = _GCOV_ftell (gcov_var.file) >> 2;
    865     }
    866 }
    867 #endif
    868 
    869 #if IN_LIBGCOV
    870 /* Move to a given position in a gcov file.  */
    871 
    872 GCOV_LINKAGE void
    873 gcov_seek (gcov_position_t base)
    874 {
    875   gcc_assert (gcov_var.mode < 0);
    876   if (gcov_var.offset)
    877     gcov_write_block (gcov_var.offset);
    878   _GCOV_fseek (gcov_var.file, base << 2, SEEK_SET);
    879   gcov_var.start = _GCOV_ftell (gcov_var.file) >> 2;
    880 }
    881 
    882 /* Truncate the gcov file at the current position.  */
    883 
    884 GCOV_LINKAGE void
    885 gcov_truncate (void)
    886 {
    887 #ifdef __KERNEL__
    888   gcc_assert (0);
    889 #else
    890   long offs;
    891   int filenum;
    892   gcc_assert (gcov_var.mode < 0);
    893   if (gcov_var.offset)
    894     gcov_write_block (gcov_var.offset);
    895   offs = _GCOV_ftell (gcov_var.file);
    896   filenum = fileno (gcov_var.file);
    897   if (offs == -1 || filenum == -1 || _GCOV_ftruncate (filenum, offs))
    898     gcov_var.error = 1;
    899 #endif /* __KERNEL__ */
    900 }
    901 #endif
    902 
    903 #if IN_GCOV > 0
    904 /* Return the modification time of the current gcov file.  */
    905 
    906 GCOV_LINKAGE time_t
    907 gcov_time (void)
    908 {
    909   struct stat status;
    910 
    911   if (fstat (fileno (gcov_var.file), &status))
    912     return 0;
    913   else
    914     return status.st_mtime;
    915 }
    916 #endif /* IN_GCOV */
    917 
    918 #if !IN_GCOV
    919 /* Determine the index into histogram for VALUE. */
    920 
    921 #if IN_LIBGCOV
    922 static unsigned
    923 #else
    924 GCOV_LINKAGE unsigned
    925 #endif
    926 gcov_histo_index (gcov_type value)
    927 {
    928   gcov_type_unsigned v = (gcov_type_unsigned)value;
    929   unsigned r = 0;
    930   unsigned prev2bits = 0;
    931 
    932   /* Find index into log2 scale histogram, where each of the log2
    933      sized buckets is divided into 4 linear sub-buckets for better
    934      focus in the higher buckets.  */
    935 
    936   /* Find the place of the most-significant bit set.  */
    937   if (v > 0)
    938     {
    939 #if IN_LIBGCOV
    940       /* When building libgcov we don't include system.h, which includes
    941          hwint.h (where floor_log2 is declared). However, libgcov.a
    942          is built by the bootstrapped compiler and therefore the builtins
    943          are always available.  */
    944       r = sizeof (long long) * __CHAR_BIT__ - 1 - __builtin_clzll (v);
    945 #else
    946       /* We use floor_log2 from hwint.c, which takes a HOST_WIDE_INT
    947          that is either 32 or 64 bits, and gcov_type_unsigned may be 64 bits.
    948          Need to check for the case where gcov_type_unsigned is 64 bits
    949          and HOST_WIDE_INT is 32 bits and handle it specially.  */
    950 #if HOST_BITS_PER_WIDEST_INT == HOST_BITS_PER_WIDE_INT
    951       r = floor_log2 (v);
    952 #elif HOST_BITS_PER_WIDEST_INT == 2 * HOST_BITS_PER_WIDE_INT
    953       HOST_WIDE_INT hwi_v = v >> HOST_BITS_PER_WIDE_INT;
    954       if (hwi_v)
    955         r = floor_log2 (hwi_v) + HOST_BITS_PER_WIDE_INT;
    956       else
    957         r = floor_log2 ((HOST_WIDE_INT)v);
    958 #else
    959       gcc_unreachable ();
    960 #endif
    961 #endif
    962     }
    963 
    964   /* If at most the 2 least significant bits are set (value is
    965      0 - 3) then that value is our index into the lowest set of
    966      four buckets.  */
    967   if (r < 2)
    968     return (unsigned)value;
    969 
    970   gcc_assert (r < 64);
    971 
    972   /* Find the two next most significant bits to determine which
    973      of the four linear sub-buckets to select.  */
    974   prev2bits = (v >> (r - 2)) & 0x3;
    975   /* Finally, compose the final bucket index from the log2 index and
    976      the next 2 bits. The minimum r value at this point is 2 since we
    977      returned above if r was 2 or more, so the minimum bucket at this
    978      point is 4.  */
    979   return (r - 1) * 4 + prev2bits;
    980 }
    981 
    982 /* Merge SRC_HISTO into TGT_HISTO. The counters are assumed to be in
    983    the same relative order in both histograms, and are matched up
    984    and merged in reverse order. Each counter is assigned an equal portion of
    985    its entry's original cumulative counter value when computing the
    986    new merged cum_value.  */
    987 
    988 static void gcov_histogram_merge (gcov_bucket_type *tgt_histo,
    989                                   gcov_bucket_type *src_histo)
    990 {
    991   int src_i, tgt_i, tmp_i = 0;
    992   unsigned src_num, tgt_num, merge_num;
    993   gcov_type src_cum, tgt_cum, merge_src_cum, merge_tgt_cum, merge_cum;
    994   gcov_type merge_min;
    995   gcov_bucket_type tmp_histo[GCOV_HISTOGRAM_SIZE];
    996   int src_done = 0;
    997 
    998   memset (tmp_histo, 0, sizeof (gcov_bucket_type) * GCOV_HISTOGRAM_SIZE);
    999 
   1000   /* Assume that the counters are in the same relative order in both
   1001      histograms. Walk the histograms from largest to smallest entry,
   1002      matching up and combining counters in order.  */
   1003   src_num = 0;
   1004   src_cum = 0;
   1005   src_i = GCOV_HISTOGRAM_SIZE - 1;
   1006   for (tgt_i = GCOV_HISTOGRAM_SIZE - 1; tgt_i >= 0 && !src_done; tgt_i--)
   1007     {
   1008       tgt_num = tgt_histo[tgt_i].num_counters;
   1009       tgt_cum = tgt_histo[tgt_i].cum_value;
   1010       /* Keep going until all of the target histogram's counters at this
   1011          position have been matched and merged with counters from the
   1012          source histogram.  */
   1013       while (tgt_num > 0 && !src_done)
   1014         {
   1015           /* If this is either the first time through this loop or we just
   1016              exhausted the previous non-zero source histogram entry, look
   1017              for the next non-zero source histogram entry.  */
   1018           if (!src_num)
   1019             {
   1020               /* Locate the next non-zero entry.  */
   1021               while (src_i >= 0 && !src_histo[src_i].num_counters)
   1022                 src_i--;
   1023               /* If source histogram has fewer counters, then just copy over the
   1024                  remaining target counters and quit.  */
   1025               if (src_i < 0)
   1026                 {
   1027                   tmp_histo[tgt_i].num_counters += tgt_num;
   1028                   tmp_histo[tgt_i].cum_value += tgt_cum;
   1029                   if (!tmp_histo[tgt_i].min_value ||
   1030                       tgt_histo[tgt_i].min_value < tmp_histo[tgt_i].min_value)
   1031                     tmp_histo[tgt_i].min_value = tgt_histo[tgt_i].min_value;
   1032                   while (--tgt_i >= 0)
   1033                     {
   1034                       tmp_histo[tgt_i].num_counters
   1035                           += tgt_histo[tgt_i].num_counters;
   1036                       tmp_histo[tgt_i].cum_value += tgt_histo[tgt_i].cum_value;
   1037                       if (!tmp_histo[tgt_i].min_value ||
   1038                           tgt_histo[tgt_i].min_value
   1039                           < tmp_histo[tgt_i].min_value)
   1040                         tmp_histo[tgt_i].min_value = tgt_histo[tgt_i].min_value;
   1041                     }
   1042 
   1043                   src_done = 1;
   1044                   break;
   1045                 }
   1046 
   1047               src_num = src_histo[src_i].num_counters;
   1048               src_cum = src_histo[src_i].cum_value;
   1049             }
   1050 
   1051           /* The number of counters to merge on this pass is the minimum
   1052              of the remaining counters from the current target and source
   1053              histogram entries.  */
   1054           merge_num = tgt_num;
   1055           if (src_num < merge_num)
   1056             merge_num = src_num;
   1057 
   1058           /* The merged min_value is the sum of the min_values from target
   1059              and source.  */
   1060           merge_min = tgt_histo[tgt_i].min_value + src_histo[src_i].min_value;
   1061 
   1062           /* Compute the portion of source and target entries' cum_value
   1063              that will be apportioned to the counters being merged.
   1064              The total remaining cum_value from each entry is divided
   1065              equally among the counters from that histogram entry if we
   1066              are not merging all of them.  */
   1067           merge_src_cum = src_cum;
   1068           if (merge_num < src_num)
   1069             merge_src_cum = merge_num * src_cum / src_num;
   1070           merge_tgt_cum = tgt_cum;
   1071           if (merge_num < tgt_num)
   1072             merge_tgt_cum = merge_num * tgt_cum / tgt_num;
   1073           /* The merged cum_value is the sum of the source and target
   1074              components.  */
   1075           merge_cum = merge_src_cum + merge_tgt_cum;
   1076 
   1077           /* Update the remaining number of counters and cum_value left
   1078              to be merged from this source and target entry.  */
   1079           src_cum -= merge_src_cum;
   1080           tgt_cum -= merge_tgt_cum;
   1081           src_num -= merge_num;
   1082           tgt_num -= merge_num;
   1083 
   1084           /* The merged counters get placed in the new merged histogram
   1085              at the entry for the merged min_value.  */
   1086           tmp_i = gcov_histo_index (merge_min);
   1087           gcc_assert (tmp_i < GCOV_HISTOGRAM_SIZE);
   1088           tmp_histo[tmp_i].num_counters += merge_num;
   1089           tmp_histo[tmp_i].cum_value += merge_cum;
   1090           if (!tmp_histo[tmp_i].min_value ||
   1091               merge_min < tmp_histo[tmp_i].min_value)
   1092             tmp_histo[tmp_i].min_value = merge_min;
   1093 
   1094           /* Ensure the search for the next non-zero src_histo entry starts
   1095              at the next smallest histogram bucket.  */
   1096           if (!src_num)
   1097             src_i--;
   1098         }
   1099     }
   1100 
   1101   gcc_assert (tgt_i < 0);
   1102 
   1103   /* In the case where there were more counters in the source histogram,
   1104      accumulate the remaining unmerged cumulative counter values. Add
   1105      those to the smallest non-zero target histogram entry. Otherwise,
   1106      the total cumulative counter values in the histogram will be smaller
   1107      than the sum_all stored in the summary, which will complicate
   1108      computing the working set information from the histogram later on.  */
   1109   if (src_num)
   1110     src_i--;
   1111   while (src_i >= 0)
   1112     {
   1113       src_cum += src_histo[src_i].cum_value;
   1114       src_i--;
   1115     }
   1116   /* At this point, tmp_i should be the smallest non-zero entry in the
   1117      tmp_histo.  */
   1118   gcc_assert (tmp_i >= 0 && tmp_i < GCOV_HISTOGRAM_SIZE
   1119 	      && tmp_histo[tmp_i].num_counters > 0);
   1120   tmp_histo[tmp_i].cum_value += src_cum;
   1121 
   1122   /* Finally, copy the merged histogram into tgt_histo.  */
   1123   memcpy (tgt_histo, tmp_histo,
   1124 	  sizeof (gcov_bucket_type) * GCOV_HISTOGRAM_SIZE);
   1125 }
   1126 #endif /* !IN_GCOV */
   1127 
   1128 /* This is used by gcov-dump (IN_GCOV == -1) and in the compiler
   1129    (!IN_GCOV && !IN_LIBGCOV).  */
   1130 #if IN_GCOV <= 0 && !IN_LIBGCOV
   1131 /* Compute the working set information from the counter histogram in
   1132    the profile summary. This is an array of information corresponding to a
   1133    range of percentages of the total execution count (sum_all), and includes
   1134    the number of counters required to cover that working set percentage and
   1135    the minimum counter value in that working set.  */
   1136 
   1137 GCOV_LINKAGE void
   1138 compute_working_sets (const struct gcov_ctr_summary *summary,
   1139                       gcov_working_set_t *gcov_working_sets)
   1140 {
   1141   gcov_type working_set_cum_values[NUM_GCOV_WORKING_SETS];
   1142   gcov_type ws_cum_hotness_incr;
   1143   gcov_type cum, tmp_cum;
   1144   const gcov_bucket_type *histo_bucket;
   1145   unsigned ws_ix, c_num, count;
   1146   int h_ix;
   1147 
   1148   /* Compute the amount of sum_all that the cumulative hotness grows
   1149      by in each successive working set entry, which depends on the
   1150      number of working set entries.  */
   1151   ws_cum_hotness_incr = summary->sum_all / NUM_GCOV_WORKING_SETS;
   1152 
   1153   /* Next fill in an array of the cumulative hotness values corresponding
   1154      to each working set summary entry we are going to compute below.
   1155      Skip 0% statistics, which can be extrapolated from the
   1156      rest of the summary data.  */
   1157   cum = ws_cum_hotness_incr;
   1158   for (ws_ix = 0; ws_ix < NUM_GCOV_WORKING_SETS;
   1159        ws_ix++, cum += ws_cum_hotness_incr)
   1160     working_set_cum_values[ws_ix] = cum;
   1161   /* The last summary entry is reserved for (roughly) 99.9% of the
   1162      working set. Divide by 1024 so it becomes a shift, which gives
   1163      almost exactly 99.9%.  */
   1164   working_set_cum_values[NUM_GCOV_WORKING_SETS-1]
   1165       = summary->sum_all - summary->sum_all/1024;
   1166 
   1167   /* Next, walk through the histogram in decending order of hotness
   1168      and compute the statistics for the working set summary array.
   1169      As histogram entries are accumulated, we check to see which
   1170      working set entries have had their expected cum_value reached
   1171      and fill them in, walking the working set entries in increasing
   1172      size of cum_value.  */
   1173   ws_ix = 0; /* The current entry into the working set array.  */
   1174   cum = 0; /* The current accumulated counter sum.  */
   1175   count = 0; /* The current accumulated count of block counters.  */
   1176   for (h_ix = GCOV_HISTOGRAM_SIZE - 1;
   1177        h_ix >= 0 && ws_ix < NUM_GCOV_WORKING_SETS; h_ix--)
   1178     {
   1179       histo_bucket = &summary->histogram[h_ix];
   1180 
   1181       /* If we haven't reached the required cumulative counter value for
   1182          the current working set percentage, simply accumulate this histogram
   1183          entry into the running sums and continue to the next histogram
   1184          entry.  */
   1185       if (cum + histo_bucket->cum_value < working_set_cum_values[ws_ix])
   1186         {
   1187           cum += histo_bucket->cum_value;
   1188           count += histo_bucket->num_counters;
   1189           continue;
   1190         }
   1191 
   1192       /* If adding the current histogram entry's cumulative counter value
   1193          causes us to exceed the current working set size, then estimate
   1194          how many of this histogram entry's counter values are required to
   1195          reach the working set size, and fill in working set entries
   1196          as we reach their expected cumulative value.  */
   1197       for (c_num = 0, tmp_cum = cum;
   1198            c_num < histo_bucket->num_counters && ws_ix < NUM_GCOV_WORKING_SETS;
   1199            c_num++)
   1200         {
   1201           count++;
   1202           /* If we haven't reached the last histogram entry counter, add
   1203              in the minimum value again. This will underestimate the
   1204              cumulative sum so far, because many of the counter values in this
   1205              entry may have been larger than the minimum. We could add in the
   1206              average value every time, but that would require an expensive
   1207              divide operation.  */
   1208           if (c_num + 1 < histo_bucket->num_counters)
   1209             tmp_cum += histo_bucket->min_value;
   1210           /* If we have reached the last histogram entry counter, then add
   1211              in the entire cumulative value.  */
   1212           else
   1213             tmp_cum = cum + histo_bucket->cum_value;
   1214 
   1215 	  /* Next walk through successive working set entries and fill in
   1216 	     the statistics for any whose size we have reached by accumulating
   1217 	     this histogram counter.  */
   1218 	  while (ws_ix < NUM_GCOV_WORKING_SETS
   1219 		 && tmp_cum >= working_set_cum_values[ws_ix])
   1220             {
   1221               gcov_working_sets[ws_ix].num_counters = count;
   1222               gcov_working_sets[ws_ix].min_counter
   1223                   = histo_bucket->min_value;
   1224               ws_ix++;
   1225             }
   1226         }
   1227       /* Finally, update the running cumulative value since we were
   1228          using a temporary above.  */
   1229       cum += histo_bucket->cum_value;
   1230     }
   1231   gcc_assert (ws_ix == NUM_GCOV_WORKING_SETS);
   1232 }
   1233 #endif /* IN_GCOV <= 0 && !IN_LIBGCOV */
   1234