1 /* Routines required for instrumenting a program. */
2 /* Compile this one with gcc. */
3 /* Copyright (C) 1989-2014 Free Software Foundation, Inc.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 Under Section 7 of GPL version 3, you are granted additional
18 permissions described in the GCC Runtime Library Exception, version
19 3.1, as published by the Free Software Foundation.
21 You should have received a copy of the GNU General Public License and
22 a copy of the GCC Runtime Library Exception along with this program;
23 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
24 <http://www.gnu.org/licenses/>. */
28 #if defined(inhibit_libc)
29 /* If libc and its header files are not available, provide dummy functions. */
32 void __gcov_init (struct gcov_info
*p
__attribute__ ((unused
))) {}
35 #else /* inhibit_libc */
46 /* A utility function for outputing errors. */
47 static int gcov_error (const char *, ...);
53 struct gcov_fn_buffer
*next
;
55 struct gcov_fn_info info
;
56 /* note gcov_fn_info ends in a trailing array. */
59 struct gcov_summary_buffer
61 struct gcov_summary_buffer
*next
;
62 struct gcov_summary summary
;
65 /* A struct that bundles all the related information about the
70 char *filename
; /* filename buffer */
71 size_t max_length
; /* maximum filename length */
72 int strip
; /* leading chars to strip from filename */
73 size_t prefix
; /* chars to prepend to filename */
76 static struct gcov_fn_buffer
*
77 free_fn_data (const struct gcov_info
*gi_ptr
, struct gcov_fn_buffer
*buffer
,
80 struct gcov_fn_buffer
*next
;
81 unsigned ix
, n_ctr
= 0;
87 for (ix
= 0; ix
!= limit
; ix
++)
88 if (gi_ptr
->merge
[ix
])
89 free (buffer
->info
.ctrs
[n_ctr
++].values
);
94 static struct gcov_fn_buffer
**
95 buffer_fn_data (const char *filename
, const struct gcov_info
*gi_ptr
,
96 struct gcov_fn_buffer
**end_ptr
, unsigned fn_ix
)
98 unsigned n_ctrs
= 0, ix
= 0;
99 struct gcov_fn_buffer
*fn_buffer
;
102 for (ix
= GCOV_COUNTERS
; ix
--;)
103 if (gi_ptr
->merge
[ix
])
106 len
= sizeof (*fn_buffer
) + sizeof (fn_buffer
->info
.ctrs
[0]) * n_ctrs
;
107 fn_buffer
= (struct gcov_fn_buffer
*) xmalloc (len
);
113 fn_buffer
->fn_ix
= fn_ix
;
114 fn_buffer
->info
.ident
= gcov_read_unsigned ();
115 fn_buffer
->info
.lineno_checksum
= gcov_read_unsigned ();
116 fn_buffer
->info
.cfg_checksum
= gcov_read_unsigned ();
118 for (n_ctrs
= ix
= 0; ix
!= GCOV_COUNTERS
; ix
++)
120 gcov_unsigned_t length
;
123 if (!gi_ptr
->merge
[ix
])
126 if (gcov_read_unsigned () != GCOV_TAG_FOR_COUNTER (ix
))
132 length
= GCOV_TAG_COUNTER_NUM (gcov_read_unsigned ());
133 len
= length
* sizeof (gcov_type
);
134 values
= (gcov_type
*) xmalloc (len
);
138 fn_buffer
->info
.ctrs
[n_ctrs
].num
= length
;
139 fn_buffer
->info
.ctrs
[n_ctrs
].values
= values
;
142 *values
++ = gcov_read_counter ();
146 *end_ptr
= fn_buffer
;
147 return &fn_buffer
->next
;
150 gcov_error ("profiling:%s:Function %u %s %u \n", filename
, fn_ix
,
151 len
? "cannot allocate" : "counter mismatch", len
? len
: ix
);
153 return (struct gcov_fn_buffer
**)free_fn_data (gi_ptr
, fn_buffer
, ix
);
156 /* Add an unsigned value to the current crc */
158 static gcov_unsigned_t
159 crc32_unsigned (gcov_unsigned_t crc32
, gcov_unsigned_t value
)
163 for (ix
= 32; ix
--; value
<<= 1)
167 feedback
= (value
^ crc32
) & 0x80000000 ? 0x04c11db7 : 0;
175 /* Check if VERSION of the info block PTR matches libgcov one.
176 Return 1 on success, or zero in case of versions mismatch.
177 If FILENAME is not NULL, its value used for reporting purposes
178 instead of value from the info block. */
181 gcov_version (struct gcov_info
*ptr
, gcov_unsigned_t version
,
182 const char *filename
)
184 if (version
!= GCOV_VERSION
)
188 GCOV_UNSIGNED2STRING (v
, version
);
189 GCOV_UNSIGNED2STRING (e
, GCOV_VERSION
);
191 gcov_error ("profiling:%s:Version mismatch - expected %.4s got %.4s\n",
192 filename
? filename
: ptr
->filename
, e
, v
);
198 /* Insert counter VALUE into HISTOGRAM. */
201 gcov_histogram_insert(gcov_bucket_type
*histogram
, gcov_type value
)
205 i
= gcov_histo_index(value
);
206 histogram
[i
].num_counters
++;
207 histogram
[i
].cum_value
+= value
;
208 if (value
< histogram
[i
].min_value
)
209 histogram
[i
].min_value
= value
;
212 /* Computes a histogram of the arc counters to place in the summary SUM. */
215 gcov_compute_histogram (struct gcov_info
*list
, struct gcov_summary
*sum
)
217 struct gcov_info
*gi_ptr
;
218 const struct gcov_fn_info
*gfi_ptr
;
219 const struct gcov_ctr_info
*ci_ptr
;
220 struct gcov_ctr_summary
*cs_ptr
;
221 unsigned t_ix
, f_ix
, ctr_info_ix
, ix
;
224 /* This currently only applies to arc counters. */
225 t_ix
= GCOV_COUNTER_ARCS
;
227 /* First check if there are any counts recorded for this counter. */
228 cs_ptr
= &(sum
->ctrs
[t_ix
]);
232 for (h_ix
= 0; h_ix
< GCOV_HISTOGRAM_SIZE
; h_ix
++)
234 cs_ptr
->histogram
[h_ix
].num_counters
= 0;
235 cs_ptr
->histogram
[h_ix
].min_value
= cs_ptr
->run_max
;
236 cs_ptr
->histogram
[h_ix
].cum_value
= 0;
239 /* Walk through all the per-object structures and record each of
240 the count values in histogram. */
241 for (gi_ptr
= list
; gi_ptr
; gi_ptr
= gi_ptr
->next
)
243 if (!gi_ptr
->merge
[t_ix
])
246 /* Find the appropriate index into the gcov_ctr_info array
247 for the counter we are currently working on based on the
248 existence of the merge function pointer for this object. */
249 for (ix
= 0, ctr_info_ix
= 0; ix
< t_ix
; ix
++)
251 if (gi_ptr
->merge
[ix
])
254 for (f_ix
= 0; f_ix
!= gi_ptr
->n_functions
; f_ix
++)
256 gfi_ptr
= gi_ptr
->functions
[f_ix
];
258 if (!gfi_ptr
|| gfi_ptr
->key
!= gi_ptr
)
261 ci_ptr
= &gfi_ptr
->ctrs
[ctr_info_ix
];
262 for (ix
= 0; ix
< ci_ptr
->num
; ix
++)
263 gcov_histogram_insert (cs_ptr
->histogram
, ci_ptr
->values
[ix
]);
268 /* buffer for the fn_data from another program. */
269 static struct gcov_fn_buffer
*fn_buffer
;
270 /* buffer for summary from other programs to be written out. */
271 static struct gcov_summary_buffer
*sum_buffer
;
273 /* This function computes the program level summary and the histo-gram.
274 It computes and returns CRC32 and stored summary in THIS_PRG.
275 Also determines the longest filename length of the info files. */
277 static gcov_unsigned_t
278 compute_summary (struct gcov_info
*list
, struct gcov_summary
*this_prg
,
281 struct gcov_info
*gi_ptr
;
282 const struct gcov_fn_info
*gfi_ptr
;
283 struct gcov_ctr_summary
*cs_ptr
;
284 const struct gcov_ctr_info
*ci_ptr
;
287 gcov_unsigned_t c_num
;
288 gcov_unsigned_t crc32
= 0;
290 /* Find the totals for this execution. */
291 memset (this_prg
, 0, sizeof (*this_prg
));
293 for (gi_ptr
= list
; gi_ptr
; gi_ptr
= gi_ptr
->next
)
295 size_t len
= strlen (gi_ptr
->filename
);
296 if (len
> *max_length
)
299 crc32
= crc32_unsigned (crc32
, gi_ptr
->stamp
);
300 crc32
= crc32_unsigned (crc32
, gi_ptr
->n_functions
);
302 for (f_ix
= 0; (unsigned)f_ix
!= gi_ptr
->n_functions
; f_ix
++)
304 gfi_ptr
= gi_ptr
->functions
[f_ix
];
306 if (gfi_ptr
&& gfi_ptr
->key
!= gi_ptr
)
309 crc32
= crc32_unsigned (crc32
, gfi_ptr
? gfi_ptr
->cfg_checksum
: 0);
310 crc32
= crc32_unsigned (crc32
,
311 gfi_ptr
? gfi_ptr
->lineno_checksum
: 0);
315 ci_ptr
= gfi_ptr
->ctrs
;
316 for (t_ix
= 0; t_ix
!= GCOV_COUNTERS_SUMMABLE
; t_ix
++)
318 if (!gi_ptr
->merge
[t_ix
])
321 cs_ptr
= &(this_prg
->ctrs
[t_ix
]);
322 cs_ptr
->num
+= ci_ptr
->num
;
323 crc32
= crc32_unsigned (crc32
, ci_ptr
->num
);
325 for (c_num
= 0; c_num
< ci_ptr
->num
; c_num
++)
327 cs_ptr
->sum_all
+= ci_ptr
->values
[c_num
];
328 if (cs_ptr
->run_max
< ci_ptr
->values
[c_num
])
329 cs_ptr
->run_max
= ci_ptr
->values
[c_num
];
335 gcov_compute_histogram (list
, this_prg
);
339 /* Including system dependent components. */
340 #include "libgcov-driver-system.c"
342 /* This function merges counters in GI_PTR to an existing gcda file.
344 Return -1 on error. In this case, caller will goto read_fatal. */
347 merge_one_data (const char *filename
,
348 struct gcov_info
*gi_ptr
,
349 struct gcov_summary
*prg_p
,
350 struct gcov_summary
*this_prg
,
351 gcov_position_t
*summary_pos_p
,
352 gcov_position_t
*eof_pos_p
,
353 gcov_unsigned_t crc32
)
355 gcov_unsigned_t tag
, length
;
359 struct gcov_fn_buffer
**fn_tail
= &fn_buffer
;
360 struct gcov_summary_buffer
**sum_tail
= &sum_buffer
;
362 length
= gcov_read_unsigned ();
363 if (!gcov_version (gi_ptr
, length
, filename
))
366 length
= gcov_read_unsigned ();
367 if (length
!= gi_ptr
->stamp
)
368 /* Read from a different compilation. Overwrite the file. */
371 /* Look for program summary. */
374 struct gcov_summary tmp
;
376 *eof_pos_p
= gcov_position ();
377 tag
= gcov_read_unsigned ();
378 if (tag
!= GCOV_TAG_PROGRAM_SUMMARY
)
382 length
= gcov_read_unsigned ();
383 gcov_read_summary (&tmp
);
384 if ((error
= gcov_is_error ()))
388 /* Save all summaries after the one that will be
389 merged into below. These will need to be rewritten
390 as histogram merging may change the number of non-zero
391 histogram entries that will be emitted, and thus the
392 size of the merged summary. */
393 (*sum_tail
) = (struct gcov_summary_buffer
*)
394 xmalloc (sizeof(struct gcov_summary_buffer
));
395 (*sum_tail
)->summary
= tmp
;
396 (*sum_tail
)->next
= 0;
397 sum_tail
= &((*sum_tail
)->next
);
400 if (tmp
.checksum
!= crc32
)
403 for (t_ix
= 0; t_ix
!= GCOV_COUNTERS_SUMMABLE
; t_ix
++)
404 if (tmp
.ctrs
[t_ix
].num
!= this_prg
->ctrs
[t_ix
].num
)
407 *summary_pos_p
= *eof_pos_p
;
412 /* Merge execution counts for each function. */
413 for (f_ix
= 0; (unsigned)f_ix
!= gi_ptr
->n_functions
;
414 f_ix
++, tag
= gcov_read_unsigned ())
416 const struct gcov_ctr_info
*ci_ptr
;
417 const struct gcov_fn_info
*gfi_ptr
= gi_ptr
->functions
[f_ix
];
419 if (tag
!= GCOV_TAG_FUNCTION
)
422 length
= gcov_read_unsigned ();
424 /* This function did not appear in the other program.
425 We have nothing to merge. */
428 if (length
!= GCOV_TAG_FUNCTION_LENGTH
)
431 if (!gfi_ptr
|| gfi_ptr
->key
!= gi_ptr
)
433 /* This function appears in the other program. We
434 need to buffer the information in order to write
435 it back out -- we'll be inserting data before
436 this point, so cannot simply keep the data in the
438 fn_tail
= buffer_fn_data (filename
, gi_ptr
, fn_tail
, f_ix
);
444 length
= gcov_read_unsigned ();
445 if (length
!= gfi_ptr
->ident
)
448 length
= gcov_read_unsigned ();
449 if (length
!= gfi_ptr
->lineno_checksum
)
452 length
= gcov_read_unsigned ();
453 if (length
!= gfi_ptr
->cfg_checksum
)
456 ci_ptr
= gfi_ptr
->ctrs
;
457 for (t_ix
= 0; t_ix
< GCOV_COUNTERS
; t_ix
++)
459 gcov_merge_fn merge
= gi_ptr
->merge
[t_ix
];
464 tag
= gcov_read_unsigned ();
465 length
= gcov_read_unsigned ();
466 if (tag
!= GCOV_TAG_FOR_COUNTER (t_ix
)
467 || length
!= GCOV_TAG_COUNTER_LENGTH (ci_ptr
->num
))
469 (*merge
) (ci_ptr
->values
, ci_ptr
->num
);
472 if ((error
= gcov_is_error ()))
479 gcov_error ("profiling:%s:Merge mismatch for %s %u\n",
480 filename
, f_ix
>= 0 ? "function" : "summary",
481 f_ix
< 0 ? -1 - f_ix
: f_ix
);
487 gcov_error ("profiling:%s:%s merging\n", filename
,
488 error
< 0 ? "Overflow": "Error");
492 /* Write counters in GI_PTR and the summary in PRG to a gcda file. In
493 the case of appending to an existing file, SUMMARY_POS will be non-zero.
494 We will write the file starting from SUMMAY_POS. */
497 write_one_data (const struct gcov_info
*gi_ptr
,
498 const struct gcov_summary
*prg_p
,
499 const gcov_position_t eof_pos
,
500 const gcov_position_t summary_pos
)
503 struct gcov_summary_buffer
*next_sum_buffer
;
505 /* Write out the data. */
508 gcov_write_tag_length (GCOV_DATA_MAGIC
, GCOV_VERSION
);
509 gcov_write_unsigned (gi_ptr
->stamp
);
513 gcov_seek (summary_pos
);
515 /* Generate whole program statistics. */
516 gcov_write_summary (GCOV_TAG_PROGRAM_SUMMARY
, prg_p
);
518 /* Rewrite all the summaries that were after the summary we merged
519 into. This is necessary as the merged summary may have a different
520 size due to the number of non-zero histogram entries changing after
525 gcov_write_summary (GCOV_TAG_PROGRAM_SUMMARY
, &sum_buffer
->summary
);
526 next_sum_buffer
= sum_buffer
->next
;
528 sum_buffer
= next_sum_buffer
;
531 /* Write execution counts for each function. */
532 for (f_ix
= 0; f_ix
!= gi_ptr
->n_functions
; f_ix
++)
534 unsigned buffered
= 0;
535 const struct gcov_fn_info
*gfi_ptr
;
536 const struct gcov_ctr_info
*ci_ptr
;
537 gcov_unsigned_t length
;
540 if (fn_buffer
&& fn_buffer
->fn_ix
== f_ix
)
542 /* Buffered data from another program. */
544 gfi_ptr
= &fn_buffer
->info
;
545 length
= GCOV_TAG_FUNCTION_LENGTH
;
549 gfi_ptr
= gi_ptr
->functions
[f_ix
];
550 if (gfi_ptr
&& gfi_ptr
->key
== gi_ptr
)
551 length
= GCOV_TAG_FUNCTION_LENGTH
;
556 gcov_write_tag_length (GCOV_TAG_FUNCTION
, length
);
560 gcov_write_unsigned (gfi_ptr
->ident
);
561 gcov_write_unsigned (gfi_ptr
->lineno_checksum
);
562 gcov_write_unsigned (gfi_ptr
->cfg_checksum
);
564 ci_ptr
= gfi_ptr
->ctrs
;
565 for (t_ix
= 0; t_ix
< GCOV_COUNTERS
; t_ix
++)
567 gcov_unsigned_t n_counts
;
570 if (!gi_ptr
->merge
[t_ix
])
573 n_counts
= ci_ptr
->num
;
574 gcov_write_tag_length (GCOV_TAG_FOR_COUNTER (t_ix
),
575 GCOV_TAG_COUNTER_LENGTH (n_counts
));
576 c_ptr
= ci_ptr
->values
;
578 gcov_write_counter (*c_ptr
++);
582 fn_buffer
= free_fn_data (gi_ptr
, fn_buffer
, GCOV_COUNTERS
);
585 gcov_write_unsigned (0);
588 /* Helper function for merging summary.
589 Return -1 on error. Return 0 on success. */
592 merge_summary (const char *filename
, int run_counted
,
593 const struct gcov_info
*gi_ptr
, struct gcov_summary
*prg
,
594 struct gcov_summary
*this_prg
, gcov_unsigned_t crc32
,
595 struct gcov_summary
*all_prg
__attribute__ ((unused
)))
597 struct gcov_ctr_summary
*cs_prg
, *cs_tprg
;
600 /* summary for all instances of program. */
601 struct gcov_ctr_summary
*cs_all
;
604 /* Merge the summaries. */
605 for (t_ix
= 0; t_ix
< GCOV_COUNTERS_SUMMABLE
; t_ix
++)
607 cs_prg
= &(prg
->ctrs
[t_ix
]);
608 cs_tprg
= &(this_prg
->ctrs
[t_ix
]);
610 if (gi_ptr
->merge
[t_ix
])
612 int first
= !cs_prg
->runs
;
617 cs_prg
->num
= cs_tprg
->num
;
618 cs_prg
->sum_all
+= cs_tprg
->sum_all
;
619 if (cs_prg
->run_max
< cs_tprg
->run_max
)
620 cs_prg
->run_max
= cs_tprg
->run_max
;
621 cs_prg
->sum_max
+= cs_tprg
->run_max
;
623 memcpy (cs_prg
->histogram
, cs_tprg
->histogram
,
624 sizeof (gcov_bucket_type
) * GCOV_HISTOGRAM_SIZE
);
626 gcov_histogram_merge (cs_prg
->histogram
, cs_tprg
->histogram
);
628 else if (cs_prg
->runs
)
630 gcov_error ("profiling:%s:Merge mismatch for summary.\n",
635 cs_all
= &all_prg
->ctrs
[t_ix
];
636 if (!cs_all
->runs
&& cs_prg
->runs
)
638 cs_all
->num
= cs_prg
->num
;
639 cs_all
->runs
= cs_prg
->runs
;
640 cs_all
->sum_all
= cs_prg
->sum_all
;
641 cs_all
->run_max
= cs_prg
->run_max
;
642 cs_all
->sum_max
= cs_prg
->sum_max
;
644 else if (!all_prg
->checksum
645 /* Don't compare the histograms, which may have slight
646 variations depending on the order they were updated
647 due to the truncating integer divides used in the
649 && (cs_all
->num
!= cs_prg
->num
650 || cs_all
->runs
!= cs_prg
->runs
651 || cs_all
->sum_all
!= cs_prg
->sum_all
652 || cs_all
->run_max
!= cs_prg
->run_max
653 || cs_all
->sum_max
!= cs_prg
->sum_max
))
655 gcov_error ("profiling:%s:Data file mismatch - some "
656 "data files may have been concurrently "
657 "updated without locking support\n", filename
);
658 all_prg
->checksum
= ~0u;
663 prg
->checksum
= crc32
;
668 /* Dump the coverage counts for one gcov_info object. We merge with existing
669 counts when possible, to avoid growing the .da files ad infinitum. We use
670 this program's checksum to make sure we only accumulate whole program
671 statistics to the correct summary. An object file might be embedded
672 in two separate programs, and we must keep the two program
673 summaries separate. */
676 dump_one_gcov (struct gcov_info
*gi_ptr
, struct gcov_filename
*gf
,
677 unsigned run_counted
,
678 gcov_unsigned_t crc32
, struct gcov_summary
*all_prg
,
679 struct gcov_summary
*this_prg
)
681 struct gcov_summary prg
; /* summary for this object over all program. */
684 gcov_position_t summary_pos
= 0;
685 gcov_position_t eof_pos
= 0;
690 error
= gcov_exit_open_gcda_file (gi_ptr
, gf
);
694 tag
= gcov_read_unsigned ();
697 /* Merge data from file. */
698 if (tag
!= GCOV_DATA_MAGIC
)
700 gcov_error ("profiling:%s:Not a gcov data file\n", gf
->filename
);
703 error
= merge_one_data (gf
->filename
, gi_ptr
, &prg
, this_prg
,
704 &summary_pos
, &eof_pos
, crc32
);
713 memset (&prg
, 0, sizeof (prg
));
714 summary_pos
= eof_pos
;
717 error
= merge_summary (gf
->filename
, run_counted
, gi_ptr
, &prg
, this_prg
,
722 write_one_data (gi_ptr
, &prg
, eof_pos
, summary_pos
);
727 fn_buffer
= free_fn_data (gi_ptr
, fn_buffer
, GCOV_COUNTERS
);
729 if ((error
= gcov_close ()))
730 gcov_error (error
< 0 ?
731 "profiling:%s:Overflow writing\n" :
732 "profiling:%s:Error writing\n",
737 /* Dump all the coverage counts for the program. It first computes program
738 summary and then traverses gcov_list list and dumps the gcov_info
739 objects one by one. */
745 gcov_do_dump (struct gcov_info
*list
, int run_counted
)
747 struct gcov_info
*gi_ptr
;
748 struct gcov_filename gf
;
749 gcov_unsigned_t crc32
;
750 struct gcov_summary all_prg
;
751 struct gcov_summary this_prg
;
753 crc32
= compute_summary (list
, &this_prg
, &gf
.max_length
);
755 allocate_filename_struct (&gf
);
757 memset (&all_prg
, 0, sizeof (all_prg
));
760 /* Now merge each file. */
761 for (gi_ptr
= list
; gi_ptr
; gi_ptr
= gi_ptr
->next
)
762 dump_one_gcov (gi_ptr
, &gf
, run_counted
, crc32
, &all_prg
, &this_prg
);
769 __gcov_dump_one (struct gcov_root
*root
)
774 gcov_do_dump (root
->list
, root
->run_counted
);
777 root
->run_counted
= 1;
780 /* Per-program/shared-object gcov state. */
781 struct gcov_root __gcov_root
;
786 __gcov_dump_one (&__gcov_root
);
789 /* Add a new object file onto the bb chain. Invoked automatically
790 when running an object file's global ctors. */
793 __gcov_init (struct gcov_info
*info
)
795 if (!info
->version
|| !info
->n_functions
)
797 if (gcov_version (info
, info
->version
, 0))
799 if (!__gcov_root
.list
)
802 info
->next
= __gcov_root
.list
;
803 __gcov_root
.list
= info
;
807 #endif /* !IN_GCOV_TOOL */
809 #endif /* inhibit_libc */