OSDN Git Service

* config.gcc (hppa*64*-*-linux*): Don't add pa/t-linux to tmake_file.
[pf3gnuchains/gcc-fork.git] / libgcc / libgcov.c
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 */