1 /* Routines required for instrumenting a program. */
2 /* Compile this one with gcc. */
3 /* Copyright (C) 1989-2013 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 #include "coretypes.h"
30 #include "libgcc_tm.h"
32 #if defined(inhibit_libc)
33 #define IN_LIBGCOV (-1)
37 #define GCOV_LINKAGE /* nothing */
42 #if defined(inhibit_libc)
43 /* If libc and its header files are not available, provide dummy functions. */
46 void __gcov_init (struct gcov_info
*p
__attribute__ ((unused
))) {}
49 #else /* inhibit_libc */
61 /* The following functions can be called from outside of this file. */
62 extern void gcov_clear (void) ATTRIBUTE_HIDDEN
;
63 extern void gcov_exit (void) ATTRIBUTE_HIDDEN
;
64 extern void set_gcov_dump_complete (void) ATTRIBUTE_HIDDEN
;
65 extern void reset_gcov_dump_complete (void) ATTRIBUTE_HIDDEN
;
66 extern int get_gcov_dump_complete (void) ATTRIBUTE_HIDDEN
;
67 extern void set_gcov_list (struct gcov_info
*) ATTRIBUTE_HIDDEN
;
71 struct gcov_fn_buffer
*next
;
73 struct gcov_fn_info info
;
74 /* note gcov_fn_info ends in a trailing array. */
77 struct gcov_summary_buffer
79 struct gcov_summary_buffer
*next
;
80 struct gcov_summary summary
;
83 /* Chain of per-object gcov structures. */
84 static struct gcov_info
*gcov_list
;
86 /* Set the head of gcov_list. */
88 set_gcov_list (struct gcov_info
*head
)
93 /* Size of the longest file name. */
94 static size_t gcov_max_filename
= 0;
96 /* Flag when the profile has already been dumped via __gcov_dump(). */
97 static int gcov_dump_complete
;
99 /* A global function that get the vaule of gcov_dump_complete. */
102 get_gcov_dump_complete (void)
104 return gcov_dump_complete
;
107 /* A global functino that set the vaule of gcov_dump_complete. Will
108 be used in __gcov_dump() in libgcov-interface.c. */
111 set_gcov_dump_complete (void)
113 gcov_dump_complete
= 1;
116 /* A global functino that set the vaule of gcov_dump_complete. Will
117 be used in __gcov_reset() in libgcov-interface.c. */
120 reset_gcov_dump_complete (void)
122 gcov_dump_complete
= 0;
125 /* A utility function for outputing errors. */
126 static int gcov_error (const char *, ...);
128 static struct gcov_fn_buffer
*
129 free_fn_data (const struct gcov_info
*gi_ptr
, struct gcov_fn_buffer
*buffer
,
132 struct gcov_fn_buffer
*next
;
133 unsigned ix
, n_ctr
= 0;
139 for (ix
= 0; ix
!= limit
; ix
++)
140 if (gi_ptr
->merge
[ix
])
141 free (buffer
->info
.ctrs
[n_ctr
++].values
);
146 static struct gcov_fn_buffer
**
147 buffer_fn_data (const char *filename
, const struct gcov_info
*gi_ptr
,
148 struct gcov_fn_buffer
**end_ptr
, unsigned fn_ix
)
150 unsigned n_ctrs
= 0, ix
= 0;
151 struct gcov_fn_buffer
*fn_buffer
;
154 for (ix
= GCOV_COUNTERS
; ix
--;)
155 if (gi_ptr
->merge
[ix
])
158 len
= sizeof (*fn_buffer
) + sizeof (fn_buffer
->info
.ctrs
[0]) * n_ctrs
;
159 fn_buffer
= (struct gcov_fn_buffer
*)malloc (len
);
165 fn_buffer
->fn_ix
= fn_ix
;
166 fn_buffer
->info
.ident
= gcov_read_unsigned ();
167 fn_buffer
->info
.lineno_checksum
= gcov_read_unsigned ();
168 fn_buffer
->info
.cfg_checksum
= gcov_read_unsigned ();
170 for (n_ctrs
= ix
= 0; ix
!= GCOV_COUNTERS
; ix
++)
172 gcov_unsigned_t length
;
175 if (!gi_ptr
->merge
[ix
])
178 if (gcov_read_unsigned () != GCOV_TAG_FOR_COUNTER (ix
))
184 length
= GCOV_TAG_COUNTER_NUM (gcov_read_unsigned ());
185 len
= length
* sizeof (gcov_type
);
186 values
= (gcov_type
*)malloc (len
);
190 fn_buffer
->info
.ctrs
[n_ctrs
].num
= length
;
191 fn_buffer
->info
.ctrs
[n_ctrs
].values
= values
;
194 *values
++ = gcov_read_counter ();
198 *end_ptr
= fn_buffer
;
199 return &fn_buffer
->next
;
202 gcov_error ("profiling:%s:Function %u %s %u \n", filename
, fn_ix
,
203 len
? "cannot allocate" : "counter mismatch", len
? len
: ix
);
205 return (struct gcov_fn_buffer
**)free_fn_data (gi_ptr
, fn_buffer
, ix
);
208 /* Add an unsigned value to the current crc */
210 static gcov_unsigned_t
211 crc32_unsigned (gcov_unsigned_t crc32
, gcov_unsigned_t value
)
215 for (ix
= 32; ix
--; value
<<= 1)
219 feedback
= (value
^ crc32
) & 0x80000000 ? 0x04c11db7 : 0;
227 /* Check if VERSION of the info block PTR matches libgcov one.
228 Return 1 on success, or zero in case of versions mismatch.
229 If FILENAME is not NULL, its value used for reporting purposes
230 instead of value from the info block. */
233 gcov_version (struct gcov_info
*ptr
, gcov_unsigned_t version
,
234 const char *filename
)
236 if (version
!= GCOV_VERSION
)
240 GCOV_UNSIGNED2STRING (v
, version
);
241 GCOV_UNSIGNED2STRING (e
, GCOV_VERSION
);
243 gcov_error ("profiling:%s:Version mismatch - expected %.4s got %.4s\n",
244 filename
? filename
: ptr
->filename
, e
, v
);
250 /* Insert counter VALUE into HISTOGRAM. */
253 gcov_histogram_insert(gcov_bucket_type
*histogram
, gcov_type value
)
257 i
= gcov_histo_index(value
);
258 histogram
[i
].num_counters
++;
259 histogram
[i
].cum_value
+= value
;
260 if (value
< histogram
[i
].min_value
)
261 histogram
[i
].min_value
= value
;
264 /* Computes a histogram of the arc counters to place in the summary SUM. */
267 gcov_compute_histogram (struct gcov_summary
*sum
)
269 struct gcov_info
*gi_ptr
;
270 const struct gcov_fn_info
*gfi_ptr
;
271 const struct gcov_ctr_info
*ci_ptr
;
272 struct gcov_ctr_summary
*cs_ptr
;
273 unsigned t_ix
, f_ix
, ctr_info_ix
, ix
;
276 /* This currently only applies to arc counters. */
277 t_ix
= GCOV_COUNTER_ARCS
;
279 /* First check if there are any counts recorded for this counter. */
280 cs_ptr
= &(sum
->ctrs
[t_ix
]);
284 for (h_ix
= 0; h_ix
< GCOV_HISTOGRAM_SIZE
; h_ix
++)
286 cs_ptr
->histogram
[h_ix
].num_counters
= 0;
287 cs_ptr
->histogram
[h_ix
].min_value
= cs_ptr
->run_max
;
288 cs_ptr
->histogram
[h_ix
].cum_value
= 0;
291 /* Walk through all the per-object structures and record each of
292 the count values in histogram. */
293 for (gi_ptr
= gcov_list
; gi_ptr
; gi_ptr
= gi_ptr
->next
)
295 if (!gi_ptr
->merge
[t_ix
])
298 /* Find the appropriate index into the gcov_ctr_info array
299 for the counter we are currently working on based on the
300 existence of the merge function pointer for this object. */
301 for (ix
= 0, ctr_info_ix
= 0; ix
< t_ix
; ix
++)
303 if (gi_ptr
->merge
[ix
])
306 for (f_ix
= 0; f_ix
!= gi_ptr
->n_functions
; f_ix
++)
308 gfi_ptr
= gi_ptr
->functions
[f_ix
];
310 if (!gfi_ptr
|| gfi_ptr
->key
!= gi_ptr
)
313 ci_ptr
= &gfi_ptr
->ctrs
[ctr_info_ix
];
314 for (ix
= 0; ix
< ci_ptr
->num
; ix
++)
315 gcov_histogram_insert (cs_ptr
->histogram
, ci_ptr
->values
[ix
]);
320 /* summary for program. */
321 static struct gcov_summary this_prg
;
323 static char *gi_filename
;
324 /* buffer for the fn_data from another program. */
325 static struct gcov_fn_buffer
*fn_buffer
;
326 /* buffer for summary from other programs to be written out. */
327 static struct gcov_summary_buffer
*sum_buffer
;
329 /* This funtions computes the program level summary and the histo-gram.
330 It computes and returns CRC32 and stored summari in THIS_PRG. */
332 static gcov_unsigned_t
333 gcov_exit_compute_summary (void)
335 struct gcov_info
*gi_ptr
;
336 const struct gcov_fn_info
*gfi_ptr
;
337 struct gcov_ctr_summary
*cs_ptr
;
338 const struct gcov_ctr_info
*ci_ptr
;
341 gcov_unsigned_t c_num
;
342 gcov_unsigned_t crc32
= 0;
344 /* Find the totals for this execution. */
345 memset (&this_prg
, 0, sizeof (this_prg
));
346 for (gi_ptr
= gcov_list
; gi_ptr
; gi_ptr
= gi_ptr
->next
)
348 crc32
= crc32_unsigned (crc32
, gi_ptr
->stamp
);
349 crc32
= crc32_unsigned (crc32
, gi_ptr
->n_functions
);
351 for (f_ix
= 0; (unsigned)f_ix
!= gi_ptr
->n_functions
; f_ix
++)
353 gfi_ptr
= gi_ptr
->functions
[f_ix
];
355 if (gfi_ptr
&& gfi_ptr
->key
!= gi_ptr
)
358 crc32
= crc32_unsigned (crc32
, gfi_ptr
? gfi_ptr
->cfg_checksum
: 0);
359 crc32
= crc32_unsigned (crc32
,
360 gfi_ptr
? gfi_ptr
->lineno_checksum
: 0);
364 ci_ptr
= gfi_ptr
->ctrs
;
365 for (t_ix
= 0; t_ix
!= GCOV_COUNTERS_SUMMABLE
; t_ix
++)
367 if (!gi_ptr
->merge
[t_ix
])
370 cs_ptr
= &this_prg
.ctrs
[t_ix
];
371 cs_ptr
->num
+= ci_ptr
->num
;
372 crc32
= crc32_unsigned (crc32
, ci_ptr
->num
);
374 for (c_num
= 0; c_num
< ci_ptr
->num
; c_num
++)
376 cs_ptr
->sum_all
+= ci_ptr
->values
[c_num
];
377 if (cs_ptr
->run_max
< ci_ptr
->values
[c_num
])
378 cs_ptr
->run_max
= ci_ptr
->values
[c_num
];
384 gcov_compute_histogram (&this_prg
);
388 /* A struct that bundles all the related information about the
390 struct gcov_filename_aux
{
391 char *gi_filename_up
;
392 int gcov_prefix_strip
;
393 size_t prefix_length
;
396 /* Including system dependent components. */
397 #include "libgcov-driver-system.c"
399 /* This function merges counters in GI_PTR to an existing gcda file.
401 Return -1 on error. In this case, caller will goto read_fatal. */
404 gcov_exit_merge_gcda (struct gcov_info
*gi_ptr
,
405 struct gcov_summary
*prg_p
,
406 gcov_position_t
*summary_pos_p
,
407 gcov_position_t
*eof_pos_p
,
408 gcov_unsigned_t crc32
)
410 gcov_unsigned_t tag
, length
;
414 struct gcov_fn_buffer
**fn_tail
= &fn_buffer
;
415 struct gcov_summary_buffer
**sum_tail
= &sum_buffer
;
417 length
= gcov_read_unsigned ();
418 if (!gcov_version (gi_ptr
, length
, gi_filename
))
421 length
= gcov_read_unsigned ();
422 if (length
!= gi_ptr
->stamp
)
423 /* Read from a different compilation. Overwrite the file. */
426 /* Look for program summary. */
429 struct gcov_summary tmp
;
431 *eof_pos_p
= gcov_position ();
432 tag
= gcov_read_unsigned ();
433 if (tag
!= GCOV_TAG_PROGRAM_SUMMARY
)
437 length
= gcov_read_unsigned ();
438 gcov_read_summary (&tmp
);
439 if ((error
= gcov_is_error ()))
443 /* Save all summaries after the one that will be
444 merged into below. These will need to be rewritten
445 as histogram merging may change the number of non-zero
446 histogram entries that will be emitted, and thus the
447 size of the merged summary. */
448 (*sum_tail
) = (struct gcov_summary_buffer
*)
449 malloc (sizeof(struct gcov_summary_buffer
));
450 (*sum_tail
)->summary
= tmp
;
451 (*sum_tail
)->next
= 0;
452 sum_tail
= &((*sum_tail
)->next
);
455 if (tmp
.checksum
!= crc32
)
458 for (t_ix
= 0; t_ix
!= GCOV_COUNTERS_SUMMABLE
; t_ix
++)
459 if (tmp
.ctrs
[t_ix
].num
!= this_prg
.ctrs
[t_ix
].num
)
462 *summary_pos_p
= *eof_pos_p
;
467 /* Merge execution counts for each function. */
468 for (f_ix
= 0; (unsigned)f_ix
!= gi_ptr
->n_functions
;
469 f_ix
++, tag
= gcov_read_unsigned ())
471 const struct gcov_ctr_info
*ci_ptr
;
472 const struct gcov_fn_info
*gfi_ptr
= gi_ptr
->functions
[f_ix
];
474 if (tag
!= GCOV_TAG_FUNCTION
)
477 length
= gcov_read_unsigned ();
479 /* This function did not appear in the other program.
480 We have nothing to merge. */
483 if (length
!= GCOV_TAG_FUNCTION_LENGTH
)
486 if (!gfi_ptr
|| gfi_ptr
->key
!= gi_ptr
)
488 /* This function appears in the other program. We
489 need to buffer the information in order to write
490 it back out -- we'll be inserting data before
491 this point, so cannot simply keep the data in the
493 fn_tail
= buffer_fn_data (gi_filename
,
494 gi_ptr
, fn_tail
, f_ix
);
500 length
= gcov_read_unsigned ();
501 if (length
!= gfi_ptr
->ident
)
504 length
= gcov_read_unsigned ();
505 if (length
!= gfi_ptr
->lineno_checksum
)
508 length
= gcov_read_unsigned ();
509 if (length
!= gfi_ptr
->cfg_checksum
)
512 ci_ptr
= gfi_ptr
->ctrs
;
513 for (t_ix
= 0; t_ix
< GCOV_COUNTERS
; t_ix
++)
515 gcov_merge_fn merge
= gi_ptr
->merge
[t_ix
];
520 tag
= gcov_read_unsigned ();
521 length
= gcov_read_unsigned ();
522 if (tag
!= GCOV_TAG_FOR_COUNTER (t_ix
)
523 || length
!= GCOV_TAG_COUNTER_LENGTH (ci_ptr
->num
))
525 (*merge
) (ci_ptr
->values
, ci_ptr
->num
);
528 if ((error
= gcov_is_error ()))
535 gcov_error ("profiling:%s:Merge mismatch for %s %u\n",
536 gi_filename
, f_ix
>= 0 ? "function" : "summary",
537 f_ix
< 0 ? -1 - f_ix
: f_ix
);
543 gcov_error ("profiling:%s:%s merging\n", gi_filename
,
544 error
< 0 ? "Overflow": "Error");
548 /* Write counters in GI_PTR and the summary in PRG to a gcda file. In
549 the case of appending to an existing file, SUMMARY_POS will be non-zero.
550 We will write the file starting from SUMMAY_POS. */
553 gcov_exit_write_gcda (const struct gcov_info
*gi_ptr
,
554 const struct gcov_summary
*prg_p
,
555 const gcov_position_t eof_pos
,
556 const gcov_position_t summary_pos
)
559 struct gcov_summary_buffer
*next_sum_buffer
;
561 /* Write out the data. */
564 gcov_write_tag_length (GCOV_DATA_MAGIC
, GCOV_VERSION
);
565 gcov_write_unsigned (gi_ptr
->stamp
);
569 gcov_seek (summary_pos
);
571 /* Generate whole program statistics. */
572 gcov_write_summary (GCOV_TAG_PROGRAM_SUMMARY
, prg_p
);
574 /* Rewrite all the summaries that were after the summary we merged
575 into. This is necessary as the merged summary may have a different
576 size due to the number of non-zero histogram entries changing after
581 gcov_write_summary (GCOV_TAG_PROGRAM_SUMMARY
, &sum_buffer
->summary
);
582 next_sum_buffer
= sum_buffer
->next
;
584 sum_buffer
= next_sum_buffer
;
587 /* Write execution counts for each function. */
588 for (f_ix
= 0; f_ix
!= gi_ptr
->n_functions
; f_ix
++)
590 unsigned buffered
= 0;
591 const struct gcov_fn_info
*gfi_ptr
;
592 const struct gcov_ctr_info
*ci_ptr
;
593 gcov_unsigned_t length
;
596 if (fn_buffer
&& fn_buffer
->fn_ix
== f_ix
)
598 /* Buffered data from another program. */
600 gfi_ptr
= &fn_buffer
->info
;
601 length
= GCOV_TAG_FUNCTION_LENGTH
;
605 gfi_ptr
= gi_ptr
->functions
[f_ix
];
606 if (gfi_ptr
&& gfi_ptr
->key
== gi_ptr
)
607 length
= GCOV_TAG_FUNCTION_LENGTH
;
612 gcov_write_tag_length (GCOV_TAG_FUNCTION
, length
);
616 gcov_write_unsigned (gfi_ptr
->ident
);
617 gcov_write_unsigned (gfi_ptr
->lineno_checksum
);
618 gcov_write_unsigned (gfi_ptr
->cfg_checksum
);
620 ci_ptr
= gfi_ptr
->ctrs
;
621 for (t_ix
= 0; t_ix
< GCOV_COUNTERS
; t_ix
++)
623 gcov_unsigned_t n_counts
;
626 if (!gi_ptr
->merge
[t_ix
])
629 n_counts
= ci_ptr
->num
;
630 gcov_write_tag_length (GCOV_TAG_FOR_COUNTER (t_ix
),
631 GCOV_TAG_COUNTER_LENGTH (n_counts
));
632 c_ptr
= ci_ptr
->values
;
634 gcov_write_counter (*c_ptr
++);
638 fn_buffer
= free_fn_data (gi_ptr
, fn_buffer
, GCOV_COUNTERS
);
641 gcov_write_unsigned (0);
644 /* Helper function for merging summary.
645 Return -1 on error. Return 0 on success. */
648 gcov_exit_merge_summary (const struct gcov_info
*gi_ptr
, struct gcov_summary
*prg
,
649 gcov_unsigned_t crc32
, struct gcov_summary
*all_prg
)
651 struct gcov_ctr_summary
*cs_prg
, *cs_tprg
;
653 /* If application calls fork or exec multiple times, we end up storing
654 profile repeadely. We should not account this as multiple runs or
655 functions executed once may mistakely become cold. */
656 static int run_accounted
= 0;
658 /* summary for all instances of program. */
659 struct gcov_ctr_summary
*cs_all
;
662 /* Merge the summaries. */
663 for (t_ix
= 0; t_ix
< GCOV_COUNTERS_SUMMABLE
; t_ix
++)
665 cs_prg
= &(prg
->ctrs
[t_ix
]);
666 cs_tprg
= &this_prg
.ctrs
[t_ix
];
668 if (gi_ptr
->merge
[t_ix
])
670 int first
= !cs_prg
->runs
;
676 cs_prg
->num
= cs_tprg
->num
;
677 cs_prg
->sum_all
+= cs_tprg
->sum_all
;
678 if (cs_prg
->run_max
< cs_tprg
->run_max
)
679 cs_prg
->run_max
= cs_tprg
->run_max
;
680 cs_prg
->sum_max
+= cs_tprg
->run_max
;
682 memcpy (cs_prg
->histogram
, cs_tprg
->histogram
,
683 sizeof (gcov_bucket_type
) * GCOV_HISTOGRAM_SIZE
);
685 gcov_histogram_merge (cs_prg
->histogram
, cs_tprg
->histogram
);
687 else if (cs_prg
->runs
)
689 gcov_error ("profiling:%s:Merge mismatch for summary.\n",
694 cs_all
= &all_prg
->ctrs
[t_ix
];
695 if (!cs_all
->runs
&& cs_prg
->runs
)
697 cs_all
->num
= cs_prg
->num
;
698 cs_all
->runs
= cs_prg
->runs
;
699 cs_all
->sum_all
= cs_prg
->sum_all
;
700 cs_all
->run_max
= cs_prg
->run_max
;
701 cs_all
->sum_max
= cs_prg
->sum_max
;
703 else if (!all_prg
->checksum
704 /* Don't compare the histograms, which may have slight
705 variations depending on the order they were updated
706 due to the truncating integer divides used in the
708 && (cs_all
->num
!= cs_prg
->num
709 || cs_all
->runs
!= cs_prg
->runs
710 || cs_all
->sum_all
!= cs_prg
->sum_all
711 || cs_all
->run_max
!= cs_prg
->run_max
712 || cs_all
->sum_max
!= cs_prg
->sum_max
))
714 gcov_error ("profiling:%s:Data file mismatch - some "
715 "data files may have been concurrently "
716 "updated without locking support\n", gi_filename
);
717 all_prg
->checksum
= ~0u;
722 prg
->checksum
= crc32
;
727 /* Dump the coverage counts for one gcov_info object. We merge with existing
728 counts when possible, to avoid growing the .da files ad infinitum. We use
729 this program's checksum to make sure we only accumulate whole program
730 statistics to the correct summary. An object file might be embedded
731 in two separate programs, and we must keep the two program
732 summaries separate. */
735 gcov_exit_dump_gcov (struct gcov_info
*gi_ptr
, struct gcov_filename_aux
*gf
,
736 gcov_unsigned_t crc32
, struct gcov_summary
*all_prg
)
738 struct gcov_summary prg
; /* summary for this object over all program. */
741 gcov_position_t summary_pos
= 0;
742 gcov_position_t eof_pos
= 0;
747 error
= gcov_exit_open_gcda_file (gi_ptr
, gf
);
751 tag
= gcov_read_unsigned ();
754 /* Merge data from file. */
755 if (tag
!= GCOV_DATA_MAGIC
)
757 gcov_error ("profiling:%s:Not a gcov data file\n", gi_filename
);
760 error
= gcov_exit_merge_gcda (gi_ptr
, &prg
, &summary_pos
, &eof_pos
,
770 memset (&prg
, 0, sizeof (prg
));
771 summary_pos
= eof_pos
;
774 error
= gcov_exit_merge_summary (gi_ptr
, &prg
, crc32
, all_prg
);
778 gcov_exit_write_gcda (gi_ptr
, &prg
, eof_pos
, summary_pos
);
783 fn_buffer
= free_fn_data (gi_ptr
, fn_buffer
, GCOV_COUNTERS
);
785 if ((error
= gcov_close ()))
786 gcov_error (error
< 0 ?
787 "profiling:%s:Overflow writing\n" :
788 "profiling:%s:Error writing\n",
793 /* Dump all the coverage counts for the program. It first computes program
794 summary and then traverses gcov_list list and dumps the gcov_info
795 objects one by one. */
800 struct gcov_info
*gi_ptr
;
801 struct gcov_filename_aux gf
;
802 gcov_unsigned_t crc32
;
803 struct gcov_summary all_prg
;
805 /* Prevent the counters from being dumped a second time on exit when the
806 application already wrote out the profile using __gcov_dump(). */
807 if (gcov_dump_complete
)
810 crc32
= gcov_exit_compute_summary ();
812 allocate_filename_struct (&gf
);
814 memset (&all_prg
, 0, sizeof (all_prg
));
817 /* Now merge each file. */
818 for (gi_ptr
= gcov_list
; gi_ptr
; gi_ptr
= gi_ptr
->next
)
819 gcov_exit_dump_gcov (gi_ptr
, &gf
, crc32
, &all_prg
);
825 /* Reset all counters to zero. */
830 const struct gcov_info
*gi_ptr
;
832 for (gi_ptr
= gcov_list
; gi_ptr
; gi_ptr
= gi_ptr
->next
)
836 for (f_ix
= 0; f_ix
< gi_ptr
->n_functions
; f_ix
++)
839 const struct gcov_fn_info
*gfi_ptr
= gi_ptr
->functions
[f_ix
];
841 if (!gfi_ptr
|| gfi_ptr
->key
!= gi_ptr
)
843 const struct gcov_ctr_info
*ci_ptr
= gfi_ptr
->ctrs
;
844 for (t_ix
= 0; t_ix
!= GCOV_COUNTERS
; t_ix
++)
846 if (!gi_ptr
->merge
[t_ix
])
849 memset (ci_ptr
->values
, 0, sizeof (gcov_type
) * ci_ptr
->num
);
856 /* Add a new object file onto the bb chain. Invoked automatically
857 when running an object file's global ctors. */
860 __gcov_init (struct gcov_info
*info
)
862 if (!info
->version
|| !info
->n_functions
)
864 if (gcov_version (info
, info
->version
, 0))
866 size_t filename_length
= strlen(info
->filename
);
868 /* Refresh the longest file name information */
869 if (filename_length
> gcov_max_filename
)
870 gcov_max_filename
= filename_length
;
875 info
->next
= gcov_list
;
882 #endif /* inhibit_libc */