1 /* Read and write coverage files, and associated functionality.
2 Copyright (C) 1990, 1991, 1992, 1993, 1994, 1996, 1997, 1998, 1999,
3 2000, 2001, 2003 Free Software Foundation, Inc.
4 Contributed by James E. Wilson, UC Berkeley/Cygnus Support;
5 based on some ideas from Dain Samples of UC Berkeley.
6 Further mangling by Bob Manson, Cygnus Support.
7 Further mangled by Nathan Sidwell, CodeSourcery
9 This file is part of GCC.
11 GCC is free software; you can redistribute it and/or modify it under
12 the terms of the GNU General Public License as published by the Free
13 Software Foundation; either version 2, or (at your option) any later
16 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
17 WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 You should have received a copy of the GNU General Public License
22 along with GCC; see the file COPYING. If not, write to the Free
23 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
31 #include "coretypes.h"
45 #include "langhooks.h"
52 struct function_list *next; /* next function */
53 unsigned ident; /* function ident */
54 unsigned checksum; /* function checksum */
55 unsigned n_ctrs[GCOV_COUNTERS];/* number of counters. */
58 /* Counts information for a function. */
59 typedef struct counts_entry
68 struct gcov_ctr_summary summary;
71 struct counts_entry *chain;
75 static unsigned fn_ident = 1;
76 static struct function_list *functions_head = 0;
77 static struct function_list **functions_tail = &functions_head;
79 /* Cumulative counter information for whole program. */
80 static unsigned prg_ctr_mask; /* Mask of counter types generated. */
81 static unsigned prg_n_ctrs[GCOV_COUNTERS];
83 /* Counter information for current function. */
84 static unsigned fn_ctr_mask;
85 static unsigned fn_n_ctrs[GCOV_COUNTERS];
87 /* Name of the output file for coverage output file. */
88 static char *bbg_file_name;
89 static unsigned bbg_file_opened;
90 static int bbg_function_announced;
92 /* Name of the count data file. */
93 static char *da_file_name;
95 /* Hash table of count data. */
96 static htab_t counts_hash = NULL;
98 /* The names of the counter tables. */
99 static GTY(()) rtx ctr_labels[GCOV_COUNTERS];
101 /* The names of merge functions for counters. */
102 static const char *const ctr_merge_functions[GCOV_COUNTERS] = GCOV_MERGE_FUNCTIONS;
103 static const char *const ctr_names[GCOV_COUNTERS] = GCOV_COUNTER_NAMES;
105 /* Forward declarations. */
106 static hashval_t htab_counts_entry_hash PARAMS ((const void *));
107 static int htab_counts_entry_eq PARAMS ((const void *, const void *));
108 static void htab_counts_entry_del PARAMS ((void *));
109 static void read_counts_file PARAMS ((void));
110 static unsigned compute_checksum PARAMS ((void));
111 static unsigned checksum_string PARAMS ((unsigned, const char *));
112 static tree build_fn_info_type PARAMS ((unsigned));
113 static tree build_fn_info_value PARAMS ((const struct function_list *, tree));
114 static tree build_ctr_info_type PARAMS ((void));
115 static tree build_ctr_info_value PARAMS ((unsigned, tree));
116 static tree build_gcov_info PARAMS ((void));
117 static void create_coverage PARAMS ((void));
121 htab_counts_entry_hash (of)
124 const counts_entry_t *entry = of;
126 return entry->ident * GCOV_COUNTERS + entry->ctr;
130 htab_counts_entry_eq (of1, of2)
134 const counts_entry_t *entry1 = of1;
135 const counts_entry_t *entry2 = of2;
137 return entry1->ident == entry2->ident && entry1->ctr == entry2->ctr;
141 htab_counts_entry_del (of)
144 counts_entry_t *entry = of;
146 free (entry->counts);
150 /* Read in the counts file, if available. */
155 gcov_unsigned_t fn_ident = 0;
156 gcov_unsigned_t version, checksum = -1;
158 counts_entry_t *summaried = NULL;
159 unsigned seen_summary = 0;
161 if (!gcov_open (da_file_name, 1))
164 if (gcov_read_unsigned () != GCOV_DATA_MAGIC)
166 warning ("`%s' is not a gcov data file", da_file_name);
170 else if ((version = gcov_read_unsigned ()) != GCOV_VERSION)
173 gcov_unsigned_t required = GCOV_VERSION;
175 for (ix = 4; ix--; required >>= 8, version >>= 8)
180 warning ("`%s' is version `%.4s', expected version `%.4s'",
186 counts_hash = htab_create (10,
187 htab_counts_entry_hash, htab_counts_entry_eq,
188 htab_counts_entry_del);
189 while (!gcov_is_eof ())
191 gcov_unsigned_t tag, length;
192 gcov_position_t offset;
195 tag = gcov_read_unsigned ();
196 length = gcov_read_unsigned ();
197 offset = gcov_position ();
198 if (tag == GCOV_TAG_FUNCTION)
200 fn_ident = gcov_read_unsigned ();
201 checksum = gcov_read_unsigned ();
204 /* We have already seen a summary, this means that this
205 new function begins a new set of program runs. We
206 must unlink the summaried chain. */
207 counts_entry_t *entry, *chain;
209 for (entry = summaried; entry; entry = chain)
211 chain = entry->chain;
218 else if (tag == GCOV_TAG_PROGRAM_SUMMARY)
220 counts_entry_t *entry;
221 struct gcov_summary summary;
223 gcov_read_summary (&summary);
225 for (entry = summaried; entry; entry = entry->chain)
227 struct gcov_ctr_summary *csum = &summary.ctrs[entry->ctr];
229 entry->summary.runs += csum->runs;
230 entry->summary.sum_all += csum->sum_all;
231 if (entry->summary.run_max < csum->run_max)
232 entry->summary.run_max = csum->run_max;
233 entry->summary.sum_max += csum->sum_max;
236 else if (GCOV_TAG_IS_COUNTER (tag) && fn_ident)
238 counts_entry_t **slot, *entry, elt;
239 unsigned n_counts = length / 8;
242 elt.ident = fn_ident;
243 elt.ctr = GCOV_COUNTER_FOR_TAG (tag);
245 slot = (counts_entry_t **) htab_find_slot
246 (counts_hash, &elt, INSERT);
250 *slot = entry = xcalloc (1, sizeof (counts_entry_t));
251 entry->ident = elt.ident;
252 entry->ctr = elt.ctr;
253 entry->checksum = checksum;
254 entry->summary.num = n_counts;
255 entry->counts = xcalloc (n_counts, sizeof (gcov_type));
257 else if (entry->checksum != checksum
258 || entry->summary.num != n_counts)
260 warning ("coverage mismatch for function %u", fn_ident);
261 htab_delete (counts_hash);
264 else if (elt.ctr >= GCOV_COUNTERS_SUMMABLE)
266 warning ("cannot merge separate %s counters for function %u",
267 ctr_names[elt.ctr], fn_ident);
271 if (elt.ctr < GCOV_COUNTERS_SUMMABLE
272 /* This should always be true for a just allocated entry,
273 and always false for an existing one. Check this way, in
274 case the gcov file is corrupt. */
275 && (!entry->chain || summaried != entry))
277 entry->chain = summaried;
280 for (ix = 0; ix != n_counts; ix++)
281 entry->counts[ix] += gcov_read_counter ();
284 gcov_sync (offset, length);
285 if ((error = gcov_is_error ()))
287 warning (error < 0 ? "`%s' has overflowed" : "`%s' is corrupted",
289 htab_delete (counts_hash);
297 /* Returns the counters for a particular tag. */
300 get_coverage_counts (unsigned counter, unsigned expected,
301 const struct gcov_ctr_summary **summary)
303 counts_entry_t *entry, elt;
305 /* No hash table, no counts. */
308 static int warned = 0;
311 warning ("file %s not found, execution counts assumed to be zero",
316 elt.ident = fn_ident;
318 entry = htab_find (counts_hash, &elt);
321 warning ("no coverage for function '%s' found.", IDENTIFIER_POINTER
322 (DECL_ASSEMBLER_NAME (current_function_decl)));
326 if (expected != entry->summary.num
327 || compute_checksum () != entry->checksum)
329 warning ("coverage mismatch for `%s'", IDENTIFIER_POINTER
330 (DECL_ASSEMBLER_NAME (current_function_decl)));
335 *summary = &entry->summary;
337 return entry->counts;
340 /* Generate a MEM rtl to access COUNTER NO . */
343 coverage_counter_ref (unsigned counter, unsigned no)
345 unsigned gcov_size = tree_low_cst (TYPE_SIZE (GCOV_TYPE_NODE), 1);
346 enum machine_mode mode = mode_for_size (gcov_size, MODE_INT, 0);
349 if (!ctr_labels[counter])
351 /* Generate and save a copy of this so it can be shared. */
354 ASM_GENERATE_INTERNAL_LABEL (buf, "LPBX", counter + 1);
355 ctr_labels[counter] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
357 if (no + 1 > fn_n_ctrs[counter])
359 fn_n_ctrs[counter] = no + 1;
360 fn_ctr_mask |= 1 << counter;
363 no += prg_n_ctrs[counter];
364 ref = plus_constant (ctr_labels[counter], gcov_size / BITS_PER_UNIT * no);
365 ref = gen_rtx_MEM (mode, ref);
366 set_mem_alias_set (ref, new_alias_set ());
371 /* Generate a checksum for a string. CHKSUM is the current
375 checksum_string (unsigned chksum, const char *string)
379 unsigned value = *string << 24;
382 for (ix = 8; ix--; value <<= 1)
386 feedback = (value ^ chksum) & 0x80000000 ? 0x04c11db7 : 0;
396 /* Compute checksum for the current function. We generate a CRC32. */
401 unsigned chksum = DECL_SOURCE_LINE (current_function_decl);
403 chksum = checksum_string (chksum, DECL_SOURCE_FILE (current_function_decl));
404 chksum = checksum_string
405 (chksum, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl)));
410 /* Begin output to the graph file for the current function.
411 Opens the output file, if not already done. Writes the
412 function header, if not already done. Returns non-zero if data
416 coverage_begin_output ()
418 if (!bbg_function_announced)
420 const char *file = DECL_SOURCE_FILE (current_function_decl);
421 unsigned line = DECL_SOURCE_LINE (current_function_decl);
422 unsigned long offset;
424 if (!bbg_file_opened)
426 if (!gcov_open (bbg_file_name, -1))
427 error ("cannot open %s", bbg_file_name);
430 gcov_write_unsigned (GCOV_GRAPH_MAGIC);
431 gcov_write_unsigned (GCOV_VERSION);
436 /* Announce function */
437 offset = gcov_write_tag (GCOV_TAG_FUNCTION);
438 gcov_write_unsigned (fn_ident);
439 gcov_write_unsigned (compute_checksum ());
440 gcov_write_string (IDENTIFIER_POINTER
441 (DECL_ASSEMBLER_NAME (current_function_decl)));
442 gcov_write_string (file);
443 gcov_write_unsigned (line);
444 gcov_write_length (offset);
446 bbg_function_announced = 1;
448 return !gcov_is_error ();
451 /* Finish coverage data for the current function. Verify no output
452 error has occurred. Save function coverage counts. */
455 coverage_end_function ()
459 if (bbg_file_opened > 1 && gcov_is_error ())
461 warning ("error writing `%s'", bbg_file_name);
462 bbg_file_opened = -1;
467 struct function_list *item;
469 item = xmalloc (sizeof (struct function_list));
471 *functions_tail = item;
472 functions_tail = &item->next;
475 /* It would be nice to use the unique source location. */
476 item->ident = fn_ident;
477 item->checksum = compute_checksum ();
478 for (i = 0; i != GCOV_COUNTERS; i++)
480 item->n_ctrs[i] = fn_n_ctrs[i];
481 prg_n_ctrs[i] += fn_n_ctrs[i];
484 prg_ctr_mask |= fn_ctr_mask;
487 bbg_function_announced = 0;
491 /* Creates the gcov_fn_info RECORD_TYPE. */
494 build_fn_info_type (counters)
497 tree type = (*lang_hooks.types.make_type) (RECORD_TYPE);
502 fields = build_decl (FIELD_DECL, NULL_TREE, unsigned_intSI_type_node);
505 field = build_decl (FIELD_DECL, NULL_TREE, unsigned_intSI_type_node);
506 TREE_CHAIN (field) = fields;
509 array_type = build_index_type (build_int_2 (counters - 1, 0));
510 array_type = build_array_type (unsigned_type_node, array_type);
513 field = build_decl (FIELD_DECL, NULL_TREE, array_type);
514 TREE_CHAIN (field) = fields;
517 finish_builtin_struct (type, "__gcov_fn_info", fields, NULL_TREE);
522 /* Creates a CONSTRUCTOR for a gcov_fn_info. FUNCTION is
523 the function being processed and TYPE is the gcov_fn_info
527 build_fn_info_value (function, type)
528 const struct function_list *function;
531 tree value = NULL_TREE;
532 tree fields = TYPE_FIELDS (type);
534 tree array_value = NULL_TREE;
537 value = tree_cons (fields,
538 convert (unsigned_intSI_type_node,
539 build_int_2 (function->ident, 0)),
541 fields = TREE_CHAIN (fields);
544 value = tree_cons (fields,
545 convert (unsigned_intSI_type_node,
546 build_int_2 (function->checksum, 0)),
548 fields = TREE_CHAIN (fields);
551 for (ix = 0; ix != GCOV_COUNTERS; ix++)
552 if (prg_ctr_mask & (1 << ix))
554 tree counters = convert (unsigned_type_node,
555 build_int_2 (function->n_ctrs[ix], 0));
557 array_value = tree_cons (NULL_TREE, counters, array_value);
560 array_value = build_constructor (TREE_TYPE (fields), nreverse (array_value));
561 value = tree_cons (fields, array_value, value);
563 value = build_constructor (type, nreverse (value));
568 /* Creates the gcov_ctr_info RECORD_TYPE. */
571 build_ctr_info_type ()
573 tree type = (*lang_hooks.types.make_type) (RECORD_TYPE);
574 tree field, fields = NULL_TREE;
575 tree gcov_ptr_type = build_pointer_type (GCOV_TYPE_NODE);
576 tree gcov_merge_fn_type;
579 field = build_decl (FIELD_DECL, NULL_TREE, unsigned_intSI_type_node);
580 TREE_CHAIN (field) = fields;
584 field = build_decl (FIELD_DECL, NULL_TREE, gcov_ptr_type);
585 TREE_CHAIN (field) = fields;
590 build_function_type_list (void_type_node,
591 gcov_ptr_type, unsigned_type_node,
593 field = build_decl (FIELD_DECL, NULL_TREE,
594 build_pointer_type (gcov_merge_fn_type));
595 TREE_CHAIN (field) = fields;
598 finish_builtin_struct (type, "__gcov_ctr_info", fields, NULL_TREE);
603 /* Creates a CONSTRUCTOR for a gcov_ctr_info. COUNTER is
604 the counter being processed and TYPE is the gcov_ctr_info
608 build_ctr_info_value (counter, type)
612 tree value = NULL_TREE;
613 tree fields = TYPE_FIELDS (type);
617 value = tree_cons (fields,
618 convert (unsigned_intSI_type_node,
619 build_int_2 (prg_n_ctrs[counter], 0)),
621 fields = TREE_CHAIN (fields);
623 if (prg_n_ctrs[counter])
625 tree array_type, array;
627 array_type = build_index_type (build_int_2 (prg_n_ctrs[counter] - 1, 0));
628 array_type = build_array_type (TREE_TYPE (TREE_TYPE (fields)),
631 array = build (VAR_DECL, array_type, NULL_TREE, NULL_TREE);
632 TREE_STATIC (array) = 1;
633 DECL_NAME (array) = get_identifier (XSTR (ctr_labels[counter], 0));
634 assemble_variable (array, 0, 0, 0);
636 value = tree_cons (fields,
637 build1 (ADDR_EXPR, TREE_TYPE (fields), array),
641 value = tree_cons (fields, null_pointer_node, value);
642 fields = TREE_CHAIN (fields);
644 fn = build_decl (FUNCTION_DECL,
645 get_identifier (ctr_merge_functions[counter]),
646 TREE_TYPE (TREE_TYPE (fields)));
647 DECL_EXTERNAL (fn) = 1;
648 TREE_PUBLIC (fn) = 1;
649 DECL_ARTIFICIAL (fn) = 1;
650 TREE_NOTHROW (fn) = 1;
651 value = tree_cons (fields,
652 build1 (ADDR_EXPR, TREE_TYPE (fields), fn),
655 value = build_constructor (type, nreverse (value));
660 /* Creates the gcov_info RECORD_TYPE and initializer for it. Returns a
666 unsigned n_ctr_types, ix;
667 tree type, const_type;
668 tree fn_info_type, fn_info_value = NULL_TREE;
669 tree fn_info_ptr_type;
670 tree ctr_info_type, ctr_info_ary_type, ctr_info_value = NULL_TREE;
671 tree field, fields = NULL_TREE;
672 tree value = NULL_TREE;
673 tree filename_string;
677 const struct function_list *fn;
680 /* Count the number of active counters. */
681 for (n_ctr_types = 0, ix = 0; ix != GCOV_COUNTERS; ix++)
682 if (prg_ctr_mask & (1 << ix))
685 type = (*lang_hooks.types.make_type) (RECORD_TYPE);
686 const_type = build_qualified_type (type, TYPE_QUAL_CONST);
689 field = build_decl (FIELD_DECL, NULL_TREE, unsigned_intSI_type_node);
690 TREE_CHAIN (field) = fields;
692 value = tree_cons (field, convert (unsigned_intSI_type_node,
693 build_int_2 (GCOV_VERSION, 0)),
697 field = build_decl (FIELD_DECL, NULL_TREE, build_pointer_type (const_type));
698 TREE_CHAIN (field) = fields;
700 value = tree_cons (field, null_pointer_node, value);
703 string_type = build_pointer_type (build_qualified_type (char_type_node,
705 field = build_decl (FIELD_DECL, NULL_TREE, string_type);
706 TREE_CHAIN (field) = fields;
708 filename = getpwd ();
709 filename = (filename && da_file_name[0] != '/'
710 ? concat (filename, "/", da_file_name, NULL)
712 filename_len = strlen (filename);
713 filename_string = build_string (filename_len + 1, filename);
714 if (filename != da_file_name)
716 TREE_TYPE (filename_string) =
717 build_array_type (char_type_node,
718 build_index_type (build_int_2 (filename_len, 0)));
719 value = tree_cons (field, build1 (ADDR_EXPR, string_type, filename_string),
722 /* Build the fn_info type and initializer. */
723 fn_info_type = build_fn_info_type (n_ctr_types);
724 fn_info_ptr_type = build_pointer_type (build_qualified_type
725 (fn_info_type, TYPE_QUAL_CONST));
726 for (fn = functions_head, n_fns = 0; fn; fn = fn->next, n_fns++)
727 fn_info_value = tree_cons (NULL_TREE,
728 build_fn_info_value (fn, fn_info_type),
734 array_type = build_index_type (build_int_2 (n_fns - 1, 0));
735 array_type = build_array_type (fn_info_type, array_type);
737 fn_info_value = build_constructor (array_type, nreverse (fn_info_value));
738 fn_info_value = build1 (ADDR_EXPR, fn_info_ptr_type, fn_info_value);
741 fn_info_value = null_pointer_node;
743 /* number of functions */
744 field = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node);
745 TREE_CHAIN (field) = fields;
747 value = tree_cons (field,
748 convert (unsigned_type_node, build_int_2 (n_fns, 0)),
752 field = build_decl (FIELD_DECL, NULL_TREE, fn_info_ptr_type);
753 TREE_CHAIN (field) = fields;
755 value = tree_cons (field, fn_info_value, value);
758 field = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node);
759 TREE_CHAIN (field) = fields;
761 value = tree_cons (field,
762 convert (unsigned_type_node,
763 build_int_2 (prg_ctr_mask, 0)),
767 ctr_info_type = build_ctr_info_type ();
768 ctr_info_ary_type = build_index_type (build_int_2 (n_ctr_types, 0));
769 ctr_info_ary_type = build_array_type (ctr_info_type, ctr_info_ary_type);
770 for (ix = 0; ix != GCOV_COUNTERS; ix++)
771 if (prg_ctr_mask & (1 << ix))
772 ctr_info_value = tree_cons (NULL_TREE,
773 build_ctr_info_value (ix, ctr_info_type),
775 ctr_info_value = build_constructor (ctr_info_ary_type,
776 nreverse (ctr_info_value));
778 field = build_decl (FIELD_DECL, NULL_TREE, ctr_info_ary_type);
779 TREE_CHAIN (field) = fields;
781 value = tree_cons (field, ctr_info_value, value);
783 finish_builtin_struct (type, "__gcov_info", fields, NULL_TREE);
785 value = build_constructor (type, nreverse (value));
790 /* Write out the structure which libgcov uses to locate all the
791 counters. The structures used here must match those defined in
792 gcov-io.h. Write out the constructor to call __gcov_init. */
797 tree gcov_info, gcov_info_value;
801 rtx gcov_info_address;
802 int save_flag_inline_functions = flag_inline_functions;
807 gcov_info_value = build_gcov_info ();
809 gcov_info = build (VAR_DECL, TREE_TYPE (gcov_info_value),
810 NULL_TREE, NULL_TREE);
811 DECL_INITIAL (gcov_info) = gcov_info_value;
813 TREE_STATIC (gcov_info) = 1;
814 ASM_GENERATE_INTERNAL_LABEL (name, "LPBX", 0);
815 DECL_NAME (gcov_info) = get_identifier (name);
817 /* Build structure. */
818 assemble_variable (gcov_info, 0, 0, 0);
820 /* Build the constructor function to invoke __gcov_init. */
821 ctor_name = concat (IDENTIFIER_POINTER (get_file_function_name ('I')),
823 ctor = build_decl (FUNCTION_DECL, get_identifier (ctor_name),
824 build_function_type (void_type_node, NULL_TREE));
826 DECL_EXTERNAL (ctor) = 0;
828 /* It can be a static function as long as collect2 does not have
829 to scan the object file to find its ctor/dtor routine. */
830 TREE_PUBLIC (ctor) = ! targetm.have_ctors_dtors;
831 TREE_USED (ctor) = 1;
832 DECL_RESULT (ctor) = build_decl (RESULT_DECL, NULL_TREE, void_type_node);
834 ctor = (*lang_hooks.decls.pushdecl) (ctor);
835 rest_of_decl_compilation (ctor, 0, 1, 0);
836 announce_function (ctor);
837 current_function_decl = ctor;
838 DECL_INITIAL (ctor) = error_mark_node;
839 make_decl_rtl (ctor, NULL);
840 init_function_start (ctor, input_filename, input_line);
841 (*lang_hooks.decls.pushlevel) (0);
842 expand_function_start (ctor, 0);
843 cfun->arc_profile = 0;
845 /* Actually generate the code to call __gcov_init. */
846 gcov_info_address = force_reg (Pmode, XEXP (DECL_RTL (gcov_info), 0));
847 emit_library_call (gcov_init_libfunc, LCT_NORMAL, VOIDmode, 1,
848 gcov_info_address, Pmode);
850 expand_function_end (input_filename, input_line, 0);
851 (*lang_hooks.decls.poplevel) (1, 0, 1);
853 /* Since ctor isn't in the list of globals, it would never be emitted
854 when it's considered to be 'safe' for inlining, so turn off
855 flag_inline_functions. */
856 flag_inline_functions = 0;
858 rest_of_compilation (ctor);
860 /* Reset flag_inline_functions to its original value. */
861 flag_inline_functions = save_flag_inline_functions;
864 fflush (asm_out_file);
865 current_function_decl = NULL_TREE;
867 if (targetm.have_ctors_dtors)
868 (* targetm.asm_out.constructor) (XEXP (DECL_RTL (ctor), 0),
869 DEFAULT_INIT_PRIORITY);
872 /* Perform file-level initialization. Read in data file, generate name
876 coverage_init (filename)
877 const char *filename;
879 int len = strlen (filename);
881 /* Name of da file. */
882 da_file_name = (char *) xmalloc (len + strlen (GCOV_DATA_SUFFIX) + 1);
883 strcpy (da_file_name, filename);
884 strcat (da_file_name, GCOV_DATA_SUFFIX);
886 /* Name of bbg file. */
887 bbg_file_name = (char *) xmalloc (len + strlen (GCOV_GRAPH_SUFFIX) + 1);
888 strcpy (bbg_file_name, filename);
889 strcat (bbg_file_name, GCOV_GRAPH_SUFFIX);
894 /* Performs file-level cleanup. Close graph file, generate coverage
895 variables and constructor. */
903 int error = gcov_close ();
906 unlink (bbg_file_name);
908 /* If the compiler is instrumented, we should not
909 unconditionally remove the counts file, because we might be
910 recompiling ourselves. The .da files are all removed during
911 copying the stage1 files. */
914 unlink (da_file_name);
918 #include "gt-coverage.h"