OSDN Git Service

* gcov.c (source_prefix, source_length): New globals.
[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 buf;
1692           
1693           *ptr = 0;
1694           if (dd_base == ptr || stat (result, &buf) || S_ISLNK (buf.st_mode))
1695             {
1696               /* Cannot elide, or unreadable or a symlink.  */
1697               dd_base = ptr + 2 + slash;
1698               goto regular;
1699             }
1700           while (ptr != dd_base && *ptr != '/')
1701             ptr--;
1702           slash = ptr != result;
1703         }
1704       else
1705         {
1706         regular:
1707           /* Regular pathname component.  */
1708           if (slash)
1709             *ptr++ = '/';
1710           memcpy (ptr, base, len);
1711           ptr += len;
1712           slash = 1;
1713         }
1714
1715       for (; IS_DIR_SEPARATOR (*probe); probe++)
1716         continue;
1717     }
1718   *ptr = 0;
1719
1720   return result;
1721 }
1722
1723 /* Generate an output file name. INPUT_NAME is the canonicalized main
1724    input file and SRC_NAME is the canonicalized file name.
1725    LONG_OUTPUT_NAMES and PRESERVE_PATHS affect name generation.  With
1726    long_output_names we prepend the processed name of the input file
1727    to each output name (except when the current source file is the
1728    input file, so you don't get a double concatenation). The two
1729    components are separated by '##'.  With preserve_paths we create a
1730    filename from all path components of the source file, replacing '/'
1731    with '#', and .. with '^', without it we simply take the basename
1732    component.  (Remember, the canonicalized name will already have
1733    elided '.' components and converted \\ separators.)  */
1734
1735 static char *
1736 make_gcov_file_name (const char *input_name, const char *src_name)
1737 {
1738   char *ptr;
1739   char *result;
1740
1741   if (flag_long_names && input_name && strcmp (src_name, input_name))
1742     {
1743       /* Generate the input filename part.  */
1744       result = XNEWVEC (char, strlen (input_name) + strlen (src_name) + 10);
1745   
1746       ptr = result;
1747       ptr = mangle_name (input_name, ptr);
1748       ptr[0] = ptr[1] = '#';
1749       ptr += 2;
1750     }
1751   else
1752     {
1753       result = XNEWVEC (char, strlen (src_name) + 10);
1754       ptr = result;
1755     }
1756
1757   ptr = mangle_name (src_name, ptr);
1758   strcpy (ptr, ".gcov");
1759   
1760   return result;
1761 }
1762
1763 static char *
1764 mangle_name (char const *base, char *ptr)
1765 {
1766   size_t len;
1767   
1768   /* Generate the source filename part.  */
1769   if (!flag_preserve_paths)
1770     {
1771       base = lbasename (base);
1772       len = strlen (base);
1773       memcpy (ptr, base, len);
1774       ptr += len;
1775     }
1776   else
1777     {
1778       /* Convert '/' to '#', convert '..' to '^',
1779          convert ':' to '~' on DOS based file system.  */
1780       const char *probe;
1781
1782 #if HAVE_DOS_BASED_FILE_SYSTEM
1783       if (base[0] && base[1] == ':')
1784         {
1785           ptr[0] = base[0];
1786           ptr[1] = '~';
1787           ptr += 2;
1788           base += 2;
1789         }
1790 #endif
1791       for (; *base; base = probe)
1792         {
1793           size_t len;
1794
1795           for (probe = base; *probe; probe++)
1796             if (*probe == '/')
1797               break;
1798           len = probe - base;
1799           if (len == 2 && base[0] == '.' && base[1] == '.')
1800             *ptr++ = '^';
1801           else
1802             {
1803               memcpy (ptr, base, len);
1804               ptr += len;
1805             }
1806           if (*probe)
1807             {
1808               *ptr++ = '#';
1809               probe++;
1810             }
1811         }
1812     }
1813   
1814   return ptr;
1815 }
1816
1817 /* Scan through the bb_data for each line in the block, increment
1818    the line number execution count indicated by the execution count of
1819    the appropriate basic block.  */
1820
1821 static void
1822 add_line_counts (coverage_t *coverage, function_t *fn)
1823 {
1824   unsigned ix;
1825   line_t *line = NULL; /* This is propagated from one iteration to the
1826                           next.  */
1827
1828   /* Scan each basic block.  */
1829   for (ix = 0; ix != fn->num_blocks; ix++)
1830     {
1831       block_t *block = &fn->blocks[ix];
1832       unsigned *encoding;
1833       const source_t *src = NULL;
1834       unsigned jx;
1835
1836       if (block->count && ix && ix + 1 != fn->num_blocks)
1837         fn->blocks_executed++;
1838       for (jx = 0, encoding = block->u.line.encoding;
1839            jx != block->u.line.num; jx++, encoding++)
1840         if (!*encoding)
1841           {
1842             src = &sources[*++encoding];
1843             jx++;
1844           }
1845         else
1846           {
1847             line = &src->lines[*encoding];
1848
1849             if (coverage)
1850               {
1851                 if (!line->exists)
1852                   coverage->lines++;
1853                 if (!line->count && block->count)
1854                   coverage->lines_executed++;
1855               }
1856             line->exists = 1;
1857             line->count += block->count;
1858           }
1859       free (block->u.line.encoding);
1860       block->u.cycle.arc = NULL;
1861       block->u.cycle.ident = ~0U;
1862
1863       if (!ix || ix + 1 == fn->num_blocks)
1864         /* Entry or exit block */;
1865       else if (flag_all_blocks)
1866         {
1867           line_t *block_line = line;
1868
1869           if (!block_line)
1870             block_line = &sources[fn->src].lines[fn->line];
1871
1872           block->chain = block_line->u.blocks;
1873           block_line->u.blocks = block;
1874         }
1875       else if (flag_branches)
1876         {
1877           arc_t *arc;
1878
1879           for (arc = block->succ; arc; arc = arc->succ_next)
1880             {
1881               arc->line_next = line->u.branches;
1882               line->u.branches = arc;
1883               if (coverage && !arc->is_unconditional)
1884                 add_branch_counts (coverage, arc);
1885             }
1886         }
1887     }
1888   if (!line)
1889     fnotice (stderr, "%s:no lines for '%s'\n", bbg_file_name, fn->name);
1890 }
1891
1892 /* Accumulate the line counts of a file.  */
1893
1894 static void
1895 accumulate_line_counts (source_t *src)
1896 {
1897   line_t *line;
1898   function_t *fn, *fn_p, *fn_n;
1899   unsigned ix;
1900
1901   /* Reverse the function order.  */
1902   for (fn = src->functions, fn_p = NULL; fn;
1903        fn_p = fn, fn = fn_n)
1904     {
1905       fn_n = fn->line_next;
1906       fn->line_next = fn_p;
1907     }
1908   src->functions = fn_p;
1909
1910   for (ix = src->num_lines, line = src->lines; ix--; line++)
1911     {
1912       if (!flag_all_blocks)
1913         {
1914           arc_t *arc, *arc_p, *arc_n;
1915
1916           /* Total and reverse the branch information.  */
1917           for (arc = line->u.branches, arc_p = NULL; arc;
1918                arc_p = arc, arc = arc_n)
1919             {
1920               arc_n = arc->line_next;
1921               arc->line_next = arc_p;
1922
1923               add_branch_counts (&src->coverage, arc);
1924             }
1925           line->u.branches = arc_p;
1926         }
1927       else if (line->u.blocks)
1928         {
1929           /* The user expects the line count to be the number of times
1930              a line has been executed. Simply summing the block count
1931              will give an artificially high number.  The Right Thing
1932              is to sum the entry counts to the graph of blocks on this
1933              line, then find the elementary cycles of the local graph
1934              and add the transition counts of those cycles.  */
1935           block_t *block, *block_p, *block_n;
1936           gcov_type count = 0;
1937
1938           /* Reverse the block information.  */
1939           for (block = line->u.blocks, block_p = NULL; block;
1940                block_p = block, block = block_n)
1941             {
1942               block_n = block->chain;
1943               block->chain = block_p;
1944               block->u.cycle.ident = ix;
1945             }
1946           line->u.blocks = block_p;
1947
1948           /* Sum the entry arcs.  */
1949           for (block = line->u.blocks; block; block = block->chain)
1950             {
1951               arc_t *arc;
1952
1953               for (arc = block->pred; arc; arc = arc->pred_next)
1954                 {
1955                   if (arc->src->u.cycle.ident != ix)
1956                     count += arc->count;
1957                   if (flag_branches)
1958                     add_branch_counts (&src->coverage, arc);
1959                 }
1960
1961               /* Initialize the cs_count.  */
1962               for (arc = block->succ; arc; arc = arc->succ_next)
1963                 arc->cs_count = arc->count;
1964             }
1965
1966           /* Find the loops. This uses the algorithm described in
1967              Tiernan 'An Efficient Search Algorithm to Find the
1968              Elementary Circuits of a Graph', CACM Dec 1970. We hold
1969              the P array by having each block point to the arc that
1970              connects to the previous block. The H array is implicitly
1971              held because of the arc ordering, and the block's
1972              previous arc pointer.
1973
1974              Although the algorithm is O(N^3) for highly connected
1975              graphs, at worst we'll have O(N^2), as most blocks have
1976              only one or two exits. Most graphs will be small.
1977
1978              For each loop we find, locate the arc with the smallest
1979              transition count, and add that to the cumulative
1980              count.  Decrease flow over the cycle and remove the arc
1981              from consideration.  */
1982           for (block = line->u.blocks; block; block = block->chain)
1983             {
1984               block_t *head = block;
1985               arc_t *arc;
1986
1987             next_vertex:;
1988               arc = head->succ;
1989             current_vertex:;
1990               while (arc)
1991                 {
1992                   block_t *dst = arc->dst;
1993                   if (/* Already used that arc.  */
1994                       arc->cycle
1995                       /* Not to same graph, or before first vertex.  */
1996                       || dst->u.cycle.ident != ix
1997                       /* Already in path.  */
1998                       || dst->u.cycle.arc)
1999                     {
2000                       arc = arc->succ_next;
2001                       continue;
2002                     }
2003
2004                   if (dst == block)
2005                     {
2006                       /* Found a closing arc.  */
2007                       gcov_type cycle_count = arc->cs_count;
2008                       arc_t *cycle_arc = arc;
2009                       arc_t *probe_arc;
2010
2011                       /* Locate the smallest arc count of the loop.  */
2012                       for (dst = head; (probe_arc = dst->u.cycle.arc);
2013                            dst = probe_arc->src)
2014                         if (cycle_count > probe_arc->cs_count)
2015                           {
2016                             cycle_count = probe_arc->cs_count;
2017                             cycle_arc = probe_arc;
2018                           }
2019
2020                       count += cycle_count;
2021                       cycle_arc->cycle = 1;
2022
2023                       /* Remove the flow from the cycle.  */
2024                       arc->cs_count -= cycle_count;
2025                       for (dst = head; (probe_arc = dst->u.cycle.arc);
2026                            dst = probe_arc->src)
2027                         probe_arc->cs_count -= cycle_count;
2028
2029                       /* Unwind to the cyclic arc.  */
2030                       while (head != cycle_arc->src)
2031                         {
2032                           arc = head->u.cycle.arc;
2033                           head->u.cycle.arc = NULL;
2034                           head = arc->src;
2035                         }
2036                       /* Move on.  */
2037                       arc = arc->succ_next;
2038                       continue;
2039                     }
2040
2041                   /* Add new block to chain.  */
2042                   dst->u.cycle.arc = arc;
2043                   head = dst;
2044                   goto next_vertex;
2045                 }
2046               /* We could not add another vertex to the path. Remove
2047                  the last vertex from the list.  */
2048               arc = head->u.cycle.arc;
2049               if (arc)
2050                 {
2051                   /* It was not the first vertex. Move onto next arc.  */
2052                   head->u.cycle.arc = NULL;
2053                   head = arc->src;
2054                   arc = arc->succ_next;
2055                   goto current_vertex;
2056                 }
2057               /* Mark this block as unusable.  */
2058               block->u.cycle.ident = ~0U;
2059             }
2060
2061           line->count = count;
2062         }
2063
2064       if (line->exists)
2065         {
2066           src->coverage.lines++;
2067           if (line->count)
2068             src->coverage.lines_executed++;
2069         }
2070     }
2071 }
2072
2073 /* Output information about ARC number IX.  Returns nonzero if
2074    anything is output.  */
2075
2076 static int
2077 output_branch_count (FILE *gcov_file, int ix, const arc_t *arc)
2078 {
2079
2080   if (arc->is_call_non_return)
2081     {
2082       if (arc->src->count)
2083         {
2084           fnotice (gcov_file, "call   %2d returned %s\n", ix,
2085                    format_gcov (arc->src->count - arc->count,
2086                                 arc->src->count, -flag_counts));
2087         }
2088       else
2089         fnotice (gcov_file, "call   %2d never executed\n", ix);
2090     }
2091   else if (!arc->is_unconditional)
2092     {
2093       if (arc->src->count)
2094         fnotice (gcov_file, "branch %2d taken %s%s\n", ix,
2095                  format_gcov (arc->count, arc->src->count, -flag_counts),
2096                  arc->fall_through ? " (fallthrough)" : "");
2097       else
2098         fnotice (gcov_file, "branch %2d never executed\n", ix);
2099     }
2100   else if (flag_unconditional && !arc->dst->is_call_return)
2101     {
2102       if (arc->src->count)
2103         fnotice (gcov_file, "unconditional %2d taken %s\n", ix,
2104                  format_gcov (arc->count, arc->src->count, -flag_counts));
2105       else
2106         fnotice (gcov_file, "unconditional %2d never executed\n", ix);
2107     }
2108   else
2109     return 0;
2110   return 1;
2111
2112 }
2113
2114 /* Read in the source file one line at a time, and output that line to
2115    the gcov file preceded by its execution count and other
2116    information.  */
2117
2118 static void
2119 output_lines (FILE *gcov_file, const source_t *src)
2120 {
2121   FILE *source_file;
2122   unsigned line_num;    /* current line number.  */
2123   const line_t *line;           /* current line info ptr.  */
2124   char string[STRING_SIZE];     /* line buffer.  */
2125   char const *retval = "";      /* status of source file reading.  */
2126   function_t *fn = NULL;
2127
2128   fprintf (gcov_file, "%9s:%5d:Source:%s\n", "-", 0, src->coverage.name);
2129   if (!multiple_files)
2130     {
2131       fprintf (gcov_file, "%9s:%5d:Graph:%s\n", "-", 0, bbg_file_name);
2132       fprintf (gcov_file, "%9s:%5d:Data:%s\n", "-", 0,
2133                no_data_file ? "-" : da_file_name);
2134       fprintf (gcov_file, "%9s:%5d:Runs:%u\n", "-", 0, object_runs);
2135     }
2136   fprintf (gcov_file, "%9s:%5d:Programs:%u\n", "-", 0, program_count);
2137
2138   source_file = fopen (src->name, "r");
2139   if (!source_file)
2140     {
2141       fnotice (stderr, "Cannot open source file %s\n", src->name);
2142       retval = NULL;
2143     }
2144   else if (src->file_time == 0)
2145     fprintf (gcov_file, "%9s:%5d:Source is newer than graph\n", "-", 0);
2146
2147   if (flag_branches)
2148     fn = src->functions;
2149
2150   for (line_num = 1, line = &src->lines[line_num];
2151        line_num < src->num_lines; line_num++, line++)
2152     {
2153       for (; fn && fn->line == line_num; fn = fn->line_next)
2154         {
2155           arc_t *arc = fn->blocks[fn->num_blocks - 1].pred;
2156           gcov_type return_count = fn->blocks[fn->num_blocks - 1].count;
2157
2158           for (; arc; arc = arc->pred_next)
2159             if (arc->fake)
2160               return_count -= arc->count;
2161
2162           fprintf (gcov_file, "function %s", fn->name);
2163           fprintf (gcov_file, " called %s",
2164                    format_gcov (fn->blocks[0].count, 0, -1));
2165           fprintf (gcov_file, " returned %s",
2166                    format_gcov (return_count, fn->blocks[0].count, 0));
2167           fprintf (gcov_file, " blocks executed %s",
2168                    format_gcov (fn->blocks_executed, fn->num_blocks - 2, 0));
2169           fprintf (gcov_file, "\n");
2170         }
2171
2172       /* For lines which don't exist in the .bb file, print '-' before
2173          the source line.  For lines which exist but were never
2174          executed, print '#####' before the source line.  Otherwise,
2175          print the execution count before the source line.  There are
2176          16 spaces of indentation added before the source line so that
2177          tabs won't be messed up.  */
2178       fprintf (gcov_file, "%9s:%5u:",
2179                !line->exists ? "-" : !line->count ? "#####"
2180                : format_gcov (line->count, 0, -1), line_num);
2181
2182       if (retval)
2183         {
2184           /* Copy source line.  */
2185           do
2186             {
2187               retval = fgets (string, STRING_SIZE, source_file);
2188               if (!retval)
2189                 break;
2190               fputs (retval, gcov_file);
2191             }
2192           while (!retval[0] || retval[strlen (retval) - 1] != '\n');
2193         }
2194       if (!retval)
2195         fputs ("/*EOF*/\n", gcov_file);
2196
2197       if (flag_all_blocks)
2198         {
2199           block_t *block;
2200           arc_t *arc;
2201           int ix, jx;
2202
2203           for (ix = jx = 0, block = line->u.blocks; block;
2204                block = block->chain)
2205             {
2206               if (!block->is_call_return)
2207                 fprintf (gcov_file, "%9s:%5u-block %2d\n",
2208                          !line->exists ? "-" : !block->count ? "$$$$$"
2209                          : format_gcov (block->count, 0, -1),
2210                          line_num, ix++);
2211               if (flag_branches)
2212                 for (arc = block->succ; arc; arc = arc->succ_next)
2213                   jx += output_branch_count (gcov_file, jx, arc);
2214             }
2215         }
2216       else if (flag_branches)
2217         {
2218           int ix;
2219           arc_t *arc;
2220
2221           for (ix = 0, arc = line->u.branches; arc; arc = arc->line_next)
2222             ix += output_branch_count (gcov_file, ix, arc);
2223         }
2224     }
2225
2226   /* Handle all remaining source lines.  There may be lines after the
2227      last line of code.  */
2228   if (retval)
2229     {
2230       for (; (retval = fgets (string, STRING_SIZE, source_file)); line_num++)
2231         {
2232           fprintf (gcov_file, "%9s:%5u:%s", "-", line_num, retval);
2233
2234           while (!retval[0] || retval[strlen (retval) - 1] != '\n')
2235             {
2236               retval = fgets (string, STRING_SIZE, source_file);
2237               if (!retval)
2238                 break;
2239               fputs (retval, gcov_file);
2240             }
2241         }
2242     }
2243
2244   if (source_file)
2245     fclose (source_file);
2246 }