/* Routines required for instrumenting a program.  */
/* Compile this one with gcc.  */
/* Copyright (C) 1989-2021 Free Software Foundation, Inc.

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.

GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
for more details.

Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.

You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
<http://www.gnu.org/licenses/>.  */

#include "libgcov.h"
#include "gcov-io.h"

/* Return 1, if all counter values are zero, otherwise 0. */

static inline int
are_all_counters_zero (const struct gcov_ctr_info *ci_ptr)
{
  for (unsigned i = 0; i < ci_ptr->num; i++)
    if (ci_ptr->values[i] != 0)
      return 0;

  return 1;
}

#if defined(inhibit_libc)
/* If libc and its header files are not available, provide dummy functions.  */

#if defined(L_gcov)
void __gcov_init (struct gcov_info *p __attribute__ ((unused))) {}
#endif

#else /* inhibit_libc */

#if GCOV_LOCKED
#include <fcntl.h>
#include <errno.h>
#include <sys/stat.h>
#elif GCOV_LOCKED_WITH_LOCKING
#include <fcntl.h>
#include <sys/locking.h>
#include <sys/stat.h>
#endif

#if HAVE_SYS_MMAN_H
#include <sys/mman.h>
#endif

#endif /* inhibit_libc */

#if defined(L_gcov) && !defined(inhibit_libc)
#define NEED_L_GCOV
#endif

#if defined(L_gcov_info_to_gcda) && !IN_GCOV_TOOL
#define NEED_L_GCOV_INFO_TO_GCDA
#endif

#ifdef NEED_L_GCOV
/* A utility function for outputting errors.  */
static int gcov_error (const char *, ...);

#if !IN_GCOV_TOOL
static void gcov_error_exit (void);
#endif

#include "gcov-io.c"

#define GCOV_PROF_PREFIX "libgcov profiling error:%s:"

struct gcov_fn_buffer
{
  struct gcov_fn_buffer *next;
  unsigned fn_ix;
  struct gcov_fn_info info;
  /* note gcov_fn_info ends in a trailing array.  */
};

struct gcov_summary_buffer
{
  struct gcov_summary_buffer *next;
  struct gcov_summary summary;
};

/* A struct that bundles all the related information about the
   gcda filename.  */

struct gcov_filename
{
  char *filename;  /* filename buffer */
  int strip; /* leading chars to strip from filename */
  char *prefix; /* prefix string */
};

static struct gcov_fn_buffer *
free_fn_data (const struct gcov_info *gi_ptr, struct gcov_fn_buffer *buffer,
              unsigned limit)
{
  struct gcov_fn_buffer *next;
  unsigned ix, n_ctr = 0;

  if (!buffer)
    return 0;
  next = buffer->next;

  for (ix = 0; ix != limit; ix++)
    if (gi_ptr->merge[ix])
      free (buffer->info.ctrs[n_ctr++].values);
  free (buffer);
  return next;
}

static struct gcov_fn_buffer **
buffer_fn_data (const char *filename, const struct gcov_info *gi_ptr,
                struct gcov_fn_buffer **end_ptr, unsigned fn_ix)
{
  unsigned n_ctrs = 0, ix = 0;
  struct gcov_fn_buffer *fn_buffer;
  unsigned len;

  for (ix = GCOV_COUNTERS; ix--;)
    if (gi_ptr->merge[ix])
      n_ctrs++;

  len = sizeof (*fn_buffer) + sizeof (fn_buffer->info.ctrs[0]) * n_ctrs;
  fn_buffer = (struct gcov_fn_buffer *) xmalloc (len);

  if (!fn_buffer)
    goto fail;

  fn_buffer->next = 0;
  fn_buffer->fn_ix = fn_ix;
  fn_buffer->info.ident = gcov_read_unsigned ();
  fn_buffer->info.lineno_checksum = gcov_read_unsigned ();
  fn_buffer->info.cfg_checksum = gcov_read_unsigned ();

