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 functino 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 /* summary for all instances of program. */
324 static struct gcov_summary all_prg
;
326 /* crc32 for this program. */
327 static gcov_unsigned_t crc32
;
329 static char *gi_filename
;
330 /* buffer for the fn_data from another program. */
331 static struct gcov_fn_buffer
*fn_buffer
;
332 /* buffer for summary from other programs to be written out. */
333 static struct gcov_summary_buffer
*sum_buffer
;
335 /* This funtions computes the program level summary and the histo-gram.
336 It initializes ALL_PRG, computes CRC32, and stores the summary in
337 THIS_PRG. All these three variables are file statics. */
340 gcov_exit_compute_summary (void)
342 struct gcov_info
*gi_ptr
;
343 const struct gcov_fn_info
*gfi_ptr
;
344 struct gcov_ctr_summary
*cs_ptr
;
345 const struct gcov_ctr_info
*ci_ptr
;
348 gcov_unsigned_t c_num
;
351 memset (&all_prg
, 0, sizeof (all_prg
));
353 /* Find the totals for this execution. */
354 memset (&this_prg
, 0, sizeof (this_prg
));
355 for (gi_ptr
= gcov_list
; gi_ptr
; gi_ptr
= gi_ptr
->next
)
357 crc32
= crc32_unsigned (crc32
, gi_ptr
->stamp
);
358 crc32
= crc32_unsigned (crc32
, gi_ptr
->n_functions
);
360 for (f_ix
= 0; (unsigned)f_ix
!= gi_ptr
->n_functions
; f_ix
++)
362 gfi_ptr
= gi_ptr
->functions
[f_ix
];
364 if (gfi_ptr
&& gfi_ptr
->key
!= gi_ptr
)
367 crc32
= crc32_unsigned (crc32
, gfi_ptr
? gfi_ptr
->cfg_checksum
: 0);
368 crc32
= crc32_unsigned (crc32
,
369 gfi_ptr
? gfi_ptr
->lineno_checksum
: 0);
373 ci_ptr
= gfi_ptr
->ctrs
;
374 for (t_ix
= 0; t_ix
!= GCOV_COUNTERS_SUMMABLE
; t_ix
++)
376 if (!gi_ptr
->merge
[t_ix
])
379 cs_ptr
= &this_prg
.ctrs
[t_ix
];
380 cs_ptr
->num
+= ci_ptr
->num
;
381 crc32
= crc32_unsigned (crc32
, ci_ptr
->num
);
383 for (c_num
= 0; c_num
< ci_ptr
->num
; c_num
++)
385 cs_ptr
->sum_all
+= ci_ptr
->values
[c_num
];
386 if (cs_ptr
->run_max
< ci_ptr
->values
[c_num
])
387 cs_ptr
->run_max
= ci_ptr
->values
[c_num
];
393 gcov_compute_histogram (&this_prg
);
396 /* A struct that bundles all the related information about the
398 struct gcov_filename_aux
{
399 char *gi_filename_up
;
400 int gcov_prefix_strip
;
401 size_t prefix_length
;
404 /* Including system dependent components. */
405 #include "libgcov-driver-system.c"
407 /* This function merges counters in GI_PTR to an existing gcda file.
409 Return -1 on error. In this case, caller will goto read_fatal. */
412 gcov_exit_merge_gcda (struct gcov_info
*gi_ptr
,
413 struct gcov_summary
*prg_p
,
414 gcov_position_t
*summary_pos_p
,
415 gcov_position_t
*eof_pos_p
)
417 gcov_unsigned_t tag
, length
;
421 struct gcov_fn_buffer
**fn_tail
= &fn_buffer
;
422 struct gcov_summary_buffer
**sum_tail
= &sum_buffer
;
424 length
= gcov_read_unsigned ();
425 if (!gcov_version (gi_ptr
, length
, gi_filename
))
428 length
= gcov_read_unsigned ();
429 if (length
!= gi_ptr
->stamp
)
430 /* Read from a different compilation. Overwrite the file. */
433 /* Look for program summary. */
436 struct gcov_summary tmp
;
438 *eof_pos_p
= gcov_position ();
439 tag
= gcov_read_unsigned ();
440 if (tag
!= GCOV_TAG_PROGRAM_SUMMARY
)
444 length
= gcov_read_unsigned ();
445 gcov_read_summary (&tmp
);
446 if ((error
= gcov_is_error ()))
450 /* Save all summaries after the one that will be
451 merged into below. These will need to be rewritten
452 as histogram merging may change the number of non-zero
453 histogram entries that will be emitted, and thus the
454 size of the merged summary. */
455 (*sum_tail
) = (struct gcov_summary_buffer
*)
456 malloc (sizeof(struct gcov_summary_buffer
));
457 (*sum_tail
)->summary
= tmp
;
458 (*sum_tail
)->next
= 0;
459 sum_tail
= &((*sum_tail
)->next
);
462 if (tmp
.checksum
!= crc32
)
465 for (t_ix
= 0; t_ix
!= GCOV_COUNTERS_SUMMABLE
; t_ix
++)
466 if (tmp
.ctrs
[t_ix
].num
!= this_prg
.ctrs
[t_ix
].num
)
469 *summary_pos_p
= *eof_pos_p
;
474 /* Merge execution counts for each function. */
475 for (f_ix
= 0; (unsigned)f_ix
!= gi_ptr
->n_functions
;
476 f_ix
++, tag
= gcov_read_unsigned ())
478 const struct gcov_ctr_info
*ci_ptr
;
479 const struct gcov_fn_info
*gfi_ptr
= gi_ptr
->functions
[f_ix
];
481 if (tag
!= GCOV_TAG_FUNCTION
)
484 length
= gcov_read_unsigned ();
486 /* This function did not appear in the other program.
487 We have nothing to merge. */
490 if (length
!= GCOV_TAG_FUNCTION_LENGTH
)
493 if (!gfi_ptr
|| gfi_ptr
->key
!= gi_ptr
)
495 /* This function appears in the other program. We
496 need to buffer the information in order to write
497 it back out -- we'll be inserting data before
498 this point, so cannot simply keep the data in the
500 fn_tail
= buffer_fn_data (gi_filename
,
501 gi_ptr
, fn_tail
, f_ix
);
507 length
= gcov_read_unsigned ();
508 if (length
!= gfi_ptr
->ident
)
511 length
= gcov_read_unsigned ();
512 if (length
!= gfi_ptr
->lineno_checksum
)
515 length
= gcov_read_unsigned ();
516 if (length
!= gfi_ptr
->cfg_checksum
)
519 ci_ptr
= gfi_ptr
->ctrs
;
520 for (t_ix
= 0; t_ix
< GCOV_COUNTERS
; t_ix
++)
522 gcov_merge_fn merge
= gi_ptr
->merge
[t_ix
];
527 tag
= gcov_read_unsigned ();
528 length
= gcov_read_unsigned ();
529 if (tag
!= GCOV_TAG_FOR_COUNTER (t_ix
)
530 || length
!= GCOV_TAG_COUNTER_LENGTH (ci_ptr
->num
))
532 (*merge
) (ci_ptr
->values
, ci_ptr
->num
);
535 if ((error
= gcov_is_error ()))
542 gcov_error ("profiling:%s:Merge mismatch for %s %u\n",
543 gi_filename
, f_ix
>= 0 ? "function" : "summary",
544 f_ix
< 0 ? -1 - f_ix
: f_ix
);
550 gcov_error ("profiling:%s:%s merging\n", gi_filename
,
551 error
< 0 ? "Overflow": "Error");
555 /* Write counters in GI_PTR and the summary in PRG to a gcda file. In
556 the case of appending to an existing file, SUMMARY_POS will be non-zero.
557 We will write the file starting from SUMMAY_POS. */
560 gcov_exit_write_gcda (const struct gcov_info
*gi_ptr
,
561 const struct gcov_summary
*prg_p
,
562 const gcov_position_t eof_pos
,
563 const gcov_position_t summary_pos
)
566 struct gcov_summary_buffer
*next_sum_buffer
;
568 /* Write out the data. */
571 gcov_write_tag_length (GCOV_DATA_MAGIC
, GCOV_VERSION
);
572 gcov_write_unsigned (gi_ptr
->stamp
);
576 gcov_seek (summary_pos
);
578 /* Generate whole program statistics. */
579 gcov_write_summary (GCOV_TAG_PROGRAM_SUMMARY
, prg_p
);
581 /* Rewrite all the summaries that were after the summary we merged
582 into. This is necessary as the merged summary may have a different
583 size due to the number of non-zero histogram entries changing after
588 gcov_write_summary (GCOV_TAG_PROGRAM_SUMMARY
, &sum_buffer
->summary
);
589 next_sum_buffer
= sum_buffer
->next
;
591 sum_buffer
= next_sum_buffer
;
594 /* Write execution counts for each function. */
595 for (f_ix
= 0; f_ix
!= gi_ptr
->n_functions
; f_ix
++)
597 unsigned buffered
= 0;
598 const struct gcov_fn_info
*gfi_ptr
;
599 const struct gcov_ctr_info
*ci_ptr
;
600 gcov_unsigned_t length
;
603 if (fn_buffer
&& fn_buffer
->fn_ix
== f_ix
)
605 /* Buffered data from another program. */
607 gfi_ptr
= &fn_buffer
->info
;
608 length
= GCOV_TAG_FUNCTION_LENGTH
;
612 gfi_ptr
= gi_ptr
->functions
[f_ix
];
613 if (gfi_ptr
&& gfi_ptr
->key
== gi_ptr
)
614 length
= GCOV_TAG_FUNCTION_LENGTH
;
619 gcov_write_tag_length (GCOV_TAG_FUNCTION
, length
);
623 gcov_write_unsigned (gfi_ptr
->ident
);
624 gcov_write_unsigned (gfi_ptr
->lineno_checksum
);
625 gcov_write_unsigned (gfi_ptr
->cfg_checksum
);
627 ci_ptr
= gfi_ptr
->ctrs
;
628 for (t_ix
= 0; t_ix
< GCOV_COUNTERS
; t_ix
++)
630 gcov_unsigned_t n_counts
;
633 if (!gi_ptr
->merge
[t_ix
])
636 n_counts
= ci_ptr
->num
;
637 gcov_write_tag_length (GCOV_TAG_FOR_COUNTER (t_ix
),
638 GCOV_TAG_COUNTER_LENGTH (n_counts
));
639 c_ptr
= ci_ptr
->values
;
641 gcov_write_counter (*c_ptr
++);
645 fn_buffer
= free_fn_data (gi_ptr
, fn_buffer
, GCOV_COUNTERS
);
648 gcov_write_unsigned (0);
651 /* Helper function for merging summary.
652 Return -1 on error. Return 0 on success. */
655 gcov_exit_merge_summary (const struct gcov_info
*gi_ptr
, struct gcov_summary
*prg
)
657 struct gcov_ctr_summary
*cs_prg
, *cs_tprg
;
659 struct gcov_ctr_summary
*cs_all
;
663 /* Merge the summaries. */
664 for (t_ix
= 0; t_ix
< GCOV_COUNTERS_SUMMABLE
; t_ix
++)
666 cs_prg
= &(prg
->ctrs
[t_ix
]);
667 cs_tprg
= &this_prg
.ctrs
[t_ix
];
669 if (gi_ptr
->merge
[t_ix
])
672 cs_prg
->num
= cs_tprg
->num
;
673 cs_prg
->sum_all
+= cs_tprg
->sum_all
;
674 if (cs_prg
->run_max
< cs_tprg
->run_max
)
675 cs_prg
->run_max
= cs_tprg
->run_max
;
676 cs_prg
->sum_max
+= cs_tprg
->run_max
;
677 if (cs_prg
->runs
== 1)
678 memcpy (cs_prg
->histogram
, cs_tprg
->histogram
,
679 sizeof (gcov_bucket_type
) * GCOV_HISTOGRAM_SIZE
);
681 gcov_histogram_merge (cs_prg
->histogram
, cs_tprg
->histogram
);
683 else if (cs_prg
->runs
)
685 gcov_error ("profiling:%s:Merge mismatch for summary.\n",
691 cs_all
= &all_prg
.ctrs
[t_ix
];
692 if (!cs_all
->runs
&& cs_prg
->runs
)
694 cs_all
->num
= cs_prg
->num
;
695 cs_all
->runs
= cs_prg
->runs
;
696 cs_all
->sum_all
= cs_prg
->sum_all
;
697 cs_all
->run_max
= cs_prg
->run_max
;
698 cs_all
->sum_max
= cs_prg
->sum_max
;
700 else if (!all_prg
.checksum
701 /* Don't compare the histograms, which may have slight
702 variations depending on the order they were updated
703 due to the truncating integer divides used in the
705 && (cs_all
->num
!= cs_prg
->num
706 || cs_all
->runs
!= cs_prg
->runs
707 || cs_all
->sum_all
!= cs_prg
->sum_all
708 || cs_all
->run_max
!= cs_prg
->run_max
709 || cs_all
->sum_max
!= cs_prg
->sum_max
))
711 gcov_error ("profiling:%s:Data file mismatch - some "
712 "data files may have been concurrently "
713 "updated without locking support\n", gi_filename
);
714 all_prg
.checksum
= ~0u;
719 prg
->checksum
= crc32
;
724 /* Dump the coverage counts for one gcov_info object. We merge with existing
725 counts when possible, to avoid growing the .da files ad infinitum. We use
726 this program's checksum to make sure we only accumulate whole program
727 statistics to the correct summary. An object file might be embedded
728 in two separate programs, and we must keep the two program
729 summaries separate. */
732 gcov_exit_dump_gcov (struct gcov_info
*gi_ptr
, struct gcov_filename_aux
*gf
)
734 struct gcov_summary prg
; /* summary for this object over all program. */
737 gcov_position_t summary_pos
= 0;
738 gcov_position_t eof_pos
= 0;
743 error
= gcov_exit_open_gcda_file (gi_ptr
, gf
);
747 tag
= gcov_read_unsigned ();
750 /* Merge data from file. */
751 if (tag
!= GCOV_DATA_MAGIC
)
753 gcov_error ("profiling:%s:Not a gcov data file\n", gi_filename
);
756 error
= gcov_exit_merge_gcda (gi_ptr
, &prg
, &summary_pos
, &eof_pos
);
765 memset (&prg
, 0, sizeof (prg
));
766 summary_pos
= eof_pos
;
769 error
= gcov_exit_merge_summary (gi_ptr
, &prg
);
773 gcov_exit_write_gcda (gi_ptr
, &prg
, eof_pos
, summary_pos
);
778 fn_buffer
= free_fn_data (gi_ptr
, fn_buffer
, GCOV_COUNTERS
);
780 if ((error
= gcov_close ()))
781 gcov_error (error
< 0 ?
782 "profiling:%s:Overflow writing\n" :
783 "profiling:%s:Error writing\n",
788 /* Dump all the coverage counts for the program. It first computes program
789 summary and then traverses gcov_list list and dumps the gcov_info
790 objects one by one. */
795 struct gcov_info
*gi_ptr
;
796 struct gcov_filename_aux gf
;
798 /* Prevent the counters from being dumped a second time on exit when the
799 application already wrote out the profile using __gcov_dump(). */
800 if (gcov_dump_complete
)
803 gcov_exit_compute_summary ();
805 allocate_filename_struct (&gf
);
807 /* Now merge each file. */
808 for (gi_ptr
= gcov_list
; gi_ptr
; gi_ptr
= gi_ptr
->next
)
809 gcov_exit_dump_gcov (gi_ptr
, &gf
);
815 /* Reset all counters to zero. */
820 const struct gcov_info
*gi_ptr
;
822 for (gi_ptr
= gcov_list
; gi_ptr
; gi_ptr
= gi_ptr
->next
)
826 for (f_ix
= 0; f_ix
< gi_ptr
->n_functions
; f_ix
++)
829 const struct gcov_fn_info
*gfi_ptr
= gi_ptr
->functions
[f_ix
];
831 if (!gfi_ptr
|| gfi_ptr
->key
!= gi_ptr
)
833 const struct gcov_ctr_info
*ci_ptr
= gfi_ptr
->ctrs
;
834 for (t_ix
= 0; t_ix
!= GCOV_COUNTERS
; t_ix
++)
836 if (!gi_ptr
->merge
[t_ix
])
839 memset (ci_ptr
->values
, 0, sizeof (gcov_type
) * ci_ptr
->num
);
846 /* Add a new object file onto the bb chain. Invoked automatically
847 when running an object file's global ctors. */
850 __gcov_init (struct gcov_info
*info
)
852 if (!info
->version
|| !info
->n_functions
)
854 if (gcov_version (info
, info
->version
, 0))
856 size_t filename_length
= strlen(info
->filename
);
858 /* Refresh the longest file name information */
859 if (filename_length
> gcov_max_filename
)
860 gcov_max_filename
= filename_length
;
865 info
->next
= gcov_list
;
872 #endif /* inhibit_libc */