OSDN Git Service

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