OSDN Git Service

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