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) {}
53 #ifdef L_gcov_merge_add
54 void __gcov_merge_add (gcov_type
*counters
__attribute__ ((unused
)),
55 unsigned n_counters
__attribute__ ((unused
))) {}
58 #ifdef L_gcov_merge_single
59 void __gcov_merge_single (gcov_type
*counters
__attribute__ ((unused
)),
60 unsigned n_counters
__attribute__ ((unused
))) {}
63 #ifdef L_gcov_merge_delta
64 void __gcov_merge_delta (gcov_type
*counters
__attribute__ ((unused
)),
65 unsigned n_counters
__attribute__ ((unused
))) {}
82 struct gcov_fn_buffer
*next
;
84 struct gcov_fn_info info
;
85 /* note gcov_fn_info ends in a trailing array. */
88 /* Chain of per-object gcov structures. */
89 static struct gcov_info
*gcov_list
;
91 /* Size of the longest file name. */
92 static size_t gcov_max_filename
= 0;
94 /* Make sure path component of the given FILENAME exists, create
95 missing directories. FILENAME must be writable.
96 Returns zero on success, or -1 if an error occurred. */
99 create_file_directory (char *filename
)
101 #if !defined(TARGET_POSIX_IO) && !defined(_WIN32)
109 if (HAS_DRIVE_SPEC(s
))
111 if (IS_DIR_SEPARATOR(*s
))
113 for (; *s
!= '\0'; s
++)
114 if (IS_DIR_SEPARATOR(*s
))
119 /* Try to make directory if it doesn't already exist. */
120 if (access (filename
, F_OK
) == -1
121 #ifdef TARGET_POSIX_IO
122 && mkdir (filename
, 0755) == -1
124 && mkdir (filename
) == -1
126 /* The directory might have been made by another process. */
129 fprintf (stderr
, "profiling:%s:Cannot create directory\n",
141 static struct gcov_fn_buffer
*
142 free_fn_data (const struct gcov_info
*gi_ptr
, struct gcov_fn_buffer
*buffer
,
145 struct gcov_fn_buffer
*next
;
146 unsigned ix
, n_ctr
= 0;
152 for (ix
= 0; ix
!= limit
; ix
++)
153 if (gi_ptr
->merge
[ix
])
154 free (buffer
->info
.ctrs
[n_ctr
++].values
);
159 static struct gcov_fn_buffer
**
160 buffer_fn_data (const char *filename
, const struct gcov_info
*gi_ptr
,
161 struct gcov_fn_buffer
**end_ptr
, unsigned fn_ix
)
163 unsigned n_ctrs
= 0, ix
= 0;
164 struct gcov_fn_buffer
*fn_buffer
;
167 for (ix
= GCOV_COUNTERS
; ix
--;)
168 if (gi_ptr
->merge
[ix
])
171 len
= sizeof (*fn_buffer
) + sizeof (fn_buffer
->info
.ctrs
[0]) * n_ctrs
;
172 fn_buffer
= (struct gcov_fn_buffer
*)malloc (len
);
178 fn_buffer
->fn_ix
= fn_ix
;
179 fn_buffer
->info
.ident
= gcov_read_unsigned ();
180 fn_buffer
->info
.lineno_checksum
= gcov_read_unsigned ();
181 fn_buffer
->info
.cfg_checksum
= gcov_read_unsigned ();
183 for (n_ctrs
= ix
= 0; ix
!= GCOV_COUNTERS
; ix
++)
185 gcov_unsigned_t length
;
188 if (!gi_ptr
->merge
[ix
])
191 if (gcov_read_unsigned () != GCOV_TAG_FOR_COUNTER (ix
))
197 length
= GCOV_TAG_COUNTER_NUM (gcov_read_unsigned ());
198 len
= length
* sizeof (gcov_type
);
199 values
= (gcov_type
*)malloc (len
);
203 fn_buffer
->info
.ctrs
[n_ctrs
].num
= length
;
204 fn_buffer
->info
.ctrs
[n_ctrs
].values
= values
;
207 *values
++ = gcov_read_counter ();
211 *end_ptr
= fn_buffer
;
212 return &fn_buffer
->next
;
215 fprintf (stderr
, "profiling:%s:Function %u %s %u \n", filename
, fn_ix
,
216 len
? "cannot allocate" : "counter mismatch", len
? len
: ix
);
218 return (struct gcov_fn_buffer
**)free_fn_data (gi_ptr
, fn_buffer
, ix
);
221 /* Add an unsigned value to the current crc */
223 static gcov_unsigned_t
224 crc32_unsigned (gcov_unsigned_t crc32
, gcov_unsigned_t value
)
228 for (ix
= 32; ix
--; value
<<= 1)
232 feedback
= (value
^ crc32
) & 0x80000000 ? 0x04c11db7 : 0;
240 /* Check if VERSION of the info block PTR matches libgcov one.
241 Return 1 on success, or zero in case of versions mismatch.
242 If FILENAME is not NULL, its value used for reporting purposes
243 instead of value from the info block. */
246 gcov_version (struct gcov_info
*ptr
, gcov_unsigned_t version
,
247 const char *filename
)
249 if (version
!= GCOV_VERSION
)
253 GCOV_UNSIGNED2STRING (v
, version
);
254 GCOV_UNSIGNED2STRING (e
, GCOV_VERSION
);
257 "profiling:%s:Version mismatch - expected %.4s got %.4s\n",
258 filename
? filename
: ptr
->filename
, e
, v
);
264 /* Dump the coverage counts. We merge with existing counts when
265 possible, to avoid growing the .da files ad infinitum. We use this
266 program's checksum to make sure we only accumulate whole program
267 statistics to the correct summary. An object file might be embedded
268 in two separate programs, and we must keep the two program
269 summaries separate. */
274 struct gcov_info
*gi_ptr
;
275 const struct gcov_fn_info
*gfi_ptr
;
276 struct gcov_summary this_prg
; /* summary for program. */
277 struct gcov_summary all_prg
; /* summary for all instances of program. */
278 struct gcov_ctr_summary
*cs_ptr
;
279 const struct gcov_ctr_info
*ci_ptr
;
282 gcov_unsigned_t c_num
;
283 const char *gcov_prefix
;
284 int gcov_prefix_strip
= 0;
285 size_t prefix_length
;
286 char *gi_filename
, *gi_filename_up
;
287 gcov_unsigned_t crc32
= 0;
289 memset (&all_prg
, 0, sizeof (all_prg
));
290 /* Find the totals for this execution. */
291 memset (&this_prg
, 0, sizeof (this_prg
));
292 for (gi_ptr
= gcov_list
; gi_ptr
; gi_ptr
= gi_ptr
->next
)
294 crc32
= crc32_unsigned (crc32
, gi_ptr
->stamp
);
295 crc32
= crc32_unsigned (crc32
, gi_ptr
->n_functions
);
297 for (f_ix
= 0; (unsigned)f_ix
!= gi_ptr
->n_functions
; f_ix
++)
299 gfi_ptr
= gi_ptr
->functions
[f_ix
];
301 if (gfi_ptr
&& gfi_ptr
->key
!= gi_ptr
)
304 crc32
= crc32_unsigned (crc32
, gfi_ptr
? gfi_ptr
->cfg_checksum
: 0);
305 crc32
= crc32_unsigned (crc32
,
306 gfi_ptr
? gfi_ptr
->lineno_checksum
: 0);
310 ci_ptr
= gfi_ptr
->ctrs
;
311 for (t_ix
= 0; t_ix
!= GCOV_COUNTERS_SUMMABLE
; t_ix
++)
313 if (!gi_ptr
->merge
[t_ix
])
316 cs_ptr
= &this_prg
.ctrs
[t_ix
];
317 cs_ptr
->num
+= ci_ptr
->num
;
318 crc32
= crc32_unsigned (crc32
, ci_ptr
->num
);
320 for (c_num
= 0; c_num
< ci_ptr
->num
; c_num
++)
322 cs_ptr
->sum_all
+= ci_ptr
->values
[c_num
];
323 if (cs_ptr
->run_max
< ci_ptr
->values
[c_num
])
324 cs_ptr
->run_max
= ci_ptr
->values
[c_num
];
332 /* Check if the level of dirs to strip off specified. */
333 char *tmp
= getenv("GCOV_PREFIX_STRIP");
336 gcov_prefix_strip
= atoi (tmp
);
337 /* Do not consider negative values. */
338 if (gcov_prefix_strip
< 0)
339 gcov_prefix_strip
= 0;
343 /* Get file name relocation prefix. Non-absolute values are ignored. */
344 gcov_prefix
= getenv("GCOV_PREFIX");
347 prefix_length
= strlen(gcov_prefix
);
349 /* Remove an unnecessary trailing '/' */
350 if (IS_DIR_SEPARATOR (gcov_prefix
[prefix_length
- 1]))
356 /* If no prefix was specified and a prefix stip, then we assume
358 if (gcov_prefix_strip
!= 0 && prefix_length
== 0)
363 /* Allocate and initialize the filename scratch space plus one. */
364 gi_filename
= (char *) alloca (prefix_length
+ gcov_max_filename
+ 2);
366 memcpy (gi_filename
, gcov_prefix
, prefix_length
);
367 gi_filename_up
= gi_filename
+ prefix_length
;
369 /* Now merge each file. */
370 for (gi_ptr
= gcov_list
; gi_ptr
; gi_ptr
= gi_ptr
->next
)
373 struct gcov_summary prg
; /* summary for this object over all
375 struct gcov_ctr_summary
*cs_prg
, *cs_tprg
, *cs_all
;
377 gcov_unsigned_t tag
, length
;
378 gcov_position_t summary_pos
= 0;
379 gcov_position_t eof_pos
= 0;
380 const char *fname
, *s
;
381 struct gcov_fn_buffer
*fn_buffer
= 0;
382 struct gcov_fn_buffer
**fn_tail
= &fn_buffer
;
384 fname
= gi_ptr
->filename
;
386 /* Avoid to add multiple drive letters into combined path. */
387 if (prefix_length
!= 0 && HAS_DRIVE_SPEC(fname
))
390 /* Build relocated filename, stripping off leading
391 directories from the initial filename if requested. */
392 if (gcov_prefix_strip
> 0)
396 if (IS_DIR_SEPARATOR(*s
))
399 /* Skip selected directory levels. */
400 for (; (*s
!= '\0') && (level
< gcov_prefix_strip
); s
++)
401 if (IS_DIR_SEPARATOR(*s
))
408 /* Update complete filename with stripped original. */
409 if (prefix_length
!= 0 && !IS_DIR_SEPARATOR (*fname
))
411 /* If prefix is given, add directory separator. */
412 strcpy (gi_filename_up
, "/");
413 strcpy (gi_filename_up
+ 1, fname
);
416 strcpy (gi_filename_up
, fname
);
418 if (!gcov_open (gi_filename
))
420 /* Open failed likely due to missed directory.
421 Create directory and retry to open file. */
422 if (create_file_directory (gi_filename
))
424 fprintf (stderr
, "profiling:%s:Skip\n", gi_filename
);
427 if (!gcov_open (gi_filename
))
429 fprintf (stderr
, "profiling:%s:Cannot open\n", gi_filename
);
434 tag
= gcov_read_unsigned ();
437 /* Merge data from file. */
438 if (tag
!= GCOV_DATA_MAGIC
)
440 fprintf (stderr
, "profiling:%s:Not a gcov data file\n",
444 length
= gcov_read_unsigned ();
445 if (!gcov_version (gi_ptr
, length
, gi_filename
))
448 length
= gcov_read_unsigned ();
449 if (length
!= gi_ptr
->stamp
)
450 /* Read from a different compilation. Overwrite the file. */
453 /* Look for program summary. */
456 struct gcov_summary tmp
;
458 eof_pos
= gcov_position ();
459 tag
= gcov_read_unsigned ();
460 if (tag
!= GCOV_TAG_PROGRAM_SUMMARY
)
464 length
= gcov_read_unsigned ();
465 if (length
!= GCOV_TAG_SUMMARY_LENGTH
)
467 gcov_read_summary (&tmp
);
468 if ((error
= gcov_is_error ()))
470 if (summary_pos
|| tmp
.checksum
!= crc32
)
473 for (t_ix
= 0; t_ix
!= GCOV_COUNTERS_SUMMABLE
; t_ix
++)
474 if (tmp
.ctrs
[t_ix
].num
!= this_prg
.ctrs
[t_ix
].num
)
477 summary_pos
= eof_pos
;
482 /* Merge execution counts for each function. */
483 for (f_ix
= 0; (unsigned)f_ix
!= gi_ptr
->n_functions
;
484 f_ix
++, tag
= gcov_read_unsigned ())
486 gfi_ptr
= gi_ptr
->functions
[f_ix
];
488 if (tag
!= GCOV_TAG_FUNCTION
)
491 length
= gcov_read_unsigned ();
493 /* This function did not appear in the other program.
494 We have nothing to merge. */
497 if (length
!= GCOV_TAG_FUNCTION_LENGTH
)
500 if (!gfi_ptr
|| gfi_ptr
->key
!= gi_ptr
)
502 /* This function appears in the other program. We
503 need to buffer the information in order to write
504 it back out -- we'll be inserting data before
505 this point, so cannot simply keep the data in the
507 fn_tail
= buffer_fn_data (gi_filename
,
508 gi_ptr
, fn_tail
, f_ix
);
514 length
= gcov_read_unsigned ();
515 if (length
!= gfi_ptr
->ident
)
518 length
= gcov_read_unsigned ();
519 if (length
!= gfi_ptr
->lineno_checksum
)
522 length
= gcov_read_unsigned ();
523 if (length
!= gfi_ptr
->cfg_checksum
)
526 ci_ptr
= gfi_ptr
->ctrs
;
527 for (t_ix
= 0; t_ix
< GCOV_COUNTERS
; t_ix
++)
529 gcov_merge_fn merge
= gi_ptr
->merge
[t_ix
];
534 tag
= gcov_read_unsigned ();
535 length
= gcov_read_unsigned ();
536 if (tag
!= GCOV_TAG_FOR_COUNTER (t_ix
)
537 || length
!= GCOV_TAG_COUNTER_LENGTH (ci_ptr
->num
))
539 (*merge
) (ci_ptr
->values
, ci_ptr
->num
);
542 if ((error
= gcov_is_error ()))
549 fprintf (stderr
, "profiling:%s:Merge mismatch for %s %u\n",
550 gi_filename
, f_ix
>= 0 ? "function" : "summary",
551 f_ix
< 0 ? -1 - f_ix
: f_ix
);
558 fprintf (stderr
, "profiling:%s:%s merging\n", gi_filename
,
559 error
< 0 ? "Overflow": "Error");
567 memset (&prg
, 0, sizeof (prg
));
568 summary_pos
= eof_pos
;
571 /* Merge the summaries. */
572 for (t_ix
= 0; t_ix
< GCOV_COUNTERS_SUMMABLE
; t_ix
++)
574 cs_prg
= &prg
.ctrs
[t_ix
];
575 cs_tprg
= &this_prg
.ctrs
[t_ix
];
576 cs_all
= &all_prg
.ctrs
[t_ix
];
578 if (gi_ptr
->merge
[t_ix
])
581 cs_prg
->num
= cs_tprg
->num
;
582 cs_prg
->sum_all
+= cs_tprg
->sum_all
;
583 if (cs_prg
->run_max
< cs_tprg
->run_max
)
584 cs_prg
->run_max
= cs_tprg
->run_max
;
585 cs_prg
->sum_max
+= cs_tprg
->run_max
;
587 else if (cs_prg
->runs
)
590 if (!cs_all
->runs
&& cs_prg
->runs
)
591 memcpy (cs_all
, cs_prg
, sizeof (*cs_all
));
592 else if (!all_prg
.checksum
593 && (!GCOV_LOCKED
|| cs_all
->runs
== cs_prg
->runs
)
594 && memcmp (cs_all
, cs_prg
, sizeof (*cs_all
)))
596 fprintf (stderr
, "profiling:%s:Invocation mismatch - some data files may have been removed%s\n",
597 gi_filename
, GCOV_LOCKED
598 ? "" : " or concurrently updated without locking support");
599 all_prg
.checksum
= ~0u;
603 prg
.checksum
= crc32
;
605 /* Write out the data. */
608 gcov_write_tag_length (GCOV_DATA_MAGIC
, GCOV_VERSION
);
609 gcov_write_unsigned (gi_ptr
->stamp
);
613 gcov_seek (summary_pos
);
615 /* Generate whole program statistics. */
616 gcov_write_summary (GCOV_TAG_PROGRAM_SUMMARY
, &prg
);
618 if (summary_pos
< eof_pos
)
621 /* Write execution counts for each function. */
622 for (f_ix
= 0; (unsigned)f_ix
!= gi_ptr
->n_functions
; f_ix
++)
624 unsigned buffered
= 0;
626 if (fn_buffer
&& fn_buffer
->fn_ix
== (unsigned)f_ix
)
628 /* Buffered data from another program. */
630 gfi_ptr
= &fn_buffer
->info
;
631 length
= GCOV_TAG_FUNCTION_LENGTH
;
635 gfi_ptr
= gi_ptr
->functions
[f_ix
];
636 if (gfi_ptr
&& gfi_ptr
->key
== gi_ptr
)
637 length
= GCOV_TAG_FUNCTION_LENGTH
;
642 gcov_write_tag_length (GCOV_TAG_FUNCTION
, length
);
646 gcov_write_unsigned (gfi_ptr
->ident
);
647 gcov_write_unsigned (gfi_ptr
->lineno_checksum
);
648 gcov_write_unsigned (gfi_ptr
->cfg_checksum
);
650 ci_ptr
= gfi_ptr
->ctrs
;
651 for (t_ix
= 0; t_ix
< GCOV_COUNTERS
; t_ix
++)
653 if (!gi_ptr
->merge
[t_ix
])
656 n_counts
= ci_ptr
->num
;
657 gcov_write_tag_length (GCOV_TAG_FOR_COUNTER (t_ix
),
658 GCOV_TAG_COUNTER_LENGTH (n_counts
));
659 gcov_type
*c_ptr
= ci_ptr
->values
;
661 gcov_write_counter (*c_ptr
++);
665 fn_buffer
= free_fn_data (gi_ptr
, fn_buffer
, GCOV_COUNTERS
);
668 gcov_write_unsigned (0);
672 fn_buffer
= free_fn_data (gi_ptr
, fn_buffer
, GCOV_COUNTERS
);
674 if ((error
= gcov_close ()))
675 fprintf (stderr
, error
< 0 ?
676 "profiling:%s:Overflow writing\n" :
677 "profiling:%s:Error writing\n",
682 /* Add a new object file onto the bb chain. Invoked automatically
683 when running an object file's global ctors. */
686 __gcov_init (struct gcov_info
*info
)
688 if (!info
->version
|| !info
->n_functions
)
690 if (gcov_version (info
, info
->version
, 0))
692 size_t filename_length
= strlen(info
->filename
);
694 /* Refresh the longest file name information */
695 if (filename_length
> gcov_max_filename
)
696 gcov_max_filename
= filename_length
;
701 info
->next
= gcov_list
;
707 #ifdef __GTHREAD_MUTEX_INIT
708 ATTRIBUTE_HIDDEN __gthread_mutex_t __gcov_flush_mx
= __GTHREAD_MUTEX_INIT
;
709 #define init_mx_once()
711 __gthread_mutex_t __gcov_flush_mx ATTRIBUTE_HIDDEN
;
716 __GTHREAD_MUTEX_INIT_FUNCTION (&__gcov_flush_mx
);
721 static __gthread_once_t once
= __GTHREAD_ONCE_INIT
;
722 __gthread_once (&once
, init_mx
);
726 /* Called before fork or exec - write out profile information gathered so
727 far and reset it to zero. This avoids duplication or loss of the
728 profile information gathered so far. */
733 const struct gcov_info
*gi_ptr
;
736 __gthread_mutex_lock (&__gcov_flush_mx
);
739 for (gi_ptr
= gcov_list
; gi_ptr
; gi_ptr
= gi_ptr
->next
)
743 for (f_ix
= 0; f_ix
< gi_ptr
->n_functions
; f_ix
++)
746 const struct gcov_fn_info
*gfi_ptr
= gi_ptr
->functions
[f_ix
];
748 if (!gfi_ptr
|| gfi_ptr
->key
!= gi_ptr
)
750 const struct gcov_ctr_info
*ci_ptr
= gfi_ptr
->ctrs
;
751 for (t_ix
= 0; t_ix
!= GCOV_COUNTERS
; t_ix
++)
753 if (!gi_ptr
->merge
[t_ix
])
756 memset (ci_ptr
->values
, 0, sizeof (gcov_type
) * ci_ptr
->num
);
762 __gthread_mutex_unlock (&__gcov_flush_mx
);
767 #ifdef L_gcov_merge_add
768 /* The profile merging function that just adds the counters. It is given
769 an array COUNTERS of N_COUNTERS old counters and it reads the same number
770 of counters from the gcov file. */
772 __gcov_merge_add (gcov_type
*counters
, unsigned n_counters
)
774 for (; n_counters
; counters
++, n_counters
--)
775 *counters
+= gcov_read_counter ();
777 #endif /* L_gcov_merge_add */
779 #ifdef L_gcov_merge_ior
780 /* The profile merging function that just adds the counters. It is given
781 an array COUNTERS of N_COUNTERS old counters and it reads the same number
782 of counters from the gcov file. */
784 __gcov_merge_ior (gcov_type
*counters
, unsigned n_counters
)
786 for (; n_counters
; counters
++, n_counters
--)
787 *counters
|= gcov_read_counter ();
791 #ifdef L_gcov_merge_single
792 /* The profile merging function for choosing the most common value.
793 It is given an array COUNTERS of N_COUNTERS old counters and it
794 reads the same number of counters from the gcov file. The counters
795 are split into 3-tuples where the members of the tuple have
798 -- the stored candidate on the most common value of the measured entity
800 -- total number of evaluations of the value */
802 __gcov_merge_single (gcov_type
*counters
, unsigned n_counters
)
804 unsigned i
, n_measures
;
805 gcov_type value
, counter
, all
;
807 gcc_assert (!(n_counters
% 3));
808 n_measures
= n_counters
/ 3;
809 for (i
= 0; i
< n_measures
; i
++, counters
+= 3)
811 value
= gcov_read_counter ();
812 counter
= gcov_read_counter ();
813 all
= gcov_read_counter ();
815 if (counters
[0] == value
)
816 counters
[1] += counter
;
817 else if (counter
> counters
[1])
820 counters
[1] = counter
- counters
[1];
823 counters
[1] -= counter
;
827 #endif /* L_gcov_merge_single */
829 #ifdef L_gcov_merge_delta
830 /* The profile merging function for choosing the most common
831 difference between two consecutive evaluations of the value. It is
832 given an array COUNTERS of N_COUNTERS old counters and it reads the
833 same number of counters from the gcov file. The counters are split
834 into 4-tuples where the members of the tuple have meanings:
836 -- the last value of the measured entity
837 -- the stored candidate on the most common difference
839 -- total number of evaluations of the value */
841 __gcov_merge_delta (gcov_type
*counters
, unsigned n_counters
)
843 unsigned i
, n_measures
;
844 gcov_type value
, counter
, all
;
846 gcc_assert (!(n_counters
% 4));
847 n_measures
= n_counters
/ 4;
848 for (i
= 0; i
< n_measures
; i
++, counters
+= 4)
850 /* last = */ gcov_read_counter ();
851 value
= gcov_read_counter ();
852 counter
= gcov_read_counter ();
853 all
= gcov_read_counter ();
855 if (counters
[1] == value
)
856 counters
[2] += counter
;
857 else if (counter
> counters
[2])
860 counters
[2] = counter
- counters
[2];
863 counters
[2] -= counter
;
867 #endif /* L_gcov_merge_delta */
869 #ifdef L_gcov_interval_profiler
870 /* If VALUE is in interval <START, START + STEPS - 1>, then increases the
871 corresponding counter in COUNTERS. If the VALUE is above or below
872 the interval, COUNTERS[STEPS] or COUNTERS[STEPS + 1] is increased
876 __gcov_interval_profiler (gcov_type
*counters
, gcov_type value
,
877 int start
, unsigned steps
)
879 gcov_type delta
= value
- start
;
881 counters
[steps
+ 1]++;
882 else if (delta
>= steps
)
889 #ifdef L_gcov_pow2_profiler
890 /* If VALUE is a power of two, COUNTERS[1] is incremented. Otherwise
891 COUNTERS[0] is incremented. */
894 __gcov_pow2_profiler (gcov_type
*counters
, gcov_type value
)
896 if (value
& (value
- 1))
903 /* Tries to determine the most common value among its inputs. Checks if the
904 value stored in COUNTERS[0] matches VALUE. If this is the case, COUNTERS[1]
905 is incremented. If this is not the case and COUNTERS[1] is not zero,
906 COUNTERS[1] is decremented. Otherwise COUNTERS[1] is set to one and
907 VALUE is stored to COUNTERS[0]. This algorithm guarantees that if this
908 function is called more than 50% of the time with one value, this value
909 will be in COUNTERS[0] in the end.
911 In any case, COUNTERS[2] is incremented. */
914 __gcov_one_value_profiler_body (gcov_type
*counters
, gcov_type value
)
916 if (value
== counters
[0])
918 else if (counters
[1] == 0)
928 #ifdef L_gcov_one_value_profiler
930 __gcov_one_value_profiler (gcov_type
*counters
, gcov_type value
)
932 __gcov_one_value_profiler_body (counters
, value
);
936 #ifdef L_gcov_indirect_call_profiler
938 /* By default, the C++ compiler will use function addresses in the
939 vtable entries. Setting TARGET_VTABLE_USES_DESCRIPTORS to nonzero
940 tells the compiler to use function descriptors instead. The value
941 of this macro says how many words wide the descriptor is (normally 2),
942 but it may be dependent on target flags. Since we do not have access
943 to the target flags here we just check to see if it is set and use
944 that to set VTABLE_USES_DESCRIPTORS to 0 or 1.
946 It is assumed that the address of a function descriptor may be treated
947 as a pointer to a function. */
949 #ifdef TARGET_VTABLE_USES_DESCRIPTORS
950 #define VTABLE_USES_DESCRIPTORS 1
952 #define VTABLE_USES_DESCRIPTORS 0
955 /* Tries to determine the most common value among its inputs. */
957 __gcov_indirect_call_profiler (gcov_type
* counter
, gcov_type value
,
958 void* cur_func
, void* callee_func
)
960 /* If the C++ virtual tables contain function descriptors then one
961 function may have multiple descriptors and we need to dereference
962 the descriptors to see if they point to the same function. */
963 if (cur_func
== callee_func
964 || (VTABLE_USES_DESCRIPTORS
&& callee_func
965 && *(void **) cur_func
== *(void **) callee_func
))
966 __gcov_one_value_profiler_body (counter
, value
);
971 #ifdef L_gcov_average_profiler
972 /* Increase corresponding COUNTER by VALUE. FIXME: Perhaps we want
976 __gcov_average_profiler (gcov_type
*counters
, gcov_type value
)
978 counters
[0] += value
;
983 #ifdef L_gcov_ior_profiler
984 /* Increase corresponding COUNTER by VALUE. FIXME: Perhaps we want
988 __gcov_ior_profiler (gcov_type
*counters
, gcov_type value
)
995 /* A wrapper for the fork function. Flushes the accumulated profiling data, so
996 that they are not counted twice. */
1002 extern __gthread_mutex_t __gcov_flush_mx
;
1006 __GTHREAD_MUTEX_INIT_FUNCTION (&__gcov_flush_mx
);
1012 /* A wrapper for the execl function. Flushes the accumulated profiling data, so
1013 that they are not lost. */
1016 __gcov_execl (const char *path
, char *arg
, ...)
1028 while (va_arg (ap
, char *))
1032 args
= (char **) alloca (length
* sizeof (void *));
1034 for (i
= 1; i
< length
; i
++)
1035 args
[i
] = va_arg (aq
, char *);
1038 return execv (path
, args
);
1042 #ifdef L_gcov_execlp
1043 /* A wrapper for the execlp function. Flushes the accumulated profiling data, so
1044 that they are not lost. */
1047 __gcov_execlp (const char *path
, char *arg
, ...)
1059 while (va_arg (ap
, char *))
1063 args
= (char **) alloca (length
* sizeof (void *));
1065 for (i
= 1; i
< length
; i
++)
1066 args
[i
] = va_arg (aq
, char *);
1069 return execvp (path
, args
);
1073 #ifdef L_gcov_execle
1074 /* A wrapper for the execle function. Flushes the accumulated profiling data, so
1075 that they are not lost. */
1078 __gcov_execle (const char *path
, char *arg
, ...)
1091 while (va_arg (ap
, char *))
1095 args
= (char **) alloca (length
* sizeof (void *));
1097 for (i
= 1; i
< length
; i
++)
1098 args
[i
] = va_arg (aq
, char *);
1099 envp
= va_arg (aq
, char **);
1102 return execve (path
, args
, envp
);
1107 /* A wrapper for the execv function. Flushes the accumulated profiling data, so
1108 that they are not lost. */
1111 __gcov_execv (const char *path
, char *const argv
[])
1114 return execv (path
, argv
);
1118 #ifdef L_gcov_execvp
1119 /* A wrapper for the execvp function. Flushes the accumulated profiling data, so
1120 that they are not lost. */
1123 __gcov_execvp (const char *path
, char *const argv
[])
1126 return execvp (path
, argv
);
1130 #ifdef L_gcov_execve
1131 /* A wrapper for the execve function. Flushes the accumulated profiling data, so
1132 that they are not lost. */
1135 __gcov_execve (const char *path
, char *const argv
[], char *const envp
[])
1138 return execve (path
, argv
, envp
);
1141 #endif /* inhibit_libc */