/* Dump a gcov file, for debugging use.
   Copyright (C) 2002-2022 Free Software Foundation, Inc.
   Contributed by Nathan Sidwell <nathan@codesourcery.com>

Gcov 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.

Gcov 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.

You should have received a copy of the GNU General Public License
along with Gcov; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "version.h"
#include "intl.h"
#include "diagnostic.h"
#include <getopt.h>
#define IN_GCOV (-1)
#include "gcov-io.h"
#include "gcov-io.cc"

static void dump_gcov_file (const char *);
static void print_prefix (const char *, unsigned, gcov_position_t);
static void print_usage (void);
static void print_version (void);
static void tag_function (const char *, unsigned, int, unsigned);
static void tag_blocks (const char *, unsigned, int, unsigned);
static void tag_arcs (const char *, unsigned, int, unsigned);
static void tag_lines (const char *, unsigned, int, unsigned);
static void tag_counters (const char *, unsigned, int, unsigned);
static void tag_summary (const char *, unsigned, int, unsigned);
extern int main (int, char **);

typedef struct tag_format
{
  unsigned tag;
  char const *name;
  void (*proc) (const char *, unsigned, int, unsigned);
} tag_format_t;

static int flag_dump_contents = 0;
static int flag_dump_positions = 0;
static int flag_dump_raw = 0;

static const struct option options[] =
{
  { "help",                 no_argument,       NULL, 'h' },
  { "version",              no_argument,       NULL, 'v' },
  { "long",                 no_argument,       NULL, 'l' },
  { "positions",	    no_argument,       NULL, 'o' },
  { 0, 0, 0, 0 }
};

#define VALUE_PADDING_PREFIX "              "
#define VALUE_PREFIX "%2d: "

static const tag_format_t tag_table[] =
{
  {0, "NOP", NULL},
  {0, "UNKNOWN", NULL},
  {0, "COUNTERS", tag_counters},
  {GCOV_TAG_FUNCTION, "FUNCTION", tag_function},
  {GCOV_TAG_BLOCKS, "BLOCKS", tag_blocks},
  {GCOV_TAG_ARCS, "ARCS", tag_arcs},
  {GCOV_TAG_LINES, "LINES", tag_lines},
  {GCOV_TAG_OBJECT_SUMMARY, "OBJECT_SUMMARY", tag_summary},
  {0, NULL, NULL}
};

int
main (int argc ATTRIBUTE_UNUSED, char **argv)
{
  int opt;
  const char *p;

  p = argv[0] + strlen (argv[0]);
  while (p != argv[0] && !IS_DIR_SEPARATOR (p[-1]))
    --p;
  progname = p;

  xmalloc_set_program_name (progname);

  /* Unlock the stdio streams.  */
  unlock_std_streams ();

  gcc_init_libintl ();

  diagnostic_initialize (global_dc, 0);

  while ((opt = getopt_long (argc, argv, "hlprvw", options, NULL)) != -1)
    {
      switch (opt)
	{
	case 'h':
	  print_usage ();
	  break;
	case 'v':
	  print_version ();
	  break;
	case 'l':
	  flag_dump_contents = 1;
	  break;
	case 'p':
	  flag_dump_positions = 1;
	  break;
	case 'r':
	  flag_dump_raw = 1;
	  break;
	default:
	  fprintf (stderr, "unknown flag `%c'\n", opt);
	}
    }

  while (argv[optind])
    dump_gcov_file (argv[optind++]);
  return 0;
}

static void
print_usage (void)
{
  printf ("Usage: gcov-dump [OPTION] ... gcovfiles\n");
  printf ("Print coverage file contents\n");
  printf ("  -h, --help           Print this help\n");
  printf ("  -l, --long           Dump record contents too\n");
  printf ("  -p, --positions      Dump record positions\n");
  printf ("  -r, --raw            Print content records in raw format\n");
  printf ("  -v, --version        Print version number\n");
  printf ("\nFor bug reporting instructions, please see:\n%s.\n",
	   bug_report_url);
}

static void
print_version (void)
{
  printf ("gcov-dump %s%s\n", pkgversion_string, version_string);
  printf ("Copyright (C) 2022 Free Software Foundation, Inc.\n");
  printf ("This is free software; see the source for copying conditions.  There is NO\n\
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n");
}

static void
print_prefix (const char *filename, unsigned depth, gcov_position_t position)
{
  static const char prefix[] = "    ";

  printf ("%s:", filename);
  if (flag_dump_positions)
    printf ("%5lu:", (unsigned long) position);
  printf ("%.*s", (int) 2 * depth, prefix);
}

