OSDN Git Service

* gcc.dg/march.c: Ignore a note for some targets.
[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, 2010
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 (prefix_length != 0 && !IS_DIR_SEPARATOR (*fname))
287         {
288           /* If prefix is given, add directory separator.  */
289           strcpy (gi_filename_up, "/");
290           strcpy (gi_filename_up + 1, fname);
291         }
292       else
293         strcpy (gi_filename_up, fname);
294
295       /* Totals for this object file.  */
296       ci_ptr = gi_ptr->counts;
297       for (t_ix = 0; t_ix < GCOV_COUNTERS_SUMMABLE; t_ix++)
298         {
299           if (!((1 << t_ix) & gi_ptr->ctr_mask))
300             continue;
301
302           cs_ptr = &this_object.ctrs[t_ix];
303           cs_ptr->num += ci_ptr->num;
304           for (c_num = 0; c_num < ci_ptr->num; c_num++)
305             {
306               cs_ptr->sum_all += ci_ptr->values[c_num];
307               if (cs_ptr->run_max < ci_ptr->values[c_num])
308                 cs_ptr->run_max = ci_ptr->values[c_num];
309             }
310
311           ci_ptr++;
312         }
313
314       c_ix = 0;
315       for (t_ix = 0; t_ix < GCOV_COUNTERS; t_ix++)
316         if ((1 << t_ix) & gi_ptr->ctr_mask)
317           {
318             values[c_ix] = gi_ptr->counts[c_ix].values;
319             c_ix++;
320           }
321
322       /* Calculate the function_info stride. This depends on the
323          number of counter types being measured.  */
324       fi_stride = sizeof (struct gcov_fn_info) + c_ix * sizeof (unsigned);
325       if (__alignof__ (struct gcov_fn_info) > sizeof (unsigned))
326         {
327           fi_stride += __alignof__ (struct gcov_fn_info) - 1;
328           fi_stride &= ~(__alignof__ (struct gcov_fn_info) - 1);
329         }
330
331       if (!gcov_open (gi_filename))
332         {
333           /* Open failed likely due to missed directory.
334              Create directory and retry to open file. */
335           if (create_file_directory (gi_filename))
336             {
337               fprintf (stderr, "profiling:%s:Skip\n", gi_filename);
338               continue;
339             }
340           if (!gcov_open (gi_filename))
341             {
342               fprintf (stderr, "profiling:%s:Cannot open\n", gi_filename);
343               continue;
344             }
345         }
346
347       tag = gcov_read_unsigned ();
348       if (tag)
349         {
350           /* Merge data from file.  */
351           if (tag != GCOV_DATA_MAGIC)
352             {
353               fprintf (stderr, "profiling:%s:Not a gcov data file\n",
354                        gi_filename);
355               goto read_fatal;
356             }
357           length = gcov_read_unsigned ();
358           if (!gcov_version (gi_ptr, length, gi_filename))
359             goto read_fatal;
360
361           length = gcov_read_unsigned ();
362           if (length != gi_ptr->stamp)
363             /* Read from a different compilation. Overwrite the file.  */
364             goto rewrite;
365
366           /* Merge execution counts for each function.  */
367           for (f_ix = 0; f_ix < gi_ptr->n_functions; f_ix++)
368             {
369               fi_ptr = (const struct gcov_fn_info *)
370                       ((const char *) gi_ptr->functions + f_ix * fi_stride);
371               tag = gcov_read_unsigned ();
372               length = gcov_read_unsigned ();
373
374               /* Check function.  */
375               if (tag != GCOV_TAG_FUNCTION
376                   || length != GCOV_TAG_FUNCTION_LENGTH
377                   || gcov_read_unsigned () != fi_ptr->ident
378                   || gcov_read_unsigned () != fi_ptr->lineno_checksum
379                   || gcov_read_unsigned () != fi_ptr->cfg_checksum)
380                 {
381                 read_mismatch:;
382                   fprintf (stderr, "profiling:%s:Merge mismatch for %s\n",
383                            gi_filename,
384                            f_ix + 1 ? "function" : "summaries");
385                   goto read_fatal;
386                 }
387
388               c_ix = 0;
389               for (t_ix = 0; t_ix < GCOV_COUNTERS; t_ix++)
390                 {
391                   gcov_merge_fn merge;
392
393                   if (!((1 << t_ix) & gi_ptr->ctr_mask))
394                     continue;
395
396                   n_counts = fi_ptr->n_ctrs[c_ix];
397                   merge = gi_ptr->counts[c_ix].merge;
398
399                   tag = gcov_read_unsigned ();
400                   length = gcov_read_unsigned ();
401                   if (tag != GCOV_TAG_FOR_COUNTER (t_ix)
402                       || length != GCOV_TAG_COUNTER_LENGTH (n_counts))
403                     goto read_mismatch;
404                   (*merge) (values[c_ix], n_counts);
405                   values[c_ix] += n_counts;
406                   c_ix++;
407                 }
408               if ((error = gcov_is_error ()))
409                 goto read_error;
410             }
411
412           f_ix = ~0u;
413           /* Check program & object summary */
414           while (1)
415             {
416               int is_program;
417
418               eof_pos = gcov_position ();
419               tag = gcov_read_unsigned ();
420               if (!tag)
421                 break;
422
423               length = gcov_read_unsigned ();
424               is_program = tag == GCOV_TAG_PROGRAM_SUMMARY;
425               if (length != GCOV_TAG_SUMMARY_LENGTH
426                   || (!is_program && tag != GCOV_TAG_OBJECT_SUMMARY))
427                 goto read_mismatch;
428               gcov_read_summary (is_program ? &program : &object);
429               if ((error = gcov_is_error ()))
430                 goto read_error;
431               if (is_program && program.checksum == gcov_crc32)
432                 {
433                   summary_pos = eof_pos;
434                   goto rewrite;
435                 }
436             }
437         }
438       goto rewrite;
439
440     read_error:;
441       fprintf (stderr, error < 0 ? "profiling:%s:Overflow merging\n"
442                : "profiling:%s:Error merging\n", gi_filename);
443
444     read_fatal:;
445       gcov_close ();
446       continue;
447
448     rewrite:;
449       gcov_rewrite ();
450       if (!summary_pos)
451         memset (&program, 0, sizeof (program));
452
453       /* Merge the summaries.  */
454       f_ix = ~0u;
455       for (t_ix = 0; t_ix < GCOV_COUNTERS_SUMMABLE; t_ix++)
456         {
457           cs_obj = &object.ctrs[t_ix];
458           cs_tobj = &this_object.ctrs[t_ix];
459           cs_prg = &program.ctrs[t_ix];
460           cs_tprg = &this_program.ctrs[t_ix];
461           cs_all = &all.ctrs[t_ix];
462
463           if ((1 << t_ix) & gi_ptr->ctr_mask)
464             {
465               if (!cs_obj->runs++)
466                 cs_obj->num = cs_tobj->num;
467               else if (cs_obj->num != cs_tobj->num)
468                 goto read_mismatch;
469               cs_obj->sum_all += cs_tobj->sum_all;
470               if (cs_obj->run_max < cs_tobj->run_max)
471                 cs_obj->run_max = cs_tobj->run_max;
472               cs_obj->sum_max += cs_tobj->run_max;
473
474               if (!cs_prg->runs++)
475                 cs_prg->num = cs_tprg->num;
476               else if (cs_prg->num != cs_tprg->num)
477                 goto read_mismatch;
478               cs_prg->sum_all += cs_tprg->sum_all;
479               if (cs_prg->run_max < cs_tprg->run_max)
480                 cs_prg->run_max = cs_tprg->run_max;
481               cs_prg->sum_max += cs_tprg->run_max;
482             }
483           else if (cs_obj->num || cs_prg->num)
484             goto read_mismatch;
485
486           if (!cs_all->runs && cs_prg->runs)
487             memcpy (cs_all, cs_prg, sizeof (*cs_all));
488           else if (!all.checksum
489                    && (!GCOV_LOCKED || cs_all->runs == cs_prg->runs)
490                    && memcmp (cs_all, cs_prg, sizeof (*cs_all)))
491             {
492               fprintf (stderr, "profiling:%s:Invocation mismatch - some data files may have been removed%s",
493                        gi_filename, GCOV_LOCKED
494                        ? "" : " or concurrent update without locking support");
495               all.checksum = ~0u;
496             }
497         }
498
499       c_ix = 0;
500       for (t_ix = 0; t_ix < GCOV_COUNTERS; t_ix++)
501         if ((1 << t_ix) & gi_ptr->ctr_mask)
502           {
503             values[c_ix] = gi_ptr->counts[c_ix].values;
504             c_ix++;
505           }
506
507       program.checksum = gcov_crc32;
508
509       /* Write out the data.  */
510       gcov_write_tag_length (GCOV_DATA_MAGIC, GCOV_VERSION);
511       gcov_write_unsigned (gi_ptr->stamp);
512
513       /* Write execution counts for each function.  */
514       for (f_ix = 0; f_ix < gi_ptr->n_functions; f_ix++)
515         {
516           fi_ptr = (const struct gcov_fn_info *)
517                   ((const char *) gi_ptr->functions + f_ix * fi_stride);
518
519           /* Announce function.  */
520           gcov_write_tag_length (GCOV_TAG_FUNCTION, GCOV_TAG_FUNCTION_LENGTH);
521           gcov_write_unsigned (fi_ptr->ident);
522           gcov_write_unsigned (fi_ptr->lineno_checksum);
523           gcov_write_unsigned (fi_ptr->cfg_checksum);
524
525           c_ix = 0;
526           for (t_ix = 0; t_ix < GCOV_COUNTERS; t_ix++)
527             {
528               gcov_type *c_ptr;
529
530               if (!((1 << t_ix) & gi_ptr->ctr_mask))
531                 continue;
532
533               n_counts = fi_ptr->n_ctrs[c_ix];
534
535               gcov_write_tag_length (GCOV_TAG_FOR_COUNTER (t_ix),
536                                      GCOV_TAG_COUNTER_LENGTH (n_counts));
537               c_ptr = values[c_ix];
538               while (n_counts--)
539                 gcov_write_counter (*c_ptr++);
540
541               values[c_ix] = c_ptr;
542               c_ix++;
543             }
544         }
545
546       /* Object file summary.  */
547       gcov_write_summary (GCOV_TAG_OBJECT_SUMMARY, &object);
548
549       /* Generate whole program statistics.  */
550       if (eof_pos)
551         gcov_seek (eof_pos);
552       gcov_write_summary (GCOV_TAG_PROGRAM_SUMMARY, &program);
553       if (!summary_pos)
554         gcov_write_unsigned (0);
555       if ((error = gcov_close ()))
556           fprintf (stderr, error  < 0 ?
557                    "profiling:%s:Overflow writing\n" :
558                    "profiling:%s:Error writing\n",
559                    gi_filename);
560     }
561 }
562
563 /* Add a new object file onto the bb chain.  Invoked automatically
564    when running an object file's global ctors.  */
565
566 void
567 __gcov_init (struct gcov_info *info)
568 {
569   if (!info->version)
570     return;
571   if (gcov_version (info, info->version, 0))
572     {
573       const char *ptr = info->filename;
574       gcov_unsigned_t crc32 = gcov_crc32;
575       size_t filename_length =  strlen(info->filename);
576
577       /* Refresh the longest file name information */
578       if (filename_length > gcov_max_filename)
579         gcov_max_filename = filename_length;
580
581       do
582         {
583           unsigned ix;
584           gcov_unsigned_t value = *ptr << 24;
585
586           for (ix = 8; ix--; value <<= 1)
587             {
588               gcov_unsigned_t feedback;
589
590               feedback = (value ^ crc32) & 0x80000000 ? 0x04c11db7 : 0;
591               crc32 <<= 1;
592               crc32 ^= feedback;
593             }
594         }
595       while (*ptr++);
596
597       gcov_crc32 = crc32;
598
599       if (!gcov_list)
600         atexit (gcov_exit);
601
602       info->next = gcov_list;
603       gcov_list = info;
604     }
605   info->version = 0;
606 }
607
608 /* Called before fork or exec - write out profile information gathered so
609    far and reset it to zero.  This avoids duplication or loss of the
610    profile information gathered so far.  */
611
612 void
613 __gcov_flush (void)
614 {
615   const struct gcov_info *gi_ptr;
616
617   gcov_exit ();
618   for (gi_ptr = gcov_list; gi_ptr; gi_ptr = gi_ptr->next)
619     {
620       unsigned t_ix;
621       const struct gcov_ctr_info *ci_ptr;
622
623       for (t_ix = 0, ci_ptr = gi_ptr->counts; t_ix != GCOV_COUNTERS; t_ix++)
624         if ((1 << t_ix) & gi_ptr->ctr_mask)
625           {
626             memset (ci_ptr->values, 0, sizeof (gcov_type) * ci_ptr->num);
627             ci_ptr++;
628           }
629     }
630 }
631
632 #endif /* L_gcov */
633
634 #ifdef L_gcov_merge_add
635 /* The profile merging function that just adds the counters.  It is given
636    an array COUNTERS of N_COUNTERS old counters and it reads the same number
637    of counters from the gcov file.  */
638 void
639 __gcov_merge_add (gcov_type *counters, unsigned n_counters)
640 {
641   for (; n_counters; counters++, n_counters--)
642     *counters += gcov_read_counter ();
643 }
644 #endif /* L_gcov_merge_add */
645
646 #ifdef L_gcov_merge_ior
647 /* The profile merging function that just adds the counters.  It is given
648    an array COUNTERS of N_COUNTERS old counters and it reads the same number
649    of counters from the gcov file.  */
650 void
651 __gcov_merge_ior (gcov_type *counters, unsigned n_counters)
652 {
653   for (; n_counters; counters++, n_counters--)
654     *counters |= gcov_read_counter ();
655 }
656 #endif
657
658 #ifdef L_gcov_merge_single
659 /* The profile merging function for choosing the most common value.
660    It is given an array COUNTERS of N_COUNTERS old counters and it
661    reads the same number of counters from the gcov file.  The counters
662    are split into 3-tuples where the members of the tuple have
663    meanings:
664
665    -- the stored candidate on the most common value of the measured entity
666    -- counter
667    -- total number of evaluations of the value  */
668 void
669 __gcov_merge_single (gcov_type *counters, unsigned n_counters)
670 {
671   unsigned i, n_measures;
672   gcov_type value, counter, all;
673
674   gcc_assert (!(n_counters % 3));
675   n_measures = n_counters / 3;
676   for (i = 0; i < n_measures; i++, counters += 3)
677     {
678       value = gcov_read_counter ();
679       counter = gcov_read_counter ();
680       all = gcov_read_counter ();
681
682       if (counters[0] == value)
683         counters[1] += counter;
684       else if (counter > counters[1])
685         {
686           counters[0] = value;
687           counters[1] = counter - counters[1];
688         }
689       else
690         counters[1] -= counter;
691       counters[2] += all;
692     }
693 }
694 #endif /* L_gcov_merge_single */
695
696 #ifdef L_gcov_merge_delta
697 /* The profile merging function for choosing the most common
698    difference between two consecutive evaluations of the value.  It is
699    given an array COUNTERS of N_COUNTERS old counters and it reads the
700    same number of counters from the gcov file.  The counters are split
701    into 4-tuples where the members of the tuple have meanings:
702
703    -- the last value of the measured entity
704    -- the stored candidate on the most common difference
705    -- counter
706    -- total number of evaluations of the value  */
707 void
708 __gcov_merge_delta (gcov_type *counters, unsigned n_counters)
709 {
710   unsigned i, n_measures;
711   gcov_type value, counter, all;
712
713   gcc_assert (!(n_counters % 4));
714   n_measures = n_counters / 4;
715   for (i = 0; i < n_measures; i++, counters += 4)
716     {
717       /* last = */ gcov_read_counter ();
718       value = gcov_read_counter ();
719       counter = gcov_read_counter ();
720       all = gcov_read_counter ();
721
722       if (counters[1] == value)
723         counters[2] += counter;
724       else if (counter > counters[2])
725         {
726           counters[1] = value;
727           counters[2] = counter - counters[2];
728         }
729       else
730         counters[2] -= counter;
731       counters[3] += all;
732     }
733 }
734 #endif /* L_gcov_merge_delta */
735
736 #ifdef L_gcov_interval_profiler
737 /* If VALUE is in interval <START, START + STEPS - 1>, then increases the
738    corresponding counter in COUNTERS.  If the VALUE is above or below
739    the interval, COUNTERS[STEPS] or COUNTERS[STEPS + 1] is increased
740    instead.  */
741
742 void
743 __gcov_interval_profiler (gcov_type *counters, gcov_type value,
744                           int start, unsigned steps)
745 {
746   gcov_type delta = value - start;
747   if (delta < 0)
748     counters[steps + 1]++;
749   else if (delta >= steps)
750     counters[steps]++;
751   else
752     counters[delta]++;
753 }
754 #endif
755
756 #ifdef L_gcov_pow2_profiler
757 /* If VALUE is a power of two, COUNTERS[1] is incremented.  Otherwise
758    COUNTERS[0] is incremented.  */
759
760 void
761 __gcov_pow2_profiler (gcov_type *counters, gcov_type value)
762 {
763   if (value & (value - 1))
764     counters[0]++;
765   else
766     counters[1]++;
767 }
768 #endif
769
770 /* Tries to determine the most common value among its inputs.  Checks if the
771    value stored in COUNTERS[0] matches VALUE.  If this is the case, COUNTERS[1]
772    is incremented.  If this is not the case and COUNTERS[1] is not zero,
773    COUNTERS[1] is decremented.  Otherwise COUNTERS[1] is set to one and
774    VALUE is stored to COUNTERS[0].  This algorithm guarantees that if this
775    function is called more than 50% of the time with one value, this value
776    will be in COUNTERS[0] in the end.
777
778    In any case, COUNTERS[2] is incremented.  */
779
780 static inline void
781 __gcov_one_value_profiler_body (gcov_type *counters, gcov_type value)
782 {
783   if (value == counters[0])
784     counters[1]++;
785   else if (counters[1] == 0)
786     {
787       counters[1] = 1;
788       counters[0] = value;
789     }
790   else
791     counters[1]--;
792   counters[2]++;
793 }
794
795 #ifdef L_gcov_one_value_profiler
796 void
797 __gcov_one_value_profiler (gcov_type *counters, gcov_type value)
798 {
799   __gcov_one_value_profiler_body (counters, value);
800 }
801 #endif
802
803 #ifdef L_gcov_indirect_call_profiler
804
805 /* By default, the C++ compiler will use function addresses in the
806    vtable entries.  Setting TARGET_VTABLE_USES_DESCRIPTORS to nonzero
807    tells the compiler to use function descriptors instead.  The value
808    of this macro says how many words wide the descriptor is (normally 2),
809    but it may be dependent on target flags.  Since we do not have access
810    to the target flags here we just check to see if it is set and use
811    that to set VTABLE_USES_DESCRIPTORS to 0 or 1.
812
813    It is assumed that the address of a function descriptor may be treated
814    as a pointer to a function.  */
815
816 #ifdef TARGET_VTABLE_USES_DESCRIPTORS
817 #define VTABLE_USES_DESCRIPTORS 1
818 #else
819 #define VTABLE_USES_DESCRIPTORS 0
820 #endif
821
822 /* Tries to determine the most common value among its inputs. */
823 void
824 __gcov_indirect_call_profiler (gcov_type* counter, gcov_type value,
825                                void* cur_func, void* callee_func)
826 {
827   /* If the C++ virtual tables contain function descriptors then one
828      function may have multiple descriptors and we need to dereference
829      the descriptors to see if they point to the same function.  */
830   if (cur_func == callee_func
831       || (VTABLE_USES_DESCRIPTORS && callee_func
832           && *(void **) cur_func == *(void **) callee_func))
833     __gcov_one_value_profiler_body (counter, value);
834 }
835 #endif
836
837
838 #ifdef L_gcov_average_profiler
839 /* Increase corresponding COUNTER by VALUE.  FIXME: Perhaps we want
840    to saturate up.  */
841
842 void
843 __gcov_average_profiler (gcov_type *counters, gcov_type value)
844 {
845   counters[0] += value;
846   counters[1] ++;
847 }
848 #endif
849
850 #ifdef L_gcov_ior_profiler
851 /* Increase corresponding COUNTER by VALUE.  FIXME: Perhaps we want
852    to saturate up.  */
853
854 void
855 __gcov_ior_profiler (gcov_type *counters, gcov_type value)
856 {
857   *counters |= value;
858 }
859 #endif
860
861 #ifdef L_gcov_fork
862 /* A wrapper for the fork function.  Flushes the accumulated profiling data, so
863    that they are not counted twice.  */
864
865 pid_t
866 __gcov_fork (void)
867 {
868   __gcov_flush ();
869   return fork ();
870 }
871 #endif
872
873 #ifdef L_gcov_execl
874 /* A wrapper for the execl function.  Flushes the accumulated profiling data, so
875    that they are not lost.  */
876
877 int
878 __gcov_execl (const char *path, char *arg, ...)
879 {
880   va_list ap, aq;
881   unsigned i, length;
882   char **args;
883
884   __gcov_flush ();
885
886   va_start (ap, arg);
887   va_copy (aq, ap);
888
889   length = 2;
890   while (va_arg (ap, char *))
891     length++;
892   va_end (ap);
893
894   args = (char **) alloca (length * sizeof (void *));
895   args[0] = arg;
896   for (i = 1; i < length; i++)
897     args[i] = va_arg (aq, char *);
898   va_end (aq);
899
900   return execv (path, args);
901 }
902 #endif
903
904 #ifdef L_gcov_execlp
905 /* A wrapper for the execlp function.  Flushes the accumulated profiling data, so
906    that they are not lost.  */
907
908 int
909 __gcov_execlp (const char *path, char *arg, ...)
910 {
911   va_list ap, aq;
912   unsigned i, length;
913   char **args;
914
915   __gcov_flush ();
916
917   va_start (ap, arg);
918   va_copy (aq, ap);
919
920   length = 2;
921   while (va_arg (ap, char *))
922     length++;
923   va_end (ap);
924
925   args = (char **) alloca (length * sizeof (void *));
926   args[0] = arg;
927   for (i = 1; i < length; i++)
928     args[i] = va_arg (aq, char *);
929   va_end (aq);
930
931   return execvp (path, args);
932 }
933 #endif
934
935 #ifdef L_gcov_execle
936 /* A wrapper for the execle function.  Flushes the accumulated profiling data, so
937    that they are not lost.  */
938
939 int
940 __gcov_execle (const char *path, char *arg, ...)
941 {
942   va_list ap, aq;
943   unsigned i, length;
944   char **args;
945   char **envp;
946
947   __gcov_flush ();
948
949   va_start (ap, arg);
950   va_copy (aq, ap);
951
952   length = 2;
953   while (va_arg (ap, char *))
954     length++;
955   va_end (ap);
956
957   args = (char **) alloca (length * sizeof (void *));
958   args[0] = arg;
959   for (i = 1; i < length; i++)
960     args[i] = va_arg (aq, char *);
961   envp = va_arg (aq, char **);
962   va_end (aq);
963
964   return execve (path, args, envp);
965 }
966 #endif
967
968 #ifdef L_gcov_execv
969 /* A wrapper for the execv function.  Flushes the accumulated profiling data, so
970    that they are not lost.  */
971
972 int
973 __gcov_execv (const char *path, char *const argv[])
974 {
975   __gcov_flush ();
976   return execv (path, argv);
977 }
978 #endif
979
980 #ifdef L_gcov_execvp
981 /* A wrapper for the execvp function.  Flushes the accumulated profiling data, so
982    that they are not lost.  */
983
984 int
985 __gcov_execvp (const char *path, char *const argv[])
986 {
987   __gcov_flush ();
988   return execvp (path, argv);
989 }
990 #endif
991
992 #ifdef L_gcov_execve
993 /* A wrapper for the execve function.  Flushes the accumulated profiling data, so
994    that they are not lost.  */
995
996 int
997 __gcov_execve (const char *path, char *const argv[], char *const envp[])
998 {
999   __gcov_flush ();
1000   return execve (path, argv, envp);
1001 }
1002 #endif
1003 #endif /* inhibit_libc */