OSDN Git Service

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