Home | History | Annotate | Download | only in gcov-src
      1 /* Routines required for instrumenting a program.  */
      2 /* Compile this one with gcc.  */
      3 /* Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
      4    2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009, 2010
      5    Free Software Foundation, Inc.
      6 
      7 This file is part of GCC.
      8 
      9 GCC is free software; you can redistribute it and/or modify it under
     10 the terms of the GNU General Public License as published by the Free
     11 Software Foundation; either version 3, or (at your option) any later
     12 version.
     13 
     14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
     15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
     16 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     17 for more details.
     18 
     19 Under Section 7 of GPL version 3, you are granted additional
     20 permissions described in the GCC Runtime Library Exception, version
     21 3.1, as published by the Free Software Foundation.
     22 
     23 You should have received a copy of the GNU General Public License and
     24 a copy of the GCC Runtime Library Exception along with this program;
     25 see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
     26 <http://www.gnu.org/licenses/>.  */
     27 
     28 /* Assume compiling for Linux Kernel if __KERNEL__ is defined.  */
     29 #ifdef __KERNEL__
     30  /* Define MACROs to be used by kernel compilation.  */
     31 # define L_gcov
     32 # define L_gcov_interval_profiler
     33 # define L_gcov_pow2_profiler
     34 # define L_gcov_one_value_profiler
     35 # define L_gcov_indirect_call_profiler
     36 # define L_gcov_average_profiler
     37 # define L_gcov_ior_profiler
     38 
     39 # define HAVE_CC_TLS 0
     40 # define __GCOV_KERNEL__
     41 
     42 # define IN_LIBGCOV 1
     43 # define IN_GCOV 0
     44 #else /* __KERNEL__ */
     45 #include "tconfig.h"
     46 #include "tsystem.h"
     47 #include "coretypes.h"
     48 #include "tm.h"
     49 #endif /* __KERNEL__ */
     50 
     51 #if 1
     52 #define THREAD_PREFIX __thread
     53 #else
     54 #define THREAD_PREFIX
     55 #endif
     56 
     57 #ifndef __GCOV_KERNEL__
     58 #if defined(inhibit_libc)
     59 #define IN_LIBGCOV (-1)
     60 #else
     61 #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch.  */
     62 #include <stdio.h>
     63 #define IN_LIBGCOV 1
     64 #if defined(L_gcov)
     65 #define GCOV_LINKAGE /* nothing */
     66 #endif
     67 #endif
     68 #endif /* __GCOV_KERNEL__ */
     69 
     70 #include "gcov-io.h"
     71 
     72 #if defined(inhibit_libc)
     73 /* If libc and its header files are not available, provide dummy functions.  */
     74 
     75 #ifdef L_gcov
     76 void __gcov_init (struct gcov_info *p __attribute__ ((unused))) {}
     77 void __gcov_flush (void) {}
     78 #endif
     79 
     80 #ifdef L_gcov_merge_add
     81 void __gcov_merge_add (gcov_type *counters  __attribute__ ((unused)),
     82 		       unsigned n_counters __attribute__ ((unused))) {}
     83 #endif
     84 
     85 #ifdef L_gcov_merge_single
     86 void __gcov_merge_single (gcov_type *counters  __attribute__ ((unused)),
     87 			  unsigned n_counters __attribute__ ((unused))) {}
     88 #endif
     89 
     90 #ifdef L_gcov_merge_delta
     91 void __gcov_merge_delta (gcov_type *counters  __attribute__ ((unused)),
     92 			 unsigned n_counters __attribute__ ((unused))) {}
     93 #endif
     94 
     95 #else
     96 
     97 #ifndef __GCOV_KERNEL__
     98 #include <string.h>
     99 #if GCOV_LOCKED
    100 #include <fcntl.h>
    101 #include <errno.h>
    102 #include <sys/stat.h>
    103 #endif
    104 #endif /* __GCOV_KERNEL__ */
    105 
    106 #ifdef L_gcov
    107 #include "gcov-io.c"
    108 
    109 /* Utility function for outputing errors.  */
    110 static int
    111 gcov_error (const char *fmt, ...)
    112 {
    113   int ret;
    114   va_list argp;
    115   va_start (argp, fmt);
    116 #ifdef __GCOV_KERNEL__
    117   ret = vprintk (fmt, argp);
    118 #else
    119   ret = vfprintf (stderr, fmt, argp);
    120 #endif
    121   va_end (argp);
    122   return ret;
    123 }
    124 
    125 #ifndef __GCOV_KERNEL__
    126 /* Emitted in coverage.c.  */
    127 extern char * __gcov_pmu_profile_filename;
    128 extern char * __gcov_pmu_profile_options;
    129 extern gcov_unsigned_t __gcov_pmu_top_n_address;
    130 
    131 /* Sampling rate.  */
    132 extern gcov_unsigned_t __gcov_sampling_rate;
    133 static int gcov_sampling_rate_initialized = 0;
    134 void __gcov_set_sampling_rate (unsigned int rate);
    135 
    136 /* Set sampling rate to RATE.  */
    137 
    138 void __gcov_set_sampling_rate (unsigned int rate)
    139 {
    140   __gcov_sampling_rate = rate;
    141 }
    142 
    143 /* Per thread sample counter.  */
    144 THREAD_PREFIX gcov_unsigned_t __gcov_sample_counter = 0;
    145 
    146 /* Chain of per-object gcov structures.  */
    147 extern struct gcov_info *__gcov_list;
    148 
    149 /* Size of the longest file name. */
    150 static size_t gcov_max_filename = 0;
    151 #endif /* __GCOV_KERNEL__ */
    152 
    153 /* Unique identifier assigned to each module (object file).  */
    154 static gcov_unsigned_t gcov_cur_module_id = 0;
    155 
    156 /* Pointer to the direct-call counters (per call-site counters).
    157    Initialized by the caller.  */
    158 THREAD_PREFIX gcov_type *__gcov_direct_call_counters ATTRIBUTE_HIDDEN;
    159 
    160 /* Direct call callee address.  */
    161 THREAD_PREFIX void *__gcov_direct_call_callee ATTRIBUTE_HIDDEN;
    162 
    163 /* Pointer to the indirect-call counters (per call-site counters).
    164    Initialized by the caller.  */
    165 THREAD_PREFIX gcov_type *__gcov_indirect_call_topn_counters ATTRIBUTE_HIDDEN;
    166 
    167 /* Indirect call callee address.  */
    168 THREAD_PREFIX void *__gcov_indirect_call_topn_callee ATTRIBUTE_HIDDEN;
    169 
    170 /* A program checksum allows us to distinguish program data for an
    171    object file included in multiple programs.  */
    172 static gcov_unsigned_t gcov_crc32;
    173 
    174 /* Dynamic call graph build and form module groups.  */
    175 void __gcov_compute_module_groups (void) ATTRIBUTE_HIDDEN;
    176 void __gcov_finalize_dyn_callgraph (void) ATTRIBUTE_HIDDEN;
    177 
    178 /* Profile summary for the gdca file, used in sanity check?  */
    179 static struct gcov_summary all;
    180 
    181 /* Profile summary for this program in current exeuction.  */
    182 static struct gcov_summary this_program;
    183 
    184 /* Profile summary for this object in current execuction.  */
    185 static struct gcov_summary this_object;
    186 
    187 /* Merged profile summary for this program.  */
    188 static struct gcov_summary program;
    189 
    190 /* Merged profile summary for this object.  */
    191 static struct gcov_summary object;
    192 
    193 /* Record the position of summary info.  */
    194 static gcov_position_t summary_pos = 0;
    195 
    196 /* Record the postion of eof.  */
    197 static gcov_position_t eof_pos = 0;
    198 
    199 /* Number of chars in prefix to be stripped.  */
    200 static int gcov_prefix_strip = 0;
    201 
    202 /* The length of path prefix.  */
    203 static size_t prefix_length = 0;
    204 
    205 /* gi_filename is current object filename.
    206    gi_filename_up points to the stripped filename.  */
    207 static char *gi_filename, *gi_filename_up;
    208 
    209 static int gcov_open_by_filename (char * gi_filename);
    210 static int gcov_exit_init (void);
    211 static void gcov_dump_one_gcov (struct gcov_info *gi_ptr);
    212 
    213 /* Make sure path component of the given FILENAME exists, create
    214    missing directories. FILENAME must be writable.
    215    Returns zero on success, or -1 if an error occurred.  */
    216 
    217 static int
    218 create_file_directory (char *filename)
    219 {
    220 #if !defined(TARGET_POSIX_IO) && !defined(_WIN32)
    221   (void) filename;
    222   return -1;
    223 #else
    224   char *s;
    225 
    226   s = filename;
    227 
    228   if (HAS_DRIVE_SPEC(s))
    229     s += 2;
    230   if (IS_DIR_SEPARATOR(*s))
    231     ++s;
    232   for (; *s != '\0'; s++)
    233     if (IS_DIR_SEPARATOR(*s))
    234       {
    235         char sep = *s;
    236 	*s  = '\0';
    237 
    238         /* Try to make directory if it doesn't already exist.  */
    239         if (access (filename, F_OK) == -1
    240 #ifdef TARGET_POSIX_IO
    241             && mkdir (filename, 0755) == -1
    242 #else
    243             && mkdir (filename) == -1
    244 #endif
    245             /* The directory might have been made by another process.  */
    246 	    && errno != EEXIST)
    247 	  {
    248             fprintf (stderr, "profiling:%s:Cannot create directory\n",
    249 		     filename);
    250             *s = sep;
    251 	    return -1;
    252 	  };
    253 
    254 	*s = sep;
    255       };
    256   return 0;
    257 #endif
    258 }
    259 
    260 /* Open a file with the specified name.  */
    261 
    262 static int
    263 gcov_open_by_filename (char * gi_filename)
    264 {
    265   if (!gcov_open (gi_filename))
    266     {
    267       /* Open failed likely due to missed directory.
    268          Create directory and retry to open file.  */
    269       if (create_file_directory (gi_filename))
    270         {
    271           gcov_error ("profiling:%s:Skip\n", gi_filename);
    272           return -1;
    273         }
    274       if (!gcov_open (gi_filename))
    275         {
    276           gcov_error ("profiling:%s:Cannot open\n", gi_filename);
    277           return -1;
    278         }
    279     }
    280   return 0;
    281 }
    282 
    283 
    284 /* Determine whether a counter is active.  */
    285 
    286 static inline int
    287 gcov_counter_active (const struct gcov_info *info, unsigned int type)
    288 {
    289   return (1 << type) & info->ctr_mask;
    290 }
    291 
    292 #ifndef __GCOV_KERNEL__
    293 /* Check if VERSION of the info block PTR matches libgcov one.
    294    Return 1 on success, or zero in case of versions mismatch.
    295    If FILENAME is not NULL, its value used for reporting purposes
    296    instead of value from the info block.  */
    297 
    298 static int
    299 gcov_version (struct gcov_info *ptr __attribute__ ((unused)),
    300               gcov_unsigned_t version, const char *filename)
    301 {
    302   if (version != GCOV_VERSION)
    303     {
    304       char v[4], e[4];
    305 
    306       GCOV_UNSIGNED2STRING (v, version);
    307       GCOV_UNSIGNED2STRING (e, GCOV_VERSION);
    308 
    309       if (filename)
    310         gcov_error ("profiling:%s:Version mismatch - expected %.4s got %.4s\n",
    311                    filename, e, v);
    312       else
    313         gcov_error ("profiling:Version mismatch - expected %.4s got %.4s\n", e, v);
    314       return 0;
    315     }
    316   return 1;
    317 }
    318 
    319 #define GCOV_GET_FILENAME gcov_strip_leading_dirs
    320 
    321 /* Strip GCOV_PREFIX_STRIP levels of leading '/' from FILENAME and
    322    put the result into GI_FILENAME_UP.  */
    323 
    324 static void
    325 gcov_strip_leading_dirs (int prefix_length, int gcov_prefix_strip,
    326 			 const char *filename, char *gi_filename_up)
    327 {
    328   /* Avoid to add multiple drive letters into combined path.  */
    329   if (prefix_length != 0 && HAS_DRIVE_SPEC(filename))
    330     filename += 2;
    331 
    332   /* Build relocated filename, stripping off leading
    333      directories from the initial filename if requested. */
    334   if (gcov_prefix_strip > 0)
    335     {
    336       int level = 0;
    337       const char *s = filename;
    338       if (IS_DIR_SEPARATOR(*s))
    339 	++s;
    340 
    341       /* Skip selected directory levels. */
    342       for (; (*s != '\0') && (level < gcov_prefix_strip); s++)
    343         if (IS_DIR_SEPARATOR(*s))
    344           {
    345             filename = s;
    346             level++;
    347           }
    348     }
    349   /* Update complete filename with stripped original. */
    350   if (prefix_length != 0 && !IS_DIR_SEPARATOR (*filename))
    351     {
    352       /* If prefix is given, add directory separator.  */
    353       strcpy (gi_filename_up, "/");
    354       strcpy (gi_filename_up + 1, filename);
    355     }
    356   else
    357     strcpy (gi_filename_up, filename);
    358 }
    359 
    360 /* This function allocates the space to store current file name.  */
    361 
    362 static void
    363 gcov_alloc_filename (void)
    364 {
    365   /* Get file name relocation prefix.  Non-absolute values are ignored.  */
    366   char *gcov_prefix = 0;
    367 
    368   prefix_length = 0;
    369   gcov_prefix_strip = 0;
    370 
    371   {
    372     /* Check if the level of dirs to strip off specified. */
    373     char *tmp = getenv ("GCOV_PREFIX_STRIP");
    374     if (tmp)
    375       {
    376         gcov_prefix_strip = atoi (tmp);
    377         /* Do not consider negative values. */
    378         if (gcov_prefix_strip < 0)
    379           gcov_prefix_strip = 0;
    380       }
    381   }
    382   /* Get file name relocation prefix.  Non-absolute values are ignored. */
    383   gcov_prefix = getenv ("GCOV_PREFIX");
    384   if (gcov_prefix)
    385     {
    386       prefix_length = strlen(gcov_prefix);
    387 
    388       /* Remove an unnecessary trailing '/' */
    389       if (IS_DIR_SEPARATOR (gcov_prefix[prefix_length - 1]))
    390         prefix_length--;
    391     }
    392   else
    393     prefix_length = 0;
    394 
    395   /* If no prefix was specified and a prefix stip, then we assume
    396      relative.  */
    397   if (gcov_prefix_strip != 0 && prefix_length == 0)
    398     {
    399       gcov_prefix = ".";
    400       prefix_length = 1;
    401     }
    402 
    403   /* Allocate and initialize the filename scratch space.  */
    404   gi_filename = (char *) malloc (prefix_length + gcov_max_filename + 2);
    405   if (prefix_length)
    406     memcpy (gi_filename, gcov_prefix, prefix_length);
    407 
    408   gi_filename_up = gi_filename + prefix_length;
    409 }
    410 
    411 /* Stop the pmu profiler and dump pmu profile info into the global file.  */
    412 
    413 static void
    414 pmu_profile_stop (void)
    415 {
    416   const char *pmu_profile_filename =  __gcov_pmu_profile_filename;
    417   const char *pmu_options = __gcov_pmu_profile_options;
    418   size_t filename_length;
    419   int gcda_error;
    420 
    421   if (!pmu_profile_filename || !pmu_options)
    422     return;
    423 
    424   __gcov_stop_pmu_profiler ();
    425 
    426   filename_length = strlen (pmu_profile_filename);
    427   if (filename_length > gcov_max_filename)
    428     gcov_max_filename = filename_length;
    429   /* Allocate and initialize the filename scratch space.  */
    430   gcov_alloc_filename ();
    431   GCOV_GET_FILENAME (prefix_length, gcov_prefix_strip, pmu_profile_filename,
    432                      gi_filename_up);
    433   /* Open the gcda file for writing. We don't support merge yet.  */
    434   gcda_error = gcov_open_by_filename (gi_filename);
    435   __gcov_end_pmu_profiler (gcda_error);
    436   if ((gcda_error = gcov_close ()))
    437     gcov_error (gcda_error  < 0 ?  "pmu_profile_stop:%s:Overflow writing\n" :
    438                 "pmu_profile_stop:%s:Error writing\n",
    439                 gi_filename);
    440 }
    441 
    442 /* Sort N entries in VALUE_ARRAY in descending order.
    443    Each entry in VALUE_ARRAY has two values. The sorting
    444    is based on the second value.  */
    445 
    446 GCOV_LINKAGE  void
    447 gcov_sort_n_vals (gcov_type *value_array, int n)
    448 {
    449   int j, k;
    450   for (j = 2; j < n; j += 2)
    451     {
    452       gcov_type cur_ent[2];
    453       cur_ent[0] = value_array[j];
    454       cur_ent[1] = value_array[j + 1];
    455       k = j - 2;
    456       while (k >= 0 && value_array[k + 1] < cur_ent[1])
    457         {
    458           value_array[k + 2] = value_array[k];
    459           value_array[k + 3] = value_array[k+1];
    460           k -= 2;
    461         }
    462       value_array[k + 2] = cur_ent[0];
    463       value_array[k + 3] = cur_ent[1];
    464     }
    465 }
    466 
    467 /* Sort the profile counters for all indirect call sites. Counters
    468    for each call site are allocated in array COUNTERS.  */
    469 
    470 static void
    471 gcov_sort_icall_topn_counter (const struct gcov_ctr_info *counters)
    472 {
    473   int i;
    474   gcov_type *values;
    475   int n = counters->num;
    476   gcc_assert (!(n % GCOV_ICALL_TOPN_NCOUNTS));
    477 
    478   values = counters->values;
    479 
    480   for (i = 0; i < n; i += GCOV_ICALL_TOPN_NCOUNTS)
    481     {
    482       gcov_type *value_array = &values[i + 1];
    483       gcov_sort_n_vals (value_array, GCOV_ICALL_TOPN_NCOUNTS - 1);
    484     }
    485 }
    486 
    487 /* Write imported files (auxiliary modules) for primary module GI_PTR
    488    into file GI_FILENAME.  */
    489 
    490 static void
    491 gcov_write_import_file (char *gi_filename, struct gcov_info *gi_ptr)
    492 {
    493   char  *gi_imports_filename;
    494   const char *gcov_suffix;
    495   FILE *imports_file;
    496   size_t prefix_length, suffix_length;
    497 
    498   gcov_suffix = getenv ("GCOV_IMPORTS_SUFFIX");
    499   if (!gcov_suffix || !strlen (gcov_suffix))
    500     gcov_suffix = ".imports";
    501   suffix_length = strlen (gcov_suffix);
    502   prefix_length = strlen (gi_filename);
    503   gi_imports_filename = (char *) alloca (prefix_length + suffix_length + 1);
    504   memset (gi_imports_filename, 0, prefix_length + suffix_length + 1);
    505   memcpy (gi_imports_filename, gi_filename, prefix_length);
    506   memcpy (gi_imports_filename + prefix_length, gcov_suffix, suffix_length);
    507   imports_file = fopen (gi_imports_filename, "w");
    508   if (imports_file)
    509     {
    510       const struct dyn_imp_mod **imp_mods;
    511       unsigned i, imp_len;
    512       imp_mods = gcov_get_sorted_import_module_array (gi_ptr, &imp_len);
    513       if (imp_mods)
    514         {
    515           for (i = 0; i < imp_len; i++)
    516 	    {
    517 	      fprintf (imports_file, "%s\n",
    518 		       imp_mods[i]->imp_mod->mod_info->source_filename);
    519 	      fprintf (imports_file, "%s%s\n",
    520 		       imp_mods[i]->imp_mod->mod_info->da_filename, GCOV_DATA_SUFFIX);
    521 	    }
    522           free (imp_mods);
    523         }
    524       fclose (imports_file);
    525     }
    526 }
    527 
    528 static void
    529 gcov_dump_module_info (void)
    530 {
    531   struct gcov_info *gi_ptr;
    532 
    533   __gcov_compute_module_groups ();
    534 
    535   /* Now write out module group info.  */
    536   for (gi_ptr = __gcov_list; gi_ptr; gi_ptr = gi_ptr->next)
    537   {
    538     int error;
    539 
    540     GCOV_GET_FILENAME (prefix_length, gcov_prefix_strip, gi_ptr->filename,
    541                        gi_filename_up);
    542     error = gcov_open_by_filename (gi_filename);
    543     if (error != 0)
    544       continue;
    545 
    546     /* Overwrite the zero word at the of the file.  */
    547     gcov_rewrite ();
    548     gcov_seek (gi_ptr->eof_pos);
    549 
    550     gcov_write_module_infos (gi_ptr);
    551     gcov_truncate ();
    552 
    553     if ((error = gcov_close ()))
    554          gcov_error (error  < 0 ?  "profiling:%s:Overflow writing\n" :
    555                                    "profiling:%s:Error writing\n",
    556                                    gi_filename);
    557     gcov_write_import_file (gi_filename, gi_ptr);
    558   }
    559   __gcov_finalize_dyn_callgraph ();
    560 }
    561 
    562 /* Dump the coverage counts. We merge with existing counts when
    563    possible, to avoid growing the .da files ad infinitum. We use this
    564    program's checksum to make sure we only accumulate whole program
    565    statistics to the correct summary. An object file might be embedded
    566    in two separate programs, and we must keep the two program
    567    summaries separate.  */
    568 
    569 static void
    570 gcov_exit (void)
    571 {
    572   struct gcov_info *gi_ptr;
    573   int dump_module_info;
    574 
    575   /* Stop and write the PMU profile data into the global file.  */
    576   pmu_profile_stop ();
    577 
    578   dump_module_info = gcov_exit_init ();
    579 
    580   for (gi_ptr = __gcov_list; gi_ptr; gi_ptr = gi_ptr->next)
    581     gcov_dump_one_gcov (gi_ptr);
    582 
    583   if (dump_module_info)
    584     gcov_dump_module_info ();
    585 
    586   free (gi_filename);
    587 }
    588 
    589 /* Add a new object file onto the bb chain.  Invoked automatically
    590    when running an object file's global ctors.  */
    591 
    592 void
    593 __gcov_init (struct gcov_info *info)
    594 {
    595   if (!gcov_sampling_rate_initialized)
    596     {
    597       const char* env_value_str = getenv ("GCOV_SAMPLING_RATE");
    598       if (env_value_str)
    599         {
    600           int env_value_int = atoi(env_value_str);
    601           if (env_value_int >= 1)
    602             __gcov_sampling_rate = env_value_int;
    603         }
    604       gcov_sampling_rate_initialized = 1;
    605     }
    606 
    607   if (!info->version)
    608     return;
    609 
    610   if (gcov_version (info, info->version, 0))
    611     {
    612       const char *ptr = info->filename;
    613       gcov_unsigned_t crc32 = gcov_crc32;
    614       size_t filename_length = strlen (info->filename);
    615       struct gcov_pmu_info pmu_info;
    616 
    617       /* Refresh the longest file name information.  */
    618       if (filename_length > gcov_max_filename)
    619         gcov_max_filename = filename_length;
    620 
    621       /* Initialize the pmu profiler.  */
    622       pmu_info.pmu_profile_filename = __gcov_pmu_profile_filename;
    623       pmu_info.pmu_tool = __gcov_pmu_profile_options;
    624       pmu_info.pmu_top_n_address = __gcov_pmu_top_n_address;
    625       __gcov_init_pmu_profiler (&pmu_info);
    626       if (pmu_info.pmu_profile_filename)
    627         {
    628           /* Refresh the longest file name information.  */
    629           filename_length = strlen (pmu_info.pmu_profile_filename);
    630           if (filename_length > gcov_max_filename)
    631             gcov_max_filename = filename_length;
    632         }
    633 
    634       /* Assign the module ID (starting at 1).  */
    635       info->mod_info->ident = (++gcov_cur_module_id);
    636       gcc_assert (EXTRACT_MODULE_ID_FROM_GLOBAL_ID (GEN_FUNC_GLOBAL_ID (
    637                                                        info->mod_info->ident, 0))
    638                   == info->mod_info->ident);
    639 
    640       do
    641 	{
    642 	  unsigned ix;
    643 	  gcov_unsigned_t value = *ptr << 24;
    644 
    645 	  for (ix = 8; ix--; value <<= 1)
    646 	    {
    647 	      gcov_unsigned_t feedback;
    648 
    649 	      feedback = (value ^ crc32) & 0x80000000 ? 0x04c11db7 : 0;
    650 	      crc32 <<= 1;
    651 	      crc32 ^= feedback;
    652 	    }
    653 	} while (*ptr++);
    654 
    655       gcov_crc32 = crc32;
    656 
    657       if (!__gcov_list)
    658         {
    659           atexit (gcov_exit);
    660           /* Start pmu profiler. */
    661           __gcov_start_pmu_profiler ();
    662         }
    663 
    664       info->next = __gcov_list;
    665       __gcov_list = info;
    666     }
    667   info->version = 0;
    668 }
    669 
    670 /* Called before fork or exec - write out profile information gathered so
    671    far and reset it to zero.  This avoids duplication or loss of the
    672    profile information gathered so far.  */
    673 
    674 void
    675 __gcov_flush (void)
    676 {
    677   const struct gcov_info *gi_ptr;
    678 
    679   __gcov_stop_pmu_profiler ();
    680   gcov_exit ();
    681   for (gi_ptr = __gcov_list; gi_ptr; gi_ptr = gi_ptr->next)
    682     {
    683       unsigned t_ix;
    684       const struct gcov_ctr_info *ci_ptr;
    685 
    686       for (t_ix = 0, ci_ptr = gi_ptr->counts; t_ix != GCOV_COUNTERS; t_ix++)
    687         if (gcov_counter_active (gi_ptr, t_ix))
    688 	  {
    689 	    memset (ci_ptr->values, 0, sizeof (gcov_type) * ci_ptr->num);
    690 	    ci_ptr++;
    691 	  }
    692     }
    693   __gcov_start_pmu_profiler ();
    694 }
    695 
    696 #else /* __GCOV_KERNEL__ */
    697 
    698 #define GCOV_GET_FILENAME gcov_get_filename
    699 
    700 /* Copy the filename to the buffer.  */
    701 
    702 static inline void
    703 gcov_get_filename (int prefix_length __attribute__ ((unused)),
    704                    int gcov_prefix_strip __attribute__ ((unused)),
    705                    const char *filename, char *gi_filename_up)
    706 {
    707     strcpy (gi_filename_up, filename);
    708 }
    709 
    710 /* Sort the profile counters for all indirect call sites. Counters
    711    for each call site are allocated in array COUNTERS.  */
    712 
    713 static void
    714 gcov_sort_icall_topn_counter (const struct gcov_ctr_info *counters)
    715 {
    716   /* Empty */
    717 }
    718 
    719 /* Reserves a buffer to store the name of the file being processed.  */
    720 static char _kernel_gi_filename[520];
    721 
    722 /* This function allocates the space to store current file name.  */
    723 
    724 static void
    725 gcov_alloc_filename (void)
    726 {
    727   prefix_length = 0;
    728   gcov_prefix_strip = 0;
    729   gi_filename = _kernel_gi_filename;
    730   gi_filename_up = _kernel_gi_filename;
    731 }
    732 
    733 #endif /* __GCOV_KERNEL__ */
    734 
    735 /* Determine number of active counters in gcov_info INFO,
    736    the counter arrays are stored in VALUES if the coming
    737    value of VALUES !=0. If FLAG_SORT_ICALL_TOPN_COUNTER !=0,
    738    the icall_topn_counter in INFO will be sorted.
    739    Return: the number of active counter types.  */
    740 
    741 static unsigned int
    742 gcov_counter_array (const struct gcov_info *info,
    743                     gcov_type *values[GCOV_COUNTERS],
    744                     int flag_sort_icall_topn_counter)
    745 {
    746   unsigned int i;
    747   unsigned int result = 0;
    748 
    749   for (i = 0; i < GCOV_COUNTERS; i++) {
    750     if (gcov_counter_active (info, i))
    751       {
    752         if (values)
    753           values[result] = info->counts[result].values;
    754         if (flag_sort_icall_topn_counter &&
    755             (i == GCOV_COUNTER_ICALL_TOPNV))
    756           gcov_sort_icall_topn_counter (&info->counts[result]);
    757         result++;
    758       }
    759   }
    760   return result;
    761 }
    762 
    763 /* Compute object summary recored in gcov_info INFO. The result is
    764    stored in OBJ_SUM. Note that the caller is responsible for
    765    zeroing out OBJ_SUM, otherwise the summary is accumulated.  */
    766 
    767 static void
    768 gcov_object_summary (struct gcov_info *info,
    769                      struct gcov_summary *obj_sum)
    770 {
    771   const struct gcov_ctr_info *ci_ptr;
    772   struct gcov_ctr_summary *cs_ptr;
    773   gcov_unsigned_t c_num;
    774   unsigned t_ix;
    775 
    776   /* Totals for this object file.  */
    777   ci_ptr = info->counts;
    778   for (t_ix = 0; t_ix < GCOV_COUNTERS_SUMMABLE; t_ix++)
    779     {
    780       if (!gcov_counter_active (info, t_ix))
    781         continue;
    782 
    783       cs_ptr = &(obj_sum->ctrs[t_ix]);
    784       cs_ptr->num += ci_ptr->num;
    785       for (c_num = 0; c_num < ci_ptr->num; c_num++)
    786         {
    787           cs_ptr->sum_all += ci_ptr->values[c_num];
    788           if (cs_ptr->run_max < ci_ptr->values[c_num])
    789             cs_ptr->run_max = ci_ptr->values[c_num];
    790         }
    791       ci_ptr++;
    792     }
    793 }
    794 
    795 /* Merge with existing gcda file in the same directory to avoid
    796    excessive growthe of the files.  */
    797 
    798 static int
    799 gcov_merge_gcda_file (struct gcov_info *info,
    800                       gcov_type *values[GCOV_COUNTERS],
    801                       unsigned fi_stride)
    802 {
    803   struct gcov_ctr_summary *cs_obj, *cs_tobj, *cs_prg, *cs_tprg, *cs_all;
    804   unsigned t_ix, f_ix;
    805 
    806 #ifndef __GCOV_KERNEL__
    807   const struct gcov_fn_info *fi_ptr;
    808   unsigned c_ix, n_counts;
    809   int error = 0;
    810   gcov_unsigned_t tag, length;
    811 
    812   eof_pos = 0;
    813   summary_pos = 0;
    814 
    815   tag = gcov_read_unsigned ();
    816   if (tag)
    817     {
    818       /* Merge data from file.  */
    819       if (tag != GCOV_DATA_MAGIC)
    820         {
    821           gcov_error ("profiling:%s:Not a gcov data file\n", gi_filename);
    822           goto read_fatal;
    823         }
    824      length = gcov_read_unsigned ();
    825      if (!gcov_version (info, length, gi_filename))
    826        goto read_fatal;
    827 
    828      length = gcov_read_unsigned ();
    829      if (length != info->stamp)
    830        /* Read from a different compilation. Overwrite the file.  */
    831        goto rewrite;
    832 
    833      /* Merge execution counts for each function.  */
    834      for (f_ix = 0; f_ix < info->n_functions; f_ix++)
    835        {
    836          fi_ptr = (const struct gcov_fn_info *)
    837                    ((const char *) info->functions + f_ix * fi_stride);
    838          tag = gcov_read_unsigned ();
    839          length = gcov_read_unsigned ();
    840 
    841          /* Check function.  */
    842          if (tag != GCOV_TAG_FUNCTION
    843 	     || length != GCOV_TAG_FUNCTION_LENGTH
    844              || gcov_read_unsigned () != fi_ptr->ident
    845              || gcov_read_unsigned () != fi_ptr->lineno_checksum
    846              || gcov_read_unsigned () != fi_ptr->cfg_checksum)
    847            goto read_mismatch;
    848 
    849            c_ix = 0;
    850            for (t_ix = 0; t_ix < GCOV_COUNTERS; t_ix++)
    851              {
    852                gcov_merge_fn merge;
    853 
    854                if (!((1 << t_ix) & info->ctr_mask))
    855                  continue;
    856 
    857                n_counts = fi_ptr->n_ctrs[c_ix];
    858                merge = info->counts[c_ix].merge;
    859 
    860                tag = gcov_read_unsigned ();
    861                length = gcov_read_unsigned ();
    862                if (tag != GCOV_TAG_FOR_COUNTER (t_ix)
    863                    || length != GCOV_TAG_COUNTER_LENGTH (n_counts))
    864                  goto read_mismatch;
    865                (*merge) (values[c_ix], n_counts);
    866                values[c_ix] += n_counts;
    867                c_ix++;
    868              }
    869            if ((error = gcov_is_error ()))
    870              goto read_error;
    871        }
    872 
    873        f_ix = ~0u;
    874        /* Check program & object summary.  */
    875        while (1)
    876          {
    877            int is_program;
    878 
    879            eof_pos = gcov_position ();
    880            tag = gcov_read_unsigned ();
    881            if (!tag)
    882              break;
    883 
    884            length = gcov_read_unsigned ();
    885            is_program = tag == GCOV_TAG_PROGRAM_SUMMARY;
    886            if (length != GCOV_TAG_SUMMARY_LENGTH
    887                || (!is_program && tag != GCOV_TAG_OBJECT_SUMMARY))
    888              goto read_mismatch;
    889            gcov_read_summary (is_program ? &program : &object);
    890            if ((error = gcov_is_error ()))
    891              goto read_error;
    892            if (is_program && program.checksum == gcov_crc32)
    893              {
    894                summary_pos = eof_pos;
    895                goto rewrite;
    896              }
    897          }
    898     }
    899 
    900     goto rewrite;
    901 
    902 read_error:;
    903     gcov_error (error < 0 ? "profiling:%s:Overflow merging\n"
    904                 : "profiling:%s:Error merging\n", gi_filename);
    905     goto read_fatal;
    906 
    907 #endif /* __GCOV_KERNEL__ */
    908 
    909     goto rewrite;
    910 
    911 read_mismatch:;
    912     gcov_error ("profiling:%s:Merge mismatch for %s\n", gi_filename,
    913                  f_ix + 1 ? "function" : "summaries");
    914     goto read_fatal; /* work-around the compiler warning */
    915 
    916 read_fatal:;
    917     gcov_close ();
    918     return 1;
    919 
    920 rewrite:;
    921     gcov_rewrite ();
    922     if (!summary_pos)
    923       memset (&program, 0, sizeof (program));
    924 
    925     /* Merge the summaries.  */
    926     f_ix = ~0u;
    927     for (t_ix = 0; t_ix < GCOV_COUNTERS_SUMMABLE; t_ix++)
    928       {
    929         cs_obj = &object.ctrs[t_ix];
    930         cs_tobj = &this_object.ctrs[t_ix];
    931         cs_prg = &program.ctrs[t_ix];
    932         cs_tprg = &this_program.ctrs[t_ix];
    933         cs_all = &all.ctrs[t_ix];
    934 
    935         if ((1 << t_ix) & info->ctr_mask)
    936           {
    937             if (!cs_obj->runs++)
    938               cs_obj->num = cs_tobj->num;
    939             else if (cs_obj->num != cs_tobj->num)
    940                goto read_mismatch;
    941             cs_obj->sum_all += cs_tobj->sum_all;
    942             if (cs_obj->run_max < cs_tobj->run_max)
    943               cs_obj->run_max = cs_tobj->run_max;
    944             cs_obj->sum_max += cs_tobj->run_max;
    945 
    946             if (!cs_prg->runs++)
    947               cs_prg->num = cs_tprg->num;
    948             else if (cs_prg->num != cs_tprg->num)
    949               goto read_mismatch;
    950             cs_prg->sum_all += cs_tprg->sum_all;
    951             if (cs_prg->run_max < cs_tprg->run_max)
    952               cs_prg->run_max = cs_tprg->run_max;
    953             cs_prg->sum_max += cs_tprg->run_max;
    954           }
    955         else if (cs_obj->num || cs_prg->num)
    956           goto read_mismatch;
    957 
    958         if (!cs_all->runs && cs_prg->runs)
    959           memcpy (cs_all, cs_prg, sizeof (*cs_all));
    960         else if (!all.checksum
    961                  && (!GCOV_LOCKED || cs_all->runs == cs_prg->runs)
    962                  && memcmp (cs_all, cs_prg, sizeof (*cs_all)))
    963           {
    964             gcov_error ("profiling:%s:Invocation mismatch - "
    965                 "some data files may have been removed%s",
    966             gi_filename, GCOV_LOCKED
    967             ? "" : " or concurrent update without locking support");
    968             all.checksum = ~0u;
    969           }
    970       }
    971 
    972   return 0;
    973 }
    974 
    975 /* Calculate the function_info stride. This depends on the
    976    number of counter types being measured.
    977    NUM_COUNTER_TYPES is number of counter types recorded.
    978    Return: the number of bytes for accessing next fn_info
    979    (aligned to gcov_fn_info).  */
    980 
    981 static unsigned
    982 gcov_compute_fi_stride (unsigned num_counter_types)
    983 {
    984    unsigned fi_stride;
    985 
    986    fi_stride = offsetof (struct gcov_fn_info, n_ctrs) +
    987                num_counter_types * sizeof (unsigned);
    988    if (__alignof__ (struct gcov_fn_info) > sizeof (unsigned))
    989    {
    990      fi_stride += __alignof__ (struct gcov_fn_info) - 1;
    991      fi_stride &= ~(__alignof__ (struct gcov_fn_info) - 1);
    992    }
    993    return fi_stride;
    994 }
    995 
    996 /* This function returns the size of gcda file to be written. Note
    997    the size is in units of gcov_type.  */
    998 
    999 GCOV_LINKAGE unsigned
   1000 gcov_gcda_file_size (struct gcov_info *gi_ptr)
   1001 {
   1002   unsigned size;
   1003   const struct gcov_fn_info *fi_ptr;
   1004   unsigned f_ix, t_ix, c_ix;
   1005   unsigned n_counts;
   1006   unsigned fi_stride;
   1007   gcov_type *values[GCOV_COUNTERS];
   1008 
   1009   c_ix = gcov_counter_array (gi_ptr, values, 0);
   1010   fi_stride = gcov_compute_fi_stride (c_ix);
   1011 
   1012   /* GCOV_DATA_MAGIC, GCOV_VERSION and time_stamp.  */
   1013   size = 3;
   1014 
   1015   /* size for each function.  */
   1016   for (f_ix = 0; f_ix < gi_ptr->n_functions; f_ix++)
   1017     {
   1018       fi_ptr = (const struct gcov_fn_info *)
   1019         ((const char *) gi_ptr->functions + f_ix * fi_stride);
   1020 
   1021       size += 2 /* tag_length itself */
   1022               + GCOV_TAG_FUNCTION_LENGTH; /* ident, lineno_cksum, cfg_cksm */
   1023 
   1024       c_ix = 0;
   1025       for (t_ix = 0; t_ix < GCOV_COUNTERS; t_ix++)
   1026         {
   1027           if (!((1 << t_ix) & gi_ptr->ctr_mask))
   1028             continue;
   1029 
   1030           n_counts = fi_ptr->n_ctrs[c_ix];
   1031           size += 2 + GCOV_TAG_COUNTER_LENGTH (n_counts);
   1032           c_ix++;
   1033         }
   1034     }
   1035 
   1036   /* Object summary.  */
   1037   size += 2 + GCOV_TAG_SUMMARY_LENGTH;
   1038 
   1039   /* Program summary.  */
   1040   size += 2 + GCOV_TAG_SUMMARY_LENGTH;
   1041 
   1042   size += 1;
   1043 
   1044   return size*4;
   1045 }
   1046 
   1047 /* Write profile data (including summary and module grouping information,
   1048    if available, to file.  */
   1049 
   1050 static void
   1051 gcov_write_gcda_file (struct gcov_info *gi_ptr,
   1052                       unsigned fi_stride)
   1053 {
   1054       const struct gcov_fn_info *fi_ptr;
   1055       gcov_type *values[GCOV_COUNTERS];
   1056       unsigned t_ix, c_ix, f_ix, n_counts;
   1057       int error = 0;
   1058 
   1059       /* Write out the data.  */
   1060       gcov_write_tag_length (GCOV_DATA_MAGIC, GCOV_VERSION);
   1061       gcov_write_unsigned (gi_ptr->stamp);
   1062 
   1063       gcov_counter_array (gi_ptr, values, 0);
   1064 
   1065       /* Write execution counts for each function.  */
   1066       for (f_ix = 0; f_ix < gi_ptr->n_functions; f_ix++)
   1067         {
   1068 	  fi_ptr = (const struct gcov_fn_info *)
   1069 		  ((const char *) gi_ptr->functions + f_ix * fi_stride);
   1070 
   1071 	  /* Announce function.  */
   1072 	  gcov_write_tag_length (GCOV_TAG_FUNCTION, GCOV_TAG_FUNCTION_LENGTH);
   1073 	  gcov_write_unsigned (fi_ptr->ident);
   1074 	  gcov_write_unsigned (fi_ptr->lineno_checksum);
   1075 	  gcov_write_unsigned (fi_ptr->cfg_checksum);
   1076 
   1077 	  c_ix = 0;
   1078 	  for (t_ix = 0; t_ix < GCOV_COUNTERS; t_ix++)
   1079 	    {
   1080 	      gcov_type *c_ptr;
   1081 
   1082 	      if (!((1 << t_ix) & gi_ptr->ctr_mask))
   1083 		continue;
   1084 
   1085 	      n_counts = fi_ptr->n_ctrs[c_ix];
   1086 
   1087 	      gcov_write_tag_length (GCOV_TAG_FOR_COUNTER (t_ix),
   1088 				     GCOV_TAG_COUNTER_LENGTH (n_counts));
   1089 	      c_ptr = values[c_ix];
   1090 	      while (n_counts--)
   1091 		gcov_write_counter (*c_ptr++);
   1092 
   1093 	      values[c_ix] = c_ptr;
   1094 	      c_ix++;
   1095 	    }
   1096         }
   1097 
   1098       /* Object file summary.  */
   1099       gcov_write_summary (GCOV_TAG_OBJECT_SUMMARY, &object);
   1100 
   1101       /* Generate whole program statistics.  */
   1102       program.checksum = gcov_crc32;
   1103       if (eof_pos)
   1104 	gcov_seek (eof_pos);
   1105       gcov_write_summary (GCOV_TAG_PROGRAM_SUMMARY, &program);
   1106       if (!summary_pos)
   1107 	gcov_write_unsigned (0);
   1108 
   1109       /* TODO: there is a problem here -- if there are other program
   1110          summary data after the matching one, setting eof_pos to this
   1111          position means that the module info table will overwrite the
   1112          those other program summary. It also means a mismatch error
   1113          may occur at the next merge if no matching program summary is
   1114          found before the module info data.  */
   1115       if (!summary_pos)
   1116         gi_ptr->eof_pos = gcov_position () - 1;
   1117       else
   1118         gi_ptr->eof_pos = gcov_position ();
   1119 
   1120       if ((error = gcov_close ()))
   1121 	  gcov_error (error  < 0 ?
   1122 		   "profiling:%s:Overflow writing\n" :
   1123 		   "profiling:%s:Error writing\n",
   1124 		   gi_filename);
   1125 }
   1126 
   1127 /* Do some preparation work before calling the actual dumping
   1128    routine.
   1129    Return: 1 when module grouping info needs to be dumped,
   1130            0 otherwise.  */
   1131 
   1132 static int
   1133 gcov_exit_init (void)
   1134 {
   1135   struct gcov_info *gi_ptr;
   1136   int dump_module_info = 0;
   1137 
   1138   dump_module_info = 0;
   1139   gcov_prefix_strip = 0;
   1140 
   1141   memset (&all, 0, sizeof (all));
   1142 
   1143   /* Find the totals for this execution.  */
   1144   memset (&this_program, 0, sizeof (this_program));
   1145   for (gi_ptr = __gcov_list; gi_ptr; gi_ptr = gi_ptr->next)
   1146     {
   1147       gcov_object_summary (gi_ptr, &this_program);
   1148 
   1149       /* The IS_PRIMARY field is overloaded to indicate if this module
   1150          is FDO/LIPO.  */
   1151       dump_module_info |= gi_ptr->mod_info->is_primary;
   1152     }
   1153 
   1154   gcov_alloc_filename ();
   1155 
   1156   return dump_module_info;
   1157 }
   1158 
   1159 /* Dump one entry in the gcov_info list (for one object).  */
   1160 
   1161 static void
   1162 gcov_dump_one_gcov (struct gcov_info *gi_ptr)
   1163 {
   1164   gcov_type *values[GCOV_COUNTERS];
   1165   unsigned fi_stride;
   1166   unsigned c_ix;
   1167   int ret;
   1168 
   1169   memset (&this_object, 0, sizeof (this_object));
   1170   memset (&object, 0, sizeof (object));
   1171 
   1172   gcov_object_summary (gi_ptr, &this_object);
   1173 
   1174   c_ix = gcov_counter_array (gi_ptr, values, 1);
   1175 
   1176   fi_stride = gcov_compute_fi_stride (c_ix);
   1177 
   1178   GCOV_GET_FILENAME (prefix_length, gcov_prefix_strip, gi_ptr->filename,
   1179                      gi_filename_up);
   1180 
   1181   if (gcov_open_by_filename (gi_filename) == -1)
   1182     return;
   1183 
   1184   /* Now merge this file.  */
   1185   ret = gcov_merge_gcda_file (gi_ptr, values, fi_stride);
   1186   if (ret != 0 ) return;
   1187 
   1188   gcov_write_gcda_file (gi_ptr, fi_stride);
   1189 }
   1190 
   1191 #endif /* L_gcov */
   1192 
   1193 #ifdef L_gcov_merge_add
   1194 /* The profile merging function that just adds the counters.  It is given
   1195    an array COUNTERS of N_COUNTERS old counters and it reads the same number
   1196    of counters from the gcov file.  */
   1197 void
   1198 __gcov_merge_add (gcov_type *counters, unsigned n_counters)
   1199 {
   1200   for (; n_counters; counters++, n_counters--)
   1201     *counters += gcov_read_counter ();
   1202 }
   1203 #endif /* L_gcov_merge_add */
   1204 
   1205 #ifdef L_gcov_merge_ior
   1206 /* The profile merging function that just adds the counters.  It is given
   1207    an array COUNTERS of N_COUNTERS old counters and it reads the same number
   1208    of counters from the gcov file.  */
   1209 void
   1210 __gcov_merge_ior (gcov_type *counters, unsigned n_counters)
   1211 {
   1212   for (; n_counters; counters++, n_counters--)
   1213     *counters |= gcov_read_counter ();
   1214 }
   1215 #endif
   1216 
   1217 #ifdef L_gcov_merge_reusedist
   1218 
   1219 /* Return the weighted arithmetic mean of two values.  */
   1220 
   1221 static gcov_type
   1222 __gcov_weighted_mean2 (gcov_type value1, gcov_type count1,
   1223                        gcov_type value2, gcov_type count2)
   1224 {
   1225   if (count1 + count2 == 0)
   1226     return 0;
   1227   else
   1228     return (value1 * count1 + value2 * count2) / (count1 + count2);
   1229 }
   1230 
   1231 void
   1232 __gcov_merge_reusedist (gcov_type *counters, unsigned n_counters)
   1233 {
   1234   unsigned i;
   1235 
   1236   gcc_assert(!(n_counters % 4));
   1237 
   1238   for (i = 0; i < n_counters; i += 4)
   1239     {
   1240       /* Decode current values.  */
   1241       gcov_type c_mean_dist = counters[i];
   1242       gcov_type c_mean_size = counters[i+1];
   1243       gcov_type c_count = counters[i+2];
   1244       gcov_type c_dist_x_size = counters[i+3];
   1245 
   1246       /* Read and decode values in file.  */
   1247       gcov_type f_mean_dist = __gcov_read_counter ();
   1248       gcov_type f_mean_size = __gcov_read_counter ();
   1249       gcov_type f_count = __gcov_read_counter ();
   1250       gcov_type f_dist_x_size = __gcov_read_counter ();
   1251 
   1252       /* Compute aggregates.  */
   1253       gcov_type a_mean_dist = __gcov_weighted_mean2 (
   1254           f_mean_dist, f_count, c_mean_dist, c_count);
   1255       gcov_type a_mean_size = __gcov_weighted_mean2 (
   1256           f_mean_size, f_count, c_mean_size, c_count);
   1257       gcov_type a_count = f_count + c_count;
   1258       gcov_type a_dist_x_size = f_dist_x_size + c_dist_x_size;
   1259 
   1260       /* Encode back into counters.  */
   1261       counters[i] = a_mean_dist;
   1262       counters[i+1] = a_mean_size;
   1263       counters[i+2] = a_count;
   1264       counters[i+3] = a_dist_x_size;
   1265     }
   1266 }
   1267 
   1268 #endif
   1269 
   1270 #ifdef L_gcov_merge_dc
   1271 
   1272 /* Returns 1 if the function global id GID is not valid.  */
   1273 
   1274 static int
   1275 __gcov_is_gid_insane (gcov_type gid)
   1276 {
   1277   if (EXTRACT_MODULE_ID_FROM_GLOBAL_ID (gid) == 0
   1278       || EXTRACT_FUNC_ID_FROM_GLOBAL_ID (gid) == 0)
   1279     return 1;
   1280   return 0;
   1281 }
   1282 
   1283 /* The profile merging function used for merging direct call counts
   1284    This function is given array COUNTERS of N_COUNTERS old counters and it
   1285    reads the same number of counters from the gcov file.  */
   1286 
   1287 void
   1288 __gcov_merge_dc (gcov_type *counters, unsigned n_counters)
   1289 {
   1290   unsigned i;
   1291 
   1292   gcc_assert (!(n_counters % 2));
   1293   for (i = 0; i < n_counters; i += 2)
   1294     {
   1295       gcov_type global_id = gcov_read_counter ();
   1296       gcov_type call_count = gcov_read_counter ();
   1297 
   1298       /* Note that global id counter may never have been set if no calls were
   1299 	 made from this call-site.  */
   1300       if (counters[i] && global_id)
   1301         {
   1302           /* TODO race condition requires us do the following correction.  */
   1303           if (__gcov_is_gid_insane (counters[i]))
   1304             counters[i] = global_id;
   1305           else if (__gcov_is_gid_insane (global_id))
   1306             global_id = counters[i];
   1307 
   1308           gcc_assert (counters[i] == global_id);
   1309         }
   1310       else if (global_id)
   1311 	counters[i] = global_id;
   1312 
   1313       counters[i + 1] += call_count;
   1314 
   1315       /* Reset. */
   1316       if (__gcov_is_gid_insane (counters[i]))
   1317         counters[i] = counters[i + 1] = 0;
   1318 
   1319       /* Assert that the invariant (global_id == 0) <==> (call_count == 0)
   1320 	 holds true after merging.  */
   1321       if (counters[i] == 0)
   1322         counters[i+1] = 0;
   1323       if (counters[i + 1] == 0)
   1324         counters[i] = 0;
   1325     }
   1326 }
   1327 #endif
   1328 
   1329 #ifdef L_gcov_merge_icall_topn
   1330 /* The profile merging function used for merging indirect call counts
   1331    This function is given array COUNTERS of N_COUNTERS old counters and it
   1332    reads the same number of counters from the gcov file.  */
   1333 
   1334 void
   1335 __gcov_merge_icall_topn (gcov_type *counters, unsigned n_counters)
   1336 {
   1337   unsigned i, j, k, m;
   1338 
   1339   gcc_assert (!(n_counters % GCOV_ICALL_TOPN_NCOUNTS));
   1340   for (i = 0; i < n_counters; i += GCOV_ICALL_TOPN_NCOUNTS)
   1341     {
   1342       gcov_type *value_array = &counters[i + 1];
   1343       unsigned tmp_size = 2 * (GCOV_ICALL_TOPN_NCOUNTS - 1);
   1344       gcov_type *tmp_array
   1345           = (gcov_type *) alloca (tmp_size * sizeof (gcov_type));
   1346 
   1347       for (j = 0; j < tmp_size; j++)
   1348         tmp_array[j] = 0;
   1349 
   1350       for (j = 0; j < GCOV_ICALL_TOPN_NCOUNTS - 1; j += 2)
   1351         {
   1352           tmp_array[j] = value_array[j];
   1353           tmp_array[j + 1] = value_array [j + 1];
   1354         }
   1355 
   1356       /* Skip the number_of_eviction entry.  */
   1357       gcov_read_counter ();
   1358       for (k = 0; k < GCOV_ICALL_TOPN_NCOUNTS - 1; k += 2)
   1359         {
   1360           int found = 0;
   1361           gcov_type global_id = gcov_read_counter ();
   1362           gcov_type call_count = gcov_read_counter ();
   1363           for (m = 0; m < j; m += 2)
   1364             {
   1365               if (tmp_array[m] == global_id)
   1366                 {
   1367                   found = 1;
   1368                   tmp_array[m + 1] += call_count;
   1369                   break;
   1370                 }
   1371             }
   1372           if (!found)
   1373             {
   1374               tmp_array[j] = global_id;
   1375               tmp_array[j + 1] = call_count;
   1376               j += 2;
   1377             }
   1378         }
   1379       /* Now sort the temp array */
   1380       gcov_sort_n_vals (tmp_array, j);
   1381 
   1382       /* Now copy back the top half of the temp array */
   1383       for (k = 0; k < GCOV_ICALL_TOPN_NCOUNTS - 1; k += 2)
   1384         {
   1385           value_array[k] = tmp_array[k];
   1386           value_array[k + 1] = tmp_array[k + 1];
   1387         }
   1388     }
   1389 }
   1390 #endif
   1391 
   1392 
   1393 #ifdef L_gcov_merge_single
   1394 /* The profile merging function for choosing the most common value.
   1395    It is given an array COUNTERS of N_COUNTERS old counters and it
   1396    reads the same number of counters from the gcov file.  The counters
   1397    are split into 3-tuples where the members of the tuple have
   1398    meanings:
   1399 
   1400    -- the stored candidate on the most common value of the measured entity
   1401    -- counter
   1402    -- total number of evaluations of the value  */
   1403 void
   1404 __gcov_merge_single (gcov_type *counters, unsigned n_counters)
   1405 {
   1406   unsigned i, n_measures;
   1407   gcov_type value, counter, all;
   1408 
   1409   gcc_assert (!(n_counters % 3));
   1410   n_measures = n_counters / 3;
   1411   for (i = 0; i < n_measures; i++, counters += 3)
   1412     {
   1413       value = gcov_read_counter ();
   1414       counter = gcov_read_counter ();
   1415       all = gcov_read_counter ();
   1416 
   1417       if (counters[0] == value)
   1418 	counters[1] += counter;
   1419       else if (counter > counters[1])
   1420 	{
   1421 	  counters[0] = value;
   1422 	  counters[1] = counter - counters[1];
   1423 	}
   1424       else
   1425 	counters[1] -= counter;
   1426       counters[2] += all;
   1427     }
   1428 }
   1429 #endif /* L_gcov_merge_single */
   1430 
   1431 #ifdef L_gcov_merge_delta
   1432 /* The profile merging function for choosing the most common
   1433    difference between two consecutive evaluations of the value.  It is
   1434    given an array COUNTERS of N_COUNTERS old counters and it reads the
   1435    same number of counters from the gcov file.  The counters are split
   1436    into 4-tuples where the members of the tuple have meanings:
   1437 
   1438    -- the last value of the measured entity
   1439    -- the stored candidate on the most common difference
   1440    -- counter
   1441    -- total number of evaluations of the value  */
   1442 void
   1443 __gcov_merge_delta (gcov_type *counters, unsigned n_counters)
   1444 {
   1445   unsigned i, n_measures;
   1446   gcov_type value, counter, all;
   1447 
   1448   gcc_assert (!(n_counters % 4));
   1449   n_measures = n_counters / 4;
   1450   for (i = 0; i < n_measures; i++, counters += 4)
   1451     {
   1452       /* last = */ gcov_read_counter ();
   1453       value = gcov_read_counter ();
   1454       counter = gcov_read_counter ();
   1455       all = gcov_read_counter ();
   1456 
   1457       if (counters[1] == value)
   1458 	counters[2] += counter;
   1459       else if (counter > counters[2])
   1460 	{
   1461 	  counters[1] = value;
   1462 	  counters[2] = counter - counters[2];
   1463 	}
   1464       else
   1465 	counters[2] -= counter;
   1466       counters[3] += all;
   1467     }
   1468 }
   1469 #endif /* L_gcov_merge_delta */
   1470 
   1471 #ifdef L_gcov_interval_profiler
   1472 /* If VALUE is in interval <START, START + STEPS - 1>, then increases the
   1473    corresponding counter in COUNTERS.  If the VALUE is above or below
   1474    the interval, COUNTERS[STEPS] or COUNTERS[STEPS + 1] is increased
   1475    instead.  */
   1476 
   1477 void
   1478 __gcov_interval_profiler (gcov_type *counters, gcov_type value,
   1479 			  int start, unsigned steps)
   1480 {
   1481   gcov_type delta = value - start;
   1482   if (delta < 0)
   1483     counters[steps + 1]++;
   1484   else if (delta >= steps)
   1485     counters[steps]++;
   1486   else
   1487     counters[delta]++;
   1488 }
   1489 #endif
   1490 
   1491 #ifdef L_gcov_pow2_profiler
   1492 /* If VALUE is a power of two, COUNTERS[1] is incremented.  Otherwise
   1493    COUNTERS[0] is incremented.  */
   1494 
   1495 void
   1496 __gcov_pow2_profiler (gcov_type *counters, gcov_type value)
   1497 {
   1498   if (value & (value - 1))
   1499     counters[0]++;
   1500   else
   1501     counters[1]++;
   1502 }
   1503 #endif
   1504 
   1505 /* Tries to determine the most common value among its inputs.  Checks if the
   1506    value stored in COUNTERS[0] matches VALUE.  If this is the case, COUNTERS[1]
   1507    is incremented.  If this is not the case and COUNTERS[1] is not zero,
   1508    COUNTERS[1] is decremented.  Otherwise COUNTERS[1] is set to one and
   1509    VALUE is stored to COUNTERS[0].  This algorithm guarantees that if this
   1510    function is called more than 50% of the time with one value, this value
   1511    will be in COUNTERS[0] in the end.
   1512 
   1513    In any case, COUNTERS[2] is incremented.  */
   1514 
   1515 static inline void
   1516 __gcov_one_value_profiler_body (gcov_type *counters, gcov_type value)
   1517 {
   1518   if (value == counters[0])
   1519     counters[1]++;
   1520   else if (counters[1] == 0)
   1521     {
   1522       counters[1] = 1;
   1523       counters[0] = value;
   1524     }
   1525   else
   1526     counters[1]--;
   1527   counters[2]++;
   1528 }
   1529 
   1530 #ifdef L_gcov_indirect_call_topn_profiler
   1531 /* Tries to keep track the most frequent N values in the counters where
   1532    N is specified by parameter TOPN_VAL. To track top N values, 2*N counter
   1533    entries are used.
   1534    counter[0] --- the accumative count of the number of times one entry in
   1535                   in the counters gets evicted/replaced due to limited capacity.
   1536                   When this value reaches a threshold, the bottom N values are
   1537                   cleared.
   1538    counter[1] through counter[2*N] records the top 2*N values collected so far.
   1539    Each value is represented by two entries: count[2*i+1] is the ith value, and
   1540    count[2*i+2] is the number of times the value is seen.  */
   1541 
   1542 static void
   1543 __gcov_topn_value_profiler_body (gcov_type *counters, gcov_type value,
   1544                                  gcov_unsigned_t topn_val)
   1545 {
   1546    unsigned i, found = 0, have_zero_count = 0;
   1547 
   1548    gcov_type *entry;
   1549    gcov_type *lfu_entry = &counters[1];
   1550    gcov_type *value_array = &counters[1];
   1551    gcov_type *num_eviction = &counters[0];
   1552 
   1553    /* There are 2*topn_val values tracked, each value takes two slots in the
   1554       counter array */
   1555    for ( i = 0; i < (topn_val << 2); i += 2)
   1556      {
   1557        entry = &value_array[i];
   1558        if ( entry[0] == value)
   1559          {
   1560            entry[1]++ ;
   1561            found = 1;
   1562            break;
   1563          }
   1564        else if (entry[1] == 0)
   1565          {
   1566            lfu_entry = entry;
   1567            have_zero_count = 1;
   1568          }
   1569       else if (entry[1] < lfu_entry[1])
   1570         lfu_entry = entry;
   1571      }
   1572 
   1573    if (found)
   1574      return;
   1575 
   1576    /* lfu_entry is either an empty entry or an entry
   1577       with lowest count, which will be evicted.  */
   1578    lfu_entry[0] = value;
   1579    lfu_entry[1] = 1;
   1580 
   1581 #define GCOV_ICALL_COUNTER_CLEAR_THRESHOLD 3000
   1582 
   1583    /* Too many evictions -- time to clear bottom entries to
   1584       avoid hot values bumping each other out.  */
   1585    if ( !have_zero_count
   1586         && ++*num_eviction >= GCOV_ICALL_COUNTER_CLEAR_THRESHOLD)
   1587      {
   1588        unsigned i, j;
   1589        gcov_type *p, minv;
   1590        gcov_type* tmp_cnts
   1591            = (gcov_type *)alloca (topn_val * sizeof(gcov_type));
   1592 
   1593        *num_eviction = 0;
   1594 
   1595        for ( i = 0; i < topn_val; i++ )
   1596          tmp_cnts[i] = 0;
   1597 
   1598        /* Find the largest topn_val values from the group of
   1599           2*topn_val values and put them into tmp_cnts. */
   1600 
   1601        for ( i = 0; i < 2 * topn_val; i += 2 )
   1602          {
   1603            p = 0;
   1604            for ( j = 0; j < topn_val; j++ )
   1605              {
   1606                if ( !p || tmp_cnts[j] < *p )
   1607                   p = &tmp_cnts[j];
   1608              }
   1609             if ( value_array[i + 1] > *p )
   1610               *p = value_array[i + 1];
   1611          }
   1612 
   1613        minv = tmp_cnts[0];
   1614        for ( j = 1; j < topn_val; j++ )
   1615          {
   1616            if (tmp_cnts[j] < minv)
   1617              minv = tmp_cnts[j];
   1618          }
   1619        /* Zero out low value entries  */
   1620        for ( i = 0; i < 2 * topn_val; i += 2 )
   1621          {
   1622            if (value_array[i + 1] < minv)
   1623              {
   1624                value_array[i] = 0;
   1625                value_array[i + 1] = 0;
   1626              }
   1627          }
   1628      }
   1629 }
   1630 #endif
   1631 
   1632 #ifdef L_gcov_one_value_profiler
   1633 void
   1634 __gcov_one_value_profiler (gcov_type *counters, gcov_type value)
   1635 {
   1636   __gcov_one_value_profiler_body (counters, value);
   1637 }
   1638 #endif
   1639 
   1640 #ifdef L_gcov_indirect_call_profiler
   1641 
   1642 /* By default, the C++ compiler will use function addresses in the
   1643    vtable entries.  Setting TARGET_VTABLE_USES_DESCRIPTORS to nonzero
   1644    tells the compiler to use function descriptors instead.  The value
   1645    of this macro says how many words wide the descriptor is (normally 2),
   1646    but it may be dependent on target flags.  Since we do not have access
   1647    to the target flags here we just check to see if it is set and use
   1648    that to set VTABLE_USES_DESCRIPTORS to 0 or 1.
   1649 
   1650    It is assumed that the address of a function descriptor may be treated
   1651    as a pointer to a function.  */
   1652 
   1653 #ifdef TARGET_VTABLE_USES_DESCRIPTORS
   1654 #define VTABLE_USES_DESCRIPTORS 1
   1655 #else
   1656 #define VTABLE_USES_DESCRIPTORS 0
   1657 #endif
   1658 
   1659 /* Tries to determine the most common value among its inputs. */
   1660 void
   1661 __gcov_indirect_call_profiler (gcov_type* counter, gcov_type value,
   1662 			       void* cur_func, void* callee_func)
   1663 {
   1664   /* If the C++ virtual tables contain function descriptors then one
   1665      function may have multiple descriptors and we need to dereference
   1666      the descriptors to see if they point to the same function.  */
   1667   if (cur_func == callee_func
   1668       || (VTABLE_USES_DESCRIPTORS && callee_func
   1669 	  && *(void **) cur_func == *(void **) callee_func))
   1670     __gcov_one_value_profiler_body (counter, value);
   1671 }
   1672 #endif
   1673 
   1674 
   1675 #ifdef L_gcov_indirect_call_topn_profiler
   1676 extern THREAD_PREFIX gcov_type *__gcov_indirect_call_topn_counters ATTRIBUTE_HIDDEN;
   1677 extern THREAD_PREFIX void *__gcov_indirect_call_topn_callee ATTRIBUTE_HIDDEN;
   1678 #ifdef TARGET_VTABLE_USES_DESCRIPTORS
   1679 #define VTABLE_USES_DESCRIPTORS 1
   1680 #else
   1681 #define VTABLE_USES_DESCRIPTORS 0
   1682 #endif
   1683 void
   1684 __gcov_indirect_call_topn_profiler (void *cur_func,
   1685                                     void *cur_module_gcov_info,
   1686                                     gcov_unsigned_t cur_func_id)
   1687 {
   1688   void *callee_func = __gcov_indirect_call_topn_callee;
   1689   gcov_type *counter = __gcov_indirect_call_topn_counters;
   1690   /* If the C++ virtual tables contain function descriptors then one
   1691      function may have multiple descriptors and we need to dereference
   1692      the descriptors to see if they point to the same function.  */
   1693   if (cur_func == callee_func
   1694       || (VTABLE_USES_DESCRIPTORS && callee_func
   1695 	  && *(void **) cur_func == *(void **) callee_func))
   1696     {
   1697       gcov_type global_id
   1698           = ((struct gcov_info *) cur_module_gcov_info)->mod_info->ident;
   1699       global_id = GEN_FUNC_GLOBAL_ID (global_id, cur_func_id);
   1700       __gcov_topn_value_profiler_body (counter, global_id, GCOV_ICALL_TOPN_VAL);
   1701       __gcov_indirect_call_topn_callee = 0;
   1702     }
   1703 }
   1704 
   1705 #endif
   1706 
   1707 #ifdef L_gcov_direct_call_profiler
   1708 extern THREAD_PREFIX gcov_type *__gcov_direct_call_counters ATTRIBUTE_HIDDEN;
   1709 extern THREAD_PREFIX void *__gcov_direct_call_callee ATTRIBUTE_HIDDEN;
   1710 /* Direct call profiler. */
   1711 void
   1712 __gcov_direct_call_profiler (void *cur_func,
   1713 			     void *cur_module_gcov_info,
   1714 			     gcov_unsigned_t cur_func_id)
   1715 {
   1716   if (cur_func == __gcov_direct_call_callee)
   1717     {
   1718       gcov_type global_id
   1719           = ((struct gcov_info *) cur_module_gcov_info)->mod_info->ident;
   1720       global_id = GEN_FUNC_GLOBAL_ID (global_id, cur_func_id);
   1721       __gcov_direct_call_counters[0] = global_id;
   1722       __gcov_direct_call_counters[1]++;
   1723       __gcov_direct_call_callee = 0;
   1724     }
   1725 }
   1726 #endif
   1727 
   1728 
   1729 #ifdef L_gcov_average_profiler
   1730 /* Increase corresponding COUNTER by VALUE.  FIXME: Perhaps we want
   1731    to saturate up.  */
   1732 
   1733 void
   1734 __gcov_average_profiler (gcov_type *counters, gcov_type value)
   1735 {
   1736   counters[0] += value;
   1737   counters[1] ++;
   1738 }
   1739 #endif
   1740 
   1741 #ifdef L_gcov_ior_profiler
   1742 /* Increase corresponding COUNTER by VALUE.  FIXME: Perhaps we want
   1743    to saturate up.  */
   1744 
   1745 void
   1746 __gcov_ior_profiler (gcov_type *counters, gcov_type value)
   1747 {
   1748   *counters |= value;
   1749 }
   1750 #endif
   1751 
   1752 #ifdef L_gcov_fork
   1753 /* A wrapper for the fork function.  Flushes the accumulated profiling data, so
   1754    that they are not counted twice.  */
   1755 
   1756 pid_t
   1757 __gcov_fork (void)
   1758 {
   1759   __gcov_flush ();
   1760   return fork ();
   1761 }
   1762 #endif
   1763 
   1764 #ifdef L_gcov_execl
   1765 /* A wrapper for the execl function.  Flushes the accumulated profiling data, so
   1766    that they are not lost.  */
   1767 
   1768 int
   1769 __gcov_execl (const char *path, char *arg, ...)
   1770 {
   1771   va_list ap, aq;
   1772   unsigned i, length;
   1773   char **args;
   1774 
   1775   __gcov_flush ();
   1776 
   1777   va_start (ap, arg);
   1778   va_copy (aq, ap);
   1779 
   1780   length = 2;
   1781   while (va_arg (ap, char *))
   1782     length++;
   1783   va_end (ap);
   1784 
   1785   args = (char **) alloca (length * sizeof (void *));
   1786   args[0] = arg;
   1787   for (i = 1; i < length; i++)
   1788     args[i] = va_arg (aq, char *);
   1789   va_end (aq);
   1790 
   1791   return execv (path, args);
   1792 }
   1793 #endif
   1794 
   1795 #ifdef L_gcov_execlp
   1796 /* A wrapper for the execlp function.  Flushes the accumulated profiling data, so
   1797    that they are not lost.  */
   1798 
   1799 int
   1800 __gcov_execlp (const char *path, char *arg, ...)
   1801 {
   1802   va_list ap, aq;
   1803   unsigned i, length;
   1804   char **args;
   1805 
   1806   __gcov_flush ();
   1807 
   1808   va_start (ap, arg);
   1809   va_copy (aq, ap);
   1810 
   1811   length = 2;
   1812   while (va_arg (ap, char *))
   1813     length++;
   1814   va_end (ap);
   1815 
   1816   args = (char **) alloca (length * sizeof (void *));
   1817   args[0] = arg;
   1818   for (i = 1; i < length; i++)
   1819     args[i] = va_arg (aq, char *);
   1820   va_end (aq);
   1821 
   1822   return execvp (path, args);
   1823 }
   1824 #endif
   1825 
   1826 #ifdef L_gcov_execle
   1827 /* A wrapper for the execle function.  Flushes the accumulated profiling data, so
   1828    that they are not lost.  */
   1829 
   1830 int
   1831 __gcov_execle (const char *path, char *arg, ...)
   1832 {
   1833   va_list ap, aq;
   1834   unsigned i, length;
   1835   char **args;
   1836   char **envp;
   1837 
   1838   __gcov_flush ();
   1839 
   1840   va_start (ap, arg);
   1841   va_copy (aq, ap);
   1842 
   1843   length = 2;
   1844   while (va_arg (ap, char *))
   1845     length++;
   1846   va_end (ap);
   1847 
   1848   args = (char **) alloca (length * sizeof (void *));
   1849   args[0] = arg;
   1850   for (i = 1; i < length; i++)
   1851     args[i] = va_arg (aq, char *);
   1852   envp = va_arg (aq, char **);
   1853   va_end (aq);
   1854 
   1855   return execve (path, args, envp);
   1856 }
   1857 #endif
   1858 
   1859 #ifdef L_gcov_execv
   1860 /* A wrapper for the execv function.  Flushes the accumulated profiling data, so
   1861    that they are not lost.  */
   1862 
   1863 int
   1864 __gcov_execv (const char *path, char *const argv[])
   1865 {
   1866   __gcov_flush ();
   1867   return execv (path, argv);
   1868 }
   1869 #endif
   1870 
   1871 #ifdef L_gcov_execvp
   1872 /* A wrapper for the execvp function.  Flushes the accumulated profiling data, so
   1873    that they are not lost.  */
   1874 
   1875 int
   1876 __gcov_execvp (const char *path, char *const argv[])
   1877 {
   1878   __gcov_flush ();
   1879   return execvp (path, argv);
   1880 }
   1881 #endif
   1882 
   1883 #ifdef L_gcov_execve
   1884 /* A wrapper for the execve function.  Flushes the accumulated profiling data, so
   1885    that they are not lost.  */
   1886 
   1887 int
   1888 __gcov_execve (const char *path, char *const argv[], char *const envp[])
   1889 {
   1890   __gcov_flush ();
   1891   return execve (path, argv, envp);
   1892 }
   1893 #endif
   1894 
   1895 #ifdef __GCOV_KERNEL__
   1896 /*
   1897  * Provide different implementation for the following functions:
   1898  *   __gcov_init
   1899  *   __gcov_exit
   1900  *
   1901  * Provide the following dummy merge functions:
   1902  *   __gcov_merge_add
   1903  *   __gcov_merge_single
   1904  *   __gcov_merge_delta
   1905  *   __gcov_merge_ior
   1906  *   __gcov_merge_icall_topn
   1907  *   __gcov_merge_dc
   1908  *   __gcov_merge_reusedist
   1909  *
   1910  * Reuse the following functions:
   1911  *   __gcov_interval_profiler()
   1912  *   __gcov_pow2_profiler()
   1913  *   __gcov_average_profiler()
   1914  *   __gcov_ior_profiler()
   1915  *   __gcov_one_value_profiler()
   1916  *   __gcov_indirect_call_profiler()
   1917  *     |-> __gcov_one_value_profiler_body()
   1918  *
   1919  * For LIPO: (TBD)
   1920  *  Change slightly for the following functions:
   1921  *   __gcov_merge_icall_topn
   1922  *   __gcov_merge_dc
   1923  *
   1924  *  Reuse the following functions:
   1925  *   __gcov_direct_call_profiler()
   1926  *   __gcov_indirect_call_topn_profiler()
   1927  *     |-> __gcov_topn_value_profiler_body()
   1928  *
   1929  */
   1930 
   1931 /* Current virual gcda file. This is for kernel use only.  */
   1932 gcov_kernel_vfile *gcov_current_file;
   1933 
   1934 /* Set current virutal gcda file. It needs to be set before dumping
   1935    profile data.  */
   1936 
   1937 void
   1938 gcov_set_vfile (gcov_kernel_vfile *file)
   1939 {
   1940   gcov_current_file = file;
   1941 }
   1942 
   1943 /* Dump one entry in the gcov_info list (for one object) in kernel.  */
   1944 
   1945 void
   1946 gcov_kernel_dump_one_gcov (struct gcov_info *info)
   1947 {
   1948   gcc_assert (gcov_current_file);
   1949 
   1950   gcov_exit_init ();
   1951 
   1952   gcov_dump_one_gcov (info);
   1953 }
   1954 
   1955 #define DUMMY_FUNC(func) \
   1956 void func (gcov_type *counters  __attribute__ ((unused)), \
   1957            unsigned n_counters __attribute__ ((unused))) {}
   1958 
   1959 DUMMY_FUNC (__gcov_merge_add)
   1960 EXPORT_SYMBOL (__gcov_merge_add);
   1961 
   1962 DUMMY_FUNC (__gcov_merge_single)
   1963 EXPORT_SYMBOL (__gcov_merge_single);
   1964 
   1965 DUMMY_FUNC (__gcov_merge_delta)
   1966 EXPORT_SYMBOL (__gcov_merge_delta);
   1967 
   1968 DUMMY_FUNC(__gcov_merge_ior)
   1969 EXPORT_SYMBOL (__gcov_merge_ior);
   1970 
   1971 DUMMY_FUNC (__gcov_merge_icall_topn)
   1972 EXPORT_SYMBOL (__gcov_merge_icall_topn);
   1973 
   1974 DUMMY_FUNC (__gcov_merge_dc)
   1975 EXPORT_SYMBOL (__gcov_merge_dc);
   1976 
   1977 DUMMY_FUNC (__gcov_merge_reusedist)
   1978 EXPORT_SYMBOL (__gcov_merge_reusedist);
   1979 
   1980 EXPORT_SYMBOL (__gcov_average_profiler);
   1981 EXPORT_SYMBOL (__gcov_indirect_call_profiler);
   1982 EXPORT_SYMBOL (__gcov_interval_profiler);
   1983 EXPORT_SYMBOL (__gcov_ior_profiler);
   1984 EXPORT_SYMBOL (__gcov_one_value_profiler);
   1985 EXPORT_SYMBOL (__gcov_pow2_profiler);
   1986 
   1987 #endif /* __GCOV_KERNEL__ */
   1988 
   1989 #endif /* inhibit_libc */
   1990