  for (n_ctrs = ix = 0; ix != GCOV_COUNTERS; ix++)
    {
      gcov_unsigned_t length;
      gcov_type *values;

      if (!gi_ptr->merge[ix])
        continue;

      if (gcov_read_unsigned () != GCOV_TAG_FOR_COUNTER (ix))
        {
          len = 0;
          goto fail;
        }

      length = GCOV_TAG_COUNTER_NUM (gcov_read_unsigned ());
      len = length * sizeof (gcov_type);
      values = (gcov_type *) xmalloc (len);
      if (!values)
        goto fail;

      fn_buffer->info.ctrs[n_ctrs].num = length;
      fn_buffer->info.ctrs[n_ctrs].values = values;

      while (length--)
        *values++ = gcov_read_counter ();
      n_ctrs++;
    }

  *end_ptr = fn_buffer;
  return &fn_buffer->next;

fail:
  gcov_error (GCOV_PROF_PREFIX "Function %u %s %u \n", filename, fn_ix,
              len ? "cannot allocate" : "counter mismatch", len ? len : ix);

  return (struct gcov_fn_buffer **)free_fn_data (gi_ptr, fn_buffer, ix);
}

/* Convert VERSION into a string description and return the it.
   BUFFER is used for storage of the string.  The code should be
   aligned wit gcov-iov.c.  */

static char *
gcov_version_string (char *buffer, char version[4])
{
  if (version[0] < 'A' || version[0] > 'Z'
      || version[1] < '0' || version[1] > '9'
      || version[2] < '0' || version[2] > '9')
    sprintf (buffer, "(unknown)");
  else
    {
      unsigned major = 10 * (version[0] - 'A') + (version[1] - '0');
      unsigned minor = version[2] - '0';
      sprintf (buffer, "%u.%u (%s)", major, minor,
	       version[3] == '*' ? "release" : "experimental");
    }
  return buffer;
}

/* Check if VERSION of the info block PTR matches libgcov one.
   Return 1 on success, or zero in case of versions mismatch.
   If FILENAME is not NULL, its value used for reporting purposes
   instead of value from the info block.  */

static int
gcov_version (struct gcov_info *ptr, gcov_unsigned_t version,
              const char *filename)
{
  if (version != GCOV_VERSION)
    {
      char v[4], e[4];
      char ver_string[128], expected_string[128];

      GCOV_UNSIGNED2STRING (v, version);
      GCOV_UNSIGNED2STRING (e, GCOV_VERSION);

      gcov_error (GCOV_PROF_PREFIX "Version mismatch - expected %s (%.4s) "
		  "got %s (%.4s)\n",
		  filename? filename : ptr->filename,
		  gcov_version_string (expected_string, e), e,
		  gcov_version_string (ver_string, v), v);
      return 0;
    }
  return 1;
}

/* buffer for the fn_data from another program.  */
static struct gcov_fn_buffer *fn_buffer;

/* Including system dependent components. */
#include "libgcov-driver-system.c"

/* This function merges counters in GI_PTR to an existing gcda file.
   Return 0 on success.
   Return -1 on error. In this case, caller will goto read_fatal.  */

static int
merge_one_data (const char *filename,
		struct gcov_info *gi_ptr,
		struct gcov_summary *summary)
{
  gcov_unsigned_t tag, length;
  unsigned t_ix;
  int f_ix = -1;
  int error = 0;
  struct gcov_fn_buffer **fn_tail = &fn_buffer;

  length = gcov_read_unsigned ();
  if (!gcov_version (gi_ptr, length, filename))
    return -1;

  /* Skip timestamp.  */
  gcov_read_unsigned ();

  length = gcov_read_unsigned ();
  if (length != gi_ptr->checksum)
    {
      /* Read from a different compilation.  Overwrite the file.  */
      gcov_error (GCOV_PROF_PREFIX "overwriting an existing profile data "
		  "with a different checksum\n", filename);
      return 0;
    }

  tag = gcov_read_unsigned ();
  if (tag != GCOV_TAG_OBJECT_SUMMARY)
    goto read_mismatch;
  length = gcov_read_unsigned ();
  gcc_assert (length > 0);
  gcov_read_summary (summary);

