xref: /dragonfly/contrib/gcc-4.7/libgcc/libgcov.c (revision 0db87cb7)
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.
6 
7 This file is part of GCC.
8 
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
12 version.
13 
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
17 for more details.
18 
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.
22 
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/>.  */
27 
28 #include "tconfig.h"
29 #include "tsystem.h"
30 #include "coretypes.h"
31 #include "tm.h"
32 #include "libgcc_tm.h"
33 
34 #if defined(inhibit_libc)
35 #define IN_LIBGCOV (-1)
36 #else
37 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch.  */
38 #include <stdio.h>
39 #define IN_LIBGCOV 1
40 #if defined(L_gcov)
41 #define GCOV_LINKAGE /* nothing */
42 #endif
43 #endif
44 #include "gcov-io.h"
45 
46 #if defined(inhibit_libc)
47 /* If libc and its header files are not available, provide dummy functions.  */
48 
49 #ifdef L_gcov
50 void __gcov_init (struct gcov_info *p __attribute__ ((unused))) {}
51 void __gcov_flush (void) {}
52 #endif
53 
54 #ifdef L_gcov_merge_add
55 void __gcov_merge_add (gcov_type *counters  __attribute__ ((unused)),
56 		       unsigned n_counters __attribute__ ((unused))) {}
57 #endif
58 
59 #ifdef L_gcov_merge_single
60 void __gcov_merge_single (gcov_type *counters  __attribute__ ((unused)),
61 			  unsigned n_counters __attribute__ ((unused))) {}
62 #endif
63 
64 #ifdef L_gcov_merge_delta
65 void __gcov_merge_delta (gcov_type *counters  __attribute__ ((unused)),
66 			 unsigned n_counters __attribute__ ((unused))) {}
67 #endif
68 
69 #else
70 
71 #include <string.h>
72 #if GCOV_LOCKED
73 #include <fcntl.h>
74 #include <errno.h>
75 #include <sys/stat.h>
76 #endif
77 
78 #ifdef L_gcov
79 #include "gcov-io.c"
80 
81 struct gcov_fn_buffer
82 {
83   struct gcov_fn_buffer *next;
84   unsigned fn_ix;
85   struct gcov_fn_info info;
86   /* note gcov_fn_info ends in a trailing array.  */
87 };
88 
89 /* Chain of per-object gcov structures.  */
90 static struct gcov_info *gcov_list;
91 
92 /* Size of the longest file name. */
93 static size_t gcov_max_filename = 0;
94 
95 /* Make sure path component of the given FILENAME exists, create
96    missing directories. FILENAME must be writable.
97    Returns zero on success, or -1 if an error occurred.  */
98 
99 static int
100 create_file_directory (char *filename)
101 {
102 #if !defined(TARGET_POSIX_IO) && !defined(_WIN32)
103   (void) filename;
104   return -1;
105 #else
106   char *s;
107 
108   s = filename;
109 
110   if (HAS_DRIVE_SPEC(s))
111     s += 2;
112   if (IS_DIR_SEPARATOR(*s))
113     ++s;
114   for (; *s != '\0'; s++)
115     if (IS_DIR_SEPARATOR(*s))
116       {
117         char sep = *s;
118 	*s  = '\0';
119 
120         /* Try to make directory if it doesn't already exist.  */
121         if (access (filename, F_OK) == -1
122 #ifdef TARGET_POSIX_IO
123             && mkdir (filename, 0755) == -1
124 #else
125             && mkdir (filename) == -1
126 #endif
127             /* The directory might have been made by another process.  */
128 	    && errno != EEXIST)
129 	  {
130             fprintf (stderr, "profiling:%s:Cannot create directory\n",
131 		     filename);
132             *s = sep;
133 	    return -1;
134 	  };
135 
136 	*s = sep;
137       };
138   return 0;
139 #endif
140 }
141 
142 static struct gcov_fn_buffer *
143 free_fn_data (const struct gcov_info *gi_ptr, struct gcov_fn_buffer *buffer,
144 	      unsigned limit)
145 {
146   struct gcov_fn_buffer *next;
147   unsigned ix, n_ctr = 0;
148 
149   if (!buffer)
150     return 0;
151   next = buffer->next;
152 
153   for (ix = 0; ix != limit; ix++)
154     if (gi_ptr->merge[ix])
155       free (buffer->info.ctrs[n_ctr++].values);
156   free (buffer);
157   return next;
158 }
159 
160 static struct gcov_fn_buffer **
161 buffer_fn_data (const char *filename, const struct gcov_info *gi_ptr,
162 		struct gcov_fn_buffer **end_ptr, unsigned fn_ix)
163 {
164   unsigned n_ctrs = 0, ix = 0;
165   struct gcov_fn_buffer *fn_buffer;
166   unsigned len;
167 
168   for (ix = GCOV_COUNTERS; ix--;)
169     if (gi_ptr->merge[ix])
170       n_ctrs++;
171 
172   len = sizeof (*fn_buffer) + sizeof (fn_buffer->info.ctrs[0]) * n_ctrs;
173   fn_buffer = (struct gcov_fn_buffer *)malloc (len);
174 
175   if (!fn_buffer)
176     goto fail;
177 
178   fn_buffer->next = 0;
179   fn_buffer->fn_ix = fn_ix;
180   fn_buffer->info.ident = gcov_read_unsigned ();
181   fn_buffer->info.lineno_checksum = gcov_read_unsigned ();
182   fn_buffer->info.cfg_checksum = gcov_read_unsigned ();
183 
184   for (n_ctrs = ix = 0; ix != GCOV_COUNTERS; ix++)
185     {
186       gcov_unsigned_t length;
187       gcov_type *values;
188 
189       if (!gi_ptr->merge[ix])
190 	continue;
191 
192       if (gcov_read_unsigned () != GCOV_TAG_FOR_COUNTER (ix))
193 	{
194 	  len = 0;
195 	  goto fail;
196 	}
197 
198       length = GCOV_TAG_COUNTER_NUM (gcov_read_unsigned ());
199       len = length * sizeof (gcov_type);
200       values = (gcov_type *)malloc (len);
201       if (!values)
202 	goto fail;
203 
204       fn_buffer->info.ctrs[n_ctrs].num = length;
205       fn_buffer->info.ctrs[n_ctrs].values = values;
206 
207       while (length--)
208 	*values++ = gcov_read_counter ();
209       n_ctrs++;
210     }
211 
212   *end_ptr = fn_buffer;
213   return &fn_buffer->next;
214 
215  fail:
216   fprintf (stderr, "profiling:%s:Function %u %s %u \n", filename, fn_ix,
217 	   len ? "cannot allocate" : "counter mismatch", len ? len : ix);
218 
219   return (struct gcov_fn_buffer **)free_fn_data (gi_ptr, fn_buffer, ix);
220 }
221 
222 /* Add an unsigned value to the current crc */
223 
224 static gcov_unsigned_t
225 crc32_unsigned (gcov_unsigned_t crc32, gcov_unsigned_t value)
226 {
227   unsigned ix;
228 
229   for (ix = 32; ix--; value <<= 1)
230     {
231       unsigned feedback;
232 
233       feedback = (value ^ crc32) & 0x80000000 ? 0x04c11db7 : 0;
234       crc32 <<= 1;
235       crc32 ^= feedback;
236     }
237 
238   return crc32;
239 }
240 
241 /* Check if VERSION of the info block PTR matches libgcov one.
242    Return 1 on success, or zero in case of versions mismatch.
243    If FILENAME is not NULL, its value used for reporting purposes
244    instead of value from the info block.  */
245 
246 static int
247 gcov_version (struct gcov_info *ptr, gcov_unsigned_t version,
248 	      const char *filename)
249 {
250   if (version != GCOV_VERSION)
251     {
252       char v[4], e[4];
253 
254       GCOV_UNSIGNED2STRING (v, version);
255       GCOV_UNSIGNED2STRING (e, GCOV_VERSION);
256 
257       fprintf (stderr,
258 	       "profiling:%s:Version mismatch - expected %.4s got %.4s\n",
259 	       filename? filename : ptr->filename, e, v);
260       return 0;
261     }
262   return 1;
263 }
264 
265 /* Dump the coverage counts. We merge with existing counts when
266    possible, to avoid growing the .da files ad infinitum. We use this
267    program's checksum to make sure we only accumulate whole program
268    statistics to the correct summary. An object file might be embedded
269    in two separate programs, and we must keep the two program
270    summaries separate.  */
271 
272 static void
273 gcov_exit (void)
274 {
275   struct gcov_info *gi_ptr;
276   const struct gcov_fn_info *gfi_ptr;
277   struct gcov_summary this_prg; /* summary for program.  */
278   struct gcov_summary all_prg;  /* summary for all instances of program.  */
279   struct gcov_ctr_summary *cs_ptr;
280   const struct gcov_ctr_info *ci_ptr;
281   unsigned t_ix;
282   int f_ix;
283   gcov_unsigned_t c_num;
284   const char *gcov_prefix;
285   int gcov_prefix_strip = 0;
286   size_t prefix_length;
287   char *gi_filename, *gi_filename_up;
288   gcov_unsigned_t crc32 = 0;
289 
290   memset (&all_prg, 0, sizeof (all_prg));
291   /* Find the totals for this execution.  */
292   memset (&this_prg, 0, sizeof (this_prg));
293   for (gi_ptr = gcov_list; gi_ptr; gi_ptr = gi_ptr->next)
294     {
295       crc32 = crc32_unsigned (crc32, gi_ptr->stamp);
296       crc32 = crc32_unsigned (crc32, gi_ptr->n_functions);
297 
298       for (f_ix = 0; (unsigned)f_ix != gi_ptr->n_functions; f_ix++)
299 	{
300 	  gfi_ptr = gi_ptr->functions[f_ix];
301 
302 	  if (gfi_ptr && gfi_ptr->key != gi_ptr)
303 	    gfi_ptr = 0;
304 
305 	  crc32 = crc32_unsigned (crc32, gfi_ptr ? gfi_ptr->cfg_checksum : 0);
306 	  crc32 = crc32_unsigned (crc32,
307 				  gfi_ptr ? gfi_ptr->lineno_checksum : 0);
308 	  if (!gfi_ptr)
309 	    continue;
310 
311 	  ci_ptr = gfi_ptr->ctrs;
312 	  for (t_ix = 0; t_ix != GCOV_COUNTERS_SUMMABLE; t_ix++)
313 	    {
314 	      if (!gi_ptr->merge[t_ix])
315 		continue;
316 
317 	      cs_ptr = &this_prg.ctrs[t_ix];
318 	      cs_ptr->num += ci_ptr->num;
319 	      crc32 = crc32_unsigned (crc32, ci_ptr->num);
320 
321 	      for (c_num = 0; c_num < ci_ptr->num; c_num++)
322 		{
323 		  cs_ptr->sum_all += ci_ptr->values[c_num];
324 		  if (cs_ptr->run_max < ci_ptr->values[c_num])
325 		    cs_ptr->run_max = ci_ptr->values[c_num];
326 		}
327 	      ci_ptr++;
328 	    }
329 	}
330     }
331 
332   {
333     /* Check if the level of dirs to strip off specified. */
334     char *tmp = getenv("GCOV_PREFIX_STRIP");
335     if (tmp)
336       {
337 	gcov_prefix_strip = atoi (tmp);
338 	/* Do not consider negative values. */
339 	if (gcov_prefix_strip < 0)
340 	  gcov_prefix_strip = 0;
341       }
342   }
343 
344   /* Get file name relocation prefix.  Non-absolute values are ignored. */
345   gcov_prefix = getenv("GCOV_PREFIX");
346   if (gcov_prefix)
347     {
348       prefix_length = strlen(gcov_prefix);
349 
350       /* Remove an unnecessary trailing '/' */
351       if (IS_DIR_SEPARATOR (gcov_prefix[prefix_length - 1]))
352 	prefix_length--;
353     }
354   else
355     prefix_length = 0;
356 
357   /* If no prefix was specified and a prefix stip, then we assume
358      relative.  */
359   if (gcov_prefix_strip != 0 && prefix_length == 0)
360     {
361       gcov_prefix = ".";
362       prefix_length = 1;
363     }
364   /* Allocate and initialize the filename scratch space plus one.  */
365   gi_filename = (char *) alloca (prefix_length + gcov_max_filename + 2);
366   if (prefix_length)
367     memcpy (gi_filename, gcov_prefix, prefix_length);
368   gi_filename_up = gi_filename + prefix_length;
369 
370   /* Now merge each file.  */
371   for (gi_ptr = gcov_list; gi_ptr; gi_ptr = gi_ptr->next)
372     {
373       unsigned n_counts;
374       struct gcov_summary prg; /* summary for this object over all
375 				  program.  */
376       struct gcov_ctr_summary *cs_prg, *cs_tprg, *cs_all;
377       int error = 0;
378       gcov_unsigned_t tag, length;
379       gcov_position_t summary_pos = 0;
380       gcov_position_t eof_pos = 0;
381       const char *fname, *s;
382       struct gcov_fn_buffer *fn_buffer = 0;
383       struct gcov_fn_buffer **fn_tail = &fn_buffer;
384 
385       fname = gi_ptr->filename;
386 
387       /* Avoid to add multiple drive letters into combined path.  */
388       if (prefix_length != 0 && HAS_DRIVE_SPEC(fname))
389         fname += 2;
390 
391       /* Build relocated filename, stripping off leading
392          directories from the initial filename if requested. */
393       if (gcov_prefix_strip > 0)
394         {
395           int level = 0;
396           s = fname;
397           if (IS_DIR_SEPARATOR(*s))
398             ++s;
399 
400           /* Skip selected directory levels. */
401 	  for (; (*s != '\0') && (level < gcov_prefix_strip); s++)
402 	    if (IS_DIR_SEPARATOR(*s))
403 	      {
404 		fname = s;
405 		level++;
406 	      }
407         }
408 
409       /* Update complete filename with stripped original. */
410       if (prefix_length != 0 && !IS_DIR_SEPARATOR (*fname))
411         {
412           /* If prefix is given, add directory separator.  */
413 	  strcpy (gi_filename_up, "/");
414 	  strcpy (gi_filename_up + 1, fname);
415 	}
416       else
417         strcpy (gi_filename_up, fname);
418 
419       if (!gcov_open (gi_filename))
420 	{
421 	  /* Open failed likely due to missed directory.
422 	     Create directory and retry to open file. */
423           if (create_file_directory (gi_filename))
424 	    {
425 	      fprintf (stderr, "profiling:%s:Skip\n", gi_filename);
426 	      continue;
427 	    }
428 	  if (!gcov_open (gi_filename))
429 	    {
430               fprintf (stderr, "profiling:%s:Cannot open\n", gi_filename);
431 	      continue;
432 	    }
433 	}
434 
435       tag = gcov_read_unsigned ();
436       if (tag)
437 	{
438 	  /* Merge data from file.  */
439 	  if (tag != GCOV_DATA_MAGIC)
440 	    {
441 	      fprintf (stderr, "profiling:%s:Not a gcov data file\n",
442 		       gi_filename);
443 	      goto read_fatal;
444 	    }
445 	  length = gcov_read_unsigned ();
446 	  if (!gcov_version (gi_ptr, length, gi_filename))
447 	    goto read_fatal;
448 
449 	  length = gcov_read_unsigned ();
450 	  if (length != gi_ptr->stamp)
451 	    /* Read from a different compilation. Overwrite the file.  */
452 	    goto rewrite;
453 
454 	  /* Look for program summary.  */
455 	  for (f_ix = 0;;)
456 	    {
457 	      struct gcov_summary tmp;
458 
459 	      eof_pos = gcov_position ();
460 	      tag = gcov_read_unsigned ();
461 	      if (tag != GCOV_TAG_PROGRAM_SUMMARY)
462 		break;
463 
464 	      f_ix--;
465 	      length = gcov_read_unsigned ();
466 	      if (length != GCOV_TAG_SUMMARY_LENGTH)
467 		goto read_mismatch;
468 	      gcov_read_summary (&tmp);
469 	      if ((error = gcov_is_error ()))
470 		goto read_error;
471 	      if (summary_pos || tmp.checksum != crc32)
472 		goto next_summary;
473 
474 	      for (t_ix = 0; t_ix != GCOV_COUNTERS_SUMMABLE; t_ix++)
475 		if (tmp.ctrs[t_ix].num != this_prg.ctrs[t_ix].num)
476 		  goto next_summary;
477 	      prg = tmp;
478 	      summary_pos = eof_pos;
479 
480 	    next_summary:;
481 	    }
482 
483 	  /* Merge execution counts for each function.  */
484 	  for (f_ix = 0; (unsigned)f_ix != gi_ptr->n_functions;
485 	       f_ix++, tag = gcov_read_unsigned ())
486 	    {
487 	      gfi_ptr = gi_ptr->functions[f_ix];
488 
489 	      if (tag != GCOV_TAG_FUNCTION)
490 		goto read_mismatch;
491 
492 	      length = gcov_read_unsigned ();
493 	      if (!length)
494 		/* This function did not appear in the other program.
495 		   We have nothing to merge.  */
496 		continue;
497 
498 	      if (length != GCOV_TAG_FUNCTION_LENGTH)
499 		goto read_mismatch;
500 
501 	      if (!gfi_ptr || gfi_ptr->key != gi_ptr)
502 		{
503 		  /* This function appears in the other program.  We
504 		     need to buffer the information in order to write
505 		     it back out -- we'll be inserting data before
506 		     this point, so cannot simply keep the data in the
507 		     file.  */
508 		  fn_tail = buffer_fn_data (gi_filename,
509 					    gi_ptr, fn_tail, f_ix);
510 		  if (!fn_tail)
511 		    goto read_mismatch;
512 		  continue;
513 		}
514 
515 	      length = gcov_read_unsigned ();
516 	      if (length != gfi_ptr->ident)
517 		goto read_mismatch;
518 
519 	      length = gcov_read_unsigned ();
520 	      if (length != gfi_ptr->lineno_checksum)
521 		goto read_mismatch;
522 
523 	      length = gcov_read_unsigned ();
524 	      if (length != gfi_ptr->cfg_checksum)
525 		goto read_mismatch;
526 
527 	      ci_ptr = gfi_ptr->ctrs;
528 	      for (t_ix = 0; t_ix < GCOV_COUNTERS; t_ix++)
529 		{
530 		  gcov_merge_fn merge = gi_ptr->merge[t_ix];
531 
532 		  if (!merge)
533 		    continue;
534 
535 		  tag = gcov_read_unsigned ();
536 		  length = gcov_read_unsigned ();
537 		  if (tag != GCOV_TAG_FOR_COUNTER (t_ix)
538 		      || length != GCOV_TAG_COUNTER_LENGTH (ci_ptr->num))
539 		    goto read_mismatch;
540 		  (*merge) (ci_ptr->values, ci_ptr->num);
541 		  ci_ptr++;
542 		}
543 	      if ((error = gcov_is_error ()))
544 		goto read_error;
545 	    }
546 
547 	  if (tag)
548 	    {
549 	    read_mismatch:;
550 	      fprintf (stderr, "profiling:%s:Merge mismatch for %s %u\n",
551 		       gi_filename, f_ix >= 0 ? "function" : "summary",
552 		       f_ix < 0 ? -1 - f_ix : f_ix);
553 	      goto read_fatal;
554 	    }
555 	}
556       goto rewrite;
557 
558     read_error:;
559       fprintf (stderr, "profiling:%s:%s merging\n", gi_filename,
560 	       error < 0 ? "Overflow": "Error");
561 
562       goto read_fatal;
563 
564     rewrite:;
565       gcov_rewrite ();
566       if (!summary_pos)
567 	{
568 	  memset (&prg, 0, sizeof (prg));
569 	  summary_pos = eof_pos;
570 	}
571 
572       /* Merge the summaries.  */
573       for (t_ix = 0; t_ix < GCOV_COUNTERS_SUMMABLE; t_ix++)
574 	{
575 	  cs_prg = &prg.ctrs[t_ix];
576 	  cs_tprg = &this_prg.ctrs[t_ix];
577 	  cs_all = &all_prg.ctrs[t_ix];
578 
579 	  if (gi_ptr->merge[t_ix])
580 	    {
581 	      if (!cs_prg->runs++)
582 		cs_prg->num = cs_tprg->num;
583 	      cs_prg->sum_all += cs_tprg->sum_all;
584 	      if (cs_prg->run_max < cs_tprg->run_max)
585 		cs_prg->run_max = cs_tprg->run_max;
586 	      cs_prg->sum_max += cs_tprg->run_max;
587 	    }
588 	  else if (cs_prg->runs)
589 	    goto read_mismatch;
590 
591 	  if (!cs_all->runs && cs_prg->runs)
592 	    memcpy (cs_all, cs_prg, sizeof (*cs_all));
593 	  else if (!all_prg.checksum
594 		   && (!GCOV_LOCKED || cs_all->runs == cs_prg->runs)
595 		   && memcmp (cs_all, cs_prg, sizeof (*cs_all)))
596 	    {
597 	      fprintf (stderr, "profiling:%s:Invocation mismatch - some data files may have been removed%s\n",
598 		       gi_filename, GCOV_LOCKED
599 		       ? "" : " or concurrently updated without locking support");
600 	      all_prg.checksum = ~0u;
601 	    }
602 	}
603 
604       prg.checksum = crc32;
605 
606       /* Write out the data.  */
607       if (!eof_pos)
608 	{
609 	  gcov_write_tag_length (GCOV_DATA_MAGIC, GCOV_VERSION);
610 	  gcov_write_unsigned (gi_ptr->stamp);
611 	}
612 
613       if (summary_pos)
614 	gcov_seek (summary_pos);
615 
616       /* Generate whole program statistics.  */
617       gcov_write_summary (GCOV_TAG_PROGRAM_SUMMARY, &prg);
618 
619       if (summary_pos < eof_pos)
620 	gcov_seek (eof_pos);
621 
622       /* Write execution counts for each function.  */
623       for (f_ix = 0; (unsigned)f_ix != gi_ptr->n_functions; f_ix++)
624 	{
625 	  unsigned buffered = 0;
626 
627 	  if (fn_buffer && fn_buffer->fn_ix == (unsigned)f_ix)
628 	    {
629 	      /* Buffered data from another program.  */
630 	      buffered = 1;
631 	      gfi_ptr = &fn_buffer->info;
632 	      length = GCOV_TAG_FUNCTION_LENGTH;
633 	    }
634 	  else
635 	    {
636 	      gfi_ptr = gi_ptr->functions[f_ix];
637 	      if (gfi_ptr && gfi_ptr->key == gi_ptr)
638 		length = GCOV_TAG_FUNCTION_LENGTH;
639 	      else
640 		length = 0;
641 	    }
642 
643 	  gcov_write_tag_length (GCOV_TAG_FUNCTION, length);
644 	  if (!length)
645 	    continue;
646 
647 	  gcov_write_unsigned (gfi_ptr->ident);
648 	  gcov_write_unsigned (gfi_ptr->lineno_checksum);
649 	  gcov_write_unsigned (gfi_ptr->cfg_checksum);
650 
651 	  ci_ptr = gfi_ptr->ctrs;
652 	  for (t_ix = 0; t_ix < GCOV_COUNTERS; t_ix++)
653 	    {
654 	      if (!gi_ptr->merge[t_ix])
655 		continue;
656 
657 	      n_counts = ci_ptr->num;
658 	      gcov_write_tag_length (GCOV_TAG_FOR_COUNTER (t_ix),
659 				     GCOV_TAG_COUNTER_LENGTH (n_counts));
660 	      gcov_type *c_ptr = ci_ptr->values;
661 	      while (n_counts--)
662 		gcov_write_counter (*c_ptr++);
663 	      ci_ptr++;
664 	    }
665 	  if (buffered)
666 	    fn_buffer = free_fn_data (gi_ptr, fn_buffer, GCOV_COUNTERS);
667 	}
668 
669       gcov_write_unsigned (0);
670 
671     read_fatal:;
672       while (fn_buffer)
673 	fn_buffer = free_fn_data (gi_ptr, fn_buffer, GCOV_COUNTERS);
674 
675       if ((error = gcov_close ()))
676 	  fprintf (stderr, error  < 0 ?
677 		   "profiling:%s:Overflow writing\n" :
678 		   "profiling:%s:Error writing\n",
679 		   gi_filename);
680     }
681 }
682 
683 /* Add a new object file onto the bb chain.  Invoked automatically
684    when running an object file's global ctors.  */
685 
686 void
687 __gcov_init (struct gcov_info *info)
688 {
689   if (!info->version || !info->n_functions)
690     return;
691   if (gcov_version (info, info->version, 0))
692     {
693       size_t filename_length = strlen(info->filename);
694 
695       /* Refresh the longest file name information */
696       if (filename_length > gcov_max_filename)
697         gcov_max_filename = filename_length;
698 
699       if (!gcov_list)
700 	atexit (gcov_exit);
701 
702       info->next = gcov_list;
703       gcov_list = info;
704     }
705   info->version = 0;
706 }
707 
708 /* Called before fork or exec - write out profile information gathered so
709    far and reset it to zero.  This avoids duplication or loss of the
710    profile information gathered so far.  */
711 
712 void
713 __gcov_flush (void)
714 {
715   const struct gcov_info *gi_ptr;
716 
717   gcov_exit ();
718   for (gi_ptr = gcov_list; gi_ptr; gi_ptr = gi_ptr->next)
719     {
720       unsigned f_ix;
721 
722       for (f_ix = 0; f_ix < gi_ptr->n_functions; f_ix++)
723 	{
724 	  unsigned t_ix;
725 	  const struct gcov_fn_info *gfi_ptr = gi_ptr->functions[f_ix];
726 
727 	  if (!gfi_ptr || gfi_ptr->key != gi_ptr)
728 	    continue;
729 	  const struct gcov_ctr_info *ci_ptr = gfi_ptr->ctrs;
730 	  for (t_ix = 0; t_ix != GCOV_COUNTERS; t_ix++)
731 	    {
732 	      if (!gi_ptr->merge[t_ix])
733 		continue;
734 
735 	      memset (ci_ptr->values, 0, sizeof (gcov_type) * ci_ptr->num);
736 	      ci_ptr++;
737 	    }
738 	}
739     }
740 }
741 
742 #endif /* L_gcov */
743 
744 #ifdef L_gcov_merge_add
745 /* The profile merging function that just adds the counters.  It is given
746    an array COUNTERS of N_COUNTERS old counters and it reads the same number
747    of counters from the gcov file.  */
748 void
749 __gcov_merge_add (gcov_type *counters, unsigned n_counters)
750 {
751   for (; n_counters; counters++, n_counters--)
752     *counters += gcov_read_counter ();
753 }
754 #endif /* L_gcov_merge_add */
755 
756 #ifdef L_gcov_merge_ior
757 /* The profile merging function that just adds the counters.  It is given
758    an array COUNTERS of N_COUNTERS old counters and it reads the same number
759    of counters from the gcov file.  */
760 void
761 __gcov_merge_ior (gcov_type *counters, unsigned n_counters)
762 {
763   for (; n_counters; counters++, n_counters--)
764     *counters |= gcov_read_counter ();
765 }
766 #endif
767 
768 #ifdef L_gcov_merge_single
769 /* The profile merging function for choosing the most common value.
770    It is given an array COUNTERS of N_COUNTERS old counters and it
771    reads the same number of counters from the gcov file.  The counters
772    are split into 3-tuples where the members of the tuple have
773    meanings:
774 
775    -- the stored candidate on the most common value of the measured entity
776    -- counter
777    -- total number of evaluations of the value  */
778 void
779 __gcov_merge_single (gcov_type *counters, unsigned n_counters)
780 {
781   unsigned i, n_measures;
782   gcov_type value, counter, all;
783 
784   gcc_assert (!(n_counters % 3));
785   n_measures = n_counters / 3;
786   for (i = 0; i < n_measures; i++, counters += 3)
787     {
788       value = gcov_read_counter ();
789       counter = gcov_read_counter ();
790       all = gcov_read_counter ();
791 
792       if (counters[0] == value)
793 	counters[1] += counter;
794       else if (counter > counters[1])
795 	{
796 	  counters[0] = value;
797 	  counters[1] = counter - counters[1];
798 	}
799       else
800 	counters[1] -= counter;
801       counters[2] += all;
802     }
803 }
804 #endif /* L_gcov_merge_single */
805 
806 #ifdef L_gcov_merge_delta
807 /* The profile merging function for choosing the most common
808    difference between two consecutive evaluations of the value.  It is
809    given an array COUNTERS of N_COUNTERS old counters and it reads the
810    same number of counters from the gcov file.  The counters are split
811    into 4-tuples where the members of the tuple have meanings:
812 
813    -- the last value of the measured entity
814    -- the stored candidate on the most common difference
815    -- counter
816    -- total number of evaluations of the value  */
817 void
818 __gcov_merge_delta (gcov_type *counters, unsigned n_counters)
819 {
820   unsigned i, n_measures;
821   gcov_type value, counter, all;
822 
823   gcc_assert (!(n_counters % 4));
824   n_measures = n_counters / 4;
825   for (i = 0; i < n_measures; i++, counters += 4)
826     {
827       /* last = */ gcov_read_counter ();
828       value = gcov_read_counter ();
829       counter = gcov_read_counter ();
830       all = gcov_read_counter ();
831 
832       if (counters[1] == value)
833 	counters[2] += counter;
834       else if (counter > counters[2])
835 	{
836 	  counters[1] = value;
837 	  counters[2] = counter - counters[2];
838 	}
839       else
840 	counters[2] -= counter;
841       counters[3] += all;
842     }
843 }
844 #endif /* L_gcov_merge_delta */
845 
846 #ifdef L_gcov_interval_profiler
847 /* If VALUE is in interval <START, START + STEPS - 1>, then increases the
848    corresponding counter in COUNTERS.  If the VALUE is above or below
849    the interval, COUNTERS[STEPS] or COUNTERS[STEPS + 1] is increased
850    instead.  */
851 
852 void
853 __gcov_interval_profiler (gcov_type *counters, gcov_type value,
854 			  int start, unsigned steps)
855 {
856   gcov_type delta = value - start;
857   if (delta < 0)
858     counters[steps + 1]++;
859   else if (delta >= steps)
860     counters[steps]++;
861   else
862     counters[delta]++;
863 }
864 #endif
865 
866 #ifdef L_gcov_pow2_profiler
867 /* If VALUE is a power of two, COUNTERS[1] is incremented.  Otherwise
868    COUNTERS[0] is incremented.  */
869 
870 void
871 __gcov_pow2_profiler (gcov_type *counters, gcov_type value)
872 {
873   if (value & (value - 1))
874     counters[0]++;
875   else
876     counters[1]++;
877 }
878 #endif
879 
880 /* Tries to determine the most common value among its inputs.  Checks if the
881    value stored in COUNTERS[0] matches VALUE.  If this is the case, COUNTERS[1]
882    is incremented.  If this is not the case and COUNTERS[1] is not zero,
883    COUNTERS[1] is decremented.  Otherwise COUNTERS[1] is set to one and
884    VALUE is stored to COUNTERS[0].  This algorithm guarantees that if this
885    function is called more than 50% of the time with one value, this value
886    will be in COUNTERS[0] in the end.
887 
888    In any case, COUNTERS[2] is incremented.  */
889 
890 static inline void
891 __gcov_one_value_profiler_body (gcov_type *counters, gcov_type value)
892 {
893   if (value == counters[0])
894     counters[1]++;
895   else if (counters[1] == 0)
896     {
897       counters[1] = 1;
898       counters[0] = value;
899     }
900   else
901     counters[1]--;
902   counters[2]++;
903 }
904 
905 #ifdef L_gcov_one_value_profiler
906 void
907 __gcov_one_value_profiler (gcov_type *counters, gcov_type value)
908 {
909   __gcov_one_value_profiler_body (counters, value);
910 }
911 #endif
912 
913 #ifdef L_gcov_indirect_call_profiler
914 
915 /* By default, the C++ compiler will use function addresses in the
916    vtable entries.  Setting TARGET_VTABLE_USES_DESCRIPTORS to nonzero
917    tells the compiler to use function descriptors instead.  The value
918    of this macro says how many words wide the descriptor is (normally 2),
919    but it may be dependent on target flags.  Since we do not have access
920    to the target flags here we just check to see if it is set and use
921    that to set VTABLE_USES_DESCRIPTORS to 0 or 1.
922 
923    It is assumed that the address of a function descriptor may be treated
924    as a pointer to a function.  */
925 
926 #ifdef TARGET_VTABLE_USES_DESCRIPTORS
927 #define VTABLE_USES_DESCRIPTORS 1
928 #else
929 #define VTABLE_USES_DESCRIPTORS 0
930 #endif
931 
932 /* Tries to determine the most common value among its inputs. */
933 void
934 __gcov_indirect_call_profiler (gcov_type* counter, gcov_type value,
935 			       void* cur_func, void* callee_func)
936 {
937   /* If the C++ virtual tables contain function descriptors then one
938      function may have multiple descriptors and we need to dereference
939      the descriptors to see if they point to the same function.  */
940   if (cur_func == callee_func
941       || (VTABLE_USES_DESCRIPTORS && callee_func
942 	  && *(void **) cur_func == *(void **) callee_func))
943     __gcov_one_value_profiler_body (counter, value);
944 }
945 #endif
946 
947 
948 #ifdef L_gcov_average_profiler
949 /* Increase corresponding COUNTER by VALUE.  FIXME: Perhaps we want
950    to saturate up.  */
951 
952 void
953 __gcov_average_profiler (gcov_type *counters, gcov_type value)
954 {
955   counters[0] += value;
956   counters[1] ++;
957 }
958 #endif
959 
960 #ifdef L_gcov_ior_profiler
961 /* Increase corresponding COUNTER by VALUE.  FIXME: Perhaps we want
962    to saturate up.  */
963 
964 void
965 __gcov_ior_profiler (gcov_type *counters, gcov_type value)
966 {
967   *counters |= value;
968 }
969 #endif
970 
971 #ifdef L_gcov_fork
972 /* A wrapper for the fork function.  Flushes the accumulated profiling data, so
973    that they are not counted twice.  */
974 
975 pid_t
976 __gcov_fork (void)
977 {
978   __gcov_flush ();
979   return fork ();
980 }
981 #endif
982 
983 #ifdef L_gcov_execl
984 /* A wrapper for the execl function.  Flushes the accumulated profiling data, so
985    that they are not lost.  */
986 
987 int
988 __gcov_execl (const char *path, char *arg, ...)
989 {
990   va_list ap, aq;
991   unsigned i, length;
992   char **args;
993 
994   __gcov_flush ();
995 
996   va_start (ap, arg);
997   va_copy (aq, ap);
998 
999   length = 2;
1000   while (va_arg (ap, char *))
1001     length++;
1002   va_end (ap);
1003 
1004   args = (char **) alloca (length * sizeof (void *));
1005   args[0] = arg;
1006   for (i = 1; i < length; i++)
1007     args[i] = va_arg (aq, char *);
1008   va_end (aq);
1009 
1010   return execv (path, args);
1011 }
1012 #endif
1013 
1014 #ifdef L_gcov_execlp
1015 /* A wrapper for the execlp function.  Flushes the accumulated profiling data, so
1016    that they are not lost.  */
1017 
1018 int
1019 __gcov_execlp (const char *path, char *arg, ...)
1020 {
1021   va_list ap, aq;
1022   unsigned i, length;
1023   char **args;
1024 
1025   __gcov_flush ();
1026 
1027   va_start (ap, arg);
1028   va_copy (aq, ap);
1029 
1030   length = 2;
1031   while (va_arg (ap, char *))
1032     length++;
1033   va_end (ap);
1034 
1035   args = (char **) alloca (length * sizeof (void *));
1036   args[0] = arg;
1037   for (i = 1; i < length; i++)
1038     args[i] = va_arg (aq, char *);
1039   va_end (aq);
1040 
1041   return execvp (path, args);
1042 }
1043 #endif
1044 
1045 #ifdef L_gcov_execle
1046 /* A wrapper for the execle function.  Flushes the accumulated profiling data, so
1047    that they are not lost.  */
1048 
1049 int
1050 __gcov_execle (const char *path, char *arg, ...)
1051 {
1052   va_list ap, aq;
1053   unsigned i, length;
1054   char **args;
1055   char **envp;
1056 
1057   __gcov_flush ();
1058 
1059   va_start (ap, arg);
1060   va_copy (aq, ap);
1061 
1062   length = 2;
1063   while (va_arg (ap, char *))
1064     length++;
1065   va_end (ap);
1066 
1067   args = (char **) alloca (length * sizeof (void *));
1068   args[0] = arg;
1069   for (i = 1; i < length; i++)
1070     args[i] = va_arg (aq, char *);
1071   envp = va_arg (aq, char **);
1072   va_end (aq);
1073 
1074   return execve (path, args, envp);
1075 }
1076 #endif
1077 
1078 #ifdef L_gcov_execv
1079 /* A wrapper for the execv function.  Flushes the accumulated profiling data, so
1080    that they are not lost.  */
1081 
1082 int
1083 __gcov_execv (const char *path, char *const argv[])
1084 {
1085   __gcov_flush ();
1086   return execv (path, argv);
1087 }
1088 #endif
1089 
1090 #ifdef L_gcov_execvp
1091 /* A wrapper for the execvp function.  Flushes the accumulated profiling data, so
1092    that they are not lost.  */
1093 
1094 int
1095 __gcov_execvp (const char *path, char *const argv[])
1096 {
1097   __gcov_flush ();
1098   return execvp (path, argv);
1099 }
1100 #endif
1101 
1102 #ifdef L_gcov_execve
1103 /* A wrapper for the execve function.  Flushes the accumulated profiling data, so
1104    that they are not lost.  */
1105 
1106 int
1107 __gcov_execve (const char *path, char *const argv[], char *const envp[])
1108 {
1109   __gcov_flush ();
1110   return execve (path, argv, envp);
1111 }
1112 #endif
1113 #endif /* inhibit_libc */
1114