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