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"
34 #if defined(inhibit_libc)
35 #define IN_LIBGCOV (-1)
37 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
41 #define GCOV_LINKAGE /* nothing */
46 #if defined(inhibit_libc)
47 /* If libc and its header files are not available, provide dummy functions. */
50 void __gcov_init (struct gcov_info
*p
__attribute__ ((unused
))) {}
51 void __gcov_flush (void) {}
54 #ifdef L_gcov_merge_add
55 void __gcov_merge_add (gcov_type
*counters
__attribute__ ((unused
)),
56 unsigned n_counters
__attribute__ ((unused
))) {}
59 #ifdef L_gcov_merge_single
60 void __gcov_merge_single (gcov_type
*counters
__attribute__ ((unused
)),
61 unsigned n_counters
__attribute__ ((unused
))) {}
64 #ifdef L_gcov_merge_delta
65 void __gcov_merge_delta (gcov_type
*counters
__attribute__ ((unused
)),
66 unsigned n_counters
__attribute__ ((unused
))) {}
83 struct gcov_fn_buffer
*next
;
85 struct gcov_fn_info info
;
86 /* note gcov_fn_info ends in a trailing array. */
89 /* Chain of per-object gcov structures. */
90 static struct gcov_info
*gcov_list
;
92 /* A program checksum allows us to distinguish program data for an
93 object file included in multiple programs. */
94 static gcov_unsigned_t gcov_crc32
;
96 /* Size of the longest file name. */
97 static size_t gcov_max_filename
= 0;
99 /* Make sure path component of the given FILENAME exists, create
100 missing directories. FILENAME must be writable.
101 Returns zero on success, or -1 if an error occurred. */
104 create_file_directory (char *filename
)
106 #if !defined(TARGET_POSIX_IO) && !defined(_WIN32)
114 if (HAS_DRIVE_SPEC(s
))
116 if (IS_DIR_SEPARATOR(*s
))
118 for (; *s
!= '\0'; s
++)
119 if (IS_DIR_SEPARATOR(*s
))
124 /* Try to make directory if it doesn't already exist. */
125 if (access (filename
, F_OK
) == -1
126 #ifdef TARGET_POSIX_IO
127 && mkdir (filename
, 0755) == -1
129 && mkdir (filename
) == -1
131 /* The directory might have been made by another process. */
134 fprintf (stderr
, "profiling:%s:Cannot create directory\n",
146 static struct gcov_fn_buffer
**
147 buffer_fn_data (struct gcov_info
*gi_ptr
, struct gcov_fn_buffer
**end_ptr
,
150 unsigned n_ctrs
= 0, ix
;
151 struct gcov_fn_buffer
*fn_buffer
;
153 for (ix
= GCOV_COUNTERS
; ix
--;)
154 if (gi_ptr
->merge
[ix
])
157 fn_buffer
= (struct gcov_fn_buffer
*)malloc
158 (sizeof (*fn_buffer
) + sizeof (fn_buffer
->info
.ctrs
[0]) * n_ctrs
);
161 return 0; /* We'll horribly fail. */
164 fn_buffer
->fn_ix
= fn_ix
;
165 fn_buffer
->info
.ident
= gcov_read_unsigned ();
166 fn_buffer
->info
.lineno_checksum
= gcov_read_unsigned ();
167 fn_buffer
->info
.cfg_checksum
= gcov_read_unsigned ();
169 for (n_ctrs
= ix
= 0; ix
!= GCOV_COUNTERS
; ix
++)
171 gcov_unsigned_t length
;
174 if (!gi_ptr
->merge
[ix
])
177 if (gcov_read_unsigned () != GCOV_TAG_FOR_COUNTER (ix
))
180 length
= GCOV_TAG_COUNTER_NUM (gcov_read_unsigned ());
181 values
= (gcov_type
*)malloc (length
* sizeof (gcov_type
));
185 free (fn_buffer
->info
.ctrs
[n_ctrs
].values
);
188 fn_buffer
->info
.ctrs
[n_ctrs
].num
= length
;
189 fn_buffer
->info
.ctrs
[n_ctrs
].values
= values
;
192 *values
++ = gcov_read_counter ();
196 *end_ptr
= fn_buffer
;
197 return &fn_buffer
->next
;
204 /* Check if VERSION of the info block PTR matches libgcov one.
205 Return 1 on success, or zero in case of versions mismatch.
206 If FILENAME is not NULL, its value used for reporting purposes
207 instead of value from the info block. */
210 gcov_version (struct gcov_info
*ptr
, gcov_unsigned_t version
,
211 const char *filename
)
213 if (version
!= GCOV_VERSION
)
217 GCOV_UNSIGNED2STRING (v
, version
);
218 GCOV_UNSIGNED2STRING (e
, GCOV_VERSION
);
221 "profiling:%s:Version mismatch - expected %.4s got %.4s\n",
222 filename
? filename
: ptr
->filename
, e
, v
);
228 /* Dump the coverage counts. We merge with existing counts when
229 possible, to avoid growing the .da files ad infinitum. We use this
230 program's checksum to make sure we only accumulate whole program
231 statistics to the correct summary. An object file might be embedded
232 in two separate programs, and we must keep the two program
233 summaries separate. */
238 struct gcov_info
*gi_ptr
;
239 const struct gcov_fn_info
*gfi_ptr
;
240 struct gcov_summary this_prg
; /* summary for program. */
241 struct gcov_summary all_prg
; /* summary for all instances of program. */
242 struct gcov_ctr_summary
*cs_ptr
;
243 const struct gcov_ctr_info
*ci_ptr
;
245 gcov_unsigned_t c_num
;
246 const char *gcov_prefix
;
247 int gcov_prefix_strip
= 0;
248 size_t prefix_length
;
249 char *gi_filename
, *gi_filename_up
;
251 memset (&all_prg
, 0, sizeof (all_prg
));
252 /* Find the totals for this execution. */
253 memset (&this_prg
, 0, sizeof (this_prg
));
254 for (gi_ptr
= gcov_list
; gi_ptr
; gi_ptr
= gi_ptr
->next
)
255 for (f_ix
= 0; f_ix
!= gi_ptr
->n_functions
; f_ix
++)
257 gfi_ptr
= gi_ptr
->functions
[f_ix
];
259 if (!gfi_ptr
|| gfi_ptr
->key
!= gi_ptr
)
262 ci_ptr
= gfi_ptr
->ctrs
;
263 for (t_ix
= 0; t_ix
!= GCOV_COUNTERS_SUMMABLE
; t_ix
++)
265 if (!gi_ptr
->merge
[t_ix
])
268 cs_ptr
= &this_prg
.ctrs
[t_ix
];
269 cs_ptr
->num
+= ci_ptr
->num
;
270 for (c_num
= 0; c_num
< ci_ptr
->num
; c_num
++)
272 cs_ptr
->sum_all
+= ci_ptr
->values
[c_num
];
273 if (cs_ptr
->run_max
< ci_ptr
->values
[c_num
])
274 cs_ptr
->run_max
= ci_ptr
->values
[c_num
];
281 /* Check if the level of dirs to strip off specified. */
282 char *tmp
= getenv("GCOV_PREFIX_STRIP");
285 gcov_prefix_strip
= atoi (tmp
);
286 /* Do not consider negative values. */
287 if (gcov_prefix_strip
< 0)
288 gcov_prefix_strip
= 0;
292 /* Get file name relocation prefix. Non-absolute values are ignored. */
293 gcov_prefix
= getenv("GCOV_PREFIX");
296 prefix_length
= strlen(gcov_prefix
);
298 /* Remove an unnecessary trailing '/' */
299 if (IS_DIR_SEPARATOR (gcov_prefix
[prefix_length
- 1]))
305 /* If no prefix was specified and a prefix stip, then we assume
307 if (gcov_prefix_strip
!= 0 && prefix_length
== 0)
312 /* Allocate and initialize the filename scratch space plus one. */
313 gi_filename
= (char *) alloca (prefix_length
+ gcov_max_filename
+ 2);
315 memcpy (gi_filename
, gcov_prefix
, prefix_length
);
316 gi_filename_up
= gi_filename
+ prefix_length
;
318 /* Now merge each file. */
319 for (gi_ptr
= gcov_list
; gi_ptr
; gi_ptr
= gi_ptr
->next
)
322 struct gcov_summary prg
; /* summary for this object over all
324 struct gcov_ctr_summary
*cs_prg
, *cs_tprg
, *cs_all
;
326 gcov_unsigned_t tag
, length
;
327 gcov_position_t summary_pos
= 0;
328 gcov_position_t eof_pos
= 0;
329 const char *fname
, *s
;
330 struct gcov_fn_buffer
*fn_buffer
= 0;
331 struct gcov_fn_buffer
**fn_tail
= &fn_buffer
;
333 fname
= gi_ptr
->filename
;
335 /* Avoid to add multiple drive letters into combined path. */
336 if (prefix_length
!= 0 && HAS_DRIVE_SPEC(fname
))
339 /* Build relocated filename, stripping off leading
340 directories from the initial filename if requested. */
341 if (gcov_prefix_strip
> 0)
345 if (IS_DIR_SEPARATOR(*s
))
348 /* Skip selected directory levels. */
349 for (; (*s
!= '\0') && (level
< gcov_prefix_strip
); s
++)
350 if (IS_DIR_SEPARATOR(*s
))
357 /* Update complete filename with stripped original. */
358 if (prefix_length
!= 0 && !IS_DIR_SEPARATOR (*fname
))
360 /* If prefix is given, add directory separator. */
361 strcpy (gi_filename_up
, "/");
362 strcpy (gi_filename_up
+ 1, fname
);
365 strcpy (gi_filename_up
, fname
);
367 if (!gcov_open (gi_filename
))
369 /* Open failed likely due to missed directory.
370 Create directory and retry to open file. */
371 if (create_file_directory (gi_filename
))
373 fprintf (stderr
, "profiling:%s:Skip\n", gi_filename
);
376 if (!gcov_open (gi_filename
))
378 fprintf (stderr
, "profiling:%s:Cannot open\n", gi_filename
);
383 tag
= gcov_read_unsigned ();
386 /* Merge data from file. */
387 if (tag
!= GCOV_DATA_MAGIC
)
389 fprintf (stderr
, "profiling:%s:Not a gcov data file\n",
393 length
= gcov_read_unsigned ();
394 if (!gcov_version (gi_ptr
, length
, gi_filename
))
397 length
= gcov_read_unsigned ();
398 if (length
!= gi_ptr
->stamp
)
399 /* Read from a different compilation. Overwrite the file. */
402 /* Look for program summary. */
405 struct gcov_summary tmp
;
407 eof_pos
= gcov_position ();
408 tag
= gcov_read_unsigned ();
409 if (tag
!= GCOV_TAG_PROGRAM_SUMMARY
)
412 length
= gcov_read_unsigned ();
413 if (length
!= GCOV_TAG_SUMMARY_LENGTH
)
415 gcov_read_summary (&tmp
);
416 if ((error
= gcov_is_error ()))
418 if (!summary_pos
&& tmp
.checksum
== gcov_crc32
)
421 summary_pos
= eof_pos
;
425 /* Merge execution counts for each function. */
426 for (f_ix
= 0; f_ix
!= gi_ptr
->n_functions
;
427 f_ix
++, tag
= gcov_read_unsigned ())
429 gfi_ptr
= gi_ptr
->functions
[f_ix
];
431 if (tag
!= GCOV_TAG_FUNCTION
)
433 length
= gcov_read_unsigned ();
436 /* This function did not appear in the other program.
437 We have nothing to merge. */
440 if (length
!= GCOV_TAG_FUNCTION_LENGTH
)
443 if (!gfi_ptr
|| gfi_ptr
->key
!= gi_ptr
)
445 /* This function appears in the other program. We
446 need to buffer the information in order to write
447 it back out -- we'll be inserting data before
448 this point, so cannot simply keep the data in the
450 fn_tail
= buffer_fn_data (gi_ptr
, fn_tail
, f_ix
);
456 if (gcov_read_unsigned () != gfi_ptr
->ident
457 || gcov_read_unsigned () != gfi_ptr
->lineno_checksum
458 || gcov_read_unsigned () != gfi_ptr
->cfg_checksum
)
461 ci_ptr
= gfi_ptr
->ctrs
;
462 for (t_ix
= 0; t_ix
< GCOV_COUNTERS
; t_ix
++)
464 gcov_merge_fn merge
= gi_ptr
->merge
[t_ix
];
469 tag
= gcov_read_unsigned ();
470 length
= gcov_read_unsigned ();
471 if (tag
!= GCOV_TAG_FOR_COUNTER (t_ix
)
472 || length
!= GCOV_TAG_COUNTER_LENGTH (ci_ptr
->num
))
474 (*merge
) (ci_ptr
->values
, ci_ptr
->num
);
477 if ((error
= gcov_is_error ()))
484 fprintf (stderr
, "profiling:%s:Merge mismatch for %s\n",
485 gi_filename
, f_ix
+ 1 ? "function" : "summaries");
492 fprintf (stderr
, "profiling:%s:%s merging\n", gi_filename
,
493 error
< 0 ? "Overflow": "Error");
503 memset (&prg
, 0, sizeof (prg
));
504 summary_pos
= eof_pos
;
507 /* Merge the summaries. */
508 for (t_ix
= 0; t_ix
< GCOV_COUNTERS_SUMMABLE
; t_ix
++)
510 cs_prg
= &prg
.ctrs
[t_ix
];
511 cs_tprg
= &this_prg
.ctrs
[t_ix
];
512 cs_all
= &all_prg
.ctrs
[t_ix
];
514 if (gi_ptr
->merge
[t_ix
])
517 cs_prg
->num
= cs_tprg
->num
;
518 else if (cs_prg
->num
!= cs_tprg
->num
)
520 cs_prg
->sum_all
+= cs_tprg
->sum_all
;
521 if (cs_prg
->run_max
< cs_tprg
->run_max
)
522 cs_prg
->run_max
= cs_tprg
->run_max
;
523 cs_prg
->sum_max
+= cs_tprg
->run_max
;
525 else if (cs_prg
->runs
)
528 if (!cs_all
->runs
&& cs_prg
->runs
)
529 memcpy (cs_all
, cs_prg
, sizeof (*cs_all
));
530 else if (!all_prg
.checksum
531 && (!GCOV_LOCKED
|| cs_all
->runs
== cs_prg
->runs
)
532 && memcmp (cs_all
, cs_prg
, sizeof (*cs_all
)))
534 fprintf (stderr
, "profiling:%s:Invocation mismatch - some data files may have been removed%s\n",
535 gi_filename
, GCOV_LOCKED
536 ? "" : " or concurrently updated without locking support");
537 all_prg
.checksum
= ~0u;
541 prg
.checksum
= gcov_crc32
;
543 /* Write out the data. */
546 gcov_write_tag_length (GCOV_DATA_MAGIC
, GCOV_VERSION
);
547 gcov_write_unsigned (gi_ptr
->stamp
);
551 gcov_seek (summary_pos
);
553 /* Generate whole program statistics. */
554 gcov_write_summary (GCOV_TAG_PROGRAM_SUMMARY
, &prg
);
556 if (summary_pos
< eof_pos
)
559 /* Write execution counts for each function. */
560 for (f_ix
= 0; f_ix
< gi_ptr
->n_functions
; f_ix
++)
562 unsigned buffered
= 0;
564 if (fn_buffer
&& fn_buffer
->fn_ix
== f_ix
)
566 /* Buffered data from another program. */
568 gfi_ptr
= &fn_buffer
->info
;
569 length
= GCOV_TAG_FUNCTION_LENGTH
;
573 gfi_ptr
= gi_ptr
->functions
[f_ix
];
574 if (gfi_ptr
&& gfi_ptr
->key
== gi_ptr
)
575 length
= GCOV_TAG_FUNCTION_LENGTH
;
580 gcov_write_tag_length (GCOV_TAG_FUNCTION
, length
);
584 gcov_write_unsigned (gfi_ptr
->ident
);
585 gcov_write_unsigned (gfi_ptr
->lineno_checksum
);
586 gcov_write_unsigned (gfi_ptr
->cfg_checksum
);
588 ci_ptr
= gfi_ptr
->ctrs
;
589 for (t_ix
= 0; t_ix
< GCOV_COUNTERS
; t_ix
++)
591 if (!gi_ptr
->merge
[t_ix
])
594 n_counts
= ci_ptr
->num
;
595 gcov_write_tag_length (GCOV_TAG_FOR_COUNTER (t_ix
),
596 GCOV_TAG_COUNTER_LENGTH (n_counts
));
597 gcov_type
*c_ptr
= ci_ptr
->values
;
599 gcov_write_counter (*c_ptr
++);
601 free (ci_ptr
->values
);
606 struct gcov_fn_buffer
*tmp
= fn_buffer
;
607 fn_buffer
= fn_buffer
->next
;
612 gcov_write_unsigned (0);
613 if ((error
= gcov_close ()))
614 fprintf (stderr
, error
< 0 ?
615 "profiling:%s:Overflow writing\n" :
616 "profiling:%s:Error writing\n",
621 /* Add a new object file onto the bb chain. Invoked automatically
622 when running an object file's global ctors. */
625 __gcov_init (struct gcov_info
*info
)
629 if (gcov_version (info
, info
->version
, 0))
631 const char *ptr
= info
->filename
;
632 gcov_unsigned_t crc32
= gcov_crc32
;
633 size_t filename_length
= strlen(info
->filename
);
635 /* Refresh the longest file name information */
636 if (filename_length
> gcov_max_filename
)
637 gcov_max_filename
= filename_length
;
642 gcov_unsigned_t value
= *ptr
<< 24;
644 for (ix
= 8; ix
--; value
<<= 1)
646 gcov_unsigned_t feedback
;
648 feedback
= (value
^ crc32
) & 0x80000000 ? 0x04c11db7 : 0;
660 info
->next
= gcov_list
;
666 /* Called before fork or exec - write out profile information gathered so
667 far and reset it to zero. This avoids duplication or loss of the
668 profile information gathered so far. */
673 const struct gcov_info
*gi_ptr
;
676 for (gi_ptr
= gcov_list
; gi_ptr
; gi_ptr
= gi_ptr
->next
)
680 for (f_ix
= 0; f_ix
< gi_ptr
->n_functions
; f_ix
++)
683 const struct gcov_fn_info
*gfi_ptr
= gi_ptr
->functions
[f_ix
];
685 if (!gfi_ptr
|| gfi_ptr
->key
!= gi_ptr
)
687 const struct gcov_ctr_info
*ci_ptr
= gfi_ptr
->ctrs
;
688 for (t_ix
= 0; t_ix
!= GCOV_COUNTERS
; t_ix
++)
690 if (!gi_ptr
->merge
[t_ix
])
693 memset (ci_ptr
->values
, 0, sizeof (gcov_type
) * ci_ptr
->num
);
702 #ifdef L_gcov_merge_add
703 /* The profile merging function that just adds the counters. It is given
704 an array COUNTERS of N_COUNTERS old counters and it reads the same number
705 of counters from the gcov file. */
707 __gcov_merge_add (gcov_type
*counters
, unsigned n_counters
)
709 for (; n_counters
; counters
++, n_counters
--)
710 *counters
+= gcov_read_counter ();
712 #endif /* L_gcov_merge_add */
714 #ifdef L_gcov_merge_ior
715 /* The profile merging function that just adds the counters. It is given
716 an array COUNTERS of N_COUNTERS old counters and it reads the same number
717 of counters from the gcov file. */
719 __gcov_merge_ior (gcov_type
*counters
, unsigned n_counters
)
721 for (; n_counters
; counters
++, n_counters
--)
722 *counters
|= gcov_read_counter ();
726 #ifdef L_gcov_merge_single
727 /* The profile merging function for choosing the most common value.
728 It is given an array COUNTERS of N_COUNTERS old counters and it
729 reads the same number of counters from the gcov file. The counters
730 are split into 3-tuples where the members of the tuple have
733 -- the stored candidate on the most common value of the measured entity
735 -- total number of evaluations of the value */
737 __gcov_merge_single (gcov_type
*counters
, unsigned n_counters
)
739 unsigned i
, n_measures
;
740 gcov_type value
, counter
, all
;
742 gcc_assert (!(n_counters
% 3));
743 n_measures
= n_counters
/ 3;
744 for (i
= 0; i
< n_measures
; i
++, counters
+= 3)
746 value
= gcov_read_counter ();
747 counter
= gcov_read_counter ();
748 all
= gcov_read_counter ();
750 if (counters
[0] == value
)
751 counters
[1] += counter
;
752 else if (counter
> counters
[1])
755 counters
[1] = counter
- counters
[1];
758 counters
[1] -= counter
;
762 #endif /* L_gcov_merge_single */
764 #ifdef L_gcov_merge_delta
765 /* The profile merging function for choosing the most common
766 difference between two consecutive evaluations of the value. It is
767 given an array COUNTERS of N_COUNTERS old counters and it reads the
768 same number of counters from the gcov file. The counters are split
769 into 4-tuples where the members of the tuple have meanings:
771 -- the last value of the measured entity
772 -- the stored candidate on the most common difference
774 -- total number of evaluations of the value */
776 __gcov_merge_delta (gcov_type
*counters
, unsigned n_counters
)
778 unsigned i
, n_measures
;
779 gcov_type value
, counter
, all
;
781 gcc_assert (!(n_counters
% 4));
782 n_measures
= n_counters
/ 4;
783 for (i
= 0; i
< n_measures
; i
++, counters
+= 4)
785 /* last = */ gcov_read_counter ();
786 value
= gcov_read_counter ();
787 counter
= gcov_read_counter ();
788 all
= gcov_read_counter ();
790 if (counters
[1] == value
)
791 counters
[2] += counter
;
792 else if (counter
> counters
[2])
795 counters
[2] = counter
- counters
[2];
798 counters
[2] -= counter
;
802 #endif /* L_gcov_merge_delta */
804 #ifdef L_gcov_interval_profiler
805 /* If VALUE is in interval <START, START + STEPS - 1>, then increases the
806 corresponding counter in COUNTERS. If the VALUE is above or below
807 the interval, COUNTERS[STEPS] or COUNTERS[STEPS + 1] is increased
811 __gcov_interval_profiler (gcov_type
*counters
, gcov_type value
,
812 int start
, unsigned steps
)
814 gcov_type delta
= value
- start
;
816 counters
[steps
+ 1]++;
817 else if (delta
>= steps
)
824 #ifdef L_gcov_pow2_profiler
825 /* If VALUE is a power of two, COUNTERS[1] is incremented. Otherwise
826 COUNTERS[0] is incremented. */
829 __gcov_pow2_profiler (gcov_type
*counters
, gcov_type value
)
831 if (value
& (value
- 1))
838 /* Tries to determine the most common value among its inputs. Checks if the
839 value stored in COUNTERS[0] matches VALUE. If this is the case, COUNTERS[1]
840 is incremented. If this is not the case and COUNTERS[1] is not zero,
841 COUNTERS[1] is decremented. Otherwise COUNTERS[1] is set to one and
842 VALUE is stored to COUNTERS[0]. This algorithm guarantees that if this
843 function is called more than 50% of the time with one value, this value
844 will be in COUNTERS[0] in the end.
846 In any case, COUNTERS[2] is incremented. */
849 __gcov_one_value_profiler_body (gcov_type
*counters
, gcov_type value
)
851 if (value
== counters
[0])
853 else if (counters
[1] == 0)
863 #ifdef L_gcov_one_value_profiler
865 __gcov_one_value_profiler (gcov_type
*counters
, gcov_type value
)
867 __gcov_one_value_profiler_body (counters
, value
);
871 #ifdef L_gcov_indirect_call_profiler
873 /* By default, the C++ compiler will use function addresses in the
874 vtable entries. Setting TARGET_VTABLE_USES_DESCRIPTORS to nonzero
875 tells the compiler to use function descriptors instead. The value
876 of this macro says how many words wide the descriptor is (normally 2),
877 but it may be dependent on target flags. Since we do not have access
878 to the target flags here we just check to see if it is set and use
879 that to set VTABLE_USES_DESCRIPTORS to 0 or 1.
881 It is assumed that the address of a function descriptor may be treated
882 as a pointer to a function. */
884 #ifdef TARGET_VTABLE_USES_DESCRIPTORS
885 #define VTABLE_USES_DESCRIPTORS 1
887 #define VTABLE_USES_DESCRIPTORS 0
890 /* Tries to determine the most common value among its inputs. */
892 __gcov_indirect_call_profiler (gcov_type
* counter
, gcov_type value
,
893 void* cur_func
, void* callee_func
)
895 /* If the C++ virtual tables contain function descriptors then one
896 function may have multiple descriptors and we need to dereference
897 the descriptors to see if they point to the same function. */
898 if (cur_func
== callee_func
899 || (VTABLE_USES_DESCRIPTORS
&& callee_func
900 && *(void **) cur_func
== *(void **) callee_func
))
901 __gcov_one_value_profiler_body (counter
, value
);
906 #ifdef L_gcov_average_profiler
907 /* Increase corresponding COUNTER by VALUE. FIXME: Perhaps we want
911 __gcov_average_profiler (gcov_type
*counters
, gcov_type value
)
913 counters
[0] += value
;
918 #ifdef L_gcov_ior_profiler
919 /* Increase corresponding COUNTER by VALUE. FIXME: Perhaps we want
923 __gcov_ior_profiler (gcov_type
*counters
, gcov_type value
)
930 /* A wrapper for the fork function. Flushes the accumulated profiling data, so
931 that they are not counted twice. */
942 /* A wrapper for the execl function. Flushes the accumulated profiling data, so
943 that they are not lost. */
946 __gcov_execl (const char *path
, char *arg
, ...)
958 while (va_arg (ap
, char *))
962 args
= (char **) alloca (length
* sizeof (void *));
964 for (i
= 1; i
< length
; i
++)
965 args
[i
] = va_arg (aq
, char *);
968 return execv (path
, args
);
973 /* A wrapper for the execlp function. Flushes the accumulated profiling data, so
974 that they are not lost. */
977 __gcov_execlp (const char *path
, char *arg
, ...)
989 while (va_arg (ap
, char *))
993 args
= (char **) alloca (length
* sizeof (void *));
995 for (i
= 1; i
< length
; i
++)
996 args
[i
] = va_arg (aq
, char *);
999 return execvp (path
, args
);
1003 #ifdef L_gcov_execle
1004 /* A wrapper for the execle function. Flushes the accumulated profiling data, so
1005 that they are not lost. */
1008 __gcov_execle (const char *path
, char *arg
, ...)
1021 while (va_arg (ap
, char *))
1025 args
= (char **) alloca (length
* sizeof (void *));
1027 for (i
= 1; i
< length
; i
++)
1028 args
[i
] = va_arg (aq
, char *);
1029 envp
= va_arg (aq
, char **);
1032 return execve (path
, args
, envp
);
1037 /* A wrapper for the execv function. Flushes the accumulated profiling data, so
1038 that they are not lost. */
1041 __gcov_execv (const char *path
, char *const argv
[])
1044 return execv (path
, argv
);
1048 #ifdef L_gcov_execvp
1049 /* A wrapper for the execvp function. Flushes the accumulated profiling data, so
1050 that they are not lost. */
1053 __gcov_execvp (const char *path
, char *const argv
[])
1056 return execvp (path
, argv
);
1060 #ifdef L_gcov_execve
1061 /* A wrapper for the execve function. Flushes the accumulated profiling data, so
1062 that they are not lost. */
1065 __gcov_execve (const char *path
, char *const argv
[], char *const envp
[])
1068 return execve (path
, argv
, envp
);
1071 #endif /* inhibit_libc */