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 Free Software Foundation, Inc.
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 2, or (at your option) any later
13 In addition to the permissions in the GNU General Public License, the
14 Free Software Foundation gives you unlimited permission to link the
15 compiled version of this file into combinations with other programs,
16 and to distribute those combinations without any restriction coming
17 from the use of this file. (The General Public License restrictions
18 do apply in other respects; for example, they cover modification of
19 the file, and distribution when not linked into a combine
22 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
23 WARRANTY; without even the implied warranty of MERCHANTABILITY or
24 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
27 You should have received a copy of the GNU General Public License
28 along with GCC; see the file COPYING. If not, write to the Free
29 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
32 /* It is incorrect to include config.h here, because this file is being
33 compiled for the target, and hence definitions concerning only the host
38 #include "coretypes.h"
41 #if defined(inhibit_libc)
42 #define IN_LIBGCOV (-1)
44 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */
48 #define GCOV_LINKAGE /* nothing */
53 #if defined(inhibit_libc)
54 /* If libc and its header files are not available, provide dummy functions. */
57 void __gcov_init (struct gcov_info
*p
__attribute__ ((unused
))) {}
58 void __gcov_flush (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
))) {}
88 /* Chain of per-object gcov structures. */
89 static struct gcov_info
*gcov_list
;
91 /* A program checksum allows us to distinguish program data for an
92 object file included in multiple programs. */
93 static gcov_unsigned_t gcov_crc32
;
96 gcov_version (struct gcov_info
*ptr
, gcov_unsigned_t version
)
98 if (version
!= GCOV_VERSION
)
102 GCOV_UNSIGNED2STRING (v
, version
);
103 GCOV_UNSIGNED2STRING (e
, GCOV_VERSION
);
106 "profiling:%s:Version mismatch - expected %.4s got %.4s\n",
107 ptr
->filename
, e
, v
);
113 /* Dump the coverage counts. We merge with existing counts when
114 possible, to avoid growing the .da files ad infinitum. We use this
115 program's checksum to make sure we only accumulate whole program
116 statistics to the correct summary. An object file might be embedded
117 in two separate programs, and we must keep the two program
118 summaries separate. */
123 struct gcov_info
*gi_ptr
;
124 struct gcov_summary this_program
;
125 struct gcov_summary all
;
126 struct gcov_ctr_summary
*cs_ptr
;
127 const struct gcov_ctr_info
*ci_ptr
;
129 gcov_unsigned_t c_num
;
131 memset (&all
, 0, sizeof (all
));
132 /* Find the totals for this execution. */
133 memset (&this_program
, 0, sizeof (this_program
));
134 for (gi_ptr
= gcov_list
; gi_ptr
; gi_ptr
= gi_ptr
->next
)
136 ci_ptr
= gi_ptr
->counts
;
137 for (t_ix
= 0; t_ix
< GCOV_COUNTERS_SUMMABLE
; t_ix
++)
139 if (!((1 << t_ix
) & gi_ptr
->ctr_mask
))
142 cs_ptr
= &this_program
.ctrs
[t_ix
];
143 cs_ptr
->num
+= ci_ptr
->num
;
144 for (c_num
= 0; c_num
< ci_ptr
->num
; c_num
++)
146 cs_ptr
->sum_all
+= ci_ptr
->values
[c_num
];
147 if (cs_ptr
->run_max
< ci_ptr
->values
[c_num
])
148 cs_ptr
->run_max
= ci_ptr
->values
[c_num
];
154 /* Now merge each file. */
155 for (gi_ptr
= gcov_list
; gi_ptr
; gi_ptr
= gi_ptr
->next
)
157 struct gcov_summary this_object
;
158 struct gcov_summary object
, program
;
159 gcov_type
*values
[GCOV_COUNTERS
];
160 const struct gcov_fn_info
*fi_ptr
;
162 unsigned c_ix
, f_ix
, n_counts
;
163 struct gcov_ctr_summary
*cs_obj
, *cs_tobj
, *cs_prg
, *cs_tprg
, *cs_all
;
165 gcov_unsigned_t tag
, length
;
166 gcov_position_t summary_pos
= 0;
168 memset (&this_object
, 0, sizeof (this_object
));
169 memset (&object
, 0, sizeof (object
));
171 /* Totals for this object file. */
172 ci_ptr
= gi_ptr
->counts
;
173 for (t_ix
= 0; t_ix
< GCOV_COUNTERS_SUMMABLE
; t_ix
++)
175 if (!((1 << t_ix
) & gi_ptr
->ctr_mask
))
178 cs_ptr
= &this_object
.ctrs
[t_ix
];
179 cs_ptr
->num
+= ci_ptr
->num
;
180 for (c_num
= 0; c_num
< ci_ptr
->num
; c_num
++)
182 cs_ptr
->sum_all
+= ci_ptr
->values
[c_num
];
183 if (cs_ptr
->run_max
< ci_ptr
->values
[c_num
])
184 cs_ptr
->run_max
= ci_ptr
->values
[c_num
];
191 for (t_ix
= 0; t_ix
< GCOV_COUNTERS
; t_ix
++)
192 if ((1 << t_ix
) & gi_ptr
->ctr_mask
)
194 values
[c_ix
] = gi_ptr
->counts
[c_ix
].values
;
198 /* Calculate the function_info stride. This depends on the
199 number of counter types being measured. */
200 fi_stride
= sizeof (struct gcov_fn_info
) + c_ix
* sizeof (unsigned);
201 if (__alignof__ (struct gcov_fn_info
) > sizeof (unsigned))
203 fi_stride
+= __alignof__ (struct gcov_fn_info
) - 1;
204 fi_stride
&= ~(__alignof__ (struct gcov_fn_info
) - 1);
207 if (!gcov_open (gi_ptr
->filename
))
209 fprintf (stderr
, "profiling:%s:Cannot open\n", gi_ptr
->filename
);
213 tag
= gcov_read_unsigned ();
216 /* Merge data from file. */
217 if (tag
!= GCOV_DATA_MAGIC
)
219 fprintf (stderr
, "profiling:%s:Not a gcov data file\n",
225 length
= gcov_read_unsigned ();
226 if (!gcov_version (gi_ptr
, length
))
229 length
= gcov_read_unsigned ();
230 if (length
!= gi_ptr
->stamp
)
232 /* Read from a different compilation. Overwrite the
238 /* Merge execution counts for each function. */
239 for (f_ix
= 0; f_ix
< gi_ptr
->n_functions
; f_ix
++)
241 fi_ptr
= (const struct gcov_fn_info
*)
242 ((const char *) gi_ptr
->functions
+ f_ix
* fi_stride
);
243 tag
= gcov_read_unsigned ();
244 length
= gcov_read_unsigned ();
246 /* Check function. */
247 if (tag
!= GCOV_TAG_FUNCTION
248 || length
!= GCOV_TAG_FUNCTION_LENGTH
249 || gcov_read_unsigned () != fi_ptr
->ident
250 || gcov_read_unsigned () != fi_ptr
->checksum
)
253 fprintf (stderr
, "profiling:%s:Merge mismatch for %s\n",
255 f_ix
+ 1 ? "function" : "summaries");
260 for (t_ix
= 0; t_ix
< GCOV_COUNTERS
; t_ix
++)
264 if (!((1 << t_ix
) & gi_ptr
->ctr_mask
))
267 n_counts
= fi_ptr
->n_ctrs
[c_ix
];
268 merge
= gi_ptr
->counts
[c_ix
].merge
;
270 tag
= gcov_read_unsigned ();
271 length
= gcov_read_unsigned ();
272 if (tag
!= GCOV_TAG_FOR_COUNTER (t_ix
)
273 || length
!= GCOV_TAG_COUNTER_LENGTH (n_counts
))
275 (*merge
) (values
[c_ix
], n_counts
);
276 values
[c_ix
] += n_counts
;
279 if ((error
= gcov_is_error ()))
284 /* Check program & object summary */
287 gcov_position_t base
= gcov_position ();
290 tag
= gcov_read_unsigned ();
293 length
= gcov_read_unsigned ();
294 is_program
= tag
== GCOV_TAG_PROGRAM_SUMMARY
;
295 if (length
!= GCOV_TAG_SUMMARY_LENGTH
296 || (!is_program
&& tag
!= GCOV_TAG_OBJECT_SUMMARY
))
298 gcov_read_summary (is_program
? &program
: &object
);
299 if ((error
= gcov_is_error ()))
301 if (is_program
&& program
.checksum
== gcov_crc32
)
312 fprintf (stderr
, error
< 0 ? "profiling:%s:Overflow merging\n"
313 : "profiling:%s:Error merging\n", gi_ptr
->filename
);
319 memset (&program
, 0, sizeof (program
));
321 /* Merge the summaries. */
323 for (t_ix
= 0; t_ix
< GCOV_COUNTERS_SUMMABLE
; t_ix
++)
325 cs_obj
= &object
.ctrs
[t_ix
];
326 cs_tobj
= &this_object
.ctrs
[t_ix
];
327 cs_prg
= &program
.ctrs
[t_ix
];
328 cs_tprg
= &this_program
.ctrs
[t_ix
];
329 cs_all
= &all
.ctrs
[t_ix
];
331 if ((1 << t_ix
) & gi_ptr
->ctr_mask
)
334 cs_obj
->num
= cs_tobj
->num
;
335 else if (cs_obj
->num
!= cs_tobj
->num
)
337 cs_obj
->sum_all
+= cs_tobj
->sum_all
;
338 if (cs_obj
->run_max
< cs_tobj
->run_max
)
339 cs_obj
->run_max
= cs_tobj
->run_max
;
340 cs_obj
->sum_max
+= cs_tobj
->run_max
;
343 cs_prg
->num
= cs_tprg
->num
;
344 else if (cs_prg
->num
!= cs_tprg
->num
)
346 cs_prg
->sum_all
+= cs_tprg
->sum_all
;
347 if (cs_prg
->run_max
< cs_tprg
->run_max
)
348 cs_prg
->run_max
= cs_tprg
->run_max
;
349 cs_prg
->sum_max
+= cs_tprg
->run_max
;
351 else if (cs_obj
->num
|| cs_prg
->num
)
354 if (!cs_all
->runs
&& cs_prg
->runs
)
355 memcpy (cs_all
, cs_prg
, sizeof (*cs_all
));
356 else if (!all
.checksum
357 && (!GCOV_LOCKED
|| cs_all
->runs
== cs_prg
->runs
)
358 && memcmp (cs_all
, cs_prg
, sizeof (*cs_all
)))
360 fprintf (stderr
, "profiling:%s:Invocation mismatch - some data files may have been removed%s",
361 gi_ptr
->filename
, GCOV_LOCKED
362 ? "" : " or concurrent update without locking support");
368 for (t_ix
= 0; t_ix
< GCOV_COUNTERS
; t_ix
++)
369 if ((1 << t_ix
) & gi_ptr
->ctr_mask
)
371 values
[c_ix
] = gi_ptr
->counts
[c_ix
].values
;
375 program
.checksum
= gcov_crc32
;
377 /* Write out the data. */
378 gcov_write_tag_length (GCOV_DATA_MAGIC
, GCOV_VERSION
);
379 gcov_write_unsigned (gi_ptr
->stamp
);
381 /* Write execution counts for each function. */
382 for (f_ix
= 0; f_ix
< gi_ptr
->n_functions
; f_ix
++)
384 fi_ptr
= (const struct gcov_fn_info
*)
385 ((const char *) gi_ptr
->functions
+ f_ix
* fi_stride
);
387 /* Announce function. */
388 gcov_write_tag_length (GCOV_TAG_FUNCTION
, GCOV_TAG_FUNCTION_LENGTH
);
389 gcov_write_unsigned (fi_ptr
->ident
);
390 gcov_write_unsigned (fi_ptr
->checksum
);
393 for (t_ix
= 0; t_ix
< GCOV_COUNTERS
; t_ix
++)
397 if (!((1 << t_ix
) & gi_ptr
->ctr_mask
))
400 n_counts
= fi_ptr
->n_ctrs
[c_ix
];
402 gcov_write_tag_length (GCOV_TAG_FOR_COUNTER (t_ix
),
403 GCOV_TAG_COUNTER_LENGTH (n_counts
));
404 c_ptr
= values
[c_ix
];
406 gcov_write_counter (*c_ptr
++);
408 values
[c_ix
] = c_ptr
;
413 /* Object file summary. */
414 gcov_write_summary (GCOV_TAG_OBJECT_SUMMARY
, &object
);
416 /* Generate whole program statistics. */
417 gcov_seek (summary_pos
);
418 gcov_write_summary (GCOV_TAG_PROGRAM_SUMMARY
, &program
);
419 if ((error
= gcov_close ()))
420 fprintf (stderr
, error
< 0 ?
421 "profiling:%s:Overflow writing\n" :
422 "profiling:%s:Error writing\n",
427 /* Add a new object file onto the bb chain. Invoked automatically
428 when running an object file's global ctors. */
431 __gcov_init (struct gcov_info
*info
)
435 if (gcov_version (info
, info
->version
))
437 const char *ptr
= info
->filename
;
438 gcov_unsigned_t crc32
= gcov_crc32
;
443 gcov_unsigned_t value
= *ptr
<< 24;
445 for (ix
= 8; ix
--; value
<<= 1)
447 gcov_unsigned_t feedback
;
449 feedback
= (value
^ crc32
) & 0x80000000 ? 0x04c11db7 : 0;
461 info
->next
= gcov_list
;
467 /* Called before fork or exec - write out profile information gathered so
468 far and reset it to zero. This avoids duplication or loss of the
469 profile information gathered so far. */
474 const struct gcov_info
*gi_ptr
;
477 for (gi_ptr
= gcov_list
; gi_ptr
; gi_ptr
= gi_ptr
->next
)
480 const struct gcov_ctr_info
*ci_ptr
;
482 for (t_ix
= 0, ci_ptr
= gi_ptr
->counts
; t_ix
!= GCOV_COUNTERS
; t_ix
++)
483 if ((1 << t_ix
) & gi_ptr
->ctr_mask
)
485 memset (ci_ptr
->values
, 0, sizeof (gcov_type
) * ci_ptr
->num
);
493 #ifdef L_gcov_merge_add
494 /* The profile merging function that just adds the counters. It is given
495 an array COUNTERS of N_COUNTERS old counters and it reads the same number
496 of counters from the gcov file. */
498 __gcov_merge_add (gcov_type
*counters
, unsigned n_counters
)
500 for (; n_counters
; counters
++, n_counters
--)
501 *counters
+= gcov_read_counter ();
503 #endif /* L_gcov_merge_add */
505 #ifdef L_gcov_merge_single
506 /* The profile merging function for choosing the most common value.
507 It is given an array COUNTERS of N_COUNTERS old counters and it
508 reads the same number of counters from the gcov file. The counters
509 are split into 3-tuples where the members of the tuple have
512 -- the stored candidate on the most common value of the measured entity
514 -- total number of evaluations of the value */
516 __gcov_merge_single (gcov_type
*counters
, unsigned n_counters
)
518 unsigned i
, n_measures
;
519 gcov_type value
, counter
, all
;
521 GCOV_CHECK (!(n_counters
% 3));
522 n_measures
= n_counters
/ 3;
523 for (i
= 0; i
< n_measures
; i
++, counters
+= 3)
525 value
= gcov_read_counter ();
526 counter
= gcov_read_counter ();
527 all
= gcov_read_counter ();
529 if (counters
[0] == value
)
530 counters
[1] += counter
;
531 else if (counter
> counters
[1])
534 counters
[1] = counter
- counters
[1];
537 counters
[1] -= counter
;
541 #endif /* L_gcov_merge_single */
543 #ifdef L_gcov_merge_delta
544 /* The profile merging function for choosing the most common
545 difference between two consecutive evaluations of the value. It is
546 given an array COUNTERS of N_COUNTERS old counters and it reads the
547 same number of counters from the gcov file. The counters are split
548 into 4-tuples where the members of the tuple have meanings:
550 -- the last value of the measured entity
551 -- the stored candidate on the most common difference
553 -- total number of evaluations of the value */
555 __gcov_merge_delta (gcov_type
*counters
, unsigned n_counters
)
557 unsigned i
, n_measures
;
558 gcov_type last
, value
, counter
, all
;
560 GCOV_CHECK (!(n_counters
% 4));
561 n_measures
= n_counters
/ 4;
562 for (i
= 0; i
< n_measures
; i
++, counters
+= 4)
564 last
= gcov_read_counter ();
565 value
= gcov_read_counter ();
566 counter
= gcov_read_counter ();
567 all
= gcov_read_counter ();
569 if (counters
[1] == value
)
570 counters
[2] += counter
;
571 else if (counter
> counters
[2])
574 counters
[2] = counter
- counters
[2];
577 counters
[2] -= counter
;
581 #endif /* L_gcov_merge_delta */
584 /* A wrapper for the fork function. Flushes the accumulated profiling data, so
585 that they are not counted twice. */
596 /* A wrapper for the execl function. Flushes the accumulated profiling data, so
597 that they are not lost. */
600 __gcov_execl (const char *path
, const char *arg
, ...)
612 while (va_arg (ap
, char *))
616 args
= alloca (length
* sizeof (void *));
617 args
[0] = (char *) arg
;
618 for (i
= 1; i
< length
; i
++)
619 args
[i
] = va_arg (aq
, char *);
622 return execv (path
, args
);
627 /* A wrapper for the execlp function. Flushes the accumulated profiling data, so
628 that they are not lost. */
631 __gcov_execlp (const char *path
, const char *arg
, ...)
643 while (va_arg (ap
, char *))
647 args
= alloca (length
* sizeof (void *));
648 args
[0] = (char *) arg
;
649 for (i
= 1; i
< length
; i
++)
650 args
[i
] = va_arg (aq
, char *);
653 return execvp (path
, args
);
658 /* A wrapper for the execle function. Flushes the accumulated profiling data, so
659 that they are not lost. */
662 __gcov_execle (const char *path
, const char *arg
, ...)
675 while (va_arg (ap
, char *))
679 args
= alloca (length
* sizeof (void *));
680 args
[0] = (char *) arg
;
681 for (i
= 1; i
< length
; i
++)
682 args
[i
] = va_arg (aq
, char *);
683 envp
= va_arg (aq
, char **);
686 return execve (path
, args
, envp
);
691 /* A wrapper for the execv function. Flushes the accumulated profiling data, so
692 that they are not lost. */
695 __gcov_execv (const char *path
, char *const argv
[])
698 return execv (path
, argv
);
703 /* A wrapper for the execvp function. Flushes the accumulated profiling data, so
704 that they are not lost. */
707 __gcov_execvp (const char *path
, char *const argv
[])
710 return execvp (path
, argv
);
715 /* A wrapper for the execve function. Flushes the accumulated profiling data, so
716 that they are not lost. */
719 __gcov_execve (const char *path
, char *const argv
[], char *const envp
[])
722 return execve (path
, argv
, envp
);
725 #endif /* inhibit_libc */