1/* Routines required for instrumenting a program.  */
2/* Compile this one with gcc.  */
3/* Copyright (C) 1989-2014 Free Software Foundation, Inc.
4
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify it under
8the terms of the GNU General Public License as published by the Free
9Software Foundation; either version 3, or (at your option) any later
10version.
11
12GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13WARRANTY; without even the implied warranty of MERCHANTABILITY or
14FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15for more details.
16
17Under Section 7 of GPL version 3, you are granted additional
18permissions described in the GCC Runtime Library Exception, version
193.1, as published by the Free Software Foundation.
20
21You should have received a copy of the GNU General Public License and
22a copy of the GCC Runtime Library Exception along with this program;
23see 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)
32void __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#include "gcov-io.c"
46
47#ifndef IN_GCOV_TOOL
48extern gcov_unsigned_t __gcov_sampling_period;
49extern gcov_unsigned_t __gcov_has_sampling;
50static int gcov_sampling_period_initialized = 0;
51#endif
52
53/* Unique identifier assigned to each module (object file).  */
54static gcov_unsigned_t gcov_cur_module_id = 0;
55
56
57/* Dynamic call graph build and form module groups.  */
58int __gcov_compute_module_groups (void) ATTRIBUTE_HIDDEN;
59void __gcov_finalize_dyn_callgraph (void) ATTRIBUTE_HIDDEN;
60
61/* The following functions can be called from outside of this file.  */
62extern void gcov_clear (void) ATTRIBUTE_HIDDEN;
63extern void gcov_exit (void) ATTRIBUTE_HIDDEN;
64extern void set_gcov_dump_complete (void) ATTRIBUTE_HIDDEN;
65extern void reset_gcov_dump_complete (void) ATTRIBUTE_HIDDEN;
66extern int get_gcov_dump_complete (void) ATTRIBUTE_HIDDEN;
67extern void set_gcov_list (struct gcov_info *) ATTRIBUTE_HIDDEN;
68__attribute__((weak)) void __coverage_callback (gcov_type, int);
69
70#ifndef IN_GCOV_TOOL
71/* Create a strong reference to these symbols so that they are
72   unconditionally pulled into the instrumented binary, even when
73   the only reference is a weak reference. This is necessary because
74   we are using weak references to enable references from code that
75   may not be linked with libgcov. These are the only symbols that
76   should be accessed via link references from application code!
77
78   A subtlety of the linker is that it will only resolve weak references
79   defined within archive libraries when there is a strong reference to
80   something else defined within the same object file. Since these functions
81   are defined within their own object files, they would not automatically
82   get resolved. Since there are symbols within the main L_gcov
83   section that are strongly referenced during -fprofile-generate and
84   -ftest-coverage builds, these dummy symbols will always need to be
85   resolved.  */
86void (*__gcov_dummy_ref1)(void) = &__gcov_reset;
87void (*__gcov_dummy_ref2)(void) = &__gcov_dump;
88extern char *__gcov_get_profile_prefix (void);
89char *(*__gcov_dummy_ref3)(void) = &__gcov_get_profile_prefix;
90extern void __gcov_set_sampling_period (unsigned int period);
91char *(*__gcov_dummy_ref4)(void) = &__gcov_set_sampling_period;
92extern unsigned int __gcov_sampling_enabled (void);
93char *(*__gcov_dummy_ref5)(void) = &__gcov_sampling_enabled;
94extern void __gcov_flush (void);
95char *(*__gcov_dummy_ref6)(void) = &__gcov_flush;
96extern unsigned int __gcov_profiling_for_test_coverage (void);
97char *(*__gcov_dummy_ref7)(void) = &__gcov_profiling_for_test_coverage;
98#endif
99
100/* Default callback function for profile instrumentation callback.  */
101__attribute__((weak)) void
102__coverage_callback (gcov_type funcdef_no __attribute__ ((unused)),
103                     int edge_no __attribute__ ((unused)))
104{
105   /* nothing */
106}
107
108struct gcov_fn_buffer
109{
110  struct gcov_fn_buffer *next;
111  unsigned fn_ix;
112  struct gcov_fn_info info;
113  /* note gcov_fn_info ends in a trailing array.  */
114};
115
116struct gcov_summary_buffer
117{
118  struct gcov_summary_buffer *next;
119  struct gcov_summary summary;
120};
121
122/* Chain of per-object gcov structures.  */
123extern struct gcov_info *__gcov_list;
124
125/* Set the head of gcov_list.  */
126void
127set_gcov_list (struct gcov_info *head)
128{
129  __gcov_list = head;
130}
131
132/* Size of the longest file name. */
133/* We need to expose this static variable when compiling for gcov-tool.  */
134#ifndef IN_GCOV_TOOL
135static
136#endif
137size_t gcov_max_filename = 0;
138
139/* Flag when the profile has already been dumped via __gcov_dump().  */
140static int gcov_dump_complete;
141
142/* A global function that get the vaule of gcov_dump_complete.  */
143
144int
145get_gcov_dump_complete (void)
146{
147  return gcov_dump_complete;
148}
149
150/* A global functino that set the vaule of gcov_dump_complete. Will
151   be used in __gcov_dump() in libgcov-interface.c.  */
152
153void
154set_gcov_dump_complete (void)
155{
156  gcov_dump_complete = 1;
157}
158
159/* A global functino that set the vaule of gcov_dump_complete. Will
160   be used in __gcov_reset() in libgcov-interface.c.  */
161
162void
163reset_gcov_dump_complete (void)
164{
165  gcov_dump_complete = 0;
166}
167
168/* A utility function for outputing errors.  */
169static int gcov_error (const char *, ...);
170
171static struct gcov_fn_buffer *
172free_fn_data (const struct gcov_info *gi_ptr, struct gcov_fn_buffer *buffer,
173              unsigned limit)
174{
175  struct gcov_fn_buffer *next;
176  unsigned ix, n_ctr = 0;
177
178  if (!buffer)
179    return 0;
180  next = buffer->next;
181
182  for (ix = 0; ix != limit; ix++)
183    if (gi_ptr->merge[ix])
184      free (buffer->info.ctrs[n_ctr++].values);
185  free (buffer);
186  return next;
187}
188
189static struct gcov_fn_buffer **
190buffer_fn_data (const char *filename, const struct gcov_info *gi_ptr,
191                struct gcov_fn_buffer **end_ptr, unsigned fn_ix)
192{
193  unsigned n_ctrs = 0, ix = 0;
194  struct gcov_fn_buffer *fn_buffer;
195  unsigned len;
196
197  for (ix = GCOV_COUNTERS; ix--;)
198    if (gi_ptr->merge[ix])
199      n_ctrs++;
200
201  len = sizeof (*fn_buffer) + sizeof (fn_buffer->info.ctrs[0]) * n_ctrs;
202  fn_buffer = (struct gcov_fn_buffer *) xmalloc (len);
203
204  if (!fn_buffer)
205    goto fail;
206
207  fn_buffer->next = 0;
208  fn_buffer->fn_ix = fn_ix;
209  fn_buffer->info.ident = gcov_read_unsigned ();
210  fn_buffer->info.lineno_checksum = gcov_read_unsigned ();
211  fn_buffer->info.cfg_checksum = gcov_read_unsigned ();
212
213  for (n_ctrs = ix = 0; ix != GCOV_COUNTERS; ix++)
214    {
215      gcov_unsigned_t length;
216      gcov_type *values;
217
218      if (!gi_ptr->merge[ix])
219        continue;
220
221      if (gcov_read_unsigned () != GCOV_TAG_FOR_COUNTER (ix))
222        {
223          len = 0;
224          goto fail;
225        }
226
227      length = GCOV_TAG_COUNTER_NUM (gcov_read_unsigned ());
228      len = length * sizeof (gcov_type);
229      values = (gcov_type *) xmalloc (len);
230      if (!values)
231        goto fail;
232
233      fn_buffer->info.ctrs[n_ctrs].num = length;
234      fn_buffer->info.ctrs[n_ctrs].values = values;
235
236      while (length--)
237        *values++ = gcov_read_counter ();
238      n_ctrs++;
239    }
240
241  *end_ptr = fn_buffer;
242  return &fn_buffer->next;
243
244fail:
245  gcov_error ("profiling:%s:Function %u %s %u \n", filename, fn_ix,
246              len ? "cannot allocate" : "counter mismatch", len ? len : ix);
247
248  return (struct gcov_fn_buffer **)free_fn_data (gi_ptr, fn_buffer, ix);
249}
250
251/* Determine whether a counter is active.  */
252
253static inline int
254gcov_counter_active (const struct gcov_info *info, unsigned int type)
255{
256  return (info->merge[type] != 0);
257}
258
259/* Add an unsigned value to the current crc */
260
261static gcov_unsigned_t
262crc32_unsigned (gcov_unsigned_t crc32, gcov_unsigned_t value)
263{
264  unsigned ix;
265
266  for (ix = 32; ix--; value <<= 1)
267    {
268      unsigned feedback;
269
270      feedback = (value ^ crc32) & 0x80000000 ? 0x04c11db7 : 0;
271      crc32 <<= 1;
272      crc32 ^= feedback;
273    }
274
275  return crc32;
276}
277
278/* Check if VERSION of the info block PTR matches libgcov one.
279   Return 1 on success, or zero in case of versions mismatch.
280   If FILENAME is not NULL, its value used for reporting purposes
281   instead of value from the info block.  */
282
283static int
284gcov_version (struct gcov_info *ptr, gcov_unsigned_t version,
285              const char *filename)
286{
287  if (version != GCOV_VERSION)
288    {
289      char v[4], e[4];
290
291      GCOV_UNSIGNED2STRING (v, version);
292      GCOV_UNSIGNED2STRING (e, GCOV_VERSION);
293
294      if (filename)
295        gcov_error ("profiling:%s:Version mismatch - expected %.4s got %.4s\n",
296                   filename? filename : ptr->filename, e, v);
297      else
298        gcov_error ("profiling:Version mismatch - expected %.4s got %.4s\n", e, v);
299
300      return 0;
301    }
302  return 1;
303}
304
305/* Insert counter VALUE into HISTOGRAM.  */
306
307static void
308gcov_histogram_insert(gcov_bucket_type *histogram, gcov_type value)
309{
310  unsigned i;
311
312  i = gcov_histo_index(value);
313  histogram[i].num_counters++;
314  histogram[i].cum_value += value;
315  if (value < histogram[i].min_value)
316    histogram[i].min_value = value;
317}
318
319/* Computes a histogram of the arc counters to place in the summary SUM.  */
320
321static void
322gcov_compute_histogram (struct gcov_summary *sum)
323{
324  struct gcov_info *gi_ptr;
325  const struct gcov_fn_info *gfi_ptr;
326  const struct gcov_ctr_info *ci_ptr;
327  struct gcov_ctr_summary *cs_ptr;
328  unsigned t_ix, f_ix, ctr_info_ix, ix;
329  int h_ix;
330
331  /* This currently only applies to arc counters.  */
332  t_ix = GCOV_COUNTER_ARCS;
333
334  /* First check if there are any counts recorded for this counter.  */
335  cs_ptr = &(sum->ctrs[t_ix]);
336  if (!cs_ptr->num)
337    return;
338
339  for (h_ix = 0; h_ix < GCOV_HISTOGRAM_SIZE; h_ix++)
340    {
341      cs_ptr->histogram[h_ix].num_counters = 0;
342      cs_ptr->histogram[h_ix].min_value = cs_ptr->run_max;
343      cs_ptr->histogram[h_ix].cum_value = 0;
344    }
345
346  /* Walk through all the per-object structures and record each of
347     the count values in histogram.  */
348  for (gi_ptr = __gcov_list; gi_ptr; gi_ptr = gi_ptr->next)
349    {
350      if (!gi_ptr->merge[t_ix])
351        continue;
352
353      /* Find the appropriate index into the gcov_ctr_info array
354         for the counter we are currently working on based on the
355         existence of the merge function pointer for this object.  */
356      for (ix = 0, ctr_info_ix = 0; ix < t_ix; ix++)
357        {
358          if (gi_ptr->merge[ix])
359            ctr_info_ix++;
360        }
361      for (f_ix = 0; f_ix != gi_ptr->n_functions; f_ix++)
362        {
363          gfi_ptr = gi_ptr->functions[f_ix];
364
365          if (!gfi_ptr || gfi_ptr->key != gi_ptr)
366            continue;
367
368          ci_ptr = &gfi_ptr->ctrs[ctr_info_ix];
369          for (ix = 0; ix < ci_ptr->num; ix++)
370            gcov_histogram_insert (cs_ptr->histogram, ci_ptr->values[ix]);
371        }
372    }
373}
374
375/* gcda filename.  */
376static char *gi_filename;
377/* buffer for the fn_data from another program.  */
378static struct gcov_fn_buffer *fn_buffer;
379/* buffer for summary from other programs to be written out. */
380static struct gcov_summary_buffer *sum_buffer;
381/* If application calls fork or exec multiple times, we end up storing
382   profile repeadely.  We should not account this as multiple runs or
383   functions executed once may mistakely become cold.  */
384static int run_accounted = 0;
385
386/* This funtions computes the program level summary and the histo-gram.
387   It computes and returns CRC32 and stored summary in THIS_PRG.  */
388
389static gcov_unsigned_t
390gcov_exit_compute_summary (struct gcov_summary *this_prg)
391{
392  struct gcov_info *gi_ptr;
393  const struct gcov_fn_info *gfi_ptr;
394  struct gcov_ctr_summary *cs_ptr;
395  const struct gcov_ctr_info *ci_ptr;
396  int f_ix;
397  unsigned t_ix;
398  gcov_unsigned_t c_num;
399  gcov_unsigned_t crc32 = 0;
400
401  /* Find the totals for this execution.  */
402  memset (this_prg, 0, sizeof (*this_prg));
403  for (gi_ptr = __gcov_list; gi_ptr; gi_ptr = gi_ptr->next)
404    {
405      crc32 = crc32_unsigned (crc32, gi_ptr->stamp);
406      crc32 = crc32_unsigned (crc32, gi_ptr->n_functions);
407
408      for (f_ix = 0; (unsigned)f_ix != gi_ptr->n_functions; f_ix++)
409        {
410          gfi_ptr = gi_ptr->functions[f_ix];
411
412          if (gfi_ptr && gfi_ptr->key != gi_ptr)
413            gfi_ptr = 0;
414
415          crc32 = crc32_unsigned (crc32, gfi_ptr ? gfi_ptr->cfg_checksum : 0);
416          crc32 = crc32_unsigned (crc32,
417                                  gfi_ptr ? gfi_ptr->lineno_checksum : 0);
418          if (!gfi_ptr)
419            continue;
420
421          ci_ptr = gfi_ptr->ctrs;
422          for (t_ix = 0; t_ix != GCOV_COUNTERS_SUMMABLE; t_ix++)
423            {
424              if (!gi_ptr->merge[t_ix])
425                continue;
426
427              cs_ptr = &(this_prg->ctrs[t_ix]);
428              cs_ptr->num += ci_ptr->num;
429              crc32 = crc32_unsigned (crc32, ci_ptr->num);
430
431              for (c_num = 0; c_num < ci_ptr->num; c_num++)
432                {
433                  cs_ptr->sum_all += ci_ptr->values[c_num];
434                  if (cs_ptr->run_max < ci_ptr->values[c_num])
435                    cs_ptr->run_max = ci_ptr->values[c_num];
436                }
437              ci_ptr++;
438            }
439        }
440    }
441  gcov_compute_histogram (this_prg);
442  return crc32;
443}
444
445/* A struct that bundles all the related information about the
446   gcda filename.  */
447struct gcov_filename_aux{
448  char *gi_filename_up;
449  int gcov_prefix_strip;
450  size_t prefix_length;
451};
452
453/* Including system dependent components. */
454#include "libgcov-driver-system.c"
455
456/* Scan through the current open gcda file corresponding to GI_PTR
457   to locate the end position of the last summary, returned in
458   SUMMARY_END_POS_P.  Return 0 on success, -1 on error.  */
459static int
460gcov_scan_summary_end (struct gcov_info *gi_ptr,
461                       gcov_position_t *summary_end_pos_p)
462{
463  gcov_unsigned_t tag, version, stamp;
464  tag = gcov_read_unsigned ();
465  if (tag != GCOV_DATA_MAGIC)
466    {
467      gcov_error ("profiling:%s:Not a gcov data file\n", gi_filename);
468      return -1;
469    }
470
471  version = gcov_read_unsigned ();
472  if (!gcov_version (gi_ptr, version, gi_filename))
473    return -1;
474
475  stamp = gcov_read_unsigned ();
476  if (stamp != gi_ptr->stamp)
477    /* Read from a different compilation.  Overwrite the file.  */
478    return -1;
479
480  /* Look for program summary.  */
481  while (1)
482    {
483      struct gcov_summary tmp;
484
485      *summary_end_pos_p = gcov_position ();
486      tag = gcov_read_unsigned ();
487      if (tag != GCOV_TAG_PROGRAM_SUMMARY)
488        break;
489
490      gcov_read_unsigned ();
491      gcov_read_summary (&tmp);
492      if (gcov_is_error ())
493        return -1;
494    }
495
496  return 0;
497}
498
499/* This function merges counters in GI_PTR to an existing gcda file.
500   Return 0 on success.
501   Return -1 on error. In this case, caller will goto read_fatal.  */
502
503static int
504gcov_exit_merge_gcda (struct gcov_info *gi_ptr,
505                      struct gcov_summary *prg_p,
506                      struct gcov_summary *this_prg,
507                      gcov_position_t *summary_pos_p,
508                      gcov_position_t *eof_pos_p,
509		      gcov_unsigned_t crc32)
510{
511  gcov_unsigned_t tag, length;
512  unsigned t_ix;
513  int f_ix;
514  int error = 0;
515  struct gcov_fn_buffer **fn_tail = &fn_buffer;
516  struct gcov_summary_buffer **sum_tail = &sum_buffer;
517
518  length = gcov_read_unsigned ();
519  if (!gcov_version (gi_ptr, length, gi_filename))
520    return -1;
521
522  length = gcov_read_unsigned ();
523  if (length != gi_ptr->stamp)
524    /* Read from a different compilation. Overwrite the file.  */
525    return 0;
526
527  /* Look for program summary.  */
528  for (f_ix = 0;;)
529    {
530      struct gcov_summary tmp;
531
532      *eof_pos_p = gcov_position ();
533      tag = gcov_read_unsigned ();
534      if (tag != GCOV_TAG_PROGRAM_SUMMARY)
535        break;
536
537      f_ix--;
538      length = gcov_read_unsigned ();
539      gcov_read_summary (&tmp);
540      if ((error = gcov_is_error ()))
541        goto read_error;
542      if (*summary_pos_p)
543        {
544          /* Save all summaries after the one that will be
545             merged into below. These will need to be rewritten
546             as histogram merging may change the number of non-zero
547             histogram entries that will be emitted, and thus the
548             size of the merged summary.  */
549          (*sum_tail) = (struct gcov_summary_buffer *)
550              xmalloc (sizeof(struct gcov_summary_buffer));
551          (*sum_tail)->summary = tmp;
552          (*sum_tail)->next = 0;
553          sum_tail = &((*sum_tail)->next);
554          goto next_summary;
555        }
556      if (tmp.checksum != crc32)
557        goto next_summary;
558
559      for (t_ix = 0; t_ix != GCOV_COUNTERS_SUMMABLE; t_ix++)
560        if (tmp.ctrs[t_ix].num != this_prg->ctrs[t_ix].num)
561          goto next_summary;
562      *prg_p = tmp;
563      *summary_pos_p = *eof_pos_p;
564
565    next_summary:;
566    }
567
568  /* Merge execution counts for each function.  */
569  for (f_ix = 0; (unsigned)f_ix != gi_ptr->n_functions;
570       f_ix++, tag = gcov_read_unsigned ())
571    {
572      const struct gcov_ctr_info *ci_ptr;
573      const struct gcov_fn_info *gfi_ptr = gi_ptr->functions[f_ix];
574
575      if (tag != GCOV_TAG_FUNCTION)
576        goto read_mismatch;
577
578      length = gcov_read_unsigned ();
579      if (!length)
580        /* This function did not appear in the other program.
581           We have nothing to merge.  */
582        continue;
583
584      if (length != GCOV_TAG_FUNCTION_LENGTH)
585        goto read_mismatch;
586
587      if (!gfi_ptr || gfi_ptr->key != gi_ptr)
588        {
589          /* This function appears in the other program.  We
590             need to buffer the information in order to write
591             it back out -- we'll be inserting data before
592             this point, so cannot simply keep the data in the
593             file.  */
594          fn_tail = buffer_fn_data (gi_filename,
595                                    gi_ptr, fn_tail, f_ix);
596          if (!fn_tail)
597            goto read_mismatch;
598          continue;
599        }
600
601      length = gcov_read_unsigned ();
602      if (length != gfi_ptr->ident)
603        goto read_mismatch;
604
605      length = gcov_read_unsigned ();
606      if (length != gfi_ptr->lineno_checksum)
607        goto read_mismatch;
608
609      length = gcov_read_unsigned ();
610      if (length != gfi_ptr->cfg_checksum)
611        goto read_mismatch;
612
613      ci_ptr = gfi_ptr->ctrs;
614      for (t_ix = 0; t_ix < GCOV_COUNTERS; t_ix++)
615        {
616          gcov_merge_fn merge = gi_ptr->merge[t_ix];
617
618          if (!merge)
619            continue;
620
621          tag = gcov_read_unsigned ();
622          length = gcov_read_unsigned ();
623          if (tag != GCOV_TAG_FOR_COUNTER (t_ix)
624              || length != GCOV_TAG_COUNTER_LENGTH (ci_ptr->num))
625            goto read_mismatch;
626          (*merge) (ci_ptr->values, ci_ptr->num);
627          ci_ptr++;
628        }
629      if ((error = gcov_is_error ()))
630        goto read_error;
631    }
632
633  if (tag && tag != GCOV_TAG_MODULE_INFO)
634    {
635    read_mismatch:;
636      gcov_error ("profiling:%s:Merge mismatch for %s %u\n",
637                  gi_filename, f_ix >= 0 ? "function" : "summary",
638                  f_ix < 0 ? -1 - f_ix : f_ix);
639      return -1;
640    }
641  return 0;
642
643read_error:
644  gcov_error ("profiling:%s:%s merging\n", gi_filename,
645              error < 0 ? "Overflow": "Error");
646  return -1;
647}
648
649/* Write counters in GI_PTR to a gcda file starting from its current
650   location.  */
651
652static void
653gcov_write_func_counters (struct gcov_info *gi_ptr)
654{
655  unsigned f_ix;
656
657  /* Write execution counts for each function.  */
658  for (f_ix = 0; f_ix != gi_ptr->n_functions; f_ix++)
659    {
660      unsigned buffered = 0;
661      const struct gcov_fn_info *gfi_ptr;
662      const struct gcov_ctr_info *ci_ptr;
663      gcov_unsigned_t length;
664      unsigned t_ix;
665
666      if (fn_buffer && fn_buffer->fn_ix == f_ix)
667        {
668          /* Buffered data from another program.  */
669          buffered = 1;
670          gfi_ptr = &fn_buffer->info;
671          length = GCOV_TAG_FUNCTION_LENGTH;
672        }
673      else
674        {
675          gfi_ptr = gi_ptr->functions[f_ix];
676          if (gfi_ptr && gfi_ptr->key == gi_ptr)
677            length = GCOV_TAG_FUNCTION_LENGTH;
678          else
679                length = 0;
680        }
681
682      gcov_write_tag_length (GCOV_TAG_FUNCTION, length);
683      if (!length)
684        continue;
685
686      gcov_write_unsigned (gfi_ptr->ident);
687      gcov_write_unsigned (gfi_ptr->lineno_checksum);
688      gcov_write_unsigned (gfi_ptr->cfg_checksum);
689
690      ci_ptr = gfi_ptr->ctrs;
691      for (t_ix = 0; t_ix < GCOV_COUNTERS; t_ix++)
692        {
693          gcov_unsigned_t n_counts;
694          gcov_type *c_ptr;
695
696          if (!gi_ptr->merge[t_ix])
697            continue;
698
699          n_counts = ci_ptr->num;
700          gcov_write_tag_length (GCOV_TAG_FOR_COUNTER (t_ix),
701                                 GCOV_TAG_COUNTER_LENGTH (n_counts));
702          c_ptr = ci_ptr->values;
703          while (n_counts--)
704            gcov_write_counter (*c_ptr++);
705          ci_ptr++;
706        }
707      if (buffered)
708        fn_buffer = free_fn_data (gi_ptr, fn_buffer, GCOV_COUNTERS);
709    }
710
711  gi_ptr->eof_pos = gcov_position ();
712  gcov_write_unsigned (0);
713}
714
715/* Write counters in GI_PTR and the summary in PRG to a gcda file.  In
716   the case of appending to an existing file, SUMMARY_POS will be non-zero.
717   We will write the file starting from SUMMAY_POS.  */
718
719static void
720gcov_exit_write_gcda (struct gcov_info *gi_ptr,
721                      const struct gcov_summary *prg_p,
722                      const gcov_position_t eof_pos,
723                      const gcov_position_t summary_pos)
724
725{
726  struct gcov_summary_buffer *next_sum_buffer;
727
728  /* Write out the data.  */
729  if (!eof_pos)
730    {
731      gcov_write_tag_length (GCOV_DATA_MAGIC, GCOV_VERSION);
732      gcov_write_unsigned (gi_ptr->stamp);
733    }
734
735  if (summary_pos)
736     gcov_seek (summary_pos);
737  gcc_assert (!summary_pos || summary_pos == gcov_position ());
738
739  /* Generate whole program statistics.  */
740  gcov_write_summary (GCOV_TAG_PROGRAM_SUMMARY, prg_p);
741
742  /* Rewrite all the summaries that were after the summary we merged
743     into.  This is necessary as the merged summary may have a different
744     size due to the number of non-zero histogram entries changing after
745     merging.  */
746
747  while (sum_buffer)
748    {
749      gcov_write_summary (GCOV_TAG_PROGRAM_SUMMARY, &sum_buffer->summary);
750      next_sum_buffer = sum_buffer->next;
751      free (sum_buffer);
752      sum_buffer = next_sum_buffer;
753    }
754
755  /* Write the counters.  */
756  gcov_write_func_counters (gi_ptr);
757}
758
759/* Helper function for merging summary.
760   Return -1 on error. Return 0 on success.  */
761
762static int
763gcov_exit_merge_summary (const struct gcov_info *gi_ptr, struct gcov_summary *prg,
764                         struct gcov_summary *this_prg, gcov_unsigned_t crc32,
765			 struct gcov_summary *all_prg __attribute__ ((unused)))
766{
767  struct gcov_ctr_summary *cs_prg, *cs_tprg;
768  unsigned t_ix;
769#if !GCOV_LOCKED
770  /* summary for all instances of program.  */
771  struct gcov_ctr_summary *cs_all;
772#endif
773
774  /* Merge the summaries.  */
775  for (t_ix = 0; t_ix < GCOV_COUNTERS_SUMMABLE; t_ix++)
776    {
777      cs_prg = &(prg->ctrs[t_ix]);
778      cs_tprg = &(this_prg->ctrs[t_ix]);
779
780      if (gi_ptr->merge[t_ix])
781        {
782	  int first = !cs_prg->runs;
783
784	  if (!run_accounted)
785	    cs_prg->runs++;
786          if (first)
787            cs_prg->num = cs_tprg->num;
788          cs_prg->sum_all += cs_tprg->sum_all;
789          if (cs_prg->run_max < cs_tprg->run_max)
790            cs_prg->run_max = cs_tprg->run_max;
791          cs_prg->sum_max += cs_tprg->run_max;
792          if (first)
793            memcpy (cs_prg->histogram, cs_tprg->histogram,
794                   sizeof (gcov_bucket_type) * GCOV_HISTOGRAM_SIZE);
795          else
796            gcov_histogram_merge (cs_prg->histogram, cs_tprg->histogram);
797        }
798      else if (cs_prg->runs)
799        {
800          gcov_error ("profiling:%s:Merge mismatch for summary.\n",
801                      gi_filename);
802          return -1;
803        }
804#if !GCOV_LOCKED
805      cs_all = &all_prg->ctrs[t_ix];
806      if (!cs_all->runs && cs_prg->runs)
807        {
808          cs_all->num = cs_prg->num;
809          cs_all->runs = cs_prg->runs;
810          cs_all->sum_all = cs_prg->sum_all;
811          cs_all->run_max = cs_prg->run_max;
812          cs_all->sum_max = cs_prg->sum_max;
813        }
814      else if (!all_prg->checksum
815               /* Don't compare the histograms, which may have slight
816                  variations depending on the order they were updated
817                  due to the truncating integer divides used in the
818                  merge.  */
819               && (cs_all->num != cs_prg->num
820                   || cs_all->runs != cs_prg->runs
821                   || cs_all->sum_all != cs_prg->sum_all
822                   || cs_all->run_max != cs_prg->run_max
823                   || cs_all->sum_max != cs_prg->sum_max))
824             {
825               gcov_error ("profiling:%s:Data file mismatch - some "
826                           "data files may have been concurrently "
827                           "updated without locking support\n", gi_filename);
828               all_prg->checksum = ~0u;
829             }
830#endif
831    }
832
833  prg->checksum = crc32;
834
835  return 0;
836}
837
838/* Sort N entries in VALUE_ARRAY in descending order.
839   Each entry in VALUE_ARRAY has two values. The sorting
840   is based on the second value.  */
841
842GCOV_LINKAGE  void
843gcov_sort_n_vals (gcov_type *value_array, int n)
844{
845  int j, k;
846  for (j = 2; j < n; j += 2)
847    {
848      gcov_type cur_ent[2];
849      cur_ent[0] = value_array[j];
850      cur_ent[1] = value_array[j + 1];
851      k = j - 2;
852      while (k >= 0 && value_array[k + 1] < cur_ent[1])
853        {
854          value_array[k + 2] = value_array[k];
855          value_array[k + 3] = value_array[k+1];
856          k -= 2;
857        }
858      value_array[k + 2] = cur_ent[0];
859      value_array[k + 3] = cur_ent[1];
860    }
861}
862
863/* Sort the profile counters for all indirect call sites. Counters
864   for each call site are allocated in array COUNTERS.  */
865
866static void
867gcov_sort_icall_topn_counter (const struct gcov_ctr_info *counters)
868{
869  int i;
870  gcov_type *values;
871  int n = counters->num;
872  gcc_assert (!(n % GCOV_ICALL_TOPN_NCOUNTS));
873
874  values = counters->values;
875
876  for (i = 0; i < n; i += GCOV_ICALL_TOPN_NCOUNTS)
877    {
878      gcov_type *value_array = &values[i + 1];
879      gcov_sort_n_vals (value_array, GCOV_ICALL_TOPN_NCOUNTS - 1);
880    }
881}
882
883static void
884gcov_sort_topn_counter_arrays (const struct gcov_info *gi_ptr)
885{
886  unsigned int i;
887  int f_ix;
888  const struct gcov_fn_info *gfi_ptr;
889  const struct gcov_ctr_info *ci_ptr;
890
891  for (f_ix = 0; (unsigned)f_ix != gi_ptr->n_functions; f_ix++)
892    {
893      gfi_ptr = gi_ptr->functions[f_ix];
894      ci_ptr = gfi_ptr->ctrs;
895      for (i = 0; i < GCOV_COUNTERS; i++)
896        {
897          if (!gcov_counter_active (gi_ptr, i))
898            continue;
899          if (i == GCOV_COUNTER_ICALL_TOPNV)
900            {
901              gcov_sort_icall_topn_counter (ci_ptr);
902              break;
903            }
904          ci_ptr++;
905        }
906     }
907}
908
909/* Dump the coverage counts for one gcov_info object. We merge with existing
910   counts when possible, to avoid growing the .da files ad infinitum. We use
911   this program's checksum to make sure we only accumulate whole program
912   statistics to the correct summary. An object file might be embedded
913   in two separate programs, and we must keep the two program
914   summaries separate.  */
915
916static void
917gcov_exit_dump_gcov (struct gcov_info *gi_ptr, struct gcov_filename_aux *gf,
918		     gcov_unsigned_t crc32, struct gcov_summary *all_prg,
919                     struct gcov_summary *this_prg)
920{
921  struct gcov_summary prg; /* summary for this object over all program.  */
922  int error;
923  gcov_unsigned_t tag;
924  gcov_position_t summary_pos = 0;
925  gcov_position_t eof_pos = 0;
926
927  fn_buffer = 0;
928  sum_buffer = 0;
929
930  gcov_sort_topn_counter_arrays (gi_ptr);
931
932  error = gcov_exit_open_gcda_file (gi_ptr, gf);
933  if (error == -1)
934    return;
935
936  tag = gcov_read_unsigned ();
937  if (tag)
938    {
939      /* Merge data from file.  */
940      if (tag != GCOV_DATA_MAGIC)
941        {
942          gcov_error ("profiling:%s:Not a gcov data file\n", gi_filename);
943          goto read_fatal;
944        }
945      error = gcov_exit_merge_gcda (gi_ptr, &prg, this_prg, &summary_pos, &eof_pos,
946				    crc32);
947      if (error == -1)
948        goto read_fatal;
949    }
950
951  gcov_rewrite ();
952
953  if (!summary_pos)
954    {
955      memset (&prg, 0, sizeof (prg));
956      summary_pos = eof_pos;
957    }
958
959  error = gcov_exit_merge_summary (gi_ptr, &prg, this_prg, crc32, all_prg);
960  if (error == -1)
961    goto read_fatal;
962
963  gcov_exit_write_gcda (gi_ptr, &prg, eof_pos, summary_pos);
964  /* fall through */
965
966read_fatal:;
967  while (fn_buffer)
968    fn_buffer = free_fn_data (gi_ptr, fn_buffer, GCOV_COUNTERS);
969
970  if ((error = gcov_close ()))
971    gcov_error (error  < 0 ?
972                "profiling:%s:Overflow writing\n" :
973                "profiling:%s:Error writing\n",
974                gi_filename);
975}
976
977/* Write imported files (auxiliary modules) for primary module GI_PTR
978   into file GI_FILENAME.  */
979
980static void
981gcov_write_import_file (char *gi_filename, struct gcov_info *gi_ptr)
982{
983  char  *gi_imports_filename;
984  const char *gcov_suffix;
985  FILE *imports_file;
986  size_t prefix_length, suffix_length;
987
988  gcov_suffix = getenv ("GCOV_IMPORTS_SUFFIX");
989  if (!gcov_suffix || !strlen (gcov_suffix))
990    gcov_suffix = ".imports";
991  suffix_length = strlen (gcov_suffix);
992  prefix_length = strlen (gi_filename);
993  gi_imports_filename = (char *) alloca (prefix_length + suffix_length + 1);
994  memset (gi_imports_filename, 0, prefix_length + suffix_length + 1);
995  memcpy (gi_imports_filename, gi_filename, prefix_length);
996  memcpy (gi_imports_filename + prefix_length, gcov_suffix, suffix_length);
997  imports_file = fopen (gi_imports_filename, "w");
998  if (imports_file)
999    {
1000      const struct dyn_imp_mod **imp_mods;
1001      unsigned i, imp_len;
1002      imp_mods = gcov_get_sorted_import_module_array (gi_ptr, &imp_len);
1003      if (imp_mods)
1004        {
1005          for (i = 0; i < imp_len; i++)
1006            {
1007              fprintf (imports_file, "%s\n",
1008                       imp_mods[i]->imp_mod->mod_info->source_filename);
1009              fprintf (imports_file, "%s%s\n",
1010                       imp_mods[i]->imp_mod->mod_info->da_filename, GCOV_DATA_SUFFIX);
1011            }
1012          free (imp_mods);
1013        }
1014      fclose (imports_file);
1015    }
1016}
1017
1018static void
1019gcov_dump_module_info (struct gcov_filename_aux *gf)
1020{
1021  struct gcov_info *gi_ptr;
1022
1023  /* Compute the module groups and record whether there were any
1024     counter fixups applied that require rewriting the counters.  */
1025  int changed = __gcov_compute_module_groups ();
1026
1027  /* Now write out module group info.  */
1028  for (gi_ptr = __gcov_list; gi_ptr; gi_ptr = gi_ptr->next)
1029    {
1030      int error;
1031
1032      if (gcov_exit_open_gcda_file (gi_ptr, gf) == -1)
1033	continue;
1034
1035      if (changed)
1036        {
1037          /* Scan file to find the end of the summary section, which is
1038             where we will start re-writing the counters.  */
1039          gcov_position_t summary_end_pos;
1040          if (gcov_scan_summary_end (gi_ptr, &summary_end_pos) == -1)
1041            gcov_error ("profiling:%s:Error scanning summaries\n",
1042                        gi_filename);
1043          else
1044            {
1045              gcov_position_t eof_pos = gi_ptr->eof_pos;
1046              gcov_rewrite ();
1047              gcov_seek (summary_end_pos);
1048              gcov_write_func_counters (gi_ptr);
1049              gcc_assert (eof_pos == gi_ptr->eof_pos);
1050            }
1051        }
1052      else
1053        gcov_rewrite ();
1054
1055      /* Overwrite the zero word at the of the file.  */
1056      gcov_seek (gi_ptr->eof_pos);
1057
1058      gcov_write_module_infos (gi_ptr);
1059      /* Write the end marker  */
1060      gcov_write_unsigned (0);
1061      gcov_truncate ();
1062
1063      if ((error = gcov_close ()))
1064        gcov_error (error  < 0 ?  "profiling:%s:Overflow writing\n" :
1065                                  "profiling:%s:Error writing\n",
1066                                  gi_filename);
1067      gcov_write_import_file (gi_filename, gi_ptr);
1068    }
1069  __gcov_finalize_dyn_callgraph ();
1070}
1071
1072/* Dump all the coverage counts for the program. It first computes program
1073   summary and then traverses gcov_list list and dumps the gcov_info
1074   objects one by one.  */
1075
1076void
1077gcov_exit (void)
1078{
1079  struct gcov_info *gi_ptr;
1080  struct gcov_filename_aux gf;
1081  gcov_unsigned_t crc32;
1082  int dump_module_info = 0;
1083  struct gcov_summary all_prg;
1084  struct gcov_summary this_prg;
1085
1086  /* Prevent the counters from being dumped a second time on exit when the
1087     application already wrote out the profile using __gcov_dump().  */
1088  if (gcov_dump_complete)
1089    return;
1090
1091  crc32 = gcov_exit_compute_summary (&this_prg);
1092
1093  allocate_filename_struct (&gf);
1094#if !GCOV_LOCKED
1095  memset (&all_prg, 0, sizeof (all_prg));
1096#endif
1097
1098  /* Now merge each file.  */
1099  for (gi_ptr = __gcov_list; gi_ptr; gi_ptr = gi_ptr->next)
1100    {
1101      gcov_exit_dump_gcov (gi_ptr, &gf, crc32, &all_prg, &this_prg);
1102
1103      /* The IS_PRIMARY field is overloaded to indicate if this module
1104       is FDO/LIPO.  */
1105      dump_module_info |= gi_ptr->mod_info->is_primary;
1106    }
1107  run_accounted = 1;
1108
1109  if (dump_module_info)
1110    gcov_dump_module_info (&gf);
1111
1112  if (gi_filename)
1113    free (gi_filename);
1114}
1115
1116/* Reset all counters to zero.  */
1117
1118void
1119gcov_clear (void)
1120{
1121  const struct gcov_info *gi_ptr;
1122
1123  for (gi_ptr = __gcov_list; gi_ptr; gi_ptr = gi_ptr->next)
1124    {
1125      unsigned f_ix;
1126
1127      for (f_ix = 0; f_ix < gi_ptr->n_functions; f_ix++)
1128        {
1129          unsigned t_ix;
1130          const struct gcov_fn_info *gfi_ptr = gi_ptr->functions[f_ix];
1131
1132          if (!gfi_ptr || gfi_ptr->key != gi_ptr)
1133            continue;
1134          const struct gcov_ctr_info *ci_ptr = gfi_ptr->ctrs;
1135          for (t_ix = 0; t_ix != GCOV_COUNTERS; t_ix++)
1136            {
1137              if (!gi_ptr->merge[t_ix])
1138                continue;
1139
1140              memset (ci_ptr->values, 0, sizeof (gcov_type) * ci_ptr->num);
1141              ci_ptr++;
1142            }
1143        }
1144    }
1145}
1146
1147/* Add a new object file onto the bb chain.  Invoked automatically
1148  when running an object file's global ctors.  */
1149
1150void
1151__gcov_init (struct gcov_info *info)
1152{
1153#ifndef IN_GCOV_TOOL
1154   if (!gcov_sampling_period_initialized)
1155    {
1156      const char* env_value_str = getenv ("GCOV_SAMPLING_PERIOD");
1157      if (env_value_str)
1158        {
1159          int env_value_int = atoi(env_value_str);
1160          if (env_value_int >= 1)
1161            __gcov_sampling_period = env_value_int;
1162        }
1163      gcov_sampling_period_initialized = 1;
1164    }
1165#endif
1166
1167  if (!info->version || !info->n_functions)
1168    return;
1169  if (gcov_version (info, info->version, 0))
1170    {
1171      size_t filename_length = strlen(info->filename);
1172
1173      /* Refresh the longest file name information */
1174      if (filename_length > gcov_max_filename)
1175        gcov_max_filename = filename_length;
1176
1177      /* Assign the module ID (starting at 1).  */
1178      info->mod_info->ident = (++gcov_cur_module_id);
1179      gcc_assert (EXTRACT_MODULE_ID_FROM_GLOBAL_ID (GEN_FUNC_GLOBAL_ID (
1180                                                       info->mod_info->ident, 0))
1181                  == info->mod_info->ident);
1182
1183      if (!__gcov_list)
1184        atexit (gcov_exit);
1185
1186      info->next = __gcov_list;
1187      __gcov_list = info;
1188    }
1189  info->version = 0;
1190}
1191
1192#endif /* L_gcov */
1193#endif /* inhibit_libc */
1194