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