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