static void
dump_gcov_file (const char *filename)
{
  unsigned tags[4];
  unsigned depth = 0;
  bool is_data_type;

  if (!gcov_open (filename, 1))
    {
      fprintf (stderr, "%s:cannot open\n", filename);
      return;
    }

  /* magic */
  {
    unsigned magic = gcov_read_unsigned ();
    unsigned version;
    int endianness = 0;
    char m[4], v[4];

    if ((endianness = gcov_magic (magic, GCOV_DATA_MAGIC)))
      is_data_type = true;
    else if ((endianness = gcov_magic (magic, GCOV_NOTE_MAGIC)))
      is_data_type = false;
    else
      {
	printf ("%s:not a gcov file\n", filename);
	gcov_close ();
	return;
      }
    version = gcov_read_unsigned ();
    GCOV_UNSIGNED2STRING (v, version);
    GCOV_UNSIGNED2STRING (m, magic);

    printf ("%s:%s:magic `%.4s':version `%.4s'%s\n", filename,
	    is_data_type ? "data" : "note",
 	    m, v, endianness < 0 ? " (swapped endianness)" : "");
    if (version != GCOV_VERSION)
      {
	char e[4];

	GCOV_UNSIGNED2STRING (e, GCOV_VERSION);
	printf ("%s:warning:current version is `%.4s'\n", filename, e);
      }
  }

  /* stamp */
  unsigned stamp = gcov_read_unsigned ();
  printf ("%s:stamp %lu\n", filename, (unsigned long)stamp);

  /* Checksum */
  unsigned checksum = gcov_read_unsigned ();
  printf ("%s:checksum %lu\n", filename, (unsigned long)checksum);

  if (!is_data_type)
    {
      printf ("%s:cwd: %s\n", filename, gcov_read_string ());

      /* Support for unexecuted basic blocks.  */
      unsigned support_unexecuted_blocks = gcov_read_unsigned ();
      if (!support_unexecuted_blocks)
	printf ("%s: has_unexecuted_block is not supported\n", filename);
    }

  while (1)
    {
      gcov_position_t base, position = gcov_position ();
      int read_length;
      unsigned tag, length;
      tag_format_t const *format;
      unsigned tag_depth;
      int error;
      unsigned mask;

      tag = gcov_read_unsigned ();
      if (!tag)
	break;
      read_length = (int)gcov_read_unsigned ();
      length = read_length > 0 ? read_length : 0;
      base = gcov_position ();
      mask = GCOV_TAG_MASK (tag) >> 1;
      for (tag_depth = 4; mask; mask >>= 8)
	{
	  if ((mask & 0xff) != 0xff)
	    {
	      printf ("%s:tag `%08x' is invalid\n", filename, tag);
	      break;
	    }
	  tag_depth--;
	}
      for (format = tag_table; format->name; format++)
	if (format->tag == tag)
	  goto found;
      format = &tag_table[GCOV_TAG_IS_COUNTER (tag) ? 2 : 1];
    found:;
      if (tag)
	{
	  if (depth && depth < tag_depth)
	    {
	      if (!GCOV_TAG_IS_SUBTAG (tags[depth - 1], tag))
		printf ("%s:tag `%08x' is incorrectly nested\n",
			filename, tag);
	    }
	  depth = tag_depth;
	  tags[depth - 1] = tag;
	}

      print_prefix (filename, tag_depth, position);
      printf ("%08x:%4u:%s", tag, abs (read_length), format->name);
      if (format->proc)
	(*format->proc) (filename, tag, read_length, depth);

      printf ("\n");
      if (flag_dump_contents && format->proc)
	{
	  unsigned long actual_length = gcov_position () - base;

	  if (actual_length > length)
	    printf ("%s:record size mismatch %lu bytes overread\n",
		    filename, actual_length - length);
	  else if (length > actual_length)
	    printf ("%s:record size mismatch %lu bytes unread\n",
		    filename, length - actual_length);
	}
      gcov_sync (base, length);
      if ((error = gcov_is_error ()))
	{
	  printf (error < 0 ? "%s:counter overflow at %lu\n" :
		  "%s:read error at %lu\n", filename,
		  (long unsigned) gcov_position ());
	  break;
	}
    }
  gcov_close ();
}

static void
tag_function (const char *filename ATTRIBUTE_UNUSED,
	      unsigned tag ATTRIBUTE_UNUSED, int length,
	      unsigned depth ATTRIBUTE_UNUSED)
{
  gcov_position_t pos = gcov_position ();

  if (!length)
    printf (" placeholder");
  else
    {
      printf (" ident=%u", gcov_read_unsigned ());
      printf (", lineno_checksum=0x%08x", gcov_read_unsigned ());
      printf (", cfg_checksum=0x%08x", gcov_read_unsigned ());

      if (gcov_position () - pos < (gcov_position_t) length)
	{
	  const char *name;
	  
	  name = gcov_read_string ();
	  printf (", `%s'", name ? name : "NULL");
	  unsigned artificial = gcov_read_unsigned ();
	  name = gcov_read_string ();
	  printf (" %s", name ? name : "NULL");
	  unsigned line_start = gcov_read_unsigned ();
	  unsigned column_start = gcov_read_unsigned ();
	  unsigned line_end = gcov_read_unsigned ();
	  unsigned column_end = gcov_read_unsigned ();
	  printf (":%u:%u-%u:%u", line_start, column_start,
		  line_end, column_end);
	  if (artificial)
	    printf (", artificial");
	}
    }
}

