OSDN Git Service

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