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 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
))) {}
87 /* Chain of per-object gcov structures. */
88 static struct gcov_info
*gcov_list
;
90 /* A program checksum allows us to distinguish program data for an
91 object file included in multiple programs. */
92 static gcov_unsigned_t gcov_crc32
;
95 gcov_version_mismatch (struct gcov_info
*ptr
, gcov_unsigned_t version
)
97 gcov_unsigned_t expected
= GCOV_VERSION
;
101 for (ix
= 4; ix
--; expected
>>= 8, version
>>= 8)
108 "profiling:%s:Version mismatch - expected %.4s got %.4s\n",
109 ptr
->filename
, e
, v
);
112 /* Dump the coverage counts. We merge with existing counts when
113 possible, to avoid growing the .da files ad infinitum. We use this
114 program's checksum to make sure we only accumulate whole program
115 statistics to the correct summary. An object file might be embedded
116 in two separate programs, and we must keep the two program
117 summaries separate. */
122 struct gcov_info
*gi_ptr
;
123 struct gcov_summary this_program
;
124 struct gcov_summary all
;
126 memset (&all
, 0, sizeof (all
));
127 /* Find the totals for this execution. */
128 memset (&this_program
, 0, sizeof (this_program
));
129 for (gi_ptr
= gcov_list
; gi_ptr
; gi_ptr
= gi_ptr
->next
)
131 const struct gcov_ctr_info
*ci_ptr
;
132 struct gcov_ctr_summary
*cs_ptr
;
135 for (t_ix
= 0, ci_ptr
= gi_ptr
->counts
, cs_ptr
= this_program
.ctrs
;
136 t_ix
!= GCOV_COUNTERS_SUMMABLE
; t_ix
++, cs_ptr
++)
137 if ((1 << t_ix
) & gi_ptr
->ctr_mask
)
139 const gcov_type
*c_ptr
;
140 gcov_unsigned_t c_num
;
142 cs_ptr
->num
+= ci_ptr
->num
;
143 for (c_num
= ci_ptr
->num
, c_ptr
= ci_ptr
->values
; c_num
--; c_ptr
++)
145 cs_ptr
->sum_all
+= *c_ptr
;
146 if (cs_ptr
->run_max
< *c_ptr
)
147 cs_ptr
->run_max
= *c_ptr
;
153 /* Now merge each file. */
154 for (gi_ptr
= gcov_list
; gi_ptr
; gi_ptr
= gi_ptr
->next
)
156 struct gcov_summary this_object
;
157 struct gcov_summary object
, program
;
158 gcov_type
*values
[GCOV_COUNTERS
];
159 const struct gcov_fn_info
*fi_ptr
;
161 unsigned c_ix
, t_ix
, f_ix
;
162 const struct gcov_ctr_info
*ci_ptr
;
163 struct gcov_ctr_summary
*cs_ptr
;
164 struct gcov_ctr_summary
*cs_obj
, *cs_tobj
, *cs_prg
, *cs_tprg
, *cs_all
;
167 gcov_unsigned_t tag
, length
;
168 gcov_position_t summary_pos
= 0;
170 memset (&this_object
, 0, sizeof (this_object
));
171 memset (&object
, 0, sizeof (object
));
173 /* Totals for this object file. */
174 for (t_ix
= c_ix
= 0,
175 ci_ptr
= gi_ptr
->counts
, cs_ptr
= this_object
.ctrs
;
176 t_ix
!= GCOV_COUNTERS_SUMMABLE
; t_ix
++, cs_ptr
++)
177 if ((1 << t_ix
) & gi_ptr
->ctr_mask
)
179 const gcov_type
*c_ptr
;
180 gcov_unsigned_t c_num
;
182 cs_ptr
->num
+= ci_ptr
->num
;
183 values
[c_ix
] = ci_ptr
->values
;
184 for (c_num
= ci_ptr
->num
, c_ptr
= ci_ptr
->values
; c_num
--; c_ptr
++)
186 cs_ptr
->sum_all
+= *c_ptr
;
187 if (cs_ptr
->run_max
< *c_ptr
)
188 cs_ptr
->run_max
= *c_ptr
;
194 /* Calculate the function_info stride. This depends on the
195 number of counter types being measured. */
196 fi_stride
= sizeof (struct gcov_fn_info
) + c_ix
* sizeof (unsigned);
197 if (__alignof__ (struct gcov_fn_info
) > sizeof (unsigned))
199 fi_stride
+= __alignof__ (struct gcov_fn_info
) - 1;
200 fi_stride
&= ~(__alignof__ (struct gcov_fn_info
) - 1);
203 /* Open for modification, if possible */
204 merging
= gcov_open (gi_ptr
->filename
, 0);
207 fprintf (stderr
, "profiling:%s:Cannot open\n", gi_ptr
->filename
);
213 /* Merge data from file. */
214 if (gcov_read_unsigned () != GCOV_DATA_MAGIC
)
216 fprintf (stderr
, "profiling:%s:Not a gcov data file\n",
222 length
= gcov_read_unsigned ();
223 if (length
!= GCOV_VERSION
)
225 gcov_version_mismatch (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
= gi_ptr
->n_functions
, fi_ptr
= gi_ptr
->functions
;
241 fi_ptr
= (const struct gcov_fn_info
*)
242 ((const char *) fi_ptr
+ fi_stride
))
244 tag
= gcov_read_unsigned ();
245 length
= gcov_read_unsigned ();
247 /* Check function. */
248 if (tag
!= GCOV_TAG_FUNCTION
249 || length
!= GCOV_TAG_FUNCTION_LENGTH
250 || gcov_read_unsigned () != fi_ptr
->ident
251 || gcov_read_unsigned () != fi_ptr
->checksum
)
254 fprintf (stderr
, "profiling:%s:Merge mismatch for %s\n",
256 f_ix
+ 1 ? "function" : "summaries");
260 for (c_ix
= t_ix
= 0; t_ix
!= GCOV_COUNTERS
; t_ix
++)
261 if ((1 << t_ix
) & gi_ptr
->ctr_mask
)
263 unsigned n_counts
= fi_ptr
->n_ctrs
[c_ix
];
264 gcov_merge_fn merge
= gi_ptr
->counts
[c_ix
].merge
;
266 tag
= gcov_read_unsigned ();
267 length
= gcov_read_unsigned ();
268 if (tag
!= GCOV_TAG_FOR_COUNTER (t_ix
)
269 || length
!= GCOV_TAG_COUNTER_LENGTH (n_counts
))
271 (*merge
) (values
[c_ix
], n_counts
);
272 values
[c_ix
] += n_counts
;
275 if ((error
= gcov_is_error ()))
279 /* Check program & object summary */
282 gcov_position_t base
= gcov_position ();
285 tag
= gcov_read_unsigned ();
288 length
= gcov_read_unsigned ();
289 is_program
= tag
== GCOV_TAG_PROGRAM_SUMMARY
;
290 if (length
!= GCOV_TAG_SUMMARY_LENGTH
291 || (!is_program
&& tag
!= GCOV_TAG_OBJECT_SUMMARY
))
293 gcov_read_summary (is_program
? &program
: &object
);
294 if ((error
= gcov_is_error ()))
296 if (is_program
&& program
.checksum
== gcov_crc32
)
305 fprintf (stderr
, error
< 0 ? "profiling:%s:Overflow merging\n"
306 : "profiling:%s:Error merging\n", gi_ptr
->filename
);
313 memset (&program
, 0, sizeof (program
));
315 /* Merge the summaries. */
317 for (t_ix
= c_ix
= 0,
318 cs_obj
= object
.ctrs
, cs_tobj
= this_object
.ctrs
,
319 cs_prg
= program
.ctrs
, cs_tprg
= this_program
.ctrs
,
321 t_ix
!= GCOV_COUNTERS_SUMMABLE
;
322 t_ix
++, cs_obj
++, cs_tobj
++, cs_prg
++, cs_tprg
++, cs_all
++)
324 if ((1 << t_ix
) & gi_ptr
->ctr_mask
)
327 cs_obj
->num
= cs_tobj
->num
;
328 else if (cs_obj
->num
!= cs_tobj
->num
)
330 cs_obj
->sum_all
+= cs_tobj
->sum_all
;
331 if (cs_obj
->run_max
< cs_tobj
->run_max
)
332 cs_obj
->run_max
= cs_tobj
->run_max
;
333 cs_obj
->sum_max
+= cs_tobj
->run_max
;
336 cs_prg
->num
= cs_tprg
->num
;
337 else if (cs_prg
->num
!= cs_tprg
->num
)
339 cs_prg
->sum_all
+= cs_tprg
->sum_all
;
340 if (cs_prg
->run_max
< cs_tprg
->run_max
)
341 cs_prg
->run_max
= cs_tprg
->run_max
;
342 cs_prg
->sum_max
+= cs_tprg
->run_max
;
344 values
[c_ix
] = gi_ptr
->counts
[c_ix
].values
;
347 else if (cs_obj
->num
|| cs_prg
->num
)
350 if (!cs_all
->runs
&& cs_prg
->runs
)
351 memcpy (cs_all
, cs_prg
, sizeof (*cs_all
));
352 else if (!all
.checksum
353 && (!GCOV_LOCKED
|| cs_all
->runs
== cs_prg
->runs
)
354 && memcmp (cs_all
, cs_prg
, sizeof (*cs_all
)))
356 fprintf (stderr
, "profiling:%s:Invocation mismatch - some data files may have been removed%s",
357 gi_ptr
->filename
, GCOV_LOCKED
358 ? "" : " or concurrent update without locking support");
363 program
.checksum
= gcov_crc32
;
365 /* Write out the data. */
366 gcov_write_tag_length (GCOV_DATA_MAGIC
, GCOV_VERSION
);
367 gcov_write_unsigned (gi_ptr
->stamp
);
369 /* Write execution counts for each function. */
370 for (f_ix
= gi_ptr
->n_functions
, fi_ptr
= gi_ptr
->functions
; f_ix
--;
371 fi_ptr
= (const struct gcov_fn_info
*)
372 ((const char *) fi_ptr
+ fi_stride
))
374 /* Announce function. */
375 gcov_write_tag_length (GCOV_TAG_FUNCTION
, GCOV_TAG_FUNCTION_LENGTH
);
376 gcov_write_unsigned (fi_ptr
->ident
);
377 gcov_write_unsigned (fi_ptr
->checksum
);
379 for (c_ix
= t_ix
= 0; t_ix
!= GCOV_COUNTERS
; t_ix
++)
380 if ((1 << t_ix
) & gi_ptr
->ctr_mask
)
382 unsigned n_counts
= fi_ptr
->n_ctrs
[c_ix
];
385 gcov_write_tag_length (GCOV_TAG_FOR_COUNTER (t_ix
),
386 GCOV_TAG_COUNTER_LENGTH (n_counts
));
387 c_ptr
= values
[c_ix
];
389 gcov_write_counter (*c_ptr
++);
390 values
[c_ix
] = c_ptr
;
395 /* Object file summary. */
396 gcov_write_summary (GCOV_TAG_OBJECT_SUMMARY
, &object
);
398 /* Generate whole program statistics. */
399 gcov_seek (summary_pos
);
400 gcov_write_summary (GCOV_TAG_PROGRAM_SUMMARY
, &program
);
401 if ((error
= gcov_close ()))
402 fprintf (stderr
, error
< 0 ?
403 "profiling:%s:Overflow writing\n" :
404 "profiling:%s:Error writing\n",
409 /* Add a new object file onto the bb chain. Invoked automatically
410 when running an object file's global ctors. */
413 __gcov_init (struct gcov_info
*info
)
417 if (info
->version
!= GCOV_VERSION
)
418 gcov_version_mismatch (info
, info
->version
);
421 const char *ptr
= info
->filename
;
422 gcov_unsigned_t crc32
= gcov_crc32
;
427 gcov_unsigned_t value
= *ptr
<< 24;
429 for (ix
= 8; ix
--; value
<<= 1)
431 gcov_unsigned_t feedback
;
433 feedback
= (value
^ crc32
) & 0x80000000 ? 0x04c11db7 : 0;
445 info
->next
= gcov_list
;
451 /* Called before fork or exec - write out profile information gathered so
452 far and reset it to zero. This avoids duplication or loss of the
453 profile information gathered so far. */
458 const struct gcov_info
*gi_ptr
;
461 for (gi_ptr
= gcov_list
; gi_ptr
; gi_ptr
= gi_ptr
->next
)
464 const struct gcov_ctr_info
*ci_ptr
;
466 for (t_ix
= 0, ci_ptr
= gi_ptr
->counts
; t_ix
!= GCOV_COUNTERS
; t_ix
++)
467 if ((1 << t_ix
) & gi_ptr
->ctr_mask
)
469 memset (ci_ptr
->values
, 0, sizeof (gcov_type
) * ci_ptr
->num
);
477 #ifdef L_gcov_merge_add
478 /* The profile merging function that just adds the counters. It is given
479 an array COUNTERS of N_COUNTERS old counters and it reads the same number
480 of counters from the gcov file. */
482 __gcov_merge_add (gcov_type
*counters
, unsigned n_counters
)
484 for (; n_counters
; counters
++, n_counters
--)
485 *counters
+= gcov_read_counter ();
487 #endif /* L_gcov_merge_add */
489 #ifdef L_gcov_merge_single
490 /* The profile merging function for choosing the most common value. It is given
491 an array COUNTERS of N_COUNTERS old counters and it reads the same number
492 of counters from the gcov file. The counters are split into 3-tuples
493 where the members of the tuple have meanings:
494 -- the stored candidate on the most common value of the measured entity
496 -- total number of evaluations of the value */
498 __gcov_merge_single (gcov_type
*counters
, unsigned n_counters
)
500 unsigned i
, n_measures
;
501 gcov_type value
, counter
, all
;
506 n_measures
= n_counters
/ 3;
507 for (i
= 0; i
< n_measures
; i
++, counters
+= 3)
509 value
= gcov_read_counter ();
510 counter
= gcov_read_counter ();
511 all
= gcov_read_counter ();
513 if (counters
[0] == value
)
514 counters
[1] += counter
;
515 else if (counter
> counters
[1])
518 counters
[1] = counter
- counters
[1];
521 counters
[1] -= counter
;
525 #endif /* L_gcov_merge_single */
527 #ifdef L_gcov_merge_delta
528 /* The profile merging function for choosing the most common difference between
529 two consecutive evaluations of the value. It is given an array COUNTERS of
530 N_COUNTERS old counters and it reads the same number of counters from the
531 gcov file. The counters are split into 4-tuples where the members of the
533 -- the last value of the measured entity
534 -- the stored candidate on the most common difference
536 -- total number of evaluations of the value */
538 __gcov_merge_delta (gcov_type
*counters
, unsigned n_counters
)
540 unsigned i
, n_measures
;
541 gcov_type last
, value
, counter
, all
;
546 n_measures
= n_counters
/ 4;
547 for (i
= 0; i
< n_measures
; i
++, counters
+= 4)
549 last
= gcov_read_counter ();
550 value
= gcov_read_counter ();
551 counter
= gcov_read_counter ();
552 all
= gcov_read_counter ();
554 if (counters
[1] == value
)
555 counters
[2] += counter
;
556 else if (counter
> counters
[2])
559 counters
[2] = counter
- counters
[2];
562 counters
[2] -= counter
;
566 #endif /* L_gcov_merge_delta */
568 #endif /* inhibit_libc */