gcov.c revision 161651
1176348Smarcel/* Gcov.c: prepend line execution counts and branch probabilities to a
2176348Smarcel   source file.
3176348Smarcel   Copyright (C) 1990, 1991, 1992, 1993, 1994, 1996, 1997, 1998, 1999,
4176348Smarcel   2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
5176348Smarcel   Contributed by James E. Wilson of Cygnus Support.
6176348Smarcel   Mangled by Bob Manson of Cygnus Support.
7176348Smarcel   Mangled further by Nathan Sidwell <nathan@codesourcery.com>
8176348Smarcel
9176348SmarcelGcov is free software; you can redistribute it and/or modify
10176348Smarcelit under the terms of the GNU General Public License as published by
11176348Smarcelthe Free Software Foundation; either version 2, or (at your option)
12176348Smarcelany later version.
13176348Smarcel
14176348SmarcelGcov is distributed in the hope that it will be useful,
15176348Smarcelbut WITHOUT ANY WARRANTY; without even the implied warranty of
16176348SmarcelMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17176348SmarcelGNU General Public License for more details.
18176348Smarcel
19176348SmarcelYou should have received a copy of the GNU General Public License
20176348Smarcelalong with Gcov; see the file COPYING.  If not, write to
21176348Smarcelthe Free Software Foundation, 59 Temple Place - Suite 330,
22176348SmarcelBoston, MA 02111-1307, USA.  */
23176348Smarcel
24176348Smarcel/* ??? Print a list of the ten blocks with the highest execution counts,
25176348Smarcel   and list the line numbers corresponding to those blocks.  Also, perhaps
26176348Smarcel   list the line numbers with the highest execution counts, only printing
27176348Smarcel   the first if there are several which are all listed in the same block.  */
28176348Smarcel
29176348Smarcel/* ??? Should have an option to print the number of basic blocks, and the
30176348Smarcel   percent of them that are covered.  */
31176348Smarcel
32176348Smarcel/* ??? Does not correctly handle the case where two .bb files refer to
33176348Smarcel   the same included source file.  For example, if one has a short
34176348Smarcel   file containing only inline functions, which is then included in
35176348Smarcel   two other files, then there will be two .bb files which refer to
36176348Smarcel   the include file, but there is no way to get the total execution
37176348Smarcel   counts for the included file, can only get execution counts for one
38176348Smarcel   or the other of the including files. this can be fixed by --ratios
39176348Smarcel   --long-file-names --preserve-paths and perl.  */
40176348Smarcel
41176348Smarcel/* Need an option to show individual block counts, and show
42176348Smarcel   probabilities of fall through arcs.  */
43176348Smarcel
44176348Smarcel#include "config.h"
45176348Smarcel#include "system.h"
46176348Smarcel#include "coretypes.h"
47176348Smarcel#include "tm.h"
48176348Smarcel#include "intl.h"
49176348Smarcel#include "version.h"
50176348Smarcel#undef abort
51176348Smarcel
52176348Smarcel#include <getopt.h>
53176348Smarcel
54176348Smarcel#define IN_GCOV 1
55176348Smarcel#include "gcov-io.h"
56176348Smarcel#include "gcov-io.c"
57176348Smarcel
58176348Smarcel/* The bbg file is generated by -ftest-coverage option. The da file is
59176348Smarcel   generated by a program compiled with -fprofile-arcs. Their formats
60176348Smarcel   are documented in gcov-io.h.  */
61176348Smarcel
62/* The functions in this file for creating and solution program flow graphs
63   are very similar to functions in the gcc source file profile.c.  In
64   some places we make use of the knowledge of how profile.c works to
65   select particular algorithms here.  */
66
67/* This is the size of the buffer used to read in source file lines.  */
68
69#define STRING_SIZE 200
70
71struct function_info;
72struct block_info;
73struct source_info;
74
75/* Describes an arc between two basic blocks.  */
76
77typedef struct arc_info
78{
79  /* source and destination blocks.  */
80  struct block_info *src;
81  struct block_info *dst;
82
83  /* transition counts.  */
84  gcov_type count;
85  /* used in cycle search, so that we do not clobber original counts.  */
86  gcov_type cs_count;
87
88  unsigned int count_valid : 1;
89  unsigned int on_tree : 1;
90  unsigned int fake : 1;
91  unsigned int fall_through : 1;
92
93  /* Arc is for a function that abnormally returns.  */
94  unsigned int is_call_non_return : 1;
95
96  /* Arc is for catch/setjump.  */
97  unsigned int is_nonlocal_return : 1;
98
99  /* Is an unconditional branch.  */
100  unsigned int is_unconditional : 1;
101
102  /* Loop making arc.  */
103  unsigned int cycle : 1;
104
105  /* Next branch on line.  */
106  struct arc_info *line_next;
107
108  /* Links to next arc on src and dst lists.  */
109  struct arc_info *succ_next;
110  struct arc_info *pred_next;
111} arc_t;
112
113/* Describes a basic block. Contains lists of arcs to successor and
114   predecessor blocks.  */
115
116typedef struct block_info
117{
118  /* Chain of exit and entry arcs.  */
119  arc_t *succ;
120  arc_t *pred;
121
122  /* Number of unprocessed exit and entry arcs.  */
123  gcov_type num_succ;
124  gcov_type num_pred;
125
126  /* Block execution count.  */
127  gcov_type count;
128  unsigned flags : 13;
129  unsigned count_valid : 1;
130  unsigned valid_chain : 1;
131  unsigned invalid_chain : 1;
132
133  /* Block is a call instrumenting site.  */
134  unsigned is_call_site : 1; /* Does the call.  */
135  unsigned is_call_return : 1; /* Is the return.  */
136
137  /* Block is a landing pad for longjmp or throw.  */
138  unsigned is_nonlocal_return : 1;
139
140  union
141  {
142    struct
143    {
144     /* Array of line numbers and source files. source files are
145        introduced by a linenumber of zero, the next 'line number' is
146        the number of the source file.  Always starts with a source
147        file.  */
148      unsigned *encoding;
149      unsigned num;
150    } line; /* Valid until blocks are linked onto lines */
151    struct
152    {
153      /* Single line graph cycle workspace.  Used for all-blocks
154	 mode.  */
155      arc_t *arc;
156      unsigned ident;
157    } cycle; /* Used in all-blocks mode, after blocks are linked onto
158	       lines.  */
159  } u;
160
161  /* Temporary chain for solving graph, and for chaining blocks on one
162     line.  */
163  struct block_info *chain;
164
165} block_t;
166
167/* Describes a single function. Contains an array of basic blocks.  */
168
169typedef struct function_info
170{
171  /* Name of function.  */
172  char *name;
173  unsigned ident;
174  unsigned checksum;
175
176  /* Array of basic blocks.  */
177  block_t *blocks;
178  unsigned num_blocks;
179  unsigned blocks_executed;
180
181  /* Raw arc coverage counts.  */
182  gcov_type *counts;
183  unsigned num_counts;
184
185  /* First line number.  */
186  unsigned line;
187  struct source_info *src;
188
189  /* Next function in same source file.  */
190  struct function_info *line_next;
191
192  /* Next function.  */
193  struct function_info *next;
194} function_t;
195
196/* Describes coverage of a file or function.  */
197
198typedef struct coverage_info
199{
200  int lines;
201  int lines_executed;
202
203  int branches;
204  int branches_executed;
205  int branches_taken;
206
207  int calls;
208  int calls_executed;
209
210  char *name;
211} coverage_t;
212
213/* Describes a single line of source. Contains a chain of basic blocks
214   with code on it.  */
215
216typedef struct line_info
217{
218  gcov_type count;	   /* execution count */
219  union
220  {
221    arc_t *branches;	   /* branches from blocks that end on this
222			      line. Used for branch-counts when not
223			      all-blocks mode.  */
224    block_t *blocks;       /* blocks which start on this line.  Used
225			      in all-blocks mode.  */
226  } u;
227  unsigned exists : 1;
228} line_t;
229
230/* Describes a file mentioned in the block graph.  Contains an array
231   of line info.  */
232
233typedef struct source_info
234{
235  /* Name of source file.  */
236  char *name;
237  unsigned index;
238
239  /* Array of line information.  */
240  line_t *lines;
241  unsigned num_lines;
242
243  coverage_t coverage;
244
245  /* Functions in this source file.  These are in ascending line
246     number order.  */
247  function_t *functions;
248
249  /* Next source file.  */
250  struct source_info *next;
251} source_t;
252
253/* Holds a list of function basic block graphs.  */
254
255static function_t *functions;
256
257/* This points to the head of the sourcefile structure list.  */
258
259static source_t *sources;
260
261/* This holds data summary information.  */
262
263static struct gcov_summary object_summary;
264static unsigned program_count;
265
266/* Modification time of graph file.  */
267
268static time_t bbg_file_time;
269
270/* Name and file pointer of the input file for the basic block graph.  */
271
272static char *bbg_file_name;
273
274/* Stamp of the bbg file */
275static unsigned bbg_stamp;
276
277/* Name and file pointer of the input file for the arc count data.  */
278
279static char *da_file_name;
280
281/* Output branch probabilities.  */
282
283static int flag_branches = 0;
284
285/* Show unconditional branches too.  */
286static int flag_unconditional = 0;
287
288/* Output a gcov file if this is true.  This is on by default, and can
289   be turned off by the -n option.  */
290
291static int flag_gcov_file = 1;
292
293/* For included files, make the gcov output file name include the name
294   of the input source file.  For example, if x.h is included in a.c,
295   then the output file name is a.c##x.h.gcov instead of x.h.gcov.  */
296
297static int flag_long_names = 0;
298
299/* Output count information for every basic block, not merely those
300   that contain line number information.  */
301
302static int flag_all_blocks = 0;
303
304/* Output summary info for each function.  */
305
306static int flag_function_summary = 0;
307
308/* Object directory file prefix.  This is the directory/file where the
309   graph and data files are looked for, if nonzero.  */
310
311static char *object_directory = 0;
312
313/* Preserve all pathname components. Needed when object files and
314   source files are in subdirectories. '/' is mangled as '#', '.' is
315   elided and '..' mangled to '^'.  */
316
317static int flag_preserve_paths = 0;
318
319/* Output the number of times a branch was taken as opposed to the percentage
320   of times it was taken.  */
321
322static int flag_counts = 0;
323
324/* Forward declarations.  */
325static void fnotice (FILE *, const char *, ...) ATTRIBUTE_PRINTF_2;
326static int process_args (int, char **);
327static void print_usage (int) ATTRIBUTE_NORETURN;
328static void print_version (void) ATTRIBUTE_NORETURN;
329static void process_file (const char *);
330static void create_file_names (const char *);
331static source_t *find_source (const char *);
332static int read_graph_file (void);
333static int read_count_file (void);
334static void solve_flow_graph (function_t *);
335static void add_branch_counts (coverage_t *, const arc_t *);
336static void add_line_counts (coverage_t *, function_t *);
337static void function_summary (const coverage_t *, const char *);
338static const char *format_gcov (gcov_type, gcov_type, int);
339static void accumulate_line_counts (source_t *);
340static int output_branch_count (FILE *, int, const arc_t *);
341static void output_lines (FILE *, const source_t *);
342static char *make_gcov_file_name (const char *, const char *);
343static void release_structures (void);
344extern int main (int, char **);
345
346int
347main (int argc, char **argv)
348{
349  int argno;
350
351  gcc_init_libintl ();
352
353  argno = process_args (argc, argv);
354  if (optind == argc)
355    print_usage (true);
356
357  for (; argno != argc; argno++)
358    {
359      release_structures ();
360
361      process_file (argv[argno]);
362    }
363
364  return 0;
365}
366
367static void
368fnotice (FILE *file, const char *msgid, ...)
369{
370  va_list ap;
371
372  va_start (ap, msgid);
373  vfprintf (file, _(msgid), ap);
374  va_end (ap);
375}
376
377/* More 'friendly' abort that prints the line and file.
378   config.h can #define abort fancy_abort if you like that sort of thing.  */
379extern void fancy_abort (void) ATTRIBUTE_NORETURN;
380
381void
382fancy_abort (void)
383{
384  fnotice (stderr, "Internal gcov abort.\n");
385  exit (FATAL_EXIT_CODE);
386}
387
388/* Print a usage message and exit.  If ERROR_P is nonzero, this is an error,
389   otherwise the output of --help.  */
390
391static void
392print_usage (int error_p)
393{
394  FILE *file = error_p ? stderr : stdout;
395  int status = error_p ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE;
396
397  fnotice (file, "Usage: gcov [OPTION]... SOURCEFILE\n\n");
398  fnotice (file, "Print code coverage information.\n\n");
399  fnotice (file, "  -h, --help                      Print this help, then exit\n");
400  fnotice (file, "  -v, --version                   Print version number, then exit\n");
401  fnotice (file, "  -a, --all-blocks                Show information for every basic block\n");
402  fnotice (file, "  -b, --branch-probabilities      Include branch probabilities in output\n");
403  fnotice (file, "  -c, --branch-counts             Given counts of branches taken\n\
404                                    rather than percentages\n");
405  fnotice (file, "  -n, --no-output                 Do not create an output file\n");
406  fnotice (file, "  -l, --long-file-names           Use long output file names for included\n\
407                                    source files\n");
408  fnotice (file, "  -f, --function-summaries        Output summaries for each function\n");
409  fnotice (file, "  -o, --object-directory DIR|FILE Search for object files in DIR or called FILE\n");
410  fnotice (file, "  -p, --preserve-paths            Preserve all pathname components\n");
411  fnotice (file, "  -u, --unconditional-branches    Show unconditional branch counts too\n");
412  fnotice (file, "\nFor bug reporting instructions, please see:\n%s.\n",
413	   bug_report_url);
414  exit (status);
415}
416
417/* Print version information and exit.  */
418
419static void
420print_version (void)
421{
422  fnotice (stdout, "gcov (GCC) %s\n", version_string);
423  fprintf (stdout, "Copyright %s 2006 Free Software Foundation, Inc.\n",
424	   _("(C)"));
425  fnotice (stdout,
426	   _("This is free software; see the source for copying conditions.\n"
427	     "There is NO warranty; not even for MERCHANTABILITY or \n"
428	     "FITNESS FOR A PARTICULAR PURPOSE.\n\n"));
429  exit (SUCCESS_EXIT_CODE);
430}
431
432static const struct option options[] =
433{
434  { "help",                 no_argument,       NULL, 'h' },
435  { "version",              no_argument,       NULL, 'v' },
436  { "all-blocks",           no_argument,       NULL, 'a' },
437  { "branch-probabilities", no_argument,       NULL, 'b' },
438  { "branch-counts",        no_argument,       NULL, 'c' },
439  { "no-output",            no_argument,       NULL, 'n' },
440  { "long-file-names",      no_argument,       NULL, 'l' },
441  { "function-summaries",   no_argument,       NULL, 'f' },
442  { "preserve-paths",       no_argument,       NULL, 'p' },
443  { "object-directory",     required_argument, NULL, 'o' },
444  { "object-file",          required_argument, NULL, 'o' },
445  { "unconditional-branches", no_argument,     NULL, 'u' },
446  { 0, 0, 0, 0 }
447};
448
449/* Process args, return index to first non-arg.  */
450
451static int
452process_args (int argc, char **argv)
453{
454  int opt;
455
456  while ((opt = getopt_long (argc, argv, "abcfhlno:puv", options, NULL)) != -1)
457    {
458      switch (opt)
459	{
460	case 'a':
461	  flag_all_blocks = 1;
462	  break;
463	case 'b':
464	  flag_branches = 1;
465	  break;
466	case 'c':
467	  flag_counts = 1;
468	  break;
469	case 'f':
470	  flag_function_summary = 1;
471	  break;
472	case 'h':
473	  print_usage (false);
474	  /* print_usage will exit.  */
475	case 'l':
476	  flag_long_names = 1;
477	  break;
478	case 'n':
479	  flag_gcov_file = 0;
480	  break;
481	case 'o':
482	  object_directory = optarg;
483	  break;
484	case 'p':
485	  flag_preserve_paths = 1;
486	  break;
487	case 'u':
488	  flag_unconditional = 1;
489	  break;
490	case 'v':
491	  print_version ();
492	  /* print_version will exit.  */
493	default:
494	  print_usage (true);
495	  /* print_usage will exit.  */
496	}
497    }
498
499  return optind;
500}
501
502/* Process a single source file.  */
503
504static void
505process_file (const char *file_name)
506{
507  source_t *src;
508  function_t *fn;
509
510  create_file_names (file_name);
511  if (read_graph_file ())
512    return;
513
514  if (!functions)
515    {
516      fnotice (stderr, "%s:no functions found\n", bbg_file_name);
517      return;
518    }
519
520  if (read_count_file ())
521    return;
522
523  for (fn = functions; fn; fn = fn->next)
524    solve_flow_graph (fn);
525  for (src = sources; src; src = src->next)
526    src->lines = xcalloc (src->num_lines, sizeof (line_t));
527  for (fn = functions; fn; fn = fn->next)
528    {
529      coverage_t coverage;
530
531      memset (&coverage, 0, sizeof (coverage));
532      coverage.name = fn->name;
533      add_line_counts (flag_function_summary ? &coverage : NULL, fn);
534      if (flag_function_summary)
535	{
536	  function_summary (&coverage, "Function");
537	  fnotice (stdout, "\n");
538	}
539    }
540
541  for (src = sources; src; src = src->next)
542    {
543      accumulate_line_counts (src);
544      function_summary (&src->coverage, "File");
545      if (flag_gcov_file)
546	{
547	  char *gcov_file_name = make_gcov_file_name (file_name, src->name);
548	  FILE *gcov_file = fopen (gcov_file_name, "w");
549
550	  if (gcov_file)
551	    {
552	      fnotice (stdout, "%s:creating `%s'\n",
553		       src->name, gcov_file_name);
554	      output_lines (gcov_file, src);
555	      if (ferror (gcov_file))
556		    fnotice (stderr, "%s:error writing output file `%s'\n",
557			     src->name, gcov_file_name);
558	      fclose (gcov_file);
559	    }
560	  else
561	    fnotice (stderr, "%s:could not open output file `%s'\n",
562		     src->name, gcov_file_name);
563	  free (gcov_file_name);
564	}
565      fnotice (stdout, "\n");
566    }
567}
568
569/* Release all memory used.  */
570
571static void
572release_structures (void)
573{
574  function_t *fn;
575  source_t *src;
576
577  free (bbg_file_name);
578  free (da_file_name);
579  da_file_name = bbg_file_name = NULL;
580  bbg_file_time = 0;
581  bbg_stamp = 0;
582
583  while ((src = sources))
584    {
585      sources = src->next;
586
587      free (src->name);
588      free (src->lines);
589    }
590
591  while ((fn = functions))
592    {
593      unsigned ix;
594      block_t *block;
595
596      functions = fn->next;
597      for (ix = fn->num_blocks, block = fn->blocks; ix--; block++)
598	{
599	  arc_t *arc, *arc_n;
600
601	  for (arc = block->succ; arc; arc = arc_n)
602	    {
603	      arc_n = arc->succ_next;
604	      free (arc);
605	    }
606	}
607      free (fn->blocks);
608      free (fn->counts);
609    }
610}
611
612/* Generate the names of the graph and data files. If OBJECT_DIRECTORY
613   is not specified, these are looked for in the current directory,
614   and named from the basename of the FILE_NAME sans extension. If
615   OBJECT_DIRECTORY is specified and is a directory, the files are in
616   that directory, but named from the basename of the FILE_NAME, sans
617   extension. Otherwise OBJECT_DIRECTORY is taken to be the name of
618   the object *file*, and the data files are named from that.  */
619
620static void
621create_file_names (const char *file_name)
622{
623  char *cptr;
624  char *name;
625  int length = strlen (file_name);
626  int base;
627
628  if (object_directory && object_directory[0])
629    {
630      struct stat status;
631
632      length += strlen (object_directory) + 2;
633      name = xmalloc (length);
634      name[0] = 0;
635
636      base = !stat (object_directory, &status) && S_ISDIR (status.st_mode);
637      strcat (name, object_directory);
638      if (base && name[strlen (name) - 1] != '/')
639	strcat (name, "/");
640    }
641  else
642    {
643      name = xmalloc (length + 1);
644      name[0] = 0;
645      base = 1;
646    }
647
648  if (base)
649    {
650      /* Append source file name.  */
651      cptr = strrchr (file_name, '/');
652      strcat (name, cptr ? cptr + 1 : file_name);
653    }
654
655  /* Remove the extension.  */
656  cptr = strrchr (name, '.');
657  if (cptr)
658    *cptr = 0;
659
660  length = strlen (name);
661
662  bbg_file_name = xmalloc (length + strlen (GCOV_NOTE_SUFFIX) + 1);
663  strcpy (bbg_file_name, name);
664  strcpy (bbg_file_name + length, GCOV_NOTE_SUFFIX);
665
666  da_file_name = xmalloc (length + strlen (GCOV_DATA_SUFFIX) + 1);
667  strcpy (da_file_name, name);
668  strcpy (da_file_name + length, GCOV_DATA_SUFFIX);
669
670  return;
671}
672
673/* Find or create a source file structure for FILE_NAME. Copies
674   FILE_NAME on creation */
675
676static source_t *
677find_source (const char *file_name)
678{
679  source_t *src;
680
681  if (!file_name)
682    file_name = "<unknown>";
683
684  for (src = sources; src; src = src->next)
685    if (!strcmp (file_name, src->name))
686      return src;
687
688  src = xcalloc (1, sizeof (source_t));
689  src->name = xstrdup (file_name);
690  src->coverage.name = src->name;
691  src->index = sources ? sources->index + 1 : 1;
692  src->next = sources;
693  sources = src;
694
695  return src;
696}
697
698/* Read the graph file. Return nonzero on fatal error.  */
699
700static int
701read_graph_file (void)
702{
703  unsigned version;
704  unsigned current_tag = 0;
705  struct function_info *fn = NULL;
706  source_t *src = NULL;
707  unsigned ix;
708  unsigned tag;
709
710  if (!gcov_open (bbg_file_name, 1))
711    {
712      fnotice (stderr, "%s:cannot open graph file\n", bbg_file_name);
713      return 1;
714    }
715  bbg_file_time = gcov_time ();
716  if (!gcov_magic (gcov_read_unsigned (), GCOV_NOTE_MAGIC))
717    {
718      fnotice (stderr, "%s:not a gcov graph file\n", bbg_file_name);
719      gcov_close ();
720      return 1;
721    }
722
723  version = gcov_read_unsigned ();
724  if (version != GCOV_VERSION)
725    {
726      char v[4], e[4];
727
728      GCOV_UNSIGNED2STRING (v, version);
729      GCOV_UNSIGNED2STRING (e, GCOV_VERSION);
730
731      fnotice (stderr, "%s:version `%.4s', prefer `%.4s'\n",
732	       bbg_file_name, v, e);
733    }
734  bbg_stamp = gcov_read_unsigned ();
735
736  while ((tag = gcov_read_unsigned ()))
737    {
738      unsigned length = gcov_read_unsigned ();
739      gcov_position_t base = gcov_position ();
740
741      if (tag == GCOV_TAG_FUNCTION)
742	{
743	  char *function_name;
744	  unsigned ident, checksum, lineno;
745	  source_t *src;
746	  function_t *probe, *prev;
747
748	  ident = gcov_read_unsigned ();
749	  checksum = gcov_read_unsigned ();
750	  function_name = xstrdup (gcov_read_string ());
751	  src = find_source (gcov_read_string ());
752	  lineno = gcov_read_unsigned ();
753
754	  fn = xcalloc (1, sizeof (function_t));
755	  fn->name = function_name;
756	  fn->ident = ident;
757	  fn->checksum = checksum;
758	  fn->src = src;
759	  fn->line = lineno;
760
761	  fn->next = functions;
762	  functions = fn;
763	  current_tag = tag;
764
765	  if (lineno >= src->num_lines)
766	    src->num_lines = lineno + 1;
767	  /* Now insert it into the source file's list of
768	     functions. Normally functions will be encountered in
769	     ascending order, so a simple scan is quick.  */
770	  for (probe = src->functions, prev = NULL;
771	       probe && probe->line > lineno;
772	       prev = probe, probe = probe->line_next)
773	    continue;
774	  fn->line_next = probe;
775	  if (prev)
776	    prev->line_next = fn;
777	  else
778	    src->functions = fn;
779	}
780      else if (fn && tag == GCOV_TAG_BLOCKS)
781	{
782	  if (fn->blocks)
783	    fnotice (stderr, "%s:already seen blocks for `%s'\n",
784		     bbg_file_name, fn->name);
785	  else
786	    {
787	      unsigned ix, num_blocks = GCOV_TAG_BLOCKS_NUM (length);
788	      fn->num_blocks = num_blocks;
789
790	      fn->blocks = xcalloc (fn->num_blocks, sizeof (block_t));
791	      for (ix = 0; ix != num_blocks; ix++)
792		fn->blocks[ix].flags = gcov_read_unsigned ();
793	    }
794	}
795      else if (fn && tag == GCOV_TAG_ARCS)
796	{
797	  unsigned src = gcov_read_unsigned ();
798	  unsigned num_dests = GCOV_TAG_ARCS_NUM (length);
799
800	  if (src >= fn->num_blocks || fn->blocks[src].succ)
801	    goto corrupt;
802
803	  while (num_dests--)
804	    {
805	      struct arc_info *arc;
806	      unsigned dest = gcov_read_unsigned ();
807	      unsigned flags = gcov_read_unsigned ();
808
809	      if (dest >= fn->num_blocks)
810		goto corrupt;
811	      arc = xcalloc (1, sizeof (arc_t));
812
813	      arc->dst = &fn->blocks[dest];
814	      arc->src = &fn->blocks[src];
815
816	      arc->count = 0;
817	      arc->count_valid = 0;
818	      arc->on_tree = !!(flags & GCOV_ARC_ON_TREE);
819	      arc->fake = !!(flags & GCOV_ARC_FAKE);
820	      arc->fall_through = !!(flags & GCOV_ARC_FALLTHROUGH);
821
822	      arc->succ_next = fn->blocks[src].succ;
823	      fn->blocks[src].succ = arc;
824	      fn->blocks[src].num_succ++;
825
826	      arc->pred_next = fn->blocks[dest].pred;
827	      fn->blocks[dest].pred = arc;
828	      fn->blocks[dest].num_pred++;
829
830	      if (arc->fake)
831		{
832		  if (src)
833		    {
834		      /* Exceptional exit from this function, the
835			 source block must be a call.  */
836		      fn->blocks[src].is_call_site = 1;
837		      arc->is_call_non_return = 1;
838		    }
839		  else
840		    {
841		      /* Non-local return from a callee of this
842		         function. The destination block is a catch or
843		         setjmp.  */
844		      arc->is_nonlocal_return = 1;
845		      fn->blocks[dest].is_nonlocal_return = 1;
846		    }
847		}
848
849	      if (!arc->on_tree)
850		fn->num_counts++;
851	    }
852	}
853      else if (fn && tag == GCOV_TAG_LINES)
854	{
855	  unsigned blockno = gcov_read_unsigned ();
856	  unsigned *line_nos = xcalloc (length - 1, sizeof (unsigned));
857
858	  if (blockno >= fn->num_blocks || fn->blocks[blockno].u.line.encoding)
859	    goto corrupt;
860
861	  for (ix = 0; ;  )
862	    {
863	      unsigned lineno = gcov_read_unsigned ();
864
865	      if (lineno)
866		{
867		  if (!ix)
868		    {
869		      line_nos[ix++] = 0;
870		      line_nos[ix++] = src->index;
871		    }
872		  line_nos[ix++] = lineno;
873		  if (lineno >= src->num_lines)
874		    src->num_lines = lineno + 1;
875		}
876	      else
877		{
878		  const char *file_name = gcov_read_string ();
879
880		  if (!file_name)
881		    break;
882		  src = find_source (file_name);
883
884		  line_nos[ix++] = 0;
885		  line_nos[ix++] = src->index;
886		}
887	    }
888
889	  fn->blocks[blockno].u.line.encoding = line_nos;
890	  fn->blocks[blockno].u.line.num = ix;
891	}
892      else if (current_tag && !GCOV_TAG_IS_SUBTAG (current_tag, tag))
893	{
894	  fn = NULL;
895	  current_tag = 0;
896	}
897      gcov_sync (base, length);
898      if (gcov_is_error ())
899	break;
900    }
901  if (!gcov_is_eof ())
902    {
903    corrupt:;
904      fnotice (stderr, "%s:corrupted\n", bbg_file_name);
905      gcov_close ();
906      return 1;
907    }
908  gcov_close ();
909
910  /* We built everything backwards, so nreverse them all.  */
911
912  /* Reverse sources. Not strictly necessary, but we'll then process
913     them in the 'expected' order.  */
914  {
915    source_t *src, *src_p, *src_n;
916
917    for (src_p = NULL, src = sources; src; src_p = src, src = src_n)
918      {
919	src_n = src->next;
920	src->next = src_p;
921      }
922    sources =  src_p;
923  }
924
925  /* Reverse functions.  */
926  {
927    function_t *fn, *fn_p, *fn_n;
928
929    for (fn_p = NULL, fn = functions; fn; fn_p = fn, fn = fn_n)
930      {
931	unsigned ix;
932
933	fn_n = fn->next;
934	fn->next = fn_p;
935
936	/* Reverse the arcs.  */
937	for (ix = fn->num_blocks; ix--;)
938	  {
939	    arc_t *arc, *arc_p, *arc_n;
940
941	    for (arc_p = NULL, arc = fn->blocks[ix].succ; arc;
942		 arc_p = arc, arc = arc_n)
943	      {
944		arc_n = arc->succ_next;
945		arc->succ_next = arc_p;
946	      }
947	    fn->blocks[ix].succ = arc_p;
948
949	    for (arc_p = NULL, arc = fn->blocks[ix].pred; arc;
950		 arc_p = arc, arc = arc_n)
951	      {
952		arc_n = arc->pred_next;
953		arc->pred_next = arc_p;
954	      }
955	    fn->blocks[ix].pred = arc_p;
956	  }
957      }
958    functions = fn_p;
959  }
960  return 0;
961}
962
963/* Reads profiles from the count file and attach to each
964   function. Return nonzero if fatal error.  */
965
966static int
967read_count_file (void)
968{
969  unsigned ix;
970  unsigned version;
971  unsigned tag;
972  function_t *fn = NULL;
973  int error = 0;
974
975  if (!gcov_open (da_file_name, 1))
976    {
977      fnotice (stderr, "%s:cannot open data file\n", da_file_name);
978      return 1;
979    }
980  if (!gcov_magic (gcov_read_unsigned (), GCOV_DATA_MAGIC))
981    {
982      fnotice (stderr, "%s:not a gcov data file\n", da_file_name);
983    cleanup:;
984      gcov_close ();
985      return 1;
986    }
987  version = gcov_read_unsigned ();
988  if (version != GCOV_VERSION)
989    {
990      char v[4], e[4];
991
992      GCOV_UNSIGNED2STRING (v, version);
993      GCOV_UNSIGNED2STRING (e, GCOV_VERSION);
994
995      fnotice (stderr, "%s:version `%.4s', prefer version `%.4s'\n",
996	       da_file_name, v, e);
997    }
998  tag = gcov_read_unsigned ();
999  if (tag != bbg_stamp)
1000    {
1001      fnotice (stderr, "%s:stamp mismatch with graph file\n", da_file_name);
1002      goto cleanup;
1003    }
1004
1005  while ((tag = gcov_read_unsigned ()))
1006    {
1007      unsigned length = gcov_read_unsigned ();
1008      unsigned long base = gcov_position ();
1009
1010      if (tag == GCOV_TAG_OBJECT_SUMMARY)
1011	gcov_read_summary (&object_summary);
1012      else if (tag == GCOV_TAG_PROGRAM_SUMMARY)
1013	program_count++;
1014      else if (tag == GCOV_TAG_FUNCTION)
1015	{
1016	  unsigned ident = gcov_read_unsigned ();
1017	  struct function_info *fn_n = functions;
1018
1019	  for (fn = fn ? fn->next : NULL; ; fn = fn->next)
1020	    {
1021	      if (fn)
1022		;
1023	      else if ((fn = fn_n))
1024		fn_n = NULL;
1025	      else
1026		{
1027		  fnotice (stderr, "%s:unknown function `%u'\n",
1028			   da_file_name, ident);
1029		  break;
1030		}
1031	      if (fn->ident == ident)
1032		break;
1033	    }
1034
1035	  if (!fn)
1036	    ;
1037	  else if (gcov_read_unsigned () != fn->checksum)
1038	    {
1039	    mismatch:;
1040	      fnotice (stderr, "%s:profile mismatch for `%s'\n",
1041		       da_file_name, fn->name);
1042	      goto cleanup;
1043	    }
1044	}
1045      else if (tag == GCOV_TAG_FOR_COUNTER (GCOV_COUNTER_ARCS) && fn)
1046	{
1047	  if (length != GCOV_TAG_COUNTER_LENGTH (fn->num_counts))
1048	    goto mismatch;
1049
1050	  if (!fn->counts)
1051	    fn->counts = xcalloc (fn->num_counts, sizeof (gcov_type));
1052
1053	  for (ix = 0; ix != fn->num_counts; ix++)
1054	    fn->counts[ix] += gcov_read_counter ();
1055	}
1056      gcov_sync (base, length);
1057      if ((error = gcov_is_error ()))
1058	break;
1059    }
1060
1061  if (!gcov_is_eof ())
1062    {
1063      fnotice (stderr, error < 0 ? "%s:overflowed\n" : "%s:corrupted\n",
1064	       da_file_name);
1065      goto cleanup;
1066    }
1067
1068  gcov_close ();
1069  return 0;
1070}
1071
1072/* Solve the flow graph. Propagate counts from the instrumented arcs
1073   to the blocks and the uninstrumented arcs.  */
1074
1075static void
1076solve_flow_graph (function_t *fn)
1077{
1078  unsigned ix;
1079  arc_t *arc;
1080  gcov_type *count_ptr = fn->counts;
1081  block_t *blk;
1082  block_t *valid_blocks = NULL;    /* valid, but unpropagated blocks.  */
1083  block_t *invalid_blocks = NULL;  /* invalid, but inferable blocks.  */
1084
1085  if (fn->num_blocks < 2)
1086    fnotice (stderr, "%s:`%s' lacks entry and/or exit blocks\n",
1087	     bbg_file_name, fn->name);
1088  else
1089    {
1090      if (fn->blocks[0].num_pred)
1091	fnotice (stderr, "%s:`%s' has arcs to entry block\n",
1092		 bbg_file_name, fn->name);
1093      else
1094	/* We can't deduce the entry block counts from the lack of
1095	   predecessors.  */
1096	fn->blocks[0].num_pred = ~(unsigned)0;
1097
1098      if (fn->blocks[fn->num_blocks - 1].num_succ)
1099	fnotice (stderr, "%s:`%s' has arcs from exit block\n",
1100		 bbg_file_name, fn->name);
1101      else
1102	/* Likewise, we can't deduce exit block counts from the lack
1103	   of its successors.  */
1104	fn->blocks[fn->num_blocks - 1].num_succ = ~(unsigned)0;
1105    }
1106
1107  /* Propagate the measured counts, this must be done in the same
1108     order as the code in profile.c  */
1109  for (ix = 0, blk = fn->blocks; ix != fn->num_blocks; ix++, blk++)
1110    {
1111      block_t const *prev_dst = NULL;
1112      int out_of_order = 0;
1113      int non_fake_succ = 0;
1114
1115      for (arc = blk->succ; arc; arc = arc->succ_next)
1116	{
1117	  if (!arc->fake)
1118	    non_fake_succ++;
1119
1120	  if (!arc->on_tree)
1121	    {
1122	      if (count_ptr)
1123		arc->count = *count_ptr++;
1124	      arc->count_valid = 1;
1125	      blk->num_succ--;
1126	      arc->dst->num_pred--;
1127	    }
1128	  if (prev_dst && prev_dst > arc->dst)
1129	    out_of_order = 1;
1130	  prev_dst = arc->dst;
1131	}
1132      if (non_fake_succ == 1)
1133	{
1134	  /* If there is only one non-fake exit, it is an
1135	     unconditional branch.  */
1136	  for (arc = blk->succ; arc; arc = arc->succ_next)
1137	    if (!arc->fake)
1138	      {
1139		arc->is_unconditional = 1;
1140		/* If this block is instrumenting a call, it might be
1141		   an artificial block. It is not artificial if it has
1142		   a non-fallthrough exit, or the destination of this
1143		   arc has more than one entry.  Mark the destination
1144		   block as a return site, if none of those conditions
1145		   hold.  */
1146		if (blk->is_call_site && arc->fall_through
1147		    && arc->dst->pred == arc && !arc->pred_next)
1148		  arc->dst->is_call_return = 1;
1149	      }
1150	}
1151
1152      /* Sort the successor arcs into ascending dst order. profile.c
1153	 normally produces arcs in the right order, but sometimes with
1154	 one or two out of order.  We're not using a particularly
1155	 smart sort.  */
1156      if (out_of_order)
1157	{
1158	  arc_t *start = blk->succ;
1159	  unsigned changes = 1;
1160
1161	  while (changes)
1162	    {
1163	      arc_t *arc, *arc_p, *arc_n;
1164
1165	      changes = 0;
1166	      for (arc_p = NULL, arc = start; (arc_n = arc->succ_next);)
1167		{
1168		  if (arc->dst > arc_n->dst)
1169		    {
1170		      changes = 1;
1171		      if (arc_p)
1172			arc_p->succ_next = arc_n;
1173		      else
1174			start = arc_n;
1175		      arc->succ_next = arc_n->succ_next;
1176		      arc_n->succ_next = arc;
1177		      arc_p = arc_n;
1178		    }
1179		  else
1180		    {
1181		      arc_p = arc;
1182		      arc = arc_n;
1183		    }
1184		}
1185	    }
1186	  blk->succ = start;
1187	}
1188
1189      /* Place it on the invalid chain, it will be ignored if that's
1190	 wrong.  */
1191      blk->invalid_chain = 1;
1192      blk->chain = invalid_blocks;
1193      invalid_blocks = blk;
1194    }
1195
1196  while (invalid_blocks || valid_blocks)
1197    {
1198      while ((blk = invalid_blocks))
1199	{
1200	  gcov_type total = 0;
1201	  const arc_t *arc;
1202
1203	  invalid_blocks = blk->chain;
1204	  blk->invalid_chain = 0;
1205	  if (!blk->num_succ)
1206	    for (arc = blk->succ; arc; arc = arc->succ_next)
1207	      total += arc->count;
1208	  else if (!blk->num_pred)
1209	    for (arc = blk->pred; arc; arc = arc->pred_next)
1210	      total += arc->count;
1211	  else
1212	    continue;
1213
1214	  blk->count = total;
1215	  blk->count_valid = 1;
1216	  blk->chain = valid_blocks;
1217	  blk->valid_chain = 1;
1218	  valid_blocks = blk;
1219	}
1220      while ((blk = valid_blocks))
1221	{
1222	  gcov_type total;
1223	  arc_t *arc, *inv_arc;
1224
1225	  valid_blocks = blk->chain;
1226	  blk->valid_chain = 0;
1227	  if (blk->num_succ == 1)
1228	    {
1229	      block_t *dst;
1230
1231	      total = blk->count;
1232	      inv_arc = NULL;
1233	      for (arc = blk->succ; arc; arc = arc->succ_next)
1234		{
1235		  total -= arc->count;
1236		  if (!arc->count_valid)
1237		    inv_arc = arc;
1238		}
1239	      dst = inv_arc->dst;
1240	      inv_arc->count_valid = 1;
1241	      inv_arc->count = total;
1242	      blk->num_succ--;
1243	      dst->num_pred--;
1244	      if (dst->count_valid)
1245		{
1246		  if (dst->num_pred == 1 && !dst->valid_chain)
1247		    {
1248		      dst->chain = valid_blocks;
1249		      dst->valid_chain = 1;
1250		      valid_blocks = dst;
1251		    }
1252		}
1253	      else
1254		{
1255		  if (!dst->num_pred && !dst->invalid_chain)
1256		    {
1257		      dst->chain = invalid_blocks;
1258		      dst->invalid_chain = 1;
1259		      invalid_blocks = dst;
1260		    }
1261		}
1262	    }
1263	  if (blk->num_pred == 1)
1264	    {
1265	      block_t *src;
1266
1267	      total = blk->count;
1268	      inv_arc = NULL;
1269	      for (arc = blk->pred; arc; arc = arc->pred_next)
1270		{
1271		  total -= arc->count;
1272		  if (!arc->count_valid)
1273		    inv_arc = arc;
1274		}
1275	      src = inv_arc->src;
1276	      inv_arc->count_valid = 1;
1277	      inv_arc->count = total;
1278	      blk->num_pred--;
1279	      src->num_succ--;
1280	      if (src->count_valid)
1281		{
1282		  if (src->num_succ == 1 && !src->valid_chain)
1283		    {
1284		      src->chain = valid_blocks;
1285		      src->valid_chain = 1;
1286		      valid_blocks = src;
1287		    }
1288		}
1289	      else
1290		{
1291		  if (!src->num_succ && !src->invalid_chain)
1292		    {
1293		      src->chain = invalid_blocks;
1294		      src->invalid_chain = 1;
1295		      invalid_blocks = src;
1296		    }
1297		}
1298	    }
1299	}
1300    }
1301
1302  /* If the graph has been correctly solved, every block will have a
1303     valid count.  */
1304  for (ix = 0; ix < fn->num_blocks; ix++)
1305    if (!fn->blocks[ix].count_valid)
1306      {
1307	fnotice (stderr, "%s:graph is unsolvable for `%s'\n",
1308		 bbg_file_name, fn->name);
1309	break;
1310      }
1311}
1312
1313
1314
1315/* Increment totals in COVERAGE according to arc ARC.  */
1316
1317static void
1318add_branch_counts (coverage_t *coverage, const arc_t *arc)
1319{
1320  if (arc->is_call_non_return)
1321    {
1322      coverage->calls++;
1323      if (arc->src->count)
1324	coverage->calls_executed++;
1325    }
1326  else if (!arc->is_unconditional)
1327    {
1328      coverage->branches++;
1329      if (arc->src->count)
1330	coverage->branches_executed++;
1331      if (arc->count)
1332	coverage->branches_taken++;
1333    }
1334}
1335
1336/* Format a HOST_WIDE_INT as either a percent ratio, or absolute
1337   count.  If dp >= 0, format TOP/BOTTOM * 100 to DP decimal places.
1338   If DP is zero, no decimal point is printed. Only print 100% when
1339   TOP==BOTTOM and only print 0% when TOP=0.  If dp < 0, then simply
1340   format TOP.  Return pointer to a static string.  */
1341
1342static char const *
1343format_gcov (gcov_type top, gcov_type bottom, int dp)
1344{
1345  static char buffer[20];
1346
1347  if (dp >= 0)
1348    {
1349      float ratio = bottom ? (float)top / bottom : 0;
1350      int ix;
1351      unsigned limit = 100;
1352      unsigned percent;
1353
1354      for (ix = dp; ix--; )
1355	limit *= 10;
1356
1357      percent = (unsigned) (ratio * limit + (float)0.5);
1358      if (percent <= 0 && top)
1359	percent = 1;
1360      else if (percent >= limit && top != bottom)
1361	percent = limit - 1;
1362      ix = sprintf (buffer, "%.*u%%", dp + 1, percent);
1363      if (dp)
1364	{
1365	  dp++;
1366	  do
1367	    {
1368	      buffer[ix+1] = buffer[ix];
1369	      ix--;
1370	    }
1371	  while (dp--);
1372	  buffer[ix + 1] = '.';
1373	}
1374    }
1375  else
1376    sprintf (buffer, HOST_WIDEST_INT_PRINT_DEC, (HOST_WIDEST_INT)top);
1377
1378  return buffer;
1379}
1380
1381
1382/* Output summary info for a function.  */
1383
1384static void
1385function_summary (const coverage_t *coverage, const char *title)
1386{
1387  fnotice (stdout, "%s `%s'\n", title, coverage->name);
1388
1389  if (coverage->lines)
1390    fnotice (stdout, "Lines executed:%s of %d\n",
1391	     format_gcov (coverage->lines_executed, coverage->lines, 2),
1392	     coverage->lines);
1393  else
1394    fnotice (stdout, "No executable lines");
1395
1396  if (flag_branches)
1397    {
1398      if (coverage->branches)
1399	{
1400	  fnotice (stdout, "Branches executed:%s of %d\n",
1401		   format_gcov (coverage->branches_executed,
1402				coverage->branches, 2),
1403		   coverage->branches);
1404	  fnotice (stdout, "Taken at least once:%s of %d\n",
1405		   format_gcov (coverage->branches_taken,
1406				coverage->branches, 2),
1407		   coverage->branches);
1408	}
1409      else
1410	fnotice (stdout, "No branches\n");
1411      if (coverage->calls)
1412	fnotice (stdout, "Calls executed:%s of %d\n",
1413		 format_gcov (coverage->calls_executed, coverage->calls, 2),
1414		 coverage->calls);
1415      else
1416	fnotice (stdout, "No calls\n");
1417    }
1418}
1419
1420/* Generate an output file name. LONG_OUTPUT_NAMES and PRESERVE_PATHS
1421   affect name generation. With preserve_paths we create a filename
1422   from all path components of the source file, replacing '/' with
1423   '#', without it we simply take the basename component. With
1424   long_output_names we prepend the processed name of the input file
1425   to each output name (except when the current source file is the
1426   input file, so you don't get a double concatenation). The two
1427   components are separated by '##'. Also '.' filename components are
1428   removed and '..'  components are renamed to '^'.  */
1429
1430static char *
1431make_gcov_file_name (const char *input_name, const char *src_name)
1432{
1433  char *cptr;
1434  char *name = xmalloc (strlen (src_name) + strlen (input_name) + 10);
1435
1436  name[0] = 0;
1437  if (flag_long_names && strcmp (src_name, input_name))
1438    {
1439      /* Generate the input filename part.  */
1440      cptr = flag_preserve_paths ? NULL : strrchr (input_name, '/');
1441      strcat (name, cptr ? cptr + 1 : input_name);
1442      strcat (name, "##");
1443    }
1444
1445  /* Generate the source filename part.  */
1446  cptr = flag_preserve_paths ? NULL : strrchr (src_name, '/');
1447  strcat (name, cptr ? cptr + 1 : src_name);
1448
1449  if (flag_preserve_paths)
1450    {
1451      /* Convert '/' to '#', remove '/./', convert '/../' to '/^/' */
1452      char *prev;
1453
1454      for (cptr = name; (cptr = strchr ((prev = cptr), '/'));)
1455	{
1456	  unsigned shift = 0;
1457
1458	  if (prev + 1 == cptr && prev[0] == '.')
1459	    {
1460	      /* Remove '.' */
1461	      shift = 2;
1462	    }
1463	  else if (prev + 2 == cptr && prev[0] == '.' && prev[1] == '.')
1464	    {
1465	      /* Convert '..' */
1466	      shift = 1;
1467	      prev[1] = '^';
1468	    }
1469	  else
1470	    *cptr++ = '#';
1471	  if (shift)
1472	    {
1473	      cptr = prev;
1474	      do
1475		prev[0] = prev[shift];
1476	      while (*prev++);
1477	    }
1478	}
1479    }
1480
1481  strcat (name, ".gcov");
1482  return name;
1483}
1484
1485/* Scan through the bb_data for each line in the block, increment
1486   the line number execution count indicated by the execution count of
1487   the appropriate basic block.  */
1488
1489static void
1490add_line_counts (coverage_t *coverage, function_t *fn)
1491{
1492  unsigned ix;
1493  line_t *line = NULL; /* This is propagated from one iteration to the
1494			  next.  */
1495
1496  /* Scan each basic block.  */
1497  for (ix = 0; ix != fn->num_blocks; ix++)
1498    {
1499      block_t *block = &fn->blocks[ix];
1500      unsigned *encoding;
1501      const source_t *src = NULL;
1502      unsigned jx;
1503
1504      if (block->count && ix && ix + 1 != fn->num_blocks)
1505	fn->blocks_executed++;
1506      for (jx = 0, encoding = block->u.line.encoding;
1507	   jx != block->u.line.num; jx++, encoding++)
1508	if (!*encoding)
1509	  {
1510	    unsigned src_n = *++encoding;
1511
1512	    for (src = sources; src->index != src_n; src = src->next)
1513	      continue;
1514	    jx++;
1515	  }
1516	else
1517	  {
1518	    line = &src->lines[*encoding];
1519
1520	    if (coverage)
1521	      {
1522		if (!line->exists)
1523		  coverage->lines++;
1524		if (!line->count && block->count)
1525		  coverage->lines_executed++;
1526	      }
1527	    line->exists = 1;
1528	    line->count += block->count;
1529	  }
1530      free (block->u.line.encoding);
1531      block->u.cycle.arc = NULL;
1532      block->u.cycle.ident = ~0U;
1533
1534      if (!ix || ix + 1 == fn->num_blocks)
1535	/* Entry or exit block */;
1536      else if (flag_all_blocks)
1537	{
1538	  line_t *block_line = line ? line : &fn->src->lines[fn->line];
1539
1540	  block->chain = block_line->u.blocks;
1541	  block_line->u.blocks = block;
1542	}
1543      else if (flag_branches)
1544	{
1545	  arc_t *arc;
1546
1547	  for (arc = block->succ; arc; arc = arc->succ_next)
1548	    {
1549	      arc->line_next = line->u.branches;
1550	      line->u.branches = arc;
1551	      if (coverage && !arc->is_unconditional)
1552		add_branch_counts (coverage, arc);
1553	    }
1554	}
1555    }
1556  if (!line)
1557    fnotice (stderr, "%s:no lines for `%s'\n", bbg_file_name, fn->name);
1558}
1559
1560/* Accumulate the line counts of a file.  */
1561
1562static void
1563accumulate_line_counts (source_t *src)
1564{
1565  line_t *line;
1566  function_t *fn, *fn_p, *fn_n;
1567  unsigned ix;
1568
1569  /* Reverse the function order.  */
1570  for (fn = src->functions, fn_p = NULL; fn;
1571       fn_p = fn, fn = fn_n)
1572    {
1573      fn_n = fn->line_next;
1574      fn->line_next = fn_p;
1575    }
1576  src->functions = fn_p;
1577
1578  for (ix = src->num_lines, line = src->lines; ix--; line++)
1579    {
1580      if (!flag_all_blocks)
1581	{
1582	  arc_t *arc, *arc_p, *arc_n;
1583
1584	  /* Total and reverse the branch information.  */
1585	  for (arc = line->u.branches, arc_p = NULL; arc;
1586	       arc_p = arc, arc = arc_n)
1587	    {
1588	      arc_n = arc->line_next;
1589	      arc->line_next = arc_p;
1590
1591	      add_branch_counts (&src->coverage, arc);
1592	    }
1593	  line->u.branches = arc_p;
1594	}
1595      else if (line->u.blocks)
1596	{
1597	  /* The user expects the line count to be the number of times
1598	     a line has been executed. Simply summing the block count
1599	     will give an artificially high number.  The Right Thing
1600	     is to sum the entry counts to the graph of blocks on this
1601	     line, then find the elementary cycles of the local graph
1602	     and add the transition counts of those cycles.  */
1603	  block_t *block, *block_p, *block_n;
1604	  gcov_type count = 0;
1605
1606	  /* Reverse the block information.  */
1607	  for (block = line->u.blocks, block_p = NULL; block;
1608	       block_p = block, block = block_n)
1609	    {
1610	      block_n = block->chain;
1611	      block->chain = block_p;
1612	      block->u.cycle.ident = ix;
1613	    }
1614	  line->u.blocks = block_p;
1615
1616	  /* Sum the entry arcs.  */
1617	  for (block = line->u.blocks; block; block = block->chain)
1618	    {
1619	      arc_t *arc;
1620
1621	      for (arc = block->pred; arc; arc = arc->pred_next)
1622		{
1623		  if (arc->src->u.cycle.ident != ix)
1624		    count += arc->count;
1625		  if (flag_branches)
1626		    add_branch_counts (&src->coverage, arc);
1627		}
1628
1629	      /* Initialize the cs_count.  */
1630	      for (arc = block->succ; arc; arc = arc->succ_next)
1631		arc->cs_count = arc->count;
1632	    }
1633
1634	  /* Find the loops. This uses the algorithm described in
1635	     Tiernan 'An Efficient Search Algorithm to Find the
1636	     Elementary Circuits of a Graph', CACM Dec 1970. We hold
1637	     the P array by having each block point to the arc that
1638	     connects to the previous block. The H array is implicitly
1639	     held because of the arc ordering, and the block's
1640	     previous arc pointer.
1641
1642	     Although the algorithm is O(N^3) for highly connected
1643	     graphs, at worst we'll have O(N^2), as most blocks have
1644	     only one or two exits. Most graphs will be small.
1645
1646	     For each loop we find, locate the arc with the smallest
1647	     transition count, and add that to the cumulative
1648	     count.  Decrease flow over the cycle and remove the arc
1649	     from consideration.  */
1650	  for (block = line->u.blocks; block; block = block->chain)
1651	    {
1652	      block_t *head = block;
1653	      arc_t *arc;
1654
1655	    next_vertex:;
1656	      arc = head->succ;
1657	    current_vertex:;
1658	      while (arc)
1659		{
1660		  block_t *dst = arc->dst;
1661		  if (/* Already used that arc.  */
1662		      arc->cycle
1663		      /* Not to same graph, or before first vertex.  */
1664		      || dst->u.cycle.ident != ix
1665		      /* Already in path.  */
1666		      || dst->u.cycle.arc)
1667		    {
1668		      arc = arc->succ_next;
1669		      continue;
1670		    }
1671
1672		  if (dst == block)
1673		    {
1674		      /* Found a closing arc.  */
1675		      gcov_type cycle_count = arc->cs_count;
1676		      arc_t *cycle_arc = arc;
1677		      arc_t *probe_arc;
1678
1679		      /* Locate the smallest arc count of the loop.  */
1680		      for (dst = head; (probe_arc = dst->u.cycle.arc);
1681			   dst = probe_arc->src)
1682			if (cycle_count > probe_arc->cs_count)
1683			  {
1684			    cycle_count = probe_arc->cs_count;
1685			    cycle_arc = probe_arc;
1686			  }
1687
1688		      count += cycle_count;
1689		      cycle_arc->cycle = 1;
1690
1691		      /* Remove the flow from the cycle.  */
1692		      arc->cs_count -= cycle_count;
1693		      for (dst = head; (probe_arc = dst->u.cycle.arc);
1694			   dst = probe_arc->src)
1695			probe_arc->cs_count -= cycle_count;
1696
1697		      /* Unwind to the cyclic arc.  */
1698		      while (head != cycle_arc->src)
1699			{
1700			  arc = head->u.cycle.arc;
1701			  head->u.cycle.arc = NULL;
1702			  head = arc->src;
1703			}
1704		      /* Move on.  */
1705		      arc = arc->succ_next;
1706		      continue;
1707		    }
1708
1709		  /* Add new block to chain.  */
1710		  dst->u.cycle.arc = arc;
1711		  head = dst;
1712		  goto next_vertex;
1713		}
1714	      /* We could not add another vertex to the path. Remove
1715		 the last vertex from the list.  */
1716	      arc = head->u.cycle.arc;
1717	      if (arc)
1718		{
1719		  /* It was not the first vertex. Move onto next arc.  */
1720		  head->u.cycle.arc = NULL;
1721		  head = arc->src;
1722		  arc = arc->succ_next;
1723		  goto current_vertex;
1724		}
1725	      /* Mark this block as unusable.  */
1726	      block->u.cycle.ident = ~0U;
1727	    }
1728
1729	  line->count = count;
1730	}
1731
1732      if (line->exists)
1733	{
1734	  src->coverage.lines++;
1735	  if (line->count)
1736	    src->coverage.lines_executed++;
1737	}
1738    }
1739}
1740
1741/* Ouput information about ARC number IX.  Returns nonzero if
1742   anything is output.  */
1743
1744static int
1745output_branch_count (FILE *gcov_file, int ix, const arc_t *arc)
1746{
1747
1748  if (arc->is_call_non_return)
1749    {
1750      if (arc->src->count)
1751	{
1752	  fnotice (gcov_file, "call   %2d returned %s\n", ix,
1753		   format_gcov (arc->src->count - arc->count,
1754				arc->src->count, -flag_counts));
1755	}
1756      else
1757	fnotice (gcov_file, "call   %2d never executed\n", ix);
1758    }
1759  else if (!arc->is_unconditional)
1760    {
1761      if (arc->src->count)
1762	fnotice (gcov_file, "branch %2d taken %s%s\n", ix,
1763		 format_gcov (arc->count, arc->src->count, -flag_counts),
1764		 arc->fall_through ? " (fallthrough)" : "");
1765      else
1766	fnotice (gcov_file, "branch %2d never executed\n", ix);
1767    }
1768  else if (flag_unconditional && !arc->dst->is_call_return)
1769    {
1770      if (arc->src->count)
1771	fnotice (gcov_file, "unconditional %2d taken %s\n", ix,
1772		 format_gcov (arc->count, arc->src->count, -flag_counts));
1773      else
1774	fnotice (gcov_file, "unconditional %2d never executed\n", ix);
1775    }
1776  else
1777    return 0;
1778  return 1;
1779
1780}
1781
1782/* Read in the source file one line at a time, and output that line to
1783   the gcov file preceded by its execution count and other
1784   information.  */
1785
1786static void
1787output_lines (FILE *gcov_file, const source_t *src)
1788{
1789  FILE *source_file;
1790  unsigned line_num;	/* current line number.  */
1791  const line_t *line;           /* current line info ptr.  */
1792  char string[STRING_SIZE];     /* line buffer.  */
1793  char const *retval = "";	/* status of source file reading.  */
1794  function_t *fn = src->functions;
1795
1796  fprintf (gcov_file, "%9s:%5d:Source:%s\n", "-", 0, src->name);
1797  fprintf (gcov_file, "%9s:%5d:Graph:%s\n", "-", 0, bbg_file_name);
1798  fprintf (gcov_file, "%9s:%5d:Data:%s\n", "-", 0, da_file_name);
1799  fprintf (gcov_file, "%9s:%5d:Runs:%u\n", "-", 0,
1800	   object_summary.ctrs[GCOV_COUNTER_ARCS].runs);
1801  fprintf (gcov_file, "%9s:%5d:Programs:%u\n", "-", 0, program_count);
1802
1803  source_file = fopen (src->name, "r");
1804  if (!source_file)
1805    {
1806      fnotice (stderr, "%s:cannot open source file\n", src->name);
1807      retval = NULL;
1808    }
1809  else
1810    {
1811      struct stat status;
1812
1813      if (!fstat (fileno (source_file), &status)
1814	  && status.st_mtime > bbg_file_time)
1815	{
1816	  fnotice (stderr, "%s:source file is newer than graph file `%s'\n",
1817		   src->name, bbg_file_name);
1818	  fprintf (gcov_file, "%9s:%5d:Source is newer than graph\n",
1819		   "-", 0);
1820	}
1821    }
1822
1823  for (line_num = 1, line = &src->lines[line_num];
1824       line_num < src->num_lines; line_num++, line++)
1825    {
1826      for (; fn && fn->line == line_num; fn = fn->line_next)
1827	{
1828	  arc_t *arc = fn->blocks[fn->num_blocks - 1].pred;
1829	  gcov_type return_count = fn->blocks[fn->num_blocks - 1].count;
1830
1831	  for (; arc; arc = arc->pred_next)
1832	    if (arc->fake)
1833	      return_count -= arc->count;
1834
1835	  fprintf (gcov_file, "function %s", fn->name);
1836	  fprintf (gcov_file, " called %s",
1837		   format_gcov (fn->blocks[0].count, 0, -1));
1838	  fprintf (gcov_file, " returned %s",
1839		   format_gcov (return_count, fn->blocks[0].count, 0));
1840	  fprintf (gcov_file, " blocks executed %s",
1841		   format_gcov (fn->blocks_executed, fn->num_blocks - 2, 0));
1842	  fprintf (gcov_file, "\n");
1843	}
1844
1845      /* For lines which don't exist in the .bb file, print '-' before
1846	 the source line.  For lines which exist but were never
1847	 executed, print '#####' before the source line.  Otherwise,
1848	 print the execution count before the source line.  There are
1849	 16 spaces of indentation added before the source line so that
1850	 tabs won't be messed up.  */
1851      fprintf (gcov_file, "%9s:%5u:",
1852	       !line->exists ? "-" : !line->count ? "#####"
1853	       : format_gcov (line->count, 0, -1), line_num);
1854
1855      if (retval)
1856	{
1857	  /* Copy source line.  */
1858	  do
1859	    {
1860	      retval = fgets (string, STRING_SIZE, source_file);
1861	      if (!retval)
1862		break;
1863	      fputs (retval, gcov_file);
1864	    }
1865	  while (!retval[0] || retval[strlen (retval) - 1] != '\n');
1866	}
1867      if (!retval)
1868	fputs ("/*EOF*/\n", gcov_file);
1869
1870      if (flag_all_blocks)
1871	{
1872	  block_t *block;
1873	  arc_t *arc;
1874	  int ix, jx;
1875
1876	  for (ix = jx = 0, block = line->u.blocks; block;
1877	       block = block->chain)
1878	    {
1879	      if (!block->is_call_return)
1880		fprintf (gcov_file, "%9s:%5u-block %2d\n",
1881			 !line->exists ? "-" : !block->count ? "$$$$$"
1882			 : format_gcov (block->count, 0, -1),
1883			 line_num, ix++);
1884	      if (flag_branches)
1885		for (arc = block->succ; arc; arc = arc->succ_next)
1886		  jx += output_branch_count (gcov_file, jx, arc);
1887	    }
1888	}
1889      else if (flag_branches)
1890	{
1891	  int ix;
1892	  arc_t *arc;
1893
1894	  for (ix = 0, arc = line->u.branches; arc; arc = arc->line_next)
1895	    ix += output_branch_count (gcov_file, ix, arc);
1896	}
1897    }
1898
1899  /* Handle all remaining source lines.  There may be lines after the
1900     last line of code.  */
1901  if (retval)
1902    {
1903      for (; (retval = fgets (string, STRING_SIZE, source_file)); line_num++)
1904	{
1905	  fprintf (gcov_file, "%9s:%5u:%s", "-", line_num, retval);
1906
1907	  while (!retval[0] || retval[strlen (retval) - 1] != '\n')
1908	    {
1909	      retval = fgets (string, STRING_SIZE, source_file);
1910	      if (!retval)
1911		break;
1912	      fputs (retval, gcov_file);
1913	    }
1914	}
1915    }
1916
1917  if (source_file)
1918    fclose (source_file);
1919}
1920