110d565efSmrg /* Dump a gcov file, for debugging use.
2*ec02198aSmrg    Copyright (C) 2002-2020 Free Software Foundation, Inc.
310d565efSmrg    Contributed by Nathan Sidwell <nathan@codesourcery.com>
410d565efSmrg 
510d565efSmrg Gcov is free software; you can redistribute it and/or modify
610d565efSmrg it under the terms of the GNU General Public License as published by
710d565efSmrg the Free Software Foundation; either version 3, or (at your option)
810d565efSmrg any later version.
910d565efSmrg 
1010d565efSmrg Gcov is distributed in the hope that it will be useful,
1110d565efSmrg but WITHOUT ANY WARRANTY; without even the implied warranty of
1210d565efSmrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1310d565efSmrg GNU General Public License for more details.
1410d565efSmrg 
1510d565efSmrg You should have received a copy of the GNU General Public License
1610d565efSmrg along with Gcov; see the file COPYING3.  If not see
1710d565efSmrg <http://www.gnu.org/licenses/>.  */
1810d565efSmrg 
1910d565efSmrg #include "config.h"
2010d565efSmrg #include "system.h"
2110d565efSmrg #include "coretypes.h"
2210d565efSmrg #include "tm.h"
2310d565efSmrg #include "version.h"
2410d565efSmrg #include "intl.h"
2510d565efSmrg #include "diagnostic.h"
2610d565efSmrg #include <getopt.h>
2710d565efSmrg #define IN_GCOV (-1)
2810d565efSmrg #include "gcov-io.h"
2910d565efSmrg #include "gcov-io.c"
3010d565efSmrg 
3110d565efSmrg static void dump_gcov_file (const char *);
3210d565efSmrg static void print_prefix (const char *, unsigned, gcov_position_t);
3310d565efSmrg static void print_usage (void);
3410d565efSmrg static void print_version (void);
35c7a68eb7Smrg static void tag_function (const char *, unsigned, unsigned, unsigned);
36c7a68eb7Smrg static void tag_blocks (const char *, unsigned, unsigned, unsigned);
37c7a68eb7Smrg static void tag_arcs (const char *, unsigned, unsigned, unsigned);
38c7a68eb7Smrg static void tag_lines (const char *, unsigned, unsigned, unsigned);
39c7a68eb7Smrg static void tag_counters (const char *, unsigned, unsigned, unsigned);
40c7a68eb7Smrg static void tag_summary (const char *, unsigned, unsigned, unsigned);
4110d565efSmrg extern int main (int, char **);
4210d565efSmrg 
4310d565efSmrg typedef struct tag_format
4410d565efSmrg {
4510d565efSmrg   unsigned tag;
4610d565efSmrg   char const *name;
47c7a68eb7Smrg   void (*proc) (const char *, unsigned, unsigned, unsigned);
4810d565efSmrg } tag_format_t;
4910d565efSmrg 
5010d565efSmrg static int flag_dump_contents = 0;
5110d565efSmrg static int flag_dump_positions = 0;
5210d565efSmrg 
5310d565efSmrg static const struct option options[] =
5410d565efSmrg {
5510d565efSmrg   { "help",                 no_argument,       NULL, 'h' },
5610d565efSmrg   { "version",              no_argument,       NULL, 'v' },
5710d565efSmrg   { "long",                 no_argument,       NULL, 'l' },
5810d565efSmrg   { "positions",	    no_argument,       NULL, 'o' },
5910d565efSmrg   { 0, 0, 0, 0 }
6010d565efSmrg };
6110d565efSmrg 
62c7a68eb7Smrg #define VALUE_PADDING_PREFIX "              "
63c7a68eb7Smrg #define VALUE_PREFIX "%2d: "
64c7a68eb7Smrg 
6510d565efSmrg static const tag_format_t tag_table[] =
6610d565efSmrg {
6710d565efSmrg   {0, "NOP", NULL},
6810d565efSmrg   {0, "UNKNOWN", NULL},
6910d565efSmrg   {0, "COUNTERS", tag_counters},
7010d565efSmrg   {GCOV_TAG_FUNCTION, "FUNCTION", tag_function},
7110d565efSmrg   {GCOV_TAG_BLOCKS, "BLOCKS", tag_blocks},
7210d565efSmrg   {GCOV_TAG_ARCS, "ARCS", tag_arcs},
7310d565efSmrg   {GCOV_TAG_LINES, "LINES", tag_lines},
7410d565efSmrg   {GCOV_TAG_OBJECT_SUMMARY, "OBJECT_SUMMARY", tag_summary},
7510d565efSmrg   {0, NULL, NULL}
7610d565efSmrg };
7710d565efSmrg 
7810d565efSmrg int
main(int argc ATTRIBUTE_UNUSED,char ** argv)7910d565efSmrg main (int argc ATTRIBUTE_UNUSED, char **argv)
8010d565efSmrg {
8110d565efSmrg   int opt;
8210d565efSmrg   const char *p;
8310d565efSmrg 
8410d565efSmrg   p = argv[0] + strlen (argv[0]);
8510d565efSmrg   while (p != argv[0] && !IS_DIR_SEPARATOR (p[-1]))
8610d565efSmrg     --p;
8710d565efSmrg   progname = p;
8810d565efSmrg 
8910d565efSmrg   xmalloc_set_program_name (progname);
9010d565efSmrg 
9110d565efSmrg   /* Unlock the stdio streams.  */
9210d565efSmrg   unlock_std_streams ();
9310d565efSmrg 
9410d565efSmrg   gcc_init_libintl ();
9510d565efSmrg 
9610d565efSmrg   diagnostic_initialize (global_dc, 0);
9710d565efSmrg 
9810d565efSmrg   while ((opt = getopt_long (argc, argv, "hlpvw", options, NULL)) != -1)
9910d565efSmrg     {
10010d565efSmrg       switch (opt)
10110d565efSmrg 	{
10210d565efSmrg 	case 'h':
10310d565efSmrg 	  print_usage ();
10410d565efSmrg 	  break;
10510d565efSmrg 	case 'v':
10610d565efSmrg 	  print_version ();
10710d565efSmrg 	  break;
10810d565efSmrg 	case 'l':
10910d565efSmrg 	  flag_dump_contents = 1;
11010d565efSmrg 	  break;
11110d565efSmrg 	case 'p':
11210d565efSmrg 	  flag_dump_positions = 1;
11310d565efSmrg 	  break;
11410d565efSmrg 	default:
11510d565efSmrg 	  fprintf (stderr, "unknown flag `%c'\n", opt);
11610d565efSmrg 	}
11710d565efSmrg     }
11810d565efSmrg 
11910d565efSmrg   while (argv[optind])
12010d565efSmrg     dump_gcov_file (argv[optind++]);
12110d565efSmrg   return 0;
12210d565efSmrg }
12310d565efSmrg 
12410d565efSmrg static void
print_usage(void)12510d565efSmrg print_usage (void)
12610d565efSmrg {
12710d565efSmrg   printf ("Usage: gcov-dump [OPTION] ... gcovfiles\n");
12810d565efSmrg   printf ("Print coverage file contents\n");
12910d565efSmrg   printf ("  -h, --help           Print this help\n");
13010d565efSmrg   printf ("  -l, --long           Dump record contents too\n");
13110d565efSmrg   printf ("  -p, --positions      Dump record positions\n");
13210d565efSmrg   printf ("  -v, --version        Print version number\n");
13310d565efSmrg   printf ("\nFor bug reporting instructions, please see:\n%s.\n",
13410d565efSmrg 	   bug_report_url);
13510d565efSmrg }
13610d565efSmrg 
13710d565efSmrg static void
print_version(void)13810d565efSmrg print_version (void)
13910d565efSmrg {
14010d565efSmrg   printf ("gcov-dump %s%s\n", pkgversion_string, version_string);
141*ec02198aSmrg   printf ("Copyright (C) 2020 Free Software Foundation, Inc.\n");
14210d565efSmrg   printf ("This is free software; see the source for copying conditions.\n"
14310d565efSmrg   	  "There is NO warranty; not even for MERCHANTABILITY or \n"
14410d565efSmrg 	  "FITNESS FOR A PARTICULAR PURPOSE.\n\n");
14510d565efSmrg }
14610d565efSmrg 
14710d565efSmrg static void
print_prefix(const char * filename,unsigned depth,gcov_position_t position)14810d565efSmrg print_prefix (const char *filename, unsigned depth, gcov_position_t position)
14910d565efSmrg {
15010d565efSmrg   static const char prefix[] = "    ";
15110d565efSmrg 
15210d565efSmrg   printf ("%s:", filename);
15310d565efSmrg   if (flag_dump_positions)
154c7a68eb7Smrg     printf ("%5lu:", (unsigned long) position);
155c7a68eb7Smrg   printf ("%.*s", (int) 2 * depth, prefix);
15610d565efSmrg }
15710d565efSmrg 
15810d565efSmrg static void
dump_gcov_file(const char * filename)15910d565efSmrg dump_gcov_file (const char *filename)
16010d565efSmrg {
16110d565efSmrg   unsigned tags[4];
16210d565efSmrg   unsigned depth = 0;
163c7a68eb7Smrg   bool is_data_type;
16410d565efSmrg 
16510d565efSmrg   if (!gcov_open (filename, 1))
16610d565efSmrg     {
16710d565efSmrg       fprintf (stderr, "%s:cannot open\n", filename);
16810d565efSmrg       return;
16910d565efSmrg     }
17010d565efSmrg 
17110d565efSmrg   /* magic */
17210d565efSmrg   {
17310d565efSmrg     unsigned magic = gcov_read_unsigned ();
17410d565efSmrg     unsigned version;
17510d565efSmrg     int endianness = 0;
17610d565efSmrg     char m[4], v[4];
17710d565efSmrg 
17810d565efSmrg     if ((endianness = gcov_magic (magic, GCOV_DATA_MAGIC)))
179c7a68eb7Smrg       is_data_type = true;
18010d565efSmrg     else if ((endianness = gcov_magic (magic, GCOV_NOTE_MAGIC)))
181c7a68eb7Smrg       is_data_type = false;
18210d565efSmrg     else
18310d565efSmrg       {
18410d565efSmrg 	printf ("%s:not a gcov file\n", filename);
18510d565efSmrg 	gcov_close ();
18610d565efSmrg 	return;
18710d565efSmrg       }
18810d565efSmrg     version = gcov_read_unsigned ();
18910d565efSmrg     GCOV_UNSIGNED2STRING (v, version);
19010d565efSmrg     GCOV_UNSIGNED2STRING (m, magic);
19110d565efSmrg 
192c7a68eb7Smrg     printf ("%s:%s:magic `%.4s':version `%.4s'%s\n", filename,
193c7a68eb7Smrg 	    is_data_type ? "data" : "note",
19410d565efSmrg  	    m, v, endianness < 0 ? " (swapped endianness)" : "");
19510d565efSmrg     if (version != GCOV_VERSION)
19610d565efSmrg       {
19710d565efSmrg 	char e[4];
19810d565efSmrg 
19910d565efSmrg 	GCOV_UNSIGNED2STRING (e, GCOV_VERSION);
20010d565efSmrg 	printf ("%s:warning:current version is `%.4s'\n", filename, e);
20110d565efSmrg       }
20210d565efSmrg   }
20310d565efSmrg 
20410d565efSmrg   /* stamp */
20510d565efSmrg   {
20610d565efSmrg     unsigned stamp = gcov_read_unsigned ();
20710d565efSmrg 
20810d565efSmrg     printf ("%s:stamp %lu\n", filename, (unsigned long)stamp);
20910d565efSmrg   }
21010d565efSmrg 
211c7a68eb7Smrg   if (!is_data_type)
212c7a68eb7Smrg     {
2130fc04c29Smrg       printf ("%s:cwd: %s\n", filename, gcov_read_string ());
2140fc04c29Smrg 
215c7a68eb7Smrg       /* Support for unexecuted basic blocks.  */
216c7a68eb7Smrg       unsigned support_unexecuted_blocks = gcov_read_unsigned ();
217c7a68eb7Smrg       if (!support_unexecuted_blocks)
218c7a68eb7Smrg 	printf ("%s: has_unexecuted_block is not supported\n", filename);
219c7a68eb7Smrg     }
220c7a68eb7Smrg 
22110d565efSmrg   while (1)
22210d565efSmrg     {
22310d565efSmrg       gcov_position_t base, position = gcov_position ();
22410d565efSmrg       unsigned tag, length;
22510d565efSmrg       tag_format_t const *format;
22610d565efSmrg       unsigned tag_depth;
22710d565efSmrg       int error;
22810d565efSmrg       unsigned mask;
22910d565efSmrg 
23010d565efSmrg       tag = gcov_read_unsigned ();
23110d565efSmrg       if (!tag)
23210d565efSmrg 	break;
23310d565efSmrg       length = gcov_read_unsigned ();
23410d565efSmrg       base = gcov_position ();
23510d565efSmrg       mask = GCOV_TAG_MASK (tag) >> 1;
23610d565efSmrg       for (tag_depth = 4; mask; mask >>= 8)
23710d565efSmrg 	{
23810d565efSmrg 	  if ((mask & 0xff) != 0xff)
23910d565efSmrg 	    {
24010d565efSmrg 	      printf ("%s:tag `%08x' is invalid\n", filename, tag);
24110d565efSmrg 	      break;
24210d565efSmrg 	    }
24310d565efSmrg 	  tag_depth--;
24410d565efSmrg 	}
24510d565efSmrg       for (format = tag_table; format->name; format++)
24610d565efSmrg 	if (format->tag == tag)
24710d565efSmrg 	  goto found;
24810d565efSmrg       format = &tag_table[GCOV_TAG_IS_COUNTER (tag) ? 2 : 1];
24910d565efSmrg     found:;
25010d565efSmrg       if (tag)
25110d565efSmrg 	{
25210d565efSmrg 	  if (depth && depth < tag_depth)
25310d565efSmrg 	    {
25410d565efSmrg 	      if (!GCOV_TAG_IS_SUBTAG (tags[depth - 1], tag))
25510d565efSmrg 		printf ("%s:tag `%08x' is incorrectly nested\n",
25610d565efSmrg 			filename, tag);
25710d565efSmrg 	    }
25810d565efSmrg 	  depth = tag_depth;
25910d565efSmrg 	  tags[depth - 1] = tag;
26010d565efSmrg 	}
26110d565efSmrg 
26210d565efSmrg       print_prefix (filename, tag_depth, position);
26310d565efSmrg       printf ("%08x:%4u:%s", tag, length, format->name);
26410d565efSmrg       if (format->proc)
265c7a68eb7Smrg 	(*format->proc) (filename, tag, length, depth);
26610d565efSmrg 
26710d565efSmrg       printf ("\n");
26810d565efSmrg       if (flag_dump_contents && format->proc)
26910d565efSmrg 	{
27010d565efSmrg 	  unsigned long actual_length = gcov_position () - base;
27110d565efSmrg 
27210d565efSmrg 	  if (actual_length > length)
27310d565efSmrg 	    printf ("%s:record size mismatch %lu bytes overread\n",
27410d565efSmrg 		    filename, actual_length - length);
27510d565efSmrg 	  else if (length > actual_length)
27610d565efSmrg 	    printf ("%s:record size mismatch %lu bytes unread\n",
27710d565efSmrg 		    filename, length - actual_length);
27810d565efSmrg 	}
27910d565efSmrg       gcov_sync (base, length);
28010d565efSmrg       if ((error = gcov_is_error ()))
28110d565efSmrg 	{
28210d565efSmrg 	  printf (error < 0 ? "%s:counter overflow at %lu\n" :
28310d565efSmrg 		  "%s:read error at %lu\n", filename,
28410d565efSmrg 		  (long unsigned) gcov_position ());
28510d565efSmrg 	  break;
28610d565efSmrg 	}
28710d565efSmrg     }
28810d565efSmrg   gcov_close ();
28910d565efSmrg }
29010d565efSmrg 
29110d565efSmrg static void
tag_function(const char * filename ATTRIBUTE_UNUSED,unsigned tag ATTRIBUTE_UNUSED,unsigned length,unsigned depth ATTRIBUTE_UNUSED)29210d565efSmrg tag_function (const char *filename ATTRIBUTE_UNUSED,
293c7a68eb7Smrg 	      unsigned tag ATTRIBUTE_UNUSED, unsigned length,
294c7a68eb7Smrg 	      unsigned depth ATTRIBUTE_UNUSED)
29510d565efSmrg {
29610d565efSmrg   unsigned long pos = gcov_position ();
29710d565efSmrg 
29810d565efSmrg   if (!length)
29910d565efSmrg     printf (" placeholder");
30010d565efSmrg   else
30110d565efSmrg     {
30210d565efSmrg       printf (" ident=%u", gcov_read_unsigned ());
30310d565efSmrg       printf (", lineno_checksum=0x%08x", gcov_read_unsigned ());
30410d565efSmrg       printf (", cfg_checksum=0x%08x", gcov_read_unsigned ());
30510d565efSmrg 
30610d565efSmrg       if (gcov_position () - pos < length)
30710d565efSmrg 	{
30810d565efSmrg 	  const char *name;
30910d565efSmrg 
31010d565efSmrg 	  name = gcov_read_string ();
31110d565efSmrg 	  printf (", `%s'", name ? name : "NULL");
312c7a68eb7Smrg 	  unsigned artificial = gcov_read_unsigned ();
31310d565efSmrg 	  name = gcov_read_string ();
31410d565efSmrg 	  printf (" %s", name ? name : "NULL");
315c7a68eb7Smrg 	  unsigned line_start = gcov_read_unsigned ();
316c7a68eb7Smrg 	  unsigned column_start = gcov_read_unsigned ();
317c7a68eb7Smrg 	  unsigned line_end = gcov_read_unsigned ();
3180fc04c29Smrg 	  unsigned column_end = gcov_read_unsigned ();
3190fc04c29Smrg 	  printf (":%u:%u-%u:%u", line_start, column_start,
3200fc04c29Smrg 		  line_end, column_end);
321c7a68eb7Smrg 	  if (artificial)
322c7a68eb7Smrg 	    printf (", artificial");
32310d565efSmrg 	}
32410d565efSmrg     }
32510d565efSmrg }
32610d565efSmrg 
32710d565efSmrg static void
tag_blocks(const char * filename ATTRIBUTE_UNUSED,unsigned tag ATTRIBUTE_UNUSED,unsigned length ATTRIBUTE_UNUSED,unsigned depth ATTRIBUTE_UNUSED)32810d565efSmrg tag_blocks (const char *filename ATTRIBUTE_UNUSED,
329c7a68eb7Smrg 	    unsigned tag ATTRIBUTE_UNUSED, unsigned length ATTRIBUTE_UNUSED,
330c7a68eb7Smrg 	    unsigned depth ATTRIBUTE_UNUSED)
33110d565efSmrg {
332c7a68eb7Smrg   printf (" %u blocks", gcov_read_unsigned ());
33310d565efSmrg }
33410d565efSmrg 
33510d565efSmrg static void
tag_arcs(const char * filename ATTRIBUTE_UNUSED,unsigned tag ATTRIBUTE_UNUSED,unsigned length ATTRIBUTE_UNUSED,unsigned depth)33610d565efSmrg tag_arcs (const char *filename ATTRIBUTE_UNUSED,
337c7a68eb7Smrg 	  unsigned tag ATTRIBUTE_UNUSED, unsigned length ATTRIBUTE_UNUSED,
338c7a68eb7Smrg 	  unsigned depth)
33910d565efSmrg {
34010d565efSmrg   unsigned n_arcs = GCOV_TAG_ARCS_NUM (length);
34110d565efSmrg 
34210d565efSmrg   printf (" %u arcs", n_arcs);
34310d565efSmrg   if (flag_dump_contents)
34410d565efSmrg     {
34510d565efSmrg       unsigned ix;
34610d565efSmrg       unsigned blockno = gcov_read_unsigned ();
34710d565efSmrg 
34810d565efSmrg       for (ix = 0; ix != n_arcs; ix++)
34910d565efSmrg 	{
35010d565efSmrg 	  unsigned dst, flags;
35110d565efSmrg 
35210d565efSmrg 	  if (!(ix & 3))
35310d565efSmrg 	    {
35410d565efSmrg 	      printf ("\n");
355c7a68eb7Smrg 	      print_prefix (filename, depth, gcov_position ());
356c7a68eb7Smrg 	      printf (VALUE_PADDING_PREFIX "block %u:", blockno);
35710d565efSmrg 	    }
35810d565efSmrg 	  dst = gcov_read_unsigned ();
35910d565efSmrg 	  flags = gcov_read_unsigned ();
36010d565efSmrg 	  printf (" %u:%04x", dst, flags);
36110d565efSmrg 	  if (flags)
36210d565efSmrg 	    {
36310d565efSmrg 	      char c = '(';
36410d565efSmrg 
36510d565efSmrg 	      if (flags & GCOV_ARC_ON_TREE)
36610d565efSmrg 		printf ("%ctree", c), c = ',';
36710d565efSmrg 	      if (flags & GCOV_ARC_FAKE)
36810d565efSmrg 		printf ("%cfake", c), c = ',';
36910d565efSmrg 	      if (flags & GCOV_ARC_FALLTHROUGH)
37010d565efSmrg 		printf ("%cfall", c), c = ',';
37110d565efSmrg 	      printf (")");
37210d565efSmrg 	    }
37310d565efSmrg 	}
37410d565efSmrg     }
37510d565efSmrg }
37610d565efSmrg 
37710d565efSmrg static void
tag_lines(const char * filename ATTRIBUTE_UNUSED,unsigned tag ATTRIBUTE_UNUSED,unsigned length ATTRIBUTE_UNUSED,unsigned depth)37810d565efSmrg tag_lines (const char *filename ATTRIBUTE_UNUSED,
379c7a68eb7Smrg 	   unsigned tag ATTRIBUTE_UNUSED, unsigned length ATTRIBUTE_UNUSED,
380c7a68eb7Smrg 	   unsigned depth)
38110d565efSmrg {
38210d565efSmrg   if (flag_dump_contents)
38310d565efSmrg     {
38410d565efSmrg       unsigned blockno = gcov_read_unsigned ();
38510d565efSmrg       char const *sep = NULL;
38610d565efSmrg 
38710d565efSmrg       while (1)
38810d565efSmrg 	{
38910d565efSmrg 	  gcov_position_t position = gcov_position ();
39010d565efSmrg 	  const char *source = NULL;
39110d565efSmrg 	  unsigned lineno = gcov_read_unsigned ();
39210d565efSmrg 
39310d565efSmrg 	  if (!lineno)
39410d565efSmrg 	    {
39510d565efSmrg 	      source = gcov_read_string ();
39610d565efSmrg 	      if (!source)
39710d565efSmrg 		break;
39810d565efSmrg 	      sep = NULL;
39910d565efSmrg 	    }
40010d565efSmrg 
40110d565efSmrg 	  if (!sep)
40210d565efSmrg 	    {
40310d565efSmrg 	      printf ("\n");
404c7a68eb7Smrg 	      print_prefix (filename, depth, position);
405c7a68eb7Smrg 	      printf (VALUE_PADDING_PREFIX "block %u:", blockno);
40610d565efSmrg 	      sep = "";
40710d565efSmrg 	    }
40810d565efSmrg 	  if (lineno)
40910d565efSmrg 	    {
41010d565efSmrg 	      printf ("%s%u", sep, lineno);
41110d565efSmrg 	      sep = ", ";
41210d565efSmrg 	    }
41310d565efSmrg 	  else
41410d565efSmrg 	    {
41510d565efSmrg 	      printf ("%s`%s'", sep, source);
41610d565efSmrg 	      sep = ":";
41710d565efSmrg 	    }
41810d565efSmrg 	}
41910d565efSmrg     }
42010d565efSmrg }
42110d565efSmrg 
42210d565efSmrg static void
tag_counters(const char * filename ATTRIBUTE_UNUSED,unsigned tag ATTRIBUTE_UNUSED,unsigned length ATTRIBUTE_UNUSED,unsigned depth)42310d565efSmrg tag_counters (const char *filename ATTRIBUTE_UNUSED,
424c7a68eb7Smrg 	      unsigned tag ATTRIBUTE_UNUSED, unsigned length ATTRIBUTE_UNUSED,
425c7a68eb7Smrg 	      unsigned depth)
42610d565efSmrg {
42710d565efSmrg #define DEF_GCOV_COUNTER(COUNTER, NAME, MERGE_FN) NAME,
42810d565efSmrg   static const char *const counter_names[] = {
42910d565efSmrg #include "gcov-counter.def"
43010d565efSmrg };
43110d565efSmrg #undef DEF_GCOV_COUNTER
43210d565efSmrg   unsigned n_counts = GCOV_TAG_COUNTER_NUM (length);
43310d565efSmrg 
43410d565efSmrg   printf (" %s %u counts",
43510d565efSmrg 	  counter_names[GCOV_COUNTER_FOR_TAG (tag)], n_counts);
43610d565efSmrg   if (flag_dump_contents)
43710d565efSmrg     {
43810d565efSmrg       unsigned ix;
43910d565efSmrg 
44010d565efSmrg       for (ix = 0; ix != n_counts; ix++)
44110d565efSmrg 	{
44210d565efSmrg 	  gcov_type count;
44310d565efSmrg 
44410d565efSmrg 	  if (!(ix & 7))
44510d565efSmrg 	    {
44610d565efSmrg 	      printf ("\n");
447c7a68eb7Smrg 	      print_prefix (filename, depth, gcov_position ());
448c7a68eb7Smrg 	      printf (VALUE_PADDING_PREFIX VALUE_PREFIX, ix);
44910d565efSmrg 	    }
45010d565efSmrg 
45110d565efSmrg 	  count = gcov_read_counter ();
452c7a68eb7Smrg 	  printf ("%" PRId64 " ", count);
45310d565efSmrg 	}
45410d565efSmrg     }
45510d565efSmrg }
45610d565efSmrg 
45710d565efSmrg static void
tag_summary(const char * filename ATTRIBUTE_UNUSED,unsigned tag ATTRIBUTE_UNUSED,unsigned length ATTRIBUTE_UNUSED,unsigned depth ATTRIBUTE_UNUSED)45810d565efSmrg tag_summary (const char *filename ATTRIBUTE_UNUSED,
459c7a68eb7Smrg 	     unsigned tag ATTRIBUTE_UNUSED, unsigned length ATTRIBUTE_UNUSED,
4600fc04c29Smrg 	     unsigned depth ATTRIBUTE_UNUSED)
46110d565efSmrg {
4620fc04c29Smrg   gcov_summary summary;
46310d565efSmrg   gcov_read_summary (&summary);
4640fc04c29Smrg   printf (" runs=%d, sum_max=%" PRId64,
4650fc04c29Smrg 	  summary.runs, summary.sum_max);
46610d565efSmrg }
467