OSDN Git Service

2011-05-16 Richard Guenther <rguenther@suse.de>
[pf3gnuchains/gcc-fork.git] / gcc / gcov.c
1 /* Gcov.c: prepend line execution counts and branch probabilities to a
2    source file.
3    Copyright (C) 1990, 1991, 1992, 1993, 1994, 1996, 1997, 1998, 1999,
4    2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
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 "version.h"
41
42 #include <getopt.h>
43
44 #define IN_GCOV 1
45 #include "gcov-io.h"
46 #include "gcov-io.c"
47
48 /* The gcno file is generated by -ftest-coverage option. The gcda file is
49    generated by a program compiled with -fprofile-arcs. Their formats
50    are documented in gcov-io.h.  */
51
52 /* The functions in this file for creating and solution program flow graphs
53    are very similar to functions in the gcc source file profile.c.  In
54    some places we make use of the knowledge of how profile.c works to
55    select particular algorithms here.  */
56
57 /* The code validates that the profile information read in corresponds
58    to the code currently being compiled.  Rather than checking for
59    identical files, the code below computes a checksum on the CFG
60    (based on the order of basic blocks and the arcs in the CFG).  If
61    the CFG checksum in the gcda file match the CFG checksum for the
62    code currently being compiled, the profile data will be used.  */
63
64 /* This is the size of the buffer used to read in source file lines.  */
65
66 #define STRING_SIZE 200
67
68 struct function_info;
69 struct block_info;
70 struct source_info;
71
72 /* Describes an arc between two basic blocks.  */
73
74 typedef struct arc_info
75 {
76   /* source and destination blocks.  */
77   struct block_info *src;
78   struct block_info *dst;
79
80   /* transition counts.  */
81   gcov_type count;
82   /* used in cycle search, so that we do not clobber original counts.  */
83   gcov_type cs_count;
84
85   unsigned int count_valid : 1;
86   unsigned int on_tree : 1;
87   unsigned int fake : 1;
88   unsigned int fall_through : 1;
89
90   /* Arc is for a function that abnormally returns.  */
91   unsigned int is_call_non_return : 1;
92
93   /* Arc is for catch/setjmp.  */
94   unsigned int is_nonlocal_return : 1;
95
96   /* Is an unconditional branch.  */
97   unsigned int is_unconditional : 1;
98
99   /* Loop making arc.  */
100   unsigned int cycle : 1;
101
102   /* Next branch on line.  */
103   struct arc_info *line_next;
104
105   /* Links to next arc on src and dst lists.  */
106   struct arc_info *succ_next;
107   struct arc_info *pred_next;
108 } arc_t;
109
110 /* Describes a basic block. Contains lists of arcs to successor and
111    predecessor blocks.  */
112
113 typedef struct block_info
114 {
115   /* Chain of exit and entry arcs.  */
116   arc_t *succ;
117   arc_t *pred;
118
119   /* Number of unprocessed exit and entry arcs.  */
120   gcov_type num_succ;
121   gcov_type num_pred;
122
123   /* Block execution count.  */
124   gcov_type count;
125   unsigned flags : 13;
126   unsigned count_valid : 1;
127   unsigned valid_chain : 1;
128   unsigned invalid_chain : 1;
129
130   /* Block is a call instrumenting site.  */
131   unsigned is_call_site : 1; /* Does the call.  */
132   unsigned is_call_return : 1; /* Is the return.  */
133
134   /* Block is a landing pad for longjmp or throw.  */
135   unsigned is_nonlocal_return : 1;
136
137   union
138   {
139     struct
140     {
141      /* Array of line numbers and source files. source files are
142         introduced by a linenumber of zero, the next 'line number' is
143         the number of the source file.  Always starts with a source
144         file.  */
145       unsigned *encoding;
146       unsigned num;
147     } line; /* Valid until blocks are linked onto lines */
148     struct
149     {
150       /* Single line graph cycle workspace.  Used for all-blocks
151          mode.  */
152       arc_t *arc;
153       unsigned ident;
154     } cycle; /* Used in all-blocks mode, after blocks are linked onto
155                lines.  */
156   } u;
157
158   /* Temporary chain for solving graph, and for chaining blocks on one
159      line.  */
160   struct block_info *chain;
161
162 } block_t;
163
164 /* Describes a single function. Contains an array of basic blocks.  */
165
166 typedef struct function_info
167 {
168   /* Name of function.  */
169   char *name;
170   unsigned ident;
171   unsigned lineno_checksum;
172   unsigned cfg_checksum;
173
174   /* Array of basic blocks.  */
175   block_t *blocks;
176   unsigned num_blocks;
177   unsigned blocks_executed;
178
179   /* Raw arc coverage counts.  */
180   gcov_type *counts;
181   unsigned num_counts;
182
183   /* First line number.  */
184   unsigned line;
185   struct source_info *src;
186
187   /* Next function in same source file.  */
188   struct function_info *line_next;
189
190   /* Next function.  */
191   struct function_info *next;
192 } function_t;
193
194 /* Describes coverage of a file or function.  */
195
196 typedef struct coverage_info
197 {
198   int lines;
199   int lines_executed;
200
201   int branches;
202   int branches_executed;
203   int branches_taken;
204
205   int calls;
206   int calls_executed;
207
208   char *name;
209 } coverage_t;
210
211 /* Describes a single line of source. Contains a chain of basic blocks
212    with code on it.  */
213
214 typedef struct line_info
215 {
216   gcov_type count;         /* execution count */
217   union
218   {
219     arc_t *branches;       /* branches from blocks that end on this
220                               line. Used for branch-counts when not
221                               all-blocks mode.  */
222     block_t *blocks;       /* blocks which start on this line.  Used
223                               in all-blocks mode.  */
224   } u;
225   unsigned exists : 1;
226 } line_t;
227
228 /* Describes a file mentioned in the block graph.  Contains an array
229    of line info.  */
230
231 typedef struct source_info
232 {
233   /* Name of source file.  */
234   char *name;
235   unsigned index;
236   time_t file_time;
237
238   /* Array of line information.  */
239   line_t *lines;
240   unsigned num_lines;
241
242   coverage_t coverage;
243
244   /* Functions in this source file.  These are in ascending line
245      number order.  */
246   function_t *functions;
247
248   /* Next source file.  */
249   struct source_info *next;
250 } source_t;
251
252 /* Holds a list of function basic block graphs.  */
253
254 static function_t *functions;
255
256 /* This points to the head of the sourcefile structure list.  New elements
257    are always prepended.  */
258
259 static source_t *sources;
260
261 /* Next index for a source file.  */
262
263 static unsigned source_index;
264
265 /* This holds data summary information.  */
266
267 static struct gcov_summary object_summary;
268 static unsigned program_count;
269
270 /* Modification time of graph file.  */
271
272 static time_t bbg_file_time;
273
274 /* Name and file pointer of the input file for the basic block graph.  */
275
276 static char *bbg_file_name;
277
278 /* Stamp of the bbg file */
279 static unsigned bbg_stamp;
280
281 /* Name and file pointer of the input file for the arc count data.  */
282
283 static char *da_file_name;
284
285 /* Data file is missing.  */
286
287 static int no_data_file;
288
289 /* If there is several input files, compute and display results after
290    reading all data files.  This way if two or more gcda file refer to
291    the same source file (eg inline subprograms in a .h file), the
292    counts are added.  */
293
294 static int multiple_files = 0;
295
296 /* Output branch probabilities.  */
297
298 static int flag_branches = 0;
299
300 /* Show unconditional branches too.  */
301 static int flag_unconditional = 0;
302
303 /* Output a gcov file if this is true.  This is on by default, and can
304    be turned off by the -n option.  */
305
306 static int flag_gcov_file = 1;
307
308 /* Output progress indication if this is true.  This is off by default
309    and can be turned on by the -d option.  */
310
311 static int flag_display_progress = 0;
312
313 /* For included files, make the gcov output file name include the name
314    of the input source file.  For example, if x.h is included in a.c,
315    then the output file name is a.c##x.h.gcov instead of x.h.gcov.  */
316
317 static int flag_long_names = 0;
318
319 /* Output count information for every basic block, not merely those
320    that contain line number information.  */
321
322 static int flag_all_blocks = 0;
323
324 /* Output summary info for each function.  */
325
326 static int flag_function_summary = 0;
327
328 /* Object directory file prefix.  This is the directory/file where the
329    graph and data files are looked for, if nonzero.  */
330
331 static char *object_directory = 0;
332
333 /* Preserve all pathname components. Needed when object files and
334    source files are in subdirectories. '/' is mangled as '#', '.' is
335    elided and '..' mangled to '^'.  */
336
337 static int flag_preserve_paths = 0;
338
339 /* Output the number of times a branch was taken as opposed to the percentage
340    of times it was taken.  */
341
342 static int flag_counts = 0;
343
344 /* Forward declarations.  */
345 static void fnotice (FILE *, const char *, ...) ATTRIBUTE_PRINTF_2;
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
373   /* Unlock the stdio streams.  */
374   unlock_std_streams ();
375
376   gcc_init_libintl ();
377
378   /* Handle response files.  */
379   expandargv (&argc, &argv);
380
381   argno = process_args (argc, argv);
382   if (optind == argc)
383     print_usage (true);
384
385   if (argc - argno > 1)
386     multiple_files = 1;
387
388   first_arg = argno;
389   
390   for (; argno != argc; argno++)
391     {
392       if (flag_display_progress)
393         printf("Processing file %d out of %d\n",  
394                argno - first_arg + 1, argc - first_arg);
395       process_file (argv[argno]);
396     }
397
398   generate_results (multiple_files ? NULL : argv[argc - 1]);
399
400   release_structures ();
401
402   return 0;
403 }
404
405 static void
406 fnotice (FILE *file, const char *cmsgid, ...)
407 {
408   va_list ap;
409
410   va_start (ap, cmsgid);
411   vfprintf (file, _(cmsgid), ap);
412   va_end (ap);
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 }