  tag = gcov_read_unsigned ();
  /* Merge execution counts for each function.  */
  for (f_ix = 0; (unsigned)f_ix != gi_ptr->n_functions;
       f_ix++, tag = gcov_read_unsigned ())
    {
      const struct gcov_ctr_info *ci_ptr;
      const struct gcov_fn_info *gfi_ptr = gi_ptr->functions[f_ix];

      if (tag != GCOV_TAG_FUNCTION)
        goto read_mismatch;

      length = gcov_read_unsigned ();
      if (!length)
        /* This function did not appear in the other program.
           We have nothing to merge.  */
        continue;

      if (length != GCOV_TAG_FUNCTION_LENGTH)
        goto read_mismatch;

      if (!gfi_ptr || gfi_ptr->key != gi_ptr)
        {
          /* This function appears in the other program.  We
             need to buffer the information in order to write
             it back out -- we'll be inserting data before
             this point, so cannot simply keep the data in the
             file.  */
          fn_tail = buffer_fn_data (filename, gi_ptr, fn_tail, f_ix);
          if (!fn_tail)
            goto read_mismatch;
          continue;
        }

      length = gcov_read_unsigned ();
      if (length != gfi_ptr->ident)
        goto read_mismatch;

      length = gcov_read_unsigned ();
      if (length != gfi_ptr->lineno_checksum)
        goto read_mismatch;

      length = gcov_read_unsigned ();
      if (length != gfi_ptr->cfg_checksum)
        goto read_mismatch;

      ci_ptr = gfi_ptr->ctrs;
      for (t_ix = 0; t_ix < GCOV_COUNTERS; t_ix++)
        {
          gcov_merge_fn merge = gi_ptr->merge[t_ix];

          if (!merge)
            continue;

	  tag = gcov_read_unsigned ();
	  int read_length = (int)gcov_read_unsigned ();
	  length = abs (read_length);
	  if (tag != GCOV_TAG_FOR_COUNTER (t_ix)
	      || (length != GCOV_TAG_COUNTER_LENGTH (ci_ptr->num)
		  && t_ix != GCOV_COUNTER_V_TOPN
		  && t_ix != GCOV_COUNTER_V_INDIR))
	    goto read_mismatch;
	  /* Merging with all zero counters does not make sense.  */
	  if (read_length > 0)
	    (*merge) (ci_ptr->values, ci_ptr->num);
	  ci_ptr++;
	}
      if ((error = gcov_is_error ()))
	goto read_error;
    }

  if (tag)
    {
    read_mismatch:;
      gcov_error (GCOV_PROF_PREFIX "Merge mismatch for %s %u\n",
                  filename, f_ix >= 0 ? "function" : "summary",
                  f_ix < 0 ? -1 - f_ix : f_ix);
      return -1;
    }
  return 0;

read_error:
  gcov_error (GCOV_PROF_PREFIX "%s merging\n", filename,
              error < 0 ? "Overflow": "Error");
  return -1;
}

/* Write the DATA of LENGTH characters to the gcov file.  */

static void
gcov_dump_handler (const void *data,
		   unsigned length,
		   void *arg ATTRIBUTE_UNUSED)
{
  gcov_write (data, length);
}

/* Allocate SIZE characters and return the address of the allocated memory.  */

static void *
gcov_allocate_handler (unsigned size, void *arg ATTRIBUTE_UNUSED)
{
  return xmalloc (size);
}
#endif /* NEED_L_GCOV */

#if defined(NEED_L_GCOV) || defined(NEED_L_GCOV_INFO_TO_GCDA)
/* Dump the WORD using the DUMP handler called with ARG.  */

static inline void
dump_unsigned (gcov_unsigned_t word,
	       void (*dump_fn) (const void *, unsigned, void *),
	       void *arg)
{
  (*dump_fn) (&word, sizeof (word), arg);
}

/* Dump the COUNTER using the DUMP handler called with ARG.  */

static inline void
dump_counter (gcov_type counter,
	      void (*dump_fn) (const void *, unsigned, void *),
	      void *arg)
{
  dump_unsigned ((gcov_unsigned_t)counter, dump_fn, arg);

  if (sizeof (counter) > sizeof (gcov_unsigned_t))
    dump_unsigned ((gcov_unsigned_t)(counter >> 32), dump_fn, arg);
  else
    dump_unsigned (0, dump_fn, arg);
}

#define MAX(X,Y) ((X) > (Y) ? (X) : (Y))

/* Store all TOP N counters where each has a dynamic length.  */

