1/* Gcov.c: prepend line execution counts and branch probabilities to a
2   source file.
3   Copyright (C) 1990-2015 Free Software Foundation, Inc.
4   Contributed by James E. Wilson of Cygnus Support.
5   Mangled by Bob Manson of Cygnus Support.
6   Mangled further by Nathan Sidwell <nathan@codesourcery.com>
7
8Gcov is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 3, or (at your option)
11any later version.
12
13Gcov is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with Gcov; see the file COPYING3.  If not see
20<http://www.gnu.org/licenses/>.  */
21
22/* ??? Print a list of the ten blocks with the highest execution counts,
23   and list the line numbers corresponding to those blocks.  Also, perhaps
24   list the line numbers with the highest execution counts, only printing
25   the first if there are several which are all listed in the same block.  */
26
27/* ??? Should have an option to print the number of basic blocks, and the
28   percent of them that are covered.  */
29
30/* Need an option to show individual block counts, and show
31   probabilities of fall through arcs.  */
32
33#include "config.h"
34#include "system.h"
35#include "coretypes.h"
36#include "tm.h"
37#include "intl.h"
38#include "diagnostic.h"
39#include "version.h"
40#include "demangle.h"
41
42#include <getopt.h>
43
44#define IN_GCOV 1
45#include "gcov-io.h"
46#include "gcov-io.c"
47
48/* The gcno file is generated by -ftest-coverage option. The gcda file is
49   generated by a program compiled with -fprofile-arcs. Their formats
50   are documented in gcov-io.h.  */
51
52/* The functions in this file for creating and solution program flow graphs
53   are very similar to functions in the gcc source file profile.c.  In
54   some places we make use of the knowledge of how profile.c works to
55   select particular algorithms here.  */
56
57/* The code validates that the profile information read in corresponds
58   to the code currently being compiled.  Rather than checking for
59   identical files, the code below compares a checksum on the CFG
60   (based on the order of basic blocks and the arcs in the CFG).  If
61   the CFG checksum in the gcda file match the CFG checksum in the
62   gcno file, the profile data will be used.  */
63
64/* This is the size of the buffer used to read in source file lines.  */
65
66struct function_info;
67struct block_info;
68struct source_info;
69
70/* Describes an arc between two basic blocks.  */
71
72typedef struct arc_info
73{
74  /* source and destination blocks.  */
75  struct block_info *src;
76  struct block_info *dst;
77
78  /* transition counts.  */
79  gcov_type count;
80  /* used in cycle search, so that we do not clobber original counts.  */
81  gcov_type cs_count;
82
83  unsigned int count_valid : 1;
84  unsigned int on_tree : 1;
85  unsigned int fake : 1;
86  unsigned int fall_through : 1;
87
88  /* Arc to a catch handler.  */
89  unsigned int is_throw : 1;
90
91  /* Arc is for a function that abnormally returns.  */
92  unsigned int is_call_non_return : 1;
93
94  /* Arc is for catch/setjmp.  */
95  unsigned int is_nonlocal_return : 1;
96
97  /* Is an unconditional branch.  */
98  unsigned int is_unconditional : 1;
99
100  /* Loop making arc.  */
101  unsigned int cycle : 1;
102
103  /* Next branch on line.  */
104  struct arc_info *line_next;
105
106  /* Links to next arc on src and dst lists.  */
107  struct arc_info *succ_next;
108  struct arc_info *pred_next;
109} arc_t;
110
111/* Describes a basic block. Contains lists of arcs to successor and
112   predecessor blocks.  */
113
114typedef struct block_info
115{
116  /* Chain of exit and entry arcs.  */
117  arc_t *succ;
118  arc_t *pred;
119
120  /* Number of unprocessed exit and entry arcs.  */
121  gcov_type num_succ;
122  gcov_type num_pred;
123
124  /* Block execution count.  */
125  gcov_type count;
126  unsigned flags : 12;
127  unsigned count_valid : 1;
128  unsigned valid_chain : 1;
129  unsigned invalid_chain : 1;
130  unsigned exceptional : 1;
131
132  /* Block is a call instrumenting site.  */
133  unsigned is_call_site : 1; /* Does the call.  */
134  unsigned is_call_return : 1; /* Is the return.  */
135
136  /* Block is a landing pad for longjmp or throw.  */
137  unsigned is_nonlocal_return : 1;
138
139  union
140  {
141    struct
142    {
143     /* Array of line numbers and source files. source files are
144        introduced by a linenumber of zero, the next 'line number' is
145        the number of the source file.  Always starts with a source
146        file.  */
147      unsigned *encoding;
148      unsigned num;
149    } line; /* Valid until blocks are linked onto lines */
150    struct
151    {
152      /* Single line graph cycle workspace.  Used for all-blocks
153	 mode.  */
154      arc_t *arc;
155      unsigned ident;
156    } cycle; /* Used in all-blocks mode, after blocks are linked onto
157	       lines.  */
158  } u;
159
160  /* Temporary chain for solving graph, and for chaining blocks on one
161     line.  */
162  struct block_info *chain;
163
164} block_t;
165
166/* Describes a single function. Contains an array of basic blocks.  */
167
168typedef struct function_info
169{
170  /* Name of function.  */
171  char *name;
172  char *demangled_name;
173  unsigned ident;
174  unsigned lineno_checksum;
175  unsigned cfg_checksum;
176
177  /* The graph contains at least one fake incoming edge.  */
178  unsigned has_catch : 1;
179
180  /* Array of basic blocks.  Like in GCC, the entry block is
181     at blocks[0] and the exit block is at blocks[1].  */
182#define ENTRY_BLOCK (0)
183#define EXIT_BLOCK (1)
184  block_t *blocks;
185  unsigned num_blocks;
186  unsigned blocks_executed;
187
188  /* Raw arc coverage counts.  */
189  gcov_type *counts;
190  unsigned num_counts;
191
192  /* First line number & file.  */
193  unsigned line;
194  unsigned src;
195
196  /* Next function in same source file.  */
197  struct function_info *line_next;
198
199  /* Next function.  */
200  struct function_info *next;
201} function_t;
202
203/* Describes coverage of a file or function.  */
204
205typedef struct coverage_info
206{
207  int lines;
208  int lines_executed;
209
210  int branches;
211  int branches_executed;
212  int branches_taken;
213
214  int calls;
215  int calls_executed;
216
217  char *name;
218} coverage_t;
219
220/* Describes a single line of source. Contains a chain of basic blocks
221   with code on it.  */
222
223typedef struct line_info
224{
225  gcov_type count;	   /* execution count */
226  union
227  {
228    arc_t *branches;	   /* branches from blocks that end on this
229			      line. Used for branch-counts when not
230			      all-blocks mode.  */
231    block_t *blocks;       /* blocks which start on this line.  Used
232			      in all-blocks mode.  */
233  } u;
234  unsigned exists : 1;
235  unsigned unexceptional : 1;
236} line_t;
237
238/* Describes a file mentioned in the block graph.  Contains an array
239   of line info.  */
240
241typedef struct source_info
242{
243  /* Canonical name of source file.  */
244  char *name;
245  time_t file_time;
246
247  /* Array of line information.  */
248  line_t *lines;
249  unsigned num_lines;
250
251  coverage_t coverage;
252
253  /* Functions in this source file.  These are in ascending line
254     number order.  */
255  function_t *functions;
256} source_t;
257
258typedef struct name_map
259{
260  char *name;  /* Source file name */
261  unsigned src;  /* Source file */
262} name_map_t;
263
264/* Holds a list of function basic block graphs.  */
265
266static function_t *functions;
267static function_t **fn_end = &functions;
268
269static source_t *sources;   /* Array of source files  */
270static unsigned n_sources;  /* Number of sources */
271static unsigned a_sources;  /* Allocated sources */
272
273static name_map_t *names;   /* Mapping of file names to sources */
274static unsigned n_names;    /* Number of names */
275static unsigned a_names;    /* Allocated names */
276
277/* This holds data summary information.  */
278
279static unsigned object_runs;
280static unsigned program_count;
281
282static unsigned total_lines;
283static unsigned total_executed;
284
285/* Modification time of graph file.  */
286
287static time_t bbg_file_time;
288
289/* Name of the notes (gcno) output file.  The "bbg" prefix is for
290   historical reasons, when the notes file contained only the
291   basic block graph notes.  */
292
293static char *bbg_file_name;
294
295/* Stamp of the bbg file */
296static unsigned bbg_stamp;
297
298/* Name and file pointer of the input file for the count data (gcda).  */
299
300static char *da_file_name;
301
302/* Data file is missing.  */
303
304static int no_data_file;
305
306/* If there is several input files, compute and display results after
307   reading all data files.  This way if two or more gcda file refer to
308   the same source file (eg inline subprograms in a .h file), the
309   counts are added.  */
310
311static int multiple_files = 0;
312
313/* Output branch probabilities.  */
314
315static int flag_branches = 0;
316
317/* Show unconditional branches too.  */
318static int flag_unconditional = 0;
319
320/* Output a gcov file if this is true.  This is on by default, and can
321   be turned off by the -n option.  */
322
323static int flag_gcov_file = 1;
324
325/* Output progress indication if this is true.  This is off by default
326   and can be turned on by the -d option.  */
327
328static int flag_display_progress = 0;
329
330/* Output *.gcov file in intermediate format used by 'lcov'.  */
331
332static int flag_intermediate_format = 0;
333
334/* Output demangled function names.  */
335
336static int flag_demangled_names = 0;
337
338/* For included files, make the gcov output file name include the name
339   of the input source file.  For example, if x.h is included in a.c,
340   then the output file name is a.c##x.h.gcov instead of x.h.gcov.  */
341
342static int flag_long_names = 0;
343
344/* Output count information for every basic block, not merely those
345   that contain line number information.  */
346
347static int flag_all_blocks = 0;
348
349/* Output summary info for each function.  */
350
351static int flag_function_summary = 0;
352
353/* Object directory file prefix.  This is the directory/file where the
354   graph and data files are looked for, if nonzero.  */
355
356static char *object_directory = 0;
357
358/* Source directory prefix.  This is removed from source pathnames
359   that match, when generating the output file name.  */
360
361static char *source_prefix = 0;
362static size_t source_length = 0;
363
364/* Only show data for sources with relative pathnames.  Absolute ones
365   usually indicate a system header file, which although it may
366   contain inline functions, is usually uninteresting.  */
367static int flag_relative_only = 0;
368
369/* Preserve all pathname components. Needed when object files and
370   source files are in subdirectories. '/' is mangled as '#', '.' is
371   elided and '..' mangled to '^'.  */
372
373static int flag_preserve_paths = 0;
374
375/* Output the number of times a branch was taken as opposed to the percentage
376   of times it was taken.  */
377
378static int flag_counts = 0;
379
380/* Forward declarations.  */
381static int process_args (int, char **);
382static void print_usage (int) ATTRIBUTE_NORETURN;
383static void print_version (void) ATTRIBUTE_NORETURN;
384static void process_file (const char *);
385static void generate_results (const char *);
386static void create_file_names (const char *);
387static int name_search (const void *, const void *);
388static int name_sort (const void *, const void *);
389static char *canonicalize_name (const char *);
390static unsigned find_source (const char *);
391static function_t *read_graph_file (void);
392static int read_count_file (function_t *);
393static void solve_flow_graph (function_t *);
394static void find_exception_blocks (function_t *);
395static void add_branch_counts (coverage_t *, const arc_t *);
396static void add_line_counts (coverage_t *, function_t *);
397static void executed_summary (unsigned, unsigned);
398static void function_summary (const coverage_t *, const char *);
399static const char *format_gcov (gcov_type, gcov_type, int);
400static void accumulate_line_counts (source_t *);
401static void output_gcov_file (const char *, source_t *);
402static int output_branch_count (FILE *, int, const arc_t *);
403static void output_lines (FILE *, const source_t *);
404static char *make_gcov_file_name (const char *, const char *);
405static char *mangle_name (const char *, char *);
406static void release_structures (void);
407static void release_function (function_t *);
408extern int main (int, char **);
409
410int
411main (int argc, char **argv)
412{
413  int argno;
414  int first_arg;
415  const char *p;
416
417  p = argv[0] + strlen (argv[0]);
418  while (p != argv[0] && !IS_DIR_SEPARATOR (p[-1]))
419    --p;
420  progname = p;
421
422  xmalloc_set_program_name (progname);
423
424  /* Unlock the stdio streams.  */
425  unlock_std_streams ();
426
427  gcc_init_libintl ();
428
429  diagnostic_initialize (global_dc, 0);
430
431  /* Handle response files.  */
432  expandargv (&argc, &argv);
433
434  a_names = 10;
435  names = XNEWVEC (name_map_t, a_names);
436  a_sources = 10;
437  sources = XNEWVEC (source_t, a_sources);
438
439  argno = process_args (argc, argv);
440  if (optind == argc)
441    print_usage (true);
442
443  if (argc - argno > 1)
444    multiple_files = 1;
445
446  first_arg = argno;
447
448  for (; argno != argc; argno++)
449    {
450      if (flag_display_progress)
451        printf ("Processing file %d out of %d\n",
452		argno - first_arg + 1, argc - first_arg);
453      process_file (argv[argno]);
454    }
455
456  generate_results (multiple_files ? NULL : argv[argc - 1]);
457
458  release_structures ();
459
460  return 0;
461}
462
463/* Print a usage message and exit.  If ERROR_P is nonzero, this is an error,
464   otherwise the output of --help.  */
465
466static void
467print_usage (int error_p)
468{
469  FILE *file = error_p ? stderr : stdout;
470  int status = error_p ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE;
471
472  fnotice (file, "Usage: gcov [OPTION]... SOURCE|OBJ...\n\n");
473  fnotice (file, "Print code coverage information.\n\n");
474  fnotice (file, "  -h, --help                      Print this help, then exit\n");
475  fnotice (file, "  -a, --all-blocks                Show information for every basic block\n");
476  fnotice (file, "  -b, --branch-probabilities      Include branch probabilities in output\n");
477  fnotice (file, "  -c, --branch-counts             Output counts of branches taken\n\
478                                    rather than percentages\n");
479  fnotice (file, "  -d, --display-progress          Display progress information\n");
480  fnotice (file, "  -f, --function-summaries        Output summaries for each function\n");
481  fnotice (file, "  -i, --intermediate-format       Output .gcov file in intermediate text format\n");
482  fnotice (file, "  -l, --long-file-names           Use long output file names for included\n\
483                                    source files\n");
484  fnotice (file, "  -m, --demangled-names           Output demangled function names\n");
485  fnotice (file, "  -n, --no-output                 Do not create an output file\n");
486  fnotice (file, "  -o, --object-directory DIR|FILE Search for object files in DIR or called FILE\n");
487  fnotice (file, "  -p, --preserve-paths            Preserve all pathname components\n");
488  fnotice (file, "  -r, --relative-only             Only show data for relative sources\n");
489  fnotice (file, "  -s, --source-prefix DIR         Source prefix to elide\n");
490  fnotice (file, "  -u, --unconditional-branches    Show unconditional branch counts too\n");
491  fnotice (file, "  -v, --version                   Print version number, then exit\n");
492  fnotice (file, "\nFor bug reporting instructions, please see:\n%s.\n",
493	   bug_report_url);
494  exit (status);
495}
496
497/* Print version information and exit.  */
498
499static void
500print_version (void)
501{
502  fnotice (stdout, "gcov %s%s\n", pkgversion_string, version_string);
503  fprintf (stdout, "Copyright %s 2015 Free Software Foundation, Inc.\n",
504	   _("(C)"));
505  fnotice (stdout,
506	   _("This is free software; see the source for copying conditions.\n"
507	     "There is NO warranty; not even for MERCHANTABILITY or \n"
508	     "FITNESS FOR A PARTICULAR PURPOSE.\n\n"));
509  exit (SUCCESS_EXIT_CODE);
510}
511
512static const struct option options[] =
513{
514  { "help",                 no_argument,       NULL, 'h' },
515  { "version",              no_argument,       NULL, 'v' },
516  { "all-blocks",           no_argument,       NULL, 'a' },
517  { "branch-probabilities", no_argument,       NULL, 'b' },
518  { "branch-counts",        no_argument,       NULL, 'c' },
519  { "intermediate-format",  no_argument,       NULL, 'i' },
520  { "no-output",            no_argument,       NULL, 'n' },
521  { "long-file-names",      no_argument,       NULL, 'l' },
522  { "function-summaries",   no_argument,       NULL, 'f' },
523  { "demangled-names",      no_argument,       NULL, 'm' },
524  { "preserve-paths",       no_argument,       NULL, 'p' },
525  { "relative-only",        no_argument,       NULL, 'r' },
526  { "object-directory",     required_argument, NULL, 'o' },
527  { "object-file",          required_argument, NULL, 'o' },
528  { "source-prefix",        required_argument, NULL, 's' },
529  { "unconditional-branches", no_argument,     NULL, 'u' },
530  { "display-progress",     no_argument,       NULL, 'd' },
531  { 0, 0, 0, 0 }
532};
533
534/* Process args, return index to first non-arg.  */
535
536static int
537process_args (int argc, char **argv)
538{
539  int opt;
540
541  while ((opt = getopt_long (argc, argv, "abcdfhilmno:s:pruv", options, NULL)) !=
542         -1)
543    {
544      switch (opt)
545	{
546	case 'a':
547	  flag_all_blocks = 1;
548	  break;
549	case 'b':
550	  flag_branches = 1;
551	  break;
552	case 'c':
553	  flag_counts = 1;
554	  break;
555	case 'f':
556	  flag_function_summary = 1;
557	  break;
558	case 'h':
559	  print_usage (false);
560	  /* print_usage will exit.  */
561	case 'l':
562	  flag_long_names = 1;
563	  break;
564	case 'm':
565	  flag_demangled_names = 1;
566	  break;
567	case 'n':
568	  flag_gcov_file = 0;
569	  break;
570	case 'o':
571	  object_directory = optarg;
572	  break;
573	case 's':
574	  source_prefix = optarg;
575	  source_length = strlen (source_prefix);
576	  break;
577	case 'r':
578	  flag_relative_only = 1;
579	  break;
580	case 'p':
581	  flag_preserve_paths = 1;
582	  break;
583	case 'u':
584	  flag_unconditional = 1;
585	  break;
586	case 'i':
587          flag_intermediate_format = 1;
588          flag_gcov_file = 1;
589          break;
590        case 'd':
591          flag_display_progress = 1;
592          break;
593	case 'v':
594	  print_version ();
595	  /* print_version will exit.  */
596	default:
597	  print_usage (true);
598	  /* print_usage will exit.  */
599	}
600    }
601
602  return optind;
603}
604
605/* Get the name of the gcov file.  The return value must be free'd.
606
607   It appends the '.gcov' extension to the *basename* of the file.
608   The resulting file name will be in PWD.
609
610   e.g.,
611   input: foo.da,       output: foo.da.gcov
612   input: a/b/foo.cc,   output: foo.cc.gcov  */
613
614static char *
615get_gcov_intermediate_filename (const char *file_name)
616{
617  const char *gcov = ".gcov";
618  char *result;
619  const char *cptr;
620
621  /* Find the 'basename'.  */
622  cptr = lbasename (file_name);
623
624  result = XNEWVEC (char, strlen (cptr) + strlen (gcov) + 1);
625  sprintf (result, "%s%s", cptr, gcov);
626
627  return result;
628}
629
630/* Output the result in intermediate format used by 'lcov'.
631
632The intermediate format contains a single file named 'foo.cc.gcov',
633with no source code included. A sample output is
634
635file:foo.cc
636function:5,1,_Z3foov
637function:13,1,main
638function:19,1,_GLOBAL__sub_I__Z3foov
639function:19,1,_Z41__static_initialization_and_destruction_0ii
640lcount:5,1
641lcount:7,9
642lcount:9,8
643lcount:11,1
644file:/.../iostream
645lcount:74,1
646file:/.../basic_ios.h
647file:/.../ostream
648file:/.../ios_base.h
649function:157,0,_ZStorSt12_Ios_IostateS_
650lcount:157,0
651file:/.../char_traits.h
652function:258,0,_ZNSt11char_traitsIcE6lengthEPKc
653lcount:258,0
654...
655
656The default gcov outputs multiple files: 'foo.cc.gcov',
657'iostream.gcov', 'ios_base.h.gcov', etc. with source code
658included. Instead the intermediate format here outputs only a single
659file 'foo.cc.gcov' similar to the above example. */
660
661static void
662output_intermediate_file (FILE *gcov_file, source_t *src)
663{
664  unsigned line_num;    /* current line number.  */
665  const line_t *line;   /* current line info ptr.  */
666  function_t *fn;       /* current function info ptr. */
667
668  fprintf (gcov_file, "file:%s\n", src->name);    /* source file name */
669
670  for (fn = src->functions; fn; fn = fn->line_next)
671    {
672      /* function:<name>,<line_number>,<execution_count> */
673      fprintf (gcov_file, "function:%d,%s,%s\n", fn->line,
674               format_gcov (fn->blocks[0].count, 0, -1),
675               flag_demangled_names ? fn->demangled_name : fn->name);
676    }
677
678  for (line_num = 1, line = &src->lines[line_num];
679       line_num < src->num_lines;
680       line_num++, line++)
681    {
682      arc_t *arc;
683      if (line->exists)
684        fprintf (gcov_file, "lcount:%u,%s\n", line_num,
685                 format_gcov (line->count, 0, -1));
686      if (flag_branches)
687        for (arc = line->u.branches; arc; arc = arc->line_next)
688          {
689            if (!arc->is_unconditional && !arc->is_call_non_return)
690              {
691                const char *branch_type;
692                /* branch:<line_num>,<branch_coverage_type>
693                   branch_coverage_type
694                     : notexec (Branch not executed)
695                     : taken (Branch executed and taken)
696                     : nottaken (Branch executed, but not taken)
697                */
698                if (arc->src->count)
699                  branch_type = (arc->count > 0) ? "taken" : "nottaken";
700                else
701                  branch_type = "notexec";
702                fprintf (gcov_file, "branch:%d,%s\n", line_num, branch_type);
703              }
704          }
705    }
706}
707
708
709/* Process a single input file.  */
710
711static void
712process_file (const char *file_name)
713{
714  function_t *fns;
715
716  create_file_names (file_name);
717  fns = read_graph_file ();
718  if (!fns)
719    return;
720
721  read_count_file (fns);
722  while (fns)
723    {
724      function_t *fn = fns;
725
726      fns = fn->next;
727      fn->next = NULL;
728      if (fn->counts)
729	{
730	  unsigned src = fn->src;
731	  unsigned line = fn->line;
732	  unsigned block_no;
733	  function_t *probe, **prev;
734
735	  /* Now insert it into the source file's list of
736	     functions. Normally functions will be encountered in
737	     ascending order, so a simple scan is quick.  Note we're
738	     building this list in reverse order.  */
739	  for (prev = &sources[src].functions;
740	       (probe = *prev); prev = &probe->line_next)
741	    if (probe->line <= line)
742	      break;
743	  fn->line_next = probe;
744	  *prev = fn;
745
746	  /* Mark last line in files touched by function.  */
747	  for (block_no = 0; block_no != fn->num_blocks; block_no++)
748	    {
749	      unsigned *enc = fn->blocks[block_no].u.line.encoding;
750	      unsigned num = fn->blocks[block_no].u.line.num;
751
752	      for (; num--; enc++)
753		if (!*enc)
754		  {
755		    if (enc[1] != src)
756		      {
757			if (line >= sources[src].num_lines)
758			  sources[src].num_lines = line + 1;
759			line = 0;
760			src = enc[1];
761		      }
762		    enc++;
763		    num--;
764		  }
765		else if (*enc > line)
766		  line = *enc;
767	    }
768	  if (line >= sources[src].num_lines)
769	    sources[src].num_lines = line + 1;
770
771	  solve_flow_graph (fn);
772	  if (fn->has_catch)
773	    find_exception_blocks (fn);
774	  *fn_end = fn;
775	  fn_end = &fn->next;
776	}
777      else
778	/* The function was not in the executable -- some other
779	   instance must have been selected.  */
780	release_function (fn);
781    }
782}
783
784static void
785output_gcov_file (const char *file_name, source_t *src)
786{
787  char *gcov_file_name = make_gcov_file_name (file_name, src->coverage.name);
788
789  if (src->coverage.lines)
790    {
791      FILE *gcov_file = fopen (gcov_file_name, "w");
792      if (gcov_file)
793        {
794          fnotice (stdout, "Creating '%s'\n", gcov_file_name);
795          output_lines (gcov_file, src);
796          if (ferror (gcov_file))
797            fnotice (stderr, "Error writing output file '%s'\n", gcov_file_name);
798          fclose (gcov_file);
799        }
800      else
801        fnotice (stderr, "Could not open output file '%s'\n", gcov_file_name);
802    }
803  else
804    {
805      unlink (gcov_file_name);
806      fnotice (stdout, "Removing '%s'\n", gcov_file_name);
807    }
808  free (gcov_file_name);
809}
810
811static void
812generate_results (const char *file_name)
813{
814  unsigned ix;
815  source_t *src;
816  function_t *fn;
817  FILE *gcov_intermediate_file = NULL;
818  char *gcov_intermediate_filename = NULL;
819
820  for (ix = n_sources, src = sources; ix--; src++)
821    if (src->num_lines)
822      src->lines = XCNEWVEC (line_t, src->num_lines);
823
824  for (fn = functions; fn; fn = fn->next)
825    {
826      coverage_t coverage;
827
828      memset (&coverage, 0, sizeof (coverage));
829      coverage.name = flag_demangled_names ? fn->demangled_name : fn->name;
830      add_line_counts (flag_function_summary ? &coverage : NULL, fn);
831      if (flag_function_summary)
832	{
833	  function_summary (&coverage, "Function");
834	  fnotice (stdout, "\n");
835	}
836    }
837
838  if (file_name)
839    {
840      name_map_t *name_map = (name_map_t *)bsearch
841	(file_name, names, n_names, sizeof (*names), name_search);
842      if (name_map)
843	file_name = sources[name_map->src].coverage.name;
844      else
845	file_name = canonicalize_name (file_name);
846    }
847
848  if (flag_gcov_file && flag_intermediate_format)
849    {
850      /* Open the intermediate file.  */
851      gcov_intermediate_filename =
852        get_gcov_intermediate_filename (file_name);
853      gcov_intermediate_file = fopen (gcov_intermediate_filename, "w");
854      if (!gcov_intermediate_file)
855        {
856          fnotice (stderr, "Cannot open intermediate output file %s\n",
857                   gcov_intermediate_filename);
858          return;
859        }
860    }
861
862  for (ix = n_sources, src = sources; ix--; src++)
863    {
864      if (flag_relative_only)
865	{
866	  /* Ignore this source, if it is an absolute path (after
867	     source prefix removal).  */
868	  char first = src->coverage.name[0];
869
870#if HAVE_DOS_BASED_FILE_SYSTEM
871	  if (first && src->coverage.name[1] == ':')
872	    first = src->coverage.name[2];
873#endif
874	  if (IS_DIR_SEPARATOR (first))
875	    continue;
876	}
877
878      accumulate_line_counts (src);
879      function_summary (&src->coverage, "File");
880      total_lines += src->coverage.lines;
881      total_executed += src->coverage.lines_executed;
882      if (flag_gcov_file)
883	{
884          if (flag_intermediate_format)
885            /* Output the intermediate format without requiring source
886               files.  This outputs a section to a *single* file.  */
887            output_intermediate_file (gcov_intermediate_file, src);
888          else
889            output_gcov_file (file_name, src);
890          fnotice (stdout, "\n");
891        }
892    }
893
894  if (flag_gcov_file && flag_intermediate_format)
895    {
896      /* Now we've finished writing the intermediate file.  */
897      fclose (gcov_intermediate_file);
898      XDELETEVEC (gcov_intermediate_filename);
899    }
900
901  if (!file_name)
902    executed_summary (total_lines, total_executed);
903}
904
905/* Release a function structure */
906
907static void
908release_function (function_t *fn)
909{
910  unsigned ix;
911  block_t *block;
912
913  for (ix = fn->num_blocks, block = fn->blocks; ix--; block++)
914    {
915      arc_t *arc, *arc_n;
916
917      for (arc = block->succ; arc; arc = arc_n)
918	{
919	  arc_n = arc->succ_next;
920	  free (arc);
921	}
922    }
923  free (fn->blocks);
924  free (fn->counts);
925  if (flag_demangled_names && fn->demangled_name != fn->name)
926    free (fn->demangled_name);
927  free (fn->name);
928}
929
930/* Release all memory used.  */
931
932static void
933release_structures (void)
934{
935  unsigned ix;
936  function_t *fn;
937
938  for (ix = n_sources; ix--;)
939    free (sources[ix].lines);
940  free (sources);
941
942  for (ix = n_names; ix--;)
943    free (names[ix].name);
944  free (names);
945
946  while ((fn = functions))
947    {
948      functions = fn->next;
949      release_function (fn);
950    }
951}
952
953/* Generate the names of the graph and data files.  If OBJECT_DIRECTORY
954   is not specified, these are named from FILE_NAME sans extension.  If
955   OBJECT_DIRECTORY is specified and is a directory, the files are in that
956   directory, but named from the basename of the FILE_NAME, sans extension.
957   Otherwise OBJECT_DIRECTORY is taken to be the name of the object *file*
958   and the data files are named from that.  */
959
960static void
961create_file_names (const char *file_name)
962{
963  char *cptr;
964  char *name;
965  int length = strlen (file_name);
966  int base;
967
968  /* Free previous file names.  */
969  free (bbg_file_name);
970  free (da_file_name);
971  da_file_name = bbg_file_name = NULL;
972  bbg_file_time = 0;
973  bbg_stamp = 0;
974
975  if (object_directory && object_directory[0])
976    {
977      struct stat status;
978
979      length += strlen (object_directory) + 2;
980      name = XNEWVEC (char, length);
981      name[0] = 0;
982
983      base = !stat (object_directory, &status) && S_ISDIR (status.st_mode);
984      strcat (name, object_directory);
985      if (base && (! IS_DIR_SEPARATOR (name[strlen (name) - 1])))
986	strcat (name, "/");
987    }
988  else
989    {
990      name = XNEWVEC (char, length + 1);
991      strcpy (name, file_name);
992      base = 0;
993    }
994
995  if (base)
996    {
997      /* Append source file name.  */
998      const char *cptr = lbasename (file_name);
999      strcat (name, cptr ? cptr : file_name);
1000    }
1001
1002  /* Remove the extension.  */
1003  cptr = strrchr (CONST_CAST (char *, lbasename (name)), '.');
1004  if (cptr)
1005    *cptr = 0;
1006
1007  length = strlen (name);
1008
1009  bbg_file_name = XNEWVEC (char, length + strlen (GCOV_NOTE_SUFFIX) + 1);
1010  strcpy (bbg_file_name, name);
1011  strcpy (bbg_file_name + length, GCOV_NOTE_SUFFIX);
1012
1013  da_file_name = XNEWVEC (char, length + strlen (GCOV_DATA_SUFFIX) + 1);
1014  strcpy (da_file_name, name);
1015  strcpy (da_file_name + length, GCOV_DATA_SUFFIX);
1016
1017  free (name);
1018  return;
1019}
1020
1021/* A is a string and B is a pointer to name_map_t.  Compare for file
1022   name orderability.  */
1023
1024static int
1025name_search (const void *a_, const void *b_)
1026{
1027  const char *a = (const char *)a_;
1028  const name_map_t *b = (const name_map_t *)b_;
1029
1030#if HAVE_DOS_BASED_FILE_SYSTEM
1031  return strcasecmp (a, b->name);
1032#else
1033  return strcmp (a, b->name);
1034#endif
1035}
1036
1037/* A and B are a pointer to name_map_t.  Compare for file name
1038   orderability.  */
1039
1040static int
1041name_sort (const void *a_, const void *b_)
1042{
1043  const name_map_t *a = (const name_map_t *)a_;
1044  return name_search (a->name, b_);
1045}
1046
1047/* Find or create a source file structure for FILE_NAME. Copies
1048   FILE_NAME on creation */
1049
1050static unsigned
1051find_source (const char *file_name)
1052{
1053  name_map_t *name_map;
1054  char *canon;
1055  unsigned idx;
1056  struct stat status;
1057
1058  if (!file_name)
1059    file_name = "<unknown>";
1060  name_map = (name_map_t *)bsearch
1061    (file_name, names, n_names, sizeof (*names), name_search);
1062  if (name_map)
1063    {
1064      idx = name_map->src;
1065      goto check_date;
1066    }
1067
1068  if (n_names + 2 > a_names)
1069    {
1070      /* Extend the name map array -- we'll be inserting one or two
1071	 entries.  */
1072      a_names *= 2;
1073      name_map = XNEWVEC (name_map_t, a_names);
1074      memcpy (name_map, names, n_names * sizeof (*names));
1075      free (names);
1076      names = name_map;
1077    }
1078
1079  /* Not found, try the canonical name. */
1080  canon = canonicalize_name (file_name);
1081  name_map = (name_map_t *)bsearch
1082    (canon, names, n_names, sizeof (*names), name_search);
1083  if (!name_map)
1084    {
1085      /* Not found with canonical name, create a new source.  */
1086      source_t *src;
1087
1088      if (n_sources == a_sources)
1089	{
1090	  a_sources *= 2;
1091	  src = XNEWVEC (source_t, a_sources);
1092	  memcpy (src, sources, n_sources * sizeof (*sources));
1093	  free (sources);
1094	  sources = src;
1095	}
1096
1097      idx = n_sources;
1098
1099      name_map = &names[n_names++];
1100      name_map->name = canon;
1101      name_map->src = idx;
1102
1103      src = &sources[n_sources++];
1104      memset (src, 0, sizeof (*src));
1105      src->name = canon;
1106      src->coverage.name = src->name;
1107      if (source_length
1108#if HAVE_DOS_BASED_FILE_SYSTEM
1109	  /* You lose if separators don't match exactly in the
1110	     prefix.  */
1111	  && !strncasecmp (source_prefix, src->coverage.name, source_length)
1112#else
1113	  && !strncmp (source_prefix, src->coverage.name, source_length)
1114#endif
1115	  && IS_DIR_SEPARATOR (src->coverage.name[source_length]))
1116	src->coverage.name += source_length + 1;
1117      if (!stat (src->name, &status))
1118	src->file_time = status.st_mtime;
1119    }
1120  else
1121    idx = name_map->src;
1122
1123  if (name_search (file_name, name_map))
1124    {
1125      /* Append the non-canonical name.  */
1126      name_map = &names[n_names++];
1127      name_map->name = xstrdup (file_name);
1128      name_map->src = idx;
1129    }
1130
1131  /* Resort the name map.  */
1132  qsort (names, n_names, sizeof (*names), name_sort);
1133
1134 check_date:
1135  if (sources[idx].file_time > bbg_file_time)
1136    {
1137      static int info_emitted;
1138
1139      fnotice (stderr, "%s:source file is newer than notes file '%s'\n",
1140	       file_name, bbg_file_name);
1141      if (!info_emitted)
1142	{
1143	  fnotice (stderr,
1144		   "(the message is displayed only once per source file)\n");
1145	  info_emitted = 1;
1146	}
1147      sources[idx].file_time = 0;
1148    }
1149
1150  return idx;
1151}
1152
1153/* Read the notes file.  Return list of functions read -- in reverse order.  */
1154
1155static function_t *
1156read_graph_file (void)
1157{
1158  unsigned version;
1159  unsigned current_tag = 0;
1160  function_t *fn = NULL;
1161  function_t *fns = NULL;
1162  function_t **fns_end = &fns;
1163  unsigned src_idx = 0;
1164  unsigned ix;
1165  unsigned tag;
1166
1167  if (!gcov_open (bbg_file_name, 1))
1168    {
1169      fnotice (stderr, "%s:cannot open notes file\n", bbg_file_name);
1170      return fns;
1171    }
1172  bbg_file_time = gcov_time ();
1173  if (!gcov_magic (gcov_read_unsigned (), GCOV_NOTE_MAGIC))
1174    {
1175      fnotice (stderr, "%s:not a gcov notes file\n", bbg_file_name);
1176      gcov_close ();
1177      return fns;
1178    }
1179
1180  version = gcov_read_unsigned ();
1181  if (version != GCOV_VERSION)
1182    {
1183      char v[4], e[4];
1184
1185      GCOV_UNSIGNED2STRING (v, version);
1186      GCOV_UNSIGNED2STRING (e, GCOV_VERSION);
1187
1188      fnotice (stderr, "%s:version '%.4s', prefer '%.4s'\n",
1189	       bbg_file_name, v, e);
1190    }
1191  bbg_stamp = gcov_read_unsigned ();
1192
1193  while ((tag = gcov_read_unsigned ()))
1194    {
1195      unsigned length = gcov_read_unsigned ();
1196      gcov_position_t base = gcov_position ();
1197
1198      if (tag == GCOV_TAG_FUNCTION)
1199	{
1200	  char *function_name;
1201	  unsigned ident, lineno;
1202	  unsigned lineno_checksum, cfg_checksum;
1203
1204	  ident = gcov_read_unsigned ();
1205	  lineno_checksum = gcov_read_unsigned ();
1206	  cfg_checksum = gcov_read_unsigned ();
1207	  function_name = xstrdup (gcov_read_string ());
1208	  src_idx = find_source (gcov_read_string ());
1209	  lineno = gcov_read_unsigned ();
1210
1211	  fn = XCNEW (function_t);
1212	  fn->name = function_name;
1213          if (flag_demangled_names)
1214            {
1215              fn->demangled_name = cplus_demangle (fn->name, DMGL_PARAMS);
1216              if (!fn->demangled_name)
1217                fn->demangled_name = fn->name;
1218            }
1219	  fn->ident = ident;
1220	  fn->lineno_checksum = lineno_checksum;
1221	  fn->cfg_checksum = cfg_checksum;
1222	  fn->src = src_idx;
1223	  fn->line = lineno;
1224
1225	  fn->line_next = NULL;
1226	  fn->next = NULL;
1227	  *fns_end = fn;
1228	  fns_end = &fn->next;
1229	  current_tag = tag;
1230	}
1231      else if (fn && tag == GCOV_TAG_BLOCKS)
1232	{
1233	  if (fn->blocks)
1234	    fnotice (stderr, "%s:already seen blocks for '%s'\n",
1235		     bbg_file_name, fn->name);
1236	  else
1237	    {
1238	      unsigned ix, num_blocks = GCOV_TAG_BLOCKS_NUM (length);
1239	      fn->num_blocks = num_blocks;
1240
1241	      fn->blocks = XCNEWVEC (block_t, fn->num_blocks);
1242	      for (ix = 0; ix != num_blocks; ix++)
1243		fn->blocks[ix].flags = gcov_read_unsigned ();
1244	    }
1245	}
1246      else if (fn && tag == GCOV_TAG_ARCS)
1247	{
1248	  unsigned src = gcov_read_unsigned ();
1249	  unsigned num_dests = GCOV_TAG_ARCS_NUM (length);
1250	  block_t *src_blk = &fn->blocks[src];
1251	  unsigned mark_catches = 0;
1252	  struct arc_info *arc;
1253
1254	  if (src >= fn->num_blocks || fn->blocks[src].succ)
1255	    goto corrupt;
1256
1257	  while (num_dests--)
1258	    {
1259	      unsigned dest = gcov_read_unsigned ();
1260	      unsigned flags = gcov_read_unsigned ();
1261
1262	      if (dest >= fn->num_blocks)
1263		goto corrupt;
1264	      arc = XCNEW (arc_t);
1265
1266	      arc->dst = &fn->blocks[dest];
1267	      arc->src = src_blk;
1268
1269	      arc->count = 0;
1270	      arc->count_valid = 0;
1271	      arc->on_tree = !!(flags & GCOV_ARC_ON_TREE);
1272	      arc->fake = !!(flags & GCOV_ARC_FAKE);
1273	      arc->fall_through = !!(flags & GCOV_ARC_FALLTHROUGH);
1274
1275	      arc->succ_next = src_blk->succ;
1276	      src_blk->succ = arc;
1277	      src_blk->num_succ++;
1278
1279	      arc->pred_next = fn->blocks[dest].pred;
1280	      fn->blocks[dest].pred = arc;
1281	      fn->blocks[dest].num_pred++;
1282
1283	      if (arc->fake)
1284		{
1285		  if (src)
1286		    {
1287		      /* Exceptional exit from this function, the
1288			 source block must be a call.  */
1289		      fn->blocks[src].is_call_site = 1;
1290		      arc->is_call_non_return = 1;
1291		      mark_catches = 1;
1292		    }
1293		  else
1294		    {
1295		      /* Non-local return from a callee of this
1296		         function. The destination block is a setjmp.  */
1297		      arc->is_nonlocal_return = 1;
1298		      fn->blocks[dest].is_nonlocal_return = 1;
1299		    }
1300		}
1301
1302	      if (!arc->on_tree)
1303		fn->num_counts++;
1304	    }
1305
1306	  if (mark_catches)
1307	    {
1308	      /* We have a fake exit from this block.  The other
1309		 non-fall through exits must be to catch handlers.
1310		 Mark them as catch arcs.  */
1311
1312	      for (arc = src_blk->succ; arc; arc = arc->succ_next)
1313		if (!arc->fake && !arc->fall_through)
1314		  {
1315		    arc->is_throw = 1;
1316		    fn->has_catch = 1;
1317		  }
1318	    }
1319	}
1320      else if (fn && tag == GCOV_TAG_LINES)
1321	{
1322	  unsigned blockno = gcov_read_unsigned ();
1323	  unsigned *line_nos = XCNEWVEC (unsigned, length - 1);
1324
1325	  if (blockno >= fn->num_blocks || fn->blocks[blockno].u.line.encoding)
1326	    goto corrupt;
1327
1328	  for (ix = 0; ;  )
1329	    {
1330	      unsigned lineno = gcov_read_unsigned ();
1331
1332	      if (lineno)
1333		{
1334		  if (!ix)
1335		    {
1336		      line_nos[ix++] = 0;
1337		      line_nos[ix++] = src_idx;
1338		    }
1339		  line_nos[ix++] = lineno;
1340		}
1341	      else
1342		{
1343		  const char *file_name = gcov_read_string ();
1344
1345		  if (!file_name)
1346		    break;
1347		  src_idx = find_source (file_name);
1348		  line_nos[ix++] = 0;
1349		  line_nos[ix++] = src_idx;
1350		}
1351	    }
1352
1353	  fn->blocks[blockno].u.line.encoding = line_nos;
1354	  fn->blocks[blockno].u.line.num = ix;
1355	}
1356      else if (current_tag && !GCOV_TAG_IS_SUBTAG (current_tag, tag))
1357	{
1358	  fn = NULL;
1359	  current_tag = 0;
1360	}
1361      gcov_sync (base, length);
1362      if (gcov_is_error ())
1363	{
1364	corrupt:;
1365	  fnotice (stderr, "%s:corrupted\n", bbg_file_name);
1366	  break;
1367	}
1368    }
1369  gcov_close ();
1370
1371  if (!fns)
1372    fnotice (stderr, "%s:no functions found\n", bbg_file_name);
1373
1374  return fns;
1375}
1376
1377/* Reads profiles from the count file and attach to each
1378   function. Return nonzero if fatal error.  */
1379
1380static int
1381read_count_file (function_t *fns)
1382{
1383  unsigned ix;
1384  unsigned version;
1385  unsigned tag;
1386  function_t *fn = NULL;
1387  int error = 0;
1388
1389  if (!gcov_open (da_file_name, 1))
1390    {
1391      fnotice (stderr, "%s:cannot open data file, assuming not executed\n",
1392	       da_file_name);
1393      no_data_file = 1;
1394      return 0;
1395    }
1396  if (!gcov_magic (gcov_read_unsigned (), GCOV_DATA_MAGIC))
1397    {
1398      fnotice (stderr, "%s:not a gcov data file\n", da_file_name);
1399    cleanup:;
1400      gcov_close ();
1401      return 1;
1402    }
1403  version = gcov_read_unsigned ();
1404  if (version != GCOV_VERSION)
1405    {
1406      char v[4], e[4];
1407
1408      GCOV_UNSIGNED2STRING (v, version);
1409      GCOV_UNSIGNED2STRING (e, GCOV_VERSION);
1410
1411      fnotice (stderr, "%s:version '%.4s', prefer version '%.4s'\n",
1412	       da_file_name, v, e);
1413    }
1414  tag = gcov_read_unsigned ();
1415  if (tag != bbg_stamp)
1416    {
1417      fnotice (stderr, "%s:stamp mismatch with notes file\n", da_file_name);
1418      goto cleanup;
1419    }
1420
1421  while ((tag = gcov_read_unsigned ()))
1422    {
1423      unsigned length = gcov_read_unsigned ();
1424      unsigned long base = gcov_position ();
1425
1426      if (tag == GCOV_TAG_PROGRAM_SUMMARY)
1427	{
1428	  struct gcov_summary summary;
1429	  gcov_read_summary (&summary);
1430	  object_runs += summary.ctrs[GCOV_COUNTER_ARCS].runs;
1431	  program_count++;
1432	}
1433      else if (tag == GCOV_TAG_FUNCTION && !length)
1434	; /* placeholder  */
1435      else if (tag == GCOV_TAG_FUNCTION && length == GCOV_TAG_FUNCTION_LENGTH)
1436	{
1437	  unsigned ident;
1438	  struct function_info *fn_n;
1439
1440	  /* Try to find the function in the list.  To speed up the
1441	     search, first start from the last function found.  */
1442	  ident = gcov_read_unsigned ();
1443	  fn_n = fns;
1444	  for (fn = fn ? fn->next : NULL; ; fn = fn->next)
1445	    {
1446	      if (fn)
1447		;
1448	      else if ((fn = fn_n))
1449		fn_n = NULL;
1450	      else
1451		{
1452		  fnotice (stderr, "%s:unknown function '%u'\n",
1453			   da_file_name, ident);
1454		  break;
1455		}
1456	      if (fn->ident == ident)
1457		break;
1458	    }
1459
1460	  if (!fn)
1461	    ;
1462	  else if (gcov_read_unsigned () != fn->lineno_checksum
1463		   || gcov_read_unsigned () != fn->cfg_checksum)
1464	    {
1465	    mismatch:;
1466	      fnotice (stderr, "%s:profile mismatch for '%s'\n",
1467		       da_file_name, fn->name);
1468	      goto cleanup;
1469	    }
1470	}
1471      else if (tag == GCOV_TAG_FOR_COUNTER (GCOV_COUNTER_ARCS) && fn)
1472	{
1473	  if (length != GCOV_TAG_COUNTER_LENGTH (fn->num_counts))
1474	    goto mismatch;
1475
1476	  if (!fn->counts)
1477	    fn->counts = XCNEWVEC (gcov_type, fn->num_counts);
1478
1479	  for (ix = 0; ix != fn->num_counts; ix++)
1480	    fn->counts[ix] += gcov_read_counter ();
1481	}
1482      gcov_sync (base, length);
1483      if ((error = gcov_is_error ()))
1484	{
1485	  fnotice (stderr, error < 0 ? "%s:overflowed\n" : "%s:corrupted\n",
1486		   da_file_name);
1487	  goto cleanup;
1488	}
1489    }
1490
1491  gcov_close ();
1492  return 0;
1493}
1494
1495/* Solve the flow graph. Propagate counts from the instrumented arcs
1496   to the blocks and the uninstrumented arcs.  */
1497
1498static void
1499solve_flow_graph (function_t *fn)
1500{
1501  unsigned ix;
1502  arc_t *arc;
1503  gcov_type *count_ptr = fn->counts;
1504  block_t *blk;
1505  block_t *valid_blocks = NULL;    /* valid, but unpropagated blocks.  */
1506  block_t *invalid_blocks = NULL;  /* invalid, but inferable blocks.  */
1507
1508  /* The arcs were built in reverse order.  Fix that now.  */
1509  for (ix = fn->num_blocks; ix--;)
1510    {
1511      arc_t *arc_p, *arc_n;
1512
1513      for (arc_p = NULL, arc = fn->blocks[ix].succ; arc;
1514	   arc_p = arc, arc = arc_n)
1515	{
1516	  arc_n = arc->succ_next;
1517	  arc->succ_next = arc_p;
1518	}
1519      fn->blocks[ix].succ = arc_p;
1520
1521      for (arc_p = NULL, arc = fn->blocks[ix].pred; arc;
1522	   arc_p = arc, arc = arc_n)
1523	{
1524	  arc_n = arc->pred_next;
1525	  arc->pred_next = arc_p;
1526	}
1527      fn->blocks[ix].pred = arc_p;
1528    }
1529
1530  if (fn->num_blocks < 2)
1531    fnotice (stderr, "%s:'%s' lacks entry and/or exit blocks\n",
1532	     bbg_file_name, fn->name);
1533  else
1534    {
1535      if (fn->blocks[ENTRY_BLOCK].num_pred)
1536	fnotice (stderr, "%s:'%s' has arcs to entry block\n",
1537		 bbg_file_name, fn->name);
1538      else
1539	/* We can't deduce the entry block counts from the lack of
1540	   predecessors.  */
1541	fn->blocks[ENTRY_BLOCK].num_pred = ~(unsigned)0;
1542
1543      if (fn->blocks[EXIT_BLOCK].num_succ)
1544	fnotice (stderr, "%s:'%s' has arcs from exit block\n",
1545		 bbg_file_name, fn->name);
1546      else
1547	/* Likewise, we can't deduce exit block counts from the lack
1548	   of its successors.  */
1549	fn->blocks[EXIT_BLOCK].num_succ = ~(unsigned)0;
1550    }
1551
1552  /* Propagate the measured counts, this must be done in the same
1553     order as the code in profile.c  */
1554  for (ix = 0, blk = fn->blocks; ix != fn->num_blocks; ix++, blk++)
1555    {
1556      block_t const *prev_dst = NULL;
1557      int out_of_order = 0;
1558      int non_fake_succ = 0;
1559
1560      for (arc = blk->succ; arc; arc = arc->succ_next)
1561	{
1562	  if (!arc->fake)
1563	    non_fake_succ++;
1564
1565	  if (!arc->on_tree)
1566	    {
1567	      if (count_ptr)
1568		arc->count = *count_ptr++;
1569	      arc->count_valid = 1;
1570	      blk->num_succ--;
1571	      arc->dst->num_pred--;
1572	    }
1573	  if (prev_dst && prev_dst > arc->dst)
1574	    out_of_order = 1;
1575	  prev_dst = arc->dst;
1576	}
1577      if (non_fake_succ == 1)
1578	{
1579	  /* If there is only one non-fake exit, it is an
1580	     unconditional branch.  */
1581	  for (arc = blk->succ; arc; arc = arc->succ_next)
1582	    if (!arc->fake)
1583	      {
1584		arc->is_unconditional = 1;
1585		/* If this block is instrumenting a call, it might be
1586		   an artificial block. It is not artificial if it has
1587		   a non-fallthrough exit, or the destination of this
1588		   arc has more than one entry.  Mark the destination
1589		   block as a return site, if none of those conditions
1590		   hold.  */
1591		if (blk->is_call_site && arc->fall_through
1592		    && arc->dst->pred == arc && !arc->pred_next)
1593		  arc->dst->is_call_return = 1;
1594	      }
1595	}
1596
1597      /* Sort the successor arcs into ascending dst order. profile.c
1598	 normally produces arcs in the right order, but sometimes with
1599	 one or two out of order.  We're not using a particularly
1600	 smart sort.  */
1601      if (out_of_order)
1602	{
1603	  arc_t *start = blk->succ;
1604	  unsigned changes = 1;
1605
1606	  while (changes)
1607	    {
1608	      arc_t *arc, *arc_p, *arc_n;
1609
1610	      changes = 0;
1611	      for (arc_p = NULL, arc = start; (arc_n = arc->succ_next);)
1612		{
1613		  if (arc->dst > arc_n->dst)
1614		    {
1615		      changes = 1;
1616		      if (arc_p)
1617			arc_p->succ_next = arc_n;
1618		      else
1619			start = arc_n;
1620		      arc->succ_next = arc_n->succ_next;
1621		      arc_n->succ_next = arc;
1622		      arc_p = arc_n;
1623		    }
1624		  else
1625		    {
1626		      arc_p = arc;
1627		      arc = arc_n;
1628		    }
1629		}
1630	    }
1631	  blk->succ = start;
1632	}
1633
1634      /* Place it on the invalid chain, it will be ignored if that's
1635	 wrong.  */
1636      blk->invalid_chain = 1;
1637      blk->chain = invalid_blocks;
1638      invalid_blocks = blk;
1639    }
1640
1641  while (invalid_blocks || valid_blocks)
1642    {
1643      while ((blk = invalid_blocks))
1644	{
1645	  gcov_type total = 0;
1646	  const arc_t *arc;
1647
1648	  invalid_blocks = blk->chain;
1649	  blk->invalid_chain = 0;
1650	  if (!blk->num_succ)
1651	    for (arc = blk->succ; arc; arc = arc->succ_next)
1652	      total += arc->count;
1653	  else if (!blk->num_pred)
1654	    for (arc = blk->pred; arc; arc = arc->pred_next)
1655	      total += arc->count;
1656	  else
1657	    continue;
1658
1659	  blk->count = total;
1660	  blk->count_valid = 1;
1661	  blk->chain = valid_blocks;
1662	  blk->valid_chain = 1;
1663	  valid_blocks = blk;
1664	}
1665      while ((blk = valid_blocks))
1666	{
1667	  gcov_type total;
1668	  arc_t *arc, *inv_arc;
1669
1670	  valid_blocks = blk->chain;
1671	  blk->valid_chain = 0;
1672	  if (blk->num_succ == 1)
1673	    {
1674	      block_t *dst;
1675
1676	      total = blk->count;
1677	      inv_arc = NULL;
1678	      for (arc = blk->succ; arc; arc = arc->succ_next)
1679		{
1680		  total -= arc->count;
1681		  if (!arc->count_valid)
1682		    inv_arc = arc;
1683		}
1684	      dst = inv_arc->dst;
1685	      inv_arc->count_valid = 1;
1686	      inv_arc->count = total;
1687	      blk->num_succ--;
1688	      dst->num_pred--;
1689	      if (dst->count_valid)
1690		{
1691		  if (dst->num_pred == 1 && !dst->valid_chain)
1692		    {
1693		      dst->chain = valid_blocks;
1694		      dst->valid_chain = 1;
1695		      valid_blocks = dst;
1696		    }
1697		}
1698	      else
1699		{
1700		  if (!dst->num_pred && !dst->invalid_chain)
1701		    {
1702		      dst->chain = invalid_blocks;
1703		      dst->invalid_chain = 1;
1704		      invalid_blocks = dst;
1705		    }
1706		}
1707	    }
1708	  if (blk->num_pred == 1)
1709	    {
1710	      block_t *src;
1711
1712	      total = blk->count;
1713	      inv_arc = NULL;
1714	      for (arc = blk->pred; arc; arc = arc->pred_next)
1715		{
1716		  total -= arc->count;
1717		  if (!arc->count_valid)
1718		    inv_arc = arc;
1719		}
1720	      src = inv_arc->src;
1721	      inv_arc->count_valid = 1;
1722	      inv_arc->count = total;
1723	      blk->num_pred--;
1724	      src->num_succ--;
1725	      if (src->count_valid)
1726		{
1727		  if (src->num_succ == 1 && !src->valid_chain)
1728		    {
1729		      src->chain = valid_blocks;
1730		      src->valid_chain = 1;
1731		      valid_blocks = src;
1732		    }
1733		}
1734	      else
1735		{
1736		  if (!src->num_succ && !src->invalid_chain)
1737		    {
1738		      src->chain = invalid_blocks;
1739		      src->invalid_chain = 1;
1740		      invalid_blocks = src;
1741		    }
1742		}
1743	    }
1744	}
1745    }
1746
1747  /* If the graph has been correctly solved, every block will have a
1748     valid count.  */
1749  for (ix = 0; ix < fn->num_blocks; ix++)
1750    if (!fn->blocks[ix].count_valid)
1751      {
1752	fnotice (stderr, "%s:graph is unsolvable for '%s'\n",
1753		 bbg_file_name, fn->name);
1754	break;
1755      }
1756}
1757
1758/* Mark all the blocks only reachable via an incoming catch.  */
1759
1760static void
1761find_exception_blocks (function_t *fn)
1762{
1763  unsigned ix;
1764  block_t **queue = XALLOCAVEC (block_t *, fn->num_blocks);
1765
1766  /* First mark all blocks as exceptional.  */
1767  for (ix = fn->num_blocks; ix--;)
1768    fn->blocks[ix].exceptional = 1;
1769
1770  /* Now mark all the blocks reachable via non-fake edges */
1771  queue[0] = fn->blocks;
1772  queue[0]->exceptional = 0;
1773  for (ix = 1; ix;)
1774    {
1775      block_t *block = queue[--ix];
1776      const arc_t *arc;
1777
1778      for (arc = block->succ; arc; arc = arc->succ_next)
1779	if (!arc->fake && !arc->is_throw && arc->dst->exceptional)
1780	  {
1781	    arc->dst->exceptional = 0;
1782	    queue[ix++] = arc->dst;
1783	  }
1784    }
1785}
1786
1787
1788/* Increment totals in COVERAGE according to arc ARC.  */
1789
1790static void
1791add_branch_counts (coverage_t *coverage, const arc_t *arc)
1792{
1793  if (arc->is_call_non_return)
1794    {
1795      coverage->calls++;
1796      if (arc->src->count)
1797	coverage->calls_executed++;
1798    }
1799  else if (!arc->is_unconditional)
1800    {
1801      coverage->branches++;
1802      if (arc->src->count)
1803	coverage->branches_executed++;
1804      if (arc->count)
1805	coverage->branches_taken++;
1806    }
1807}
1808
1809/* Format a GCOV_TYPE integer as either a percent ratio, or absolute
1810   count.  If dp >= 0, format TOP/BOTTOM * 100 to DP decimal places.
1811   If DP is zero, no decimal point is printed. Only print 100% when
1812   TOP==BOTTOM and only print 0% when TOP=0.  If dp < 0, then simply
1813   format TOP.  Return pointer to a static string.  */
1814
1815static char const *
1816format_gcov (gcov_type top, gcov_type bottom, int dp)
1817{
1818  static char buffer[20];
1819
1820  if (dp >= 0)
1821    {
1822      float ratio = bottom ? (float)top / bottom : 0;
1823      int ix;
1824      unsigned limit = 100;
1825      unsigned percent;
1826
1827      for (ix = dp; ix--; )
1828	limit *= 10;
1829
1830      percent = (unsigned) (ratio * limit + (float)0.5);
1831      if (percent <= 0 && top)
1832	percent = 1;
1833      else if (percent >= limit && top != bottom)
1834	percent = limit - 1;
1835      ix = sprintf (buffer, "%.*u%%", dp + 1, percent);
1836      if (dp)
1837	{
1838	  dp++;
1839	  do
1840	    {
1841	      buffer[ix+1] = buffer[ix];
1842	      ix--;
1843	    }
1844	  while (dp--);
1845	  buffer[ix + 1] = '.';
1846	}
1847    }
1848  else
1849    sprintf (buffer, "%"PRId64, (int64_t)top);
1850
1851  return buffer;
1852}
1853
1854/* Summary of execution */
1855
1856static void
1857executed_summary (unsigned lines, unsigned executed)
1858{
1859  if (lines)
1860    fnotice (stdout, "Lines executed:%s of %d\n",
1861	     format_gcov (executed, lines, 2), lines);
1862  else
1863    fnotice (stdout, "No executable lines\n");
1864}
1865
1866/* Output summary info for a function or file.  */
1867
1868static void
1869function_summary (const coverage_t *coverage, const char *title)
1870{
1871  fnotice (stdout, "%s '%s'\n", title, coverage->name);
1872  executed_summary (coverage->lines, coverage->lines_executed);
1873
1874  if (flag_branches)
1875    {
1876      if (coverage->branches)
1877	{
1878	  fnotice (stdout, "Branches executed:%s of %d\n",
1879		   format_gcov (coverage->branches_executed,
1880				coverage->branches, 2),
1881		   coverage->branches);
1882	  fnotice (stdout, "Taken at least once:%s of %d\n",
1883		   format_gcov (coverage->branches_taken,
1884				coverage->branches, 2),
1885		   coverage->branches);
1886	}
1887      else
1888	fnotice (stdout, "No branches\n");
1889      if (coverage->calls)
1890	fnotice (stdout, "Calls executed:%s of %d\n",
1891		 format_gcov (coverage->calls_executed, coverage->calls, 2),
1892		 coverage->calls);
1893      else
1894	fnotice (stdout, "No calls\n");
1895    }
1896}
1897
1898/* Canonicalize the filename NAME by canonicalizing directory
1899   separators, eliding . components and resolving .. components
1900   appropriately.  Always returns a unique string.  */
1901
1902static char *
1903canonicalize_name (const char *name)
1904{
1905  /* The canonical name cannot be longer than the incoming name.  */
1906  char *result = XNEWVEC (char, strlen (name) + 1);
1907  const char *base = name, *probe;
1908  char *ptr = result;
1909  char *dd_base;
1910  int slash = 0;
1911
1912#if HAVE_DOS_BASED_FILE_SYSTEM
1913  if (base[0] && base[1] == ':')
1914    {
1915      result[0] = base[0];
1916      result[1] = ':';
1917      base += 2;
1918      ptr += 2;
1919    }
1920#endif
1921  for (dd_base = ptr; *base; base = probe)
1922    {
1923      size_t len;
1924
1925      for (probe = base; *probe; probe++)
1926	if (IS_DIR_SEPARATOR (*probe))
1927	  break;
1928
1929      len = probe - base;
1930      if (len == 1 && base[0] == '.')
1931	/* Elide a '.' directory */
1932	;
1933      else if (len == 2 && base[0] == '.' && base[1] == '.')
1934	{
1935	  /* '..', we can only elide it and the previous directory, if
1936	     we're not a symlink.  */
1937	  struct stat ATTRIBUTE_UNUSED buf;
1938
1939	  *ptr = 0;
1940	  if (dd_base == ptr
1941#if defined (S_ISLNK)
1942	      /* S_ISLNK is not POSIX.1-1996.  */
1943	      || stat (result, &buf) || S_ISLNK (buf.st_mode)
1944#endif
1945	      )
1946	    {
1947	      /* Cannot elide, or unreadable or a symlink.  */
1948	      dd_base = ptr + 2 + slash;
1949	      goto regular;
1950	    }
1951	  while (ptr != dd_base && *ptr != '/')
1952	    ptr--;
1953	  slash = ptr != result;
1954	}
1955      else
1956	{
1957	regular:
1958	  /* Regular pathname component.  */
1959	  if (slash)
1960	    *ptr++ = '/';
1961	  memcpy (ptr, base, len);
1962	  ptr += len;
1963	  slash = 1;
1964	}
1965
1966      for (; IS_DIR_SEPARATOR (*probe); probe++)
1967	continue;
1968    }
1969  *ptr = 0;
1970
1971  return result;
1972}
1973
1974/* Generate an output file name. INPUT_NAME is the canonicalized main
1975   input file and SRC_NAME is the canonicalized file name.
1976   LONG_OUTPUT_NAMES and PRESERVE_PATHS affect name generation.  With
1977   long_output_names we prepend the processed name of the input file
1978   to each output name (except when the current source file is the
1979   input file, so you don't get a double concatenation). The two
1980   components are separated by '##'.  With preserve_paths we create a
1981   filename from all path components of the source file, replacing '/'
1982   with '#', and .. with '^', without it we simply take the basename
1983   component.  (Remember, the canonicalized name will already have
1984   elided '.' components and converted \\ separators.)  */
1985
1986static char *
1987make_gcov_file_name (const char *input_name, const char *src_name)
1988{
1989  char *ptr;
1990  char *result;
1991
1992  if (flag_long_names && input_name && strcmp (src_name, input_name))
1993    {
1994      /* Generate the input filename part.  */
1995      result = XNEWVEC (char, strlen (input_name) + strlen (src_name) + 10);
1996
1997      ptr = result;
1998      ptr = mangle_name (input_name, ptr);
1999      ptr[0] = ptr[1] = '#';
2000      ptr += 2;
2001    }
2002  else
2003    {
2004      result = XNEWVEC (char, strlen (src_name) + 10);
2005      ptr = result;
2006    }
2007
2008  ptr = mangle_name (src_name, ptr);
2009  strcpy (ptr, ".gcov");
2010
2011  return result;
2012}
2013
2014static char *
2015mangle_name (char const *base, char *ptr)
2016{
2017  size_t len;
2018
2019  /* Generate the source filename part.  */
2020  if (!flag_preserve_paths)
2021    {
2022      base = lbasename (base);
2023      len = strlen (base);
2024      memcpy (ptr, base, len);
2025      ptr += len;
2026    }
2027  else
2028    {
2029      /* Convert '/' to '#', convert '..' to '^',
2030	 convert ':' to '~' on DOS based file system.  */
2031      const char *probe;
2032
2033#if HAVE_DOS_BASED_FILE_SYSTEM
2034      if (base[0] && base[1] == ':')
2035	{
2036	  ptr[0] = base[0];
2037	  ptr[1] = '~';
2038	  ptr += 2;
2039	  base += 2;
2040	}
2041#endif
2042      for (; *base; base = probe)
2043	{
2044	  size_t len;
2045
2046	  for (probe = base; *probe; probe++)
2047	    if (*probe == '/')
2048	      break;
2049	  len = probe - base;
2050	  if (len == 2 && base[0] == '.' && base[1] == '.')
2051	    *ptr++ = '^';
2052	  else
2053	    {
2054	      memcpy (ptr, base, len);
2055	      ptr += len;
2056	    }
2057	  if (*probe)
2058	    {
2059	      *ptr++ = '#';
2060	      probe++;
2061	    }
2062	}
2063    }
2064
2065  return ptr;
2066}
2067
2068/* Scan through the bb_data for each line in the block, increment
2069   the line number execution count indicated by the execution count of
2070   the appropriate basic block.  */
2071
2072static void
2073add_line_counts (coverage_t *coverage, function_t *fn)
2074{
2075  unsigned ix;
2076  line_t *line = NULL; /* This is propagated from one iteration to the
2077			  next.  */
2078
2079  /* Scan each basic block.  */
2080  for (ix = 0; ix != fn->num_blocks; ix++)
2081    {
2082      block_t *block = &fn->blocks[ix];
2083      unsigned *encoding;
2084      const source_t *src = NULL;
2085      unsigned jx;
2086
2087      if (block->count && ix && ix + 1 != fn->num_blocks)
2088	fn->blocks_executed++;
2089      for (jx = 0, encoding = block->u.line.encoding;
2090	   jx != block->u.line.num; jx++, encoding++)
2091	if (!*encoding)
2092	  {
2093	    src = &sources[*++encoding];
2094	    jx++;
2095	  }
2096	else
2097	  {
2098	    line = &src->lines[*encoding];
2099
2100	    if (coverage)
2101	      {
2102		if (!line->exists)
2103		  coverage->lines++;
2104		if (!line->count && block->count)
2105		  coverage->lines_executed++;
2106	      }
2107	    line->exists = 1;
2108	    if (!block->exceptional)
2109	      line->unexceptional = 1;
2110	    line->count += block->count;
2111	  }
2112      free (block->u.line.encoding);
2113      block->u.cycle.arc = NULL;
2114      block->u.cycle.ident = ~0U;
2115
2116      if (!ix || ix + 1 == fn->num_blocks)
2117	/* Entry or exit block */;
2118      else if (flag_all_blocks)
2119	{
2120	  line_t *block_line = line;
2121
2122	  if (!block_line)
2123	    block_line = &sources[fn->src].lines[fn->line];
2124
2125	  block->chain = block_line->u.blocks;
2126	  block_line->u.blocks = block;
2127	}
2128      else if (flag_branches)
2129	{
2130	  arc_t *arc;
2131
2132	  for (arc = block->succ; arc; arc = arc->succ_next)
2133	    {
2134	      arc->line_next = line->u.branches;
2135	      line->u.branches = arc;
2136	      if (coverage && !arc->is_unconditional)
2137		add_branch_counts (coverage, arc);
2138	    }
2139	}
2140    }
2141  if (!line)
2142    fnotice (stderr, "%s:no lines for '%s'\n", bbg_file_name, fn->name);
2143}
2144
2145/* Accumulate the line counts of a file.  */
2146
2147static void
2148accumulate_line_counts (source_t *src)
2149{
2150  line_t *line;
2151  function_t *fn, *fn_p, *fn_n;
2152  unsigned ix;
2153
2154  /* Reverse the function order.  */
2155  for (fn = src->functions, fn_p = NULL; fn;
2156       fn_p = fn, fn = fn_n)
2157    {
2158      fn_n = fn->line_next;
2159      fn->line_next = fn_p;
2160    }
2161  src->functions = fn_p;
2162
2163  for (ix = src->num_lines, line = src->lines; ix--; line++)
2164    {
2165      if (!flag_all_blocks)
2166	{
2167	  arc_t *arc, *arc_p, *arc_n;
2168
2169	  /* Total and reverse the branch information.  */
2170	  for (arc = line->u.branches, arc_p = NULL; arc;
2171	       arc_p = arc, arc = arc_n)
2172	    {
2173	      arc_n = arc->line_next;
2174	      arc->line_next = arc_p;
2175
2176	      add_branch_counts (&src->coverage, arc);
2177	    }
2178	  line->u.branches = arc_p;
2179	}
2180      else if (line->u.blocks)
2181	{
2182	  /* The user expects the line count to be the number of times
2183	     a line has been executed. Simply summing the block count
2184	     will give an artificially high number.  The Right Thing
2185	     is to sum the entry counts to the graph of blocks on this
2186	     line, then find the elementary cycles of the local graph
2187	     and add the transition counts of those cycles.  */
2188	  block_t *block, *block_p, *block_n;
2189	  gcov_type count = 0;
2190
2191	  /* Reverse the block information.  */
2192	  for (block = line->u.blocks, block_p = NULL; block;
2193	       block_p = block, block = block_n)
2194	    {
2195	      block_n = block->chain;
2196	      block->chain = block_p;
2197	      block->u.cycle.ident = ix;
2198	    }
2199	  line->u.blocks = block_p;
2200
2201	  /* Sum the entry arcs.  */
2202	  for (block = line->u.blocks; block; block = block->chain)
2203	    {
2204	      arc_t *arc;
2205
2206	      for (arc = block->pred; arc; arc = arc->pred_next)
2207		{
2208		  if (arc->src->u.cycle.ident != ix)
2209		    count += arc->count;
2210		  if (flag_branches)
2211		    add_branch_counts (&src->coverage, arc);
2212		}
2213
2214	      /* Initialize the cs_count.  */
2215	      for (arc = block->succ; arc; arc = arc->succ_next)
2216		arc->cs_count = arc->count;
2217	    }
2218
2219	  /* Find the loops. This uses the algorithm described in
2220	     Tiernan 'An Efficient Search Algorithm to Find the
2221	     Elementary Circuits of a Graph', CACM Dec 1970. We hold
2222	     the P array by having each block point to the arc that
2223	     connects to the previous block. The H array is implicitly
2224	     held because of the arc ordering, and the block's
2225	     previous arc pointer.
2226
2227	     Although the algorithm is O(N^3) for highly connected
2228	     graphs, at worst we'll have O(N^2), as most blocks have
2229	     only one or two exits. Most graphs will be small.
2230
2231	     For each loop we find, locate the arc with the smallest
2232	     transition count, and add that to the cumulative
2233	     count.  Decrease flow over the cycle and remove the arc
2234	     from consideration.  */
2235	  for (block = line->u.blocks; block; block = block->chain)
2236	    {
2237	      block_t *head = block;
2238	      arc_t *arc;
2239
2240	    next_vertex:;
2241	      arc = head->succ;
2242	    current_vertex:;
2243	      while (arc)
2244		{
2245		  block_t *dst = arc->dst;
2246		  if (/* Already used that arc.  */
2247		      arc->cycle
2248		      /* Not to same graph, or before first vertex.  */
2249		      || dst->u.cycle.ident != ix
2250		      /* Already in path.  */
2251		      || dst->u.cycle.arc)
2252		    {
2253		      arc = arc->succ_next;
2254		      continue;
2255		    }
2256
2257		  if (dst == block)
2258		    {
2259		      /* Found a closing arc.  */
2260		      gcov_type cycle_count = arc->cs_count;
2261		      arc_t *cycle_arc = arc;
2262		      arc_t *probe_arc;
2263
2264		      /* Locate the smallest arc count of the loop.  */
2265		      for (dst = head; (probe_arc = dst->u.cycle.arc);
2266			   dst = probe_arc->src)
2267			if (cycle_count > probe_arc->cs_count)
2268			  {
2269			    cycle_count = probe_arc->cs_count;
2270			    cycle_arc = probe_arc;
2271			  }
2272
2273		      count += cycle_count;
2274		      cycle_arc->cycle = 1;
2275
2276		      /* Remove the flow from the cycle.  */
2277		      arc->cs_count -= cycle_count;
2278		      for (dst = head; (probe_arc = dst->u.cycle.arc);
2279			   dst = probe_arc->src)
2280			probe_arc->cs_count -= cycle_count;
2281
2282		      /* Unwind to the cyclic arc.  */
2283		      while (head != cycle_arc->src)
2284			{
2285			  arc = head->u.cycle.arc;
2286			  head->u.cycle.arc = NULL;
2287			  head = arc->src;
2288			}
2289		      /* Move on.  */
2290		      arc = arc->succ_next;
2291		      continue;
2292		    }
2293
2294		  /* Add new block to chain.  */
2295		  dst->u.cycle.arc = arc;
2296		  head = dst;
2297		  goto next_vertex;
2298		}
2299	      /* We could not add another vertex to the path. Remove
2300		 the last vertex from the list.  */
2301	      arc = head->u.cycle.arc;
2302	      if (arc)
2303		{
2304		  /* It was not the first vertex. Move onto next arc.  */
2305		  head->u.cycle.arc = NULL;
2306		  head = arc->src;
2307		  arc = arc->succ_next;
2308		  goto current_vertex;
2309		}
2310	      /* Mark this block as unusable.  */
2311	      block->u.cycle.ident = ~0U;
2312	    }
2313
2314	  line->count = count;
2315	}
2316
2317      if (line->exists)
2318	{
2319	  src->coverage.lines++;
2320	  if (line->count)
2321	    src->coverage.lines_executed++;
2322	}
2323    }
2324}
2325
2326/* Output information about ARC number IX.  Returns nonzero if
2327   anything is output.  */
2328
2329static int
2330output_branch_count (FILE *gcov_file, int ix, const arc_t *arc)
2331{
2332  if (arc->is_call_non_return)
2333    {
2334      if (arc->src->count)
2335	{
2336	  fnotice (gcov_file, "call   %2d returned %s\n", ix,
2337		   format_gcov (arc->src->count - arc->count,
2338				arc->src->count, -flag_counts));
2339	}
2340      else
2341	fnotice (gcov_file, "call   %2d never executed\n", ix);
2342    }
2343  else if (!arc->is_unconditional)
2344    {
2345      if (arc->src->count)
2346	fnotice (gcov_file, "branch %2d taken %s%s\n", ix,
2347		 format_gcov (arc->count, arc->src->count, -flag_counts),
2348		 arc->fall_through ? " (fallthrough)"
2349		 : arc->is_throw ? " (throw)" : "");
2350      else
2351	fnotice (gcov_file, "branch %2d never executed\n", ix);
2352    }
2353  else if (flag_unconditional && !arc->dst->is_call_return)
2354    {
2355      if (arc->src->count)
2356	fnotice (gcov_file, "unconditional %2d taken %s\n", ix,
2357		 format_gcov (arc->count, arc->src->count, -flag_counts));
2358      else
2359	fnotice (gcov_file, "unconditional %2d never executed\n", ix);
2360    }
2361  else
2362    return 0;
2363  return 1;
2364
2365}
2366
2367static const char *
2368read_line (FILE *file)
2369{
2370  static char *string;
2371  static size_t string_len;
2372  size_t pos = 0;
2373  char *ptr;
2374
2375  if (!string_len)
2376    {
2377      string_len = 200;
2378      string = XNEWVEC (char, string_len);
2379    }
2380
2381  while ((ptr = fgets (string + pos, string_len - pos, file)))
2382    {
2383      size_t len = strlen (string + pos);
2384
2385      if (string[pos + len - 1] == '\n')
2386	{
2387	  string[pos + len - 1] = 0;
2388	  return string;
2389	}
2390      pos += len;
2391      string = XRESIZEVEC (char, string, string_len * 2);
2392      string_len *= 2;
2393    }
2394
2395  return pos ? string : NULL;
2396}
2397
2398/* Read in the source file one line at a time, and output that line to
2399   the gcov file preceded by its execution count and other
2400   information.  */
2401
2402static void
2403output_lines (FILE *gcov_file, const source_t *src)
2404{
2405  FILE *source_file;
2406  unsigned line_num;	/* current line number.  */
2407  const line_t *line;           /* current line info ptr.  */
2408  const char *retval = "";	/* status of source file reading.  */
2409  function_t *fn = NULL;
2410
2411  fprintf (gcov_file, "%9s:%5d:Source:%s\n", "-", 0, src->coverage.name);
2412  if (!multiple_files)
2413    {
2414      fprintf (gcov_file, "%9s:%5d:Graph:%s\n", "-", 0, bbg_file_name);
2415      fprintf (gcov_file, "%9s:%5d:Data:%s\n", "-", 0,
2416	       no_data_file ? "-" : da_file_name);
2417      fprintf (gcov_file, "%9s:%5d:Runs:%u\n", "-", 0, object_runs);
2418    }
2419  fprintf (gcov_file, "%9s:%5d:Programs:%u\n", "-", 0, program_count);
2420
2421  source_file = fopen (src->name, "r");
2422  if (!source_file)
2423    {
2424      fnotice (stderr, "Cannot open source file %s\n", src->name);
2425      retval = NULL;
2426    }
2427  else if (src->file_time == 0)
2428    fprintf (gcov_file, "%9s:%5d:Source is newer than graph\n", "-", 0);
2429
2430  if (flag_branches)
2431    fn = src->functions;
2432
2433  for (line_num = 1, line = &src->lines[line_num];
2434       line_num < src->num_lines; line_num++, line++)
2435    {
2436      for (; fn && fn->line == line_num; fn = fn->line_next)
2437	{
2438	  arc_t *arc = fn->blocks[EXIT_BLOCK].pred;
2439	  gcov_type return_count = fn->blocks[EXIT_BLOCK].count;
2440	  gcov_type called_count = fn->blocks[ENTRY_BLOCK].count;
2441
2442	  for (; arc; arc = arc->pred_next)
2443	    if (arc->fake)
2444	      return_count -= arc->count;
2445
2446	  fprintf (gcov_file, "function %s", flag_demangled_names ?
2447                   fn->demangled_name : fn->name);
2448	  fprintf (gcov_file, " called %s",
2449		   format_gcov (called_count, 0, -1));
2450	  fprintf (gcov_file, " returned %s",
2451		   format_gcov (return_count, called_count, 0));
2452	  fprintf (gcov_file, " blocks executed %s",
2453		   format_gcov (fn->blocks_executed, fn->num_blocks - 2, 0));
2454	  fprintf (gcov_file, "\n");
2455	}
2456
2457      if (retval)
2458	retval = read_line (source_file);
2459
2460      /* For lines which don't exist in the .bb file, print '-' before
2461	 the source line.  For lines which exist but were never
2462	 executed, print '#####' or '=====' before the source line.
2463	 Otherwise, print the execution count before the source line.
2464	 There are 16 spaces of indentation added before the source
2465	 line so that tabs won't be messed up.  */
2466      fprintf (gcov_file, "%9s:%5u:%s\n",
2467	       !line->exists ? "-" : line->count
2468	       ? format_gcov (line->count, 0, -1)
2469	       : line->unexceptional ? "#####" : "=====", line_num,
2470	       retval ? retval : "/*EOF*/");
2471
2472      if (flag_all_blocks)
2473	{
2474	  block_t *block;
2475	  arc_t *arc;
2476	  int ix, jx;
2477
2478	  for (ix = jx = 0, block = line->u.blocks; block;
2479	       block = block->chain)
2480	    {
2481	      if (!block->is_call_return)
2482		fprintf (gcov_file, "%9s:%5u-block %2d\n",
2483			 !line->exists ? "-" : block->count
2484			 ? format_gcov (block->count, 0, -1)
2485			 : block->exceptional ? "%%%%%" : "$$$$$",
2486			 line_num, ix++);
2487	      if (flag_branches)
2488		for (arc = block->succ; arc; arc = arc->succ_next)
2489		  jx += output_branch_count (gcov_file, jx, arc);
2490	    }
2491	}
2492      else if (flag_branches)
2493	{
2494	  int ix;
2495	  arc_t *arc;
2496
2497	  for (ix = 0, arc = line->u.branches; arc; arc = arc->line_next)
2498	    ix += output_branch_count (gcov_file, ix, arc);
2499	}
2500    }
2501
2502  /* Handle all remaining source lines.  There may be lines after the
2503     last line of code.  */
2504  if (retval)
2505    {
2506      for (; (retval = read_line (source_file)); line_num++)
2507	fprintf (gcov_file, "%9s:%5u:%s\n", "-", line_num, retval);
2508    }
2509
2510  if (source_file)
2511    fclose (source_file);
2512}
2513