prj-nmsc.adb, [...] (Expand_Subdirectory_Pattern): New subprogram.
[gcc.git] / gcc / gcov.c
1 /* Gcov.c: prepend line execution counts and branch probabilities to a
2 source file.
3 Copyright (C) 1990, 1991, 1992, 1993, 1994, 1996, 1997, 1998, 1999,
4 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
5 Free Software Foundation, Inc.
6 Contributed by James E. Wilson of Cygnus Support.
7 Mangled by Bob Manson of Cygnus Support.
8 Mangled further by Nathan Sidwell <nathan@codesourcery.com>
9
10 Gcov is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 3, or (at your option)
13 any later version.
14
15 Gcov is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with Gcov; see the file COPYING3. If not see
22 <http://www.gnu.org/licenses/>. */
23
24 /* ??? Print a list of the ten blocks with the highest execution counts,
25 and list the line numbers corresponding to those blocks. Also, perhaps
26 list the line numbers with the highest execution counts, only printing
27 the first if there are several which are all listed in the same block. */
28
29 /* ??? Should have an option to print the number of basic blocks, and the
30 percent of them that are covered. */
31
32 /* Need an option to show individual block counts, and show
33 probabilities of fall through arcs. */
34
35 #include "config.h"
36 #include "system.h"
37 #include "coretypes.h"
38 #include "tm.h"
39 #include "intl.h"
40 #include "version.h"
41
42 #include <getopt.h>
43
44 #define IN_GCOV 1
45 #include "gcov-io.h"
46 #include "gcov-io.c"
47
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. */
51
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. */
56
57 /* This is the size of the buffer used to read in source file lines. */
58
59 #define STRING_SIZE 200
60
61 struct function_info;
62 struct block_info;
63 struct source_info;
64
65 /* Describes an arc between two basic blocks. */
66
67 typedef struct arc_info
68 {
69 /* source and destination blocks. */
70 struct block_info *src;
71 struct block_info *dst;
72
73 /* transition counts. */
74 gcov_type count;
75 /* used in cycle search, so that we do not clobber original counts. */
76 gcov_type cs_count;
77
78 unsigned int count_valid : 1;
79 unsigned int on_tree : 1;
80 unsigned int fake : 1;
81 unsigned int fall_through : 1;
82
83 /* Arc is for a function that abnormally returns. */
84 unsigned int is_call_non_return : 1;
85
86 /* Arc is for catch/setjmp. */
87 unsigned int is_nonlocal_return : 1;
88
89 /* Is an unconditional branch. */
90 unsigned int is_unconditional : 1;
91
92 /* Loop making arc. */
93 unsigned int cycle : 1;
94
95 /* Next branch on line. */
96 struct arc_info *line_next;
97
98 /* Links to next arc on src and dst lists. */
99 struct arc_info *succ_next;
100 struct arc_info *pred_next;
101 } arc_t;
102
103 /* Describes a basic block. Contains lists of arcs to successor and
104 predecessor blocks. */
105
106 typedef struct block_info
107 {
108 /* Chain of exit and entry arcs. */
109 arc_t *succ;
110 arc_t *pred;
111
112 /* Number of unprocessed exit and entry arcs. */
113 gcov_type num_succ;
114 gcov_type num_pred;
115
116 /* Block execution count. */
117 gcov_type count;
118 unsigned flags : 13;
119 unsigned count_valid : 1;
120 unsigned valid_chain : 1;
121 unsigned invalid_chain : 1;
122
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. */
126
127 /* Block is a landing pad for longjmp or throw. */
128 unsigned is_nonlocal_return : 1;
129
130 union
131 {
132 struct
133 {
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
137 file. */
138 unsigned *encoding;
139 unsigned num;
140 } line; /* Valid until blocks are linked onto lines */
141 struct
142 {
143 /* Single line graph cycle workspace. Used for all-blocks
144 mode. */
145 arc_t *arc;
146 unsigned ident;
147 } cycle; /* Used in all-blocks mode, after blocks are linked onto
148 lines. */
149 } u;
150
151 /* Temporary chain for solving graph, and for chaining blocks on one
152 line. */
153 struct block_info *chain;
154
155 } block_t;
156
157 /* Describes a single function. Contains an array of basic blocks. */
158
159 typedef struct function_info
160 {
161 /* Name of function. */
162 char *name;
163 unsigned ident;
164 unsigned checksum;
165
166 /* Array of basic blocks. */
167 block_t *blocks;
168 unsigned num_blocks;
169 unsigned blocks_executed;
170
171 /* Raw arc coverage counts. */
172 gcov_type *counts;
173 unsigned num_counts;
174
175 /* First line number. */
176 unsigned line;
177 struct source_info *src;
178
179 /* Next function in same source file. */
180 struct function_info *line_next;
181
182 /* Next function. */
183 struct function_info *next;
184 } function_t;
185
186 /* Describes coverage of a file or function. */
187
188 typedef struct coverage_info
189 {
190 int lines;
191 int lines_executed;
192
193 int branches;
194 int branches_executed;
195 int branches_taken;
196
197 int calls;
198 int calls_executed;
199
200 char *name;
201 } coverage_t;
202
203 /* Describes a single line of source. Contains a chain of basic blocks
204 with code on it. */
205
206 typedef struct line_info
207 {
208 gcov_type count; /* execution count */
209 union
210 {
211 arc_t *branches; /* branches from blocks that end on this
212 line. Used for branch-counts when not
213 all-blocks mode. */
214 block_t *blocks; /* blocks which start on this line. Used
215 in all-blocks mode. */
216 } u;
217 unsigned exists : 1;
218 } line_t;
219
220 /* Describes a file mentioned in the block graph. Contains an array
221 of line info. */
222
223 typedef struct source_info
224 {
225 /* Name of source file. */
226 char *name;
227 unsigned index;
228 time_t file_time;
229
230 /* Array of line information. */
231 line_t *lines;
232 unsigned num_lines;
233
234 coverage_t coverage;
235
236 /* Functions in this source file. These are in ascending line
237 number order. */
238 function_t *functions;
239
240 /* Next source file. */
241 struct source_info *next;
242 } source_t;
243
244 /* Holds a list of function basic block graphs. */
245
246 static function_t *functions;
247
248 /* This points to the head of the sourcefile structure list. New elements
249 are always prepended. */
250
251 static source_t *sources;
252
253 /* Next index for a source file. */
254
255 static unsigned source_index;
256
257 /* This holds data summary information. */
258
259 static struct gcov_summary object_summary;
260 static unsigned program_count;
261
262 /* Modification time of graph file. */
263
264 static time_t bbg_file_time;
265
266 /* Name and file pointer of the input file for the basic block graph. */
267
268 static char *bbg_file_name;
269
270 /* Stamp of the bbg file */
271 static unsigned bbg_stamp;
272
273 /* Name and file pointer of the input file for the arc count data. */
274
275 static char *da_file_name;
276
277 /* Data file is missing. */
278
279 static int no_data_file;
280
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
284 counts are added. */
285
286 static int multiple_files = 0;
287
288 /* Output branch probabilities. */
289
290 static int flag_branches = 0;
291
292 /* Show unconditional branches too. */
293 static int flag_unconditional = 0;
294
295 /* Output a gcov file if this is true. This is on by default, and can
296 be turned off by the -n option. */
297
298 static int flag_gcov_file = 1;
299
300 /* Output progress indication if this is true. This is off by default
301 and can be turned on by the -d option. */
302
303 static int flag_display_progress = 0;
304
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. */
308
309 static int flag_long_names = 0;
310
311 /* Output count information for every basic block, not merely those
312 that contain line number information. */
313
314 static int flag_all_blocks = 0;
315
316 /* Output summary info for each function. */
317
318 static int flag_function_summary = 0;
319
320 /* Object directory file prefix. This is the directory/file where the
321 graph and data files are looked for, if nonzero. */
322
323 static char *object_directory = 0;
324
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 '^'. */
328
329 static int flag_preserve_paths = 0;
330
331 /* Output the number of times a branch was taken as opposed to the percentage
332 of times it was taken. */
333
334 static int flag_counts = 0;
335
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 **);
358
359 int
360 main (int argc, char **argv)
361 {
362 int argno;
363 int first_arg;
364
365 /* Unlock the stdio streams. */
366 unlock_std_streams ();
367
368 gcc_init_libintl ();
369
370 /* Handle response files. */
371 expandargv (&argc, &argv);
372
373 argno = process_args (argc, argv);
374 if (optind == argc)
375 print_usage (true);
376
377 if (argc - argno > 1)
378 multiple_files = 1;
379
380 first_arg = argno;
381
382 for (; argno != argc; argno++)
383 {
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]);
388 }
389
390 generate_results (multiple_files ? NULL : argv[argc - 1]);
391
392 release_structures ();
393
394 return 0;
395 }
396
397 static void
398 fnotice (FILE *file, const char *cmsgid, ...)
399 {
400 va_list ap;
401
402 va_start (ap, cmsgid);
403 vfprintf (file, _(cmsgid), ap);
404 va_end (ap);
405 }
406 \f
407 /* Print a usage message and exit. If ERROR_P is nonzero, this is an error,
408 otherwise the output of --help. */
409
410 static void
411 print_usage (int error_p)
412 {
413 FILE *file = error_p ? stderr : stdout;
414 int status = error_p ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE;
415
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\
426 source files\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",
433 bug_report_url);
434 exit (status);
435 }
436
437 /* Print version information and exit. */
438
439 static void
440 print_version (void)
441 {
442 fnotice (stdout, "gcov %s%s\n", pkgversion_string, version_string);
443 fprintf (stdout, "Copyright %s 2010 Free Software Foundation, Inc.\n",
444 _("(C)"));
445 fnotice (stdout,
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);
450 }
451
452 static const struct option options[] =
453 {
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' },
467 { 0, 0, 0, 0 }
468 };
469
470 /* Process args, return index to first non-arg. */
471
472 static int
473 process_args (int argc, char **argv)
474 {
475 int opt;
476
477 while ((opt = getopt_long (argc, argv, "abcdfhlno:puv", options, NULL)) != -1)
478 {
479 switch (opt)
480 {
481 case 'a':
482 flag_all_blocks = 1;
483 break;
484 case 'b':
485 flag_branches = 1;
486 break;
487 case 'c':
488 flag_counts = 1;
489 break;
490 case 'f':
491 flag_function_summary = 1;
492 break;
493 case 'h':
494 print_usage (false);
495 /* print_usage will exit. */
496 case 'l':
497 flag_long_names = 1;
498 break;
499 case 'n':
500 flag_gcov_file = 0;
501 break;
502 case 'o':
503 object_directory = optarg;
504 break;
505 case 'p':
506 flag_preserve_paths = 1;
507 break;
508 case 'u':
509 flag_unconditional = 1;
510 break;
511 case 'd':
512 flag_display_progress = 1;
513 break;
514 case 'v':
515 print_version ();
516 /* print_version will exit. */
517 default:
518 print_usage (true);
519 /* print_usage will exit. */
520 }
521 }
522
523 return optind;
524 }
525
526 /* Process a single source file. */
527
528 static void
529 process_file (const char *file_name)
530 {
531 function_t *fn;
532 function_t *fn_p;
533 function_t *old_functions;
534
535 /* Save and clear the list of current functions. They will be appended
536 later. */
537 old_functions = functions;
538 functions = NULL;
539
540 create_file_names (file_name);
541 if (read_graph_file ())
542 return;
543
544 if (!functions)
545 {
546 fnotice (stderr, "%s:no functions found\n", bbg_file_name);
547 return;
548 }
549
550 if (read_count_file ())
551 return;
552
553 for (fn_p = NULL, fn = functions; fn; fn_p = fn, fn = fn->next)
554 solve_flow_graph (fn);
555
556 if (fn_p)
557 fn_p->next = old_functions;
558 }
559
560 static void
561 generate_results (const char *file_name)
562 {
563 source_t *src;
564 function_t *fn;
565
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)
569 {
570 coverage_t coverage;
571
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)
576 {
577 function_summary (&coverage, "Function");
578 fnotice (stdout, "\n");
579 }
580 }
581
582 for (src = sources; src; src = src->next)
583 {
584 accumulate_line_counts (src);
585 function_summary (&src->coverage, "File");
586 if (flag_gcov_file)
587 {
588 char *gcov_file_name = make_gcov_file_name (file_name, src->name);
589 FILE *gcov_file = fopen (gcov_file_name, "w");
590
591 if (gcov_file)
592 {
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);
599 fclose (gcov_file);
600 }
601 else
602 fnotice (stderr, "%s:could not open output file '%s'\n",
603 src->name, gcov_file_name);
604 free (gcov_file_name);
605 }
606 fnotice (stdout, "\n");
607 }
608 }
609
610 /* Release all memory used. */
611
612 static void
613 release_structures (void)
614 {
615 function_t *fn;
616 source_t *src;
617
618 while ((src = sources))
619 {
620 sources = src->next;
621
622 free (src->name);
623 free (src->lines);
624 }
625
626 while ((fn = functions))
627 {
628 unsigned ix;
629 block_t *block;
630
631 functions = fn->next;
632 for (ix = fn->num_blocks, block = fn->blocks; ix--; block++)
633 {
634 arc_t *arc, *arc_n;
635
636 for (arc = block->succ; arc; arc = arc_n)
637 {
638 arc_n = arc->succ_next;
639 free (arc);
640 }
641 }
642 free (fn->blocks);
643 free (fn->counts);
644 }
645 }
646
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. */
654
655 static void
656 create_file_names (const char *file_name)
657 {
658 char *cptr;
659 char *name;
660 int length = strlen (file_name);
661 int base;
662
663 /* Free previous file names. */
664 if (bbg_file_name)
665 free (bbg_file_name);
666 if (da_file_name)
667 free (da_file_name);
668 da_file_name = bbg_file_name = NULL;
669 bbg_file_time = 0;
670 bbg_stamp = 0;
671
672 if (object_directory && object_directory[0])
673 {
674 struct stat status;
675
676 length += strlen (object_directory) + 2;
677 name = XNEWVEC (char, length);
678 name[0] = 0;
679
680 base = !stat (object_directory, &status) && S_ISDIR (status.st_mode);
681 strcat (name, object_directory);
682 if (base && (! IS_DIR_SEPARATOR (name[strlen (name) - 1])))
683 strcat (name, "/");
684 }
685 else
686 {
687 name = XNEWVEC (char, length + 1);
688 name[0] = 0;
689 base = 1;
690 }
691
692 if (base)
693 {
694 /* Append source file name. */
695 const char *cptr = lbasename (file_name);
696 strcat (name, cptr ? cptr : file_name);
697 }
698
699 /* Remove the extension. */
700 cptr = strrchr (name, '.');
701 if (cptr)
702 *cptr = 0;
703
704 length = strlen (name);
705
706 bbg_file_name = XNEWVEC (char, length + strlen (GCOV_NOTE_SUFFIX) + 1);
707 strcpy (bbg_file_name, name);
708 strcpy (bbg_file_name + length, GCOV_NOTE_SUFFIX);
709
710 da_file_name = XNEWVEC (char, length + strlen (GCOV_DATA_SUFFIX) + 1);
711 strcpy (da_file_name, name);
712 strcpy (da_file_name + length, GCOV_DATA_SUFFIX);
713
714 free (name);
715 return;
716 }
717
718 /* Find or create a source file structure for FILE_NAME. Copies
719 FILE_NAME on creation */
720
721 static source_t *
722 find_source (const char *file_name)
723 {
724 source_t *src;
725 struct stat status;
726
727 if (!file_name)
728 file_name = "<unknown>";
729
730 for (src = sources; src; src = src->next)
731 if (!strcmp (file_name, src->name))
732 break;
733
734 if (!src)
735 {
736 src = XCNEW (source_t);
737 src->name = xstrdup (file_name);
738 src->coverage.name = src->name;
739 src->index = source_index++;
740 src->next = sources;
741 sources = src;
742
743 if (!stat (file_name, &status))
744 src->file_time = status.st_mtime;
745 }
746
747 if (src->file_time > bbg_file_time)
748 {
749 static int info_emitted;
750
751 fnotice (stderr, "%s:source file is newer than graph file '%s'\n",
752 src->name, bbg_file_name);
753 if (!info_emitted)
754 {
755 fnotice (stderr,
756 "(the message is only displayed one per source file)\n");
757 info_emitted = 1;
758 }
759 src->file_time = 0;
760 }
761
762 return src;
763 }
764
765 /* Read the graph file. Return nonzero on fatal error. */
766
767 static int
768 read_graph_file (void)
769 {
770 unsigned version;
771 unsigned current_tag = 0;
772 struct function_info *fn = NULL;
773 function_t *old_functions_head = functions;
774 source_t *src = NULL;
775 unsigned ix;
776 unsigned tag;
777
778 if (!gcov_open (bbg_file_name, 1))
779 {
780 fnotice (stderr, "%s:cannot open graph file\n", bbg_file_name);
781 return 1;
782 }
783 bbg_file_time = gcov_time ();
784 if (!gcov_magic (gcov_read_unsigned (), GCOV_NOTE_MAGIC))
785 {
786 fnotice (stderr, "%s:not a gcov graph file\n", bbg_file_name);
787 gcov_close ();
788 return 1;
789 }
790
791 version = gcov_read_unsigned ();
792 if (version != GCOV_VERSION)
793 {
794 char v[4], e[4];
795
796 GCOV_UNSIGNED2STRING (v, version);
797 GCOV_UNSIGNED2STRING (e, GCOV_VERSION);
798
799 fnotice (stderr, "%s:version '%.4s', prefer '%.4s'\n",
800 bbg_file_name, v, e);
801 }
802 bbg_stamp = gcov_read_unsigned ();
803
804 while ((tag = gcov_read_unsigned ()))
805 {
806 unsigned length = gcov_read_unsigned ();
807 gcov_position_t base = gcov_position ();
808
809 if (tag == GCOV_TAG_FUNCTION)
810 {
811 char *function_name;
812 unsigned ident, checksum, lineno;
813 source_t *src;
814 function_t *probe, *prev;
815
816 ident = gcov_read_unsigned ();
817 checksum = gcov_read_unsigned ();
818 function_name = xstrdup (gcov_read_string ());
819 src = find_source (gcov_read_string ());
820 lineno = gcov_read_unsigned ();
821
822 fn = XCNEW (function_t);
823 fn->name = function_name;
824 fn->ident = ident;
825 fn->checksum = checksum;
826 fn->src = src;
827 fn->line = lineno;
828
829 fn->next = functions;
830 functions = fn;
831 current_tag = tag;
832
833 if (lineno >= src->num_lines)
834 src->num_lines = lineno + 1;
835 /* Now insert it into the source file's list of
836 functions. Normally functions will be encountered in
837 ascending order, so a simple scan is quick. */
838 for (probe = src->functions, prev = NULL;
839 probe && probe->line > lineno;
840 prev = probe, probe = probe->line_next)
841 continue;
842 fn->line_next = probe;
843 if (prev)
844 prev->line_next = fn;
845 else
846 src->functions = fn;
847 }
848 else if (fn && tag == GCOV_TAG_BLOCKS)
849 {
850 if (fn->blocks)
851 fnotice (stderr, "%s:already seen blocks for '%s'\n",
852 bbg_file_name, fn->name);
853 else
854 {
855 unsigned ix, num_blocks = GCOV_TAG_BLOCKS_NUM (length);
856 fn->num_blocks = num_blocks;
857
858 fn->blocks = XCNEWVEC (block_t, fn->num_blocks);
859 for (ix = 0; ix != num_blocks; ix++)
860 fn->blocks[ix].flags = gcov_read_unsigned ();
861 }
862 }
863 else if (fn && tag == GCOV_TAG_ARCS)
864 {
865 unsigned src = gcov_read_unsigned ();
866 unsigned num_dests = GCOV_TAG_ARCS_NUM (length);
867
868 if (src >= fn->num_blocks || fn->blocks[src].succ)
869 goto corrupt;
870
871 while (num_dests--)
872 {
873 struct arc_info *arc;
874 unsigned dest = gcov_read_unsigned ();
875 unsigned flags = gcov_read_unsigned ();
876
877 if (dest >= fn->num_blocks)
878 goto corrupt;
879 arc = XCNEW (arc_t);
880
881 arc->dst = &fn->blocks[dest];
882 arc->src = &fn->blocks[src];
883
884 arc->count = 0;
885 arc->count_valid = 0;
886 arc->on_tree = !!(flags & GCOV_ARC_ON_TREE);
887 arc->fake = !!(flags & GCOV_ARC_FAKE);
888 arc->fall_through = !!(flags & GCOV_ARC_FALLTHROUGH);
889
890 arc->succ_next = fn->blocks[src].succ;
891 fn->blocks[src].succ = arc;
892 fn->blocks[src].num_succ++;
893
894 arc->pred_next = fn->blocks[dest].pred;
895 fn->blocks[dest].pred = arc;
896 fn->blocks[dest].num_pred++;
897
898 if (arc->fake)
899 {
900 if (src)
901 {
902 /* Exceptional exit from this function, the
903 source block must be a call. */
904 fn->blocks[src].is_call_site = 1;
905 arc->is_call_non_return = 1;
906 }
907 else
908 {
909 /* Non-local return from a callee of this
910 function. The destination block is a catch or
911 setjmp. */
912 arc->is_nonlocal_return = 1;
913 fn->blocks[dest].is_nonlocal_return = 1;
914 }
915 }
916
917 if (!arc->on_tree)
918 fn->num_counts++;
919 }
920 }
921 else if (fn && tag == GCOV_TAG_LINES)
922 {
923 unsigned blockno = gcov_read_unsigned ();
924 unsigned *line_nos = XCNEWVEC (unsigned, length - 1);
925
926 if (blockno >= fn->num_blocks || fn->blocks[blockno].u.line.encoding)
927 goto corrupt;
928
929 for (ix = 0; ; )
930 {
931 unsigned lineno = gcov_read_unsigned ();
932
933 if (lineno)
934 {
935 if (!ix)
936 {
937 line_nos[ix++] = 0;
938 line_nos[ix++] = src->index;
939 }
940 line_nos[ix++] = lineno;
941 if (lineno >= src->num_lines)
942 src->num_lines = lineno + 1;
943 }
944 else
945 {
946 const char *file_name = gcov_read_string ();
947
948 if (!file_name)
949 break;
950 src = find_source (file_name);
951
952 line_nos[ix++] = 0;
953 line_nos[ix++] = src->index;
954 }
955 }
956
957 fn->blocks[blockno].u.line.encoding = line_nos;
958 fn->blocks[blockno].u.line.num = ix;
959 }
960 else if (current_tag && !GCOV_TAG_IS_SUBTAG (current_tag, tag))
961 {
962 fn = NULL;
963 current_tag = 0;
964 }
965 gcov_sync (base, length);
966 if (gcov_is_error ())
967 {
968 corrupt:;
969 fnotice (stderr, "%s:corrupted\n", bbg_file_name);
970 gcov_close ();
971 return 1;
972 }
973 }
974 gcov_close ();
975
976 /* We built everything backwards, so nreverse them all. */
977
978 /* Reverse sources. Not strictly necessary, but we'll then process
979 them in the 'expected' order. */
980 {
981 source_t *src, *src_p, *src_n;
982
983 for (src_p = NULL, src = sources; src; src_p = src, src = src_n)
984 {
985 src_n = src->next;
986 src->next = src_p;
987 }
988 sources = src_p;
989 }
990
991 /* Reverse functions. */
992 {
993 function_t *fn, *fn_p, *fn_n;
994
995 for (fn_p = old_functions_head, fn = functions;
996 fn != old_functions_head;
997 fn_p = fn, fn = fn_n)
998 {
999 unsigned ix;
1000
1001 fn_n = fn->next;
1002 fn->next = fn_p;
1003
1004 /* Reverse the arcs. */
1005 for (ix = fn->num_blocks; ix--;)
1006 {
1007 arc_t *arc, *arc_p, *arc_n;
1008
1009 for (arc_p = NULL, arc = fn->blocks[ix].succ; arc;
1010 arc_p = arc, arc = arc_n)
1011 {
1012 arc_n = arc->succ_next;
1013 arc->succ_next = arc_p;
1014 }
1015 fn->blocks[ix].succ = arc_p;
1016
1017 for (arc_p = NULL, arc = fn->blocks[ix].pred; arc;
1018 arc_p = arc, arc = arc_n)
1019 {
1020 arc_n = arc->pred_next;
1021 arc->pred_next = arc_p;
1022 }
1023 fn->blocks[ix].pred = arc_p;
1024 }
1025 }
1026 functions = fn_p;
1027 }
1028 return 0;
1029 }
1030
1031 /* Reads profiles from the count file and attach to each
1032 function. Return nonzero if fatal error. */
1033
1034 static int
1035 read_count_file (void)
1036 {
1037 unsigned ix;
1038 unsigned version;
1039 unsigned tag;
1040 function_t *fn = NULL;
1041 int error = 0;
1042
1043 if (!gcov_open (da_file_name, 1))
1044 {
1045 fnotice (stderr, "%s:cannot open data file, assuming not executed\n",
1046 da_file_name);
1047 no_data_file = 1;
1048 return 0;
1049 }
1050 if (!gcov_magic (gcov_read_unsigned (), GCOV_DATA_MAGIC))
1051 {
1052 fnotice (stderr, "%s:not a gcov data file\n", da_file_name);
1053 cleanup:;
1054 gcov_close ();
1055 return 1;
1056 }
1057 version = gcov_read_unsigned ();
1058 if (version != GCOV_VERSION)
1059 {
1060 char v[4], e[4];
1061
1062 GCOV_UNSIGNED2STRING (v, version);
1063 GCOV_UNSIGNED2STRING (e, GCOV_VERSION);
1064
1065 fnotice (stderr, "%s:version '%.4s', prefer version '%.4s'\n",
1066 da_file_name, v, e);
1067 }
1068 tag = gcov_read_unsigned ();
1069 if (tag != bbg_stamp)
1070 {
1071 fnotice (stderr, "%s:stamp mismatch with graph file\n", da_file_name);
1072 goto cleanup;
1073 }
1074
1075 while ((tag = gcov_read_unsigned ()))
1076 {
1077 unsigned length = gcov_read_unsigned ();
1078 unsigned long base = gcov_position ();
1079
1080 if (tag == GCOV_TAG_OBJECT_SUMMARY)
1081 gcov_read_summary (&object_summary);
1082 else if (tag == GCOV_TAG_PROGRAM_SUMMARY)
1083 program_count++;
1084 else if (tag == GCOV_TAG_FUNCTION)
1085 {
1086 {
1087 unsigned ident = gcov_read_unsigned ();
1088 struct function_info *fn_n = functions;
1089
1090 /* Try to find the function in the list.
1091 To speed up the search, first start from the last function
1092 found. */
1093 for (fn = fn ? fn->next : NULL; ; fn = fn->next)
1094 {
1095 if (fn)
1096 ;
1097 else if ((fn = fn_n))
1098 fn_n = NULL;
1099 else
1100 {
1101 fnotice (stderr, "%s:unknown function '%u'\n",
1102 da_file_name, ident);
1103 break;
1104 }
1105 if (fn->ident == ident)
1106 break;
1107 }
1108 }
1109
1110 if (!fn)
1111 ;
1112 else if (gcov_read_unsigned () != fn->checksum)
1113 {
1114 mismatch:;
1115 fnotice (stderr, "%s:profile mismatch for '%s'\n",
1116 da_file_name, fn->name);
1117 goto cleanup;
1118 }
1119 }
1120 else if (tag == GCOV_TAG_FOR_COUNTER (GCOV_COUNTER_ARCS) && fn)
1121 {
1122 if (length != GCOV_TAG_COUNTER_LENGTH (fn->num_counts))
1123 goto mismatch;
1124
1125 if (!fn->counts)
1126 fn->counts = XCNEWVEC (gcov_type, fn->num_counts);
1127
1128 for (ix = 0; ix != fn->num_counts; ix++)
1129 fn->counts[ix] += gcov_read_counter ();
1130 }
1131 gcov_sync (base, length);
1132 if ((error = gcov_is_error ()))
1133 {
1134 fnotice (stderr, error < 0 ? "%s:overflowed\n" : "%s:corrupted\n",
1135 da_file_name);
1136 goto cleanup;
1137 }
1138 }
1139
1140 gcov_close ();
1141 return 0;
1142 }
1143
1144 /* Solve the flow graph. Propagate counts from the instrumented arcs
1145 to the blocks and the uninstrumented arcs. */
1146
1147 static void
1148 solve_flow_graph (function_t *fn)
1149 {
1150 unsigned ix;
1151 arc_t *arc;
1152 gcov_type *count_ptr = fn->counts;
1153 block_t *blk;
1154 block_t *valid_blocks = NULL; /* valid, but unpropagated blocks. */
1155 block_t *invalid_blocks = NULL; /* invalid, but inferable blocks. */
1156
1157 if (fn->num_blocks < 2)
1158 fnotice (stderr, "%s:'%s' lacks entry and/or exit blocks\n",
1159 bbg_file_name, fn->name);
1160 else
1161 {
1162 if (fn->blocks[0].num_pred)
1163 fnotice (stderr, "%s:'%s' has arcs to entry block\n",
1164 bbg_file_name, fn->name);
1165 else
1166 /* We can't deduce the entry block counts from the lack of
1167 predecessors. */
1168 fn->blocks[0].num_pred = ~(unsigned)0;
1169
1170 if (fn->blocks[fn->num_blocks - 1].num_succ)
1171 fnotice (stderr, "%s:'%s' has arcs from exit block\n",
1172 bbg_file_name, fn->name);
1173 else
1174 /* Likewise, we can't deduce exit block counts from the lack
1175 of its successors. */
1176 fn->blocks[fn->num_blocks - 1].num_succ = ~(unsigned)0;
1177 }
1178
1179 /* Propagate the measured counts, this must be done in the same
1180 order as the code in profile.c */
1181 for (ix = 0, blk = fn->blocks; ix != fn->num_blocks; ix++, blk++)
1182 {
1183 block_t const *prev_dst = NULL;
1184 int out_of_order = 0;
1185 int non_fake_succ = 0;
1186
1187 for (arc = blk->succ; arc; arc = arc->succ_next)
1188 {
1189 if (!arc->fake)
1190 non_fake_succ++;
1191
1192 if (!arc->on_tree)
1193 {
1194 if (count_ptr)
1195 arc->count = *count_ptr++;
1196 arc->count_valid = 1;
1197 blk->num_succ--;
1198 arc->dst->num_pred--;
1199 }
1200 if (prev_dst && prev_dst > arc->dst)
1201 out_of_order = 1;
1202 prev_dst = arc->dst;
1203 }
1204 if (non_fake_succ == 1)
1205 {
1206 /* If there is only one non-fake exit, it is an
1207 unconditional branch. */
1208 for (arc = blk->succ; arc; arc = arc->succ_next)
1209 if (!arc->fake)
1210 {
1211 arc->is_unconditional = 1;
1212 /* If this block is instrumenting a call, it might be
1213 an artificial block. It is not artificial if it has
1214 a non-fallthrough exit, or the destination of this
1215 arc has more than one entry. Mark the destination
1216 block as a return site, if none of those conditions
1217 hold. */
1218 if (blk->is_call_site && arc->fall_through
1219 && arc->dst->pred == arc && !arc->pred_next)
1220 arc->dst->is_call_return = 1;
1221 }
1222 }
1223
1224 /* Sort the successor arcs into ascending dst order. profile.c
1225 normally produces arcs in the right order, but sometimes with
1226 one or two out of order. We're not using a particularly
1227 smart sort. */
1228 if (out_of_order)
1229 {
1230 arc_t *start = blk->succ;
1231 unsigned changes = 1;
1232
1233 while (changes)
1234 {
1235 arc_t *arc, *arc_p, *arc_n;
1236
1237 changes = 0;
1238 for (arc_p = NULL, arc = start; (arc_n = arc->succ_next);)
1239 {
1240 if (arc->dst > arc_n->dst)
1241 {
1242 changes = 1;
1243 if (arc_p)
1244 arc_p->succ_next = arc_n;
1245 else
1246 start = arc_n;
1247 arc->succ_next = arc_n->succ_next;
1248 arc_n->succ_next = arc;
1249 arc_p = arc_n;
1250 }
1251 else
1252 {
1253 arc_p = arc;
1254 arc = arc_n;
1255 }
1256 }
1257 }
1258 blk->succ = start;
1259 }
1260
1261 /* Place it on the invalid chain, it will be ignored if that's
1262 wrong. */
1263 blk->invalid_chain = 1;
1264 blk->chain = invalid_blocks;
1265 invalid_blocks = blk;
1266 }
1267
1268 while (invalid_blocks || valid_blocks)
1269 {
1270 while ((blk = invalid_blocks))
1271 {
1272 gcov_type total = 0;
1273 const arc_t *arc;
1274
1275 invalid_blocks = blk->chain;
1276 blk->invalid_chain = 0;
1277 if (!blk->num_succ)
1278 for (arc = blk->succ; arc; arc = arc->succ_next)
1279 total += arc->count;
1280 else if (!blk->num_pred)
1281 for (arc = blk->pred; arc; arc = arc->pred_next)
1282 total += arc->count;
1283 else
1284 continue;
1285
1286 blk->count = total;
1287 blk->count_valid = 1;
1288 blk->chain = valid_blocks;
1289 blk->valid_chain = 1;
1290 valid_blocks = blk;
1291 }
1292 while ((blk = valid_blocks))
1293 {
1294 gcov_type total;
1295 arc_t *arc, *inv_arc;
1296
1297 valid_blocks = blk->chain;
1298 blk->valid_chain = 0;
1299 if (blk->num_succ == 1)
1300 {
1301 block_t *dst;
1302
1303 total = blk->count;
1304 inv_arc = NULL;
1305 for (arc = blk->succ; arc; arc = arc->succ_next)
1306 {
1307 total -= arc->count;
1308 if (!arc->count_valid)
1309 inv_arc = arc;
1310 }
1311 dst = inv_arc->dst;
1312 inv_arc->count_valid = 1;
1313 inv_arc->count = total;
1314 blk->num_succ--;
1315 dst->num_pred--;
1316 if (dst->count_valid)
1317 {
1318 if (dst->num_pred == 1 && !dst->valid_chain)
1319 {
1320 dst->chain = valid_blocks;
1321 dst->valid_chain = 1;
1322 valid_blocks = dst;
1323 }
1324 }
1325 else
1326 {
1327 if (!dst->num_pred && !dst->invalid_chain)
1328 {
1329 dst->chain = invalid_blocks;
1330 dst->invalid_chain = 1;
1331 invalid_blocks = dst;
1332 }
1333 }
1334 }
1335 if (blk->num_pred == 1)
1336 {
1337 block_t *src;
1338
1339 total = blk->count;
1340 inv_arc = NULL;
1341 for (arc = blk->pred; arc; arc = arc->pred_next)
1342 {
1343 total -= arc->count;
1344 if (!arc->count_valid)
1345 inv_arc = arc;
1346 }
1347 src = inv_arc->src;
1348 inv_arc->count_valid = 1;
1349 inv_arc->count = total;
1350 blk->num_pred--;
1351 src->num_succ--;
1352 if (src->count_valid)
1353 {
1354 if (src->num_succ == 1 && !src->valid_chain)
1355 {
1356 src->chain = valid_blocks;
1357 src->valid_chain = 1;
1358 valid_blocks = src;
1359 }
1360 }
1361 else
1362 {
1363 if (!src->num_succ && !src->invalid_chain)
1364 {
1365 src->chain = invalid_blocks;
1366 src->invalid_chain = 1;
1367 invalid_blocks = src;
1368 }
1369 }
1370 }
1371 }
1372 }
1373
1374 /* If the graph has been correctly solved, every block will have a
1375 valid count. */
1376 for (ix = 0; ix < fn->num_blocks; ix++)
1377 if (!fn->blocks[ix].count_valid)
1378 {
1379 fnotice (stderr, "%s:graph is unsolvable for '%s'\n",
1380 bbg_file_name, fn->name);
1381 break;
1382 }
1383 }
1384
1385 \f
1386
1387 /* Increment totals in COVERAGE according to arc ARC. */
1388
1389 static void
1390 add_branch_counts (coverage_t *coverage, const arc_t *arc)
1391 {
1392 if (arc->is_call_non_return)
1393 {
1394 coverage->calls++;
1395 if (arc->src->count)
1396 coverage->calls_executed++;
1397 }
1398 else if (!arc->is_unconditional)
1399 {
1400 coverage->branches++;
1401 if (arc->src->count)
1402 coverage->branches_executed++;
1403 if (arc->count)
1404 coverage->branches_taken++;
1405 }
1406 }
1407
1408 /* Format a HOST_WIDE_INT as either a percent ratio, or absolute
1409 count. If dp >= 0, format TOP/BOTTOM * 100 to DP decimal places.
1410 If DP is zero, no decimal point is printed. Only print 100% when
1411 TOP==BOTTOM and only print 0% when TOP=0. If dp < 0, then simply
1412 format TOP. Return pointer to a static string. */
1413
1414 static char const *
1415 format_gcov (gcov_type top, gcov_type bottom, int dp)
1416 {
1417 static char buffer[20];
1418
1419 if (dp >= 0)
1420 {
1421 float ratio = bottom ? (float)top / bottom : 0;
1422 int ix;
1423 unsigned limit = 100;
1424 unsigned percent;
1425
1426 for (ix = dp; ix--; )
1427 limit *= 10;
1428
1429 percent = (unsigned) (ratio * limit + (float)0.5);
1430 if (percent <= 0 && top)
1431 percent = 1;
1432 else if (percent >= limit && top != bottom)
1433 percent = limit - 1;
1434 ix = sprintf (buffer, "%.*u%%", dp + 1, percent);
1435 if (dp)
1436 {
1437 dp++;
1438 do
1439 {
1440 buffer[ix+1] = buffer[ix];
1441 ix--;
1442 }
1443 while (dp--);
1444 buffer[ix + 1] = '.';
1445 }
1446 }
1447 else
1448 sprintf (buffer, HOST_WIDEST_INT_PRINT_DEC, (HOST_WIDEST_INT)top);
1449
1450 return buffer;
1451 }
1452
1453
1454 /* Output summary info for a function. */
1455
1456 static void
1457 function_summary (const coverage_t *coverage, const char *title)
1458 {
1459 fnotice (stdout, "%s '%s'\n", title, coverage->name);
1460
1461 if (coverage->lines)
1462 fnotice (stdout, "Lines executed:%s of %d\n",
1463 format_gcov (coverage->lines_executed, coverage->lines, 2),
1464 coverage->lines);
1465 else
1466 fnotice (stdout, "No executable lines\n");
1467
1468 if (flag_branches)
1469 {
1470 if (coverage->branches)
1471 {
1472 fnotice (stdout, "Branches executed:%s of %d\n",
1473 format_gcov (coverage->branches_executed,
1474 coverage->branches, 2),
1475 coverage->branches);
1476 fnotice (stdout, "Taken at least once:%s of %d\n",
1477 format_gcov (coverage->branches_taken,
1478 coverage->branches, 2),
1479 coverage->branches);
1480 }
1481 else
1482 fnotice (stdout, "No branches\n");
1483 if (coverage->calls)
1484 fnotice (stdout, "Calls executed:%s of %d\n",
1485 format_gcov (coverage->calls_executed, coverage->calls, 2),
1486 coverage->calls);
1487 else
1488 fnotice (stdout, "No calls\n");
1489 }
1490 }
1491
1492 /* Generate an output file name. LONG_OUTPUT_NAMES and PRESERVE_PATHS
1493 affect name generation. With preserve_paths we create a filename
1494 from all path components of the source file, replacing '/' with
1495 '#', without it we simply take the basename component. With
1496 long_output_names we prepend the processed name of the input file
1497 to each output name (except when the current source file is the
1498 input file, so you don't get a double concatenation). The two
1499 components are separated by '##'. Also '.' filename components are
1500 removed and '..' components are renamed to '^'. */
1501
1502 static char *
1503 make_gcov_file_name (const char *input_name, const char *src_name)
1504 {
1505 const char *cptr;
1506 char *name;
1507
1508 if (flag_long_names && input_name && strcmp (src_name, input_name))
1509 {
1510 name = XNEWVEC (char, strlen (src_name) + strlen (input_name) + 10);
1511 name[0] = 0;
1512 /* Generate the input filename part. */
1513 cptr = flag_preserve_paths ? NULL : lbasename (input_name);
1514 strcat (name, cptr ? cptr : input_name);
1515 strcat (name, "##");
1516 }
1517 else
1518 {
1519 name = XNEWVEC (char, strlen (src_name) + 10);
1520 name[0] = 0;
1521 }
1522
1523 /* Generate the source filename part. */
1524
1525 cptr = flag_preserve_paths ? NULL : lbasename (src_name);
1526 strcat (name, cptr ? cptr : src_name);
1527
1528 if (flag_preserve_paths)
1529 {
1530 /* Convert '/' and '\' to '#', remove '/./', convert '/../' to '/^/',
1531 convert ':' to '~' on DOS based file system. */
1532 char *pnew = name, *pold = name;
1533
1534 /* First check for leading drive separator. */
1535
1536 while (*pold != '\0')
1537 {
1538 if (*pold == '/' || *pold == '\\')
1539 {
1540 *pnew++ = '#';
1541 pold++;
1542 }
1543 #if defined (HAVE_DOS_BASED_FILE_SYSTEM)
1544 else if (*pold == ':')
1545 {
1546 *pnew++ = '~';
1547 pold++;
1548 }
1549 #endif
1550 else if ((*pold == '/' && strstr (pold, "/./") == pold)
1551 || (*pold == '\\' && strstr (pold, "\\.\\") == pold))
1552 pold += 3;
1553 else if (*pold == '/' && strstr (pold, "/../") == pold)
1554 {
1555 strcpy (pnew, "/^/");
1556 pnew += 3;
1557 pold += 4;
1558 }
1559 else if (*pold == '\\' && strstr (pold, "\\..\\") == pold)
1560 {
1561 strcpy (pnew, "\\^\\");
1562 pnew += 3;
1563 pold += 4;
1564 }
1565 else
1566 *pnew++ = *pold++;
1567 }
1568
1569 *pnew = '\0';
1570 }
1571
1572 strcat (name, ".gcov");
1573 return name;
1574 }
1575
1576 /* Scan through the bb_data for each line in the block, increment
1577 the line number execution count indicated by the execution count of
1578 the appropriate basic block. */
1579
1580 static void
1581 add_line_counts (coverage_t *coverage, function_t *fn)
1582 {
1583 unsigned ix;
1584 line_t *line = NULL; /* This is propagated from one iteration to the
1585 next. */
1586
1587 /* Scan each basic block. */
1588 for (ix = 0; ix != fn->num_blocks; ix++)
1589 {
1590 block_t *block = &fn->blocks[ix];
1591 unsigned *encoding;
1592 const source_t *src = NULL;
1593 unsigned jx;
1594
1595 if (block->count && ix && ix + 1 != fn->num_blocks)
1596 fn->blocks_executed++;
1597 for (jx = 0, encoding = block->u.line.encoding;
1598 jx != block->u.line.num; jx++, encoding++)
1599 if (!*encoding)
1600 {
1601 unsigned src_n = *++encoding;
1602
1603 for (src = sources; src->index != src_n; src = src->next)
1604 continue;
1605 jx++;
1606 }
1607 else
1608 {
1609 line = &src->lines[*encoding];
1610
1611 if (coverage)
1612 {
1613 if (!line->exists)
1614 coverage->lines++;
1615 if (!line->count && block->count)
1616 coverage->lines_executed++;
1617 }
1618 line->exists = 1;
1619 line->count += block->count;
1620 }
1621 free (block->u.line.encoding);
1622 block->u.cycle.arc = NULL;
1623 block->u.cycle.ident = ~0U;
1624
1625 if (!ix || ix + 1 == fn->num_blocks)
1626 /* Entry or exit block */;
1627 else if (flag_all_blocks)
1628 {
1629 line_t *block_line = line ? line : &fn->src->lines[fn->line];
1630
1631 block->chain = block_line->u.blocks;
1632 block_line->u.blocks = block;
1633 }
1634 else if (flag_branches)
1635 {
1636 arc_t *arc;
1637
1638 for (arc = block->succ; arc; arc = arc->succ_next)
1639 {
1640 arc->line_next = line->u.branches;
1641 line->u.branches = arc;
1642 if (coverage && !arc->is_unconditional)
1643 add_branch_counts (coverage, arc);
1644 }
1645 }
1646 }
1647 if (!line)
1648 fnotice (stderr, "%s:no lines for '%s'\n", bbg_file_name, fn->name);
1649 }
1650
1651 /* Accumulate the line counts of a file. */
1652
1653 static void
1654 accumulate_line_counts (source_t *src)
1655 {
1656 line_t *line;
1657 function_t *fn, *fn_p, *fn_n;
1658 unsigned ix;
1659
1660 /* Reverse the function order. */
1661 for (fn = src->functions, fn_p = NULL; fn;
1662 fn_p = fn, fn = fn_n)
1663 {
1664 fn_n = fn->line_next;
1665 fn->line_next = fn_p;
1666 }
1667 src->functions = fn_p;
1668
1669 for (ix = src->num_lines, line = src->lines; ix--; line++)
1670 {
1671 if (!flag_all_blocks)
1672 {
1673 arc_t *arc, *arc_p, *arc_n;
1674
1675 /* Total and reverse the branch information. */
1676 for (arc = line->u.branches, arc_p = NULL; arc;
1677 arc_p = arc, arc = arc_n)
1678 {
1679 arc_n = arc->line_next;
1680 arc->line_next = arc_p;
1681
1682 add_branch_counts (&src->coverage, arc);
1683 }
1684 line->u.branches = arc_p;
1685 }
1686 else if (line->u.blocks)
1687 {
1688 /* The user expects the line count to be the number of times
1689 a line has been executed. Simply summing the block count
1690 will give an artificially high number. The Right Thing
1691 is to sum the entry counts to the graph of blocks on this
1692 line, then find the elementary cycles of the local graph
1693 and add the transition counts of those cycles. */
1694 block_t *block, *block_p, *block_n;
1695 gcov_type count = 0;
1696
1697 /* Reverse the block information. */
1698 for (block = line->u.blocks, block_p = NULL; block;
1699 block_p = block, block = block_n)
1700 {
1701 block_n = block->chain;
1702 block->chain = block_p;
1703 block->u.cycle.ident = ix;
1704 }
1705 line->u.blocks = block_p;
1706
1707 /* Sum the entry arcs. */
1708 for (block = line->u.blocks; block; block = block->chain)
1709 {
1710 arc_t *arc;
1711
1712 for (arc = block->pred; arc; arc = arc->pred_next)
1713 {
1714 if (arc->src->u.cycle.ident != ix)
1715 count += arc->count;
1716 if (flag_branches)
1717 add_branch_counts (&src->coverage, arc);
1718 }
1719
1720 /* Initialize the cs_count. */
1721 for (arc = block->succ; arc; arc = arc->succ_next)
1722 arc->cs_count = arc->count;
1723 }
1724
1725 /* Find the loops. This uses the algorithm described in
1726 Tiernan 'An Efficient Search Algorithm to Find the
1727 Elementary Circuits of a Graph', CACM Dec 1970. We hold
1728 the P array by having each block point to the arc that
1729 connects to the previous block. The H array is implicitly
1730 held because of the arc ordering, and the block's
1731 previous arc pointer.
1732
1733 Although the algorithm is O(N^3) for highly connected
1734 graphs, at worst we'll have O(N^2), as most blocks have
1735 only one or two exits. Most graphs will be small.
1736
1737 For each loop we find, locate the arc with the smallest
1738 transition count, and add that to the cumulative
1739 count. Decrease flow over the cycle and remove the arc
1740 from consideration. */
1741 for (block = line->u.blocks; block; block = block->chain)
1742 {
1743 block_t *head = block;
1744 arc_t *arc;
1745
1746 next_vertex:;
1747 arc = head->succ;
1748 current_vertex:;
1749 while (arc)
1750 {
1751 block_t *dst = arc->dst;
1752 if (/* Already used that arc. */
1753 arc->cycle
1754 /* Not to same graph, or before first vertex. */
1755 || dst->u.cycle.ident != ix
1756 /* Already in path. */
1757 || dst->u.cycle.arc)
1758 {
1759 arc = arc->succ_next;
1760 continue;
1761 }
1762
1763 if (dst == block)
1764 {
1765 /* Found a closing arc. */
1766 gcov_type cycle_count = arc->cs_count;
1767 arc_t *cycle_arc = arc;
1768 arc_t *probe_arc;
1769
1770 /* Locate the smallest arc count of the loop. */
1771 for (dst = head; (probe_arc = dst->u.cycle.arc);
1772 dst = probe_arc->src)
1773 if (cycle_count > probe_arc->cs_count)
1774 {
1775 cycle_count = probe_arc->cs_count;
1776 cycle_arc = probe_arc;
1777 }
1778
1779 count += cycle_count;
1780 cycle_arc->cycle = 1;
1781
1782 /* Remove the flow from the cycle. */
1783 arc->cs_count -= cycle_count;
1784 for (dst = head; (probe_arc = dst->u.cycle.arc);
1785 dst = probe_arc->src)
1786 probe_arc->cs_count -= cycle_count;
1787
1788 /* Unwind to the cyclic arc. */
1789 while (head != cycle_arc->src)
1790 {
1791 arc = head->u.cycle.arc;
1792 head->u.cycle.arc = NULL;
1793 head = arc->src;
1794 }
1795 /* Move on. */
1796 arc = arc->succ_next;
1797 continue;
1798 }
1799
1800 /* Add new block to chain. */
1801 dst->u.cycle.arc = arc;
1802 head = dst;
1803 goto next_vertex;
1804 }
1805 /* We could not add another vertex to the path. Remove
1806 the last vertex from the list. */
1807 arc = head->u.cycle.arc;
1808 if (arc)
1809 {
1810 /* It was not the first vertex. Move onto next arc. */
1811 head->u.cycle.arc = NULL;
1812 head = arc->src;
1813 arc = arc->succ_next;
1814 goto current_vertex;
1815 }
1816 /* Mark this block as unusable. */
1817 block->u.cycle.ident = ~0U;
1818 }
1819
1820 line->count = count;
1821 }
1822
1823 if (line->exists)
1824 {
1825 src->coverage.lines++;
1826 if (line->count)
1827 src->coverage.lines_executed++;
1828 }
1829 }
1830 }
1831
1832 /* Output information about ARC number IX. Returns nonzero if
1833 anything is output. */
1834
1835 static int
1836 output_branch_count (FILE *gcov_file, int ix, const arc_t *arc)
1837 {
1838
1839 if (arc->is_call_non_return)
1840 {
1841 if (arc->src->count)
1842 {
1843 fnotice (gcov_file, "call %2d returned %s\n", ix,
1844 format_gcov (arc->src->count - arc->count,
1845 arc->src->count, -flag_counts));
1846 }
1847 else
1848 fnotice (gcov_file, "call %2d never executed\n", ix);
1849 }
1850 else if (!arc->is_unconditional)
1851 {
1852 if (arc->src->count)
1853 fnotice (gcov_file, "branch %2d taken %s%s\n", ix,
1854 format_gcov (arc->count, arc->src->count, -flag_counts),
1855 arc->fall_through ? " (fallthrough)" : "");
1856 else
1857 fnotice (gcov_file, "branch %2d never executed\n", ix);
1858 }
1859 else if (flag_unconditional && !arc->dst->is_call_return)
1860 {
1861 if (arc->src->count)
1862 fnotice (gcov_file, "unconditional %2d taken %s\n", ix,
1863 format_gcov (arc->count, arc->src->count, -flag_counts));
1864 else
1865 fnotice (gcov_file, "unconditional %2d never executed\n", ix);
1866 }
1867 else
1868 return 0;
1869 return 1;
1870
1871 }
1872
1873 /* Read in the source file one line at a time, and output that line to
1874 the gcov file preceded by its execution count and other
1875 information. */
1876
1877 static void
1878 output_lines (FILE *gcov_file, const source_t *src)
1879 {
1880 FILE *source_file;
1881 unsigned line_num; /* current line number. */
1882 const line_t *line; /* current line info ptr. */
1883 char string[STRING_SIZE]; /* line buffer. */
1884 char const *retval = ""; /* status of source file reading. */
1885 function_t *fn = NULL;
1886
1887 fprintf (gcov_file, "%9s:%5d:Source:%s\n", "-", 0, src->name);
1888 if (!multiple_files)
1889 {
1890 fprintf (gcov_file, "%9s:%5d:Graph:%s\n", "-", 0, bbg_file_name);
1891 fprintf (gcov_file, "%9s:%5d:Data:%s\n", "-", 0,
1892 no_data_file ? "-" : da_file_name);
1893 fprintf (gcov_file, "%9s:%5d:Runs:%u\n", "-", 0,
1894 object_summary.ctrs[GCOV_COUNTER_ARCS].runs);
1895 }
1896 fprintf (gcov_file, "%9s:%5d:Programs:%u\n", "-", 0, program_count);
1897
1898 source_file = fopen (src->name, "r");
1899 if (!source_file)
1900 {
1901 fnotice (stderr, "%s:cannot open source file\n", src->name);
1902 retval = NULL;
1903 }
1904 else if (src->file_time == 0)
1905 fprintf (gcov_file, "%9s:%5d:Source is newer than graph\n", "-", 0);
1906
1907 if (flag_branches)
1908 fn = src->functions;
1909
1910 for (line_num = 1, line = &src->lines[line_num];
1911 line_num < src->num_lines; line_num++, line++)
1912 {
1913 for (; fn && fn->line == line_num; fn = fn->line_next)
1914 {
1915 arc_t *arc = fn->blocks[fn->num_blocks - 1].pred;
1916 gcov_type return_count = fn->blocks[fn->num_blocks - 1].count;
1917
1918 for (; arc; arc = arc->pred_next)
1919 if (arc->fake)
1920 return_count -= arc->count;
1921
1922 fprintf (gcov_file, "function %s", fn->name);
1923 fprintf (gcov_file, " called %s",
1924 format_gcov (fn->blocks[0].count, 0, -1));
1925 fprintf (gcov_file, " returned %s",
1926 format_gcov (return_count, fn->blocks[0].count, 0));
1927 fprintf (gcov_file, " blocks executed %s",
1928 format_gcov (fn->blocks_executed, fn->num_blocks - 2, 0));
1929 fprintf (gcov_file, "\n");
1930 }
1931
1932 /* For lines which don't exist in the .bb file, print '-' before
1933 the source line. For lines which exist but were never
1934 executed, print '#####' before the source line. Otherwise,
1935 print the execution count before the source line. There are
1936 16 spaces of indentation added before the source line so that
1937 tabs won't be messed up. */
1938 fprintf (gcov_file, "%9s:%5u:",
1939 !line->exists ? "-" : !line->count ? "#####"
1940 : format_gcov (line->count, 0, -1), line_num);
1941
1942 if (retval)
1943 {
1944 /* Copy source line. */
1945 do
1946 {
1947 retval = fgets (string, STRING_SIZE, source_file);
1948 if (!retval)
1949 break;
1950 fputs (retval, gcov_file);
1951 }
1952 while (!retval[0] || retval[strlen (retval) - 1] != '\n');
1953 }
1954 if (!retval)
1955 fputs ("/*EOF*/\n", gcov_file);
1956
1957 if (flag_all_blocks)
1958 {
1959 block_t *block;
1960 arc_t *arc;
1961 int ix, jx;
1962
1963 for (ix = jx = 0, block = line->u.blocks; block;
1964 block = block->chain)
1965 {
1966 if (!block->is_call_return)
1967 fprintf (gcov_file, "%9s:%5u-block %2d\n",
1968 !line->exists ? "-" : !block->count ? "$$$$$"
1969 : format_gcov (block->count, 0, -1),
1970 line_num, ix++);
1971 if (flag_branches)
1972 for (arc = block->succ; arc; arc = arc->succ_next)
1973 jx += output_branch_count (gcov_file, jx, arc);
1974 }
1975 }
1976 else if (flag_branches)
1977 {
1978 int ix;
1979 arc_t *arc;
1980
1981 for (ix = 0, arc = line->u.branches; arc; arc = arc->line_next)
1982 ix += output_branch_count (gcov_file, ix, arc);
1983 }
1984 }
1985
1986 /* Handle all remaining source lines. There may be lines after the
1987 last line of code. */
1988 if (retval)
1989 {
1990 for (; (retval = fgets (string, STRING_SIZE, source_file)); line_num++)
1991 {
1992 fprintf (gcov_file, "%9s:%5u:%s", "-", line_num, retval);
1993
1994 while (!retval[0] || retval[strlen (retval) - 1] != '\n')
1995 {
1996 retval = fgets (string, STRING_SIZE, source_file);
1997 if (!retval)
1998 break;
1999 fputs (retval, gcov_file);
2000 }
2001 }
2002 }
2003
2004 if (source_file)
2005 fclose (source_file);
2006 }