static void
write_topn_counters (const struct gcov_ctr_info *ci_ptr,
		     unsigned t_ix,
		     gcov_unsigned_t n_counts,
		     void (*dump_fn) (const void *, unsigned, void *),
		     void *(*allocate_fn)(unsigned, void *),
		     void *arg)
{
  unsigned counters = n_counts / GCOV_TOPN_MEM_COUNTERS;
  gcc_assert (n_counts % GCOV_TOPN_MEM_COUNTERS == 0);

  /* It can happen in a multi-threaded environment that number of counters is
     different from the size of the corresponding linked lists.  */
#define LIST_SIZE_MIN_LENGTH 4 * 1024

  static unsigned *list_sizes = NULL;
  static unsigned list_size_length = 0;

  if (list_sizes == NULL || counters > list_size_length)
    {
      list_size_length = MAX (LIST_SIZE_MIN_LENGTH, 2 * counters);
#if !defined(inhibit_libc) && HAVE_SYS_MMAN_H
      list_sizes
	= (unsigned *)malloc_mmap (list_size_length * sizeof (unsigned));
#endif

      /* Malloc fallback.  */
      if (list_sizes == NULL)
	list_sizes =
	  (unsigned *)(*allocate_fn) (list_size_length * sizeof (unsigned),
				      arg);
    }

  unsigned pair_total = 0;

  for (unsigned i = 0; i < counters; i++)
    {
      gcov_type start = ci_ptr->values[GCOV_TOPN_MEM_COUNTERS * i + 2];
      unsigned sizes = 0;

      for (struct gcov_kvp *node = (struct gcov_kvp *)(__INTPTR_TYPE__)start;
	   node != NULL; node = node->next)
	++sizes;

      pair_total += sizes;
      list_sizes[i] = sizes;
    }

  unsigned disk_size = GCOV_TOPN_DISK_COUNTERS * counters + 2 * pair_total;
  dump_unsigned (GCOV_TAG_FOR_COUNTER (t_ix), dump_fn, arg),
  dump_unsigned (GCOV_TAG_COUNTER_LENGTH (disk_size), dump_fn, arg);

  for (unsigned i = 0; i < counters; i++)
    {
      dump_counter (ci_ptr->values[GCOV_TOPN_MEM_COUNTERS * i], dump_fn, arg);
      dump_counter (list_sizes[i], dump_fn, arg);
      gcov_type start = ci_ptr->values[GCOV_TOPN_MEM_COUNTERS * i + 2];

      unsigned j = 0;
      for (struct gcov_kvp *node = (struct gcov_kvp *)(__INTPTR_TYPE__)start;
	   j < list_sizes[i]; node = node->next, j++)
	{
	  dump_counter (node->value, dump_fn, arg);
	  dump_counter (node->count, dump_fn, arg);
	}
    }
}

/* Write counters in GI_PTR and the summary in PRG to a gcda file. In
   the case of appending to an existing file, SUMMARY_POS will be non-zero.
   We will write the file starting from SUMMAY_POS.  */

