OSDN Git Service

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