Update gcc-50 to SVN version 222168 (gcc-5-branch)
[dragonfly.git] / contrib / gcc-5.0 / libgcc / libgcov-driver.c
1 /* Routines required for instrumenting a program.  */
2 /* Compile this one with gcc.  */
3 /* Copyright (C) 1989-2015 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 "libgcov.h"
27
28 #if defined(inhibit_libc)
29 /* If libc and its header files are not available, provide dummy functions.  */
30
31 #if defined(L_gcov)
32 void __gcov_init (struct gcov_info *p __attribute__ ((unused))) {}
33 #endif
34
35 #else /* inhibit_libc */
36
37 #include <string.h>
38 #if GCOV_LOCKED
39 #include <fcntl.h>
40 #include <errno.h>
41 #include <sys/stat.h>
42 #endif
43
44 #ifdef L_gcov
45
46 /* A utility function for outputing errors.  */
47 static int gcov_error (const char *, ...);
48
49 #include "gcov-io.c"
50
51 struct gcov_fn_buffer
52 {
53   struct gcov_fn_buffer *next;
54   unsigned fn_ix;
55   struct gcov_fn_info info;
56   /* note gcov_fn_info ends in a trailing array.  */
57 };
58
59 struct gcov_summary_buffer
60 {
61   struct gcov_summary_buffer *next;
62   struct gcov_summary summary;
63 };
64
65 /* A struct that bundles all the related information about the
66    gcda filename.  */
67
68 struct gcov_filename
69 {
70   char *filename;  /* filename buffer */
71   size_t max_length;  /* maximum filename length */
72   int strip; /* leading chars to strip from filename */
73   size_t prefix; /* chars to prepend to filename */
74 };
75
76 static struct gcov_fn_buffer *
77 free_fn_data (const struct gcov_info *gi_ptr, struct gcov_fn_buffer *buffer,
78               unsigned limit)
79 {
80   struct gcov_fn_buffer *next;
81   unsigned ix, n_ctr = 0;
82
83   if (!buffer)
84     return 0;
85   next = buffer->next;
86
87   for (ix = 0; ix != limit; ix++)
88     if (gi_ptr->merge[ix])
89       free (buffer->info.ctrs[n_ctr++].values);
90   free (buffer);
91   return next;
92 }
93
94 static struct gcov_fn_buffer **
95 buffer_fn_data (const char *filename, const struct gcov_info *gi_ptr,
96                 struct gcov_fn_buffer **end_ptr, unsigned fn_ix)
97 {
98   unsigned n_ctrs = 0, ix = 0;
99   struct gcov_fn_buffer *fn_buffer;
100   unsigned len;
101
102   for (ix = GCOV_COUNTERS; ix--;)
103     if (gi_ptr->merge[ix])
104       n_ctrs++;
105
106   len = sizeof (*fn_buffer) + sizeof (fn_buffer->info.ctrs[0]) * n_ctrs;
107   fn_buffer = (struct gcov_fn_buffer *) xmalloc (len);
108
109   if (!fn_buffer)
110     goto fail;
111
112   fn_buffer->next = 0;
113   fn_buffer->fn_ix = fn_ix;
114   fn_buffer->info.ident = gcov_read_unsigned ();
115   fn_buffer->info.lineno_checksum = gcov_read_unsigned ();
116   fn_buffer->info.cfg_checksum = gcov_read_unsigned ();
117
118   for (n_ctrs = ix = 0; ix != GCOV_COUNTERS; ix++)
119     {
120       gcov_unsigned_t length;
121       gcov_type *values;
122
123       if (!gi_ptr->merge[ix])
124         continue;
125
126       if (gcov_read_unsigned () != GCOV_TAG_FOR_COUNTER (ix))
127         {
128           len = 0;
129           goto fail;
130         }
131
132       length = GCOV_TAG_COUNTER_NUM (gcov_read_unsigned ());
133       len = length * sizeof (gcov_type);
134       values = (gcov_type *) xmalloc (len);
135       if (!values)
136         goto fail;
137
138       fn_buffer->info.ctrs[n_ctrs].num = length;
139       fn_buffer->info.ctrs[n_ctrs].values = values;
140
141       while (length--)
142         *values++ = gcov_read_counter ();
143       n_ctrs++;
144     }
145
146   *end_ptr = fn_buffer;
147   return &fn_buffer->next;
148
149 fail:
150   gcov_error ("profiling:%s:Function %u %s %u \n", filename, fn_ix,
151               len ? "cannot allocate" : "counter mismatch", len ? len : ix);
152
153   return (struct gcov_fn_buffer **)free_fn_data (gi_ptr, fn_buffer, ix);
154 }
155
156 /* Add an unsigned value to the current crc */
157
158 static gcov_unsigned_t
159 crc32_unsigned (gcov_unsigned_t crc32, gcov_unsigned_t value)
160 {
161   unsigned ix;
162
163   for (ix = 32; ix--; value <<= 1)
164     {
165       unsigned feedback;
166
167       feedback = (value ^ crc32) & 0x80000000 ? 0x04c11db7 : 0;
168       crc32 <<= 1;
169       crc32 ^= feedback;
170     }
171
172   return crc32;
173 }
174
175 /* Check if VERSION of the info block PTR matches libgcov one.
176    Return 1 on success, or zero in case of versions mismatch.
177    If FILENAME is not NULL, its value used for reporting purposes
178    instead of value from the info block.  */
179
180 static int
181 gcov_version (struct gcov_info *ptr, gcov_unsigned_t version,
182               const char *filename)
183 {
184   if (version != GCOV_VERSION)
185     {
186       char v[4], e[4];
187
188       GCOV_UNSIGNED2STRING (v, version);
189       GCOV_UNSIGNED2STRING (e, GCOV_VERSION);
190
191       gcov_error ("profiling:%s:Version mismatch - expected %.4s got %.4s\n",
192                   filename? filename : ptr->filename, e, v);
193       return 0;
194     }
195   return 1;
196 }
197
198 /* Insert counter VALUE into HISTOGRAM.  */
199
200 static void
201 gcov_histogram_insert(gcov_bucket_type *histogram, gcov_type value)
202 {
203   unsigned i;
204
205   i = gcov_histo_index(value);
206   histogram[i].num_counters++;
207   histogram[i].cum_value += value;
208   if (value < histogram[i].min_value)
209     histogram[i].min_value = value;
210 }
211
212 /* Computes a histogram of the arc counters to place in the summary SUM.  */
213
214 static void
215 gcov_compute_histogram (struct gcov_info *list, struct gcov_summary *sum)
216 {
217   struct gcov_info *gi_ptr;
218   const struct gcov_fn_info *gfi_ptr;
219   const struct gcov_ctr_info *ci_ptr;
220   struct gcov_ctr_summary *cs_ptr;
221   unsigned t_ix, f_ix, ctr_info_ix, ix;
222   int h_ix;
223
224   /* This currently only applies to arc counters.  */
225   t_ix = GCOV_COUNTER_ARCS;
226
227   /* First check if there are any counts recorded for this counter.  */
228   cs_ptr = &(sum->ctrs[t_ix]);
229   if (!cs_ptr->num)
230     return;
231
232   for (h_ix = 0; h_ix < GCOV_HISTOGRAM_SIZE; h_ix++)
233     {
234       cs_ptr->histogram[h_ix].num_counters = 0;
235       cs_ptr->histogram[h_ix].min_value = cs_ptr->run_max;
236       cs_ptr->histogram[h_ix].cum_value = 0;
237     }
238
239   /* Walk through all the per-object structures and record each of
240      the count values in histogram.  */
241   for (gi_ptr = list; gi_ptr; gi_ptr = gi_ptr->next)
242     {
243       if (!gi_ptr->merge[t_ix])
244         continue;
245
246       /* Find the appropriate index into the gcov_ctr_info array
247          for the counter we are currently working on based on the
248          existence of the merge function pointer for this object.  */
249       for (ix = 0, ctr_info_ix = 0; ix < t_ix; ix++)
250         {
251           if (gi_ptr->merge[ix])
252             ctr_info_ix++;
253         }
254       for (f_ix = 0; f_ix != gi_ptr->n_functions; f_ix++)
255         {
256           gfi_ptr = gi_ptr->functions[f_ix];
257
258           if (!gfi_ptr || gfi_ptr->key != gi_ptr)
259             continue;
260
261           ci_ptr = &gfi_ptr->ctrs[ctr_info_ix];
262           for (ix = 0; ix < ci_ptr->num; ix++)
263             gcov_histogram_insert (cs_ptr->histogram, ci_ptr->values[ix]);
264         }
265     }
266 }
267
268 /* buffer for the fn_data from another program.  */
269 static struct gcov_fn_buffer *fn_buffer;
270 /* buffer for summary from other programs to be written out. */
271 static struct gcov_summary_buffer *sum_buffer;
272
273 /* This function computes the program level summary and the histo-gram.
274    It computes and returns CRC32 and stored summary in THIS_PRG.
275    Also determines the longest filename length of the info files.  */
276
277 #if !IN_GCOV_TOOL
278 static
279 #endif
280 gcov_unsigned_t
281 compute_summary (struct gcov_info *list, struct gcov_summary *this_prg,
282                  size_t *max_length)
283 {
284   struct gcov_info *gi_ptr;
285   const struct gcov_fn_info *gfi_ptr;
286   struct gcov_ctr_summary *cs_ptr;
287   const struct gcov_ctr_info *ci_ptr;
288   int f_ix;
289   unsigned t_ix;
290   gcov_unsigned_t c_num;
291   gcov_unsigned_t crc32 = 0;
292
293   /* Find the totals for this execution.  */
294   memset (this_prg, 0, sizeof (*this_prg));
295   *max_length = 0;
296   for (gi_ptr = list; gi_ptr; gi_ptr = gi_ptr->next)
297     {
298       size_t len = strlen (gi_ptr->filename);
299       if (len > *max_length)
300         *max_length = len;
301       
302       crc32 = crc32_unsigned (crc32, gi_ptr->stamp);
303       crc32 = crc32_unsigned (crc32, gi_ptr->n_functions);
304
305       for (f_ix = 0; (unsigned)f_ix != gi_ptr->n_functions; f_ix++)
306         {
307           gfi_ptr = gi_ptr->functions[f_ix];
308
309           if (gfi_ptr && gfi_ptr->key != gi_ptr)
310             gfi_ptr = 0;
311
312           crc32 = crc32_unsigned (crc32, gfi_ptr ? gfi_ptr->cfg_checksum : 0);
313           crc32 = crc32_unsigned (crc32,
314                                   gfi_ptr ? gfi_ptr->lineno_checksum : 0);
315           if (!gfi_ptr)
316             continue;
317
318           ci_ptr = gfi_ptr->ctrs;
319           for (t_ix = 0; t_ix != GCOV_COUNTERS_SUMMABLE; t_ix++)
320             {
321               if (!gi_ptr->merge[t_ix])
322                 continue;
323
324               cs_ptr = &(this_prg->ctrs[t_ix]);
325               cs_ptr->num += ci_ptr->num;
326               crc32 = crc32_unsigned (crc32, ci_ptr->num);
327
328               for (c_num = 0; c_num < ci_ptr->num; c_num++)
329                 {
330                   cs_ptr->sum_all += ci_ptr->values[c_num];
331                   if (cs_ptr->run_max < ci_ptr->values[c_num])
332                     cs_ptr->run_max = ci_ptr->values[c_num];
333                 }
334               ci_ptr++;
335             }
336         }
337     }
338   gcov_compute_histogram (list, this_prg);
339   return crc32;
340 }
341
342 /* Including system dependent components. */
343 #include "libgcov-driver-system.c"
344
345 /* This function merges counters in GI_PTR to an existing gcda file.
346    Return 0 on success.
347    Return -1 on error. In this case, caller will goto read_fatal.  */
348
349 static int
350 merge_one_data (const char *filename,
351                 struct gcov_info *gi_ptr,
352                 struct gcov_summary *prg_p,
353                 struct gcov_summary *this_prg,
354                 gcov_position_t *summary_pos_p,
355                 gcov_position_t *eof_pos_p,
356                 gcov_unsigned_t crc32)
357 {
358   gcov_unsigned_t tag, length;
359   unsigned t_ix;
360   int f_ix;
361   int error = 0;
362   struct gcov_fn_buffer **fn_tail = &fn_buffer;
363   struct gcov_summary_buffer **sum_tail = &sum_buffer;
364
365   length = gcov_read_unsigned ();
366   if (!gcov_version (gi_ptr, length, filename))
367     return -1;
368
369   length = gcov_read_unsigned ();
370   if (length != gi_ptr->stamp)
371     /* Read from a different compilation. Overwrite the file.  */
372     return 0;
373
374   /* Look for program summary.  */
375   for (f_ix = 0;;)
376     {
377       struct gcov_summary tmp;
378
379       *eof_pos_p = gcov_position ();
380       tag = gcov_read_unsigned ();
381       if (tag != GCOV_TAG_PROGRAM_SUMMARY)
382         break;
383
384       f_ix--;
385       length = gcov_read_unsigned ();
386       gcov_read_summary (&tmp);
387       if ((error = gcov_is_error ()))
388         goto read_error;
389       if (*summary_pos_p)
390         {
391           /* Save all summaries after the one that will be
392              merged into below. These will need to be rewritten
393              as histogram merging may change the number of non-zero
394              histogram entries that will be emitted, and thus the
395              size of the merged summary.  */
396           (*sum_tail) = (struct gcov_summary_buffer *)
397               xmalloc (sizeof(struct gcov_summary_buffer));
398           (*sum_tail)->summary = tmp;
399           (*sum_tail)->next = 0;
400           sum_tail = &((*sum_tail)->next);
401           goto next_summary;
402         }
403       if (tmp.checksum != crc32)
404         goto next_summary;
405
406       for (t_ix = 0; t_ix != GCOV_COUNTERS_SUMMABLE; t_ix++)
407         if (tmp.ctrs[t_ix].num != this_prg->ctrs[t_ix].num)
408           goto next_summary;
409       *prg_p = tmp;
410       *summary_pos_p = *eof_pos_p;
411
412     next_summary:;
413     }
414
415   /* Merge execution counts for each function.  */
416   for (f_ix = 0; (unsigned)f_ix != gi_ptr->n_functions;
417        f_ix++, tag = gcov_read_unsigned ())
418     {
419       const struct gcov_ctr_info *ci_ptr;
420       const struct gcov_fn_info *gfi_ptr = gi_ptr->functions[f_ix];
421
422       if (tag != GCOV_TAG_FUNCTION)
423         goto read_mismatch;
424
425       length = gcov_read_unsigned ();
426       if (!length)
427         /* This function did not appear in the other program.
428            We have nothing to merge.  */
429         continue;
430
431       if (length != GCOV_TAG_FUNCTION_LENGTH)
432         goto read_mismatch;
433
434       if (!gfi_ptr || gfi_ptr->key != gi_ptr)
435         {
436           /* This function appears in the other program.  We
437              need to buffer the information in order to write
438              it back out -- we'll be inserting data before
439              this point, so cannot simply keep the data in the
440              file.  */
441           fn_tail = buffer_fn_data (filename, gi_ptr, fn_tail, f_ix);
442           if (!fn_tail)
443             goto read_mismatch;
444           continue;
445         }
446
447       length = gcov_read_unsigned ();
448       if (length != gfi_ptr->ident)
449         goto read_mismatch;
450
451       length = gcov_read_unsigned ();
452       if (length != gfi_ptr->lineno_checksum)
453         goto read_mismatch;
454
455       length = gcov_read_unsigned ();
456       if (length != gfi_ptr->cfg_checksum)
457         goto read_mismatch;
458
459       ci_ptr = gfi_ptr->ctrs;
460       for (t_ix = 0; t_ix < GCOV_COUNTERS; t_ix++)
461         {
462           gcov_merge_fn merge = gi_ptr->merge[t_ix];
463
464           if (!merge)
465             continue;
466
467           tag = gcov_read_unsigned ();
468           length = gcov_read_unsigned ();
469           if (tag != GCOV_TAG_FOR_COUNTER (t_ix)
470               || length != GCOV_TAG_COUNTER_LENGTH (ci_ptr->num))
471             goto read_mismatch;
472           (*merge) (ci_ptr->values, ci_ptr->num);
473           ci_ptr++;
474         }
475       if ((error = gcov_is_error ()))
476         goto read_error;
477     }
478
479   if (tag)
480     {
481     read_mismatch:;
482       gcov_error ("profiling:%s:Merge mismatch for %s %u\n",
483                   filename, f_ix >= 0 ? "function" : "summary",
484                   f_ix < 0 ? -1 - f_ix : f_ix);
485       return -1;
486     }
487   return 0;
488
489 read_error:
490   gcov_error ("profiling:%s:%s merging\n", filename,
491               error < 0 ? "Overflow": "Error");
492   return -1;
493 }
494
495 /* Write counters in GI_PTR and the summary in PRG to a gcda file. In
496    the case of appending to an existing file, SUMMARY_POS will be non-zero.
497    We will write the file starting from SUMMAY_POS.  */
498
499 static void
500 write_one_data (const struct gcov_info *gi_ptr,
501                 const struct gcov_summary *prg_p,
502                 const gcov_position_t eof_pos,
503                 const gcov_position_t summary_pos)
504 {
505   unsigned f_ix;
506   struct gcov_summary_buffer *next_sum_buffer;
507
508   /* Write out the data.  */
509   if (!eof_pos)
510     {
511       gcov_write_tag_length (GCOV_DATA_MAGIC, GCOV_VERSION);
512       gcov_write_unsigned (gi_ptr->stamp);
513     }
514
515   if (summary_pos)
516     gcov_seek (summary_pos);
517
518   /* Generate whole program statistics.  */
519   gcov_write_summary (GCOV_TAG_PROGRAM_SUMMARY, prg_p);
520
521   /* Rewrite all the summaries that were after the summary we merged
522      into. This is necessary as the merged summary may have a different
523      size due to the number of non-zero histogram entries changing after
524      merging.  */
525
526   while (sum_buffer)
527     {
528       gcov_write_summary (GCOV_TAG_PROGRAM_SUMMARY, &sum_buffer->summary);
529       next_sum_buffer = sum_buffer->next;
530       free (sum_buffer);
531       sum_buffer = next_sum_buffer;
532     }
533
534   /* Write execution counts for each function.  */
535   for (f_ix = 0; f_ix != gi_ptr->n_functions; f_ix++)
536     {
537       unsigned buffered = 0;
538       const struct gcov_fn_info *gfi_ptr;
539       const struct gcov_ctr_info *ci_ptr;
540       gcov_unsigned_t length;
541       unsigned t_ix;
542
543       if (fn_buffer && fn_buffer->fn_ix == f_ix)
544         {
545           /* Buffered data from another program.  */
546           buffered = 1;
547           gfi_ptr = &fn_buffer->info;
548           length = GCOV_TAG_FUNCTION_LENGTH;
549         }
550       else
551         {
552           gfi_ptr = gi_ptr->functions[f_ix];
553           if (gfi_ptr && gfi_ptr->key == gi_ptr)
554             length = GCOV_TAG_FUNCTION_LENGTH;
555           else
556                 length = 0;
557         }
558
559       gcov_write_tag_length (GCOV_TAG_FUNCTION, length);
560       if (!length)
561         continue;
562
563       gcov_write_unsigned (gfi_ptr->ident);
564       gcov_write_unsigned (gfi_ptr->lineno_checksum);
565       gcov_write_unsigned (gfi_ptr->cfg_checksum);
566
567       ci_ptr = gfi_ptr->ctrs;
568       for (t_ix = 0; t_ix < GCOV_COUNTERS; t_ix++)
569         {
570           gcov_unsigned_t n_counts;
571           gcov_type *c_ptr;
572
573           if (!gi_ptr->merge[t_ix])
574             continue;
575
576           n_counts = ci_ptr->num;
577           gcov_write_tag_length (GCOV_TAG_FOR_COUNTER (t_ix),
578                                  GCOV_TAG_COUNTER_LENGTH (n_counts));
579           c_ptr = ci_ptr->values;
580           while (n_counts--)
581             gcov_write_counter (*c_ptr++);
582           ci_ptr++;
583         }
584       if (buffered)
585         fn_buffer = free_fn_data (gi_ptr, fn_buffer, GCOV_COUNTERS);
586     }
587
588   gcov_write_unsigned (0);
589 }
590
591 /* Helper function for merging summary.
592    Return -1 on error. Return 0 on success.  */
593
594 static int
595 merge_summary (const char *filename, int run_counted,
596                const struct gcov_info *gi_ptr, struct gcov_summary *prg,
597                struct gcov_summary *this_prg, gcov_unsigned_t crc32,
598                struct gcov_summary *all_prg __attribute__ ((unused)))
599 {
600   struct gcov_ctr_summary *cs_prg, *cs_tprg;
601   unsigned t_ix;
602 #if !GCOV_LOCKED 
603   /* summary for all instances of program.  */ 
604   struct gcov_ctr_summary *cs_all;
605 #endif 
606
607   /* Merge the summaries.  */
608   for (t_ix = 0; t_ix < GCOV_COUNTERS_SUMMABLE; t_ix++)
609     {
610       cs_prg = &(prg->ctrs[t_ix]);
611       cs_tprg = &(this_prg->ctrs[t_ix]);
612
613       if (gi_ptr->merge[t_ix])
614         {
615           int first = !cs_prg->runs;
616
617           if (!run_counted)
618             cs_prg->runs++;
619           if (first)
620             cs_prg->num = cs_tprg->num;
621           cs_prg->sum_all += cs_tprg->sum_all;
622           if (cs_prg->run_max < cs_tprg->run_max)
623             cs_prg->run_max = cs_tprg->run_max;
624           cs_prg->sum_max += cs_tprg->run_max;
625           if (first)
626             memcpy (cs_prg->histogram, cs_tprg->histogram,
627                    sizeof (gcov_bucket_type) * GCOV_HISTOGRAM_SIZE);
628           else
629             gcov_histogram_merge (cs_prg->histogram, cs_tprg->histogram);
630         }
631       else if (cs_prg->runs)
632         {
633           gcov_error ("profiling:%s:Merge mismatch for summary.\n",
634                       filename);
635           return -1;
636         }
637 #if !GCOV_LOCKED
638       cs_all = &all_prg->ctrs[t_ix];
639       if (!cs_all->runs && cs_prg->runs)
640         {
641           cs_all->num = cs_prg->num;
642           cs_all->runs = cs_prg->runs;
643           cs_all->sum_all = cs_prg->sum_all;
644           cs_all->run_max = cs_prg->run_max;
645           cs_all->sum_max = cs_prg->sum_max;
646         }
647       else if (!all_prg->checksum
648                /* Don't compare the histograms, which may have slight
649                   variations depending on the order they were updated
650                   due to the truncating integer divides used in the
651                   merge.  */
652                && (cs_all->num != cs_prg->num
653                    || cs_all->runs != cs_prg->runs
654                    || cs_all->sum_all != cs_prg->sum_all
655                    || cs_all->run_max != cs_prg->run_max
656                    || cs_all->sum_max != cs_prg->sum_max))
657              {
658                gcov_error ("profiling:%s:Data file mismatch - some "
659                            "data files may have been concurrently "
660                            "updated without locking support\n", filename);
661                all_prg->checksum = ~0u;
662              }
663 #endif
664     }
665   
666   prg->checksum = crc32;
667
668   return 0;
669 }
670
671
672 /* Sort N entries in VALUE_ARRAY in descending order.
673    Each entry in VALUE_ARRAY has two values. The sorting
674    is based on the second value.  */
675
676 GCOV_LINKAGE  void
677 gcov_sort_n_vals (gcov_type *value_array, int n)
678 {
679   int j, k;
680
681   for (j = 2; j < n; j += 2)
682     {
683       gcov_type cur_ent[2];
684
685       cur_ent[0] = value_array[j];
686       cur_ent[1] = value_array[j + 1];
687       k = j - 2;
688       while (k >= 0 && value_array[k + 1] < cur_ent[1])
689         {
690           value_array[k + 2] = value_array[k];
691           value_array[k + 3] = value_array[k+1];
692           k -= 2;
693         }
694       value_array[k + 2] = cur_ent[0];
695       value_array[k + 3] = cur_ent[1];
696     }
697 }
698
699 /* Sort the profile counters for all indirect call sites. Counters
700    for each call site are allocated in array COUNTERS.  */
701
702 static void
703 gcov_sort_icall_topn_counter (const struct gcov_ctr_info *counters)
704 {
705   int i;
706   gcov_type *values;
707   int n = counters->num;
708
709   gcc_assert (!(n % GCOV_ICALL_TOPN_NCOUNTS));
710   values = counters->values;
711
712   for (i = 0; i < n; i += GCOV_ICALL_TOPN_NCOUNTS)
713     {
714       gcov_type *value_array = &values[i + 1];
715       gcov_sort_n_vals (value_array, GCOV_ICALL_TOPN_NCOUNTS - 1);
716     }
717 }
718
719 /* Sort topn indirect_call profile counters in GI_PTR.  */
720
721 static void
722 gcov_sort_topn_counter_arrays (const struct gcov_info *gi_ptr)
723 {
724   unsigned int i;
725   int f_ix;
726   const struct gcov_fn_info *gfi_ptr;
727   const struct gcov_ctr_info *ci_ptr;
728
729   if (!gi_ptr->merge[GCOV_COUNTER_ICALL_TOPNV]) 
730     return;
731
732   for (f_ix = 0; (unsigned)f_ix != gi_ptr->n_functions; f_ix++)
733     {
734       gfi_ptr = gi_ptr->functions[f_ix];
735       ci_ptr = gfi_ptr->ctrs;
736       for (i = 0; i < GCOV_COUNTERS; i++)
737         {
738           if (!gi_ptr->merge[i])
739             continue;
740           if (i == GCOV_COUNTER_ICALL_TOPNV)
741             {
742               gcov_sort_icall_topn_counter (ci_ptr);
743               break;
744             }
745           ci_ptr++;
746         }
747     }
748 }
749
750 /* Dump the coverage counts for one gcov_info object. We merge with existing
751    counts when possible, to avoid growing the .da files ad infinitum. We use
752    this program's checksum to make sure we only accumulate whole program
753    statistics to the correct summary. An object file might be embedded
754    in two separate programs, and we must keep the two program
755    summaries separate.  */
756
757 static void
758 dump_one_gcov (struct gcov_info *gi_ptr, struct gcov_filename *gf,
759                unsigned run_counted,
760                gcov_unsigned_t crc32, struct gcov_summary *all_prg,
761                struct gcov_summary *this_prg)
762 {
763   struct gcov_summary prg; /* summary for this object over all program.  */
764   int error;
765   gcov_unsigned_t tag;
766   gcov_position_t summary_pos = 0;
767   gcov_position_t eof_pos = 0;
768
769   fn_buffer = 0;
770   sum_buffer = 0;
771
772   gcov_sort_topn_counter_arrays (gi_ptr);
773
774   error = gcov_exit_open_gcda_file (gi_ptr, gf);
775   if (error == -1)
776     return;
777
778   tag = gcov_read_unsigned ();
779   if (tag)
780     {
781       /* Merge data from file.  */
782       if (tag != GCOV_DATA_MAGIC)
783         {
784           gcov_error ("profiling:%s:Not a gcov data file\n", gf->filename);
785           goto read_fatal;
786         }
787       error = merge_one_data (gf->filename, gi_ptr, &prg, this_prg,
788                               &summary_pos, &eof_pos, crc32);
789       if (error == -1)
790         goto read_fatal;
791     }
792
793   gcov_rewrite ();
794
795   if (!summary_pos)
796     {
797       memset (&prg, 0, sizeof (prg));
798       summary_pos = eof_pos;
799     }
800
801   error = merge_summary (gf->filename, run_counted, gi_ptr, &prg, this_prg,
802                          crc32, all_prg);
803   if (error == -1)
804     goto read_fatal;
805
806   write_one_data (gi_ptr, &prg, eof_pos, summary_pos);
807   /* fall through */
808
809 read_fatal:;
810   while (fn_buffer)
811     fn_buffer = free_fn_data (gi_ptr, fn_buffer, GCOV_COUNTERS);
812
813   if ((error = gcov_close ()))
814     gcov_error (error  < 0 ?
815                 "profiling:%s:Overflow writing\n" :
816                 "profiling:%s:Error writing\n",
817                 gf->filename);
818 }
819
820
821 /* Dump all the coverage counts for the program. It first computes program
822    summary and then traverses gcov_list list and dumps the gcov_info
823    objects one by one.  */
824
825 #if !IN_GCOV_TOOL
826 static
827 #endif
828 void
829 gcov_do_dump (struct gcov_info *list, int run_counted)
830 {
831   struct gcov_info *gi_ptr;
832   struct gcov_filename gf;
833   gcov_unsigned_t crc32;
834   struct gcov_summary all_prg;
835   struct gcov_summary this_prg;
836
837   crc32 = compute_summary (list, &this_prg, &gf.max_length);
838
839   allocate_filename_struct (&gf);
840 #if !GCOV_LOCKED
841   memset (&all_prg, 0, sizeof (all_prg));
842 #endif
843
844   /* Now merge each file.  */
845   for (gi_ptr = list; gi_ptr; gi_ptr = gi_ptr->next)
846     dump_one_gcov (gi_ptr, &gf, run_counted, crc32, &all_prg, &this_prg);
847
848   free (gf.filename);
849 }
850
851 #if !IN_GCOV_TOOL
852 void
853 __gcov_dump_one (struct gcov_root *root)
854 {
855   if (root->dumped)
856     return;
857
858   gcov_do_dump (root->list, root->run_counted);
859   
860   root->dumped = 1;
861   root->run_counted = 1;
862 }
863
864 /* Per-dynamic-object gcov state.  */
865 struct gcov_root __gcov_root;
866
867 /* Exactly one of these will be live in the process image.  */
868 struct gcov_master __gcov_master = 
869   {GCOV_VERSION, 0};
870
871 static void
872 gcov_exit (void)
873 {
874   __gcov_dump_one (&__gcov_root);
875   if (__gcov_root.next)
876     __gcov_root.next->prev = __gcov_root.prev;
877   if (__gcov_root.prev)
878     __gcov_root.prev->next = __gcov_root.next;
879   else
880     __gcov_master.root = __gcov_root.next;
881 }
882
883 /* Add a new object file onto the bb chain.  Invoked automatically
884   when running an object file's global ctors.  */
885
886 void
887 __gcov_init (struct gcov_info *info)
888 {
889   if (!info->version || !info->n_functions)
890     return;
891   if (gcov_version (info, info->version, 0))
892     {
893       if (!__gcov_root.list)
894         {
895           /* Add to master list and at exit function.  */
896           if (gcov_version (NULL, __gcov_master.version, "<master>"))
897             {
898               __gcov_root.next = __gcov_master.root;
899               if (__gcov_master.root)
900                 __gcov_master.root->prev = &__gcov_root;
901               __gcov_master.root = &__gcov_root;
902             }
903           atexit (gcov_exit);
904         }
905
906       info->next = __gcov_root.list;
907       __gcov_root.list = info;
908     }
909 }
910 #endif /* !IN_GCOV_TOOL */
911 #endif /* L_gcov */
912 #endif /* inhibit_libc */