blob: f226cbf0e682368c7143239a0f7941bbdbada997 [file] [log] [blame]
Rong Xua1f277f2014-09-05 13:42:16 -07001/* 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 */