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
7This file is part of GCC.
8
9GCC is free software; you can redistribute it and/or modify it under
10the terms of the GNU General Public License as published by the Free
11Software Foundation; either version 3, or (at your option) any later
12version.
13
14GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15WARRANTY; without even the implied warranty of MERCHANTABILITY or
16FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
17for more details.
18
19Under Section 7 of GPL version 3, you are granted additional
20permissions described in the GCC Runtime Library Exception, version
213.1, as published by the Free Software Foundation.
22
23You should have received a copy of the GNU General Public License and
24a copy of the GCC Runtime Library Exception along with this program;
25see 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
76void __gcov_init (struct gcov_info *p __attribute__ ((unused))) {}
77void __gcov_flush (void) {}
78#endif
79
80#ifdef L_gcov_merge_add
81void __gcov_merge_add (gcov_type *counters  __attribute__ ((unused)),
82		       unsigned n_counters __attribute__ ((unused))) {}
83#endif
84
85#ifdef L_gcov_merge_single
86void __gcov_merge_single (gcov_type *counters  __attribute__ ((unused)),
87			  unsigned n_counters __attribute__ ((unused))) {}
88#endif
89
90#ifdef L_gcov_merge_delta
91void __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.  */
110static int
111gcov_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.  */
127extern char * __gcov_pmu_profile_filename;
128extern char * __gcov_pmu_profile_options;
129extern gcov_unsigned_t __gcov_pmu_top_n_address;
130
131/* Sampling rate.  */
132extern gcov_unsigned_t __gcov_sampling_rate;
133static int gcov_sampling_rate_initialized = 0;
134void __gcov_set_sampling_rate (unsigned int rate);
135
136/* Set sampling rate to RATE.  */
137
138void __gcov_set_sampling_rate (unsigned int rate)
139{
140  __gcov_sampling_rate = rate;
141}
142
143/* Per thread sample counter.  */
144THREAD_PREFIX gcov_unsigned_t __gcov_sample_counter = 0;
145
146/* Chain of per-object gcov structures.  */
147extern struct gcov_info *__gcov_list;
148
149/* Size of the longest file name. */
150static size_t gcov_max_filename = 0;
151#endif /* __GCOV_KERNEL__ */
152
153/* Unique identifier assigned to each module (object file).  */
154static 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.  */
158THREAD_PREFIX gcov_type *__gcov_direct_call_counters ATTRIBUTE_HIDDEN;
159
160/* Direct call callee address.  */
161THREAD_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.  */
165THREAD_PREFIX gcov_type *__gcov_indirect_call_topn_counters ATTRIBUTE_HIDDEN;
166
167/* Indirect call callee address.  */
168THREAD_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.  */
172static gcov_unsigned_t gcov_crc32;
173
174/* Dynamic call graph build and form module groups.  */
175void __gcov_compute_module_groups (void) ATTRIBUTE_HIDDEN;
176void __gcov_finalize_dyn_callgraph (void) ATTRIBUTE_HIDDEN;
177
178/* Profile summary for the gdca file, used in sanity check?  */
179static struct gcov_summary all;
180
181/* Profile summary for this program in current exeuction.  */
182static struct gcov_summary this_program;
183
184/* Profile summary for this object in current execuction.  */
185static struct gcov_summary this_object;
186
187/* Merged profile summary for this program.  */
188static struct gcov_summary program;
189
190/* Merged profile summary for this object.  */
191static struct gcov_summary object;
192
193/* Record the position of summary info.  */
194static gcov_position_t summary_pos = 0;
195
196/* Record the postion of eof.  */
197static gcov_position_t eof_pos = 0;
198
199/* Number of chars in prefix to be stripped.  */
200static int gcov_prefix_strip = 0;
201
202/* The length of path prefix.  */
203static size_t prefix_length = 0;
204
205/* gi_filename is current object filename.
206   gi_filename_up points to the stripped filename.  */
207static char *gi_filename, *gi_filename_up;
208
209static int gcov_open_by_filename (char * gi_filename);
210static int gcov_exit_init (void);
211static 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
217static int
218create_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
262static int
263gcov_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
286static inline int
287gcov_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
298static int
299gcov_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
324static void
325gcov_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
362static void
363gcov_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
413static void
414pmu_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
446GCOV_LINKAGE  void
447gcov_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
470static void
471gcov_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
490static void
491gcov_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
528static void
529gcov_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
569static void
570gcov_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
592void
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
674void
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
702static inline void
703gcov_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
713static void
714gcov_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.  */
720static char _kernel_gi_filename[520];
721
722/* This function allocates the space to store current file name.  */
723
724static void
725gcov_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
741static unsigned int
742gcov_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
767static void
768gcov_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
798static int
799gcov_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
902read_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
911read_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
916read_fatal:;
917    gcov_close ();
918    return 1;
919
920rewrite:;
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
981static unsigned
982gcov_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
999GCOV_LINKAGE unsigned
1000gcov_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
1050static void
1051gcov_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
1132static int
1133gcov_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
1161static void
1162gcov_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.  */
1197void
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.  */
1209void
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
1221static 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
1231void
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
1274static 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
1287void
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
1334void
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  */
1403void
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  */
1442void
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
1477void
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
1495void
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
1515static 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
1542static 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
1633void
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. */
1660void
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
1676extern THREAD_PREFIX gcov_type *__gcov_indirect_call_topn_counters ATTRIBUTE_HIDDEN;
1677extern 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
1683void
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
1708extern THREAD_PREFIX gcov_type *__gcov_direct_call_counters ATTRIBUTE_HIDDEN;
1709extern THREAD_PREFIX void *__gcov_direct_call_callee ATTRIBUTE_HIDDEN;
1710/* Direct call profiler. */
1711void
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
1733void
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
1745void
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
1756pid_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
1768int
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
1799int
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
1830int
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
1863int
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
1875int
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
1887int
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.  */
1932gcov_kernel_vfile *gcov_current_file;
1933
1934/* Set current virutal gcda file. It needs to be set before dumping
1935   profile data.  */
1936
1937void
1938gcov_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
1945void
1946gcov_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) \
1956void func (gcov_type *counters  __attribute__ ((unused)), \
1957           unsigned n_counters __attribute__ ((unused))) {}
1958
1959DUMMY_FUNC (__gcov_merge_add)
1960EXPORT_SYMBOL (__gcov_merge_add);
1961
1962DUMMY_FUNC (__gcov_merge_single)
1963EXPORT_SYMBOL (__gcov_merge_single);
1964
1965DUMMY_FUNC (__gcov_merge_delta)
1966EXPORT_SYMBOL (__gcov_merge_delta);
1967
1968DUMMY_FUNC(__gcov_merge_ior)
1969EXPORT_SYMBOL (__gcov_merge_ior);
1970
1971DUMMY_FUNC (__gcov_merge_icall_topn)
1972EXPORT_SYMBOL (__gcov_merge_icall_topn);
1973
1974DUMMY_FUNC (__gcov_merge_dc)
1975EXPORT_SYMBOL (__gcov_merge_dc);
1976
1977DUMMY_FUNC (__gcov_merge_reusedist)
1978EXPORT_SYMBOL (__gcov_merge_reusedist);
1979
1980EXPORT_SYMBOL (__gcov_average_profiler);
1981EXPORT_SYMBOL (__gcov_indirect_call_profiler);
1982EXPORT_SYMBOL (__gcov_interval_profiler);
1983EXPORT_SYMBOL (__gcov_ior_profiler);
1984EXPORT_SYMBOL (__gcov_one_value_profiler);
1985EXPORT_SYMBOL (__gcov_pow2_profiler);
1986
1987#endif /* __GCOV_KERNEL__ */
1988
1989#endif /* inhibit_libc */
1990