1 /* Gcov.c: prepend line execution counts and branch probabilities to a
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)
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. */
37 #include "coretypes.h"
48 /* The gcno file is generated by -ftest-coverage option. The gcda file is
49 generated by a program compiled with -fprofile-arcs. Their formats
50 are documented in gcov-io.h. */
52 /* The functions in this file for creating and solution program flow graphs
53 are very similar to functions in the gcc source file profile.c. In
54 some places we make use of the knowledge of how profile.c works to
55 select particular algorithms here. */
57 /* This is the size of the buffer used to read in source file lines. */
59 #define STRING_SIZE 200
65 /* Describes an arc between two basic blocks. */
67 typedef struct arc_info
69 /* source and destination blocks. */
70 struct block_info *src;
71 struct block_info *dst;
73 /* transition counts. */
75 /* used in cycle search, so that we do not clobber original counts. */
78 unsigned int count_valid : 1;
79 unsigned int on_tree : 1;
80 unsigned int fake : 1;
81 unsigned int fall_through : 1;
83 /* Arc is for a function that abnormally returns. */
84 unsigned int is_call_non_return : 1;
86 /* Arc is for catch/setjmp. */
87 unsigned int is_nonlocal_return : 1;
89 /* Is an unconditional branch. */
90 unsigned int is_unconditional : 1;
92 /* Loop making arc. */
93 unsigned int cycle : 1;
95 /* Next branch on line. */
96 struct arc_info *line_next;
98 /* Links to next arc on src and dst lists. */
99 struct arc_info *succ_next;
100 struct arc_info *pred_next;
103 /* Describes a basic block. Contains lists of arcs to successor and
104 predecessor blocks. */
106 typedef struct block_info
108 /* Chain of exit and entry arcs. */
112 /* Number of unprocessed exit and entry arcs. */
116 /* Block execution count. */
119 unsigned count_valid : 1;
120 unsigned valid_chain : 1;
121 unsigned invalid_chain : 1;
123 /* Block is a call instrumenting site. */
124 unsigned is_call_site : 1; /* Does the call. */
125 unsigned is_call_return : 1; /* Is the return. */
127 /* Block is a landing pad for longjmp or throw. */
128 unsigned is_nonlocal_return : 1;
134 /* Array of line numbers and source files. source files are
135 introduced by a linenumber of zero, the next 'line number' is
136 the number of the source file. Always starts with a source
140 } line; /* Valid until blocks are linked onto lines */
143 /* Single line graph cycle workspace. Used for all-blocks
147 } cycle; /* Used in all-blocks mode, after blocks are linked onto
151 /* Temporary chain for solving graph, and for chaining blocks on one
153 struct block_info *chain;
157 /* Describes a single function. Contains an array of basic blocks. */
159 typedef struct function_info
161 /* Name of function. */
166 /* Array of basic blocks. */
169 unsigned blocks_executed;
171 /* Raw arc coverage counts. */
175 /* First line number. */
177 struct source_info *src;
179 /* Next function in same source file. */
180 struct function_info *line_next;
183 struct function_info *next;
186 /* Describes coverage of a file or function. */
188 typedef struct coverage_info
194 int branches_executed;
203 /* Describes a single line of source. Contains a chain of basic blocks
206 typedef struct line_info
208 gcov_type count; /* execution count */
211 arc_t *branches; /* branches from blocks that end on this
212 line. Used for branch-counts when not
214 block_t *blocks; /* blocks which start on this line. Used
215 in all-blocks mode. */
220 /* Describes a file mentioned in the block graph. Contains an array
223 typedef struct source_info
225 /* Name of source file. */
230 /* Array of line information. */
236 /* Functions in this source file. These are in ascending line
238 function_t *functions;
240 /* Next source file. */
241 struct source_info *next;
244 /* Holds a list of function basic block graphs. */
246 static function_t *functions;
248 /* This points to the head of the sourcefile structure list. New elements
249 are always prepended. */
251 static source_t *sources;
253 /* Next index for a source file. */
255 static unsigned source_index;
257 /* This holds data summary information. */
259 static struct gcov_summary object_summary;
260 static unsigned program_count;
262 /* Modification time of graph file. */
264 static time_t bbg_file_time;
266 /* Name and file pointer of the input file for the basic block graph. */
268 static char *bbg_file_name;
270 /* Stamp of the bbg file */
271 static unsigned bbg_stamp;
273 /* Name and file pointer of the input file for the arc count data. */
275 static char *da_file_name;
277 /* Data file is missing. */
279 static int no_data_file;
281 /* If there is several input files, compute and display results after
282 reading all data files. This way if two or more gcda file refer to
283 the same source file (eg inline subprograms in a .h file), the
286 static int multiple_files = 0;
288 /* Output branch probabilities. */
290 static int flag_branches = 0;
292 /* Show unconditional branches too. */
293 static int flag_unconditional = 0;
295 /* Output a gcov file if this is true. This is on by default, and can
296 be turned off by the -n option. */
298 static int flag_gcov_file = 1;
300 /* Output progress indication if this is true. This is off by default
301 and can be turned on by the -d option. */
303 static int flag_display_progress = 0;
305 /* For included files, make the gcov output file name include the name
306 of the input source file. For example, if x.h is included in a.c,
307 then the output file name is a.c##x.h.gcov instead of x.h.gcov. */
309 static int flag_long_names = 0;
311 /* Output count information for every basic block, not merely those
312 that contain line number information. */
314 static int flag_all_blocks = 0;
316 /* Output summary info for each function. */
318 static int flag_function_summary = 0;
320 /* Object directory file prefix. This is the directory/file where the
321 graph and data files are looked for, if nonzero. */
323 static char *object_directory = 0;
325 /* Preserve all pathname components. Needed when object files and
326 source files are in subdirectories. '/' is mangled as '#', '.' is
327 elided and '..' mangled to '^'. */
329 static int flag_preserve_paths = 0;
331 /* Output the number of times a branch was taken as opposed to the percentage
332 of times it was taken. */
334 static int flag_counts = 0;
336 /* Forward declarations. */
337 static void fnotice (FILE *, const char *, ...) ATTRIBUTE_PRINTF_2;
338 static int process_args (int, char **);
339 static void print_usage (int) ATTRIBUTE_NORETURN;
340 static void print_version (void) ATTRIBUTE_NORETURN;
341 static void process_file (const char *);
342 static void generate_results (const char *);
343 static void create_file_names (const char *);
344 static source_t *find_source (const char *);
345 static int read_graph_file (void);
346 static int read_count_file (void);
347 static void solve_flow_graph (function_t *);
348 static void add_branch_counts (coverage_t *, const arc_t *);
349 static void add_line_counts (coverage_t *, function_t *);
350 static void function_summary (const coverage_t *, const char *);
351 static const char *format_gcov (gcov_type, gcov_type, int);
352 static void accumulate_line_counts (source_t *);
353 static int output_branch_count (FILE *, int, const arc_t *);
354 static void output_lines (FILE *, const source_t *);
355 static char *make_gcov_file_name (const char *, const char *);
356 static void release_structures (void);
357 extern int main (int, char **);
360 main (int argc, char **argv)
365 /* Unlock the stdio streams. */
366 unlock_std_streams ();
370 /* Handle response files. */
371 expandargv (&argc, &argv);
373 argno = process_args (argc, argv);
377 if (argc - argno > 1)
382 for (; argno != argc; argno++)
384 if (flag_display_progress)
385 printf("Processing file %d out of %d\n",
386 argno - first_arg + 1, argc - first_arg);
387 process_file (argv[argno]);
390 generate_results (multiple_files ? NULL : argv[argc - 1]);
392 release_structures ();
398 fnotice (FILE *file, const char *cmsgid, ...)
402 va_start (ap, cmsgid);
403 vfprintf (file, _(cmsgid), ap);
407 /* Print a usage message and exit. If ERROR_P is nonzero, this is an error,
408 otherwise the output of --help. */
411 print_usage (int error_p)
413 FILE *file = error_p ? stderr : stdout;
414 int status = error_p ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE;
416 fnotice (file, "Usage: gcov [OPTION]... SOURCEFILE...\n\n");
417 fnotice (file, "Print code coverage information.\n\n");
418 fnotice (file, " -h, --help Print this help, then exit\n");
419 fnotice (file, " -v, --version Print version number, then exit\n");
420 fnotice (file, " -a, --all-blocks Show information for every basic block\n");
421 fnotice (file, " -b, --branch-probabilities Include branch probabilities in output\n");
422 fnotice (file, " -c, --branch-counts Given counts of branches taken\n\
423 rather than percentages\n");
424 fnotice (file, " -n, --no-output Do not create an output file\n");
425 fnotice (file, " -l, --long-file-names Use long output file names for included\n\
427 fnotice (file, " -f, --function-summaries Output summaries for each function\n");
428 fnotice (file, " -o, --object-directory DIR|FILE Search for object files in DIR or called FILE\n");
429 fnotice (file, " -p, --preserve-paths Preserve all pathname components\n");
430 fnotice (file, " -u, --unconditional-branches Show unconditional branch counts too\n");
431 fnotice (file, " -d, --display-progress Display progress information\n");
432 fnotice (file, "\nFor bug reporting instructions, please see:\n%s.\n",
437 /* Print version information and exit. */
442 fnotice (stdout, "gcov %s%s\n", pkgversion_string, version_string);
443 fprintf (stdout, "Copyright %s 2011 Free Software Foundation, Inc.\n",
446 _("This is free software; see the source for copying conditions.\n"
447 "There is NO warranty; not even for MERCHANTABILITY or \n"
448 "FITNESS FOR A PARTICULAR PURPOSE.\n\n"));
449 exit (SUCCESS_EXIT_CODE);
452 static const struct option options[] =
454 { "help", no_argument, NULL, 'h' },
455 { "version", no_argument, NULL, 'v' },
456 { "all-blocks", no_argument, NULL, 'a' },
457 { "branch-probabilities", no_argument, NULL, 'b' },
458 { "branch-counts", no_argument, NULL, 'c' },
459 { "no-output", no_argument, NULL, 'n' },
460 { "long-file-names", no_argument, NULL, 'l' },
461 { "function-summaries", no_argument, NULL, 'f' },
462 { "preserve-paths", no_argument, NULL, 'p' },
463 { "object-directory", required_argument, NULL, 'o' },
464 { "object-file", required_argument, NULL, 'o' },
465 { "unconditional-branches", no_argument, NULL, 'u' },
466 { "display-progress", no_argument, NULL, 'd' },
470 /* Process args, return index to first non-arg. */
473 process_args (int argc, char **argv)
477 while ((opt = getopt_long (argc, argv, "abcdfhlno:puv", options, NULL)) != -1)
491 flag_function_summary = 1;
495 /* print_usage will exit. */
503 object_directory = optarg;
506 flag_preserve_paths = 1;
509 flag_unconditional = 1;
512 flag_display_progress = 1;
516 /* print_version will exit. */
519 /* print_usage will exit. */
526 /* Process a single source file. */
529 process_file (const char *file_name)
533 function_t *old_functions;
535 /* Save and clear the list of current functions. They will be appended
537 old_functions = functions;
540 create_file_names (file_name);
541 if (read_graph_file ())
546 fnotice (stderr, "%s:no functions found\n", bbg_file_name);
550 if (read_count_file ())
553 for (fn_p = NULL, fn = functions; fn; fn_p = fn, fn = fn->next)
554 solve_flow_graph (fn);
557 fn_p->next = old_functions;
561 generate_results (const char *file_name)
566 for (src = sources; src; src = src->next)
567 src->lines = XCNEWVEC (line_t, src->num_lines);
568 for (fn = functions; fn; fn = fn->next)
572 memset (&coverage, 0, sizeof (coverage));
573 coverage.name = fn->name;
574 add_line_counts (flag_function_summary ? &coverage : NULL, fn);
575 if (flag_function_summary)
577 function_summary (&coverage, "Function");
578 fnotice (stdout, "\n");
582 for (src = sources; src; src = src->next)
584 accumulate_line_counts (src);
585 function_summary (&src->coverage, "File");
588 char *gcov_file_name = make_gcov_file_name (file_name, src->name);
589 FILE *gcov_file = fopen (gcov_file_name, "w");
593 fnotice (stdout, "%s:creating '%s'\n",
594 src->name, gcov_file_name);
595 output_lines (gcov_file, src);
596 if (ferror (gcov_file))
597 fnotice (stderr, "%s:error writing output file '%s'\n",
598 src->name, gcov_file_name);
602 fnotice (stderr, "%s:could not open output file '%s'\n",
603 src->name, gcov_file_name);
604 free (gcov_file_name);
606 fnotice (stdout, "\n");
610 /* Release all memory used. */
613 release_structures (void)
618 while ((src = sources))
626 while ((fn = functions))
631 functions = fn->next;
632 for (ix = fn->num_blocks, block = fn->blocks; ix--; block++)
636 for (arc = block->succ; arc; arc = arc_n)
638 arc_n = arc->succ_next;
647 /* Generate the names of the graph and data files. If OBJECT_DIRECTORY
648 is not specified, these are looked for in the current directory,
649 and named from the basename of the FILE_NAME sans extension. If
650 OBJECT_DIRECTORY is specified and is a directory, the files are in
651 that directory, but named from the basename of the FILE_NAME, sans
652 extension. Otherwise OBJECT_DIRECTORY is taken to be the name of
653 the object *file*, and the data files are named from that. */
656 create_file_names (const char *file_name)
660 int length = strlen (file_name);
663 /* Free previous file names. */
664 free (bbg_file_name);
666 da_file_name = bbg_file_name = NULL;
670 if (object_directory && object_directory[0])
674 length += strlen (object_directory) + 2;
675 name = XNEWVEC (char, length);
678 base = !stat (object_directory, &status) && S_ISDIR (status.st_mode);
679 strcat (name, object_directory);
680 if (base && (! IS_DIR_SEPARATOR (name[strlen (name) - 1])))
685 name = XNEWVEC (char, length + 1);
692 /* Append source file name. */
693 const char *cptr = lbasename (file_name);
694 strcat (name, cptr ? cptr : file_name);
697 /* Remove the extension. */
698 cptr = strrchr (name, '.');
702 length = strlen (name);
704 bbg_file_name = XNEWVEC (char, length + strlen (GCOV_NOTE_SUFFIX) + 1);
705 strcpy (bbg_file_name, name);
706 strcpy (bbg_file_name + length, GCOV_NOTE_SUFFIX);
708 da_file_name = XNEWVEC (char, length + strlen (GCOV_DATA_SUFFIX) + 1);
709 strcpy (da_file_name, name);
710 strcpy (da_file_name + length, GCOV_DATA_SUFFIX);
716 /* Find or create a source file structure for FILE_NAME. Copies
717 FILE_NAME on creation */
720 find_source (const char *file_name)
726 file_name = "<unknown>";
728 for (src = sources; src; src = src->next)
729 if (!filename_cmp (file_name, src->name))
734 src = XCNEW (source_t);
735 src->name = xstrdup (file_name);
736 src->coverage.name = src->name;
737 src->index = source_index++;
741 if (!stat (file_name, &status))
742 src->file_time = status.st_mtime;
745 if (src->file_time > bbg_file_time)
747 static int info_emitted;
749 fnotice (stderr, "%s:source file is newer than graph file '%s'\n",
750 src->name, bbg_file_name);
754 "(the message is only displayed one per source file)\n");
763 /* Read the graph file. Return nonzero on fatal error. */
766 read_graph_file (void)
769 unsigned current_tag = 0;
770 struct function_info *fn = NULL;
771 function_t *old_functions_head = functions;
772 source_t *src = NULL;
776 if (!gcov_open (bbg_file_name, 1))
778 fnotice (stderr, "%s:cannot open graph file\n", bbg_file_name);
781 bbg_file_time = gcov_time ();
782 if (!gcov_magic (gcov_read_unsigned (), GCOV_NOTE_MAGIC))
784 fnotice (stderr, "%s:not a gcov graph file\n", bbg_file_name);
789 version = gcov_read_unsigned ();
790 if (version != GCOV_VERSION)
794 GCOV_UNSIGNED2STRING (v, version);
795 GCOV_UNSIGNED2STRING (e, GCOV_VERSION);
797 fnotice (stderr, "%s:version '%.4s', prefer '%.4s'\n",
798 bbg_file_name, v, e);
800 bbg_stamp = gcov_read_unsigned ();
802 while ((tag = gcov_read_unsigned ()))
804 unsigned length = gcov_read_unsigned ();
805 gcov_position_t base = gcov_position ();
807 if (tag == GCOV_TAG_FUNCTION)
810 unsigned ident, checksum, lineno;
812 function_t *probe, *prev;
814 ident = gcov_read_unsigned ();
815 checksum = gcov_read_unsigned ();
816 function_name = xstrdup (gcov_read_string ());
817 src = find_source (gcov_read_string ());
818 lineno = gcov_read_unsigned ();
820 fn = XCNEW (function_t);
821 fn->name = function_name;
823 fn->checksum = checksum;
827 fn->next = functions;
831 if (lineno >= src->num_lines)
832 src->num_lines = lineno + 1;
833 /* Now insert it into the source file's list of
834 functions. Normally functions will be encountered in
835 ascending order, so a simple scan is quick. */
836 for (probe = src->functions, prev = NULL;
837 probe && probe->line > lineno;
838 prev = probe, probe = probe->line_next)
840 fn->line_next = probe;
842 prev->line_next = fn;
846 else if (fn && tag == GCOV_TAG_BLOCKS)
849 fnotice (stderr, "%s:already seen blocks for '%s'\n",
850 bbg_file_name, fn->name);
853 unsigned ix, num_blocks = GCOV_TAG_BLOCKS_NUM (length);
854 fn->num_blocks = num_blocks;
856 fn->blocks = XCNEWVEC (block_t, fn->num_blocks);
857 for (ix = 0; ix != num_blocks; ix++)
858 fn->blocks[ix].flags = gcov_read_unsigned ();
861 else if (fn && tag == GCOV_TAG_ARCS)
863 unsigned src = gcov_read_unsigned ();
864 unsigned num_dests = GCOV_TAG_ARCS_NUM (length);
866 if (src >= fn->num_blocks || fn->blocks[src].succ)
871 struct arc_info *arc;
872 unsigned dest = gcov_read_unsigned ();
873 unsigned flags = gcov_read_unsigned ();
875 if (dest >= fn->num_blocks)
879 arc->dst = &fn->blocks[dest];
880 arc->src = &fn->blocks[src];
883 arc->count_valid = 0;
884 arc->on_tree = !!(flags & GCOV_ARC_ON_TREE);
885 arc->fake = !!(flags & GCOV_ARC_FAKE);
886 arc->fall_through = !!(flags & GCOV_ARC_FALLTHROUGH);
888 arc->succ_next = fn->blocks[src].succ;
889 fn->blocks[src].succ = arc;
890 fn->blocks[src].num_succ++;
892 arc->pred_next = fn->blocks[dest].pred;
893 fn->blocks[dest].pred = arc;
894 fn->blocks[dest].num_pred++;
900 /* Exceptional exit from this function, the
901 source block must be a call. */
902 fn->blocks[src].is_call_site = 1;
903 arc->is_call_non_return = 1;
907 /* Non-local return from a callee of this
908 function. The destination block is a catch or
910 arc->is_nonlocal_return = 1;
911 fn->blocks[dest].is_nonlocal_return = 1;
919 else if (fn && tag == GCOV_TAG_LINES)
921 unsigned blockno = gcov_read_unsigned ();
922 unsigned *line_nos = XCNEWVEC (unsigned, length - 1);
924 if (blockno >= fn->num_blocks || fn->blocks[blockno].u.line.encoding)
929 unsigned lineno = gcov_read_unsigned ();
936 line_nos[ix++] = src->index;
938 line_nos[ix++] = lineno;
939 if (lineno >= src->num_lines)
940 src->num_lines = lineno + 1;
944 const char *file_name = gcov_read_string ();
948 src = find_source (file_name);
951 line_nos[ix++] = src->index;
955 fn->blocks[blockno].u.line.encoding = line_nos;
956 fn->blocks[blockno].u.line.num = ix;
958 else if (current_tag && !GCOV_TAG_IS_SUBTAG (current_tag, tag))
963 gcov_sync (base, length);
964 if (gcov_is_error ())
967 fnotice (stderr, "%s:corrupted\n", bbg_file_name);
974 /* We built everything backwards, so nreverse them all. */
976 /* Reverse sources. Not strictly necessary, but we'll then process
977 them in the 'expected' order. */
979 source_t *src, *src_p, *src_n;
981 for (src_p = NULL, src = sources; src; src_p = src, src = src_n)
989 /* Reverse functions. */
991 function_t *fn, *fn_p, *fn_n;
993 for (fn_p = old_functions_head, fn = functions;
994 fn != old_functions_head;
995 fn_p = fn, fn = fn_n)
1002 /* Reverse the arcs. */
1003 for (ix = fn->num_blocks; ix--;)
1005 arc_t *arc, *arc_p, *arc_n;
1007 for (arc_p = NULL, arc = fn->blocks[ix].succ; arc;
1008 arc_p = arc, arc = arc_n)
1010 arc_n = arc->succ_next;
1011 arc->succ_next = arc_p;
1013 fn->blocks[ix].succ = arc_p;
1015 for (arc_p = NULL, arc = fn->blocks[ix].pred; arc;
1016 arc_p = arc, arc = arc_n)
1018 arc_n = arc->pred_next;
1019 arc->pred_next = arc_p;
1021 fn->blocks[ix].pred = arc_p;
1029 /* Reads profiles from the count file and attach to each
1030 function. Return nonzero if fatal error. */
1033 read_count_file (void)
1038 function_t *fn = NULL;
1041 if (!gcov_open (da_file_name, 1))
1043 fnotice (stderr, "%s:cannot open data file, assuming not executed\n",
1048 if (!gcov_magic (gcov_read_unsigned (), GCOV_DATA_MAGIC))
1050 fnotice (stderr, "%s:not a gcov data file\n", da_file_name);
1055 version = gcov_read_unsigned ();
1056 if (version != GCOV_VERSION)
1060 GCOV_UNSIGNED2STRING (v, version);
1061 GCOV_UNSIGNED2STRING (e, GCOV_VERSION);
1063 fnotice (stderr, "%s:version '%.4s', prefer version '%.4s'\n",
1064 da_file_name, v, e);
1066 tag = gcov_read_unsigned ();
1067 if (tag != bbg_stamp)
1069 fnotice (stderr, "%s:stamp mismatch with graph file\n", da_file_name);
1073 while ((tag = gcov_read_unsigned ()))
1075 unsigned length = gcov_read_unsigned ();
1076 unsigned long base = gcov_position ();
1078 if (tag == GCOV_TAG_OBJECT_SUMMARY)
1079 gcov_read_summary (&object_summary);
1080 else if (tag == GCOV_TAG_PROGRAM_SUMMARY)
1082 else if (tag == GCOV_TAG_FUNCTION)
1085 unsigned ident = gcov_read_unsigned ();
1086 struct function_info *fn_n = functions;
1088 /* Try to find the function in the list.
1089 To speed up the search, first start from the last function
1091 for (fn = fn ? fn->next : NULL; ; fn = fn->next)
1095 else if ((fn = fn_n))
1099 fnotice (stderr, "%s:unknown function '%u'\n",
1100 da_file_name, ident);
1103 if (fn->ident == ident)
1110 else if (gcov_read_unsigned () != fn->checksum)
1113 fnotice (stderr, "%s:profile mismatch for '%s'\n",
1114 da_file_name, fn->name);
1118 else if (tag == GCOV_TAG_FOR_COUNTER (GCOV_COUNTER_ARCS) && fn)
1120 if (length != GCOV_TAG_COUNTER_LENGTH (fn->num_counts))
1124 fn->counts = XCNEWVEC (gcov_type, fn->num_counts);
1126 for (ix = 0; ix != fn->num_counts; ix++)
1127 fn->counts[ix] += gcov_read_counter ();
1129 gcov_sync (base, length);
1130 if ((error = gcov_is_error ()))
1132 fnotice (stderr, error < 0 ? "%s:overflowed\n" : "%s:corrupted\n",
1142 /* Solve the flow graph. Propagate counts from the instrumented arcs
1143 to the blocks and the uninstrumented arcs. */
1146 solve_flow_graph (function_t *fn)
1150 gcov_type *count_ptr = fn->counts;
1152 block_t *valid_blocks = NULL; /* valid, but unpropagated blocks. */
1153 block_t *invalid_blocks = NULL; /* invalid, but inferable blocks. */
1155 if (fn->num_blocks < 2)
1156 fnotice (stderr, "%s:'%s' lacks entry and/or exit blocks\n",
1157 bbg_file_name, fn->name);
1160 if (fn->blocks[0].num_pred)
1161 fnotice (stderr, "%s:'%s' has arcs to entry block\n",
1162 bbg_file_name, fn->name);
1164 /* We can't deduce the entry block counts from the lack of
1166 fn->blocks[0].num_pred = ~(unsigned)0;
1168 if (fn->blocks[fn->num_blocks - 1].num_succ)
1169 fnotice (stderr, "%s:'%s' has arcs from exit block\n",
1170 bbg_file_name, fn->name);
1172 /* Likewise, we can't deduce exit block counts from the lack
1173 of its successors. */
1174 fn->blocks[fn->num_blocks - 1].num_succ = ~(unsigned)0;
1177 /* Propagate the measured counts, this must be done in the same
1178 order as the code in profile.c */
1179 for (ix = 0, blk = fn->blocks; ix != fn->num_blocks; ix++, blk++)
1181 block_t const *prev_dst = NULL;
1182 int out_of_order = 0;
1183 int non_fake_succ = 0;
1185 for (arc = blk->succ; arc; arc = arc->succ_next)
1193 arc->count = *count_ptr++;
1194 arc->count_valid = 1;
1196 arc->dst->num_pred--;
1198 if (prev_dst && prev_dst > arc->dst)
1200 prev_dst = arc->dst;
1202 if (non_fake_succ == 1)
1204 /* If there is only one non-fake exit, it is an
1205 unconditional branch. */
1206 for (arc = blk->succ; arc; arc = arc->succ_next)
1209 arc->is_unconditional = 1;
1210 /* If this block is instrumenting a call, it might be
1211 an artificial block. It is not artificial if it has
1212 a non-fallthrough exit, or the destination of this
1213 arc has more than one entry. Mark the destination
1214 block as a return site, if none of those conditions
1216 if (blk->is_call_site && arc->fall_through
1217 && arc->dst->pred == arc && !arc->pred_next)
1218 arc->dst->is_call_return = 1;
1222 /* Sort the successor arcs into ascending dst order. profile.c
1223 normally produces arcs in the right order, but sometimes with
1224 one or two out of order. We're not using a particularly
1228 arc_t *start = blk->succ;
1229 unsigned changes = 1;
1233 arc_t *arc, *arc_p, *arc_n;
1236 for (arc_p = NULL, arc = start; (arc_n = arc->succ_next);)
1238 if (arc->dst > arc_n->dst)
1242 arc_p->succ_next = arc_n;
1245 arc->succ_next = arc_n->succ_next;
1246 arc_n->succ_next = arc;
1259 /* Place it on the invalid chain, it will be ignored if that's
1261 blk->invalid_chain = 1;
1262 blk->chain = invalid_blocks;
1263 invalid_blocks = blk;
1266 while (invalid_blocks || valid_blocks)
1268 while ((blk = invalid_blocks))
1270 gcov_type total = 0;
1273 invalid_blocks = blk->chain;
1274 blk->invalid_chain = 0;
1276 for (arc = blk->succ; arc; arc = arc->succ_next)
1277 total += arc->count;
1278 else if (!blk->num_pred)
1279 for (arc = blk->pred; arc; arc = arc->pred_next)
1280 total += arc->count;
1285 blk->count_valid = 1;
1286 blk->chain = valid_blocks;
1287 blk->valid_chain = 1;
1290 while ((blk = valid_blocks))
1293 arc_t *arc, *inv_arc;
1295 valid_blocks = blk->chain;
1296 blk->valid_chain = 0;
1297 if (blk->num_succ == 1)
1303 for (arc = blk->succ; arc; arc = arc->succ_next)
1305 total -= arc->count;
1306 if (!arc->count_valid)
1310 inv_arc->count_valid = 1;
1311 inv_arc->count = total;
1314 if (dst->count_valid)
1316 if (dst->num_pred == 1 && !dst->valid_chain)
1318 dst->chain = valid_blocks;
1319 dst->valid_chain = 1;
1325 if (!dst->num_pred && !dst->invalid_chain)
1327 dst->chain = invalid_blocks;
1328 dst->invalid_chain = 1;
1329 invalid_blocks = dst;
1333 if (blk->num_pred == 1)
1339 for (arc = blk->pred; arc; arc = arc->pred_next)
1341 total -= arc->count;
1342 if (!arc->count_valid)
1346 inv_arc->count_valid = 1;
1347 inv_arc->count = total;
1350 if (src->count_valid)
1352 if (src->num_succ == 1 && !src->valid_chain)
1354 src->chain = valid_blocks;
1355 src->valid_chain = 1;
1361 if (!src->num_succ && !src->invalid_chain)
1363 src->chain = invalid_blocks;
1364 src->invalid_chain = 1;
1365 invalid_blocks = src;
1372 /* If the graph has been correctly solved, every block will have a
1374 for (ix = 0; ix < fn->num_blocks; ix++)
1375 if (!fn->blocks[ix].count_valid)
1377 fnotice (stderr, "%s:graph is unsolvable for '%s'\n",
1378 bbg_file_name, fn->name);
1385 /* Increment totals in COVERAGE according to arc ARC. */
1388 add_branch_counts (coverage_t *coverage, const arc_t *arc)
1390 if (arc->is_call_non_return)
1393 if (arc->src->count)
1394 coverage->calls_executed++;
1396 else if (!arc->is_unconditional)
1398 coverage->branches++;
1399 if (arc->src->count)
1400 coverage->branches_executed++;
1402 coverage->branches_taken++;
1406 /* Format a HOST_WIDE_INT as either a percent ratio, or absolute
1407 count. If dp >= 0, format TOP/BOTTOM * 100 to DP decimal places.
1408 If DP is zero, no decimal point is printed. Only print 100% when
1409 TOP==BOTTOM and only print 0% when TOP=0. If dp < 0, then simply
1410 format TOP. Return pointer to a static string. */
1413 format_gcov (gcov_type top, gcov_type bottom, int dp)
1415 static char buffer[20];
1419 float ratio = bottom ? (float)top / bottom : 0;
1421 unsigned limit = 100;
1424 for (ix = dp; ix--; )
1427 percent = (unsigned) (ratio * limit + (float)0.5);
1428 if (percent <= 0 && top)
1430 else if (percent >= limit && top != bottom)
1431 percent = limit - 1;
1432 ix = sprintf (buffer, "%.*u%%", dp + 1, percent);
1438 buffer[ix+1] = buffer[ix];
1442 buffer[ix + 1] = '.';
1446 sprintf (buffer, HOST_WIDEST_INT_PRINT_DEC, (HOST_WIDEST_INT)top);
1452 /* Output summary info for a function. */
1455 function_summary (const coverage_t *coverage, const char *title)
1457 fnotice (stdout, "%s '%s'\n", title, coverage->name);
1459 if (coverage->lines)
1460 fnotice (stdout, "Lines executed:%s of %d\n",
1461 format_gcov (coverage->lines_executed, coverage->lines, 2),
1464 fnotice (stdout, "No executable lines\n");
1468 if (coverage->branches)
1470 fnotice (stdout, "Branches executed:%s of %d\n",
1471 format_gcov (coverage->branches_executed,
1472 coverage->branches, 2),
1473 coverage->branches);
1474 fnotice (stdout, "Taken at least once:%s of %d\n",
1475 format_gcov (coverage->branches_taken,
1476 coverage->branches, 2),
1477 coverage->branches);
1480 fnotice (stdout, "No branches\n");
1481 if (coverage->calls)
1482 fnotice (stdout, "Calls executed:%s of %d\n",
1483 format_gcov (coverage->calls_executed, coverage->calls, 2),
1486 fnotice (stdout, "No calls\n");
1490 /* Generate an output file name. LONG_OUTPUT_NAMES and PRESERVE_PATHS
1491 affect name generation. With preserve_paths we create a filename
1492 from all path components of the source file, replacing '/' with
1493 '#', without it we simply take the basename component. With
1494 long_output_names we prepend the processed name of the input file
1495 to each output name (except when the current source file is the
1496 input file, so you don't get a double concatenation). The two
1497 components are separated by '##'. Also '.' filename components are
1498 removed and '..' components are renamed to '^'. */
1501 make_gcov_file_name (const char *input_name, const char *src_name)
1506 if (flag_long_names && input_name && strcmp (src_name, input_name))
1508 name = XNEWVEC (char, strlen (src_name) + strlen (input_name) + 10);
1510 /* Generate the input filename part. */
1511 cptr = flag_preserve_paths ? NULL : lbasename (input_name);
1512 strcat (name, cptr ? cptr : input_name);
1513 strcat (name, "##");
1517 name = XNEWVEC (char, strlen (src_name) + 10);
1521 /* Generate the source filename part. */
1523 cptr = flag_preserve_paths ? NULL : lbasename (src_name);
1524 strcat (name, cptr ? cptr : src_name);
1526 if (flag_preserve_paths)
1528 /* Convert '/' and '\' to '#', remove '/./', convert '/../' to '#^#',
1529 convert ':' to '~' on DOS based file system. */
1530 char *pnew = name, *pold = name;
1532 /* First check for leading drive separator. */
1534 while (*pold != '\0')
1536 #if defined (HAVE_DOS_BASED_FILE_SYSTEM)
1545 && (strstr (pold, "/./") == pold
1546 || strstr (pold, "/.\\") == pold))
1548 && (strstr (pold, "\\.\\") == pold
1549 || strstr (pold, "\\./") == pold)))
1551 else if (*pold == '/'
1552 && (strstr (pold, "/../") == pold
1553 || strstr (pold, "/..\\") == pold))
1555 strcpy (pnew, "#^#");
1559 else if (*pold == '\\'
1560 && (strstr (pold, "\\..\\") == pold
1561 || strstr (pold, "\\../") == pold))
1563 strcpy (pnew, "#^#");
1567 else if (*pold == '/' || *pold == '\\')
1579 strcat (name, ".gcov");
1583 /* Scan through the bb_data for each line in the block, increment
1584 the line number execution count indicated by the execution count of
1585 the appropriate basic block. */
1588 add_line_counts (coverage_t *coverage, function_t *fn)
1591 line_t *line = NULL; /* This is propagated from one iteration to the
1594 /* Scan each basic block. */
1595 for (ix = 0; ix != fn->num_blocks; ix++)
1597 block_t *block = &fn->blocks[ix];
1599 const source_t *src = NULL;
1602 if (block->count && ix && ix + 1 != fn->num_blocks)
1603 fn->blocks_executed++;
1604 for (jx = 0, encoding = block->u.line.encoding;
1605 jx != block->u.line.num; jx++, encoding++)
1608 unsigned src_n = *++encoding;
1610 for (src = sources; src->index != src_n; src = src->next)
1616 line = &src->lines[*encoding];
1622 if (!line->count && block->count)
1623 coverage->lines_executed++;
1626 line->count += block->count;
1628 free (block->u.line.encoding);
1629 block->u.cycle.arc = NULL;
1630 block->u.cycle.ident = ~0U;
1632 if (!ix || ix + 1 == fn->num_blocks)
1633 /* Entry or exit block */;
1634 else if (flag_all_blocks)
1636 line_t *block_line = line ? line : &fn->src->lines[fn->line];
1638 block->chain = block_line->u.blocks;
1639 block_line->u.blocks = block;
1641 else if (flag_branches)
1645 for (arc = block->succ; arc; arc = arc->succ_next)
1647 arc->line_next = line->u.branches;
1648 line->u.branches = arc;
1649 if (coverage && !arc->is_unconditional)
1650 add_branch_counts (coverage, arc);
1655 fnotice (stderr, "%s:no lines for '%s'\n", bbg_file_name, fn->name);
1658 /* Accumulate the line counts of a file. */
1661 accumulate_line_counts (source_t *src)
1664 function_t *fn, *fn_p, *fn_n;
1667 /* Reverse the function order. */
1668 for (fn = src->functions, fn_p = NULL; fn;
1669 fn_p = fn, fn = fn_n)
1671 fn_n = fn->line_next;
1672 fn->line_next = fn_p;
1674 src->functions = fn_p;
1676 for (ix = src->num_lines, line = src->lines; ix--; line++)
1678 if (!flag_all_blocks)
1680 arc_t *arc, *arc_p, *arc_n;
1682 /* Total and reverse the branch information. */
1683 for (arc = line->u.branches, arc_p = NULL; arc;
1684 arc_p = arc, arc = arc_n)
1686 arc_n = arc->line_next;
1687 arc->line_next = arc_p;
1689 add_branch_counts (&src->coverage, arc);
1691 line->u.branches = arc_p;
1693 else if (line->u.blocks)
1695 /* The user expects the line count to be the number of times
1696 a line has been executed. Simply summing the block count
1697 will give an artificially high number. The Right Thing
1698 is to sum the entry counts to the graph of blocks on this
1699 line, then find the elementary cycles of the local graph
1700 and add the transition counts of those cycles. */
1701 block_t *block, *block_p, *block_n;
1702 gcov_type count = 0;
1704 /* Reverse the block information. */
1705 for (block = line->u.blocks, block_p = NULL; block;
1706 block_p = block, block = block_n)
1708 block_n = block->chain;
1709 block->chain = block_p;
1710 block->u.cycle.ident = ix;
1712 line->u.blocks = block_p;
1714 /* Sum the entry arcs. */
1715 for (block = line->u.blocks; block; block = block->chain)
1719 for (arc = block->pred; arc; arc = arc->pred_next)
1721 if (arc->src->u.cycle.ident != ix)
1722 count += arc->count;
1724 add_branch_counts (&src->coverage, arc);
1727 /* Initialize the cs_count. */
1728 for (arc = block->succ; arc; arc = arc->succ_next)
1729 arc->cs_count = arc->count;
1732 /* Find the loops. This uses the algorithm described in
1733 Tiernan 'An Efficient Search Algorithm to Find the
1734 Elementary Circuits of a Graph', CACM Dec 1970. We hold
1735 the P array by having each block point to the arc that
1736 connects to the previous block. The H array is implicitly
1737 held because of the arc ordering, and the block's
1738 previous arc pointer.
1740 Although the algorithm is O(N^3) for highly connected
1741 graphs, at worst we'll have O(N^2), as most blocks have
1742 only one or two exits. Most graphs will be small.
1744 For each loop we find, locate the arc with the smallest
1745 transition count, and add that to the cumulative
1746 count. Decrease flow over the cycle and remove the arc
1747 from consideration. */
1748 for (block = line->u.blocks; block; block = block->chain)
1750 block_t *head = block;
1758 block_t *dst = arc->dst;
1759 if (/* Already used that arc. */
1761 /* Not to same graph, or before first vertex. */
1762 || dst->u.cycle.ident != ix
1763 /* Already in path. */
1764 || dst->u.cycle.arc)
1766 arc = arc->succ_next;
1772 /* Found a closing arc. */
1773 gcov_type cycle_count = arc->cs_count;
1774 arc_t *cycle_arc = arc;
1777 /* Locate the smallest arc count of the loop. */
1778 for (dst = head; (probe_arc = dst->u.cycle.arc);
1779 dst = probe_arc->src)
1780 if (cycle_count > probe_arc->cs_count)
1782 cycle_count = probe_arc->cs_count;
1783 cycle_arc = probe_arc;
1786 count += cycle_count;
1787 cycle_arc->cycle = 1;
1789 /* Remove the flow from the cycle. */
1790 arc->cs_count -= cycle_count;
1791 for (dst = head; (probe_arc = dst->u.cycle.arc);
1792 dst = probe_arc->src)
1793 probe_arc->cs_count -= cycle_count;
1795 /* Unwind to the cyclic arc. */
1796 while (head != cycle_arc->src)
1798 arc = head->u.cycle.arc;
1799 head->u.cycle.arc = NULL;
1803 arc = arc->succ_next;
1807 /* Add new block to chain. */
1808 dst->u.cycle.arc = arc;
1812 /* We could not add another vertex to the path. Remove
1813 the last vertex from the list. */
1814 arc = head->u.cycle.arc;
1817 /* It was not the first vertex. Move onto next arc. */
1818 head->u.cycle.arc = NULL;
1820 arc = arc->succ_next;
1821 goto current_vertex;
1823 /* Mark this block as unusable. */
1824 block->u.cycle.ident = ~0U;
1827 line->count = count;
1832 src->coverage.lines++;
1834 src->coverage.lines_executed++;
1839 /* Output information about ARC number IX. Returns nonzero if
1840 anything is output. */
1843 output_branch_count (FILE *gcov_file, int ix, const arc_t *arc)
1846 if (arc->is_call_non_return)
1848 if (arc->src->count)
1850 fnotice (gcov_file, "call %2d returned %s\n", ix,
1851 format_gcov (arc->src->count - arc->count,
1852 arc->src->count, -flag_counts));
1855 fnotice (gcov_file, "call %2d never executed\n", ix);
1857 else if (!arc->is_unconditional)
1859 if (arc->src->count)
1860 fnotice (gcov_file, "branch %2d taken %s%s\n", ix,
1861 format_gcov (arc->count, arc->src->count, -flag_counts),
1862 arc->fall_through ? " (fallthrough)" : "");
1864 fnotice (gcov_file, "branch %2d never executed\n", ix);
1866 else if (flag_unconditional && !arc->dst->is_call_return)
1868 if (arc->src->count)
1869 fnotice (gcov_file, "unconditional %2d taken %s\n", ix,
1870 format_gcov (arc->count, arc->src->count, -flag_counts));
1872 fnotice (gcov_file, "unconditional %2d never executed\n", ix);
1880 /* Read in the source file one line at a time, and output that line to
1881 the gcov file preceded by its execution count and other
1885 output_lines (FILE *gcov_file, const source_t *src)
1888 unsigned line_num; /* current line number. */
1889 const line_t *line; /* current line info ptr. */
1890 char string[STRING_SIZE]; /* line buffer. */
1891 char const *retval = ""; /* status of source file reading. */
1892 function_t *fn = NULL;
1894 fprintf (gcov_file, "%9s:%5d:Source:%s\n", "-", 0, src->name);
1895 if (!multiple_files)
1897 fprintf (gcov_file, "%9s:%5d:Graph:%s\n", "-", 0, bbg_file_name);
1898 fprintf (gcov_file, "%9s:%5d:Data:%s\n", "-", 0,
1899 no_data_file ? "-" : da_file_name);
1900 fprintf (gcov_file, "%9s:%5d:Runs:%u\n", "-", 0,
1901 object_summary.ctrs[GCOV_COUNTER_ARCS].runs);
1903 fprintf (gcov_file, "%9s:%5d:Programs:%u\n", "-", 0, program_count);
1905 source_file = fopen (src->name, "r");
1908 fnotice (stderr, "%s:cannot open source file\n", src->name);
1911 else if (src->file_time == 0)
1912 fprintf (gcov_file, "%9s:%5d:Source is newer than graph\n", "-", 0);
1915 fn = src->functions;
1917 for (line_num = 1, line = &src->lines[line_num];
1918 line_num < src->num_lines; line_num++, line++)
1920 for (; fn && fn->line == line_num; fn = fn->line_next)
1922 arc_t *arc = fn->blocks[fn->num_blocks - 1].pred;
1923 gcov_type return_count = fn->blocks[fn->num_blocks - 1].count;
1925 for (; arc; arc = arc->pred_next)
1927 return_count -= arc->count;
1929 fprintf (gcov_file, "function %s", fn->name);
1930 fprintf (gcov_file, " called %s",
1931 format_gcov (fn->blocks[0].count, 0, -1));
1932 fprintf (gcov_file, " returned %s",
1933 format_gcov (return_count, fn->blocks[0].count, 0));
1934 fprintf (gcov_file, " blocks executed %s",
1935 format_gcov (fn->blocks_executed, fn->num_blocks - 2, 0));
1936 fprintf (gcov_file, "\n");
1939 /* For lines which don't exist in the .bb file, print '-' before
1940 the source line. For lines which exist but were never
1941 executed, print '#####' before the source line. Otherwise,
1942 print the execution count before the source line. There are
1943 16 spaces of indentation added before the source line so that
1944 tabs won't be messed up. */
1945 fprintf (gcov_file, "%9s:%5u:",
1946 !line->exists ? "-" : !line->count ? "#####"
1947 : format_gcov (line->count, 0, -1), line_num);
1951 /* Copy source line. */
1954 retval = fgets (string, STRING_SIZE, source_file);
1957 fputs (retval, gcov_file);
1959 while (!retval[0] || retval[strlen (retval) - 1] != '\n');
1962 fputs ("/*EOF*/\n", gcov_file);
1964 if (flag_all_blocks)
1970 for (ix = jx = 0, block = line->u.blocks; block;
1971 block = block->chain)
1973 if (!block->is_call_return)
1974 fprintf (gcov_file, "%9s:%5u-block %2d\n",
1975 !line->exists ? "-" : !block->count ? "$$$$$"
1976 : format_gcov (block->count, 0, -1),
1979 for (arc = block->succ; arc; arc = arc->succ_next)
1980 jx += output_branch_count (gcov_file, jx, arc);
1983 else if (flag_branches)
1988 for (ix = 0, arc = line->u.branches; arc; arc = arc->line_next)
1989 ix += output_branch_count (gcov_file, ix, arc);
1993 /* Handle all remaining source lines. There may be lines after the
1994 last line of code. */
1997 for (; (retval = fgets (string, STRING_SIZE, source_file)); line_num++)
1999 fprintf (gcov_file, "%9s:%5u:%s", "-", line_num, retval);
2001 while (!retval[0] || retval[strlen (retval) - 1] != '\n')
2003 retval = fgets (string, STRING_SIZE, source_file);
2006 fputs (retval, gcov_file);
2012 fclose (source_file);