1 /* Routines required for instrumenting a program. */
2 /* Compile this one with gcc. */
3 /* Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
4 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009, 2010, 2011
5 Free Software Foundation, Inc.
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 3, or (at your option) any later
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 Under Section 7 of GPL version 3, you are granted additional
20 permissions described in the GCC Runtime Library Exception, version
21 3.1, as published by the Free Software Foundation.
23 You should have received a copy of the GNU General Public License and
24 a copy of the GCC Runtime Library Exception along with this program;
25 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
26 <http://www.gnu.org/licenses/>. */
30 #include "coretypes.h"
32 #include "libgcc_tm.h"
35 #if defined(inhibit_libc)
36 #define IN_LIBGCOV (-1)
40 #define GCOV_LINKAGE /* nothing */
45 #if defined(inhibit_libc)
46 /* If libc and its header files are not available, provide dummy functions. */
49 void __gcov_init (struct gcov_info
*p
__attribute__ ((unused
))) {}
50 void __gcov_flush (void) {}
54 void __gcov_reset (void) {}
58 void __gcov_dump (void) {}
61 #ifdef L_gcov_merge_add
62 void __gcov_merge_add (gcov_type
*counters
__attribute__ ((unused
)),
63 unsigned n_counters
__attribute__ ((unused
))) {}
66 #ifdef L_gcov_merge_single
67 void __gcov_merge_single (gcov_type
*counters
__attribute__ ((unused
)),
68 unsigned n_counters
__attribute__ ((unused
))) {}
71 #ifdef L_gcov_merge_delta
72 void __gcov_merge_delta (gcov_type
*counters
__attribute__ ((unused
)),
73 unsigned n_counters
__attribute__ ((unused
))) {}
85 extern void gcov_clear (void) ATTRIBUTE_HIDDEN
;
86 extern void gcov_exit (void) ATTRIBUTE_HIDDEN
;
87 extern int gcov_dump_complete ATTRIBUTE_HIDDEN
;
94 struct gcov_fn_buffer
*next
;
96 struct gcov_fn_info info
;
97 /* note gcov_fn_info ends in a trailing array. */
100 struct gcov_summary_buffer
102 struct gcov_summary_buffer
*next
;
103 struct gcov_summary summary
;
106 /* Chain of per-object gcov structures. */
107 static struct gcov_info
*gcov_list
;
109 /* Size of the longest file name. */
110 static size_t gcov_max_filename
= 0;
112 /* Flag when the profile has already been dumped via __gcov_dump(). */
113 int gcov_dump_complete
= 0;
115 /* Make sure path component of the given FILENAME exists, create
116 missing directories. FILENAME must be writable.
117 Returns zero on success, or -1 if an error occurred. */
120 create_file_directory (char *filename
)
122 #if !defined(TARGET_POSIX_IO) && !defined(_WIN32)
130 if (HAS_DRIVE_SPEC(s
))
132 if (IS_DIR_SEPARATOR(*s
))
134 for (; *s
!= '\0'; s
++)
135 if (IS_DIR_SEPARATOR(*s
))
140 /* Try to make directory if it doesn't already exist. */
141 if (access (filename
, F_OK
) == -1
142 #ifdef TARGET_POSIX_IO
143 && mkdir (filename
, 0755) == -1
145 && mkdir (filename
) == -1
147 /* The directory might have been made by another process. */
150 fprintf (stderr
, "profiling:%s:Cannot create directory\n",
162 static struct gcov_fn_buffer
*
163 free_fn_data (const struct gcov_info
*gi_ptr
, struct gcov_fn_buffer
*buffer
,
166 struct gcov_fn_buffer
*next
;
167 unsigned ix
, n_ctr
= 0;
173 for (ix
= 0; ix
!= limit
; ix
++)
174 if (gi_ptr
->merge
[ix
])
175 free (buffer
->info
.ctrs
[n_ctr
++].values
);
180 static struct gcov_fn_buffer
**
181 buffer_fn_data (const char *filename
, const struct gcov_info
*gi_ptr
,
182 struct gcov_fn_buffer
**end_ptr
, unsigned fn_ix
)
184 unsigned n_ctrs
= 0, ix
= 0;
185 struct gcov_fn_buffer
*fn_buffer
;
188 for (ix
= GCOV_COUNTERS
; ix
--;)
189 if (gi_ptr
->merge
[ix
])
192 len
= sizeof (*fn_buffer
) + sizeof (fn_buffer
->info
.ctrs
[0]) * n_ctrs
;
193 fn_buffer
= (struct gcov_fn_buffer
*)malloc (len
);
199 fn_buffer
->fn_ix
= fn_ix
;
200 fn_buffer
->info
.ident
= gcov_read_unsigned ();
201 fn_buffer
->info
.lineno_checksum
= gcov_read_unsigned ();
202 fn_buffer
->info
.cfg_checksum
= gcov_read_unsigned ();
204 for (n_ctrs
= ix
= 0; ix
!= GCOV_COUNTERS
; ix
++)
206 gcov_unsigned_t length
;
209 if (!gi_ptr
->merge
[ix
])
212 if (gcov_read_unsigned () != GCOV_TAG_FOR_COUNTER (ix
))
218 length
= GCOV_TAG_COUNTER_NUM (gcov_read_unsigned ());
219 len
= length
* sizeof (gcov_type
);
220 values
= (gcov_type
*)malloc (len
);
224 fn_buffer
->info
.ctrs
[n_ctrs
].num
= length
;
225 fn_buffer
->info
.ctrs
[n_ctrs
].values
= values
;
228 *values
++ = gcov_read_counter ();
232 *end_ptr
= fn_buffer
;
233 return &fn_buffer
->next
;
236 fprintf (stderr
, "profiling:%s:Function %u %s %u \n", filename
, fn_ix
,
237 len
? "cannot allocate" : "counter mismatch", len
? len
: ix
);
239 return (struct gcov_fn_buffer
**)free_fn_data (gi_ptr
, fn_buffer
, ix
);
242 /* Add an unsigned value to the current crc */
244 static gcov_unsigned_t
245 crc32_unsigned (gcov_unsigned_t crc32
, gcov_unsigned_t value
)
249 for (ix
= 32; ix
--; value
<<= 1)
253 feedback
= (value
^ crc32
) & 0x80000000 ? 0x04c11db7 : 0;
261 /* Check if VERSION of the info block PTR matches libgcov one.
262 Return 1 on success, or zero in case of versions mismatch.
263 If FILENAME is not NULL, its value used for reporting purposes
264 instead of value from the info block. */
267 gcov_version (struct gcov_info
*ptr
, gcov_unsigned_t version
,
268 const char *filename
)
270 if (version
!= GCOV_VERSION
)
274 GCOV_UNSIGNED2STRING (v
, version
);
275 GCOV_UNSIGNED2STRING (e
, GCOV_VERSION
);
278 "profiling:%s:Version mismatch - expected %.4s got %.4s\n",
279 filename
? filename
: ptr
->filename
, e
, v
);
285 /* Insert counter VALUE into HISTOGRAM. */
288 gcov_histogram_insert(gcov_bucket_type
*histogram
, gcov_type value
)
292 i
= gcov_histo_index(value
);
293 histogram
[i
].num_counters
++;
294 histogram
[i
].cum_value
+= value
;
295 if (value
< histogram
[i
].min_value
)
296 histogram
[i
].min_value
= value
;
299 /* Computes a histogram of the arc counters to place in the summary SUM. */
302 gcov_compute_histogram (struct gcov_summary
*sum
)
304 struct gcov_info
*gi_ptr
;
305 const struct gcov_fn_info
*gfi_ptr
;
306 const struct gcov_ctr_info
*ci_ptr
;
307 struct gcov_ctr_summary
*cs_ptr
;
308 unsigned t_ix
, f_ix
, ctr_info_ix
, ix
;
311 /* This currently only applies to arc counters. */
312 t_ix
= GCOV_COUNTER_ARCS
;
314 /* First check if there are any counts recorded for this counter. */
315 cs_ptr
= &(sum
->ctrs
[t_ix
]);
319 for (h_ix
= 0; h_ix
< GCOV_HISTOGRAM_SIZE
; h_ix
++)
321 cs_ptr
->histogram
[h_ix
].num_counters
= 0;
322 cs_ptr
->histogram
[h_ix
].min_value
= cs_ptr
->run_max
;
323 cs_ptr
->histogram
[h_ix
].cum_value
= 0;
326 /* Walk through all the per-object structures and record each of
327 the count values in histogram. */
328 for (gi_ptr
= gcov_list
; gi_ptr
; gi_ptr
= gi_ptr
->next
)
330 if (!gi_ptr
->merge
[t_ix
])
333 /* Find the appropriate index into the gcov_ctr_info array
334 for the counter we are currently working on based on the
335 existence of the merge function pointer for this object. */
336 for (ix
= 0, ctr_info_ix
= 0; ix
< t_ix
; ix
++)
338 if (gi_ptr
->merge
[ix
])
341 for (f_ix
= 0; f_ix
!= gi_ptr
->n_functions
; f_ix
++)
343 gfi_ptr
= gi_ptr
->functions
[f_ix
];
345 if (!gfi_ptr
|| gfi_ptr
->key
!= gi_ptr
)
348 ci_ptr
= &gfi_ptr
->ctrs
[ctr_info_ix
];
349 for (ix
= 0; ix
< ci_ptr
->num
; ix
++)
350 gcov_histogram_insert (cs_ptr
->histogram
, ci_ptr
->values
[ix
]);
355 /* Dump the coverage counts. We merge with existing counts when
356 possible, to avoid growing the .da files ad infinitum. We use this
357 program's checksum to make sure we only accumulate whole program
358 statistics to the correct summary. An object file might be embedded
359 in two separate programs, and we must keep the two program
360 summaries separate. */
365 struct gcov_info
*gi_ptr
;
366 const struct gcov_fn_info
*gfi_ptr
;
367 struct gcov_summary this_prg
; /* summary for program. */
368 struct gcov_summary all_prg
; /* summary for all instances of program. */
369 struct gcov_ctr_summary
*cs_ptr
;
370 const struct gcov_ctr_info
*ci_ptr
;
373 gcov_unsigned_t c_num
;
374 const char *gcov_prefix
;
375 int gcov_prefix_strip
= 0;
376 size_t prefix_length
;
377 char *gi_filename
, *gi_filename_up
;
378 gcov_unsigned_t crc32
= 0;
380 /* Prevent the counters from being dumped a second time on exit when the
381 application already wrote out the profile using __gcov_dump(). */
382 if (gcov_dump_complete
)
385 memset (&all_prg
, 0, sizeof (all_prg
));
386 /* Find the totals for this execution. */
387 memset (&this_prg
, 0, sizeof (this_prg
));
388 for (gi_ptr
= gcov_list
; gi_ptr
; gi_ptr
= gi_ptr
->next
)
390 crc32
= crc32_unsigned (crc32
, gi_ptr
->stamp
);
391 crc32
= crc32_unsigned (crc32
, gi_ptr
->n_functions
);
393 for (f_ix
= 0; (unsigned)f_ix
!= gi_ptr
->n_functions
; f_ix
++)
395 gfi_ptr
= gi_ptr
->functions
[f_ix
];
397 if (gfi_ptr
&& gfi_ptr
->key
!= gi_ptr
)
400 crc32
= crc32_unsigned (crc32
, gfi_ptr
? gfi_ptr
->cfg_checksum
: 0);
401 crc32
= crc32_unsigned (crc32
,
402 gfi_ptr
? gfi_ptr
->lineno_checksum
: 0);
406 ci_ptr
= gfi_ptr
->ctrs
;
407 for (t_ix
= 0; t_ix
!= GCOV_COUNTERS_SUMMABLE
; t_ix
++)
409 if (!gi_ptr
->merge
[t_ix
])
412 cs_ptr
= &this_prg
.ctrs
[t_ix
];
413 cs_ptr
->num
+= ci_ptr
->num
;
414 crc32
= crc32_unsigned (crc32
, ci_ptr
->num
);
416 for (c_num
= 0; c_num
< ci_ptr
->num
; c_num
++)
418 cs_ptr
->sum_all
+= ci_ptr
->values
[c_num
];
419 if (cs_ptr
->run_max
< ci_ptr
->values
[c_num
])
420 cs_ptr
->run_max
= ci_ptr
->values
[c_num
];
426 gcov_compute_histogram (&this_prg
);
429 /* Check if the level of dirs to strip off specified. */
430 char *tmp
= getenv("GCOV_PREFIX_STRIP");
433 gcov_prefix_strip
= atoi (tmp
);
434 /* Do not consider negative values. */
435 if (gcov_prefix_strip
< 0)
436 gcov_prefix_strip
= 0;
440 /* Get file name relocation prefix. Non-absolute values are ignored. */
441 gcov_prefix
= getenv("GCOV_PREFIX");
444 prefix_length
= strlen(gcov_prefix
);
446 /* Remove an unnecessary trailing '/' */
447 if (IS_DIR_SEPARATOR (gcov_prefix
[prefix_length
- 1]))
453 /* If no prefix was specified and a prefix stip, then we assume
455 if (gcov_prefix_strip
!= 0 && prefix_length
== 0)
460 /* Allocate and initialize the filename scratch space plus one. */
461 gi_filename
= (char *) alloca (prefix_length
+ gcov_max_filename
+ 2);
463 memcpy (gi_filename
, gcov_prefix
, prefix_length
);
464 gi_filename_up
= gi_filename
+ prefix_length
;
466 /* Now merge each file. */
467 for (gi_ptr
= gcov_list
; gi_ptr
; gi_ptr
= gi_ptr
->next
)
470 struct gcov_summary prg
; /* summary for this object over all
472 struct gcov_ctr_summary
*cs_prg
, *cs_tprg
, *cs_all
;
474 gcov_unsigned_t tag
, length
;
475 gcov_position_t summary_pos
= 0;
476 gcov_position_t eof_pos
= 0;
477 const char *fname
, *s
;
478 struct gcov_fn_buffer
*fn_buffer
= 0;
479 struct gcov_fn_buffer
**fn_tail
= &fn_buffer
;
480 struct gcov_summary_buffer
*next_sum_buffer
, *sum_buffer
= 0;
481 struct gcov_summary_buffer
**sum_tail
= &sum_buffer
;
483 fname
= gi_ptr
->filename
;
485 /* Avoid to add multiple drive letters into combined path. */
486 if (prefix_length
!= 0 && HAS_DRIVE_SPEC(fname
))
489 /* Build relocated filename, stripping off leading
490 directories from the initial filename if requested. */
491 if (gcov_prefix_strip
> 0)
495 if (IS_DIR_SEPARATOR(*s
))
498 /* Skip selected directory levels. */
499 for (; (*s
!= '\0') && (level
< gcov_prefix_strip
); s
++)
500 if (IS_DIR_SEPARATOR(*s
))
507 /* Update complete filename with stripped original. */
508 if (prefix_length
!= 0 && !IS_DIR_SEPARATOR (*fname
))
510 /* If prefix is given, add directory separator. */
511 strcpy (gi_filename_up
, "/");
512 strcpy (gi_filename_up
+ 1, fname
);
515 strcpy (gi_filename_up
, fname
);
517 if (!gcov_open (gi_filename
))
519 /* Open failed likely due to missed directory.
520 Create directory and retry to open file. */
521 if (create_file_directory (gi_filename
))
523 fprintf (stderr
, "profiling:%s:Skip\n", gi_filename
);
526 if (!gcov_open (gi_filename
))
528 fprintf (stderr
, "profiling:%s:Cannot open\n", gi_filename
);
533 tag
= gcov_read_unsigned ();
536 /* Merge data from file. */
537 if (tag
!= GCOV_DATA_MAGIC
)
539 fprintf (stderr
, "profiling:%s:Not a gcov data file\n",
543 length
= gcov_read_unsigned ();
544 if (!gcov_version (gi_ptr
, length
, gi_filename
))
547 length
= gcov_read_unsigned ();
548 if (length
!= gi_ptr
->stamp
)
549 /* Read from a different compilation. Overwrite the file. */
552 /* Look for program summary. */
555 struct gcov_summary tmp
;
557 eof_pos
= gcov_position ();
558 tag
= gcov_read_unsigned ();
559 if (tag
!= GCOV_TAG_PROGRAM_SUMMARY
)
563 length
= gcov_read_unsigned ();
564 gcov_read_summary (&tmp
);
565 if ((error
= gcov_is_error ()))
569 /* Save all summaries after the one that will be
570 merged into below. These will need to be rewritten
571 as histogram merging may change the number of non-zero
572 histogram entries that will be emitted, and thus the
573 size of the merged summary. */
574 (*sum_tail
) = (struct gcov_summary_buffer
*)
575 malloc (sizeof(struct gcov_summary_buffer
));
576 (*sum_tail
)->summary
= tmp
;
577 (*sum_tail
)->next
= 0;
578 sum_tail
= &((*sum_tail
)->next
);
581 if (tmp
.checksum
!= crc32
)
584 for (t_ix
= 0; t_ix
!= GCOV_COUNTERS_SUMMABLE
; t_ix
++)
585 if (tmp
.ctrs
[t_ix
].num
!= this_prg
.ctrs
[t_ix
].num
)
588 summary_pos
= eof_pos
;
593 /* Merge execution counts for each function. */
594 for (f_ix
= 0; (unsigned)f_ix
!= gi_ptr
->n_functions
;
595 f_ix
++, tag
= gcov_read_unsigned ())
597 gfi_ptr
= gi_ptr
->functions
[f_ix
];
599 if (tag
!= GCOV_TAG_FUNCTION
)
602 length
= gcov_read_unsigned ();
604 /* This function did not appear in the other program.
605 We have nothing to merge. */
608 if (length
!= GCOV_TAG_FUNCTION_LENGTH
)
611 if (!gfi_ptr
|| gfi_ptr
->key
!= gi_ptr
)
613 /* This function appears in the other program. We
614 need to buffer the information in order to write
615 it back out -- we'll be inserting data before
616 this point, so cannot simply keep the data in the
618 fn_tail
= buffer_fn_data (gi_filename
,
619 gi_ptr
, fn_tail
, f_ix
);
625 length
= gcov_read_unsigned ();
626 if (length
!= gfi_ptr
->ident
)
629 length
= gcov_read_unsigned ();
630 if (length
!= gfi_ptr
->lineno_checksum
)
633 length
= gcov_read_unsigned ();
634 if (length
!= gfi_ptr
->cfg_checksum
)
637 ci_ptr
= gfi_ptr
->ctrs
;
638 for (t_ix
= 0; t_ix
< GCOV_COUNTERS
; t_ix
++)
640 gcov_merge_fn merge
= gi_ptr
->merge
[t_ix
];
645 tag
= gcov_read_unsigned ();
646 length
= gcov_read_unsigned ();
647 if (tag
!= GCOV_TAG_FOR_COUNTER (t_ix
)
648 || length
!= GCOV_TAG_COUNTER_LENGTH (ci_ptr
->num
))
650 (*merge
) (ci_ptr
->values
, ci_ptr
->num
);
653 if ((error
= gcov_is_error ()))
660 fprintf (stderr
, "profiling:%s:Merge mismatch for %s %u\n",
661 gi_filename
, f_ix
>= 0 ? "function" : "summary",
662 f_ix
< 0 ? -1 - f_ix
: f_ix
);
669 fprintf (stderr
, "profiling:%s:%s merging\n", gi_filename
,
670 error
< 0 ? "Overflow": "Error");
678 memset (&prg
, 0, sizeof (prg
));
679 summary_pos
= eof_pos
;
682 /* Merge the summaries. */
683 for (t_ix
= 0; t_ix
< GCOV_COUNTERS_SUMMABLE
; t_ix
++)
685 cs_prg
= &prg
.ctrs
[t_ix
];
686 cs_tprg
= &this_prg
.ctrs
[t_ix
];
687 cs_all
= &all_prg
.ctrs
[t_ix
];
689 if (gi_ptr
->merge
[t_ix
])
692 cs_prg
->num
= cs_tprg
->num
;
693 cs_prg
->sum_all
+= cs_tprg
->sum_all
;
694 if (cs_prg
->run_max
< cs_tprg
->run_max
)
695 cs_prg
->run_max
= cs_tprg
->run_max
;
696 cs_prg
->sum_max
+= cs_tprg
->run_max
;
697 if (cs_prg
->runs
== 1)
698 memcpy (cs_prg
->histogram
, cs_tprg
->histogram
,
699 sizeof (gcov_bucket_type
) * GCOV_HISTOGRAM_SIZE
);
701 gcov_histogram_merge (cs_prg
->histogram
, cs_tprg
->histogram
);
703 else if (cs_prg
->runs
)
706 if (!cs_all
->runs
&& cs_prg
->runs
)
707 memcpy (cs_all
, cs_prg
, sizeof (*cs_all
));
708 else if (!all_prg
.checksum
709 && (!GCOV_LOCKED
|| cs_all
->runs
== cs_prg
->runs
)
710 /* Don't compare the histograms, which may have slight
711 variations depending on the order they were updated
712 due to the truncating integer divides used in the
714 && memcmp (cs_all
, cs_prg
,
715 sizeof (*cs_all
) - (sizeof (gcov_bucket_type
)
716 * GCOV_HISTOGRAM_SIZE
)))
718 fprintf (stderr
, "profiling:%s:Invocation mismatch - some data files may have been removed%s\n",
719 gi_filename
, GCOV_LOCKED
720 ? "" : " or concurrently updated without locking support");
721 all_prg
.checksum
= ~0u;
725 prg
.checksum
= crc32
;
727 /* Write out the data. */
730 gcov_write_tag_length (GCOV_DATA_MAGIC
, GCOV_VERSION
);
731 gcov_write_unsigned (gi_ptr
->stamp
);
735 gcov_seek (summary_pos
);
737 /* Generate whole program statistics. */
738 gcov_write_summary (GCOV_TAG_PROGRAM_SUMMARY
, &prg
);
740 /* Rewrite all the summaries that were after the summary we merged
741 into. This is necessary as the merged summary may have a different
742 size due to the number of non-zero histogram entries changing after
747 gcov_write_summary (GCOV_TAG_PROGRAM_SUMMARY
, &sum_buffer
->summary
);
748 next_sum_buffer
= sum_buffer
->next
;
750 sum_buffer
= next_sum_buffer
;
753 /* Write execution counts for each function. */
754 for (f_ix
= 0; (unsigned)f_ix
!= gi_ptr
->n_functions
; f_ix
++)
756 unsigned buffered
= 0;
758 if (fn_buffer
&& fn_buffer
->fn_ix
== (unsigned)f_ix
)
760 /* Buffered data from another program. */
762 gfi_ptr
= &fn_buffer
->info
;
763 length
= GCOV_TAG_FUNCTION_LENGTH
;
767 gfi_ptr
= gi_ptr
->functions
[f_ix
];
768 if (gfi_ptr
&& gfi_ptr
->key
== gi_ptr
)
769 length
= GCOV_TAG_FUNCTION_LENGTH
;
774 gcov_write_tag_length (GCOV_TAG_FUNCTION
, length
);
778 gcov_write_unsigned (gfi_ptr
->ident
);
779 gcov_write_unsigned (gfi_ptr
->lineno_checksum
);
780 gcov_write_unsigned (gfi_ptr
->cfg_checksum
);
782 ci_ptr
= gfi_ptr
->ctrs
;
783 for (t_ix
= 0; t_ix
< GCOV_COUNTERS
; t_ix
++)
785 if (!gi_ptr
->merge
[t_ix
])
788 n_counts
= ci_ptr
->num
;
789 gcov_write_tag_length (GCOV_TAG_FOR_COUNTER (t_ix
),
790 GCOV_TAG_COUNTER_LENGTH (n_counts
));
791 gcov_type
*c_ptr
= ci_ptr
->values
;
793 gcov_write_counter (*c_ptr
++);
797 fn_buffer
= free_fn_data (gi_ptr
, fn_buffer
, GCOV_COUNTERS
);
800 gcov_write_unsigned (0);
804 fn_buffer
= free_fn_data (gi_ptr
, fn_buffer
, GCOV_COUNTERS
);
806 if ((error
= gcov_close ()))
807 fprintf (stderr
, error
< 0 ?
808 "profiling:%s:Overflow writing\n" :
809 "profiling:%s:Error writing\n",
814 /* Reset all counters to zero. */
819 const struct gcov_info
*gi_ptr
;
821 for (gi_ptr
= gcov_list
; gi_ptr
; gi_ptr
= gi_ptr
->next
)
825 for (f_ix
= 0; f_ix
< gi_ptr
->n_functions
; f_ix
++)
828 const struct gcov_fn_info
*gfi_ptr
= gi_ptr
->functions
[f_ix
];
830 if (!gfi_ptr
|| gfi_ptr
->key
!= gi_ptr
)
832 const struct gcov_ctr_info
*ci_ptr
= gfi_ptr
->ctrs
;
833 for (t_ix
= 0; t_ix
!= GCOV_COUNTERS
; t_ix
++)
835 if (!gi_ptr
->merge
[t_ix
])
838 memset (ci_ptr
->values
, 0, sizeof (gcov_type
) * ci_ptr
->num
);
845 /* Add a new object file onto the bb chain. Invoked automatically
846 when running an object file's global ctors. */
849 __gcov_init (struct gcov_info
*info
)
851 if (!info
->version
|| !info
->n_functions
)
853 if (gcov_version (info
, info
->version
, 0))
855 size_t filename_length
= strlen(info
->filename
);
857 /* Refresh the longest file name information */
858 if (filename_length
> gcov_max_filename
)
859 gcov_max_filename
= filename_length
;
864 info
->next
= gcov_list
;
870 #ifdef __GTHREAD_MUTEX_INIT
871 ATTRIBUTE_HIDDEN __gthread_mutex_t __gcov_flush_mx
= __GTHREAD_MUTEX_INIT
;
872 #define init_mx_once()
874 __gthread_mutex_t __gcov_flush_mx ATTRIBUTE_HIDDEN
;
879 __GTHREAD_MUTEX_INIT_FUNCTION (&__gcov_flush_mx
);
884 static __gthread_once_t once
= __GTHREAD_ONCE_INIT
;
885 __gthread_once (&once
, init_mx
);
889 /* Called before fork or exec - write out profile information gathered so
890 far and reset it to zero. This avoids duplication or loss of the
891 profile information gathered so far. */
897 __gthread_mutex_lock (&__gcov_flush_mx
);
902 __gthread_mutex_unlock (&__gcov_flush_mx
);
909 /* Function that can be called from application to reset counters to zero,
910 in order to collect profile in region of interest. */
916 /* Re-enable dumping to support collecting profile in multiple regions
918 gcov_dump_complete
= 0;
921 #endif /* L_gcov_reset */
925 /* Function that can be called from application to write profile collected
926 so far, in order to collect profile in region of interest. */
932 /* Prevent profile from being dumped a second time on application exit. */
933 gcov_dump_complete
= 1;
936 #endif /* L_gcov_dump */
938 #ifdef L_gcov_merge_add
939 /* The profile merging function that just adds the counters. It is given
940 an array COUNTERS of N_COUNTERS old counters and it reads the same number
941 of counters from the gcov file. */
943 __gcov_merge_add (gcov_type
*counters
, unsigned n_counters
)
945 for (; n_counters
; counters
++, n_counters
--)
946 *counters
+= gcov_read_counter ();
948 #endif /* L_gcov_merge_add */
950 #ifdef L_gcov_merge_ior
951 /* The profile merging function that just adds the counters. It is given
952 an array COUNTERS of N_COUNTERS old counters and it reads the same number
953 of counters from the gcov file. */
955 __gcov_merge_ior (gcov_type
*counters
, unsigned n_counters
)
957 for (; n_counters
; counters
++, n_counters
--)
958 *counters
|= gcov_read_counter ();
962 #ifdef L_gcov_merge_single
963 /* The profile merging function for choosing the most common value.
964 It is given an array COUNTERS of N_COUNTERS old counters and it
965 reads the same number of counters from the gcov file. The counters
966 are split into 3-tuples where the members of the tuple have
969 -- the stored candidate on the most common value of the measured entity
971 -- total number of evaluations of the value */
973 __gcov_merge_single (gcov_type
*counters
, unsigned n_counters
)
975 unsigned i
, n_measures
;
976 gcov_type value
, counter
, all
;
978 gcc_assert (!(n_counters
% 3));
979 n_measures
= n_counters
/ 3;
980 for (i
= 0; i
< n_measures
; i
++, counters
+= 3)
982 value
= gcov_read_counter ();
983 counter
= gcov_read_counter ();
984 all
= gcov_read_counter ();
986 if (counters
[0] == value
)
987 counters
[1] += counter
;
988 else if (counter
> counters
[1])
991 counters
[1] = counter
- counters
[1];
994 counters
[1] -= counter
;
998 #endif /* L_gcov_merge_single */
1000 #ifdef L_gcov_merge_delta
1001 /* The profile merging function for choosing the most common
1002 difference between two consecutive evaluations of the value. It is
1003 given an array COUNTERS of N_COUNTERS old counters and it reads the
1004 same number of counters from the gcov file. The counters are split
1005 into 4-tuples where the members of the tuple have meanings:
1007 -- the last value of the measured entity
1008 -- the stored candidate on the most common difference
1010 -- total number of evaluations of the value */
1012 __gcov_merge_delta (gcov_type
*counters
, unsigned n_counters
)
1014 unsigned i
, n_measures
;
1015 gcov_type value
, counter
, all
;
1017 gcc_assert (!(n_counters
% 4));
1018 n_measures
= n_counters
/ 4;
1019 for (i
= 0; i
< n_measures
; i
++, counters
+= 4)
1021 /* last = */ gcov_read_counter ();
1022 value
= gcov_read_counter ();
1023 counter
= gcov_read_counter ();
1024 all
= gcov_read_counter ();
1026 if (counters
[1] == value
)
1027 counters
[2] += counter
;
1028 else if (counter
> counters
[2])
1030 counters
[1] = value
;
1031 counters
[2] = counter
- counters
[2];
1034 counters
[2] -= counter
;
1038 #endif /* L_gcov_merge_delta */
1040 #ifdef L_gcov_interval_profiler
1041 /* If VALUE is in interval <START, START + STEPS - 1>, then increases the
1042 corresponding counter in COUNTERS. If the VALUE is above or below
1043 the interval, COUNTERS[STEPS] or COUNTERS[STEPS + 1] is increased
1047 __gcov_interval_profiler (gcov_type
*counters
, gcov_type value
,
1048 int start
, unsigned steps
)
1050 gcov_type delta
= value
- start
;
1052 counters
[steps
+ 1]++;
1053 else if (delta
>= steps
)
1060 #ifdef L_gcov_pow2_profiler
1061 /* If VALUE is a power of two, COUNTERS[1] is incremented. Otherwise
1062 COUNTERS[0] is incremented. */
1065 __gcov_pow2_profiler (gcov_type
*counters
, gcov_type value
)
1067 if (value
& (value
- 1))
1074 /* Tries to determine the most common value among its inputs. Checks if the
1075 value stored in COUNTERS[0] matches VALUE. If this is the case, COUNTERS[1]
1076 is incremented. If this is not the case and COUNTERS[1] is not zero,
1077 COUNTERS[1] is decremented. Otherwise COUNTERS[1] is set to one and
1078 VALUE is stored to COUNTERS[0]. This algorithm guarantees that if this
1079 function is called more than 50% of the time with one value, this value
1080 will be in COUNTERS[0] in the end.
1082 In any case, COUNTERS[2] is incremented. */
1085 __gcov_one_value_profiler_body (gcov_type
*counters
, gcov_type value
)
1087 if (value
== counters
[0])
1089 else if (counters
[1] == 0)
1092 counters
[0] = value
;
1099 #ifdef L_gcov_one_value_profiler
1101 __gcov_one_value_profiler (gcov_type
*counters
, gcov_type value
)
1103 __gcov_one_value_profiler_body (counters
, value
);
1107 #ifdef L_gcov_indirect_call_profiler
1109 /* By default, the C++ compiler will use function addresses in the
1110 vtable entries. Setting TARGET_VTABLE_USES_DESCRIPTORS to nonzero
1111 tells the compiler to use function descriptors instead. The value
1112 of this macro says how many words wide the descriptor is (normally 2),
1113 but it may be dependent on target flags. Since we do not have access
1114 to the target flags here we just check to see if it is set and use
1115 that to set VTABLE_USES_DESCRIPTORS to 0 or 1.
1117 It is assumed that the address of a function descriptor may be treated
1118 as a pointer to a function. */
1120 #ifdef TARGET_VTABLE_USES_DESCRIPTORS
1121 #define VTABLE_USES_DESCRIPTORS 1
1123 #define VTABLE_USES_DESCRIPTORS 0
1126 /* Tries to determine the most common value among its inputs. */
1128 __gcov_indirect_call_profiler (gcov_type
* counter
, gcov_type value
,
1129 void* cur_func
, void* callee_func
)
1131 /* If the C++ virtual tables contain function descriptors then one
1132 function may have multiple descriptors and we need to dereference
1133 the descriptors to see if they point to the same function. */
1134 if (cur_func
== callee_func
1135 || (VTABLE_USES_DESCRIPTORS
&& callee_func
1136 && *(void **) cur_func
== *(void **) callee_func
))
1137 __gcov_one_value_profiler_body (counter
, value
);
1142 #ifdef L_gcov_average_profiler
1143 /* Increase corresponding COUNTER by VALUE. FIXME: Perhaps we want
1147 __gcov_average_profiler (gcov_type
*counters
, gcov_type value
)
1149 counters
[0] += value
;
1154 #ifdef L_gcov_ior_profiler
1155 /* Bitwise-OR VALUE into COUNTER. */
1158 __gcov_ior_profiler (gcov_type
*counters
, gcov_type value
)
1165 /* A wrapper for the fork function. Flushes the accumulated profiling data, so
1166 that they are not counted twice. */
1172 extern __gthread_mutex_t __gcov_flush_mx
;
1176 __GTHREAD_MUTEX_INIT_FUNCTION (&__gcov_flush_mx
);
1182 /* A wrapper for the execl function. Flushes the accumulated profiling data, so
1183 that they are not lost. */
1186 __gcov_execl (const char *path
, char *arg
, ...)
1198 while (va_arg (ap
, char *))
1202 args
= (char **) alloca (length
* sizeof (void *));
1204 for (i
= 1; i
< length
; i
++)
1205 args
[i
] = va_arg (aq
, char *);
1208 return execv (path
, args
);
1212 #ifdef L_gcov_execlp
1213 /* A wrapper for the execlp function. Flushes the accumulated profiling data, so
1214 that they are not lost. */
1217 __gcov_execlp (const char *path
, char *arg
, ...)
1229 while (va_arg (ap
, char *))
1233 args
= (char **) alloca (length
* sizeof (void *));
1235 for (i
= 1; i
< length
; i
++)
1236 args
[i
] = va_arg (aq
, char *);
1239 return execvp (path
, args
);
1243 #ifdef L_gcov_execle
1244 /* A wrapper for the execle function. Flushes the accumulated profiling data, so
1245 that they are not lost. */
1248 __gcov_execle (const char *path
, char *arg
, ...)
1261 while (va_arg (ap
, char *))
1265 args
= (char **) alloca (length
* sizeof (void *));
1267 for (i
= 1; i
< length
; i
++)
1268 args
[i
] = va_arg (aq
, char *);
1269 envp
= va_arg (aq
, char **);
1272 return execve (path
, args
, envp
);
1277 /* A wrapper for the execv function. Flushes the accumulated profiling data, so
1278 that they are not lost. */
1281 __gcov_execv (const char *path
, char *const argv
[])
1284 return execv (path
, argv
);
1288 #ifdef L_gcov_execvp
1289 /* A wrapper for the execvp function. Flushes the accumulated profiling data, so
1290 that they are not lost. */
1293 __gcov_execvp (const char *path
, char *const argv
[])
1296 return execvp (path
, argv
);
1300 #ifdef L_gcov_execve
1301 /* A wrapper for the execve function. Flushes the accumulated profiling data, so
1302 that they are not lost. */
1305 __gcov_execve (const char *path
, char *const argv
[], char *const envp
[])
1308 return execve (path
, argv
, envp
);
1311 #endif /* inhibit_libc */