static void
write_one_data (const struct gcov_info *gi_ptr,
		const struct gcov_summary *prg_p ATTRIBUTE_UNUSED,
		void (*dump_fn) (const void *, unsigned, void *),
		void *(*allocate_fn) (unsigned, void *),
		void *arg)
{
  unsigned f_ix;

  dump_unsigned (GCOV_DATA_MAGIC, dump_fn, arg);
  dump_unsigned (GCOV_VERSION, dump_fn, arg);
  dump_unsigned (gi_ptr->stamp, dump_fn, arg);
  dump_unsigned (gi_ptr->checksum, dump_fn, arg);

#ifdef NEED_L_GCOV
  /* Generate whole program statistics.  */
  gcov_write_summary (GCOV_TAG_OBJECT_SUMMARY, prg_p);
#endif

  /* Write execution counts for each function.  */
  for (f_ix = 0; f_ix != gi_ptr->n_functions; f_ix++)
    {
#ifdef NEED_L_GCOV
      unsigned buffered = 0;
#endif
      const struct gcov_fn_info *gfi_ptr;
      const struct gcov_ctr_info *ci_ptr;
      gcov_unsigned_t length;
      unsigned t_ix;

#ifdef NEED_L_GCOV
      if (fn_buffer && fn_buffer->fn_ix == f_ix)
        {
          /* Buffered data from another program.  */
          buffered = 1;
          gfi_ptr = &fn_buffer->info;
          length = GCOV_TAG_FUNCTION_LENGTH;
        }
      else
#endif
        {
          gfi_ptr = gi_ptr->functions[f_ix];
          if (gfi_ptr && gfi_ptr->key == gi_ptr)
            length = GCOV_TAG_FUNCTION_LENGTH;
          else
                length = 0;
        }

      dump_unsigned (GCOV_TAG_FUNCTION, dump_fn, arg);
      dump_unsigned (length, dump_fn, arg);
      if (!length)
        continue;

      dump_unsigned (gfi_ptr->ident, dump_fn, arg);
      dump_unsigned (gfi_ptr->lineno_checksum, dump_fn, arg);
      dump_unsigned (gfi_ptr->cfg_checksum, dump_fn, arg);

      ci_ptr = gfi_ptr->ctrs;
      for (t_ix = 0; t_ix < GCOV_COUNTERS; t_ix++)
        {
	  gcov_position_t n_counts;

	  if (!gi_ptr->merge[t_ix])
	    continue;

	  n_counts = ci_ptr->num;

	  if (t_ix == GCOV_COUNTER_V_TOPN || t_ix == GCOV_COUNTER_V_INDIR)
	    write_topn_counters (ci_ptr, t_ix, n_counts, dump_fn, allocate_fn,
				 arg);
	  else
	    {
	      dump_unsigned (GCOV_TAG_FOR_COUNTER (t_ix), dump_fn, arg);
	      if (are_all_counters_zero (ci_ptr))
		/* Do not stream when all counters are zero.  */
		dump_unsigned (GCOV_TAG_COUNTER_LENGTH (-n_counts),
			       dump_fn, arg);
	      else
		{
		  dump_unsigned (GCOV_TAG_COUNTER_LENGTH (n_counts),
				 dump_fn, arg);
		  for (unsigned i = 0; i < n_counts; i++)
		    dump_counter (ci_ptr->values[i], dump_fn, arg);
		}
	    }

	  ci_ptr++;
	}
#ifdef NEED_L_GCOV
      if (buffered)
        fn_buffer = free_fn_data (gi_ptr, fn_buffer, GCOV_COUNTERS);
#endif
    }

  dump_unsigned (0, dump_fn, arg);
}
#endif /* NEED_L_GCOV || NEED_L_GCOV_INFO_TO_GCDA */

#ifdef NEED_L_GCOV
/* Dump the coverage counts for one gcov_info object. We merge with existing
   counts when possible, to avoid growing the .da files ad infinitum. We use
   this program's checksum to make sure we only accumulate whole program
   statistics to the correct summary. An object file might be embedded
   in two separate programs, and we must keep the two program
   summaries separate.  */

static void
dump_one_gcov (struct gcov_info *gi_ptr, struct gcov_filename *gf,
	       unsigned run_counted ATTRIBUTE_UNUSED,
	       gcov_type run_max ATTRIBUTE_UNUSED)
{
  struct gcov_summary summary = {};
  int error;
  gcov_unsigned_t tag;
  fn_buffer = 0;

  error = gcov_exit_open_gcda_file (gi_ptr, gf);
  if (error == -1)
    return;

  tag = gcov_read_unsigned ();
  if (tag)
    {
      /* Merge data from file.  */
      if (tag != GCOV_DATA_MAGIC)
        {
	  gcov_error (GCOV_PROF_PREFIX "Not a gcov data file\n",
		      gf->filename);
          goto read_fatal;
        }
      error = merge_one_data (gf->filename, gi_ptr, &summary);
      if (error == -1)
        goto read_fatal;
    }

  gcov_rewrite ();

#if !IN_GCOV_TOOL
  if (!run_counted)
    {
      summary.runs++;
      summary.sum_max += run_max;
    }
#else
  summary = gi_ptr->summary;
#endif

  write_one_data (gi_ptr, &summary, gcov_dump_handler, gcov_allocate_handler,
		  NULL);
  /* fall through */

read_fatal:;
  while (fn_buffer)
    fn_buffer = free_fn_data (gi_ptr, fn_buffer, GCOV_COUNTERS);

  if ((error = gcov_close ()))
    gcov_error ((error < 0 ? GCOV_PROF_PREFIX "Overflow writing\n"
		 : GCOV_PROF_PREFIX "Error writing\n"), gf->filename);
}


