2011-12-09 François Dumont <fdumont@gcc.gnu.org>
[official-gcc.git] / gcc / gcov.c
blobd3cb4d095855d75e47e55c2613669b92409e3661
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>
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.
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.
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/>. */
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. */
29 /* ??? Should have an option to print the number of basic blocks, and the
30 percent of them that are covered. */
32 /* Need an option to show individual block counts, and show
33 probabilities of fall through arcs. */
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"
43 #include <getopt.h>
45 #define IN_GCOV 1
46 #include "gcov-io.h"
47 #include "gcov-io.c"
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. */
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. */
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. */
65 /* This is the size of the buffer used to read in source file lines. */
67 #define STRING_SIZE 200
69 struct function_info;
70 struct block_info;
71 struct source_info;
73 /* Describes an arc between two basic blocks. */
75 typedef struct arc_info
77 /* source and destination blocks. */
78 struct block_info *src;
79 struct block_info *dst;
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;
86 unsigned int count_valid : 1;
87 unsigned int on_tree : 1;
88 unsigned int fake : 1;
89 unsigned int fall_through : 1;
91 /* Arc to a catch handler. */
92 unsigned int is_throw : 1;
94 /* Arc is for a function that abnormally returns. */
95 unsigned int is_call_non_return : 1;
97 /* Arc is for catch/setjmp. */
98 unsigned int is_nonlocal_return : 1;
100 /* Is an unconditional branch. */
101 unsigned int is_unconditional : 1;
103 /* Loop making arc. */
104 unsigned int cycle : 1;
106 /* Next branch on line. */
107 struct arc_info *line_next;
109 /* Links to next arc on src and dst lists. */
110 struct arc_info *succ_next;
111 struct arc_info *pred_next;
112 } arc_t;
114 /* Describes a basic block. Contains lists of arcs to successor and
115 predecessor blocks. */
117 typedef struct block_info
119 /* Chain of exit and entry arcs. */
120 arc_t *succ;
121 arc_t *pred;
123 /* Number of unprocessed exit and entry arcs. */
124 gcov_type num_succ;
125 gcov_type num_pred;
127 /* Block execution count. */
128 gcov_type count;
129 unsigned flags : 12;
130 unsigned count_valid : 1;
131 unsigned valid_chain : 1;
132 unsigned invalid_chain : 1;
133 unsigned exceptional : 1;
135 /* Block is a call instrumenting site. */
136 unsigned is_call_site : 1; /* Does the call. */
137 unsigned is_call_return : 1; /* Is the return. */
139 /* Block is a landing pad for longjmp or throw. */
140 unsigned is_nonlocal_return : 1;
142 union
144 struct
146 /* Array of line numbers and source files. source files are
147 introduced by a linenumber of zero, the next 'line number' is
148 the number of the source file. Always starts with a source
149 file. */
150 unsigned *encoding;
151 unsigned num;
152 } line; /* Valid until blocks are linked onto lines */
153 struct
155 /* Single line graph cycle workspace. Used for all-blocks
156 mode. */
157 arc_t *arc;
158 unsigned ident;
159 } cycle; /* Used in all-blocks mode, after blocks are linked onto
160 lines. */
161 } u;
163 /* Temporary chain for solving graph, and for chaining blocks on one
164 line. */
165 struct block_info *chain;
167 } block_t;
169 /* Describes a single function. Contains an array of basic blocks. */
171 typedef struct function_info
173 /* Name of function. */
174 char *name;
175 unsigned ident;
176 unsigned lineno_checksum;
177 unsigned cfg_checksum;
179 /* The graph contains at least one fake incoming edge. */
180 unsigned has_catch : 1;
182 /* Array of basic blocks. */
183 block_t *blocks;
184 unsigned num_blocks;
185 unsigned blocks_executed;
187 /* Raw arc coverage counts. */
188 gcov_type *counts;
189 unsigned num_counts;
191 /* First line number & file. */
192 unsigned line;
193 unsigned src;
195 /* Next function in same source file. */
196 struct function_info *line_next;
198 /* Next function. */
199 struct function_info *next;
200 } function_t;
202 /* Describes coverage of a file or function. */
204 typedef struct coverage_info
206 int lines;
207 int lines_executed;
209 int branches;
210 int branches_executed;
211 int branches_taken;
213 int calls;
214 int calls_executed;
216 char *name;
217 } coverage_t;
219 /* Describes a single line of source. Contains a chain of basic blocks
220 with code on it. */
222 typedef struct line_info
224 gcov_type count; /* execution count */
225 union
227 arc_t *branches; /* branches from blocks that end on this
228 line. Used for branch-counts when not
229 all-blocks mode. */
230 block_t *blocks; /* blocks which start on this line. Used
231 in all-blocks mode. */
232 } u;
233 unsigned exists : 1;
234 unsigned unexceptional : 1;
235 } line_t;
237 /* Describes a file mentioned in the block graph. Contains an array
238 of line info. */
240 typedef struct source_info
242 /* Canonical name of source file. */
243 char *name;
244 time_t file_time;
246 /* Array of line information. */
247 line_t *lines;
248 unsigned num_lines;
250 coverage_t coverage;
252 /* Functions in this source file. These are in ascending line
253 number order. */
254 function_t *functions;
255 } source_t;
257 typedef struct name_map
259 char *name; /* Source file name */
260 unsigned src; /* Source file */
261 } name_map_t;
263 /* Holds a list of function basic block graphs. */
265 static function_t *functions;
266 static function_t **fn_end = &functions;
268 static source_t *sources; /* Array of source files */
269 static unsigned n_sources; /* Number of sources */
270 static unsigned a_sources; /* Allocated sources */
272 static name_map_t *names; /* Mapping of file names to sources */
273 static unsigned n_names; /* Number of names */
274 static unsigned a_names; /* Allocated names */
276 /* This holds data summary information. */
278 static unsigned object_runs;
279 static unsigned program_count;
281 /* Modification time of graph file. */
283 static time_t bbg_file_time;
285 /* Name and file pointer of the input file for the basic block graph. */
287 static char *bbg_file_name;
289 /* Stamp of the bbg file */
290 static unsigned bbg_stamp;
292 /* Name and file pointer of the input file for the arc count data. */
294 static char *da_file_name;
296 /* Data file is missing. */
298 static int no_data_file;
300 /* If there is several input files, compute and display results after
301 reading all data files. This way if two or more gcda file refer to
302 the same source file (eg inline subprograms in a .h file), the
303 counts are added. */
305 static int multiple_files = 0;
307 /* Output branch probabilities. */
309 static int flag_branches = 0;
311 /* Show unconditional branches too. */
312 static int flag_unconditional = 0;
314 /* Output a gcov file if this is true. This is on by default, and can
315 be turned off by the -n option. */
317 static int flag_gcov_file = 1;
319 /* Output progress indication if this is true. This is off by default
320 and can be turned on by the -d option. */
322 static int flag_display_progress = 0;
324 /* For included files, make the gcov output file name include the name
325 of the input source file. For example, if x.h is included in a.c,
326 then the output file name is a.c##x.h.gcov instead of x.h.gcov. */
328 static int flag_long_names = 0;
330 /* Output count information for every basic block, not merely those
331 that contain line number information. */
333 static int flag_all_blocks = 0;
335 /* Output summary info for each function. */
337 static int flag_function_summary = 0;
339 /* Object directory file prefix. This is the directory/file where the
340 graph and data files are looked for, if nonzero. */
342 static char *object_directory = 0;
344 /* Source directory prefix. This is removed from source pathnames
345 that match, when generating the output file name. */
347 static char *source_prefix = 0;
348 static size_t source_length = 0;
350 /* Only show data for sources with relative pathnames. Absolute ones
351 usually indicate a system header file, which although it may
352 contain inline functions, is usually uninteresting. */
353 static int flag_relative_only = 0;
355 /* Preserve all pathname components. Needed when object files and
356 source files are in subdirectories. '/' is mangled as '#', '.' is
357 elided and '..' mangled to '^'. */
359 static int flag_preserve_paths = 0;
361 /* Output the number of times a branch was taken as opposed to the percentage
362 of times it was taken. */
364 static int flag_counts = 0;
366 /* Forward declarations. */
367 static int process_args (int, char **);
368 static void print_usage (int) ATTRIBUTE_NORETURN;
369 static void print_version (void) ATTRIBUTE_NORETURN;
370 static void process_file (const char *);
371 static void generate_results (const char *);
372 static void create_file_names (const char *);
373 static int name_search (const void *, const void *);
374 static int name_sort (const void *, const void *);
375 static char *canonicalize_name (const char *);
376 static unsigned find_source (const char *);
377 static function_t *read_graph_file (void);
378 static int read_count_file (function_t *);
379 static void solve_flow_graph (function_t *);
380 static void find_exception_blocks (function_t *);
381 static void add_branch_counts (coverage_t *, const arc_t *);
382 static void add_line_counts (coverage_t *, function_t *);
383 static void function_summary (const coverage_t *, const char *);
384 static const char *format_gcov (gcov_type, gcov_type, int);
385 static void accumulate_line_counts (source_t *);
386 static int output_branch_count (FILE *, int, const arc_t *);
387 static void output_lines (FILE *, const source_t *);
388 static char *make_gcov_file_name (const char *, const char *);
389 static char *mangle_name (const char *, char *);
390 static void release_structures (void);
391 static void release_function (function_t *);
392 extern int main (int, char **);
395 main (int argc, char **argv)
397 int argno;
398 int first_arg;
399 const char *p;
401 p = argv[0] + strlen (argv[0]);
402 while (p != argv[0] && !IS_DIR_SEPARATOR (p[-1]))
403 --p;
404 progname = p;
406 xmalloc_set_program_name (progname);
408 /* Unlock the stdio streams. */
409 unlock_std_streams ();
411 gcc_init_libintl ();
413 diagnostic_initialize (global_dc, 0);
415 /* Handle response files. */
416 expandargv (&argc, &argv);
418 a_names = 10;
419 names = XNEWVEC (name_map_t, a_names);
420 a_sources = 10;
421 sources = XNEWVEC (source_t, a_sources);
423 argno = process_args (argc, argv);
424 if (optind == argc)
425 print_usage (true);
427 if (argc - argno > 1)
428 multiple_files = 1;
430 first_arg = argno;
432 for (; argno != argc; argno++)
434 if (flag_display_progress)
435 printf("Processing file %d out of %d\n",
436 argno - first_arg + 1, argc - first_arg);
437 process_file (argv[argno]);
440 generate_results (multiple_files ? NULL : argv[argc - 1]);
442 release_structures ();
444 return 0;
447 /* Print a usage message and exit. If ERROR_P is nonzero, this is an error,
448 otherwise the output of --help. */
450 static void
451 print_usage (int error_p)
453 FILE *file = error_p ? stderr : stdout;
454 int status = error_p ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE;
456 fnotice (file, "Usage: gcov [OPTION]... SOURCE|OBJ...\n\n");
457 fnotice (file, "Print code coverage information.\n\n");
458 fnotice (file, " -h, --help Print this help, then exit\n");
459 fnotice (file, " -v, --version Print version number, then exit\n");
460 fnotice (file, " -a, --all-blocks Show information for every basic block\n");
461 fnotice (file, " -b, --branch-probabilities Include branch probabilities in output\n");
462 fnotice (file, " -c, --branch-counts Given counts of branches taken\n\
463 rather than percentages\n");
464 fnotice (file, " -n, --no-output Do not create an output file\n");
465 fnotice (file, " -l, --long-file-names Use long output file names for included\n\
466 source files\n");
467 fnotice (file, " -f, --function-summaries Output summaries for each function\n");
468 fnotice (file, " -o, --object-directory DIR|FILE Search for object files in DIR or called FILE\n");
469 fnotice (file, " -s, --source-prefix DIR Source prefix to elide\n");
470 fnotice (file, " -r, --relative-only Only show data for relative sources\n");
471 fnotice (file, " -p, --preserve-paths Preserve all pathname components\n");
472 fnotice (file, " -u, --unconditional-branches Show unconditional branch counts too\n");
473 fnotice (file, " -d, --display-progress Display progress information\n");
474 fnotice (file, "\nFor bug reporting instructions, please see:\n%s.\n",
475 bug_report_url);
476 exit (status);
479 /* Print version information and exit. */
481 static void
482 print_version (void)
484 fnotice (stdout, "gcov %s%s\n", pkgversion_string, version_string);
485 fprintf (stdout, "Copyright %s 2011 Free Software Foundation, Inc.\n",
486 _("(C)"));
487 fnotice (stdout,
488 _("This is free software; see the source for copying conditions.\n"
489 "There is NO warranty; not even for MERCHANTABILITY or \n"
490 "FITNESS FOR A PARTICULAR PURPOSE.\n\n"));
491 exit (SUCCESS_EXIT_CODE);
494 static const struct option options[] =
496 { "help", no_argument, NULL, 'h' },
497 { "version", no_argument, NULL, 'v' },
498 { "all-blocks", no_argument, NULL, 'a' },
499 { "branch-probabilities", no_argument, NULL, 'b' },
500 { "branch-counts", no_argument, NULL, 'c' },
501 { "no-output", no_argument, NULL, 'n' },
502 { "long-file-names", no_argument, NULL, 'l' },
503 { "function-summaries", no_argument, NULL, 'f' },
504 { "preserve-paths", no_argument, NULL, 'p' },
505 { "relative-only", no_argument, NULL, 'r' },
506 { "object-directory", required_argument, NULL, 'o' },
507 { "object-file", required_argument, NULL, 'o' },
508 { "source-prefix", required_argument, NULL, 's' },
509 { "unconditional-branches", no_argument, NULL, 'u' },
510 { "display-progress", no_argument, NULL, 'd' },
511 { 0, 0, 0, 0 }
514 /* Process args, return index to first non-arg. */
516 static int
517 process_args (int argc, char **argv)
519 int opt;
521 while ((opt = getopt_long (argc, argv, "abcdfhlno:s:pruv", options, NULL)) != -1)
523 switch (opt)
525 case 'a':
526 flag_all_blocks = 1;
527 break;
528 case 'b':
529 flag_branches = 1;
530 break;
531 case 'c':
532 flag_counts = 1;
533 break;
534 case 'f':
535 flag_function_summary = 1;
536 break;
537 case 'h':
538 print_usage (false);
539 /* print_usage will exit. */
540 case 'l':
541 flag_long_names = 1;
542 break;
543 case 'n':
544 flag_gcov_file = 0;
545 break;
546 case 'o':
547 object_directory = optarg;
548 break;
549 case 's':
550 source_prefix = optarg;
551 source_length = strlen (source_prefix);
552 break;
553 case 'r':
554 flag_relative_only = 1;
555 break;
556 case 'p':
557 flag_preserve_paths = 1;
558 break;
559 case 'u':
560 flag_unconditional = 1;
561 break;
562 case 'd':
563 flag_display_progress = 1;
564 break;
565 case 'v':
566 print_version ();
567 /* print_version will exit. */
568 default:
569 print_usage (true);
570 /* print_usage will exit. */
574 return optind;
577 /* Process a single input file. */
579 static void
580 process_file (const char *file_name)
582 function_t *fns;
584 create_file_names (file_name);
585 fns = read_graph_file ();
586 if (!fns)
587 return;
589 read_count_file (fns);
590 while (fns)
592 function_t *fn = fns;
594 fns = fn->next;
595 fn->next = NULL;
596 if (fn->counts)
598 unsigned src = fn->src;
599 unsigned line = fn->line;
600 unsigned block_no;
601 function_t *probe, **prev;
603 /* Now insert it into the source file's list of
604 functions. Normally functions will be encountered in
605 ascending order, so a simple scan is quick. Note we're
606 building this list in reverse order. */
607 for (prev = &sources[src].functions;
608 (probe = *prev); prev = &probe->line_next)
609 if (probe->line <= line)
610 break;
611 fn->line_next = probe;
612 *prev = fn;
614 /* Mark last line in files touched by function. */
615 for (block_no = 0; block_no != fn->num_blocks; block_no++)
617 unsigned *enc = fn->blocks[block_no].u.line.encoding;
618 unsigned num = fn->blocks[block_no].u.line.num;
620 for (; num--; enc++)
621 if (!*enc)
623 if (enc[1] != src)
625 if (line >= sources[src].num_lines)
626 sources[src].num_lines = line + 1;
627 line = 0;
628 src = enc[1];
630 enc++;
631 num--;
633 else if (*enc > line)
634 line = *enc;
636 if (line >= sources[src].num_lines)
637 sources[src].num_lines = line + 1;
639 solve_flow_graph (fn);
640 if (fn->has_catch)
641 find_exception_blocks (fn);
642 *fn_end = fn;
643 fn_end = &fn->next;
645 else
646 /* The function was not in the executable -- some other
647 instance must have been selected. */
648 release_function (fn);
652 static void
653 generate_results (const char *file_name)
655 unsigned ix;
656 source_t *src;
657 function_t *fn;
659 for (ix = n_sources, src = sources; ix--; src++)
660 if (src->num_lines)
661 src->lines = XCNEWVEC (line_t, src->num_lines);
663 for (fn = functions; fn; fn = fn->next)
665 coverage_t coverage;
667 memset (&coverage, 0, sizeof (coverage));
668 coverage.name = fn->name;
669 add_line_counts (flag_function_summary ? &coverage : NULL, fn);
670 if (flag_function_summary)
672 function_summary (&coverage, "Function");
673 fnotice (stdout, "\n");
677 if (file_name)
679 name_map_t *name_map = (name_map_t *)bsearch
680 (file_name, names, n_names, sizeof (*names), name_search);
681 if (name_map)
682 file_name = sources[name_map->src].coverage.name;
683 else
684 file_name = canonicalize_name (file_name);
687 for (ix = n_sources, src = sources; ix--; src++)
689 if (flag_relative_only)
691 /* Ignore this source, if it is an absolute path (after
692 source prefix removal). */
693 char first = src->coverage.name[0];
695 #if HAVE_DOS_BASED_FILE_SYSTEM
696 if (first && src->coverage.name[1] == ':')
697 first = src->coverage.name[2];
698 #endif
699 if (IS_DIR_SEPARATOR (first))
700 continue;
703 accumulate_line_counts (src);
704 function_summary (&src->coverage, "File");
705 if (flag_gcov_file && src->coverage.lines)
707 char *gcov_file_name
708 = make_gcov_file_name (file_name, src->coverage.name);
709 FILE *gcov_file = fopen (gcov_file_name, "w");
711 if (gcov_file)
713 fnotice (stdout, "Creating '%s'\n", gcov_file_name);
714 output_lines (gcov_file, src);
715 if (ferror (gcov_file))
716 fnotice (stderr, "Error writing output file '%s'\n",
717 gcov_file_name);
718 fclose (gcov_file);
720 else
721 fnotice (stderr, "Could not open output file '%s'\n",
722 gcov_file_name);
723 free (gcov_file_name);
725 fnotice (stdout, "\n");
729 /* Release a function structure */
731 static void
732 release_function (function_t *fn)
734 unsigned ix;
735 block_t *block;
737 for (ix = fn->num_blocks, block = fn->blocks; ix--; block++)
739 arc_t *arc, *arc_n;
741 for (arc = block->succ; arc; arc = arc_n)
743 arc_n = arc->succ_next;
744 free (arc);
747 free (fn->blocks);
748 free (fn->counts);
751 /* Release all memory used. */
753 static void
754 release_structures (void)
756 unsigned ix;
757 function_t *fn;
759 for (ix = n_sources; ix--;)
760 free (sources[ix].lines);
761 free (sources);
763 for (ix = n_names; ix--;)
764 free (names[ix].name);
765 free (names);
767 while ((fn = functions))
769 functions = fn->next;
770 release_function (fn);
774 /* Generate the names of the graph and data files. If OBJECT_DIRECTORY
775 is not specified, these are named from FILE_NAME sans extension. If
776 OBJECT_DIRECTORY is specified and is a directory, the files are in that
777 directory, but named from the basename of the FILE_NAME, sans extension.
778 Otherwise OBJECT_DIRECTORY is taken to be the name of the object *file*
779 and the data files are named from that. */
781 static void
782 create_file_names (const char *file_name)
784 char *cptr;
785 char *name;
786 int length = strlen (file_name);
787 int base;
789 /* Free previous file names. */
790 free (bbg_file_name);
791 free (da_file_name);
792 da_file_name = bbg_file_name = NULL;
793 bbg_file_time = 0;
794 bbg_stamp = 0;
796 if (object_directory && object_directory[0])
798 struct stat status;
800 length += strlen (object_directory) + 2;
801 name = XNEWVEC (char, length);
802 name[0] = 0;
804 base = !stat (object_directory, &status) && S_ISDIR (status.st_mode);
805 strcat (name, object_directory);
806 if (base && (! IS_DIR_SEPARATOR (name[strlen (name) - 1])))
807 strcat (name, "/");
809 else
811 name = XNEWVEC (char, length + 1);
812 strcpy (name, file_name);
813 base = 0;
816 if (base)
818 /* Append source file name. */
819 const char *cptr = lbasename (file_name);
820 strcat (name, cptr ? cptr : file_name);
823 /* Remove the extension. */
824 cptr = strrchr (name, '.');
825 if (cptr)
826 *cptr = 0;
828 length = strlen (name);
830 bbg_file_name = XNEWVEC (char, length + strlen (GCOV_NOTE_SUFFIX) + 1);
831 strcpy (bbg_file_name, name);
832 strcpy (bbg_file_name + length, GCOV_NOTE_SUFFIX);
834 da_file_name = XNEWVEC (char, length + strlen (GCOV_DATA_SUFFIX) + 1);
835 strcpy (da_file_name, name);
836 strcpy (da_file_name + length, GCOV_DATA_SUFFIX);
838 free (name);
839 return;
842 /* A is a string and B is a pointer to name_map_t. Compare for file
843 name orderability. */
845 static int
846 name_search (const void *a_, const void *b_)
848 const char *a = (const char *)a_;
849 const name_map_t *b = (const name_map_t *)b_;
851 #if HAVE_DOS_BASED_FILE_SYSTEM
852 return strcasecmp (a, b->name);
853 #else
854 return strcmp (a, b->name);
855 #endif
858 /* A and B are a pointer to name_map_t. Compare for file name
859 orderability. */
861 static int
862 name_sort (const void *a_, const void *b_)
864 const name_map_t *a = (const name_map_t *)a_;
865 return name_search (a->name, b_);
868 /* Find or create a source file structure for FILE_NAME. Copies
869 FILE_NAME on creation */
871 static unsigned
872 find_source (const char *file_name)
874 name_map_t *name_map;
875 char *canon;
876 unsigned idx;
877 struct stat status;
879 if (!file_name)
880 file_name = "<unknown>";
881 name_map = (name_map_t *)bsearch
882 (file_name, names, n_names, sizeof (*names), name_search);
883 if (name_map)
885 idx = name_map->src;
886 goto check_date;
889 if (n_names + 2 > a_names)
891 /* Extend the name map array -- we'll be inserting one or two
892 entries. */
893 a_names *= 2;
894 name_map = XNEWVEC (name_map_t, a_names);
895 memcpy (name_map, names, n_names * sizeof (*names));
896 free (names);
897 names = name_map;
900 /* Not found, try the canonical name. */
901 canon = canonicalize_name (file_name);
902 name_map = (name_map_t *)bsearch
903 (canon, names, n_names, sizeof (*names), name_search);
904 if (!name_map)
906 /* Not found with canonical name, create a new source. */
907 source_t *src;
909 if (n_sources == a_sources)
911 a_sources *= 2;
912 src = XNEWVEC (source_t, a_sources);
913 memcpy (src, sources, n_sources * sizeof (*sources));
914 free (sources);
915 sources = src;
918 idx = n_sources;
920 name_map = &names[n_names++];
921 name_map->name = canon;
922 name_map->src = idx;
924 src = &sources[n_sources++];
925 memset (src, 0, sizeof (*src));
926 src->name = canon;
927 src->coverage.name = src->name;
928 if (source_length
929 #if HAVE_DOS_BASED_FILE_SYSTEM
930 /* You lose if separators don't match exactly in the
931 prefix. */
932 && !strncasecmp (source_prefix, src->coverage.name, source_length)
933 #else
934 && !strncmp (source_prefix, src->coverage.name, source_length)
935 #endif
936 && IS_DIR_SEPARATOR (src->coverage.name[source_length]))
937 src->coverage.name += source_length + 1;
938 if (!stat (src->name, &status))
939 src->file_time = status.st_mtime;
941 else
942 idx = name_map->src;
944 if (name_search (file_name, name_map))
946 /* Append the non-canonical name. */
947 name_map = &names[n_names++];
948 name_map->name = xstrdup (file_name);
949 name_map->src = idx;
952 /* Resort the name map. */
953 qsort (names, n_names, sizeof (*names), name_sort);
955 check_date:
956 if (sources[idx].file_time > bbg_file_time)
958 static int info_emitted;
960 fnotice (stderr, "%s:source file is newer than graph file '%s'\n",
961 file_name, bbg_file_name);
962 if (!info_emitted)
964 fnotice (stderr,
965 "(the message is only displayed one per source file)\n");
966 info_emitted = 1;
968 sources[idx].file_time = 0;
971 return idx;
974 /* Read the graph file. Return list of functions read -- in reverse order. */
976 static function_t *
977 read_graph_file (void)
979 unsigned version;
980 unsigned current_tag = 0;
981 function_t *fn = NULL;
982 function_t *fns = NULL;
983 function_t **fns_end = &fns;
984 unsigned src_idx = 0;
985 unsigned ix;
986 unsigned tag;
988 if (!gcov_open (bbg_file_name, 1))
990 fnotice (stderr, "%s:cannot open graph file\n", bbg_file_name);
991 return fns;
993 bbg_file_time = gcov_time ();
994 if (!gcov_magic (gcov_read_unsigned (), GCOV_NOTE_MAGIC))
996 fnotice (stderr, "%s:not a gcov graph file\n", bbg_file_name);
997 gcov_close ();
998 return fns;
1001 version = gcov_read_unsigned ();
1002 if (version != GCOV_VERSION)
1004 char v[4], e[4];
1006 GCOV_UNSIGNED2STRING (v, version);
1007 GCOV_UNSIGNED2STRING (e, GCOV_VERSION);
1009 fnotice (stderr, "%s:version '%.4s', prefer '%.4s'\n",
1010 bbg_file_name, v, e);
1012 bbg_stamp = gcov_read_unsigned ();
1014 while ((tag = gcov_read_unsigned ()))
1016 unsigned length = gcov_read_unsigned ();
1017 gcov_position_t base = gcov_position ();
1019 if (tag == GCOV_TAG_FUNCTION)
1021 char *function_name;
1022 unsigned ident, lineno;
1023 unsigned lineno_checksum, cfg_checksum;
1025 ident = gcov_read_unsigned ();
1026 lineno_checksum = gcov_read_unsigned ();
1027 cfg_checksum = gcov_read_unsigned ();
1028 function_name = xstrdup (gcov_read_string ());
1029 src_idx = find_source (gcov_read_string ());
1030 lineno = gcov_read_unsigned ();
1032 fn = XCNEW (function_t);
1033 fn->name = function_name;
1034 fn->ident = ident;
1035 fn->lineno_checksum = lineno_checksum;
1036 fn->cfg_checksum = cfg_checksum;
1037 fn->src = src_idx;
1038 fn->line = lineno;
1040 fn->line_next = NULL;
1041 fn->next = NULL;
1042 *fns_end = fn;
1043 fns_end = &fn->next;
1044 current_tag = tag;
1046 else if (fn && tag == GCOV_TAG_BLOCKS)
1048 if (fn->blocks)
1049 fnotice (stderr, "%s:already seen blocks for '%s'\n",
1050 bbg_file_name, fn->name);
1051 else
1053 unsigned ix, num_blocks = GCOV_TAG_BLOCKS_NUM (length);
1054 fn->num_blocks = num_blocks;
1056 fn->blocks = XCNEWVEC (block_t, fn->num_blocks);
1057 for (ix = 0; ix != num_blocks; ix++)
1058 fn->blocks[ix].flags = gcov_read_unsigned ();
1061 else if (fn && tag == GCOV_TAG_ARCS)
1063 unsigned src = gcov_read_unsigned ();
1064 unsigned num_dests = GCOV_TAG_ARCS_NUM (length);
1065 block_t *src_blk = &fn->blocks[src];
1066 unsigned mark_catches = 0;
1067 struct arc_info *arc;
1069 if (src >= fn->num_blocks || fn->blocks[src].succ)
1070 goto corrupt;
1072 while (num_dests--)
1074 unsigned dest = gcov_read_unsigned ();
1075 unsigned flags = gcov_read_unsigned ();
1077 if (dest >= fn->num_blocks)
1078 goto corrupt;
1079 arc = XCNEW (arc_t);
1081 arc->dst = &fn->blocks[dest];
1082 arc->src = src_blk;
1084 arc->count = 0;
1085 arc->count_valid = 0;
1086 arc->on_tree = !!(flags & GCOV_ARC_ON_TREE);
1087 arc->fake = !!(flags & GCOV_ARC_FAKE);
1088 arc->fall_through = !!(flags & GCOV_ARC_FALLTHROUGH);
1090 arc->succ_next = src_blk->succ;
1091 src_blk->succ = arc;
1092 src_blk->num_succ++;
1094 arc->pred_next = fn->blocks[dest].pred;
1095 fn->blocks[dest].pred = arc;
1096 fn->blocks[dest].num_pred++;
1098 if (arc->fake)
1100 if (src)
1102 /* Exceptional exit from this function, the
1103 source block must be a call. */
1104 fn->blocks[src].is_call_site = 1;
1105 arc->is_call_non_return = 1;
1106 mark_catches = 1;
1108 else
1110 /* Non-local return from a callee of this
1111 function. The destination block is a setjmp. */
1112 arc->is_nonlocal_return = 1;
1113 fn->blocks[dest].is_nonlocal_return = 1;
1117 if (!arc->on_tree)
1118 fn->num_counts++;
1121 if (mark_catches)
1123 /* We have a fake exit from this block. The other
1124 non-fall through exits must be to catch handlers.
1125 Mark them as catch arcs. */
1127 for (arc = src_blk->succ; arc; arc = arc->succ_next)
1128 if (!arc->fake && !arc->fall_through)
1130 arc->is_throw = 1;
1131 fn->has_catch = 1;
1135 else if (fn && tag == GCOV_TAG_LINES)
1137 unsigned blockno = gcov_read_unsigned ();
1138 unsigned *line_nos = XCNEWVEC (unsigned, length - 1);
1140 if (blockno >= fn->num_blocks || fn->blocks[blockno].u.line.encoding)
1141 goto corrupt;
1143 for (ix = 0; ; )
1145 unsigned lineno = gcov_read_unsigned ();
1147 if (lineno)
1149 if (!ix)
1151 line_nos[ix++] = 0;
1152 line_nos[ix++] = src_idx;
1154 line_nos[ix++] = lineno;
1156 else
1158 const char *file_name = gcov_read_string ();
1160 if (!file_name)
1161 break;
1162 src_idx = find_source (file_name);
1163 line_nos[ix++] = 0;
1164 line_nos[ix++] = src_idx;
1168 fn->blocks[blockno].u.line.encoding = line_nos;
1169 fn->blocks[blockno].u.line.num = ix;
1171 else if (current_tag && !GCOV_TAG_IS_SUBTAG (current_tag, tag))
1173 fn = NULL;
1174 current_tag = 0;
1176 gcov_sync (base, length);
1177 if (gcov_is_error ())
1179 corrupt:;
1180 fnotice (stderr, "%s:corrupted\n", bbg_file_name);
1181 break;
1184 gcov_close ();
1186 if (!fns)
1187 fnotice (stderr, "%s:no functions found\n", bbg_file_name);
1189 return fns;
1192 /* Reads profiles from the count file and attach to each
1193 function. Return nonzero if fatal error. */
1195 static int
1196 read_count_file (function_t *fns)
1198 unsigned ix;
1199 unsigned version;
1200 unsigned tag;
1201 function_t *fn = NULL;
1202 int error = 0;
1204 if (!gcov_open (da_file_name, 1))
1206 fnotice (stderr, "%s:cannot open data file, assuming not executed\n",
1207 da_file_name);
1208 no_data_file = 1;
1209 return 0;
1211 if (!gcov_magic (gcov_read_unsigned (), GCOV_DATA_MAGIC))
1213 fnotice (stderr, "%s:not a gcov data file\n", da_file_name);
1214 cleanup:;
1215 gcov_close ();
1216 return 1;
1218 version = gcov_read_unsigned ();
1219 if (version != GCOV_VERSION)
1221 char v[4], e[4];
1223 GCOV_UNSIGNED2STRING (v, version);
1224 GCOV_UNSIGNED2STRING (e, GCOV_VERSION);
1226 fnotice (stderr, "%s:version '%.4s', prefer version '%.4s'\n",
1227 da_file_name, v, e);
1229 tag = gcov_read_unsigned ();
1230 if (tag != bbg_stamp)
1232 fnotice (stderr, "%s:stamp mismatch with graph file\n", da_file_name);
1233 goto cleanup;
1236 while ((tag = gcov_read_unsigned ()))
1238 unsigned length = gcov_read_unsigned ();
1239 unsigned long base = gcov_position ();
1241 if (tag == GCOV_TAG_PROGRAM_SUMMARY)
1243 struct gcov_summary summary;
1244 gcov_read_summary (&summary);
1245 object_runs += summary.ctrs[GCOV_COUNTER_ARCS].runs;
1246 program_count++;
1248 else if (tag == GCOV_TAG_FUNCTION && !length)
1249 ; /* placeholder */
1250 else if (tag == GCOV_TAG_FUNCTION && length == GCOV_TAG_FUNCTION_LENGTH)
1252 unsigned ident;
1253 struct function_info *fn_n;
1255 /* Try to find the function in the list. To speed up the
1256 search, first start from the last function found. */
1257 ident = gcov_read_unsigned ();
1258 fn_n = fns;
1259 for (fn = fn ? fn->next : NULL; ; fn = fn->next)
1261 if (fn)
1263 else if ((fn = fn_n))
1264 fn_n = NULL;
1265 else
1267 fnotice (stderr, "%s:unknown function '%u'\n",
1268 da_file_name, ident);
1269 break;
1271 if (fn->ident == ident)
1272 break;
1275 if (!fn)
1277 else if (gcov_read_unsigned () != fn->lineno_checksum
1278 || gcov_read_unsigned () != fn->cfg_checksum)
1280 mismatch:;
1281 fnotice (stderr, "%s:profile mismatch for '%s'\n",
1282 da_file_name, fn->name);
1283 goto cleanup;
1286 else if (tag == GCOV_TAG_FOR_COUNTER (GCOV_COUNTER_ARCS) && fn)
1288 if (length != GCOV_TAG_COUNTER_LENGTH (fn->num_counts))
1289 goto mismatch;
1291 if (!fn->counts)
1292 fn->counts = XCNEWVEC (gcov_type, fn->num_counts);
1294 for (ix = 0; ix != fn->num_counts; ix++)
1295 fn->counts[ix] += gcov_read_counter ();
1297 gcov_sync (base, length);
1298 if ((error = gcov_is_error ()))
1300 fnotice (stderr, error < 0 ? "%s:overflowed\n" : "%s:corrupted\n",
1301 da_file_name);
1302 goto cleanup;
1306 gcov_close ();
1307 return 0;
1310 /* Solve the flow graph. Propagate counts from the instrumented arcs
1311 to the blocks and the uninstrumented arcs. */
1313 static void
1314 solve_flow_graph (function_t *fn)
1316 unsigned ix;
1317 arc_t *arc;
1318 gcov_type *count_ptr = fn->counts;
1319 block_t *blk;
1320 block_t *valid_blocks = NULL; /* valid, but unpropagated blocks. */
1321 block_t *invalid_blocks = NULL; /* invalid, but inferable blocks. */
1323 /* The arcs were built in reverse order. Fix that now. */
1324 for (ix = fn->num_blocks; ix--;)
1326 arc_t *arc_p, *arc_n;
1328 for (arc_p = NULL, arc = fn->blocks[ix].succ; arc;
1329 arc_p = arc, arc = arc_n)
1331 arc_n = arc->succ_next;
1332 arc->succ_next = arc_p;
1334 fn->blocks[ix].succ = arc_p;
1336 for (arc_p = NULL, arc = fn->blocks[ix].pred; arc;
1337 arc_p = arc, arc = arc_n)
1339 arc_n = arc->pred_next;
1340 arc->pred_next = arc_p;
1342 fn->blocks[ix].pred = arc_p;
1345 if (fn->num_blocks < 2)
1346 fnotice (stderr, "%s:'%s' lacks entry and/or exit blocks\n",
1347 bbg_file_name, fn->name);
1348 else
1350 if (fn->blocks[0].num_pred)
1351 fnotice (stderr, "%s:'%s' has arcs to entry block\n",
1352 bbg_file_name, fn->name);
1353 else
1354 /* We can't deduce the entry block counts from the lack of
1355 predecessors. */
1356 fn->blocks[0].num_pred = ~(unsigned)0;
1358 if (fn->blocks[fn->num_blocks - 1].num_succ)
1359 fnotice (stderr, "%s:'%s' has arcs from exit block\n",
1360 bbg_file_name, fn->name);
1361 else
1362 /* Likewise, we can't deduce exit block counts from the lack
1363 of its successors. */
1364 fn->blocks[fn->num_blocks - 1].num_succ = ~(unsigned)0;
1367 /* Propagate the measured counts, this must be done in the same
1368 order as the code in profile.c */
1369 for (ix = 0, blk = fn->blocks; ix != fn->num_blocks; ix++, blk++)
1371 block_t const *prev_dst = NULL;
1372 int out_of_order = 0;
1373 int non_fake_succ = 0;
1375 for (arc = blk->succ; arc; arc = arc->succ_next)
1377 if (!arc->fake)
1378 non_fake_succ++;
1380 if (!arc->on_tree)
1382 if (count_ptr)
1383 arc->count = *count_ptr++;
1384 arc->count_valid = 1;
1385 blk->num_succ--;
1386 arc->dst->num_pred--;
1388 if (prev_dst && prev_dst > arc->dst)
1389 out_of_order = 1;
1390 prev_dst = arc->dst;
1392 if (non_fake_succ == 1)
1394 /* If there is only one non-fake exit, it is an
1395 unconditional branch. */
1396 for (arc = blk->succ; arc; arc = arc->succ_next)
1397 if (!arc->fake)
1399 arc->is_unconditional = 1;
1400 /* If this block is instrumenting a call, it might be
1401 an artificial block. It is not artificial if it has
1402 a non-fallthrough exit, or the destination of this
1403 arc has more than one entry. Mark the destination
1404 block as a return site, if none of those conditions
1405 hold. */
1406 if (blk->is_call_site && arc->fall_through
1407 && arc->dst->pred == arc && !arc->pred_next)
1408 arc->dst->is_call_return = 1;
1412 /* Sort the successor arcs into ascending dst order. profile.c
1413 normally produces arcs in the right order, but sometimes with
1414 one or two out of order. We're not using a particularly
1415 smart sort. */
1416 if (out_of_order)
1418 arc_t *start = blk->succ;
1419 unsigned changes = 1;
1421 while (changes)
1423 arc_t *arc, *arc_p, *arc_n;
1425 changes = 0;
1426 for (arc_p = NULL, arc = start; (arc_n = arc->succ_next);)
1428 if (arc->dst > arc_n->dst)
1430 changes = 1;
1431 if (arc_p)
1432 arc_p->succ_next = arc_n;
1433 else
1434 start = arc_n;
1435 arc->succ_next = arc_n->succ_next;
1436 arc_n->succ_next = arc;
1437 arc_p = arc_n;
1439 else
1441 arc_p = arc;
1442 arc = arc_n;
1446 blk->succ = start;
1449 /* Place it on the invalid chain, it will be ignored if that's
1450 wrong. */
1451 blk->invalid_chain = 1;
1452 blk->chain = invalid_blocks;
1453 invalid_blocks = blk;
1456 while (invalid_blocks || valid_blocks)
1458 while ((blk = invalid_blocks))
1460 gcov_type total = 0;
1461 const arc_t *arc;
1463 invalid_blocks = blk->chain;
1464 blk->invalid_chain = 0;
1465 if (!blk->num_succ)
1466 for (arc = blk->succ; arc; arc = arc->succ_next)
1467 total += arc->count;
1468 else if (!blk->num_pred)
1469 for (arc = blk->pred; arc; arc = arc->pred_next)
1470 total += arc->count;
1471 else
1472 continue;
1474 blk->count = total;
1475 blk->count_valid = 1;
1476 blk->chain = valid_blocks;
1477 blk->valid_chain = 1;
1478 valid_blocks = blk;
1480 while ((blk = valid_blocks))
1482 gcov_type total;
1483 arc_t *arc, *inv_arc;
1485 valid_blocks = blk->chain;
1486 blk->valid_chain = 0;
1487 if (blk->num_succ == 1)
1489 block_t *dst;
1491 total = blk->count;
1492 inv_arc = NULL;
1493 for (arc = blk->succ; arc; arc = arc->succ_next)
1495 total -= arc->count;
1496 if (!arc->count_valid)
1497 inv_arc = arc;
1499 dst = inv_arc->dst;
1500 inv_arc->count_valid = 1;
1501 inv_arc->count = total;
1502 blk->num_succ--;
1503 dst->num_pred--;
1504 if (dst->count_valid)
1506 if (dst->num_pred == 1 && !dst->valid_chain)
1508 dst->chain = valid_blocks;
1509 dst->valid_chain = 1;
1510 valid_blocks = dst;
1513 else
1515 if (!dst->num_pred && !dst->invalid_chain)
1517 dst->chain = invalid_blocks;
1518 dst->invalid_chain = 1;
1519 invalid_blocks = dst;
1523 if (blk->num_pred == 1)
1525 block_t *src;
1527 total = blk->count;
1528 inv_arc = NULL;
1529 for (arc = blk->pred; arc; arc = arc->pred_next)
1531 total -= arc->count;
1532 if (!arc->count_valid)
1533 inv_arc = arc;
1535 src = inv_arc->src;
1536 inv_arc->count_valid = 1;
1537 inv_arc->count = total;
1538 blk->num_pred--;
1539 src->num_succ--;
1540 if (src->count_valid)
1542 if (src->num_succ == 1 && !src->valid_chain)
1544 src->chain = valid_blocks;
1545 src->valid_chain = 1;
1546 valid_blocks = src;
1549 else
1551 if (!src->num_succ && !src->invalid_chain)
1553 src->chain = invalid_blocks;
1554 src->invalid_chain = 1;
1555 invalid_blocks = src;
1562 /* If the graph has been correctly solved, every block will have a
1563 valid count. */
1564 for (ix = 0; ix < fn->num_blocks; ix++)
1565 if (!fn->blocks[ix].count_valid)
1567 fnotice (stderr, "%s:graph is unsolvable for '%s'\n",
1568 bbg_file_name, fn->name);
1569 break;
1573 /* Mark all the blocks only reachable via an incoming catch. */
1575 static void
1576 find_exception_blocks (function_t *fn)
1578 unsigned ix;
1579 block_t **queue = XALLOCAVEC (block_t *, fn->num_blocks);
1581 /* First mark all blocks as exceptional. */
1582 for (ix = fn->num_blocks; ix--;)
1583 fn->blocks[ix].exceptional = 1;
1585 /* Now mark all the blocks reachable via non-fake edges */
1586 queue[0] = fn->blocks;
1587 queue[0]->exceptional = 0;
1588 for (ix = 1; ix;)
1590 block_t *block = queue[--ix];
1591 const arc_t *arc;
1593 for (arc = block->succ; arc; arc = arc->succ_next)
1594 if (!arc->fake && !arc->is_throw && arc->dst->exceptional)
1596 arc->dst->exceptional = 0;
1597 queue[ix++] = arc->dst;
1603 /* Increment totals in COVERAGE according to arc ARC. */
1605 static void
1606 add_branch_counts (coverage_t *coverage, const arc_t *arc)
1608 if (arc->is_call_non_return)
1610 coverage->calls++;
1611 if (arc->src->count)
1612 coverage->calls_executed++;
1614 else if (!arc->is_unconditional)
1616 coverage->branches++;
1617 if (arc->src->count)
1618 coverage->branches_executed++;
1619 if (arc->count)
1620 coverage->branches_taken++;
1624 /* Format a HOST_WIDE_INT as either a percent ratio, or absolute
1625 count. If dp >= 0, format TOP/BOTTOM * 100 to DP decimal places.
1626 If DP is zero, no decimal point is printed. Only print 100% when
1627 TOP==BOTTOM and only print 0% when TOP=0. If dp < 0, then simply
1628 format TOP. Return pointer to a static string. */
1630 static char const *
1631 format_gcov (gcov_type top, gcov_type bottom, int dp)
1633 static char buffer[20];
1635 if (dp >= 0)
1637 float ratio = bottom ? (float)top / bottom : 0;
1638 int ix;
1639 unsigned limit = 100;
1640 unsigned percent;
1642 for (ix = dp; ix--; )
1643 limit *= 10;
1645 percent = (unsigned) (ratio * limit + (float)0.5);
1646 if (percent <= 0 && top)
1647 percent = 1;
1648 else if (percent >= limit && top != bottom)
1649 percent = limit - 1;
1650 ix = sprintf (buffer, "%.*u%%", dp + 1, percent);
1651 if (dp)
1653 dp++;
1656 buffer[ix+1] = buffer[ix];
1657 ix--;
1659 while (dp--);
1660 buffer[ix + 1] = '.';
1663 else
1664 sprintf (buffer, HOST_WIDEST_INT_PRINT_DEC, (HOST_WIDEST_INT)top);
1666 return buffer;
1670 /* Output summary info for a function. */
1672 static void
1673 function_summary (const coverage_t *coverage, const char *title)
1675 fnotice (stdout, "%s '%s'\n", title, coverage->name);
1677 if (coverage->lines)
1678 fnotice (stdout, "Lines executed:%s of %d\n",
1679 format_gcov (coverage->lines_executed, coverage->lines, 2),
1680 coverage->lines);
1681 else
1682 fnotice (stdout, "No executable lines\n");
1684 if (flag_branches)
1686 if (coverage->branches)
1688 fnotice (stdout, "Branches executed:%s of %d\n",
1689 format_gcov (coverage->branches_executed,
1690 coverage->branches, 2),
1691 coverage->branches);
1692 fnotice (stdout, "Taken at least once:%s of %d\n",
1693 format_gcov (coverage->branches_taken,
1694 coverage->branches, 2),
1695 coverage->branches);
1697 else
1698 fnotice (stdout, "No branches\n");
1699 if (coverage->calls)
1700 fnotice (stdout, "Calls executed:%s of %d\n",
1701 format_gcov (coverage->calls_executed, coverage->calls, 2),
1702 coverage->calls);
1703 else
1704 fnotice (stdout, "No calls\n");
1708 /* Canonicalize the filename NAME by canonicalizing directory
1709 separators, eliding . components and resolving .. components
1710 appropriately. Always returns a unique string. */
1712 static char *
1713 canonicalize_name (const char *name)
1715 /* The canonical name cannot be longer than the incoming name. */
1716 char *result = XNEWVEC (char, strlen (name) + 1);
1717 const char *base = name, *probe;
1718 char *ptr = result;
1719 char *dd_base;
1720 int slash = 0;
1722 #if HAVE_DOS_BASED_FILE_SYSTEM
1723 if (base[0] && base[1] == ':')
1725 result[0] = base[0];
1726 result[1] = ':';
1727 base += 2;
1728 ptr += 2;
1730 #endif
1731 for (dd_base = ptr; *base; base = probe)
1733 size_t len;
1735 for (probe = base; *probe; probe++)
1736 if (IS_DIR_SEPARATOR (*probe))
1737 break;
1739 len = probe - base;
1740 if (len == 1 && base[0] == '.')
1741 /* Elide a '.' directory */
1743 else if (len == 2 && base[0] == '.' && base[1] == '.')
1745 /* '..', we can only elide it and the previous directory, if
1746 we're not a symlink. */
1747 struct stat ATTRIBUTE_UNUSED buf;
1749 *ptr = 0;
1750 if (dd_base == ptr
1751 #if defined (S_ISLNK)
1752 /* S_ISLNK is not POSIX.1-1996. */
1753 || stat (result, &buf) || S_ISLNK (buf.st_mode)
1754 #endif
1757 /* Cannot elide, or unreadable or a symlink. */
1758 dd_base = ptr + 2 + slash;
1759 goto regular;
1761 while (ptr != dd_base && *ptr != '/')
1762 ptr--;
1763 slash = ptr != result;
1765 else
1767 regular:
1768 /* Regular pathname component. */
1769 if (slash)
1770 *ptr++ = '/';
1771 memcpy (ptr, base, len);
1772 ptr += len;
1773 slash = 1;
1776 for (; IS_DIR_SEPARATOR (*probe); probe++)
1777 continue;
1779 *ptr = 0;
1781 return result;
1784 /* Generate an output file name. INPUT_NAME is the canonicalized main
1785 input file and SRC_NAME is the canonicalized file name.
1786 LONG_OUTPUT_NAMES and PRESERVE_PATHS affect name generation. With
1787 long_output_names we prepend the processed name of the input file
1788 to each output name (except when the current source file is the
1789 input file, so you don't get a double concatenation). The two
1790 components are separated by '##'. With preserve_paths we create a
1791 filename from all path components of the source file, replacing '/'
1792 with '#', and .. with '^', without it we simply take the basename
1793 component. (Remember, the canonicalized name will already have
1794 elided '.' components and converted \\ separators.) */
1796 static char *
1797 make_gcov_file_name (const char *input_name, const char *src_name)
1799 char *ptr;
1800 char *result;
1802 if (flag_long_names && input_name && strcmp (src_name, input_name))
1804 /* Generate the input filename part. */
1805 result = XNEWVEC (char, strlen (input_name) + strlen (src_name) + 10);
1807 ptr = result;
1808 ptr = mangle_name (input_name, ptr);
1809 ptr[0] = ptr[1] = '#';
1810 ptr += 2;
1812 else
1814 result = XNEWVEC (char, strlen (src_name) + 10);
1815 ptr = result;
1818 ptr = mangle_name (src_name, ptr);
1819 strcpy (ptr, ".gcov");
1821 return result;
1824 static char *
1825 mangle_name (char const *base, char *ptr)
1827 size_t len;
1829 /* Generate the source filename part. */
1830 if (!flag_preserve_paths)
1832 base = lbasename (base);
1833 len = strlen (base);
1834 memcpy (ptr, base, len);
1835 ptr += len;
1837 else
1839 /* Convert '/' to '#', convert '..' to '^',
1840 convert ':' to '~' on DOS based file system. */
1841 const char *probe;
1843 #if HAVE_DOS_BASED_FILE_SYSTEM
1844 if (base[0] && base[1] == ':')
1846 ptr[0] = base[0];
1847 ptr[1] = '~';
1848 ptr += 2;
1849 base += 2;
1851 #endif
1852 for (; *base; base = probe)
1854 size_t len;
1856 for (probe = base; *probe; probe++)
1857 if (*probe == '/')
1858 break;
1859 len = probe - base;
1860 if (len == 2 && base[0] == '.' && base[1] == '.')
1861 *ptr++ = '^';
1862 else
1864 memcpy (ptr, base, len);
1865 ptr += len;
1867 if (*probe)
1869 *ptr++ = '#';
1870 probe++;
1875 return ptr;
1878 /* Scan through the bb_data for each line in the block, increment
1879 the line number execution count indicated by the execution count of
1880 the appropriate basic block. */
1882 static void
1883 add_line_counts (coverage_t *coverage, function_t *fn)
1885 unsigned ix;
1886 line_t *line = NULL; /* This is propagated from one iteration to the
1887 next. */
1889 /* Scan each basic block. */
1890 for (ix = 0; ix != fn->num_blocks; ix++)
1892 block_t *block = &fn->blocks[ix];
1893 unsigned *encoding;
1894 const source_t *src = NULL;
1895 unsigned jx;
1897 if (block->count && ix && ix + 1 != fn->num_blocks)
1898 fn->blocks_executed++;
1899 for (jx = 0, encoding = block->u.line.encoding;
1900 jx != block->u.line.num; jx++, encoding++)
1901 if (!*encoding)
1903 src = &sources[*++encoding];
1904 jx++;
1906 else
1908 line = &src->lines[*encoding];
1910 if (coverage)
1912 if (!line->exists)
1913 coverage->lines++;
1914 if (!line->count && block->count)
1915 coverage->lines_executed++;
1917 line->exists = 1;
1918 if (!block->exceptional)
1919 line->unexceptional = 1;
1920 line->count += block->count;
1922 free (block->u.line.encoding);
1923 block->u.cycle.arc = NULL;
1924 block->u.cycle.ident = ~0U;
1926 if (!ix || ix + 1 == fn->num_blocks)
1927 /* Entry or exit block */;
1928 else if (flag_all_blocks)
1930 line_t *block_line = line;
1932 if (!block_line)
1933 block_line = &sources[fn->src].lines[fn->line];
1935 block->chain = block_line->u.blocks;
1936 block_line->u.blocks = block;
1938 else if (flag_branches)
1940 arc_t *arc;
1942 for (arc = block->succ; arc; arc = arc->succ_next)
1944 arc->line_next = line->u.branches;
1945 line->u.branches = arc;
1946 if (coverage && !arc->is_unconditional)
1947 add_branch_counts (coverage, arc);
1951 if (!line)
1952 fnotice (stderr, "%s:no lines for '%s'\n", bbg_file_name, fn->name);
1955 /* Accumulate the line counts of a file. */
1957 static void
1958 accumulate_line_counts (source_t *src)
1960 line_t *line;
1961 function_t *fn, *fn_p, *fn_n;
1962 unsigned ix;
1964 /* Reverse the function order. */
1965 for (fn = src->functions, fn_p = NULL; fn;
1966 fn_p = fn, fn = fn_n)
1968 fn_n = fn->line_next;
1969 fn->line_next = fn_p;
1971 src->functions = fn_p;
1973 for (ix = src->num_lines, line = src->lines; ix--; line++)
1975 if (!flag_all_blocks)
1977 arc_t *arc, *arc_p, *arc_n;
1979 /* Total and reverse the branch information. */
1980 for (arc = line->u.branches, arc_p = NULL; arc;
1981 arc_p = arc, arc = arc_n)
1983 arc_n = arc->line_next;
1984 arc->line_next = arc_p;
1986 add_branch_counts (&src->coverage, arc);
1988 line->u.branches = arc_p;
1990 else if (line->u.blocks)
1992 /* The user expects the line count to be the number of times
1993 a line has been executed. Simply summing the block count
1994 will give an artificially high number. The Right Thing
1995 is to sum the entry counts to the graph of blocks on this
1996 line, then find the elementary cycles of the local graph
1997 and add the transition counts of those cycles. */
1998 block_t *block, *block_p, *block_n;
1999 gcov_type count = 0;
2001 /* Reverse the block information. */
2002 for (block = line->u.blocks, block_p = NULL; block;
2003 block_p = block, block = block_n)
2005 block_n = block->chain;
2006 block->chain = block_p;
2007 block->u.cycle.ident = ix;
2009 line->u.blocks = block_p;
2011 /* Sum the entry arcs. */
2012 for (block = line->u.blocks; block; block = block->chain)
2014 arc_t *arc;
2016 for (arc = block->pred; arc; arc = arc->pred_next)
2018 if (arc->src->u.cycle.ident != ix)
2019 count += arc->count;
2020 if (flag_branches)
2021 add_branch_counts (&src->coverage, arc);
2024 /* Initialize the cs_count. */
2025 for (arc = block->succ; arc; arc = arc->succ_next)
2026 arc->cs_count = arc->count;
2029 /* Find the loops. This uses the algorithm described in
2030 Tiernan 'An Efficient Search Algorithm to Find the
2031 Elementary Circuits of a Graph', CACM Dec 1970. We hold
2032 the P array by having each block point to the arc that
2033 connects to the previous block. The H array is implicitly
2034 held because of the arc ordering, and the block's
2035 previous arc pointer.
2037 Although the algorithm is O(N^3) for highly connected
2038 graphs, at worst we'll have O(N^2), as most blocks have
2039 only one or two exits. Most graphs will be small.
2041 For each loop we find, locate the arc with the smallest
2042 transition count, and add that to the cumulative
2043 count. Decrease flow over the cycle and remove the arc
2044 from consideration. */
2045 for (block = line->u.blocks; block; block = block->chain)
2047 block_t *head = block;
2048 arc_t *arc;
2050 next_vertex:;
2051 arc = head->succ;
2052 current_vertex:;
2053 while (arc)
2055 block_t *dst = arc->dst;
2056 if (/* Already used that arc. */
2057 arc->cycle
2058 /* Not to same graph, or before first vertex. */
2059 || dst->u.cycle.ident != ix
2060 /* Already in path. */
2061 || dst->u.cycle.arc)
2063 arc = arc->succ_next;
2064 continue;
2067 if (dst == block)
2069 /* Found a closing arc. */
2070 gcov_type cycle_count = arc->cs_count;
2071 arc_t *cycle_arc = arc;
2072 arc_t *probe_arc;
2074 /* Locate the smallest arc count of the loop. */
2075 for (dst = head; (probe_arc = dst->u.cycle.arc);
2076 dst = probe_arc->src)
2077 if (cycle_count > probe_arc->cs_count)
2079 cycle_count = probe_arc->cs_count;
2080 cycle_arc = probe_arc;
2083 count += cycle_count;
2084 cycle_arc->cycle = 1;
2086 /* Remove the flow from the cycle. */
2087 arc->cs_count -= cycle_count;
2088 for (dst = head; (probe_arc = dst->u.cycle.arc);
2089 dst = probe_arc->src)
2090 probe_arc->cs_count -= cycle_count;
2092 /* Unwind to the cyclic arc. */
2093 while (head != cycle_arc->src)
2095 arc = head->u.cycle.arc;
2096 head->u.cycle.arc = NULL;
2097 head = arc->src;
2099 /* Move on. */
2100 arc = arc->succ_next;
2101 continue;
2104 /* Add new block to chain. */
2105 dst->u.cycle.arc = arc;
2106 head = dst;
2107 goto next_vertex;
2109 /* We could not add another vertex to the path. Remove
2110 the last vertex from the list. */
2111 arc = head->u.cycle.arc;
2112 if (arc)
2114 /* It was not the first vertex. Move onto next arc. */
2115 head->u.cycle.arc = NULL;
2116 head = arc->src;
2117 arc = arc->succ_next;
2118 goto current_vertex;
2120 /* Mark this block as unusable. */
2121 block->u.cycle.ident = ~0U;
2124 line->count = count;
2127 if (line->exists)
2129 src->coverage.lines++;
2130 if (line->count)
2131 src->coverage.lines_executed++;
2136 /* Output information about ARC number IX. Returns nonzero if
2137 anything is output. */
2139 static int
2140 output_branch_count (FILE *gcov_file, int ix, const arc_t *arc)
2142 if (arc->is_call_non_return)
2144 if (arc->src->count)
2146 fnotice (gcov_file, "call %2d returned %s\n", ix,
2147 format_gcov (arc->src->count - arc->count,
2148 arc->src->count, -flag_counts));
2150 else
2151 fnotice (gcov_file, "call %2d never executed\n", ix);
2153 else if (!arc->is_unconditional)
2155 if (arc->src->count)
2156 fnotice (gcov_file, "branch %2d taken %s%s\n", ix,
2157 format_gcov (arc->count, arc->src->count, -flag_counts),
2158 arc->fall_through ? " (fallthrough)"
2159 : arc->is_throw ? " (throw)" : "");
2160 else
2161 fnotice (gcov_file, "branch %2d never executed\n", ix);
2163 else if (flag_unconditional && !arc->dst->is_call_return)
2165 if (arc->src->count)
2166 fnotice (gcov_file, "unconditional %2d taken %s\n", ix,
2167 format_gcov (arc->count, arc->src->count, -flag_counts));
2168 else
2169 fnotice (gcov_file, "unconditional %2d never executed\n", ix);
2171 else
2172 return 0;
2173 return 1;
2177 /* Read in the source file one line at a time, and output that line to
2178 the gcov file preceded by its execution count and other
2179 information. */
2181 static void
2182 output_lines (FILE *gcov_file, const source_t *src)
2184 FILE *source_file;
2185 unsigned line_num; /* current line number. */
2186 const line_t *line; /* current line info ptr. */
2187 char string[STRING_SIZE]; /* line buffer. */
2188 char const *retval = ""; /* status of source file reading. */
2189 function_t *fn = NULL;
2191 fprintf (gcov_file, "%9s:%5d:Source:%s\n", "-", 0, src->coverage.name);
2192 if (!multiple_files)
2194 fprintf (gcov_file, "%9s:%5d:Graph:%s\n", "-", 0, bbg_file_name);
2195 fprintf (gcov_file, "%9s:%5d:Data:%s\n", "-", 0,
2196 no_data_file ? "-" : da_file_name);
2197 fprintf (gcov_file, "%9s:%5d:Runs:%u\n", "-", 0, object_runs);
2199 fprintf (gcov_file, "%9s:%5d:Programs:%u\n", "-", 0, program_count);
2201 source_file = fopen (src->name, "r");
2202 if (!source_file)
2204 fnotice (stderr, "Cannot open source file %s\n", src->name);
2205 retval = NULL;
2207 else if (src->file_time == 0)
2208 fprintf (gcov_file, "%9s:%5d:Source is newer than graph\n", "-", 0);
2210 if (flag_branches)
2211 fn = src->functions;
2213 for (line_num = 1, line = &src->lines[line_num];
2214 line_num < src->num_lines; line_num++, line++)
2216 for (; fn && fn->line == line_num; fn = fn->line_next)
2218 arc_t *arc = fn->blocks[fn->num_blocks - 1].pred;
2219 gcov_type return_count = fn->blocks[fn->num_blocks - 1].count;
2221 for (; arc; arc = arc->pred_next)
2222 if (arc->fake)
2223 return_count -= arc->count;
2225 fprintf (gcov_file, "function %s", fn->name);
2226 fprintf (gcov_file, " called %s",
2227 format_gcov (fn->blocks[0].count, 0, -1));
2228 fprintf (gcov_file, " returned %s",
2229 format_gcov (return_count, fn->blocks[0].count, 0));
2230 fprintf (gcov_file, " blocks executed %s",
2231 format_gcov (fn->blocks_executed, fn->num_blocks - 2, 0));
2232 fprintf (gcov_file, "\n");
2235 /* For lines which don't exist in the .bb file, print '-' before
2236 the source line. For lines which exist but were never
2237 executed, print '#####' before the source line. Otherwise,
2238 print the execution count before the source line. There are
2239 16 spaces of indentation added before the source line so that
2240 tabs won't be messed up. */
2241 fprintf (gcov_file, "%9s:%5u:",
2242 !line->exists ? "-" : line->count
2243 ? format_gcov (line->count, 0, -1)
2244 : line->unexceptional ? "#####" : "=====", line_num);
2246 if (retval)
2248 /* Copy source line. */
2251 retval = fgets (string, STRING_SIZE, source_file);
2252 if (!retval)
2253 break;
2254 fputs (retval, gcov_file);
2256 while (!retval[0] || retval[strlen (retval) - 1] != '\n');
2258 if (!retval)
2259 fputs ("/*EOF*/\n", gcov_file);
2261 if (flag_all_blocks)
2263 block_t *block;
2264 arc_t *arc;
2265 int ix, jx;
2267 for (ix = jx = 0, block = line->u.blocks; block;
2268 block = block->chain)
2270 if (!block->is_call_return)
2271 fprintf (gcov_file, "%9s:%5u-block %2d\n",
2272 !line->exists ? "-" : block->count
2273 ? format_gcov (block->count, 0, -1)
2274 : block->exceptional ? "%%%%%" : "$$$$$",
2275 line_num, ix++);
2276 if (flag_branches)
2277 for (arc = block->succ; arc; arc = arc->succ_next)
2278 jx += output_branch_count (gcov_file, jx, arc);
2281 else if (flag_branches)
2283 int ix;
2284 arc_t *arc;
2286 for (ix = 0, arc = line->u.branches; arc; arc = arc->line_next)
2287 ix += output_branch_count (gcov_file, ix, arc);
2291 /* Handle all remaining source lines. There may be lines after the
2292 last line of code. */
2293 if (retval)
2295 for (; (retval = fgets (string, STRING_SIZE, source_file)); line_num++)
2297 fprintf (gcov_file, "%9s:%5u:%s", "-", line_num, retval);
2299 while (!retval[0] || retval[strlen (retval) - 1] != '\n')
2301 retval = fgets (string, STRING_SIZE, source_file);
2302 if (!retval)
2303 break;
2304 fputs (retval, gcov_file);
2309 if (source_file)
2310 fclose (source_file);