analyzer: fix feasibility false +ve on jumps through function ptrs [PR107582]
[platform/upstream/gcc.git] / gcc / coverage.cc
1 /* Read and write coverage files, and associated functionality.
2    Copyright (C) 1990-2022 Free Software Foundation, Inc.
3    Contributed by James E. Wilson, UC Berkeley/Cygnus Support;
4    based on some ideas from Dain Samples of UC Berkeley.
5    Further mangling by Bob Manson, Cygnus Support.
6    Further mangled by Nathan Sidwell, CodeSourcery
7
8 This file is part of GCC.
9
10 GCC is free software; you can redistribute it and/or modify it under
11 the terms of the GNU General Public License as published by the Free
12 Software Foundation; either version 3, or (at your option) any later
13 version.
14
15 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
16 WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
18 for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with GCC; see the file COPYING3.  If not see
22 <http://www.gnu.org/licenses/>.  */
23
24
25 #define GCOV_LINKAGE
26
27 #include "config.h"
28 #include "system.h"
29 #include "coretypes.h"
30 #include "backend.h"
31 #include "target.h"
32 #include "rtl.h"
33 #include "tree.h"
34 #include "tree-pass.h"
35 #include "memmodel.h"
36 #include "tm_p.h"
37 #include "stringpool.h"
38 #include "cgraph.h"
39 #include "coverage.h"
40 #include "diagnostic-core.h"
41 #include "fold-const.h"
42 #include "stor-layout.h"
43 #include "output.h"
44 #include "toplev.h"
45 #include "langhooks.h"
46 #include "tree-iterator.h"
47 #include "context.h"
48 #include "pass_manager.h"
49 #include "intl.h"
50 #include "auto-profile.h"
51 #include "profile.h"
52 #include "diagnostic.h"
53 #include "varasm.h"
54 #include "file-prefix-map.h"
55
56 #include "gcov-io.cc"
57
58 struct GTY((chain_next ("%h.next"))) coverage_data
59 {
60   struct coverage_data *next;    /* next function */
61   unsigned ident;                /* function ident */
62   unsigned lineno_checksum;      /* function lineno checksum */
63   unsigned cfg_checksum;         /* function cfg checksum */
64   tree fn_decl;                  /* the function decl */
65   tree ctr_vars[GCOV_COUNTERS];  /* counter variables.  */
66 };
67
68 /* Counts information for a function.  */
69 struct counts_entry : pointer_hash <counts_entry>
70 {
71   /* We hash by  */
72   unsigned ident;
73   unsigned ctr;
74
75   /* Store  */
76   unsigned lineno_checksum;
77   unsigned cfg_checksum;
78   gcov_type *counts;
79   unsigned n_counts;
80
81   /* hash_table support.  */
82   static inline hashval_t hash (const counts_entry *);
83   static int equal (const counts_entry *, const counts_entry *);
84   static void remove (counts_entry *);
85 };
86
87 static GTY(()) struct coverage_data *functions_head = 0;
88 static struct coverage_data **functions_tail = &functions_head;
89 static unsigned no_coverage = 0;
90
91 /* Cumulative counter information for whole program.  */
92 static unsigned prg_ctr_mask; /* Mask of counter types generated.  */
93
94 /* Counter information for current function.  */
95 static unsigned fn_ctr_mask; /* Mask of counters used.  */
96 static GTY(()) tree fn_v_ctrs[GCOV_COUNTERS];   /* counter variables.  */
97 static unsigned fn_n_ctrs[GCOV_COUNTERS]; /* Counters allocated.  */
98 static unsigned fn_b_ctrs[GCOV_COUNTERS]; /* Allocation base.  */
99
100 /* Coverage info VAR_DECL and function info type nodes.  */
101 static GTY(()) tree gcov_info_var;
102 static GTY(()) tree gcov_fn_info_type;
103 static GTY(()) tree gcov_fn_info_ptr_type;
104
105 /* Name of the notes (gcno) output file.  The "bbg" prefix is for
106    historical reasons, when the notes file contained only the
107    basic block graph notes.
108    If this is NULL we're not writing to the notes file.  */
109 static char *bbg_file_name;
110
111 /* File stamp for notes file.  */
112 static unsigned bbg_file_stamp;
113
114 /* Name of the count data (gcda) file.  */
115 static char *da_file_name;
116
117 /* The names of merge functions for counters.  */
118 #define STR(str) #str
119 #define DEF_GCOV_COUNTER(COUNTER, NAME, FN_TYPE) STR(__gcov_merge ## FN_TYPE),
120 static const char *const ctr_merge_functions[GCOV_COUNTERS] = {
121 #include "gcov-counter.def"
122 };
123 #undef DEF_GCOV_COUNTER
124 #undef STR
125
126 #define DEF_GCOV_COUNTER(COUNTER, NAME, FN_TYPE) NAME,
127 static const char *const ctr_names[GCOV_COUNTERS] = {
128 #include "gcov-counter.def"
129 };
130 #undef DEF_GCOV_COUNTER
131
132 /* Forward declarations.  */
133 static tree build_var (tree, tree, int);
134 \f
135 /* Return the type node for gcov_type.  */
136
137 tree
138 get_gcov_type (void)
139 {
140   scalar_int_mode mode
141     = smallest_int_mode_for_size (targetm.gcov_type_size ());
142   return lang_hooks.types.type_for_mode (mode, false);
143 }
144
145 /* Return the type node for gcov_unsigned_t.  */
146
147 static tree
148 get_gcov_unsigned_t (void)
149 {
150   scalar_int_mode mode = smallest_int_mode_for_size (32);
151   return lang_hooks.types.type_for_mode (mode, true);
152 }
153 \f
154 inline hashval_t
155 counts_entry::hash (const counts_entry *entry)
156 {
157   return entry->ident * GCOV_COUNTERS + entry->ctr;
158 }
159
160 inline int
161 counts_entry::equal (const counts_entry *entry1, const counts_entry *entry2)
162 {
163   return entry1->ident == entry2->ident && entry1->ctr == entry2->ctr;
164 }
165
166 inline void
167 counts_entry::remove (counts_entry *entry)
168 {
169   free (entry->counts);
170   free (entry);
171 }
172
173 /* Hash table of count data.  */
174 static hash_table<counts_entry> *counts_hash;
175
176 /* Read in the counts file, if available.  */
177
178 static void
179 read_counts_file (void)
180 {
181   gcov_unsigned_t fn_ident = 0;
182   gcov_unsigned_t tag;
183   int is_error = 0;
184   unsigned lineno_checksum = 0;
185   unsigned cfg_checksum = 0;
186
187   if (!gcov_open (da_file_name, 1))
188     return;
189
190   if (!gcov_magic (gcov_read_unsigned (), GCOV_DATA_MAGIC))
191     {
192       warning (0, "%qs is not a gcov data file", da_file_name);
193       gcov_close ();
194       return;
195     }
196   else if ((tag = gcov_read_unsigned ()) != GCOV_VERSION)
197     {
198       char v[4], e[4];
199
200       GCOV_UNSIGNED2STRING (v, tag);
201       GCOV_UNSIGNED2STRING (e, GCOV_VERSION);
202
203       warning (0, "%qs is version %q.*s, expected version %q.*s",
204                da_file_name, 4, v, 4, e);
205       gcov_close ();
206       return;
207     }
208
209   /* Read the stamp, used for creating a generation count.  */
210   tag = gcov_read_unsigned ();
211   bbg_file_stamp = crc32_unsigned (bbg_file_stamp, tag);
212
213   /* Read checksum.  */
214   gcov_read_unsigned ();
215
216   counts_hash = new hash_table<counts_entry> (10);
217   while ((tag = gcov_read_unsigned ()))
218     {
219       gcov_unsigned_t length;
220       gcov_position_t offset;
221
222       length = gcov_read_unsigned ();
223       offset = gcov_position ();
224       if (tag == GCOV_TAG_FUNCTION)
225         {
226           if (length)
227             {
228               fn_ident = gcov_read_unsigned ();
229               lineno_checksum = gcov_read_unsigned ();
230               cfg_checksum = gcov_read_unsigned ();
231             }
232           else
233             fn_ident = lineno_checksum = cfg_checksum = 0;
234         }
235       else if (tag == GCOV_TAG_OBJECT_SUMMARY)
236         {
237           profile_info = XCNEW (gcov_summary);
238           profile_info->runs = gcov_read_unsigned ();
239           profile_info->sum_max = gcov_read_unsigned ();
240         }
241       else if (GCOV_TAG_IS_COUNTER (tag) && fn_ident)
242         {
243           counts_entry **slot, *entry, elt;
244           int read_length = (int)length;
245           length = read_length > 0 ? read_length : 0;
246           unsigned n_counts = GCOV_TAG_COUNTER_NUM (abs (read_length));
247           unsigned ix;
248
249           elt.ident = fn_ident;
250           elt.ctr = GCOV_COUNTER_FOR_TAG (tag);
251
252           slot = counts_hash->find_slot (&elt, INSERT);
253           entry = *slot;
254           if (!entry)
255             {
256               *slot = entry = XCNEW (counts_entry);
257               entry->ident = fn_ident;
258               entry->ctr = elt.ctr;
259               entry->lineno_checksum = lineno_checksum;
260               entry->cfg_checksum = cfg_checksum;
261               entry->counts = XCNEWVEC (gcov_type, n_counts);
262               entry->n_counts = n_counts;
263             }
264           else if (entry->lineno_checksum != lineno_checksum
265                    || entry->cfg_checksum != cfg_checksum)
266             {
267               error ("profile data for function %u is corrupted", fn_ident);
268               error ("checksum is (%x,%x) instead of (%x,%x)",
269                      entry->lineno_checksum, entry->cfg_checksum,
270                      lineno_checksum, cfg_checksum);
271               delete counts_hash;
272               counts_hash = NULL;
273               break;
274             }
275           if (read_length > 0)
276             for (ix = 0; ix != n_counts; ix++)
277               entry->counts[ix] = gcov_read_counter ();
278         }
279       gcov_sync (offset, length);
280       if ((is_error = gcov_is_error ()))
281         {
282           error (is_error < 0
283                  ? G_("%qs has overflowed")
284                  : G_("%qs is corrupted"),
285                  da_file_name);
286           delete counts_hash;
287           counts_hash = NULL;
288           break;
289         }
290     }
291
292   gcov_close ();
293 }
294
295 /* Returns the counters for a particular tag.  */
296
297 gcov_type *
298 get_coverage_counts (unsigned counter, unsigned cfg_checksum,
299                      unsigned lineno_checksum, unsigned int n_counts)
300 {
301   counts_entry *entry, elt;
302
303   /* No hash table, no counts.  */
304   if (!counts_hash)
305     {
306       static int warned = 0;
307
308       if (!warned++)
309         {
310           warning (OPT_Wmissing_profile,
311                    "%qs profile count data file not found",
312                    da_file_name);
313           if (dump_enabled_p ())
314             {
315               dump_user_location_t loc
316                 = dump_user_location_t::from_location_t (input_location);
317               dump_printf_loc (MSG_MISSED_OPTIMIZATION, loc,
318                                "file %s not found, %s\n", da_file_name,
319                                (flag_guess_branch_prob
320                                 ? "execution counts estimated"
321                                 : "execution counts assumed to be zero"));
322             }
323         }
324       return NULL;
325     }
326   if (param_profile_func_internal_id)
327     elt.ident = current_function_funcdef_no + 1;
328   else
329     {
330       gcc_assert (coverage_node_map_initialized_p ());
331       elt.ident = cgraph_node::get (current_function_decl)->profile_id;
332     }
333   elt.ctr = counter;
334   entry = counts_hash->find (&elt);
335   if (!entry)
336     {
337       if (counter == GCOV_COUNTER_ARCS)
338         warning_at (DECL_SOURCE_LOCATION (current_function_decl),
339                     OPT_Wmissing_profile,
340                     "profile for function %qD not found in profile data",
341                     current_function_decl);
342       /* The function was not emitted, or is weak and not chosen in the
343          final executable.  Silently fail, because there's nothing we
344          can do about it.  */
345       return NULL;
346     }
347
348   if (entry->cfg_checksum != cfg_checksum
349       || (counter != GCOV_COUNTER_V_INDIR
350           && counter != GCOV_COUNTER_V_TOPN
351           && entry->n_counts != n_counts))
352     {
353       static int warned = 0;
354       bool warning_printed = false;
355
356       if (entry->n_counts != n_counts)
357         warning_printed =
358           warning_at (DECL_SOURCE_LOCATION (current_function_decl),
359                       OPT_Wcoverage_mismatch,
360                       "number of counters in profile data for function %qD "
361                       "does not match "
362                       "its profile data (counter %qs, expected %i and have %i)",
363                       current_function_decl,
364                       ctr_names[counter], entry->n_counts, n_counts);
365       else
366         warning_printed =
367           warning_at (DECL_SOURCE_LOCATION (current_function_decl),
368                       OPT_Wcoverage_mismatch,
369                       "the control flow of function %qD does not match "
370                       "its profile data (counter %qs)", current_function_decl,
371                       ctr_names[counter]);
372       if (warning_printed && dump_enabled_p ())
373         {
374           dump_user_location_t loc
375             = dump_user_location_t::from_function_decl (current_function_decl);
376           dump_printf_loc (MSG_MISSED_OPTIMIZATION, loc,
377                            "use -Wno-error=coverage-mismatch to tolerate "
378                            "the mismatch but performance may drop if the "
379                            "function is hot\n");
380           
381           if (!seen_error ()
382               && !warned++)
383             {
384               dump_printf_loc (MSG_MISSED_OPTIMIZATION, loc,
385                                "coverage mismatch ignored\n");
386               dump_printf (MSG_MISSED_OPTIMIZATION,
387                            flag_guess_branch_prob
388                            ? G_("execution counts estimated\n")
389                            : G_("execution counts assumed to be zero\n"));
390               if (!flag_guess_branch_prob)
391                 dump_printf (MSG_MISSED_OPTIMIZATION,
392                              "this can result in poorly optimized code\n");
393             }
394         }
395
396       return NULL;
397     }
398   else if (entry->lineno_checksum != lineno_checksum)
399     {
400       warning_at (DECL_SOURCE_LOCATION (current_function_decl),
401                   OPT_Wcoverage_mismatch,
402                   "source locations for function %qD have changed,"
403                   " the profile data may be out of date",
404                   current_function_decl);
405     }
406
407   return entry->counts;
408 }
409
410 /* Allocate NUM counters of type COUNTER. Returns nonzero if the
411    allocation succeeded.  */
412
413 int
414 coverage_counter_alloc (unsigned counter, unsigned num)
415 {
416   if (no_coverage)
417     return 0;
418
419   if (!num)
420     return 1;
421
422   if (!fn_v_ctrs[counter])
423     {
424       tree array_type = build_array_type (get_gcov_type (), NULL_TREE);
425
426       fn_v_ctrs[counter]
427         = build_var (current_function_decl, array_type, counter);
428     }
429
430   fn_b_ctrs[counter] = fn_n_ctrs[counter];
431   fn_n_ctrs[counter] += num;
432   
433   fn_ctr_mask |= 1 << counter;
434   return 1;
435 }
436
437 /* Generate a tree to access COUNTER NO.  */
438
439 tree
440 tree_coverage_counter_ref (unsigned counter, unsigned no)
441 {
442   tree gcov_type_node = get_gcov_type ();
443
444   gcc_assert (no < fn_n_ctrs[counter] - fn_b_ctrs[counter]);
445
446   no += fn_b_ctrs[counter];
447   
448   /* "no" here is an array index, scaled to bytes later.  */
449   return build4 (ARRAY_REF, gcov_type_node, fn_v_ctrs[counter],
450                  build_int_cst (integer_type_node, no), NULL, NULL);
451 }
452
453 /* Generate a tree to access the address of COUNTER NO.  */
454
455 tree
456 tree_coverage_counter_addr (unsigned counter, unsigned no)
457 {
458   tree gcov_type_node = get_gcov_type ();
459
460   gcc_assert (no < fn_n_ctrs[counter] - fn_b_ctrs[counter]);
461   no += fn_b_ctrs[counter];
462
463   /* "no" here is an array index, scaled to bytes later.  */
464   return build_fold_addr_expr (build4 (ARRAY_REF, gcov_type_node,
465                                        fn_v_ctrs[counter],
466                                        build_int_cst (integer_type_node, no),
467                                        NULL, NULL));
468 }
469 \f
470
471 /* Generate a checksum for a string.  CHKSUM is the current
472    checksum.  */
473
474 static unsigned
475 coverage_checksum_string (unsigned chksum, const char *string)
476 {
477   int i;
478   char *dup = NULL;
479
480   /* Look for everything that looks if it were produced by
481      get_file_function_name and zero out the second part
482      that may result from flag_random_seed.  This is not critical
483      as the checksums are used only for sanity checking.  */
484   for (i = 0; string[i]; i++)
485     {
486       int offset = 0;
487       if (startswith (string + i, "_GLOBAL__N_"))
488       offset = 11;
489       if (startswith (string + i, "_GLOBAL__"))
490       offset = 9;
491
492       /* C++ namespaces do have scheme:
493          _GLOBAL__N_<filename>_<wrongmagicnumber>_<magicnumber>functionname
494        since filename might contain extra underscores there seems
495        to be no better chance then walk all possible offsets looking
496        for magicnumber.  */
497       if (offset)
498         {
499           for (i = i + offset; string[i]; i++)
500             if (string[i]=='_')
501               {
502                 int y;
503
504                 for (y = 1; y < 9; y++)
505                   if (!(string[i + y] >= '0' && string[i + y] <= '9')
506                       && !(string[i + y] >= 'A' && string[i + y] <= 'F'))
507                     break;
508                 if (y != 9 || string[i + 9] != '_')
509                   continue;
510                 for (y = 10; y < 18; y++)
511                   if (!(string[i + y] >= '0' && string[i + y] <= '9')
512                       && !(string[i + y] >= 'A' && string[i + y] <= 'F'))
513                     break;
514                 if (y != 18)
515                   continue;
516                 if (!dup)
517                   string = dup = xstrdup (string);
518                 for (y = 10; y < 18; y++)
519                   dup[i + y] = '0';
520               }
521           break;
522         }
523     }
524
525   chksum = crc32_string (chksum, string);
526   free (dup);
527
528   return chksum;
529 }
530
531 /* Compute checksum for the current function.  We generate a CRC32.  */
532
533 unsigned
534 coverage_compute_lineno_checksum (void)
535 {
536   expanded_location xloc
537     = expand_location (DECL_SOURCE_LOCATION (current_function_decl));
538   unsigned chksum = xloc.line;
539
540   if (xloc.file)
541     chksum = coverage_checksum_string (chksum, xloc.file);
542   chksum = coverage_checksum_string
543     (chksum, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl)));
544
545   return chksum;
546 }
547
548 /* Compute profile ID.  This is better to be unique in whole program.  */
549
550 unsigned
551 coverage_compute_profile_id (struct cgraph_node *n)
552 {
553   unsigned chksum;
554
555   /* Externally visible symbols have unique name.  */
556   if (TREE_PUBLIC (n->decl) || DECL_EXTERNAL (n->decl) || n->unique_name)
557     {
558       chksum = coverage_checksum_string
559         (0, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (n->decl)));
560     }
561   else
562     {
563       expanded_location xloc
564         = expand_location (DECL_SOURCE_LOCATION (n->decl));
565       bool use_name_only = (param_profile_func_internal_id == 0);
566
567       chksum = (use_name_only ? 0 : xloc.line);
568       if (xloc.file)
569         chksum = coverage_checksum_string (chksum, xloc.file);
570       chksum = coverage_checksum_string
571         (chksum, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (n->decl)));
572       if (!use_name_only && first_global_object_name)
573         chksum = coverage_checksum_string
574           (chksum, first_global_object_name);
575       char *base_name = xstrdup (aux_base_name);
576       if (endswith (base_name, ".gk"))
577         base_name[strlen (base_name) - 3] = '\0';
578       chksum = coverage_checksum_string (chksum, base_name);
579       free (base_name);
580     }
581
582   /* Non-negative integers are hopefully small enough to fit in all targets.
583      Gcov file formats wants non-zero function IDs.  */
584   chksum = chksum & 0x7fffffff;
585   return chksum + (!chksum);
586 }
587
588 /* Compute cfg checksum for the function FN given as argument.
589    The checksum is calculated carefully so that
590    source code changes that doesn't affect the control flow graph
591    won't change the checksum.
592    This is to make the profile data useable across source code change.
593    The downside of this is that the compiler may use potentially
594    wrong profile data - that the source code change has non-trivial impact
595    on the validity of profile data (e.g. the reversed condition)
596    but the compiler won't detect the change and use the wrong profile data.  */
597
598 unsigned
599 coverage_compute_cfg_checksum (struct function *fn)
600 {
601   basic_block bb;
602   unsigned chksum = n_basic_blocks_for_fn (fn);
603
604   FOR_EACH_BB_FN (bb, fn)
605     {
606       edge e;
607       edge_iterator ei;
608       chksum = crc32_byte (chksum, bb->index);
609       FOR_EACH_EDGE (e, ei, bb->succs)
610         {
611           chksum = crc32_byte (chksum, e->dest->index);
612         }
613     }
614
615   return chksum;
616 }
617 \f
618 /* Begin output to the notes file for the current function.
619    Writes the function header. Returns nonzero if data should be output.  */
620
621 int
622 coverage_begin_function (unsigned lineno_checksum, unsigned cfg_checksum)
623 {
624   /* We don't need to output .gcno file unless we're under -ftest-coverage
625      (e.g. -fprofile-arcs/generate/use don't need .gcno to work). */
626   if (no_coverage || !bbg_file_name)
627     return 0;
628
629   expanded_location startloc
630     = expand_location (DECL_SOURCE_LOCATION (current_function_decl));
631
632   /* Announce function */
633   unsigned long offset = gcov_write_tag (GCOV_TAG_FUNCTION);
634   if (param_profile_func_internal_id)
635     gcov_write_unsigned (current_function_funcdef_no + 1);
636   else
637     {
638       gcc_assert (coverage_node_map_initialized_p ());
639       gcov_write_unsigned (
640         cgraph_node::get (current_function_decl)->profile_id);
641     }
642
643   gcov_write_unsigned (lineno_checksum);
644   gcov_write_unsigned (cfg_checksum);
645   gcov_write_string (IDENTIFIER_POINTER
646                      (DECL_ASSEMBLER_NAME (current_function_decl)));
647   gcov_write_unsigned (DECL_ARTIFICIAL (current_function_decl)
648                        && !DECL_FUNCTION_VERSIONED (current_function_decl)
649                        && !DECL_LAMBDA_FUNCTION_P (current_function_decl));
650   gcov_write_filename (remap_profile_filename (startloc.file));
651   gcov_write_unsigned (startloc.line);
652   gcov_write_unsigned (startloc.column);
653
654   expanded_location endloc = expand_location (cfun->function_end_locus);
655
656   /* Function can start in a single file and end in another one.  */
657   int end_line
658     = endloc.file == startloc.file ? endloc.line : startloc.line;
659   int end_column
660     = endloc.file == startloc.file ? endloc.column: startloc.column;
661
662   if (startloc.line > end_line)
663     {
664       warning_at (DECL_SOURCE_LOCATION (current_function_decl),
665                   OPT_Wcoverage_invalid_line_number,
666                   "function starts on a higher line number than it ends");
667       end_line = startloc.line;
668       end_column = startloc.column;
669     }
670
671   gcov_write_unsigned (end_line);
672   gcov_write_unsigned (end_column);
673   gcov_write_length (offset);
674
675   return !gcov_is_error ();
676 }
677
678 /* Finish coverage data for the current function. Verify no output
679    error has occurred.  Save function coverage counts.  */
680
681 void
682 coverage_end_function (unsigned lineno_checksum, unsigned cfg_checksum)
683 {
684   unsigned i;
685
686   if (bbg_file_name && gcov_is_error ())
687     {
688       warning (0, "error writing %qs", bbg_file_name);
689       unlink (bbg_file_name);
690       bbg_file_name = NULL;
691     }
692
693   if (fn_ctr_mask)
694     {
695       struct coverage_data *item = 0;
696
697       item = ggc_alloc<coverage_data> ();
698
699       if (param_profile_func_internal_id)
700         item->ident = current_function_funcdef_no + 1;
701       else
702         {
703           gcc_assert (coverage_node_map_initialized_p ());
704           item->ident = cgraph_node::get (cfun->decl)->profile_id;
705         }
706
707       item->lineno_checksum = lineno_checksum;
708       item->cfg_checksum = cfg_checksum;
709
710       item->fn_decl = current_function_decl;
711       item->next = 0;
712       *functions_tail = item;
713       functions_tail = &item->next;
714
715       for (i = 0; i != GCOV_COUNTERS; i++)
716         {
717           tree var = fn_v_ctrs[i];
718
719           if (item)
720             item->ctr_vars[i] = var;
721           if (var)
722             {
723               tree array_type = build_index_type (size_int (fn_n_ctrs[i] - 1));
724               array_type = build_array_type (get_gcov_type (), array_type);
725               TREE_TYPE (var) = array_type;
726               DECL_SIZE (var) = TYPE_SIZE (array_type);
727               DECL_SIZE_UNIT (var) = TYPE_SIZE_UNIT (array_type);
728               varpool_node::finalize_decl (var);
729             }
730           
731           fn_b_ctrs[i] = fn_n_ctrs[i] = 0;
732           fn_v_ctrs[i] = NULL_TREE;
733         }
734       prg_ctr_mask |= fn_ctr_mask;
735       fn_ctr_mask = 0;
736     }
737 }
738
739 /* Remove coverage file if opened.  */
740
741 void
742 coverage_remove_note_file (void)
743 {
744   if (bbg_file_name)
745     {
746       gcov_close ();
747       unlink (bbg_file_name);
748     }
749 }
750
751 /* Build a coverage variable of TYPE for function FN_DECL.  If COUNTER
752    >= 0 it is a counter array, otherwise it is the function structure.  */
753
754 static tree
755 build_var (tree fn_decl, tree type, int counter)
756 {
757   tree var = build_decl (BUILTINS_LOCATION, VAR_DECL, NULL_TREE, type);
758   const char *fn_name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (fn_decl));
759   char *buf;
760   size_t fn_name_len, len;
761
762   fn_name = targetm.strip_name_encoding (fn_name);
763   fn_name_len = strlen (fn_name);
764   buf = XALLOCAVEC (char, fn_name_len + 8 + sizeof (int) * 3);
765
766   if (counter < 0)
767     strcpy (buf, "__gcov__");
768   else
769     sprintf (buf, "__gcov%u_", counter);
770   len = strlen (buf);
771   buf[len - 1] = symbol_table::symbol_suffix_separator ();
772   memcpy (buf + len, fn_name, fn_name_len + 1);
773   DECL_NAME (var) = get_identifier (buf);
774   TREE_STATIC (var) = 1;
775   TREE_ADDRESSABLE (var) = 1;
776   DECL_NONALIASED (var) = 1;
777   SET_DECL_ALIGN (var, TYPE_ALIGN (type));
778
779   return var;
780 }
781
782 /* Creates the gcov_fn_info RECORD_TYPE.  */
783
784 static void
785 build_fn_info_type (tree type, unsigned counters, tree gcov_info_type)
786 {
787   tree ctr_info = lang_hooks.types.make_type (RECORD_TYPE);
788   tree field, fields;
789   tree array_type;
790
791   gcc_assert (counters);
792   
793   /* ctr_info::num */
794   field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
795                       get_gcov_unsigned_t ());
796   fields = field;
797   
798   /* ctr_info::values */
799   field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
800                       build_pointer_type (get_gcov_type ()));
801   DECL_CHAIN (field) = fields;
802   fields = field;
803   
804   finish_builtin_struct (ctr_info, "__gcov_ctr_info", fields, NULL_TREE);
805
806   /* key */
807   field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
808                       build_pointer_type (build_qualified_type
809                                           (gcov_info_type, TYPE_QUAL_CONST)));
810   fields = field;
811   
812   /* ident */
813   field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
814                       get_gcov_unsigned_t ());
815   DECL_CHAIN (field) = fields;
816   fields = field;
817   
818   /* lineno_checksum */
819   field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
820                       get_gcov_unsigned_t ());
821   DECL_CHAIN (field) = fields;
822   fields = field;
823
824   /* cfg checksum */
825   field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
826                       get_gcov_unsigned_t ());
827   DECL_CHAIN (field) = fields;
828   fields = field;
829
830   array_type = build_index_type (size_int (counters - 1));
831   array_type = build_array_type (ctr_info, array_type);
832
833   /* counters */
834   field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE, array_type);
835   DECL_CHAIN (field) = fields;
836   fields = field;
837
838   finish_builtin_struct (type, "__gcov_fn_info", fields, NULL_TREE);
839 }
840
841 /* Returns a CONSTRUCTOR for a gcov_fn_info.  DATA is
842    the coverage data for the function and TYPE is the gcov_fn_info
843    RECORD_TYPE.  KEY is the object file key.  */
844
845 static tree
846 build_fn_info (const struct coverage_data *data, tree type, tree key)
847 {
848   tree fields = TYPE_FIELDS (type);
849   tree ctr_type;
850   unsigned ix;
851   vec<constructor_elt, va_gc> *v1 = NULL;
852   vec<constructor_elt, va_gc> *v2 = NULL;
853
854   /* key */
855   CONSTRUCTOR_APPEND_ELT (v1, fields,
856                           build1 (ADDR_EXPR, TREE_TYPE (fields), key));
857   fields = DECL_CHAIN (fields);
858   
859   /* ident */
860   CONSTRUCTOR_APPEND_ELT (v1, fields,
861                           build_int_cstu (get_gcov_unsigned_t (),
862                                           data->ident));
863   fields = DECL_CHAIN (fields);
864
865   /* lineno_checksum */
866   CONSTRUCTOR_APPEND_ELT (v1, fields,
867                           build_int_cstu (get_gcov_unsigned_t (),
868                                           data->lineno_checksum));
869   fields = DECL_CHAIN (fields);
870
871   /* cfg_checksum */
872   CONSTRUCTOR_APPEND_ELT (v1, fields,
873                           build_int_cstu (get_gcov_unsigned_t (),
874                                           data->cfg_checksum));
875   fields = DECL_CHAIN (fields);
876
877   /* counters */
878   ctr_type = TREE_TYPE (TREE_TYPE (fields));
879   for (ix = 0; ix != GCOV_COUNTERS; ix++)
880     if (prg_ctr_mask & (1 << ix))
881       {
882         vec<constructor_elt, va_gc> *ctr = NULL;
883         tree var = data->ctr_vars[ix];
884         unsigned count = 0;
885
886         if (var)
887           count
888             = tree_to_shwi (TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (var))))
889             + 1;
890
891         CONSTRUCTOR_APPEND_ELT (ctr, TYPE_FIELDS (ctr_type),
892                                 build_int_cstu (get_gcov_unsigned_t (),
893                                                 count));
894
895         if (var)
896           CONSTRUCTOR_APPEND_ELT (ctr, DECL_CHAIN (TYPE_FIELDS (ctr_type)),
897                                   build_fold_addr_expr (var));
898         
899         CONSTRUCTOR_APPEND_ELT (v2, NULL, build_constructor (ctr_type, ctr));
900       }
901   
902   CONSTRUCTOR_APPEND_ELT (v1, fields,
903                           build_constructor (TREE_TYPE (fields), v2));
904
905   return build_constructor (type, v1);
906 }
907
908 /* Create gcov_info struct.  TYPE is the incomplete RECORD_TYPE to be
909    completed, and FN_INFO_PTR_TYPE is a pointer to the function info type.  */
910
911 static void
912 build_info_type (tree type, tree fn_info_ptr_type)
913 {
914   tree field, fields = NULL_TREE;
915   tree merge_fn_type;
916
917   /* Version ident */
918   field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
919                       get_gcov_unsigned_t ());
920   DECL_CHAIN (field) = fields;
921   fields = field;
922
923   /* next pointer */
924   field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
925                       build_pointer_type (build_qualified_type
926                                           (type, TYPE_QUAL_CONST)));
927   DECL_CHAIN (field) = fields;
928   fields = field;
929
930   /* stamp */
931   field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
932                       get_gcov_unsigned_t ());
933   DECL_CHAIN (field) = fields;
934   fields = field;
935
936   /* Checksum.  */
937   field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
938                       get_gcov_unsigned_t ());
939   DECL_CHAIN (field) = fields;
940   fields = field;
941
942   /* Filename */
943   field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
944                       build_pointer_type (build_qualified_type
945                                           (char_type_node, TYPE_QUAL_CONST)));
946   DECL_CHAIN (field) = fields;
947   fields = field;
948
949   /* merge fn array */
950   merge_fn_type
951     = build_function_type_list (void_type_node,
952                                 build_pointer_type (get_gcov_type ()),
953                                 get_gcov_unsigned_t (), NULL_TREE);
954   merge_fn_type
955     = build_array_type (build_pointer_type (merge_fn_type),
956                         build_index_type (size_int (GCOV_COUNTERS - 1)));
957   field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
958                       merge_fn_type);
959   DECL_CHAIN (field) = fields;
960   fields = field;
961   
962   /* n_functions */
963   field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
964                       get_gcov_unsigned_t ());
965   DECL_CHAIN (field) = fields;
966   fields = field;
967   
968   /* function_info pointer pointer */
969   fn_info_ptr_type = build_pointer_type
970     (build_qualified_type (fn_info_ptr_type, TYPE_QUAL_CONST));
971   field = build_decl (BUILTINS_LOCATION, FIELD_DECL, NULL_TREE,
972                       fn_info_ptr_type);
973   DECL_CHAIN (field) = fields;
974   fields = field;
975
976   finish_builtin_struct (type, "__gcov_info", fields, NULL_TREE);
977 }
978
979 /* Returns a CONSTRUCTOR for the gcov_info object.  INFO_TYPE is the
980    gcov_info structure type, FN_ARY is the array of pointers to
981    function info objects.  */
982
983 static tree
984 build_info (tree info_type, tree fn_ary, unsigned object_checksum)
985 {
986   tree info_fields = TYPE_FIELDS (info_type);
987   tree merge_fn_type, n_funcs;
988   unsigned ix;
989   tree filename_string;
990   int da_file_name_len;
991   vec<constructor_elt, va_gc> *v1 = NULL;
992   vec<constructor_elt, va_gc> *v2 = NULL;
993
994   /* Version ident */
995   CONSTRUCTOR_APPEND_ELT (v1, info_fields,
996                           build_int_cstu (TREE_TYPE (info_fields),
997                                           GCOV_VERSION));
998   info_fields = DECL_CHAIN (info_fields);
999
1000   /* next -- NULL */
1001   CONSTRUCTOR_APPEND_ELT (v1, info_fields, null_pointer_node);
1002   info_fields = DECL_CHAIN (info_fields);
1003
1004   /* stamp */
1005   CONSTRUCTOR_APPEND_ELT (v1, info_fields,
1006                           build_int_cstu (TREE_TYPE (info_fields),
1007                                           bbg_file_stamp));
1008   info_fields = DECL_CHAIN (info_fields);
1009
1010   /* Checksum.  */
1011   CONSTRUCTOR_APPEND_ELT (v1, info_fields,
1012                           build_int_cstu (TREE_TYPE (info_fields),
1013                                           object_checksum));
1014   info_fields = DECL_CHAIN (info_fields);
1015
1016   /* Filename */
1017   da_file_name_len = strlen (da_file_name);
1018   filename_string = build_string (da_file_name_len + 1, da_file_name);
1019   TREE_TYPE (filename_string) = build_array_type
1020     (char_type_node, build_index_type (size_int (da_file_name_len)));
1021   CONSTRUCTOR_APPEND_ELT (v1, info_fields,
1022                           build1 (ADDR_EXPR, TREE_TYPE (info_fields),
1023                                   filename_string));
1024   info_fields = DECL_CHAIN (info_fields);
1025
1026   /* merge fn array -- NULL slots indicate unmeasured counters */
1027   merge_fn_type = TREE_TYPE (TREE_TYPE (info_fields));
1028   for (ix = 0; ix != GCOV_COUNTERS; ix++)
1029     {
1030       tree ptr = null_pointer_node;
1031
1032       if ((1u << ix) & prg_ctr_mask)
1033         {
1034           tree merge_fn = build_decl (BUILTINS_LOCATION,
1035                                       FUNCTION_DECL,
1036                                       get_identifier (ctr_merge_functions[ix]),
1037                                       TREE_TYPE (merge_fn_type));
1038           DECL_EXTERNAL (merge_fn) = 1;
1039           TREE_PUBLIC (merge_fn) = 1;
1040           DECL_ARTIFICIAL (merge_fn) = 1;
1041           TREE_NOTHROW (merge_fn) = 1;
1042           /* Initialize assembler name so we can stream out. */
1043           DECL_ASSEMBLER_NAME (merge_fn);
1044           ptr = build1 (ADDR_EXPR, merge_fn_type, merge_fn);
1045         }
1046       CONSTRUCTOR_APPEND_ELT (v2, NULL, ptr);
1047     }
1048   CONSTRUCTOR_APPEND_ELT (v1, info_fields,
1049                           build_constructor (TREE_TYPE (info_fields), v2));
1050   info_fields = DECL_CHAIN (info_fields);
1051
1052   /* n_functions */
1053   n_funcs = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (fn_ary)));
1054   n_funcs = fold_build2 (PLUS_EXPR, TREE_TYPE (info_fields),
1055                          n_funcs, size_one_node);
1056   CONSTRUCTOR_APPEND_ELT (v1, info_fields, n_funcs);
1057   info_fields = DECL_CHAIN (info_fields);
1058
1059   /* functions */
1060   CONSTRUCTOR_APPEND_ELT (v1, info_fields,
1061                           build1 (ADDR_EXPR, TREE_TYPE (info_fields), fn_ary));
1062   info_fields = DECL_CHAIN (info_fields);
1063
1064   gcc_assert (!info_fields);
1065   return build_constructor (info_type, v1);
1066 }
1067
1068 /* Generate the constructor function to call __gcov_init.  */
1069
1070 static void
1071 build_init_ctor (tree gcov_info_type)
1072 {
1073   tree ctor, stmt, init_fn;
1074
1075   /* Build a decl for __gcov_init.  */
1076   init_fn = build_pointer_type (gcov_info_type);
1077   init_fn = build_function_type_list (void_type_node, init_fn, NULL);
1078   init_fn = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
1079                         get_identifier ("__gcov_init"), init_fn);
1080   TREE_PUBLIC (init_fn) = 1;
1081   DECL_EXTERNAL (init_fn) = 1;
1082   DECL_ASSEMBLER_NAME (init_fn);
1083
1084   /* Generate a call to __gcov_init(&gcov_info).  */
1085   ctor = NULL;
1086   stmt = build_fold_addr_expr (gcov_info_var);
1087   stmt = build_call_expr (init_fn, 1, stmt);
1088   append_to_statement_list (stmt, &ctor);
1089
1090   /* Generate a constructor to run it.  */
1091   int priority = SUPPORTS_INIT_PRIORITY
1092     ? MAX_RESERVED_INIT_PRIORITY: DEFAULT_INIT_PRIORITY;
1093   cgraph_build_static_cdtor ('I', ctor, priority);
1094 }
1095
1096 /* Generate the destructor function to call __gcov_exit.  */
1097
1098 static void
1099 build_gcov_exit_decl (void)
1100 {
1101   tree init_fn = build_function_type_list (void_type_node, NULL);
1102   init_fn = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
1103                         get_identifier ("__gcov_exit"), init_fn);
1104   TREE_PUBLIC (init_fn) = 1;
1105   DECL_EXTERNAL (init_fn) = 1;
1106   DECL_ASSEMBLER_NAME (init_fn);
1107
1108   /* Generate a call to __gcov_exit ().  */
1109   tree dtor = NULL;
1110   tree stmt = build_call_expr (init_fn, 0);
1111   append_to_statement_list (stmt, &dtor);
1112
1113   /* Generate a destructor to run it.  */
1114   int priority = SUPPORTS_INIT_PRIORITY
1115     ? MAX_RESERVED_INIT_PRIORITY: DEFAULT_INIT_PRIORITY;
1116
1117   cgraph_build_static_cdtor ('D', dtor, priority);
1118 }
1119
1120 /* Generate the pointer to the gcov_info_var in a dedicated section.  */
1121
1122 static void
1123 build_gcov_info_var_registration (tree gcov_info_type)
1124 {
1125   tree var = build_decl (BUILTINS_LOCATION,
1126                          VAR_DECL, NULL_TREE,
1127                          build_pointer_type (gcov_info_type));
1128   TREE_STATIC (var) = 1;
1129   TREE_READONLY (var) = 1;
1130   char name_buf[32];
1131   ASM_GENERATE_INTERNAL_LABEL (name_buf, "LPBX", 2);
1132   DECL_NAME (var) = get_identifier (name_buf);
1133   get_section (profile_info_section, SECTION_UNNAMED, NULL);
1134   set_decl_section_name (var, profile_info_section);
1135   mark_decl_referenced (var);
1136   DECL_INITIAL (var) = build_fold_addr_expr (gcov_info_var);
1137   varpool_node::finalize_decl (var);
1138 }
1139
1140 /* Create the gcov_info types and object.  Generate the constructor
1141    function to call __gcov_init.  Does not generate the initializer
1142    for the object.  Returns TRUE if coverage data is being emitted.  */
1143
1144 static bool
1145 coverage_obj_init (void)
1146 {
1147   tree gcov_info_type;
1148   unsigned n_counters = 0;
1149   unsigned ix;
1150   struct coverage_data *fn;
1151   struct coverage_data **fn_prev;
1152   char name_buf[32];
1153
1154   no_coverage = 1; /* Disable any further coverage.  */
1155
1156   if (!prg_ctr_mask)
1157     return false;
1158
1159   if (symtab->dump_file)
1160     fprintf (symtab->dump_file, "Using data file %s\n", da_file_name);
1161
1162   /* Prune functions.  */
1163   for (fn_prev = &functions_head; (fn = *fn_prev);)
1164     if (DECL_STRUCT_FUNCTION (fn->fn_decl))
1165       fn_prev = &fn->next;
1166     else
1167       /* The function is not being emitted, remove from list.  */
1168       *fn_prev = fn->next;
1169
1170   if (functions_head == NULL)
1171     return false;
1172
1173   for (ix = 0; ix != GCOV_COUNTERS; ix++)
1174     if ((1u << ix) & prg_ctr_mask)
1175       n_counters++;
1176   
1177   /* Build the info and fn_info types.  These are mutually recursive.  */
1178   gcov_info_type = lang_hooks.types.make_type (RECORD_TYPE);
1179   gcov_fn_info_type = lang_hooks.types.make_type (RECORD_TYPE);
1180   build_fn_info_type (gcov_fn_info_type, n_counters, gcov_info_type);
1181   gcov_info_type = lang_hooks.types.make_type (RECORD_TYPE);
1182   gcov_fn_info_ptr_type = build_pointer_type
1183     (build_qualified_type (gcov_fn_info_type, TYPE_QUAL_CONST));
1184   build_info_type (gcov_info_type, gcov_fn_info_ptr_type);
1185   
1186   /* Build the gcov info var, this is referred to in its own
1187      initializer.  */
1188   gcov_info_var = build_decl (BUILTINS_LOCATION,
1189                               VAR_DECL, NULL_TREE, gcov_info_type);
1190   TREE_STATIC (gcov_info_var) = 1;
1191   ASM_GENERATE_INTERNAL_LABEL (name_buf, "LPBX", 0);
1192   DECL_NAME (gcov_info_var) = get_identifier (name_buf);
1193
1194   if (profile_info_section)
1195     build_gcov_info_var_registration (gcov_info_type);
1196   else
1197     {
1198       build_init_ctor (gcov_info_type);
1199       build_gcov_exit_decl ();
1200     }
1201
1202   return true;
1203 }
1204
1205 /* Generate the coverage function info for FN and DATA.  Append a
1206    pointer to that object to CTOR and return the appended CTOR.  */
1207
1208 static vec<constructor_elt, va_gc> *
1209 coverage_obj_fn (vec<constructor_elt, va_gc> *ctor, tree fn,
1210                  struct coverage_data const *data)
1211 {
1212   tree init = build_fn_info (data, gcov_fn_info_type, gcov_info_var);
1213   tree var = build_var (fn, gcov_fn_info_type, -1);
1214   
1215   DECL_INITIAL (var) = init;
1216   varpool_node::finalize_decl (var);
1217       
1218   CONSTRUCTOR_APPEND_ELT (ctor, NULL,
1219                           build1 (ADDR_EXPR, gcov_fn_info_ptr_type, var));
1220   return ctor;
1221 }
1222
1223 /* Finalize the coverage data.  Generates the array of pointers to
1224    function objects from CTOR.  Generate the gcov_info initializer.  */
1225
1226 static void
1227 coverage_obj_finish (vec<constructor_elt, va_gc> *ctor,
1228                      unsigned object_checksum)
1229 {
1230   unsigned n_functions = vec_safe_length (ctor);
1231   tree fn_info_ary_type = build_array_type
1232     (build_qualified_type (gcov_fn_info_ptr_type, TYPE_QUAL_CONST),
1233      build_index_type (size_int (n_functions - 1)));
1234   tree fn_info_ary = build_decl (BUILTINS_LOCATION, VAR_DECL, NULL_TREE,
1235                                  fn_info_ary_type);
1236   char name_buf[32];
1237
1238   TREE_STATIC (fn_info_ary) = 1;
1239   ASM_GENERATE_INTERNAL_LABEL (name_buf, "LPBX", 1);
1240   DECL_NAME (fn_info_ary) = get_identifier (name_buf);
1241   DECL_INITIAL (fn_info_ary) = build_constructor (fn_info_ary_type, ctor);
1242   varpool_node::finalize_decl (fn_info_ary);
1243   
1244   DECL_INITIAL (gcov_info_var)
1245     = build_info (TREE_TYPE (gcov_info_var), fn_info_ary, object_checksum);
1246   varpool_node::finalize_decl (gcov_info_var);
1247 }
1248
1249 /* Perform file-level initialization. Read in data file, generate name
1250    of notes file.  */
1251
1252 void
1253 coverage_init (const char *filename)
1254 {
1255   const char *original_filename = filename;
1256   int original_len = strlen (original_filename);
1257 #if HAVE_DOS_BASED_FILE_SYSTEM
1258   const char *separator = "\\";
1259 #else
1260   const char *separator = "/";
1261 #endif
1262   int len = strlen (filename);
1263   int prefix_len = 0;
1264
1265   /* Since coverage_init is invoked very early, before the pass
1266      manager, we need to set up the dumping explicitly. This is
1267      similar to the handling in finish_optimization_passes.  */
1268   int profile_pass_num =
1269     g->get_passes ()->get_pass_profile ()->static_pass_number;
1270   g->get_dumps ()->dump_start (profile_pass_num, NULL);
1271
1272   if (!IS_ABSOLUTE_PATH (filename))
1273     {
1274       /* When a profile_data_prefix is provided, then mangle full path
1275          of filename in order to prevent file path clashing.  */
1276       if (profile_data_prefix)
1277         {
1278           filename = concat (getpwd (), separator, filename, NULL);
1279           if (profile_prefix_path)
1280             {
1281               if (startswith (filename, profile_prefix_path))
1282                 {
1283                   filename += strlen (profile_prefix_path);
1284                   while (*filename == *separator)
1285                     filename++;
1286                 }
1287               else
1288                 warning (0, "filename %qs does not start with profile "
1289                          "prefix %qs", filename, profile_prefix_path);
1290             }
1291           filename = mangle_path (filename);
1292           len = strlen (filename);
1293         }
1294       else
1295         profile_data_prefix = getpwd ();
1296     }
1297
1298   if (profile_data_prefix)
1299     prefix_len = strlen (profile_data_prefix);
1300
1301   /* Name of da file.  */
1302   da_file_name = XNEWVEC (char, len + strlen (GCOV_DATA_SUFFIX)
1303                           + prefix_len + 2);
1304
1305   if (profile_data_prefix)
1306     {
1307       memcpy (da_file_name, profile_data_prefix, prefix_len);
1308       da_file_name[prefix_len++] = *separator;
1309     }
1310   memcpy (da_file_name + prefix_len, filename, len);
1311   strcpy (da_file_name + prefix_len + len, GCOV_DATA_SUFFIX);
1312
1313   bbg_file_stamp = local_tick;
1314   if (flag_auto_profile)
1315     read_autofdo_file ();
1316   else if (flag_branch_probabilities)
1317     read_counts_file ();
1318
1319   /* Name of bbg file.  */
1320   if (flag_test_coverage && !flag_compare_debug)
1321     {
1322       if (profile_note_location)
1323         bbg_file_name = xstrdup (profile_note_location);
1324       else
1325         {
1326           bbg_file_name = XNEWVEC (char, original_len + strlen (GCOV_NOTE_SUFFIX) + 1);
1327           memcpy (bbg_file_name, original_filename, original_len);
1328           strcpy (bbg_file_name + original_len, GCOV_NOTE_SUFFIX);
1329         }
1330
1331       if (!gcov_open (bbg_file_name, -1))
1332         {
1333           error ("cannot open %s", bbg_file_name);
1334           bbg_file_name = NULL;
1335         }
1336       else
1337         {
1338           gcov_write_unsigned (GCOV_NOTE_MAGIC);
1339           gcov_write_unsigned (GCOV_VERSION);
1340           gcov_write_unsigned (bbg_file_stamp);
1341           /* Use an arbitrary checksum */
1342           gcov_write_unsigned (0);
1343           gcov_write_string (getpwd ());
1344
1345           /* Do not support has_unexecuted_blocks for Ada.  */
1346           gcov_write_unsigned (strcmp (lang_hooks.name, "GNU Ada") != 0);
1347         }
1348     }
1349
1350   g->get_dumps ()->dump_finish (profile_pass_num);
1351 }
1352
1353 /* Performs file-level cleanup.  Close notes file, generate coverage
1354    variables and constructor.  */
1355
1356 void
1357 coverage_finish (void)
1358 {
1359   if (bbg_file_name && gcov_close ())
1360     unlink (bbg_file_name);
1361
1362   if (!flag_branch_probabilities && flag_test_coverage
1363       && (!local_tick || local_tick == (unsigned)-1))
1364     /* Only remove the da file, if we're emitting coverage code and
1365        cannot uniquely stamp it.  If we can stamp it, libgcov will DTRT.  */
1366     unlink (da_file_name);
1367
1368   /* Global GCDA checksum that aggregates all functions.  */
1369   unsigned object_checksum = 0;
1370
1371   if (coverage_obj_init ())
1372     {
1373       vec<constructor_elt, va_gc> *fn_ctor = NULL;
1374       struct coverage_data *fn;
1375       
1376       for (fn = functions_head; fn; fn = fn->next)
1377         {
1378           fn_ctor = coverage_obj_fn (fn_ctor, fn->fn_decl, fn);
1379
1380           object_checksum = crc32_unsigned (object_checksum, fn->ident);
1381           object_checksum = crc32_unsigned (object_checksum,
1382                                             fn->lineno_checksum);
1383           object_checksum = crc32_unsigned (object_checksum, fn->cfg_checksum);
1384         }
1385       coverage_obj_finish (fn_ctor, object_checksum);
1386     }
1387
1388   XDELETEVEC (da_file_name);
1389   da_file_name = NULL;
1390 }
1391
1392 #include "gt-coverage.h"