/* Dump all the coverage counts for the program. It first computes program
   summary and then traverses gcov_list list and dumps the gcov_info
   objects one by one.  */

#if !IN_GCOV_TOOL
static
#endif
void
gcov_do_dump (struct gcov_info *list, int run_counted)
{
  struct gcov_info *gi_ptr;
  struct gcov_filename gf;

  /* Compute run_max of this program run.  */
  gcov_type run_max = 0;
  for (gi_ptr = list; gi_ptr; gi_ptr = gi_ptr->next)
    for (unsigned f_ix = 0; (unsigned)f_ix != gi_ptr->n_functions; f_ix++)
      {
	const struct gcov_ctr_info *cinfo
	  = &gi_ptr->functions[f_ix]->ctrs[GCOV_COUNTER_ARCS];

	for (unsigned i = 0; i < cinfo->num; i++)
	  if (run_max < cinfo->values[i])
	    run_max = cinfo->values[i];
      }

  allocate_filename_struct (&gf);

  /* Now merge each file.  */
  for (gi_ptr = list; gi_ptr; gi_ptr = gi_ptr->next)
    {
      dump_one_gcov (gi_ptr, &gf, run_counted, run_max);
      free (gf.filename);
    }

  free (gf.prefix);
}

#if IN_GCOV_TOOL
const char *
__attribute__ ((unused))
gcov_get_filename (struct gcov_info *list)
{
  return list->filename;
}
#endif

#if !IN_GCOV_TOOL
void
__gcov_dump_one (struct gcov_root *root)
{
  if (root->dumped)
    return;

  gcov_do_dump (root->list, root->run_counted);
  
  root->dumped = 1;
  root->run_counted = 1;
}

/* Per-dynamic-object gcov state.  */
struct gcov_root __gcov_root;

/* Exactly one of these will be live in the process image.  */
struct gcov_master __gcov_master = 
  {GCOV_VERSION, 0};

/* Dynamic pool for gcov_kvp structures.  */
struct gcov_kvp *__gcov_kvp_dynamic_pool;

/* Index into __gcov_kvp_dynamic_pool array.  */
unsigned __gcov_kvp_dynamic_pool_index;

/* Size of _gcov_kvp_dynamic_pool array.  */
unsigned __gcov_kvp_dynamic_pool_size;

void
__gcov_exit (void)
{
  __gcov_dump_one (&__gcov_root);
  if (__gcov_root.next)
    __gcov_root.next->prev = __gcov_root.prev;
  if (__gcov_root.prev)
    __gcov_root.prev->next = __gcov_root.next;
  else
    __gcov_master.root = __gcov_root.next;

  gcov_error_exit ();
}

/* Add a new object file onto the bb chain.  Invoked automatically
  when running an object file's global ctors.  */

void
__gcov_init (struct gcov_info *info)
{
  if (!info->version || !info->n_functions)
    return;
  if (gcov_version (info, info->version, 0))
    {
      if (!__gcov_root.list)
	{
	  /* Add to master list and at exit function.  */
	  if (gcov_version (NULL, __gcov_master.version, "<master>"))
	    {
	      __gcov_root.next = __gcov_master.root;
	      if (__gcov_master.root)
		__gcov_master.root->prev = &__gcov_root;
	      __gcov_master.root = &__gcov_root;
	    }
	}

      info->next = __gcov_root.list;
      __gcov_root.list = info;
    }
}
#endif /* !IN_GCOV_TOOL */
#endif /* NEED_L_GCOV */

#ifdef NEED_L_GCOV_INFO_TO_GCDA
/* Convert the gcov info to a gcda data stream.  It is intended for
   free-standing environments which do not support the C library file I/O.  */

void
__gcov_info_to_gcda (const struct gcov_info *gi_ptr,
		     void (*filename_fn) (const char *, void *),
		     void (*dump_fn) (const void *, unsigned, void *),
		     void *(*allocate_fn) (unsigned, void *),
		     void *arg)
{
  (*filename_fn) (gi_ptr->filename, arg);
  write_one_data (gi_ptr, NULL, dump_fn, allocate_fn, arg);
}
#endif /* NEED_L_GCOV_INFO_TO_GCDA */