static void
tag_blocks (const char *filename ATTRIBUTE_UNUSED,
	    unsigned tag ATTRIBUTE_UNUSED, int length ATTRIBUTE_UNUSED,
	    unsigned depth ATTRIBUTE_UNUSED)
{
  printf (" %u blocks", gcov_read_unsigned ());
}

static void
tag_arcs (const char *filename ATTRIBUTE_UNUSED,
	  unsigned tag ATTRIBUTE_UNUSED, int length ATTRIBUTE_UNUSED,
	  unsigned depth)
{
  unsigned n_arcs = GCOV_TAG_ARCS_NUM (length);

  printf (" %u arcs", n_arcs);
  if (flag_dump_contents)
    {
      unsigned ix;
      unsigned blockno = gcov_read_unsigned ();

      for (ix = 0; ix != n_arcs; ix++)
	{
	  unsigned dst, flags;

	  if (!(ix & 3))
	    {
	      printf ("\n");
	      print_prefix (filename, depth, gcov_position ());
	      printf (VALUE_PADDING_PREFIX "block %u:", blockno);
	    }
	  dst = gcov_read_unsigned ();
	  flags = gcov_read_unsigned ();
	  printf (" %u:%04x", dst, flags);
	  if (flags)
	    {
	      char c = '(';
	      
	      if (flags & GCOV_ARC_ON_TREE)
		printf ("%ctree", c), c = ',';
	      if (flags & GCOV_ARC_FAKE)
		printf ("%cfake", c), c = ',';
	      if (flags & GCOV_ARC_FALLTHROUGH)
		printf ("%cfall", c), c = ',';
	      printf (")");
	    }
	}
    }
}

static void
tag_lines (const char *filename ATTRIBUTE_UNUSED,
	   unsigned tag ATTRIBUTE_UNUSED, int length ATTRIBUTE_UNUSED,
	   unsigned depth)
{
  if (flag_dump_contents)
    {
      unsigned blockno = gcov_read_unsigned ();
      char const *sep = NULL;

      while (1)
	{
	  gcov_position_t position = gcov_position ();
	  const char *source = NULL;
	  unsigned lineno = gcov_read_unsigned ();

	  if (!lineno)
	    {
	      source = gcov_read_string ();
	      if (!source)
		break;
	      sep = NULL;
	    }

	  if (!sep)
	    {
	      printf ("\n");
	      print_prefix (filename, depth, position);
	      printf (VALUE_PADDING_PREFIX "block %u:", blockno);
	      sep = "";
	    }
	  if (lineno)
	    {
	      printf ("%s%u", sep, lineno);
	      sep = ", ";
	    }
	  else
	    {
	      printf ("%s`%s'", sep, source);
	      sep = ":";
	    }
	}
    }
}

static void
tag_counters (const char *filename ATTRIBUTE_UNUSED,
	      unsigned tag ATTRIBUTE_UNUSED, int length ATTRIBUTE_UNUSED,
	      unsigned depth)
{
#define DEF_GCOV_COUNTER(COUNTER, NAME, MERGE_FN) NAME,
  static const char *const counter_names[] = {
#include "gcov-counter.def"
};
#undef DEF_GCOV_COUNTER
  int n_counts = GCOV_TAG_COUNTER_NUM (length);
  bool has_zeros = n_counts < 0;
  n_counts = abs (n_counts);

  printf (" %s %u counts%s",
	  counter_names[GCOV_COUNTER_FOR_TAG (tag)], n_counts,
	  has_zeros ? " (all zero)" : "");
  if (flag_dump_contents)
    {
      for (int ix = 0; ix != n_counts; ix++)
	{
	  gcov_type count;

	  if (flag_dump_raw)
	    {
	      if (ix == 0)
		printf (": ");
	    }
	  else if (!(ix & 7))
	    {
	      printf ("\n");
	      print_prefix (filename, depth, gcov_position ());
	      printf (VALUE_PADDING_PREFIX VALUE_PREFIX, ix);
	    }

	  count = has_zeros ? 0 : gcov_read_counter ();
	  printf ("%" PRId64 " ", count);
	}
    }
}

static void
tag_summary (const char *filename ATTRIBUTE_UNUSED,
	     unsigned tag ATTRIBUTE_UNUSED, int length ATTRIBUTE_UNUSED,
	     unsigned depth ATTRIBUTE_UNUSED)
{
  gcov_summary summary;
  gcov_read_summary (&summary);
  printf (" runs=%d, sum_max=%" PRId64,
	  summary.runs, summary.sum_max);
}
