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