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