1/* File format for coverage information
2   Copyright (C) 1996-2014 Free Software Foundation, Inc.
3   Contributed by Bob Manson <manson@cygnus.com>.
4   Completely remangled by Nathan Sidwell <nathan@codesourcery.com>.
5
6This file is part of GCC.
7
8GCC is free software; you can redistribute it and/or modify it under
9the terms of the GNU General Public License as published by the Free
10Software Foundation; either version 3, or (at your option) any later
11version.
12
13GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14WARRANTY; without even the implied warranty of MERCHANTABILITY or
15FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16for more details.
17
18Under Section 7 of GPL version 3, you are granted additional
19permissions described in the GCC Runtime Library Exception, version
203.1, as published by the Free Software Foundation.
21
22You should have received a copy of the GNU General Public License and
23a copy of the GCC Runtime Library Exception along with this program;
24see 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
31static void gcov_write_block (unsigned);
32static gcov_unsigned_t *gcov_write_words (unsigned);
33#endif
34static const gcov_unsigned_t *gcov_read_words (unsigned);
35#if !IN_LIBGCOV
36static 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
42GCOV_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
69static inline
70#endif
71gcov_position_t
72gcov_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
80static inline
81#endif
82int
83gcov_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.  */
90GCOV_LINKAGE inline void
91gcov_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
101static 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
123GCOV_LINKAGE int
124#if IN_LIBGCOV
125gcov_open (const char *name)
126#else
127gcov_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
228GCOV_LINKAGE int
229gcov_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
255GCOV_LINKAGE int
256gcov_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
272static void
273gcov_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
290static void
291gcov_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
302static gcov_unsigned_t *
303gcov_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
331GCOV_LINKAGE void
332gcov_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
343GCOV_LINKAGE void
344gcov_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
360GCOV_LINKAGE void
361gcov_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
385GCOV_LINKAGE gcov_position_t
386gcov_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
402GCOV_LINKAGE void
403gcov_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
424GCOV_LINKAGE void
425gcov_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
436GCOV_LINKAGE void
437gcov_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
491static const gcov_unsigned_t *
492gcov_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
538GCOV_LINKAGE gcov_unsigned_t
539gcov_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
553GCOV_LINKAGE gcov_type
554gcov_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
577GCOV_LINKAGE const char *
578gcov_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
589GCOV_LINKAGE void
590gcov_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
656GCOV_LINKAGE void
657gcov_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
712GCOV_LINKAGE void
713gcov_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
731GCOV_LINKAGE void
732gcov_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
743GCOV_LINKAGE void
744gcov_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
761GCOV_LINKAGE time_t
762gcov_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
777static unsigned
778#else
779GCOV_LINKAGE unsigned
780#endif
781gcov_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
843static 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
992GCOV_LINKAGE void
993compute_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