xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/gcov.c (revision e6c7e151de239c49d2e38720a061ed9d1fa99309)
1 /* Gcov.c: prepend line execution counts and branch probabilities to a
2    source file.
3    Copyright (C) 1990-2017 Free Software Foundation, Inc.
4    Contributed by James E. Wilson of Cygnus Support.
5    Mangled by Bob Manson of Cygnus Support.
6    Mangled further by Nathan Sidwell <nathan@codesourcery.com>
7 
8 Gcov is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
11 any later version.
12 
13 Gcov is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 GNU General Public License for more details.
17 
18 You should have received a copy of the GNU General Public License
19 along with Gcov; see the file COPYING3.  If not see
20 <http://www.gnu.org/licenses/>.  */
21 
22 /* ??? Print a list of the ten blocks with the highest execution counts,
23    and list the line numbers corresponding to those blocks.  Also, perhaps
24    list the line numbers with the highest execution counts, only printing
25    the first if there are several which are all listed in the same block.  */
26 
27 /* ??? Should have an option to print the number of basic blocks, and the
28    percent of them that are covered.  */
29 
30 /* Need an option to show individual block counts, and show
31    probabilities of fall through arcs.  */
32 
33 #include "config.h"
34 #define INCLUDE_ALGORITHM
35 #define INCLUDE_VECTOR
36 #include "system.h"
37 #include "coretypes.h"
38 #include "tm.h"
39 #include "intl.h"
40 #include "diagnostic.h"
41 #include "version.h"
42 #include "demangle.h"
43 
44 #include <getopt.h>
45 
46 #include "md5.h"
47 
48 using namespace std;
49 
50 #define IN_GCOV 1
51 #include "gcov-io.h"
52 #include "gcov-io.c"
53 
54 /* The gcno file is generated by -ftest-coverage option. The gcda file is
55    generated by a program compiled with -fprofile-arcs. Their formats
56    are documented in gcov-io.h.  */
57 
58 /* The functions in this file for creating and solution program flow graphs
59    are very similar to functions in the gcc source file profile.c.  In
60    some places we make use of the knowledge of how profile.c works to
61    select particular algorithms here.  */
62 
63 /* The code validates that the profile information read in corresponds
64    to the code currently being compiled.  Rather than checking for
65    identical files, the code below compares a checksum on the CFG
66    (based on the order of basic blocks and the arcs in the CFG).  If
67    the CFG checksum in the gcda file match the CFG checksum in the
68    gcno file, the profile data will be used.  */
69 
70 /* This is the size of the buffer used to read in source file lines.  */
71 
72 struct function_info;
73 struct block_info;
74 struct source_info;
75 
76 /* Describes an arc between two basic blocks.  */
77 
78 typedef struct arc_info
79 {
80   /* source and destination blocks.  */
81   struct block_info *src;
82   struct block_info *dst;
83 
84   /* transition counts.  */
85   gcov_type count;
86   /* used in cycle search, so that we do not clobber original counts.  */
87   gcov_type cs_count;
88 
89   unsigned int count_valid : 1;
90   unsigned int on_tree : 1;
91   unsigned int fake : 1;
92   unsigned int fall_through : 1;
93 
94   /* Arc to a catch handler.  */
95   unsigned int is_throw : 1;
96 
97   /* Arc is for a function that abnormally returns.  */
98   unsigned int is_call_non_return : 1;
99 
100   /* Arc is for catch/setjmp.  */
101   unsigned int is_nonlocal_return : 1;
102 
103   /* Is an unconditional branch.  */
104   unsigned int is_unconditional : 1;
105 
106   /* Loop making arc.  */
107   unsigned int cycle : 1;
108 
109   /* Next branch on line.  */
110   struct arc_info *line_next;
111 
112   /* Links to next arc on src and dst lists.  */
113   struct arc_info *succ_next;
114   struct arc_info *pred_next;
115 } arc_t;
116 
117 /* Describes a basic block. Contains lists of arcs to successor and
118    predecessor blocks.  */
119 
120 typedef struct block_info
121 {
122   /* Chain of exit and entry arcs.  */
123   arc_t *succ;
124   arc_t *pred;
125 
126   /* Number of unprocessed exit and entry arcs.  */
127   gcov_type num_succ;
128   gcov_type num_pred;
129 
130   /* Block execution count.  */
131   gcov_type count;
132   unsigned flags : 12;
133   unsigned count_valid : 1;
134   unsigned valid_chain : 1;
135   unsigned invalid_chain : 1;
136   unsigned exceptional : 1;
137 
138   /* Block is a call instrumenting site.  */
139   unsigned is_call_site : 1; /* Does the call.  */
140   unsigned is_call_return : 1; /* Is the return.  */
141 
142   /* Block is a landing pad for longjmp or throw.  */
143   unsigned is_nonlocal_return : 1;
144 
145   union
146   {
147     struct
148     {
149      /* Array of line numbers and source files. source files are
150         introduced by a linenumber of zero, the next 'line number' is
151         the number of the source file.  Always starts with a source
152         file.  */
153       unsigned *encoding;
154       unsigned num;
155     } line; /* Valid until blocks are linked onto lines */
156     struct
157     {
158       /* Single line graph cycle workspace.  Used for all-blocks
159 	 mode.  */
160       arc_t *arc;
161       unsigned ident;
162     } cycle; /* Used in all-blocks mode, after blocks are linked onto
163 	       lines.  */
164   } u;
165 
166   /* Temporary chain for solving graph, and for chaining blocks on one
167      line.  */
168   struct block_info *chain;
169 
170 } block_t;
171 
172 /* Describes a single function. Contains an array of basic blocks.  */
173 
174 typedef struct function_info
175 {
176   /* Name of function.  */
177   char *name;
178   char *demangled_name;
179   unsigned ident;
180   unsigned lineno_checksum;
181   unsigned cfg_checksum;
182 
183   /* The graph contains at least one fake incoming edge.  */
184   unsigned has_catch : 1;
185 
186   /* Array of basic blocks.  Like in GCC, the entry block is
187      at blocks[0] and the exit block is at blocks[1].  */
188 #define ENTRY_BLOCK (0)
189 #define EXIT_BLOCK (1)
190   block_t *blocks;
191   unsigned num_blocks;
192   unsigned blocks_executed;
193 
194   /* Raw arc coverage counts.  */
195   gcov_type *counts;
196   unsigned num_counts;
197 
198   /* First line number & file.  */
199   unsigned line;
200   unsigned src;
201 
202   /* Next function in same source file.  */
203   struct function_info *next_file_fn;
204 
205   /* Next function.  */
206   struct function_info *next;
207 } function_t;
208 
209 /* Describes coverage of a file or function.  */
210 
211 typedef struct coverage_info
212 {
213   int lines;
214   int lines_executed;
215 
216   int branches;
217   int branches_executed;
218   int branches_taken;
219 
220   int calls;
221   int calls_executed;
222 
223   char *name;
224 } coverage_t;
225 
226 /* Describes a single line of source. Contains a chain of basic blocks
227    with code on it.  */
228 
229 typedef struct line_info
230 {
231   /* Return true when NEEDLE is one of basic blocks the line belongs to.  */
232   bool has_block (block_t *needle);
233 
234   gcov_type count;	   /* execution count */
235   union
236   {
237     arc_t *branches;	   /* branches from blocks that end on this
238 			      line. Used for branch-counts when not
239 			      all-blocks mode.  */
240     block_t *blocks;       /* blocks which start on this line.  Used
241 			      in all-blocks mode.  */
242   } u;
243   unsigned exists : 1;
244   unsigned unexceptional : 1;
245 } line_t;
246 
247 bool
248 line_t::has_block (block_t *needle)
249 {
250   for (block_t *n = u.blocks; n; n = n->chain)
251     if (n == needle)
252       return true;
253 
254   return false;
255 }
256 
257 /* Describes a file mentioned in the block graph.  Contains an array
258    of line info.  */
259 
260 typedef struct source_info
261 {
262   /* Canonical name of source file.  */
263   char *name;
264   time_t file_time;
265 
266   /* Array of line information.  */
267   line_t *lines;
268   unsigned num_lines;
269 
270   coverage_t coverage;
271 
272   /* Functions in this source file.  These are in ascending line
273      number order.  */
274   function_t *functions;
275 } source_t;
276 
277 typedef struct name_map
278 {
279   char *name;  /* Source file name */
280   unsigned src;  /* Source file */
281 } name_map_t;
282 
283 /* Holds a list of function basic block graphs.  */
284 
285 static function_t *functions;
286 static function_t **fn_end = &functions;
287 
288 static source_t *sources;   /* Array of source files  */
289 static unsigned n_sources;  /* Number of sources */
290 static unsigned a_sources;  /* Allocated sources */
291 
292 static name_map_t *names;   /* Mapping of file names to sources */
293 static unsigned n_names;    /* Number of names */
294 static unsigned a_names;    /* Allocated names */
295 
296 /* This holds data summary information.  */
297 
298 static unsigned object_runs;
299 static unsigned program_count;
300 
301 static unsigned total_lines;
302 static unsigned total_executed;
303 
304 /* Modification time of graph file.  */
305 
306 static time_t bbg_file_time;
307 
308 /* Name of the notes (gcno) output file.  The "bbg" prefix is for
309    historical reasons, when the notes file contained only the
310    basic block graph notes.  */
311 
312 static char *bbg_file_name;
313 
314 /* Stamp of the bbg file */
315 static unsigned bbg_stamp;
316 
317 /* Name and file pointer of the input file for the count data (gcda).  */
318 
319 static char *da_file_name;
320 
321 /* Data file is missing.  */
322 
323 static int no_data_file;
324 
325 /* If there is several input files, compute and display results after
326    reading all data files.  This way if two or more gcda file refer to
327    the same source file (eg inline subprograms in a .h file), the
328    counts are added.  */
329 
330 static int multiple_files = 0;
331 
332 /* Output branch probabilities.  */
333 
334 static int flag_branches = 0;
335 
336 /* Show unconditional branches too.  */
337 static int flag_unconditional = 0;
338 
339 /* Output a gcov file if this is true.  This is on by default, and can
340    be turned off by the -n option.  */
341 
342 static int flag_gcov_file = 1;
343 
344 /* Output progress indication if this is true.  This is off by default
345    and can be turned on by the -d option.  */
346 
347 static int flag_display_progress = 0;
348 
349 /* Output *.gcov file in intermediate format used by 'lcov'.  */
350 
351 static int flag_intermediate_format = 0;
352 
353 /* Output demangled function names.  */
354 
355 static int flag_demangled_names = 0;
356 
357 /* For included files, make the gcov output file name include the name
358    of the input source file.  For example, if x.h is included in a.c,
359    then the output file name is a.c##x.h.gcov instead of x.h.gcov.  */
360 
361 static int flag_long_names = 0;
362 
363 /* For situations when a long name can potentially hit filesystem path limit,
364    let's calculate md5sum of the path and append it to a file name.  */
365 
366 static int flag_hash_filenames = 0;
367 
368 /* Output count information for every basic block, not merely those
369    that contain line number information.  */
370 
371 static int flag_all_blocks = 0;
372 
373 /* Output summary info for each function.  */
374 
375 static int flag_function_summary = 0;
376 
377 /* Object directory file prefix.  This is the directory/file where the
378    graph and data files are looked for, if nonzero.  */
379 
380 static char *object_directory = 0;
381 
382 /* Source directory prefix.  This is removed from source pathnames
383    that match, when generating the output file name.  */
384 
385 static char *source_prefix = 0;
386 static size_t source_length = 0;
387 
388 /* Only show data for sources with relative pathnames.  Absolute ones
389    usually indicate a system header file, which although it may
390    contain inline functions, is usually uninteresting.  */
391 static int flag_relative_only = 0;
392 
393 /* Preserve all pathname components. Needed when object files and
394    source files are in subdirectories. '/' is mangled as '#', '.' is
395    elided and '..' mangled to '^'.  */
396 
397 static int flag_preserve_paths = 0;
398 
399 /* Output the number of times a branch was taken as opposed to the percentage
400    of times it was taken.  */
401 
402 static int flag_counts = 0;
403 
404 /* Forward declarations.  */
405 static int process_args (int, char **);
406 static void print_usage (int) ATTRIBUTE_NORETURN;
407 static void print_version (void) ATTRIBUTE_NORETURN;
408 static void process_file (const char *);
409 static void generate_results (const char *);
410 static void create_file_names (const char *);
411 static int name_search (const void *, const void *);
412 static int name_sort (const void *, const void *);
413 static char *canonicalize_name (const char *);
414 static unsigned find_source (const char *);
415 static function_t *read_graph_file (void);
416 static int read_count_file (function_t *);
417 static void solve_flow_graph (function_t *);
418 static void find_exception_blocks (function_t *);
419 static void add_branch_counts (coverage_t *, const arc_t *);
420 static void add_line_counts (coverage_t *, function_t *);
421 static void executed_summary (unsigned, unsigned);
422 static void function_summary (const coverage_t *, const char *);
423 static const char *format_gcov (gcov_type, gcov_type, int);
424 static void accumulate_line_counts (source_t *);
425 static void output_gcov_file (const char *, source_t *);
426 static int output_branch_count (FILE *, int, const arc_t *);
427 static void output_lines (FILE *, const source_t *);
428 static char *make_gcov_file_name (const char *, const char *);
429 static char *mangle_name (const char *, char *);
430 static void release_structures (void);
431 static void release_function (function_t *);
432 extern int main (int, char **);
433 
434 /* Cycle detection!
435    There are a bajillion algorithms that do this.  Boost's function is named
436    hawick_cycles, so I used the algorithm by K. A. Hawick and H. A. James in
437    "Enumerating Circuits and Loops in Graphs with Self-Arcs and Multiple-Arcs"
438    (url at <http://complexity.massey.ac.nz/cstn/013/cstn-013.pdf>).
439 
440    The basic algorithm is simple: effectively, we're finding all simple paths
441    in a subgraph (that shrinks every iteration).  Duplicates are filtered by
442    "blocking" a path when a node is added to the path (this also prevents non-
443    simple paths)--the node is unblocked only when it participates in a cycle.
444    */
445 
446 typedef vector<arc_t *> arc_vector_t;
447 typedef vector<const block_t *> block_vector_t;
448 
449 /* Enum with types of loop in CFG.  */
450 
451 enum loop_type
452 {
453   NO_LOOP = 0,
454   LOOP = 1,
455   NEGATIVE_LOOP = 3
456 };
457 
458 /* Loop_type operator that merges two values: A and B.  */
459 
460 inline loop_type& operator |= (loop_type& a, loop_type b)
461 {
462     return a = static_cast<loop_type> (a | b);
463 }
464 
465 /* Handle cycle identified by EDGES, where the function finds minimum cs_count
466    and subtract the value from all counts.  The subtracted value is added
467    to COUNT.  Returns type of loop.  */
468 
469 static loop_type
470 handle_cycle (const arc_vector_t &edges, int64_t &count)
471 {
472   /* Find the minimum edge of the cycle, and reduce all nodes in the cycle by
473      that amount.  */
474   int64_t cycle_count = INTTYPE_MAXIMUM (int64_t);
475   for (unsigned i = 0; i < edges.size (); i++)
476     {
477       int64_t ecount = edges[i]->cs_count;
478       if (cycle_count > ecount)
479 	cycle_count = ecount;
480     }
481   count += cycle_count;
482   for (unsigned i = 0; i < edges.size (); i++)
483     edges[i]->cs_count -= cycle_count;
484 
485   return cycle_count < 0 ? NEGATIVE_LOOP : LOOP;
486 }
487 
488 /* Unblock a block U from BLOCKED.  Apart from that, iterate all blocks
489    blocked by U in BLOCK_LISTS.  */
490 
491 static void
492 unblock (const block_t *u, block_vector_t &blocked,
493 	 vector<block_vector_t > &block_lists)
494 {
495   block_vector_t::iterator it = find (blocked.begin (), blocked.end (), u);
496   if (it == blocked.end ())
497     return;
498 
499   unsigned index = it - blocked.begin ();
500   blocked.erase (it);
501 
502   block_vector_t to_unblock (block_lists[index]);
503 
504   block_lists.erase (block_lists.begin () + index);
505 
506   for (block_vector_t::iterator it = to_unblock.begin ();
507        it != to_unblock.end (); it++)
508     unblock (*it, blocked, block_lists);
509 }
510 
511 /* Find circuit going to block V, PATH is provisional seen cycle.
512    BLOCKED is vector of blocked vertices, BLOCK_LISTS contains vertices
513    blocked by a block.  COUNT is accumulated count of the current LINE.
514    Returns what type of loop it contains.  */
515 
516 static loop_type
517 circuit (block_t *v, arc_vector_t &path, block_t *start,
518 	 block_vector_t &blocked, vector<block_vector_t> &block_lists,
519 	 line_t &linfo, int64_t &count)
520 {
521   loop_type result = NO_LOOP;
522 
523   /* Add v to the block list.  */
524   gcc_assert (find (blocked.begin (), blocked.end (), v) == blocked.end ());
525   blocked.push_back (v);
526   block_lists.push_back (block_vector_t ());
527 
528   for (arc_t *arc = v->succ; arc; arc = arc->succ_next)
529     {
530       block_t *w = arc->dst;
531       if (w < start || !linfo.has_block (w))
532 	continue;
533 
534       path.push_back (arc);
535       if (w == start)
536 	/* Cycle has been found.  */
537 	result |= handle_cycle (path, count);
538       else if (find (blocked.begin (), blocked.end (), w) == blocked.end ())
539 	result |= circuit (w, path, start, blocked, block_lists, linfo, count);
540 
541       path.pop_back ();
542     }
543 
544   if (result != NO_LOOP)
545     unblock (v, blocked, block_lists);
546   else
547     for (arc_t *arc = v->succ; arc; arc = arc->succ_next)
548       {
549 	block_t *w = arc->dst;
550 	if (w < start || !linfo.has_block (w))
551 	  continue;
552 
553 	size_t index
554 	  = find (blocked.begin (), blocked.end (), w) - blocked.begin ();
555 	gcc_assert (index < blocked.size ());
556 	block_vector_t &list = block_lists[index];
557 	if (find (list.begin (), list.end (), v) == list.end ())
558 	  list.push_back (v);
559       }
560 
561   return result;
562 }
563 
564 /* Find cycles for a LINFO.  If HANDLE_NEGATIVE_CYCLES is set and the line
565    contains a negative loop, then perform the same function once again.  */
566 
567 static gcov_type
568 get_cycles_count (line_t &linfo, bool handle_negative_cycles = true)
569 {
570   /* Note that this algorithm works even if blocks aren't in sorted order.
571      Each iteration of the circuit detection is completely independent
572      (except for reducing counts, but that shouldn't matter anyways).
573      Therefore, operating on a permuted order (i.e., non-sorted) only
574      has the effect of permuting the output cycles.  */
575 
576   loop_type result = NO_LOOP;
577   gcov_type count = 0;
578   for (block_t *block = linfo.u.blocks; block; block = block->chain)
579     {
580       arc_vector_t path;
581       block_vector_t blocked;
582       vector<block_vector_t > block_lists;
583       result |= circuit (block, path, block, blocked, block_lists, linfo,
584 			 count);
585     }
586 
587   /* If we have a negative cycle, repeat the find_cycles routine.  */
588   if (result == NEGATIVE_LOOP && handle_negative_cycles)
589     count += get_cycles_count (linfo, false);
590 
591   return count;
592 }
593 
594 int
595 main (int argc, char **argv)
596 {
597   int argno;
598   int first_arg;
599   const char *p;
600 
601   p = argv[0] + strlen (argv[0]);
602   while (p != argv[0] && !IS_DIR_SEPARATOR (p[-1]))
603     --p;
604   progname = p;
605 
606   xmalloc_set_program_name (progname);
607 
608   /* Unlock the stdio streams.  */
609   unlock_std_streams ();
610 
611   gcc_init_libintl ();
612 
613   diagnostic_initialize (global_dc, 0);
614 
615   /* Handle response files.  */
616   expandargv (&argc, &argv);
617 
618   a_names = 10;
619   names = XNEWVEC (name_map_t, a_names);
620   a_sources = 10;
621   sources = XNEWVEC (source_t, a_sources);
622 
623   argno = process_args (argc, argv);
624   if (optind == argc)
625     print_usage (true);
626 
627   if (argc - argno > 1)
628     multiple_files = 1;
629 
630   first_arg = argno;
631 
632   for (; argno != argc; argno++)
633     {
634       if (flag_display_progress)
635 	printf ("Processing file %d out of %d\n", argno - first_arg + 1,
636 		argc - first_arg);
637       process_file (argv[argno]);
638     }
639 
640   generate_results (multiple_files ? NULL : argv[argc - 1]);
641 
642   release_structures ();
643 
644   return 0;
645 }
646 
647 /* Print a usage message and exit.  If ERROR_P is nonzero, this is an error,
648    otherwise the output of --help.  */
649 
650 static void
651 print_usage (int error_p)
652 {
653   FILE *file = error_p ? stderr : stdout;
654   int status = error_p ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE;
655 
656   fnotice (file, "Usage: gcov [OPTION...] SOURCE|OBJ...\n\n");
657   fnotice (file, "Print code coverage information.\n\n");
658   fnotice (file, "  -a, --all-blocks                Show information for every basic block\n");
659   fnotice (file, "  -b, --branch-probabilities      Include branch probabilities in output\n");
660   fnotice (file, "  -c, --branch-counts             Output counts of branches taken\n\
661                                     rather than percentages\n");
662   fnotice (file, "  -d, --display-progress          Display progress information\n");
663   fnotice (file, "  -f, --function-summaries        Output summaries for each function\n");
664   fnotice (file, "  -h, --help                      Print this help, then exit\n");
665   fnotice (file, "  -i, --intermediate-format       Output .gcov file in intermediate text format\n");
666   fnotice (file, "  -l, --long-file-names           Use long output file names for included\n\
667                                     source files\n");
668   fnotice (file, "  -m, --demangled-names           Output demangled function names\n");
669   fnotice (file, "  -n, --no-output                 Do not create an output file\n");
670   fnotice (file, "  -o, --object-directory DIR|FILE Search for object files in DIR or called FILE\n");
671   fnotice (file, "  -p, --preserve-paths            Preserve all pathname components\n");
672   fnotice (file, "  -r, --relative-only             Only show data for relative sources\n");
673   fnotice (file, "  -s, --source-prefix DIR         Source prefix to elide\n");
674   fnotice (file, "  -u, --unconditional-branches    Show unconditional branch counts too\n");
675   fnotice (file, "  -v, --version                   Print version number, then exit\n");
676   fnotice (file, "  -x, --hash-filenames            Hash long pathnames\n");
677   fnotice (file, "\nFor bug reporting instructions, please see:\n%s.\n",
678 	   bug_report_url);
679   exit (status);
680 }
681 
682 /* Print version information and exit.  */
683 
684 static void
685 print_version (void)
686 {
687   fnotice (stdout, "gcov %s%s\n", pkgversion_string, version_string);
688   fprintf (stdout, "Copyright %s 2017 Free Software Foundation, Inc.\n",
689 	   _("(C)"));
690   fnotice (stdout,
691 	   _("This is free software; see the source for copying conditions.\n"
692 	     "There is NO warranty; not even for MERCHANTABILITY or \n"
693 	     "FITNESS FOR A PARTICULAR PURPOSE.\n\n"));
694   exit (SUCCESS_EXIT_CODE);
695 }
696 
697 static const struct option options[] =
698 {
699   { "help",                 no_argument,       NULL, 'h' },
700   { "version",              no_argument,       NULL, 'v' },
701   { "all-blocks",           no_argument,       NULL, 'a' },
702   { "branch-probabilities", no_argument,       NULL, 'b' },
703   { "branch-counts",        no_argument,       NULL, 'c' },
704   { "intermediate-format",  no_argument,       NULL, 'i' },
705   { "no-output",            no_argument,       NULL, 'n' },
706   { "long-file-names",      no_argument,       NULL, 'l' },
707   { "function-summaries",   no_argument,       NULL, 'f' },
708   { "demangled-names",      no_argument,       NULL, 'm' },
709   { "preserve-paths",       no_argument,       NULL, 'p' },
710   { "relative-only",        no_argument,       NULL, 'r' },
711   { "object-directory",     required_argument, NULL, 'o' },
712   { "object-file",          required_argument, NULL, 'o' },
713   { "source-prefix",        required_argument, NULL, 's' },
714   { "unconditional-branches", no_argument,     NULL, 'u' },
715   { "display-progress",     no_argument,       NULL, 'd' },
716   { "hash-filenames",	    no_argument,       NULL, 'x' },
717   { 0, 0, 0, 0 }
718 };
719 
720 /* Process args, return index to first non-arg.  */
721 
722 static int
723 process_args (int argc, char **argv)
724 {
725   int opt;
726 
727   const char *opts = "abcdfhilmno:prs:uvx";
728   while ((opt = getopt_long (argc, argv, opts, options, NULL)) != -1)
729     {
730       switch (opt)
731 	{
732 	case 'a':
733 	  flag_all_blocks = 1;
734 	  break;
735 	case 'b':
736 	  flag_branches = 1;
737 	  break;
738 	case 'c':
739 	  flag_counts = 1;
740 	  break;
741 	case 'f':
742 	  flag_function_summary = 1;
743 	  break;
744 	case 'h':
745 	  print_usage (false);
746 	  /* print_usage will exit.  */
747 	case 'l':
748 	  flag_long_names = 1;
749 	  break;
750 	case 'm':
751 	  flag_demangled_names = 1;
752 	  break;
753 	case 'n':
754 	  flag_gcov_file = 0;
755 	  break;
756 	case 'o':
757 	  object_directory = optarg;
758 	  break;
759 	case 's':
760 	  source_prefix = optarg;
761 	  source_length = strlen (source_prefix);
762 	  break;
763 	case 'r':
764 	  flag_relative_only = 1;
765 	  break;
766 	case 'p':
767 	  flag_preserve_paths = 1;
768 	  break;
769 	case 'u':
770 	  flag_unconditional = 1;
771 	  break;
772 	case 'i':
773           flag_intermediate_format = 1;
774           flag_gcov_file = 1;
775           break;
776         case 'd':
777           flag_display_progress = 1;
778           break;
779 	case 'x':
780 	  flag_hash_filenames = 1;
781 	  break;
782 	case 'v':
783 	  print_version ();
784 	  /* print_version will exit.  */
785 	default:
786 	  print_usage (true);
787 	  /* print_usage will exit.  */
788 	}
789     }
790 
791   return optind;
792 }
793 
794 /* Output the result in intermediate format used by 'lcov'.
795 
796 The intermediate format contains a single file named 'foo.cc.gcov',
797 with no source code included. A sample output is
798 
799 file:foo.cc
800 function:5,1,_Z3foov
801 function:13,1,main
802 function:19,1,_GLOBAL__sub_I__Z3foov
803 function:19,1,_Z41__static_initialization_and_destruction_0ii
804 lcount:5,1
805 lcount:7,9
806 lcount:9,8
807 lcount:11,1
808 file:/.../iostream
809 lcount:74,1
810 file:/.../basic_ios.h
811 file:/.../ostream
812 file:/.../ios_base.h
813 function:157,0,_ZStorSt12_Ios_IostateS_
814 lcount:157,0
815 file:/.../char_traits.h
816 function:258,0,_ZNSt11char_traitsIcE6lengthEPKc
817 lcount:258,0
818 ...
819 
820 The default gcov outputs multiple files: 'foo.cc.gcov',
821 'iostream.gcov', 'ios_base.h.gcov', etc. with source code
822 included. Instead the intermediate format here outputs only a single
823 file 'foo.cc.gcov' similar to the above example. */
824 
825 static void
826 output_intermediate_file (FILE *gcov_file, source_t *src)
827 {
828   unsigned line_num;    /* current line number.  */
829   const line_t *line;   /* current line info ptr.  */
830   function_t *fn;       /* current function info ptr. */
831 
832   fprintf (gcov_file, "file:%s\n", src->name);    /* source file name */
833 
834   for (fn = src->functions; fn; fn = fn->next_file_fn)
835     {
836       /* function:<name>,<line_number>,<execution_count> */
837       fprintf (gcov_file, "function:%d,%s,%s\n", fn->line,
838 	       format_gcov (fn->blocks[0].count, 0, -1),
839 	       flag_demangled_names ? fn->demangled_name : fn->name);
840     }
841 
842   for (line_num = 1, line = &src->lines[line_num];
843        line_num < src->num_lines;
844        line_num++, line++)
845     {
846       arc_t *arc;
847       if (line->exists)
848 	fprintf (gcov_file, "lcount:%u,%s\n", line_num,
849 		 format_gcov (line->count, 0, -1));
850       if (flag_branches)
851         for (arc = line->u.branches; arc; arc = arc->line_next)
852           {
853             if (!arc->is_unconditional && !arc->is_call_non_return)
854               {
855                 const char *branch_type;
856                 /* branch:<line_num>,<branch_coverage_type>
857                    branch_coverage_type
858                      : notexec (Branch not executed)
859                      : taken (Branch executed and taken)
860                      : nottaken (Branch executed, but not taken)
861                 */
862                 if (arc->src->count)
863                   branch_type = (arc->count > 0) ? "taken" : "nottaken";
864                 else
865                   branch_type = "notexec";
866                 fprintf (gcov_file, "branch:%d,%s\n", line_num, branch_type);
867               }
868           }
869     }
870 }
871 
872 /* Process a single input file.  */
873 
874 static void
875 process_file (const char *file_name)
876 {
877   function_t *fns;
878 
879   create_file_names (file_name);
880   fns = read_graph_file ();
881   if (!fns)
882     return;
883 
884   read_count_file (fns);
885   while (fns)
886     {
887       function_t *fn = fns;
888 
889       fns = fn->next;
890       fn->next = NULL;
891       if (fn->counts || no_data_file)
892 	{
893 	  unsigned src = fn->src;
894 	  unsigned line = fn->line;
895 	  unsigned block_no;
896 	  function_t *probe, **prev;
897 
898 	  /* Now insert it into the source file's list of
899 	     functions. Normally functions will be encountered in
900 	     ascending order, so a simple scan is quick.  Note we're
901 	     building this list in reverse order.  */
902 	  for (prev = &sources[src].functions;
903 	       (probe = *prev); prev = &probe->next_file_fn)
904 	    if (probe->line <= line)
905 	      break;
906 	  fn->next_file_fn = probe;
907 	  *prev = fn;
908 
909 	  /* Mark last line in files touched by function.  */
910 	  for (block_no = 0; block_no != fn->num_blocks; block_no++)
911 	    {
912 	      unsigned *enc = fn->blocks[block_no].u.line.encoding;
913 	      unsigned num = fn->blocks[block_no].u.line.num;
914 
915 	      for (; num--; enc++)
916 		if (!*enc)
917 		  {
918 		    if (enc[1] != src)
919 		      {
920 			if (line >= sources[src].num_lines)
921 			  sources[src].num_lines = line + 1;
922 			line = 0;
923 			src = enc[1];
924 		      }
925 		    enc++;
926 		    num--;
927 		  }
928 		else if (*enc > line)
929 		  line = *enc;
930 	    }
931 	  if (line >= sources[src].num_lines)
932 	    sources[src].num_lines = line + 1;
933 
934 	  solve_flow_graph (fn);
935 	  if (fn->has_catch)
936 	    find_exception_blocks (fn);
937 	  *fn_end = fn;
938 	  fn_end = &fn->next;
939 	}
940       else
941 	/* The function was not in the executable -- some other
942 	   instance must have been selected.  */
943 	release_function (fn);
944     }
945 }
946 
947 static void
948 output_gcov_file (const char *file_name, source_t *src)
949 {
950   char *gcov_file_name = make_gcov_file_name (file_name, src->coverage.name);
951 
952   if (src->coverage.lines)
953     {
954       FILE *gcov_file = fopen (gcov_file_name, "w");
955       if (gcov_file)
956         {
957           fnotice (stdout, "Creating '%s'\n", gcov_file_name);
958 
959 	  if (flag_intermediate_format)
960 	    output_intermediate_file (gcov_file, src);
961 	  else
962 	    output_lines (gcov_file, src);
963           if (ferror (gcov_file))
964             fnotice (stderr, "Error writing output file '%s'\n", gcov_file_name);
965           fclose (gcov_file);
966         }
967       else
968         fnotice (stderr, "Could not open output file '%s'\n", gcov_file_name);
969     }
970   else
971     {
972       unlink (gcov_file_name);
973       fnotice (stdout, "Removing '%s'\n", gcov_file_name);
974     }
975   free (gcov_file_name);
976 }
977 
978 static void
979 generate_results (const char *file_name)
980 {
981   unsigned ix;
982   source_t *src;
983   function_t *fn;
984 
985   for (ix = n_sources, src = sources; ix--; src++)
986     if (src->num_lines)
987       src->lines = XCNEWVEC (line_t, src->num_lines);
988 
989   for (fn = functions; fn; fn = fn->next)
990     {
991       coverage_t coverage;
992 
993       memset (&coverage, 0, sizeof (coverage));
994       coverage.name = flag_demangled_names ? fn->demangled_name : fn->name;
995       add_line_counts (flag_function_summary ? &coverage : NULL, fn);
996       if (flag_function_summary)
997 	{
998 	  function_summary (&coverage, "Function");
999 	  fnotice (stdout, "\n");
1000 	}
1001     }
1002 
1003   if (file_name)
1004     {
1005       name_map_t *name_map = (name_map_t *)bsearch
1006 	(file_name, names, n_names, sizeof (*names), name_search);
1007       if (name_map)
1008 	file_name = sources[name_map->src].coverage.name;
1009       else
1010 	file_name = canonicalize_name (file_name);
1011     }
1012 
1013   for (ix = n_sources, src = sources; ix--; src++)
1014     {
1015       if (flag_relative_only)
1016 	{
1017 	  /* Ignore this source, if it is an absolute path (after
1018 	     source prefix removal).  */
1019 	  char first = src->coverage.name[0];
1020 
1021 #if HAVE_DOS_BASED_FILE_SYSTEM
1022 	  if (first && src->coverage.name[1] == ':')
1023 	    first = src->coverage.name[2];
1024 #endif
1025 	  if (IS_DIR_SEPARATOR (first))
1026 	    continue;
1027 	}
1028 
1029       accumulate_line_counts (src);
1030       function_summary (&src->coverage, "File");
1031       total_lines += src->coverage.lines;
1032       total_executed += src->coverage.lines_executed;
1033       if (flag_gcov_file)
1034 	{
1035 	  output_gcov_file (file_name, src);
1036           fnotice (stdout, "\n");
1037         }
1038     }
1039 
1040   if (!file_name)
1041     executed_summary (total_lines, total_executed);
1042 }
1043 
1044 /* Release a function structure */
1045 
1046 static void
1047 release_function (function_t *fn)
1048 {
1049   unsigned ix;
1050   block_t *block;
1051 
1052   for (ix = fn->num_blocks, block = fn->blocks; ix--; block++)
1053     {
1054       arc_t *arc, *arc_n;
1055 
1056       for (arc = block->succ; arc; arc = arc_n)
1057 	{
1058 	  arc_n = arc->succ_next;
1059 	  free (arc);
1060 	}
1061     }
1062   free (fn->blocks);
1063   free (fn->counts);
1064   if (flag_demangled_names && fn->demangled_name != fn->name)
1065     free (fn->demangled_name);
1066   free (fn->name);
1067 }
1068 
1069 /* Release all memory used.  */
1070 
1071 static void
1072 release_structures (void)
1073 {
1074   unsigned ix;
1075   function_t *fn;
1076 
1077   for (ix = n_sources; ix--;)
1078     free (sources[ix].lines);
1079   free (sources);
1080 
1081   for (ix = n_names; ix--;)
1082     free (names[ix].name);
1083   free (names);
1084 
1085   while ((fn = functions))
1086     {
1087       functions = fn->next;
1088       release_function (fn);
1089     }
1090 }
1091 
1092 /* Generate the names of the graph and data files.  If OBJECT_DIRECTORY
1093    is not specified, these are named from FILE_NAME sans extension.  If
1094    OBJECT_DIRECTORY is specified and is a directory, the files are in that
1095    directory, but named from the basename of the FILE_NAME, sans extension.
1096    Otherwise OBJECT_DIRECTORY is taken to be the name of the object *file*
1097    and the data files are named from that.  */
1098 
1099 static void
1100 create_file_names (const char *file_name)
1101 {
1102   char *cptr;
1103   char *name;
1104   int length = strlen (file_name);
1105   int base;
1106 
1107   /* Free previous file names.  */
1108   free (bbg_file_name);
1109   free (da_file_name);
1110   da_file_name = bbg_file_name = NULL;
1111   bbg_file_time = 0;
1112   bbg_stamp = 0;
1113 
1114   if (object_directory && object_directory[0])
1115     {
1116       struct stat status;
1117 
1118       length += strlen (object_directory) + 2;
1119       name = XNEWVEC (char, length);
1120       name[0] = 0;
1121 
1122       base = !stat (object_directory, &status) && S_ISDIR (status.st_mode);
1123       strcat (name, object_directory);
1124       if (base && (!IS_DIR_SEPARATOR (name[strlen (name) - 1])))
1125 	strcat (name, "/");
1126     }
1127   else
1128     {
1129       name = XNEWVEC (char, length + 1);
1130       strcpy (name, file_name);
1131       base = 0;
1132     }
1133 
1134   if (base)
1135     {
1136       /* Append source file name.  */
1137       const char *cptr = lbasename (file_name);
1138       strcat (name, cptr ? cptr : file_name);
1139     }
1140 
1141   /* Remove the extension.  */
1142   cptr = strrchr (CONST_CAST (char *, lbasename (name)), '.');
1143   if (cptr)
1144     *cptr = 0;
1145 
1146   length = strlen (name);
1147 
1148   bbg_file_name = XNEWVEC (char, length + strlen (GCOV_NOTE_SUFFIX) + 1);
1149   strcpy (bbg_file_name, name);
1150   strcpy (bbg_file_name + length, GCOV_NOTE_SUFFIX);
1151 
1152   da_file_name = XNEWVEC (char, length + strlen (GCOV_DATA_SUFFIX) + 1);
1153   strcpy (da_file_name, name);
1154   strcpy (da_file_name + length, GCOV_DATA_SUFFIX);
1155 
1156   free (name);
1157   return;
1158 }
1159 
1160 /* A is a string and B is a pointer to name_map_t.  Compare for file
1161    name orderability.  */
1162 
1163 static int
1164 name_search (const void *a_, const void *b_)
1165 {
1166   const char *a = (const char *)a_;
1167   const name_map_t *b = (const name_map_t *)b_;
1168 
1169 #if HAVE_DOS_BASED_FILE_SYSTEM
1170   return strcasecmp (a, b->name);
1171 #else
1172   return strcmp (a, b->name);
1173 #endif
1174 }
1175 
1176 /* A and B are a pointer to name_map_t.  Compare for file name
1177    orderability.  */
1178 
1179 static int
1180 name_sort (const void *a_, const void *b_)
1181 {
1182   const name_map_t *a = (const name_map_t *)a_;
1183   return name_search (a->name, b_);
1184 }
1185 
1186 /* Find or create a source file structure for FILE_NAME. Copies
1187    FILE_NAME on creation */
1188 
1189 static unsigned
1190 find_source (const char *file_name)
1191 {
1192   name_map_t *name_map;
1193   char *canon;
1194   unsigned idx;
1195   struct stat status;
1196 
1197   if (!file_name)
1198     file_name = "<unknown>";
1199   name_map = (name_map_t *)bsearch
1200     (file_name, names, n_names, sizeof (*names), name_search);
1201   if (name_map)
1202     {
1203       idx = name_map->src;
1204       goto check_date;
1205     }
1206 
1207   if (n_names + 2 > a_names)
1208     {
1209       /* Extend the name map array -- we'll be inserting one or two
1210 	 entries.  */
1211       a_names *= 2;
1212       name_map = XNEWVEC (name_map_t, a_names);
1213       memcpy (name_map, names, n_names * sizeof (*names));
1214       free (names);
1215       names = name_map;
1216     }
1217 
1218   /* Not found, try the canonical name. */
1219   canon = canonicalize_name (file_name);
1220   name_map = (name_map_t *) bsearch (canon, names, n_names, sizeof (*names),
1221 				     name_search);
1222   if (!name_map)
1223     {
1224       /* Not found with canonical name, create a new source.  */
1225       source_t *src;
1226 
1227       if (n_sources == a_sources)
1228 	{
1229 	  a_sources *= 2;
1230 	  src = XNEWVEC (source_t, a_sources);
1231 	  memcpy (src, sources, n_sources * sizeof (*sources));
1232 	  free (sources);
1233 	  sources = src;
1234 	}
1235 
1236       idx = n_sources;
1237 
1238       name_map = &names[n_names++];
1239       name_map->name = canon;
1240       name_map->src = idx;
1241 
1242       src = &sources[n_sources++];
1243       memset (src, 0, sizeof (*src));
1244       src->name = canon;
1245       src->coverage.name = src->name;
1246       if (source_length
1247 #if HAVE_DOS_BASED_FILE_SYSTEM
1248 	  /* You lose if separators don't match exactly in the
1249 	     prefix.  */
1250 	  && !strncasecmp (source_prefix, src->coverage.name, source_length)
1251 #else
1252 	  && !strncmp (source_prefix, src->coverage.name, source_length)
1253 #endif
1254 	  && IS_DIR_SEPARATOR (src->coverage.name[source_length]))
1255 	src->coverage.name += source_length + 1;
1256       if (!stat (src->name, &status))
1257 	src->file_time = status.st_mtime;
1258     }
1259   else
1260     idx = name_map->src;
1261 
1262   if (name_search (file_name, name_map))
1263     {
1264       /* Append the non-canonical name.  */
1265       name_map = &names[n_names++];
1266       name_map->name = xstrdup (file_name);
1267       name_map->src = idx;
1268     }
1269 
1270   /* Resort the name map.  */
1271   qsort (names, n_names, sizeof (*names), name_sort);
1272 
1273  check_date:
1274   if (sources[idx].file_time > bbg_file_time)
1275     {
1276       static int info_emitted;
1277 
1278       fnotice (stderr, "%s:source file is newer than notes file '%s'\n",
1279 	       file_name, bbg_file_name);
1280       if (!info_emitted)
1281 	{
1282 	  fnotice (stderr,
1283 		   "(the message is displayed only once per source file)\n");
1284 	  info_emitted = 1;
1285 	}
1286       sources[idx].file_time = 0;
1287     }
1288 
1289   return idx;
1290 }
1291 
1292 /* Read the notes file.  Return list of functions read -- in reverse order.  */
1293 
1294 static function_t *
1295 read_graph_file (void)
1296 {
1297   unsigned version;
1298   unsigned current_tag = 0;
1299   function_t *fn = NULL;
1300   function_t *fns = NULL;
1301   function_t **fns_end = &fns;
1302   unsigned src_idx = 0;
1303   unsigned ix;
1304   unsigned tag;
1305 
1306   if (!gcov_open (bbg_file_name, 1))
1307     {
1308       fnotice (stderr, "%s:cannot open notes file\n", bbg_file_name);
1309       return fns;
1310     }
1311   bbg_file_time = gcov_time ();
1312   if (!gcov_magic (gcov_read_unsigned (), GCOV_NOTE_MAGIC))
1313     {
1314       fnotice (stderr, "%s:not a gcov notes file\n", bbg_file_name);
1315       gcov_close ();
1316       return fns;
1317     }
1318 
1319   version = gcov_read_unsigned ();
1320   if (version != GCOV_VERSION)
1321     {
1322       char v[4], e[4];
1323 
1324       GCOV_UNSIGNED2STRING (v, version);
1325       GCOV_UNSIGNED2STRING (e, GCOV_VERSION);
1326 
1327       fnotice (stderr, "%s:version '%.4s', prefer '%.4s'\n",
1328 	       bbg_file_name, v, e);
1329     }
1330   bbg_stamp = gcov_read_unsigned ();
1331 
1332   while ((tag = gcov_read_unsigned ()))
1333     {
1334       unsigned length = gcov_read_unsigned ();
1335       gcov_position_t base = gcov_position ();
1336 
1337       if (tag == GCOV_TAG_FUNCTION)
1338 	{
1339 	  char *function_name;
1340 	  unsigned ident, lineno;
1341 	  unsigned lineno_checksum, cfg_checksum;
1342 
1343 	  ident = gcov_read_unsigned ();
1344 	  lineno_checksum = gcov_read_unsigned ();
1345 	  cfg_checksum = gcov_read_unsigned ();
1346 	  function_name = xstrdup (gcov_read_string ());
1347 	  src_idx = find_source (gcov_read_string ());
1348 	  lineno = gcov_read_unsigned ();
1349 
1350 	  fn = XCNEW (function_t);
1351 	  fn->name = function_name;
1352 	  if (flag_demangled_names)
1353 	    {
1354 	      fn->demangled_name = cplus_demangle (fn->name, DMGL_PARAMS);
1355 	      if (!fn->demangled_name)
1356 		fn->demangled_name = fn->name;
1357 	    }
1358 	  fn->ident = ident;
1359 	  fn->lineno_checksum = lineno_checksum;
1360 	  fn->cfg_checksum = cfg_checksum;
1361 	  fn->src = src_idx;
1362 	  fn->line = lineno;
1363 
1364 	  fn->next_file_fn = NULL;
1365 	  fn->next = NULL;
1366 	  *fns_end = fn;
1367 	  fns_end = &fn->next;
1368 	  current_tag = tag;
1369 	}
1370       else if (fn && tag == GCOV_TAG_BLOCKS)
1371 	{
1372 	  if (fn->blocks)
1373 	    fnotice (stderr, "%s:already seen blocks for '%s'\n",
1374 		     bbg_file_name, fn->name);
1375 	  else
1376 	    {
1377 	      unsigned ix, num_blocks = GCOV_TAG_BLOCKS_NUM (length);
1378 	      fn->num_blocks = num_blocks;
1379 
1380 	      fn->blocks = XCNEWVEC (block_t, fn->num_blocks);
1381 	      for (ix = 0; ix != num_blocks; ix++)
1382 		fn->blocks[ix].flags = gcov_read_unsigned ();
1383 	    }
1384 	}
1385       else if (fn && tag == GCOV_TAG_ARCS)
1386 	{
1387 	  unsigned src = gcov_read_unsigned ();
1388 	  unsigned num_dests = GCOV_TAG_ARCS_NUM (length);
1389 	  block_t *src_blk = &fn->blocks[src];
1390 	  unsigned mark_catches = 0;
1391 	  struct arc_info *arc;
1392 
1393 	  if (src >= fn->num_blocks || fn->blocks[src].succ)
1394 	    goto corrupt;
1395 
1396 	  while (num_dests--)
1397 	    {
1398 	      unsigned dest = gcov_read_unsigned ();
1399 	      unsigned flags = gcov_read_unsigned ();
1400 
1401 	      if (dest >= fn->num_blocks)
1402 		goto corrupt;
1403 	      arc = XCNEW (arc_t);
1404 
1405 	      arc->dst = &fn->blocks[dest];
1406 	      arc->src = src_blk;
1407 
1408 	      arc->count = 0;
1409 	      arc->count_valid = 0;
1410 	      arc->on_tree = !!(flags & GCOV_ARC_ON_TREE);
1411 	      arc->fake = !!(flags & GCOV_ARC_FAKE);
1412 	      arc->fall_through = !!(flags & GCOV_ARC_FALLTHROUGH);
1413 
1414 	      arc->succ_next = src_blk->succ;
1415 	      src_blk->succ = arc;
1416 	      src_blk->num_succ++;
1417 
1418 	      arc->pred_next = fn->blocks[dest].pred;
1419 	      fn->blocks[dest].pred = arc;
1420 	      fn->blocks[dest].num_pred++;
1421 
1422 	      if (arc->fake)
1423 		{
1424 		  if (src)
1425 		    {
1426 		      /* Exceptional exit from this function, the
1427 			 source block must be a call.  */
1428 		      fn->blocks[src].is_call_site = 1;
1429 		      arc->is_call_non_return = 1;
1430 		      mark_catches = 1;
1431 		    }
1432 		  else
1433 		    {
1434 		      /* Non-local return from a callee of this
1435 			 function.  The destination block is a setjmp.  */
1436 		      arc->is_nonlocal_return = 1;
1437 		      fn->blocks[dest].is_nonlocal_return = 1;
1438 		    }
1439 		}
1440 
1441 	      if (!arc->on_tree)
1442 		fn->num_counts++;
1443 	    }
1444 
1445 	  if (mark_catches)
1446 	    {
1447 	      /* We have a fake exit from this block.  The other
1448 		 non-fall through exits must be to catch handlers.
1449 		 Mark them as catch arcs.  */
1450 
1451 	      for (arc = src_blk->succ; arc; arc = arc->succ_next)
1452 		if (!arc->fake && !arc->fall_through)
1453 		  {
1454 		    arc->is_throw = 1;
1455 		    fn->has_catch = 1;
1456 		  }
1457 	    }
1458 	}
1459       else if (fn && tag == GCOV_TAG_LINES)
1460 	{
1461 	  unsigned blockno = gcov_read_unsigned ();
1462 	  unsigned *line_nos = XCNEWVEC (unsigned, length - 1);
1463 
1464 	  if (blockno >= fn->num_blocks || fn->blocks[blockno].u.line.encoding)
1465 	    goto corrupt;
1466 
1467 	  for (ix = 0; ;  )
1468 	    {
1469 	      unsigned lineno = gcov_read_unsigned ();
1470 
1471 	      if (lineno)
1472 		{
1473 		  if (!ix)
1474 		    {
1475 		      line_nos[ix++] = 0;
1476 		      line_nos[ix++] = src_idx;
1477 		    }
1478 		  line_nos[ix++] = lineno;
1479 		}
1480 	      else
1481 		{
1482 		  const char *file_name = gcov_read_string ();
1483 
1484 		  if (!file_name)
1485 		    break;
1486 		  src_idx = find_source (file_name);
1487 		  line_nos[ix++] = 0;
1488 		  line_nos[ix++] = src_idx;
1489 		}
1490 	    }
1491 
1492 	  fn->blocks[blockno].u.line.encoding = line_nos;
1493 	  fn->blocks[blockno].u.line.num = ix;
1494 	}
1495       else if (current_tag && !GCOV_TAG_IS_SUBTAG (current_tag, tag))
1496 	{
1497 	  fn = NULL;
1498 	  current_tag = 0;
1499 	}
1500       gcov_sync (base, length);
1501       if (gcov_is_error ())
1502 	{
1503 	corrupt:;
1504 	  fnotice (stderr, "%s:corrupted\n", bbg_file_name);
1505 	  break;
1506 	}
1507     }
1508   gcov_close ();
1509 
1510   if (!fns)
1511     fnotice (stderr, "%s:no functions found\n", bbg_file_name);
1512 
1513   return fns;
1514 }
1515 
1516 /* Reads profiles from the count file and attach to each
1517    function. Return nonzero if fatal error.  */
1518 
1519 static int
1520 read_count_file (function_t *fns)
1521 {
1522   unsigned ix;
1523   unsigned version;
1524   unsigned tag;
1525   function_t *fn = NULL;
1526   int error = 0;
1527 
1528   if (!gcov_open (da_file_name, 1))
1529     {
1530       fnotice (stderr, "%s:cannot open data file, assuming not executed\n",
1531 	       da_file_name);
1532       no_data_file = 1;
1533       return 0;
1534     }
1535   if (!gcov_magic (gcov_read_unsigned (), GCOV_DATA_MAGIC))
1536     {
1537       fnotice (stderr, "%s:not a gcov data file\n", da_file_name);
1538     cleanup:;
1539       gcov_close ();
1540       return 1;
1541     }
1542   version = gcov_read_unsigned ();
1543   if (version != GCOV_VERSION)
1544     {
1545       char v[4], e[4];
1546 
1547       GCOV_UNSIGNED2STRING (v, version);
1548       GCOV_UNSIGNED2STRING (e, GCOV_VERSION);
1549 
1550       fnotice (stderr, "%s:version '%.4s', prefer version '%.4s'\n",
1551 	       da_file_name, v, e);
1552     }
1553   tag = gcov_read_unsigned ();
1554   if (tag != bbg_stamp)
1555     {
1556       fnotice (stderr, "%s:stamp mismatch with notes file\n", da_file_name);
1557       goto cleanup;
1558     }
1559 
1560   while ((tag = gcov_read_unsigned ()))
1561     {
1562       unsigned length = gcov_read_unsigned ();
1563       unsigned long base = gcov_position ();
1564 
1565       if (tag == GCOV_TAG_PROGRAM_SUMMARY)
1566 	{
1567 	  struct gcov_summary summary;
1568 	  gcov_read_summary (&summary);
1569 	  object_runs += summary.ctrs[GCOV_COUNTER_ARCS].runs;
1570 	  program_count++;
1571 	}
1572       else if (tag == GCOV_TAG_FUNCTION && !length)
1573 	; /* placeholder  */
1574       else if (tag == GCOV_TAG_FUNCTION && length == GCOV_TAG_FUNCTION_LENGTH)
1575 	{
1576 	  unsigned ident;
1577 	  struct function_info *fn_n;
1578 
1579 	  /* Try to find the function in the list.  To speed up the
1580 	     search, first start from the last function found.  */
1581 	  ident = gcov_read_unsigned ();
1582 	  fn_n = fns;
1583 	  for (fn = fn ? fn->next : NULL; ; fn = fn->next)
1584 	    {
1585 	      if (fn)
1586 		;
1587 	      else if ((fn = fn_n))
1588 		fn_n = NULL;
1589 	      else
1590 		{
1591 		  fnotice (stderr, "%s:unknown function '%u'\n",
1592 			   da_file_name, ident);
1593 		  break;
1594 		}
1595 	      if (fn->ident == ident)
1596 		break;
1597 	    }
1598 
1599 	  if (!fn)
1600 	    ;
1601 	  else if (gcov_read_unsigned () != fn->lineno_checksum
1602 		   || gcov_read_unsigned () != fn->cfg_checksum)
1603 	    {
1604 	    mismatch:;
1605 	      fnotice (stderr, "%s:profile mismatch for '%s'\n",
1606 		       da_file_name, fn->name);
1607 	      goto cleanup;
1608 	    }
1609 	}
1610       else if (tag == GCOV_TAG_FOR_COUNTER (GCOV_COUNTER_ARCS) && fn)
1611 	{
1612 	  if (length != GCOV_TAG_COUNTER_LENGTH (fn->num_counts))
1613 	    goto mismatch;
1614 
1615 	  if (!fn->counts)
1616 	    fn->counts = XCNEWVEC (gcov_type, fn->num_counts);
1617 
1618 	  for (ix = 0; ix != fn->num_counts; ix++)
1619 	    fn->counts[ix] += gcov_read_counter ();
1620 	}
1621       gcov_sync (base, length);
1622       if ((error = gcov_is_error ()))
1623 	{
1624 	  fnotice (stderr,
1625 		   error < 0
1626 		   ? N_("%s:overflowed\n")
1627 		   : N_("%s:corrupted\n"),
1628 		   da_file_name);
1629 	  goto cleanup;
1630 	}
1631     }
1632 
1633   gcov_close ();
1634   return 0;
1635 }
1636 
1637 /* Solve the flow graph. Propagate counts from the instrumented arcs
1638    to the blocks and the uninstrumented arcs.  */
1639 
1640 static void
1641 solve_flow_graph (function_t *fn)
1642 {
1643   unsigned ix;
1644   arc_t *arc;
1645   gcov_type *count_ptr = fn->counts;
1646   block_t *blk;
1647   block_t *valid_blocks = NULL;    /* valid, but unpropagated blocks.  */
1648   block_t *invalid_blocks = NULL;  /* invalid, but inferable blocks.  */
1649 
1650   /* The arcs were built in reverse order.  Fix that now.  */
1651   for (ix = fn->num_blocks; ix--;)
1652     {
1653       arc_t *arc_p, *arc_n;
1654 
1655       for (arc_p = NULL, arc = fn->blocks[ix].succ; arc;
1656 	   arc_p = arc, arc = arc_n)
1657 	{
1658 	  arc_n = arc->succ_next;
1659 	  arc->succ_next = arc_p;
1660 	}
1661       fn->blocks[ix].succ = arc_p;
1662 
1663       for (arc_p = NULL, arc = fn->blocks[ix].pred; arc;
1664 	   arc_p = arc, arc = arc_n)
1665 	{
1666 	  arc_n = arc->pred_next;
1667 	  arc->pred_next = arc_p;
1668 	}
1669       fn->blocks[ix].pred = arc_p;
1670     }
1671 
1672   if (fn->num_blocks < 2)
1673     fnotice (stderr, "%s:'%s' lacks entry and/or exit blocks\n",
1674 	     bbg_file_name, fn->name);
1675   else
1676     {
1677       if (fn->blocks[ENTRY_BLOCK].num_pred)
1678 	fnotice (stderr, "%s:'%s' has arcs to entry block\n",
1679 		 bbg_file_name, fn->name);
1680       else
1681 	/* We can't deduce the entry block counts from the lack of
1682 	   predecessors.  */
1683 	fn->blocks[ENTRY_BLOCK].num_pred = ~(unsigned)0;
1684 
1685       if (fn->blocks[EXIT_BLOCK].num_succ)
1686 	fnotice (stderr, "%s:'%s' has arcs from exit block\n",
1687 		 bbg_file_name, fn->name);
1688       else
1689 	/* Likewise, we can't deduce exit block counts from the lack
1690 	   of its successors.  */
1691 	fn->blocks[EXIT_BLOCK].num_succ = ~(unsigned)0;
1692     }
1693 
1694   /* Propagate the measured counts, this must be done in the same
1695      order as the code in profile.c  */
1696   for (ix = 0, blk = fn->blocks; ix != fn->num_blocks; ix++, blk++)
1697     {
1698       block_t const *prev_dst = NULL;
1699       int out_of_order = 0;
1700       int non_fake_succ = 0;
1701 
1702       for (arc = blk->succ; arc; arc = arc->succ_next)
1703 	{
1704 	  if (!arc->fake)
1705 	    non_fake_succ++;
1706 
1707 	  if (!arc->on_tree)
1708 	    {
1709 	      if (count_ptr)
1710 		arc->count = *count_ptr++;
1711 	      arc->count_valid = 1;
1712 	      blk->num_succ--;
1713 	      arc->dst->num_pred--;
1714 	    }
1715 	  if (prev_dst && prev_dst > arc->dst)
1716 	    out_of_order = 1;
1717 	  prev_dst = arc->dst;
1718 	}
1719       if (non_fake_succ == 1)
1720 	{
1721 	  /* If there is only one non-fake exit, it is an
1722 	     unconditional branch.  */
1723 	  for (arc = blk->succ; arc; arc = arc->succ_next)
1724 	    if (!arc->fake)
1725 	      {
1726 		arc->is_unconditional = 1;
1727 		/* If this block is instrumenting a call, it might be
1728 		   an artificial block. It is not artificial if it has
1729 		   a non-fallthrough exit, or the destination of this
1730 		   arc has more than one entry.  Mark the destination
1731 		   block as a return site, if none of those conditions
1732 		   hold.  */
1733 		if (blk->is_call_site && arc->fall_through
1734 		    && arc->dst->pred == arc && !arc->pred_next)
1735 		  arc->dst->is_call_return = 1;
1736 	      }
1737 	}
1738 
1739       /* Sort the successor arcs into ascending dst order. profile.c
1740 	 normally produces arcs in the right order, but sometimes with
1741 	 one or two out of order.  We're not using a particularly
1742 	 smart sort.  */
1743       if (out_of_order)
1744 	{
1745 	  arc_t *start = blk->succ;
1746 	  unsigned changes = 1;
1747 
1748 	  while (changes)
1749 	    {
1750 	      arc_t *arc, *arc_p, *arc_n;
1751 
1752 	      changes = 0;
1753 	      for (arc_p = NULL, arc = start; (arc_n = arc->succ_next);)
1754 		{
1755 		  if (arc->dst > arc_n->dst)
1756 		    {
1757 		      changes = 1;
1758 		      if (arc_p)
1759 			arc_p->succ_next = arc_n;
1760 		      else
1761 			start = arc_n;
1762 		      arc->succ_next = arc_n->succ_next;
1763 		      arc_n->succ_next = arc;
1764 		      arc_p = arc_n;
1765 		    }
1766 		  else
1767 		    {
1768 		      arc_p = arc;
1769 		      arc = arc_n;
1770 		    }
1771 		}
1772 	    }
1773 	  blk->succ = start;
1774 	}
1775 
1776       /* Place it on the invalid chain, it will be ignored if that's
1777 	 wrong.  */
1778       blk->invalid_chain = 1;
1779       blk->chain = invalid_blocks;
1780       invalid_blocks = blk;
1781     }
1782 
1783   while (invalid_blocks || valid_blocks)
1784     {
1785       while ((blk = invalid_blocks))
1786 	{
1787 	  gcov_type total = 0;
1788 	  const arc_t *arc;
1789 
1790 	  invalid_blocks = blk->chain;
1791 	  blk->invalid_chain = 0;
1792 	  if (!blk->num_succ)
1793 	    for (arc = blk->succ; arc; arc = arc->succ_next)
1794 	      total += arc->count;
1795 	  else if (!blk->num_pred)
1796 	    for (arc = blk->pred; arc; arc = arc->pred_next)
1797 	      total += arc->count;
1798 	  else
1799 	    continue;
1800 
1801 	  blk->count = total;
1802 	  blk->count_valid = 1;
1803 	  blk->chain = valid_blocks;
1804 	  blk->valid_chain = 1;
1805 	  valid_blocks = blk;
1806 	}
1807       while ((blk = valid_blocks))
1808 	{
1809 	  gcov_type total;
1810 	  arc_t *arc, *inv_arc;
1811 
1812 	  valid_blocks = blk->chain;
1813 	  blk->valid_chain = 0;
1814 	  if (blk->num_succ == 1)
1815 	    {
1816 	      block_t *dst;
1817 
1818 	      total = blk->count;
1819 	      inv_arc = NULL;
1820 	      for (arc = blk->succ; arc; arc = arc->succ_next)
1821 		{
1822 		  total -= arc->count;
1823 		  if (!arc->count_valid)
1824 		    inv_arc = arc;
1825 		}
1826 	      dst = inv_arc->dst;
1827 	      inv_arc->count_valid = 1;
1828 	      inv_arc->count = total;
1829 	      blk->num_succ--;
1830 	      dst->num_pred--;
1831 	      if (dst->count_valid)
1832 		{
1833 		  if (dst->num_pred == 1 && !dst->valid_chain)
1834 		    {
1835 		      dst->chain = valid_blocks;
1836 		      dst->valid_chain = 1;
1837 		      valid_blocks = dst;
1838 		    }
1839 		}
1840 	      else
1841 		{
1842 		  if (!dst->num_pred && !dst->invalid_chain)
1843 		    {
1844 		      dst->chain = invalid_blocks;
1845 		      dst->invalid_chain = 1;
1846 		      invalid_blocks = dst;
1847 		    }
1848 		}
1849 	    }
1850 	  if (blk->num_pred == 1)
1851 	    {
1852 	      block_t *src;
1853 
1854 	      total = blk->count;
1855 	      inv_arc = NULL;
1856 	      for (arc = blk->pred; arc; arc = arc->pred_next)
1857 		{
1858 		  total -= arc->count;
1859 		  if (!arc->count_valid)
1860 		    inv_arc = arc;
1861 		}
1862 	      src = inv_arc->src;
1863 	      inv_arc->count_valid = 1;
1864 	      inv_arc->count = total;
1865 	      blk->num_pred--;
1866 	      src->num_succ--;
1867 	      if (src->count_valid)
1868 		{
1869 		  if (src->num_succ == 1 && !src->valid_chain)
1870 		    {
1871 		      src->chain = valid_blocks;
1872 		      src->valid_chain = 1;
1873 		      valid_blocks = src;
1874 		    }
1875 		}
1876 	      else
1877 		{
1878 		  if (!src->num_succ && !src->invalid_chain)
1879 		    {
1880 		      src->chain = invalid_blocks;
1881 		      src->invalid_chain = 1;
1882 		      invalid_blocks = src;
1883 		    }
1884 		}
1885 	    }
1886 	}
1887     }
1888 
1889   /* If the graph has been correctly solved, every block will have a
1890      valid count.  */
1891   for (ix = 0; ix < fn->num_blocks; ix++)
1892     if (!fn->blocks[ix].count_valid)
1893       {
1894 	fnotice (stderr, "%s:graph is unsolvable for '%s'\n",
1895 		 bbg_file_name, fn->name);
1896 	break;
1897       }
1898 }
1899 
1900 /* Mark all the blocks only reachable via an incoming catch.  */
1901 
1902 static void
1903 find_exception_blocks (function_t *fn)
1904 {
1905   unsigned ix;
1906   block_t **queue = XALLOCAVEC (block_t *, fn->num_blocks);
1907 
1908   /* First mark all blocks as exceptional.  */
1909   for (ix = fn->num_blocks; ix--;)
1910     fn->blocks[ix].exceptional = 1;
1911 
1912   /* Now mark all the blocks reachable via non-fake edges */
1913   queue[0] = fn->blocks;
1914   queue[0]->exceptional = 0;
1915   for (ix = 1; ix;)
1916     {
1917       block_t *block = queue[--ix];
1918       const arc_t *arc;
1919 
1920       for (arc = block->succ; arc; arc = arc->succ_next)
1921 	if (!arc->fake && !arc->is_throw && arc->dst->exceptional)
1922 	  {
1923 	    arc->dst->exceptional = 0;
1924 	    queue[ix++] = arc->dst;
1925 	  }
1926     }
1927 }
1928 
1929 
1930 /* Increment totals in COVERAGE according to arc ARC.  */
1931 
1932 static void
1933 add_branch_counts (coverage_t *coverage, const arc_t *arc)
1934 {
1935   if (arc->is_call_non_return)
1936     {
1937       coverage->calls++;
1938       if (arc->src->count)
1939 	coverage->calls_executed++;
1940     }
1941   else if (!arc->is_unconditional)
1942     {
1943       coverage->branches++;
1944       if (arc->src->count)
1945 	coverage->branches_executed++;
1946       if (arc->count)
1947 	coverage->branches_taken++;
1948     }
1949 }
1950 
1951 /* Format a GCOV_TYPE integer as either a percent ratio, or absolute
1952    count.  If dp >= 0, format TOP/BOTTOM * 100 to DP decimal places.
1953    If DP is zero, no decimal point is printed. Only print 100% when
1954    TOP==BOTTOM and only print 0% when TOP=0.  If dp < 0, then simply
1955    format TOP.  Return pointer to a static string.  */
1956 
1957 static char const *
1958 format_gcov (gcov_type top, gcov_type bottom, int dp)
1959 {
1960   static char buffer[20];
1961 
1962   /* Handle invalid values that would result in a misleading value.  */
1963   if (bottom != 0 && top > bottom && dp >= 0)
1964     {
1965       sprintf (buffer, "NAN %%");
1966       return buffer;
1967     }
1968 
1969   if (dp >= 0)
1970     {
1971       float ratio = bottom ? (float)top / bottom : 0;
1972       int ix;
1973       unsigned limit = 100;
1974       unsigned percent;
1975 
1976       for (ix = dp; ix--; )
1977 	limit *= 10;
1978 
1979       percent = (unsigned) (ratio * limit + (float)0.5);
1980       if (percent <= 0 && top)
1981 	percent = 1;
1982       else if (percent >= limit && top != bottom)
1983 	percent = limit - 1;
1984       ix = sprintf (buffer, "%.*u%%", dp + 1, percent);
1985       if (dp)
1986 	{
1987 	  dp++;
1988 	  do
1989 	    {
1990 	      buffer[ix+1] = buffer[ix];
1991 	      ix--;
1992 	    }
1993 	  while (dp--);
1994 	  buffer[ix + 1] = '.';
1995 	}
1996     }
1997   else
1998     sprintf (buffer, "%" PRId64, (int64_t)top);
1999 
2000   return buffer;
2001 }
2002 
2003 /* Summary of execution */
2004 
2005 static void
2006 executed_summary (unsigned lines, unsigned executed)
2007 {
2008   if (lines)
2009     fnotice (stdout, "Lines executed:%s of %d\n",
2010 	     format_gcov (executed, lines, 2), lines);
2011   else
2012     fnotice (stdout, "No executable lines\n");
2013 }
2014 
2015 /* Output summary info for a function or file.  */
2016 
2017 static void
2018 function_summary (const coverage_t *coverage, const char *title)
2019 {
2020   fnotice (stdout, "%s '%s'\n", title, coverage->name);
2021   executed_summary (coverage->lines, coverage->lines_executed);
2022 
2023   if (flag_branches)
2024     {
2025       if (coverage->branches)
2026 	{
2027 	  fnotice (stdout, "Branches executed:%s of %d\n",
2028 		   format_gcov (coverage->branches_executed,
2029 				coverage->branches, 2),
2030 		   coverage->branches);
2031 	  fnotice (stdout, "Taken at least once:%s of %d\n",
2032 		   format_gcov (coverage->branches_taken,
2033 				coverage->branches, 2),
2034 		   coverage->branches);
2035 	}
2036       else
2037 	fnotice (stdout, "No branches\n");
2038       if (coverage->calls)
2039 	fnotice (stdout, "Calls executed:%s of %d\n",
2040 		 format_gcov (coverage->calls_executed, coverage->calls, 2),
2041 		 coverage->calls);
2042       else
2043 	fnotice (stdout, "No calls\n");
2044     }
2045 }
2046 
2047 /* Canonicalize the filename NAME by canonicalizing directory
2048    separators, eliding . components and resolving .. components
2049    appropriately.  Always returns a unique string.  */
2050 
2051 static char *
2052 canonicalize_name (const char *name)
2053 {
2054   /* The canonical name cannot be longer than the incoming name.  */
2055   char *result = XNEWVEC (char, strlen (name) + 1);
2056   const char *base = name, *probe;
2057   char *ptr = result;
2058   char *dd_base;
2059   int slash = 0;
2060 
2061 #if HAVE_DOS_BASED_FILE_SYSTEM
2062   if (base[0] && base[1] == ':')
2063     {
2064       result[0] = base[0];
2065       result[1] = ':';
2066       base += 2;
2067       ptr += 2;
2068     }
2069 #endif
2070   for (dd_base = ptr; *base; base = probe)
2071     {
2072       size_t len;
2073 
2074       for (probe = base; *probe; probe++)
2075 	if (IS_DIR_SEPARATOR (*probe))
2076 	  break;
2077 
2078       len = probe - base;
2079       if (len == 1 && base[0] == '.')
2080 	/* Elide a '.' directory */
2081 	;
2082       else if (len == 2 && base[0] == '.' && base[1] == '.')
2083 	{
2084 	  /* '..', we can only elide it and the previous directory, if
2085 	     we're not a symlink.  */
2086 	  struct stat ATTRIBUTE_UNUSED buf;
2087 
2088 	  *ptr = 0;
2089 	  if (dd_base == ptr
2090 #if defined (S_ISLNK)
2091 	      /* S_ISLNK is not POSIX.1-1996.  */
2092 	      || stat (result, &buf) || S_ISLNK (buf.st_mode)
2093 #endif
2094 		)
2095 	    {
2096 	      /* Cannot elide, or unreadable or a symlink.  */
2097 	      dd_base = ptr + 2 + slash;
2098 	      goto regular;
2099 	    }
2100 	  while (ptr != dd_base && *ptr != '/')
2101 	    ptr--;
2102 	  slash = ptr != result;
2103 	}
2104       else
2105 	{
2106 	regular:
2107 	  /* Regular pathname component.  */
2108 	  if (slash)
2109 	    *ptr++ = '/';
2110 	  memcpy (ptr, base, len);
2111 	  ptr += len;
2112 	  slash = 1;
2113 	}
2114 
2115       for (; IS_DIR_SEPARATOR (*probe); probe++)
2116 	continue;
2117     }
2118   *ptr = 0;
2119 
2120   return result;
2121 }
2122 
2123 /* Print hex representation of 16 bytes from SUM and write it to BUFFER.  */
2124 
2125 static void
2126 md5sum_to_hex (const char *sum, char *buffer)
2127 {
2128   for (unsigned i = 0; i < 16; i++)
2129     sprintf (buffer + (2 * i), "%02x", (unsigned char)sum[i]);
2130 }
2131 
2132 /* Generate an output file name. INPUT_NAME is the canonicalized main
2133    input file and SRC_NAME is the canonicalized file name.
2134    LONG_OUTPUT_NAMES and PRESERVE_PATHS affect name generation.  With
2135    long_output_names we prepend the processed name of the input file
2136    to each output name (except when the current source file is the
2137    input file, so you don't get a double concatenation). The two
2138    components are separated by '##'.  With preserve_paths we create a
2139    filename from all path components of the source file, replacing '/'
2140    with '#', and .. with '^', without it we simply take the basename
2141    component.  (Remember, the canonicalized name will already have
2142    elided '.' components and converted \\ separators.)  */
2143 
2144 static char *
2145 make_gcov_file_name (const char *input_name, const char *src_name)
2146 {
2147   char *ptr;
2148   char *result;
2149 
2150   if (flag_long_names && input_name && strcmp (src_name, input_name))
2151     {
2152       /* Generate the input filename part.  */
2153       result = XNEWVEC (char, strlen (input_name) + strlen (src_name) + 10);
2154 
2155       ptr = result;
2156       ptr = mangle_name (input_name, ptr);
2157       ptr[0] = ptr[1] = '#';
2158       ptr += 2;
2159     }
2160   else
2161     {
2162       result = XNEWVEC (char, strlen (src_name) + 10);
2163       ptr = result;
2164     }
2165 
2166   ptr = mangle_name (src_name, ptr);
2167   strcpy (ptr, ".gcov");
2168 
2169   /* When hashing filenames, we shorten them by only using the filename
2170      component and appending a hash of the full (mangled) pathname.  */
2171   if (flag_hash_filenames)
2172     {
2173       md5_ctx ctx;
2174       char md5sum[16];
2175       char md5sum_hex[33];
2176 
2177       md5_init_ctx (&ctx);
2178       md5_process_bytes (src_name, strlen (src_name), &ctx);
2179       md5_finish_ctx (&ctx, md5sum);
2180       md5sum_to_hex (md5sum, md5sum_hex);
2181       free (result);
2182 
2183       result = XNEWVEC (char, strlen (src_name) + 50);
2184       ptr = result;
2185       ptr = mangle_name (src_name, ptr);
2186       ptr[0] = ptr[1] = '#';
2187       ptr += 2;
2188       memcpy (ptr, md5sum_hex, 32);
2189       ptr += 32;
2190       strcpy (ptr, ".gcov");
2191     }
2192 
2193   return result;
2194 }
2195 
2196 static char *
2197 mangle_name (char const *base, char *ptr)
2198 {
2199   size_t len;
2200 
2201   /* Generate the source filename part.  */
2202   if (!flag_preserve_paths)
2203     {
2204       base = lbasename (base);
2205       len = strlen (base);
2206       memcpy (ptr, base, len);
2207       ptr += len;
2208     }
2209   else
2210     {
2211       /* Convert '/' to '#', convert '..' to '^',
2212 	 convert ':' to '~' on DOS based file system.  */
2213       const char *probe;
2214 
2215 #if HAVE_DOS_BASED_FILE_SYSTEM
2216       if (base[0] && base[1] == ':')
2217 	{
2218 	  ptr[0] = base[0];
2219 	  ptr[1] = '~';
2220 	  ptr += 2;
2221 	  base += 2;
2222 	}
2223 #endif
2224       for (; *base; base = probe)
2225 	{
2226 	  size_t len;
2227 
2228 	  for (probe = base; *probe; probe++)
2229 	    if (*probe == '/')
2230 	      break;
2231 	  len = probe - base;
2232 	  if (len == 2 && base[0] == '.' && base[1] == '.')
2233 	    *ptr++ = '^';
2234 	  else
2235 	    {
2236 	      memcpy (ptr, base, len);
2237 	      ptr += len;
2238 	    }
2239 	  if (*probe)
2240 	    {
2241 	      *ptr++ = '#';
2242 	      probe++;
2243 	    }
2244 	}
2245     }
2246 
2247   return ptr;
2248 }
2249 
2250 /* Scan through the bb_data for each line in the block, increment
2251    the line number execution count indicated by the execution count of
2252    the appropriate basic block.  */
2253 
2254 static void
2255 add_line_counts (coverage_t *coverage, function_t *fn)
2256 {
2257   unsigned ix;
2258   line_t *line = NULL; /* This is propagated from one iteration to the
2259 			  next.  */
2260 
2261   /* Scan each basic block.  */
2262   for (ix = 0; ix != fn->num_blocks; ix++)
2263     {
2264       block_t *block = &fn->blocks[ix];
2265       unsigned *encoding;
2266       const source_t *src = NULL;
2267       unsigned jx;
2268 
2269       if (block->count && ix && ix + 1 != fn->num_blocks)
2270 	fn->blocks_executed++;
2271       for (jx = 0, encoding = block->u.line.encoding;
2272 	   jx != block->u.line.num; jx++, encoding++)
2273 	if (!*encoding)
2274 	  {
2275 	    src = &sources[*++encoding];
2276 	    jx++;
2277 	  }
2278 	else
2279 	  {
2280 	    line = &src->lines[*encoding];
2281 
2282 	    if (coverage)
2283 	      {
2284 		if (!line->exists)
2285 		  coverage->lines++;
2286 		if (!line->count && block->count)
2287 		  coverage->lines_executed++;
2288 	      }
2289 	    line->exists = 1;
2290 	    if (!block->exceptional)
2291 	      line->unexceptional = 1;
2292 	    line->count += block->count;
2293 	  }
2294       free (block->u.line.encoding);
2295       block->u.cycle.arc = NULL;
2296       block->u.cycle.ident = ~0U;
2297 
2298       if (!ix || ix + 1 == fn->num_blocks)
2299 	/* Entry or exit block */;
2300       else if (flag_all_blocks)
2301 	{
2302 	  line_t *block_line = line;
2303 
2304 	  if (!block_line)
2305 	    block_line = &sources[fn->src].lines[fn->line];
2306 
2307 	  block->chain = block_line->u.blocks;
2308 	  block_line->u.blocks = block;
2309 	}
2310       else if (flag_branches)
2311 	{
2312 	  arc_t *arc;
2313 
2314 	  for (arc = block->succ; arc; arc = arc->succ_next)
2315 	    {
2316 	      arc->line_next = line->u.branches;
2317 	      line->u.branches = arc;
2318 	      if (coverage && !arc->is_unconditional)
2319 		add_branch_counts (coverage, arc);
2320 	    }
2321 	}
2322     }
2323   if (!line)
2324     fnotice (stderr, "%s:no lines for '%s'\n", bbg_file_name, fn->name);
2325 }
2326 
2327 /* Accumulate the line counts of a file.  */
2328 
2329 static void
2330 accumulate_line_counts (source_t *src)
2331 {
2332   line_t *line;
2333   function_t *fn, *fn_p, *fn_n;
2334   unsigned ix;
2335 
2336   /* Reverse the function order.  */
2337   for (fn = src->functions, fn_p = NULL; fn; fn_p = fn, fn = fn_n)
2338     {
2339       fn_n = fn->next_file_fn;
2340       fn->next_file_fn = fn_p;
2341     }
2342   src->functions = fn_p;
2343 
2344   for (ix = src->num_lines, line = src->lines; ix--; line++)
2345     {
2346       if (!flag_all_blocks)
2347 	{
2348 	  arc_t *arc, *arc_p, *arc_n;
2349 
2350 	  /* Total and reverse the branch information.  */
2351 	  for (arc = line->u.branches, arc_p = NULL; arc;
2352 	       arc_p = arc, arc = arc_n)
2353 	    {
2354 	      arc_n = arc->line_next;
2355 	      arc->line_next = arc_p;
2356 
2357 	      add_branch_counts (&src->coverage, arc);
2358 	    }
2359 	  line->u.branches = arc_p;
2360 	}
2361       else if (line->u.blocks)
2362 	{
2363 	  /* The user expects the line count to be the number of times
2364 	     a line has been executed. Simply summing the block count
2365 	     will give an artificially high number.  The Right Thing
2366 	     is to sum the entry counts to the graph of blocks on this
2367 	     line, then find the elementary cycles of the local graph
2368 	     and add the transition counts of those cycles.  */
2369 	  block_t *block, *block_p, *block_n;
2370 	  gcov_type count = 0;
2371 
2372 	  /* Reverse the block information.  */
2373 	  for (block = line->u.blocks, block_p = NULL; block;
2374 	       block_p = block, block = block_n)
2375 	    {
2376 	      block_n = block->chain;
2377 	      block->chain = block_p;
2378 	      block->u.cycle.ident = ix;
2379 	    }
2380 	  line->u.blocks = block_p;
2381 
2382 	  /* Sum the entry arcs.  */
2383 	  for (block = line->u.blocks; block; block = block->chain)
2384 	    {
2385 	      arc_t *arc;
2386 
2387 	      for (arc = block->pred; arc; arc = arc->pred_next)
2388 		if (flag_branches)
2389 		  add_branch_counts (&src->coverage, arc);
2390 	    }
2391 
2392 	  /* Cycle detection.  */
2393 	  for (block = line->u.blocks; block; block = block->chain)
2394 	    {
2395 	      for (arc_t *arc = block->pred; arc; arc = arc->pred_next)
2396 		if (!line->has_block (arc->src))
2397 		  count += arc->count;
2398 	      for (arc_t *arc = block->succ; arc; arc = arc->succ_next)
2399 		arc->cs_count = arc->count;
2400 	    }
2401 
2402 	  /* Now, add the count of loops entirely on this line.  */
2403 	  count += get_cycles_count (*line);
2404 	  line->count = count;
2405 	}
2406 
2407       if (line->exists)
2408 	{
2409 	  src->coverage.lines++;
2410 	  if (line->count)
2411 	    src->coverage.lines_executed++;
2412 	}
2413     }
2414 }
2415 
2416 /* Output information about ARC number IX.  Returns nonzero if
2417    anything is output.  */
2418 
2419 static int
2420 output_branch_count (FILE *gcov_file, int ix, const arc_t *arc)
2421 {
2422   if (arc->is_call_non_return)
2423     {
2424       if (arc->src->count)
2425 	{
2426 	  fnotice (gcov_file, "call   %2d returned %s\n", ix,
2427 		   format_gcov (arc->src->count - arc->count,
2428 				arc->src->count, -flag_counts));
2429 	}
2430       else
2431 	fnotice (gcov_file, "call   %2d never executed\n", ix);
2432     }
2433   else if (!arc->is_unconditional)
2434     {
2435       if (arc->src->count)
2436 	fnotice (gcov_file, "branch %2d taken %s%s\n", ix,
2437 		 format_gcov (arc->count, arc->src->count, -flag_counts),
2438 		 arc->fall_through ? " (fallthrough)"
2439 		 : arc->is_throw ? " (throw)" : "");
2440       else
2441 	fnotice (gcov_file, "branch %2d never executed\n", ix);
2442     }
2443   else if (flag_unconditional && !arc->dst->is_call_return)
2444     {
2445       if (arc->src->count)
2446 	fnotice (gcov_file, "unconditional %2d taken %s\n", ix,
2447 		 format_gcov (arc->count, arc->src->count, -flag_counts));
2448       else
2449 	fnotice (gcov_file, "unconditional %2d never executed\n", ix);
2450     }
2451   else
2452     return 0;
2453   return 1;
2454 }
2455 
2456 static const char *
2457 read_line (FILE *file)
2458 {
2459   static char *string;
2460   static size_t string_len;
2461   size_t pos = 0;
2462   char *ptr;
2463 
2464   if (!string_len)
2465     {
2466       string_len = 200;
2467       string = XNEWVEC (char, string_len);
2468     }
2469 
2470   while ((ptr = fgets (string + pos, string_len - pos, file)))
2471     {
2472       size_t len = strlen (string + pos);
2473 
2474       if (len && string[pos + len - 1] == '\n')
2475 	{
2476 	  string[pos + len - 1] = 0;
2477 	  return string;
2478 	}
2479       pos += len;
2480       /* If the file contains NUL characters or an incomplete
2481 	 last line, which can happen more than once in one run,
2482 	 we have to avoid doubling the STRING_LEN unnecessarily.  */
2483       if (pos > string_len / 2)
2484 	{
2485 	  string_len *= 2;
2486 	  string = XRESIZEVEC (char, string, string_len);
2487 	}
2488     }
2489 
2490   return pos ? string : NULL;
2491 }
2492 
2493 /* Read in the source file one line at a time, and output that line to
2494    the gcov file preceded by its execution count and other
2495    information.  */
2496 
2497 static void
2498 output_lines (FILE *gcov_file, const source_t *src)
2499 {
2500   FILE *source_file;
2501   unsigned line_num;	/* current line number.  */
2502   const line_t *line;           /* current line info ptr.  */
2503   const char *retval = "";	/* status of source file reading.  */
2504   function_t *fn = NULL;
2505 
2506   fprintf (gcov_file, "%9s:%5d:Source:%s\n", "-", 0, src->coverage.name);
2507   if (!multiple_files)
2508     {
2509       fprintf (gcov_file, "%9s:%5d:Graph:%s\n", "-", 0, bbg_file_name);
2510       fprintf (gcov_file, "%9s:%5d:Data:%s\n", "-", 0,
2511 	       no_data_file ? "-" : da_file_name);
2512       fprintf (gcov_file, "%9s:%5d:Runs:%u\n", "-", 0, object_runs);
2513     }
2514   fprintf (gcov_file, "%9s:%5d:Programs:%u\n", "-", 0, program_count);
2515 
2516   source_file = fopen (src->name, "r");
2517   if (!source_file)
2518     {
2519       fnotice (stderr, "Cannot open source file %s\n", src->name);
2520       retval = NULL;
2521     }
2522   else if (src->file_time == 0)
2523     fprintf (gcov_file, "%9s:%5d:Source is newer than graph\n", "-", 0);
2524 
2525   if (flag_branches)
2526     fn = src->functions;
2527 
2528   for (line_num = 1, line = &src->lines[line_num];
2529        line_num < src->num_lines; line_num++, line++)
2530     {
2531       for (; fn && fn->line == line_num; fn = fn->next_file_fn)
2532 	{
2533 	  arc_t *arc = fn->blocks[EXIT_BLOCK].pred;
2534 	  gcov_type return_count = fn->blocks[EXIT_BLOCK].count;
2535 	  gcov_type called_count = fn->blocks[ENTRY_BLOCK].count;
2536 
2537 	  for (; arc; arc = arc->pred_next)
2538 	    if (arc->fake)
2539 	      return_count -= arc->count;
2540 
2541 	  fprintf (gcov_file, "function %s", flag_demangled_names ?
2542                    fn->demangled_name : fn->name);
2543 	  fprintf (gcov_file, " called %s",
2544 		   format_gcov (called_count, 0, -1));
2545 	  fprintf (gcov_file, " returned %s",
2546 		   format_gcov (return_count, called_count, 0));
2547 	  fprintf (gcov_file, " blocks executed %s",
2548 		   format_gcov (fn->blocks_executed, fn->num_blocks - 2, 0));
2549 	  fprintf (gcov_file, "\n");
2550 	}
2551 
2552       if (retval)
2553 	retval = read_line (source_file);
2554 
2555       /* For lines which don't exist in the .bb file, print '-' before
2556 	 the source line.  For lines which exist but were never
2557 	 executed, print '#####' or '=====' before the source line.
2558 	 Otherwise, print the execution count before the source line.
2559 	 There are 16 spaces of indentation added before the source
2560 	 line so that tabs won't be messed up.  */
2561       fprintf (gcov_file, "%9s:%5u:%s\n",
2562 	       !line->exists ? "-" : line->count
2563 	       ? format_gcov (line->count, 0, -1)
2564 	       : line->unexceptional ? "#####" : "=====", line_num,
2565 	       retval ? retval : "/*EOF*/");
2566 
2567       if (flag_all_blocks)
2568 	{
2569 	  block_t *block;
2570 	  arc_t *arc;
2571 	  int ix, jx;
2572 
2573 	  for (ix = jx = 0, block = line->u.blocks; block;
2574 	       block = block->chain)
2575 	    {
2576 	      if (!block->is_call_return)
2577 		fprintf (gcov_file, "%9s:%5u-block %2d\n",
2578 			 !line->exists ? "-" : block->count
2579 			 ? format_gcov (block->count, 0, -1)
2580 			 : block->exceptional ? "%%%%%" : "$$$$$",
2581 			 line_num, ix++);
2582 	      if (flag_branches)
2583 		for (arc = block->succ; arc; arc = arc->succ_next)
2584 		  jx += output_branch_count (gcov_file, jx, arc);
2585 	    }
2586 	}
2587       else if (flag_branches)
2588 	{
2589 	  int ix;
2590 	  arc_t *arc;
2591 
2592 	  for (ix = 0, arc = line->u.branches; arc; arc = arc->line_next)
2593 	    ix += output_branch_count (gcov_file, ix, arc);
2594 	}
2595     }
2596 
2597   /* Handle all remaining source lines.  There may be lines after the
2598      last line of code.  */
2599   if (retval)
2600     {
2601       for (; (retval = read_line (source_file)); line_num++)
2602 	fprintf (gcov_file, "%9s:%5u:%s\n", "-", line_num, retval);
2603     }
2604 
2605   if (source_file)
2606     fclose (source_file);
2607 }
2608