libgcov.c revision 132718
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.
5
6This file is part of GCC.
7
8GCC is free software; you can redistribute it and/or modify it under
9the terms of the GNU General Public License as published by the Free
10Software Foundation; either version 2, or (at your option) any later
11version.
12
13In addition to the permissions in the GNU General Public License, the
14Free Software Foundation gives you unlimited permission to link the
15compiled version of this file into combinations with other programs,
16and to distribute those combinations without any restriction coming
17from the use of this file.  (The General Public License restrictions
18do apply in other respects; for example, they cover modification of
19the file, and distribution when not linked into a combine
20executable.)
21
22GCC is distributed in the hope that it will be useful, but WITHOUT ANY
23WARRANTY; without even the implied warranty of MERCHANTABILITY or
24FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
25for more details.
26
27You should have received a copy of the GNU General Public License
28along with GCC; see the file COPYING.  If not, write to the Free
29Software Foundation, 59 Temple Place - Suite 330, Boston, MA
3002111-1307, USA.  */
31
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
34   do not apply.  */
35
36#include "tconfig.h"
37#include "tsystem.h"
38#include "coretypes.h"
39#include "tm.h"
40
41#if defined(inhibit_libc)
42#define IN_LIBGCOV (-1)
43#else
44#undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch.  */
45#include <stdio.h>
46#define IN_LIBGCOV 1
47#if defined(L_gcov)
48#define GCOV_LINKAGE /* nothing */
49#endif
50#endif
51#include "gcov-io.h"
52
53#if defined(inhibit_libc)
54/* If libc and its header files are not available, provide dummy functions.  */
55
56#ifdef L_gcov
57void __gcov_init (struct gcov_info *p __attribute__ ((unused))) {}
58void __gcov_flush (void) {}
59#endif
60
61#ifdef L_gcov_merge_add
62void __gcov_merge_add (gcov_type *counters  __attribute__ ((unused)),
63		       unsigned n_counters __attribute__ ((unused))) {}
64#endif
65
66#ifdef L_gcov_merge_single
67void __gcov_merge_single (gcov_type *counters  __attribute__ ((unused)),
68			  unsigned n_counters __attribute__ ((unused))) {}
69#endif
70
71#ifdef L_gcov_merge_delta
72void __gcov_merge_delta (gcov_type *counters  __attribute__ ((unused)),
73			 unsigned n_counters __attribute__ ((unused))) {}
74#endif
75
76#else
77
78#include <string.h>
79#if GCOV_LOCKED
80#include <fcntl.h>
81#include <errno.h>
82#include <sys/stat.h>
83#endif
84
85#ifdef L_gcov
86#include "gcov-io.c"
87
88/* Chain of per-object gcov structures.  */
89static struct gcov_info *gcov_list;
90
91/* A program checksum allows us to distinguish program data for an
92   object file included in multiple programs.  */
93static gcov_unsigned_t gcov_crc32;
94
95static int
96gcov_version (struct gcov_info *ptr, gcov_unsigned_t version)
97{
98  if (version != GCOV_VERSION)
99    {
100      char v[4], e[4];
101
102      GCOV_UNSIGNED2STRING (v, version);
103      GCOV_UNSIGNED2STRING (e, GCOV_VERSION);
104
105      fprintf (stderr,
106	       "profiling:%s:Version mismatch - expected %.4s got %.4s\n",
107	       ptr->filename, e, v);
108      return 0;
109    }
110  return 1;
111}
112
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.  */
119
120static void
121gcov_exit (void)
122{
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;
128  unsigned t_ix;
129  gcov_unsigned_t c_num;
130
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)
135    {
136      ci_ptr = gi_ptr->counts;
137      for (t_ix = 0; t_ix < GCOV_COUNTERS_SUMMABLE; t_ix++)
138	{
139	  if (!((1 << t_ix) & gi_ptr->ctr_mask))
140	    continue;
141
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++)
145	    {
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];
149	    }
150	  ci_ptr++;
151	}
152    }
153
154  /* Now merge each file.  */
155  for (gi_ptr = gcov_list; gi_ptr; gi_ptr = gi_ptr->next)
156    {
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;
161      unsigned fi_stride;
162      unsigned c_ix, f_ix, n_counts;
163      struct gcov_ctr_summary *cs_obj, *cs_tobj, *cs_prg, *cs_tprg, *cs_all;
164      int error = 0;
165      gcov_unsigned_t tag, length;
166      gcov_position_t summary_pos = 0;
167
168      memset (&this_object, 0, sizeof (this_object));
169      memset (&object, 0, sizeof (object));
170
171      /* Totals for this object file.  */
172      ci_ptr = gi_ptr->counts;
173      for (t_ix = 0; t_ix < GCOV_COUNTERS_SUMMABLE; t_ix++)
174	{
175	  if (!((1 << t_ix) & gi_ptr->ctr_mask))
176	    continue;
177
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++)
181	    {
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];
185	    }
186
187	  ci_ptr++;
188	}
189
190      c_ix = 0;
191      for (t_ix = 0; t_ix < GCOV_COUNTERS; t_ix++)
192	if ((1 << t_ix) & gi_ptr->ctr_mask)
193	  {
194	    values[c_ix] = gi_ptr->counts[c_ix].values;
195	    c_ix++;
196	  }
197
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))
202	{
203	  fi_stride += __alignof__ (struct gcov_fn_info) - 1;
204	  fi_stride &= ~(__alignof__ (struct gcov_fn_info) - 1);
205	}
206
207      if (!gcov_open (gi_ptr->filename))
208	{
209	  fprintf (stderr, "profiling:%s:Cannot open\n", gi_ptr->filename);
210	  continue;
211	}
212
213      tag = gcov_read_unsigned ();
214      if (tag)
215	{
216	  /* Merge data from file.  */
217	  if (tag != GCOV_DATA_MAGIC)
218	    {
219	      fprintf (stderr, "profiling:%s:Not a gcov data file\n",
220		       gi_ptr->filename);
221	    read_fatal:;
222	      gcov_close ();
223	      continue;
224	    }
225	  length = gcov_read_unsigned ();
226	  if (!gcov_version (gi_ptr, length))
227	    goto read_fatal;
228
229	  length = gcov_read_unsigned ();
230	  if (length != gi_ptr->stamp)
231	    {
232	      /* Read from a different compilation. Overwrite the
233		 file.  */
234	      gcov_truncate ();
235	      goto rewrite;
236	    }
237
238	  /* Merge execution counts for each function.  */
239	  for (f_ix = 0; f_ix < gi_ptr->n_functions; f_ix++)
240	    {
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 ();
245
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)
251		{
252		read_mismatch:;
253		  fprintf (stderr, "profiling:%s:Merge mismatch for %s\n",
254			   gi_ptr->filename,
255			   f_ix + 1 ? "function" : "summaries");
256		  goto read_fatal;
257		}
258
259	      c_ix = 0;
260	      for (t_ix = 0; t_ix < GCOV_COUNTERS; t_ix++)
261		{
262		  gcov_merge_fn merge;
263
264		  if (!((1 << t_ix) & gi_ptr->ctr_mask))
265		    continue;
266
267		  n_counts = fi_ptr->n_ctrs[c_ix];
268		  merge = gi_ptr->counts[c_ix].merge;
269
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))
274		    goto read_mismatch;
275		  (*merge) (values[c_ix], n_counts);
276		  values[c_ix] += n_counts;
277		  c_ix++;
278		}
279	      if ((error = gcov_is_error ()))
280		goto read_error;
281	    }
282
283	  f_ix = ~0u;
284	  /* Check program & object summary */
285	  while (1)
286	    {
287	      gcov_position_t base = gcov_position ();
288	      int is_program;
289
290	      tag = gcov_read_unsigned ();
291	      if (!tag)
292		break;
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))
297		goto read_mismatch;
298	      gcov_read_summary (is_program ? &program : &object);
299	      if ((error = gcov_is_error ()))
300		goto read_error;
301	      if (is_program && program.checksum == gcov_crc32)
302		{
303		  summary_pos = base;
304		  goto rewrite;
305		}
306	    }
307	}
308
309      if (!gcov_is_eof ())
310 	{
311 	read_error:;
312 	  fprintf (stderr, error < 0 ? "profiling:%s:Overflow merging\n"
313 		   : "profiling:%s:Error merging\n", gi_ptr->filename);
314 	  goto read_fatal;
315 	}
316    rewrite:;
317      gcov_rewrite ();
318      if (!summary_pos)
319	memset (&program, 0, sizeof (program));
320
321      /* Merge the summaries.  */
322      f_ix = ~0u;
323      for (t_ix = 0; t_ix < GCOV_COUNTERS_SUMMABLE; t_ix++)
324	{
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];
330
331	  if ((1 << t_ix) & gi_ptr->ctr_mask)
332	    {
333	      if (!cs_obj->runs++)
334		cs_obj->num = cs_tobj->num;
335	      else if (cs_obj->num != cs_tobj->num)
336		goto read_mismatch;
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;
341
342	      if (!cs_prg->runs++)
343		cs_prg->num = cs_tprg->num;
344	      else if (cs_prg->num != cs_tprg->num)
345		goto read_mismatch;
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;
350	    }
351	  else if (cs_obj->num || cs_prg->num)
352	    goto read_mismatch;
353
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)))
359	    {
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");
363	      all.checksum = ~0u;
364	    }
365	}
366
367      c_ix = 0;
368      for (t_ix = 0; t_ix < GCOV_COUNTERS; t_ix++)
369	if ((1 << t_ix) & gi_ptr->ctr_mask)
370	  {
371	    values[c_ix] = gi_ptr->counts[c_ix].values;
372	    c_ix++;
373	  }
374
375      program.checksum = gcov_crc32;
376
377      /* Write out the data.  */
378      gcov_write_tag_length (GCOV_DATA_MAGIC, GCOV_VERSION);
379      gcov_write_unsigned (gi_ptr->stamp);
380
381      /* Write execution counts for each function.  */
382      for (f_ix = 0; f_ix < gi_ptr->n_functions; f_ix++)
383	{
384	  fi_ptr = (const struct gcov_fn_info *)
385		  ((const char *) gi_ptr->functions + f_ix * fi_stride);
386
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);
391
392	  c_ix = 0;
393	  for (t_ix = 0; t_ix < GCOV_COUNTERS; t_ix++)
394	    {
395	      gcov_type *c_ptr;
396
397	      if (!((1 << t_ix) & gi_ptr->ctr_mask))
398		continue;
399
400	      n_counts = fi_ptr->n_ctrs[c_ix];
401
402	      gcov_write_tag_length (GCOV_TAG_FOR_COUNTER (t_ix),
403				     GCOV_TAG_COUNTER_LENGTH (n_counts));
404	      c_ptr = values[c_ix];
405	      while (n_counts--)
406		gcov_write_counter (*c_ptr++);
407
408	      values[c_ix] = c_ptr;
409	      c_ix++;
410	    }
411	}
412
413      /* Object file summary.  */
414      gcov_write_summary (GCOV_TAG_OBJECT_SUMMARY, &object);
415
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",
423		   gi_ptr->filename);
424    }
425}
426
427/* Add a new object file onto the bb chain.  Invoked automatically
428   when running an object file's global ctors.  */
429
430void
431__gcov_init (struct gcov_info *info)
432{
433  if (!info->version)
434    return;
435  if (gcov_version (info, info->version))
436    {
437      const char *ptr = info->filename;
438      gcov_unsigned_t crc32 = gcov_crc32;
439
440      do
441	{
442	  unsigned ix;
443	  gcov_unsigned_t value = *ptr << 24;
444
445	  for (ix = 8; ix--; value <<= 1)
446	    {
447	      gcov_unsigned_t feedback;
448
449	      feedback = (value ^ crc32) & 0x80000000 ? 0x04c11db7 : 0;
450	      crc32 <<= 1;
451	      crc32 ^= feedback;
452	    }
453	}
454      while (*ptr++);
455
456      gcov_crc32 = crc32;
457
458      if (!gcov_list)
459	atexit (gcov_exit);
460
461      info->next = gcov_list;
462      gcov_list = info;
463    }
464  info->version = 0;
465}
466
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.  */
470
471void
472__gcov_flush (void)
473{
474  const struct gcov_info *gi_ptr;
475
476  gcov_exit ();
477  for (gi_ptr = gcov_list; gi_ptr; gi_ptr = gi_ptr->next)
478    {
479      unsigned t_ix;
480      const struct gcov_ctr_info *ci_ptr;
481
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)
484	  {
485	    memset (ci_ptr->values, 0, sizeof (gcov_type) * ci_ptr->num);
486	    ci_ptr++;
487	  }
488    }
489}
490
491#endif /* L_gcov */
492
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.  */
497void
498__gcov_merge_add (gcov_type *counters, unsigned n_counters)
499{
500  for (; n_counters; counters++, n_counters--)
501    *counters += gcov_read_counter ();
502}
503#endif /* L_gcov_merge_add */
504
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
510   meanings:
511
512   -- the stored candidate on the most common value of the measured entity
513   -- counter
514   -- total number of evaluations of the value  */
515void
516__gcov_merge_single (gcov_type *counters, unsigned n_counters)
517{
518  unsigned i, n_measures;
519  gcov_type value, counter, all;
520
521  GCOV_CHECK (!(n_counters % 3));
522  n_measures = n_counters / 3;
523  for (i = 0; i < n_measures; i++, counters += 3)
524    {
525      value = gcov_read_counter ();
526      counter = gcov_read_counter ();
527      all = gcov_read_counter ();
528
529      if (counters[0] == value)
530	counters[1] += counter;
531      else if (counter > counters[1])
532	{
533	  counters[0] = value;
534	  counters[1] = counter - counters[1];
535	}
536      else
537	counters[1] -= counter;
538      counters[2] += all;
539    }
540}
541#endif /* L_gcov_merge_single */
542
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:
549
550   -- the last value of the measured entity
551   -- the stored candidate on the most common difference
552   -- counter
553   -- total number of evaluations of the value  */
554void
555__gcov_merge_delta (gcov_type *counters, unsigned n_counters)
556{
557  unsigned i, n_measures;
558  gcov_type last, value, counter, all;
559
560  GCOV_CHECK (!(n_counters % 4));
561  n_measures = n_counters / 4;
562  for (i = 0; i < n_measures; i++, counters += 4)
563    {
564      last = gcov_read_counter ();
565      value = gcov_read_counter ();
566      counter = gcov_read_counter ();
567      all = gcov_read_counter ();
568
569      if (counters[1] == value)
570	counters[2] += counter;
571      else if (counter > counters[2])
572	{
573	  counters[1] = value;
574	  counters[2] = counter - counters[2];
575	}
576      else
577	counters[2] -= counter;
578      counters[3] += all;
579    }
580}
581#endif /* L_gcov_merge_delta */
582
583#endif /* inhibit_libc */
584