OSDN Git Service

* cp-tree.h (struct tinst_level): Add chain_next GTY
[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 named from FILE_NAME sans extension.  If
657    OBJECT_DIRECTORY is specified and is a directory, the files are in that
658    directory, but named from the basename of the FILE_NAME, sans extension.
659    Otherwise OBJECT_DIRECTORY is taken to be the name of the object *file*
660    and the data files are named from that.  */
661
662 static void
663 create_file_names (const char *file_name)
664 {
665   char *cptr;
666   char *name;
667   int length = strlen (file_name);
668   int base;
669
670   /* Free previous file names.  */
671   free (bbg_file_name);
672   free (da_file_name);
673   da_file_name = bbg_file_name = NULL;
674   bbg_file_time = 0;
675   bbg_stamp = 0;
676
677   if (object_directory && object_directory[0])
678     {
679       struct stat status;
680
681       length += strlen (object_directory) + 2;
682       name = XNEWVEC (char, length);
683       name[0] = 0;
684
685       base = !stat (object_directory, &status) && S_ISDIR (status.st_mode);
686       strcat (name, object_directory);
687       if (base && (! IS_DIR_SEPARATOR (name[strlen (name) - 1])))
688         strcat (name, "/");
689     }
690   else
691     {
692       name = XNEWVEC (char, length + 1);
693       strcpy (name, file_name);
694       base = 0;
695     }
696
697   if (base)
698     {
699       /* Append source file name.  */
700       const char *cptr = lbasename (file_name);
701       strcat (name, cptr ? cptr : file_name);
702     }
703
704   /* Remove the extension.  */
705   cptr = strrchr (name, '.');
706   if (cptr)
707     *cptr = 0;
708
709   length = strlen (name);
710
711   bbg_file_name = XNEWVEC (char, length + strlen (GCOV_NOTE_SUFFIX) + 1);
712   strcpy (bbg_file_name, name);
713   strcpy (bbg_file_name + length, GCOV_NOTE_SUFFIX);
714
715   da_file_name = XNEWVEC (char, length + strlen (GCOV_DATA_SUFFIX) + 1);
716   strcpy (da_file_name, name);
717   strcpy (da_file_name + length, GCOV_DATA_SUFFIX);
718
719   free (name);
720   return;
721 }
722
723 /* Find or create a source file structure for FILE_NAME. Copies
724    FILE_NAME on creation */
725
726 static source_t *
727 find_source (const char *file_name)
728 {
729   source_t *src;
730   struct stat status;
731
732   if (!file_name)
733     file_name = "<unknown>";
734
735   for (src = sources; src; src = src->next)
736     if (!filename_cmp (file_name, src->name))
737       break;
738
739   if (!src)
740     {
741       src = XCNEW (source_t);
742       src->name = xstrdup (file_name);
743       src->coverage.name = src->name;
744       src->index = source_index++;
745       src->next = sources;
746       sources = src;
747
748       if (!stat (file_name, &status))
749         src->file_time = status.st_mtime;
750     }
751
752   if (src->file_time > bbg_file_time)
753     {
754       static int info_emitted;
755
756       fnotice (stderr, "%s:source file is newer than graph file '%s'\n",
757                src->name, bbg_file_name);
758       if (!info_emitted)
759         {
760           fnotice (stderr,
761                    "(the message is only displayed one per source file)\n");
762           info_emitted = 1;
763         }
764       src->file_time = 0;
765     }
766
767   return src;
768 }
769
770 /* Read the graph file. Return nonzero on fatal error.  */
771
772 static int
773 read_graph_file (void)
774 {
775   unsigned version;
776   unsigned current_tag = 0;
777   struct function_info *fn = NULL;
778   function_t *old_functions_head = functions;
779   source_t *src = NULL;
780   unsigned ix;
781   unsigned tag;
782
783   if (!gcov_open (bbg_file_name, 1))
784     {
785       fnotice (stderr, "%s:cannot open graph file\n", bbg_file_name);
786       return 1;
787     }
788   bbg_file_time = gcov_time ();
789   if (!gcov_magic (gcov_read_unsigned (), GCOV_NOTE_MAGIC))
790     {
791       fnotice (stderr, "%s:not a gcov graph file\n", bbg_file_name);
792       gcov_close ();
793       return 1;
794     }
795
796   version = gcov_read_unsigned ();
797   if (version != GCOV_VERSION)
798     {
799       char v[4], e[4];
800
801       GCOV_UNSIGNED2STRING (v, version);
802       GCOV_UNSIGNED2STRING (e, GCOV_VERSION);
803
804       fnotice (stderr, "%s:version '%.4s', prefer '%.4s'\n",
805                bbg_file_name, v, e);
806     }
807   bbg_stamp = gcov_read_unsigned ();
808
809   while ((tag = gcov_read_unsigned ()))
810     {
811       unsigned length = gcov_read_unsigned ();
812       gcov_position_t base = gcov_position ();
813
814       if (tag == GCOV_TAG_FUNCTION)
815         {
816           char *function_name;
817           unsigned ident, lineno;
818           unsigned lineno_checksum, cfg_checksum;
819           source_t *src;
820           function_t *probe, *prev;
821
822           ident = gcov_read_unsigned ();
823           lineno_checksum = gcov_read_unsigned ();
824           cfg_checksum = gcov_read_unsigned ();
825           function_name = xstrdup (gcov_read_string ());
826           src = find_source (gcov_read_string ());
827           lineno = gcov_read_unsigned ();
828
829           fn = XCNEW (function_t);
830           fn->name = function_name;
831           fn->ident = ident;
832           fn->lineno_checksum = lineno_checksum;
833           fn->cfg_checksum = cfg_checksum;
834           fn->src = src;
835           fn->line = lineno;
836
837           fn->next = functions;
838           functions = fn;
839           current_tag = tag;
840
841           if (lineno >= src->num_lines)
842             src->num_lines = lineno + 1;
843           /* Now insert it into the source file's list of
844              functions. Normally functions will be encountered in
845              ascending order, so a simple scan is quick.  */
846           for (probe = src->functions, prev = NULL;
847                probe && probe->line > lineno;
848                prev = probe, probe = probe->line_next)
849             continue;
850           fn->line_next = probe;
851           if (prev)
852             prev->line_next = fn;
853           else
854             src->functions = fn;
855         }
856       else if (fn && tag == GCOV_TAG_BLOCKS)
857         {
858           if (fn->blocks)
859             fnotice (stderr, "%s:already seen blocks for '%s'\n",
860                      bbg_file_name, fn->name);
861           else
862             {
863               unsigned ix, num_blocks = GCOV_TAG_BLOCKS_NUM (length);
864               fn->num_blocks = num_blocks;
865
866               fn->blocks = XCNEWVEC (block_t, fn->num_blocks);
867               for (ix = 0; ix != num_blocks; ix++)
868                 fn->blocks[ix].flags = gcov_read_unsigned ();
869             }
870         }
871       else if (fn && tag == GCOV_TAG_ARCS)
872         {
873           unsigned src = gcov_read_unsigned ();
874           unsigned num_dests = GCOV_TAG_ARCS_NUM (length);
875
876           if (src >= fn->num_blocks || fn->blocks[src].succ)
877             goto corrupt;
878
879           while (num_dests--)
880             {
881               struct arc_info *arc;
882               unsigned dest = gcov_read_unsigned ();
883               unsigned flags = gcov_read_unsigned ();
884
885               if (dest >= fn->num_blocks)
886                 goto corrupt;
887               arc = XCNEW (arc_t);
888
889               arc->dst = &fn->blocks[dest];
890               arc->src = &fn->blocks[src];
891
892               arc->count = 0;
893               arc->count_valid = 0;
894               arc->on_tree = !!(flags & GCOV_ARC_ON_TREE);
895               arc->fake = !!(flags & GCOV_ARC_FAKE);
896               arc->fall_through = !!(flags & GCOV_ARC_FALLTHROUGH);
897
898               arc->succ_next = fn->blocks[src].succ;
899               fn->blocks[src].succ = arc;
900               fn->blocks[src].num_succ++;
901
902               arc->pred_next = fn->blocks[dest].pred;
903               fn->blocks[dest].pred = arc;
904               fn->blocks[dest].num_pred++;
905
906               if (arc->fake)
907                 {
908                   if (src)
909                     {
910                       /* Exceptional exit from this function, the
911                          source block must be a call.  */
912                       fn->blocks[src].is_call_site = 1;
913                       arc->is_call_non_return = 1;
914                     }
915                   else
916                     {
917                       /* Non-local return from a callee of this
918                          function. The destination block is a catch or
919                          setjmp.  */
920                       arc->is_nonlocal_return = 1;
921                       fn->blocks[dest].is_nonlocal_return = 1;
922                     }
923                 }
924
925               if (!arc->on_tree)
926                 fn->num_counts++;
927             }
928         }
929       else if (fn && tag == GCOV_TAG_LINES)
930         {
931           unsigned blockno = gcov_read_unsigned ();
932           unsigned *line_nos = XCNEWVEC (unsigned, length - 1);
933
934           if (blockno >= fn->num_blocks || fn->blocks[blockno].u.line.encoding)
935             goto corrupt;
936
937           for (ix = 0; ;  )
938             {
939               unsigned lineno = gcov_read_unsigned ();
940
941               if (lineno)
942                 {
943                   if (!ix)
944                     {
945                       line_nos[ix++] = 0;
946                       line_nos[ix++] = src->index;
947                     }
948                   line_nos[ix++] = lineno;
949                   if (lineno >= src->num_lines)
950                     src->num_lines = lineno + 1;
951                 }
952               else
953                 {
954                   const char *file_name = gcov_read_string ();
955
956                   if (!file_name)
957                     break;
958                   src = find_source (file_name);
959
960                   line_nos[ix++] = 0;
961                   line_nos[ix++] = src->index;
962                 }
963             }
964
965           fn->blocks[blockno].u.line.encoding = line_nos;
966           fn->blocks[blockno].u.line.num = ix;
967         }
968       else if (current_tag && !GCOV_TAG_IS_SUBTAG (current_tag, tag))
969         {
970           fn = NULL;
971           current_tag = 0;
972         }
973       gcov_sync (base, length);
974       if (gcov_is_error ())
975         {
976         corrupt:;
977           fnotice (stderr, "%s:corrupted\n", bbg_file_name);
978           gcov_close ();
979           return 1;
980         }
981     }
982   gcov_close ();
983
984   /* We built everything backwards, so nreverse them all.  */
985
986   /* Reverse sources. Not strictly necessary, but we'll then process
987      them in the 'expected' order.  */
988   {
989     source_t *src, *src_p, *src_n;
990
991     for (src_p = NULL, src = sources; src; src_p = src, src = src_n)
992       {
993         src_n = src->next;
994         src->next = src_p;
995       }
996     sources =  src_p;
997   }
998
999   /* Reverse functions.  */
1000   {
1001     function_t *fn, *fn_p, *fn_n;
1002
1003     for (fn_p = old_functions_head, fn = functions;
1004          fn != old_functions_head;
1005          fn_p = fn, fn = fn_n)
1006       {
1007         unsigned ix;
1008
1009         fn_n = fn->next;
1010         fn->next = fn_p;
1011
1012         /* Reverse the arcs.  */
1013         for (ix = fn->num_blocks; ix--;)
1014           {
1015             arc_t *arc, *arc_p, *arc_n;
1016
1017             for (arc_p = NULL, arc = fn->blocks[ix].succ; arc;
1018                  arc_p = arc, arc = arc_n)
1019               {
1020                 arc_n = arc->succ_next;
1021                 arc->succ_next = arc_p;
1022               }
1023             fn->blocks[ix].succ = arc_p;
1024
1025             for (arc_p = NULL, arc = fn->blocks[ix].pred; arc;
1026                  arc_p = arc, arc = arc_n)
1027               {
1028                 arc_n = arc->pred_next;
1029                 arc->pred_next = arc_p;
1030               }
1031             fn->blocks[ix].pred = arc_p;
1032           }
1033       }
1034     functions = fn_p;
1035   }
1036   return 0;
1037 }
1038
1039 /* Reads profiles from the count file and attach to each
1040    function. Return nonzero if fatal error.  */
1041
1042 static int
1043 read_count_file (void)
1044 {
1045   unsigned ix;
1046   unsigned version;
1047   unsigned tag;
1048   function_t *fn = NULL;
1049   int error = 0;
1050
1051   if (!gcov_open (da_file_name, 1))
1052     {
1053       fnotice (stderr, "%s:cannot open data file, assuming not executed\n",
1054                da_file_name);
1055       no_data_file = 1;
1056       return 0;
1057     }
1058   if (!gcov_magic (gcov_read_unsigned (), GCOV_DATA_MAGIC))
1059     {
1060       fnotice (stderr, "%s:not a gcov data file\n", da_file_name);
1061     cleanup:;
1062       gcov_close ();
1063       return 1;
1064     }
1065   version = gcov_read_unsigned ();
1066   if (version != GCOV_VERSION)
1067     {
1068       char v[4], e[4];
1069
1070       GCOV_UNSIGNED2STRING (v, version);
1071       GCOV_UNSIGNED2STRING (e, GCOV_VERSION);
1072
1073       fnotice (stderr, "%s:version '%.4s', prefer version '%.4s'\n",
1074                da_file_name, v, e);
1075     }
1076   tag = gcov_read_unsigned ();
1077   if (tag != bbg_stamp)
1078     {
1079       fnotice (stderr, "%s:stamp mismatch with graph file\n", da_file_name);
1080       goto cleanup;
1081     }
1082
1083   while ((tag = gcov_read_unsigned ()))
1084     {
1085       unsigned length = gcov_read_unsigned ();
1086       unsigned long base = gcov_position ();
1087
1088       if (tag == GCOV_TAG_OBJECT_SUMMARY)
1089         gcov_read_summary (&object_summary);
1090       else if (tag == GCOV_TAG_PROGRAM_SUMMARY)
1091         program_count++;
1092       else if (tag == GCOV_TAG_FUNCTION)
1093         {
1094           {
1095             unsigned ident = gcov_read_unsigned ();
1096             struct function_info *fn_n = functions;
1097
1098             /* Try to find the function in the list.
1099                To speed up the search, first start from the last function
1100                found.   */
1101             for (fn = fn ? fn->next : NULL; ; fn = fn->next)
1102               {
1103                 if (fn)
1104                   ;
1105                 else if ((fn = fn_n))
1106                   fn_n = NULL;
1107                 else
1108                   {
1109                     fnotice (stderr, "%s:unknown function '%u'\n",
1110                              da_file_name, ident);
1111                     break;
1112                   }
1113                 if (fn->ident == ident)
1114                   break;
1115               }
1116           }
1117
1118           if (!fn)
1119             ;
1120           else if (gcov_read_unsigned () != fn->lineno_checksum
1121                    || gcov_read_unsigned () != fn->cfg_checksum)
1122             {
1123             mismatch:;
1124               fnotice (stderr, "%s:profile mismatch for '%s'\n",
1125                        da_file_name, fn->name);
1126               goto cleanup;
1127             }
1128         }
1129       else if (tag == GCOV_TAG_FOR_COUNTER (GCOV_COUNTER_ARCS) && fn)
1130         {
1131           if (length != GCOV_TAG_COUNTER_LENGTH (fn->num_counts))
1132             goto mismatch;
1133
1134           if (!fn->counts)
1135             fn->counts = XCNEWVEC (gcov_type, fn->num_counts);
1136
1137           for (ix = 0; ix != fn->num_counts; ix++)
1138             fn->counts[ix] += gcov_read_counter ();
1139         }
1140       gcov_sync (base, length);
1141       if ((error = gcov_is_error ()))
1142         {
1143           fnotice (stderr, error < 0 ? "%s:overflowed\n" : "%s:corrupted\n",
1144                    da_file_name);
1145           goto cleanup;
1146         }
1147     }
1148
1149   gcov_close ();
1150   return 0;
1151 }
1152
1153 /* Solve the flow graph. Propagate counts from the instrumented arcs
1154    to the blocks and the uninstrumented arcs.  */
1155
1156 static void
1157 solve_flow_graph (function_t *fn)
1158 {
1159   unsigned ix;
1160   arc_t *arc;
1161   gcov_type *count_ptr = fn->counts;
1162   block_t *blk;
1163   block_t *valid_blocks = NULL;    /* valid, but unpropagated blocks.  */
1164   block_t *invalid_blocks = NULL;  /* invalid, but inferable blocks.  */
1165
1166   if (fn->num_blocks < 2)
1167     fnotice (stderr, "%s:'%s' lacks entry and/or exit blocks\n",
1168              bbg_file_name, fn->name);
1169   else
1170     {
1171       if (fn->blocks[0].num_pred)
1172         fnotice (stderr, "%s:'%s' has arcs to entry block\n",
1173                  bbg_file_name, fn->name);
1174       else
1175         /* We can't deduce the entry block counts from the lack of
1176            predecessors.  */
1177         fn->blocks[0].num_pred = ~(unsigned)0;
1178
1179       if (fn->blocks[fn->num_blocks - 1].num_succ)
1180         fnotice (stderr, "%s:'%s' has arcs from exit block\n",
1181                  bbg_file_name, fn->name);
1182       else
1183         /* Likewise, we can't deduce exit block counts from the lack
1184            of its successors.  */
1185         fn->blocks[fn->num_blocks - 1].num_succ = ~(unsigned)0;
1186     }
1187
1188   /* Propagate the measured counts, this must be done in the same
1189      order as the code in profile.c  */
1190   for (ix = 0, blk = fn->blocks; ix != fn->num_blocks; ix++, blk++)
1191     {
1192       block_t const *prev_dst = NULL;
1193       int out_of_order = 0;
1194       int non_fake_succ = 0;
1195
1196       for (arc = blk->succ; arc; arc = arc->succ_next)
1197         {
1198           if (!arc->fake)
1199             non_fake_succ++;
1200
1201           if (!arc->on_tree)
1202             {
1203               if (count_ptr)
1204                 arc->count = *count_ptr++;
1205               arc->count_valid = 1;
1206               blk->num_succ--;
1207               arc->dst->num_pred--;
1208             }
1209           if (prev_dst && prev_dst > arc->dst)
1210             out_of_order = 1;
1211           prev_dst = arc->dst;
1212         }
1213       if (non_fake_succ == 1)
1214         {
1215           /* If there is only one non-fake exit, it is an
1216              unconditional branch.  */
1217           for (arc = blk->succ; arc; arc = arc->succ_next)
1218             if (!arc->fake)
1219               {
1220                 arc->is_unconditional = 1;
1221                 /* If this block is instrumenting a call, it might be
1222                    an artificial block. It is not artificial if it has
1223                    a non-fallthrough exit, or the destination of this
1224                    arc has more than one entry.  Mark the destination
1225                    block as a return site, if none of those conditions
1226                    hold.  */
1227                 if (blk->is_call_site && arc->fall_through
1228                     && arc->dst->pred == arc && !arc->pred_next)
1229                   arc->dst->is_call_return = 1;
1230               }
1231         }
1232
1233       /* Sort the successor arcs into ascending dst order. profile.c
1234          normally produces arcs in the right order, but sometimes with
1235          one or two out of order.  We're not using a particularly
1236          smart sort.  */
1237       if (out_of_order)
1238         {
1239           arc_t *start = blk->succ;
1240           unsigned changes = 1;
1241
1242           while (changes)
1243             {
1244               arc_t *arc, *arc_p, *arc_n;
1245
1246               changes = 0;
1247               for (arc_p = NULL, arc = start; (arc_n = arc->succ_next);)
1248                 {
1249                   if (arc->dst > arc_n->dst)
1250                     {
1251                       changes = 1;
1252                       if (arc_p)
1253                         arc_p->succ_next = arc_n;
1254                       else
1255                         start = arc_n;
1256                       arc->succ_next = arc_n->succ_next;
1257                       arc_n->succ_next = arc;
1258                       arc_p = arc_n;
1259                     }
1260                   else
1261                     {
1262                       arc_p = arc;
1263                       arc = arc_n;
1264                     }
1265                 }
1266             }
1267           blk->succ = start;
1268         }
1269
1270       /* Place it on the invalid chain, it will be ignored if that's
1271          wrong.  */
1272       blk->invalid_chain = 1;
1273       blk->chain = invalid_blocks;
1274       invalid_blocks = blk;
1275     }
1276
1277   while (invalid_blocks || valid_blocks)
1278     {
1279       while ((blk = invalid_blocks))
1280         {
1281           gcov_type total = 0;
1282           const arc_t *arc;
1283
1284           invalid_blocks = blk->chain;
1285           blk->invalid_chain = 0;
1286           if (!blk->num_succ)
1287             for (arc = blk->succ; arc; arc = arc->succ_next)
1288               total += arc->count;
1289           else if (!blk->num_pred)
1290             for (arc = blk->pred; arc; arc = arc->pred_next)
1291               total += arc->count;
1292           else
1293             continue;
1294
1295           blk->count = total;
1296           blk->count_valid = 1;
1297           blk->chain = valid_blocks;
1298           blk->valid_chain = 1;
1299           valid_blocks = blk;
1300         }
1301       while ((blk = valid_blocks))
1302         {
1303           gcov_type total;
1304           arc_t *arc, *inv_arc;
1305
1306           valid_blocks = blk->chain;
1307           blk->valid_chain = 0;
1308           if (blk->num_succ == 1)
1309             {
1310               block_t *dst;
1311
1312               total = blk->count;
1313               inv_arc = NULL;
1314               for (arc = blk->succ; arc; arc = arc->succ_next)
1315                 {
1316                   total -= arc->count;
1317                   if (!arc->count_valid)
1318                     inv_arc = arc;
1319                 }
1320               dst = inv_arc->dst;
1321               inv_arc->count_valid = 1;
1322               inv_arc->count = total;
1323               blk->num_succ--;
1324               dst->num_pred--;
1325               if (dst->count_valid)
1326                 {
1327                   if (dst->num_pred == 1 && !dst->valid_chain)
1328                     {
1329                       dst->chain = valid_blocks;
1330                       dst->valid_chain = 1;
1331                       valid_blocks = dst;
1332                     }
1333                 }
1334               else
1335                 {
1336                   if (!dst->num_pred && !dst->invalid_chain)
1337                     {
1338                       dst->chain = invalid_blocks;
1339                       dst->invalid_chain = 1;
1340                       invalid_blocks = dst;
1341                     }
1342                 }
1343             }
1344           if (blk->num_pred == 1)
1345             {
1346               block_t *src;
1347
1348               total = blk->count;
1349               inv_arc = NULL;
1350               for (arc = blk->pred; arc; arc = arc->pred_next)
1351                 {
1352                   total -= arc->count;
1353                   if (!arc->count_valid)
1354                     inv_arc = arc;
1355                 }
1356               src = inv_arc->src;
1357               inv_arc->count_valid = 1;
1358               inv_arc->count = total;
1359               blk->num_pred--;
1360               src->num_succ--;
1361               if (src->count_valid)
1362                 {
1363                   if (src->num_succ == 1 && !src->valid_chain)
1364                     {
1365                       src->chain = valid_blocks;
1366                       src->valid_chain = 1;
1367                       valid_blocks = src;
1368                     }
1369                 }
1370               else
1371                 {
1372                   if (!src->num_succ && !src->invalid_chain)
1373                     {
1374                       src->chain = invalid_blocks;
1375                       src->invalid_chain = 1;
1376                       invalid_blocks = src;
1377                     }
1378                 }
1379             }
1380         }
1381     }
1382
1383   /* If the graph has been correctly solved, every block will have a
1384      valid count.  */
1385   for (ix = 0; ix < fn->num_blocks; ix++)
1386     if (!fn->blocks[ix].count_valid)
1387       {
1388         fnotice (stderr, "%s:graph is unsolvable for '%s'\n",
1389                  bbg_file_name, fn->name);
1390         break;
1391       }
1392 }
1393
1394 \f
1395
1396 /* Increment totals in COVERAGE according to arc ARC.  */
1397
1398 static void
1399 add_branch_counts (coverage_t *coverage, const arc_t *arc)
1400 {
1401   if (arc->is_call_non_return)
1402     {
1403       coverage->calls++;
1404       if (arc->src->count)
1405         coverage->calls_executed++;
1406     }
1407   else if (!arc->is_unconditional)
1408     {
1409       coverage->branches++;
1410       if (arc->src->count)
1411         coverage->branches_executed++;
1412       if (arc->count)
1413         coverage->branches_taken++;
1414     }
1415 }
1416
1417 /* Format a HOST_WIDE_INT as either a percent ratio, or absolute
1418    count.  If dp >= 0, format TOP/BOTTOM * 100 to DP decimal places.
1419    If DP is zero, no decimal point is printed. Only print 100% when
1420    TOP==BOTTOM and only print 0% when TOP=0.  If dp < 0, then simply
1421    format TOP.  Return pointer to a static string.  */
1422
1423 static char const *
1424 format_gcov (gcov_type top, gcov_type bottom, int dp)
1425 {
1426   static char buffer[20];
1427
1428   if (dp >= 0)
1429     {
1430       float ratio = bottom ? (float)top / bottom : 0;
1431       int ix;
1432       unsigned limit = 100;
1433       unsigned percent;
1434
1435       for (ix = dp; ix--; )
1436         limit *= 10;
1437
1438       percent = (unsigned) (ratio * limit + (float)0.5);
1439       if (percent <= 0 && top)
1440         percent = 1;
1441       else if (percent >= limit && top != bottom)
1442         percent = limit - 1;
1443       ix = sprintf (buffer, "%.*u%%", dp + 1, percent);
1444       if (dp)
1445         {
1446           dp++;
1447           do
1448             {
1449               buffer[ix+1] = buffer[ix];
1450               ix--;
1451             }
1452           while (dp--);
1453           buffer[ix + 1] = '.';
1454         }
1455     }
1456   else
1457     sprintf (buffer, HOST_WIDEST_INT_PRINT_DEC, (HOST_WIDEST_INT)top);
1458
1459   return buffer;
1460 }
1461
1462
1463 /* Output summary info for a function.  */
1464
1465 static void
1466 function_summary (const coverage_t *coverage, const char *title)
1467 {
1468   fnotice (stdout, "%s '%s'\n", title, coverage->name);
1469
1470   if (coverage->lines)
1471     fnotice (stdout, "Lines executed:%s of %d\n",
1472              format_gcov (coverage->lines_executed, coverage->lines, 2),
1473              coverage->lines);
1474   else
1475     fnotice (stdout, "No executable lines\n");
1476
1477   if (flag_branches)
1478     {
1479       if (coverage->branches)
1480         {
1481           fnotice (stdout, "Branches executed:%s of %d\n",
1482                    format_gcov (coverage->branches_executed,
1483                                 coverage->branches, 2),
1484                    coverage->branches);
1485           fnotice (stdout, "Taken at least once:%s of %d\n",
1486                    format_gcov (coverage->branches_taken,
1487                                 coverage->branches, 2),
1488                    coverage->branches);
1489         }
1490       else
1491         fnotice (stdout, "No branches\n");
1492       if (coverage->calls)
1493         fnotice (stdout, "Calls executed:%s of %d\n",
1494                  format_gcov (coverage->calls_executed, coverage->calls, 2),
1495                  coverage->calls);
1496       else
1497         fnotice (stdout, "No calls\n");
1498     }
1499 }
1500
1501 /* Generate an output file name. LONG_OUTPUT_NAMES and PRESERVE_PATHS
1502    affect name generation. With preserve_paths we create a filename
1503    from all path components of the source file, replacing '/' with
1504    '#', without it we simply take the basename component. With
1505    long_output_names we prepend the processed name of the input file
1506    to each output name (except when the current source file is the
1507    input file, so you don't get a double concatenation). The two
1508    components are separated by '##'. Also '.' filename components are
1509    removed and '..'  components are renamed to '^'.  */
1510
1511 static char *
1512 make_gcov_file_name (const char *input_name, const char *src_name)
1513 {
1514   const char *cptr;
1515   char *name;
1516
1517   if (flag_long_names && input_name && strcmp (src_name, input_name))
1518     {
1519       name = XNEWVEC (char, strlen (src_name) + strlen (input_name) + 10);
1520       name[0] = 0;
1521       /* Generate the input filename part.  */
1522       cptr = flag_preserve_paths ? NULL : lbasename (input_name);
1523       strcat (name, cptr ? cptr : input_name);
1524       strcat (name, "##");
1525     }
1526   else
1527     {
1528       name = XNEWVEC (char, strlen (src_name) + 10);
1529       name[0] = 0;
1530     }
1531
1532   /* Generate the source filename part.  */
1533
1534   cptr = flag_preserve_paths ? NULL : lbasename (src_name);
1535   strcat (name, cptr ? cptr : src_name);
1536
1537   if (flag_preserve_paths)
1538     {
1539       /* Convert '/' and '\' to '#', remove '/./', convert '/../' to '#^#',
1540          convert ':' to '~' on DOS based file system.  */
1541       char *pnew = name, *pold = name;
1542
1543       /* First check for leading drive separator.  */
1544
1545       while (*pold != '\0')
1546         {
1547 #if defined (HAVE_DOS_BASED_FILE_SYSTEM)
1548           if (*pold == ':')
1549             {
1550               *pnew++ = '~';
1551               pold++;
1552             }
1553           else
1554 #endif
1555           if ((*pold == '/'
1556                     && (strstr (pold, "/./") == pold
1557                         || strstr (pold, "/.\\") == pold))
1558                    || (*pold == '\\'
1559                        && (strstr (pold, "\\.\\") == pold
1560                            || strstr (pold, "\\./") == pold)))
1561               pold += 3;
1562           else if (*pold == '/'
1563                    && (strstr (pold, "/../") == pold
1564                        || strstr (pold, "/..\\") == pold))
1565             {
1566               strcpy (pnew, "#^#");
1567               pnew += 3;
1568               pold += 4;
1569             }
1570           else if (*pold == '\\'
1571                    && (strstr (pold, "\\..\\") == pold
1572                        || strstr (pold, "\\../") == pold))
1573             {
1574               strcpy (pnew, "#^#");
1575               pnew += 3;
1576               pold += 4;
1577             }
1578           else if (*pold == '/' || *pold == '\\')
1579             {
1580               *pnew++ = '#';
1581               pold++;
1582             }
1583           else
1584             *pnew++ = *pold++;
1585         }
1586
1587       *pnew = '\0';
1588     }
1589
1590   strcat (name, ".gcov");
1591   return name;
1592 }
1593
1594 /* Scan through the bb_data for each line in the block, increment
1595    the line number execution count indicated by the execution count of
1596    the appropriate basic block.  */
1597
1598 static void
1599 add_line_counts (coverage_t *coverage, function_t *fn)
1600 {
1601   unsigned ix;
1602   line_t *line = NULL; /* This is propagated from one iteration to the
1603                           next.  */
1604
1605   /* Scan each basic block.  */
1606   for (ix = 0; ix != fn->num_blocks; ix++)
1607     {
1608       block_t *block = &fn->blocks[ix];
1609       unsigned *encoding;
1610       const source_t *src = NULL;
1611       unsigned jx;
1612
1613       if (block->count && ix && ix + 1 != fn->num_blocks)
1614         fn->blocks_executed++;
1615       for (jx = 0, encoding = block->u.line.encoding;
1616            jx != block->u.line.num; jx++, encoding++)
1617         if (!*encoding)
1618           {
1619             unsigned src_n = *++encoding;
1620
1621             for (src = sources; src->index != src_n; src = src->next)
1622               continue;
1623             jx++;
1624           }
1625         else
1626           {
1627             line = &src->lines[*encoding];
1628
1629             if (coverage)
1630               {
1631                 if (!line->exists)
1632                   coverage->lines++;
1633                 if (!line->count && block->count)
1634                   coverage->lines_executed++;
1635               }
1636             line->exists = 1;
1637             line->count += block->count;
1638           }
1639       free (block->u.line.encoding);
1640       block->u.cycle.arc = NULL;
1641       block->u.cycle.ident = ~0U;
1642
1643       if (!ix || ix + 1 == fn->num_blocks)
1644         /* Entry or exit block */;
1645       else if (flag_all_blocks)
1646         {
1647           line_t *block_line = line ? line : &fn->src->lines[fn->line];
1648
1649           block->chain = block_line->u.blocks;
1650           block_line->u.blocks = block;
1651         }
1652       else if (flag_branches)
1653         {
1654           arc_t *arc;
1655
1656           for (arc = block->succ; arc; arc = arc->succ_next)
1657             {
1658               arc->line_next = line->u.branches;
1659               line->u.branches = arc;
1660               if (coverage && !arc->is_unconditional)
1661                 add_branch_counts (coverage, arc);
1662             }
1663         }
1664     }
1665   if (!line)
1666     fnotice (stderr, "%s:no lines for '%s'\n", bbg_file_name, fn->name);
1667 }
1668
1669 /* Accumulate the line counts of a file.  */
1670
1671 static void
1672 accumulate_line_counts (source_t *src)
1673 {
1674   line_t *line;
1675   function_t *fn, *fn_p, *fn_n;
1676   unsigned ix;
1677
1678   /* Reverse the function order.  */
1679   for (fn = src->functions, fn_p = NULL; fn;
1680        fn_p = fn, fn = fn_n)
1681     {
1682       fn_n = fn->line_next;
1683       fn->line_next = fn_p;
1684     }
1685   src->functions = fn_p;
1686
1687   for (ix = src->num_lines, line = src->lines; ix--; line++)
1688     {
1689       if (!flag_all_blocks)
1690         {
1691           arc_t *arc, *arc_p, *arc_n;
1692
1693           /* Total and reverse the branch information.  */
1694           for (arc = line->u.branches, arc_p = NULL; arc;
1695                arc_p = arc, arc = arc_n)
1696             {
1697               arc_n = arc->line_next;
1698               arc->line_next = arc_p;
1699
1700               add_branch_counts (&src->coverage, arc);
1701             }
1702           line->u.branches = arc_p;
1703         }
1704       else if (line->u.blocks)
1705         {
1706           /* The user expects the line count to be the number of times
1707              a line has been executed. Simply summing the block count
1708              will give an artificially high number.  The Right Thing
1709              is to sum the entry counts to the graph of blocks on this
1710              line, then find the elementary cycles of the local graph
1711              and add the transition counts of those cycles.  */
1712           block_t *block, *block_p, *block_n;
1713           gcov_type count = 0;
1714
1715           /* Reverse the block information.  */
1716           for (block = line->u.blocks, block_p = NULL; block;
1717                block_p = block, block = block_n)
1718             {
1719               block_n = block->chain;
1720               block->chain = block_p;
1721               block->u.cycle.ident = ix;
1722             }
1723           line->u.blocks = block_p;
1724
1725           /* Sum the entry arcs.  */
1726           for (block = line->u.blocks; block; block = block->chain)
1727             {
1728               arc_t *arc;
1729
1730               for (arc = block->pred; arc; arc = arc->pred_next)
1731                 {
1732                   if (arc->src->u.cycle.ident != ix)
1733                     count += arc->count;
1734                   if (flag_branches)
1735                     add_branch_counts (&src->coverage, arc);
1736                 }
1737
1738               /* Initialize the cs_count.  */
1739               for (arc = block->succ; arc; arc = arc->succ_next)
1740                 arc->cs_count = arc->count;
1741             }
1742
1743           /* Find the loops. This uses the algorithm described in
1744              Tiernan 'An Efficient Search Algorithm to Find the
1745              Elementary Circuits of a Graph', CACM Dec 1970. We hold
1746              the P array by having each block point to the arc that
1747              connects to the previous block. The H array is implicitly
1748              held because of the arc ordering, and the block's
1749              previous arc pointer.
1750
1751              Although the algorithm is O(N^3) for highly connected
1752              graphs, at worst we'll have O(N^2), as most blocks have
1753              only one or two exits. Most graphs will be small.
1754
1755              For each loop we find, locate the arc with the smallest
1756              transition count, and add that to the cumulative
1757              count.  Decrease flow over the cycle and remove the arc
1758              from consideration.  */
1759           for (block = line->u.blocks; block; block = block->chain)
1760             {
1761               block_t *head = block;
1762               arc_t *arc;
1763
1764             next_vertex:;
1765               arc = head->succ;
1766             current_vertex:;
1767               while (arc)
1768                 {
1769                   block_t *dst = arc->dst;
1770                   if (/* Already used that arc.  */
1771                       arc->cycle
1772                       /* Not to same graph, or before first vertex.  */
1773                       || dst->u.cycle.ident != ix
1774                       /* Already in path.  */
1775                       || dst->u.cycle.arc)
1776                     {
1777                       arc = arc->succ_next;
1778                       continue;
1779                     }
1780
1781                   if (dst == block)
1782                     {
1783                       /* Found a closing arc.  */
1784                       gcov_type cycle_count = arc->cs_count;
1785                       arc_t *cycle_arc = arc;
1786                       arc_t *probe_arc;
1787
1788                       /* Locate the smallest arc count of the loop.  */
1789                       for (dst = head; (probe_arc = dst->u.cycle.arc);
1790                            dst = probe_arc->src)
1791                         if (cycle_count > probe_arc->cs_count)
1792                           {
1793                             cycle_count = probe_arc->cs_count;
1794                             cycle_arc = probe_arc;
1795                           }
1796
1797                       count += cycle_count;
1798                       cycle_arc->cycle = 1;
1799
1800                       /* Remove the flow from the cycle.  */
1801                       arc->cs_count -= cycle_count;
1802                       for (dst = head; (probe_arc = dst->u.cycle.arc);
1803                            dst = probe_arc->src)
1804                         probe_arc->cs_count -= cycle_count;
1805
1806                       /* Unwind to the cyclic arc.  */
1807                       while (head != cycle_arc->src)
1808                         {
1809                           arc = head->u.cycle.arc;
1810                           head->u.cycle.arc = NULL;
1811                           head = arc->src;
1812                         }
1813                       /* Move on.  */
1814                       arc = arc->succ_next;
1815                       continue;
1816                     }
1817
1818                   /* Add new block to chain.  */
1819                   dst->u.cycle.arc = arc;
1820                   head = dst;
1821                   goto next_vertex;
1822                 }
1823               /* We could not add another vertex to the path. Remove
1824                  the last vertex from the list.  */
1825               arc = head->u.cycle.arc;
1826               if (arc)
1827                 {
1828                   /* It was not the first vertex. Move onto next arc.  */
1829                   head->u.cycle.arc = NULL;
1830                   head = arc->src;
1831                   arc = arc->succ_next;
1832                   goto current_vertex;
1833                 }
1834               /* Mark this block as unusable.  */
1835               block->u.cycle.ident = ~0U;
1836             }
1837
1838           line->count = count;
1839         }
1840
1841       if (line->exists)
1842         {
1843           src->coverage.lines++;
1844           if (line->count)
1845             src->coverage.lines_executed++;
1846         }
1847     }
1848 }
1849
1850 /* Output information about ARC number IX.  Returns nonzero if
1851    anything is output.  */
1852
1853 static int
1854 output_branch_count (FILE *gcov_file, int ix, const arc_t *arc)
1855 {
1856
1857   if (arc->is_call_non_return)
1858     {
1859       if (arc->src->count)
1860         {
1861           fnotice (gcov_file, "call   %2d returned %s\n", ix,
1862                    format_gcov (arc->src->count - arc->count,
1863                                 arc->src->count, -flag_counts));
1864         }
1865       else
1866         fnotice (gcov_file, "call   %2d never executed\n", ix);
1867     }
1868   else if (!arc->is_unconditional)
1869     {
1870       if (arc->src->count)
1871         fnotice (gcov_file, "branch %2d taken %s%s\n", ix,
1872                  format_gcov (arc->count, arc->src->count, -flag_counts),
1873                  arc->fall_through ? " (fallthrough)" : "");
1874       else
1875         fnotice (gcov_file, "branch %2d never executed\n", ix);
1876     }
1877   else if (flag_unconditional && !arc->dst->is_call_return)
1878     {
1879       if (arc->src->count)
1880         fnotice (gcov_file, "unconditional %2d taken %s\n", ix,
1881                  format_gcov (arc->count, arc->src->count, -flag_counts));
1882       else
1883         fnotice (gcov_file, "unconditional %2d never executed\n", ix);
1884     }
1885   else
1886     return 0;
1887   return 1;
1888
1889 }
1890
1891 /* Read in the source file one line at a time, and output that line to
1892    the gcov file preceded by its execution count and other
1893    information.  */
1894
1895 static void
1896 output_lines (FILE *gcov_file, const source_t *src)
1897 {
1898   FILE *source_file;
1899   unsigned line_num;    /* current line number.  */
1900   const line_t *line;           /* current line info ptr.  */
1901   char string[STRING_SIZE];     /* line buffer.  */
1902   char const *retval = "";      /* status of source file reading.  */
1903   function_t *fn = NULL;
1904
1905   fprintf (gcov_file, "%9s:%5d:Source:%s\n", "-", 0, src->name);
1906   if (!multiple_files)
1907     {
1908       fprintf (gcov_file, "%9s:%5d:Graph:%s\n", "-", 0, bbg_file_name);
1909       fprintf (gcov_file, "%9s:%5d:Data:%s\n", "-", 0,
1910                no_data_file ? "-" : da_file_name);
1911       fprintf (gcov_file, "%9s:%5d:Runs:%u\n", "-", 0,
1912                object_summary.ctrs[GCOV_COUNTER_ARCS].runs);
1913     }
1914   fprintf (gcov_file, "%9s:%5d:Programs:%u\n", "-", 0, program_count);
1915
1916   source_file = fopen (src->name, "r");
1917   if (!source_file)
1918     {
1919       fnotice (stderr, "%s:cannot open source file\n", src->name);
1920       retval = NULL;
1921     }
1922   else if (src->file_time == 0)
1923     fprintf (gcov_file, "%9s:%5d:Source is newer than graph\n", "-", 0);
1924
1925   if (flag_branches)
1926     fn = src->functions;
1927
1928   for (line_num = 1, line = &src->lines[line_num];
1929        line_num < src->num_lines; line_num++, line++)
1930     {
1931       for (; fn && fn->line == line_num; fn = fn->line_next)
1932         {
1933           arc_t *arc = fn->blocks[fn->num_blocks - 1].pred;
1934           gcov_type return_count = fn->blocks[fn->num_blocks - 1].count;
1935
1936           for (; arc; arc = arc->pred_next)
1937             if (arc->fake)
1938               return_count -= arc->count;
1939
1940           fprintf (gcov_file, "function %s", fn->name);
1941           fprintf (gcov_file, " called %s",
1942                    format_gcov (fn->blocks[0].count, 0, -1));
1943           fprintf (gcov_file, " returned %s",
1944                    format_gcov (return_count, fn->blocks[0].count, 0));
1945           fprintf (gcov_file, " blocks executed %s",
1946                    format_gcov (fn->blocks_executed, fn->num_blocks - 2, 0));
1947           fprintf (gcov_file, "\n");
1948         }
1949
1950       /* For lines which don't exist in the .bb file, print '-' before
1951          the source line.  For lines which exist but were never
1952          executed, print '#####' before the source line.  Otherwise,
1953          print the execution count before the source line.  There are
1954          16 spaces of indentation added before the source line so that
1955          tabs won't be messed up.  */
1956       fprintf (gcov_file, "%9s:%5u:",
1957                !line->exists ? "-" : !line->count ? "#####"
1958                : format_gcov (line->count, 0, -1), line_num);
1959
1960       if (retval)
1961         {
1962           /* Copy source line.  */
1963           do
1964             {
1965               retval = fgets (string, STRING_SIZE, source_file);
1966               if (!retval)
1967                 break;
1968               fputs (retval, gcov_file);
1969             }
1970           while (!retval[0] || retval[strlen (retval) - 1] != '\n');
1971         }
1972       if (!retval)
1973         fputs ("/*EOF*/\n", gcov_file);
1974
1975       if (flag_all_blocks)
1976         {
1977           block_t *block;
1978           arc_t *arc;
1979           int ix, jx;
1980
1981           for (ix = jx = 0, block = line->u.blocks; block;
1982                block = block->chain)
1983             {
1984               if (!block->is_call_return)
1985                 fprintf (gcov_file, "%9s:%5u-block %2d\n",
1986                          !line->exists ? "-" : !block->count ? "$$$$$"
1987                          : format_gcov (block->count, 0, -1),
1988                          line_num, ix++);
1989               if (flag_branches)
1990                 for (arc = block->succ; arc; arc = arc->succ_next)
1991                   jx += output_branch_count (gcov_file, jx, arc);
1992             }
1993         }
1994       else if (flag_branches)
1995         {
1996           int ix;
1997           arc_t *arc;
1998
1999           for (ix = 0, arc = line->u.branches; arc; arc = arc->line_next)
2000             ix += output_branch_count (gcov_file, ix, arc);
2001         }
2002     }
2003
2004   /* Handle all remaining source lines.  There may be lines after the
2005      last line of code.  */
2006   if (retval)
2007     {
2008       for (; (retval = fgets (string, STRING_SIZE, source_file)); line_num++)
2009         {
2010           fprintf (gcov_file, "%9s:%5u:%s", "-", line_num, retval);
2011
2012           while (!retval[0] || retval[strlen (retval) - 1] != '\n')
2013             {
2014               retval = fgets (string, STRING_SIZE, source_file);
2015               if (!retval)
2016                 break;
2017               fputs (retval, gcov_file);
2018             }
2019         }
2020     }
2021
2022   if (source_file)
2023     fclose (source_file);
2024 }