OSDN Git Service

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