coverage.c (read_counts_file): Better error messages...
[platform/upstream/gcc.git] / gcc / coverage.c
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
8
9 This file is part of GCC.
10
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
14 version.
15
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
19 for more details.
20
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
24 02111-1307, USA.  */
25
26
27 #define GCOV_LINKAGE
28
29 #include "config.h"
30 #include "system.h"
31 #include "coretypes.h"
32 #include "tm.h"
33 #include "rtl.h"
34 #include "tree.h"
35 #include "flags.h"
36 #include "output.h"
37 #include "regs.h"
38 #include "expr.h"
39 #include "function.h"
40 #include "toplev.h"
41 #include "ggc.h"
42 #include "target.h"
43 #include "coverage.h"
44 #include "libfuncs.h"
45 #include "langhooks.h"
46 #include "hashtab.h"
47
48 #include "gcov-io.c"
49
50 struct function_list
51 {
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.  */
56 };
57
58 /* Counts information for a function.  */
59 typedef struct counts_entry
60 {
61   /* We hash by  */
62   unsigned ident;
63   unsigned ctr;
64
65   /* Store  */
66   unsigned checksum;
67   gcov_type *counts;
68   struct gcov_ctr_summary summary;
69
70   /* Workspace */
71   struct counts_entry *chain;
72
73 } counts_entry_t;
74
75 static struct function_list *functions_head = 0;
76 static struct function_list **functions_tail = &functions_head;
77 static unsigned no_coverage = 0;
78
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]; /* Total counters allocated.  */
82
83 /* Counter information for current function.  */
84 static unsigned fn_ctr_mask; /* Mask of counters used.  */
85 static unsigned fn_n_ctrs[GCOV_COUNTERS]; /* Counters allocated.  */
86 static unsigned fn_b_ctrs[GCOV_COUNTERS]; /* Allocation base.  */
87
88 /* Name of the output file for coverage output file.  */
89 static char *bbg_file_name;
90 static unsigned bbg_file_opened;
91 static int bbg_function_announced;
92
93 /* Name of the count data file.  */
94 static char *da_file_name;
95
96 /* Hash table of count data.  */
97 static htab_t counts_hash = NULL;
98
99 /* The names of the counter tables.  */
100 static GTY(()) rtx ctr_labels[GCOV_COUNTERS];
101
102 /* The names of merge functions for counters.  */
103 static const char *const ctr_merge_functions[GCOV_COUNTERS] = GCOV_MERGE_FUNCTIONS;
104 static const char *const ctr_names[GCOV_COUNTERS] = GCOV_COUNTER_NAMES;
105
106 /* Forward declarations.  */
107 static hashval_t htab_counts_entry_hash (const void *);
108 static int htab_counts_entry_eq (const void *, const void *);
109 static void htab_counts_entry_del (void *);
110 static void read_counts_file (void);
111 static unsigned compute_checksum (void);
112 static unsigned checksum_string (unsigned, const char *);
113 static tree build_fn_info_type (unsigned);
114 static tree build_fn_info_value (const struct function_list *, tree);
115 static tree build_ctr_info_type (void);
116 static tree build_ctr_info_value (unsigned, tree);
117 static tree build_gcov_info (void);
118 static void create_coverage (void);
119
120 \f
121 static hashval_t
122 htab_counts_entry_hash (const void *of)
123 {
124   const counts_entry_t *entry = of;
125
126   return entry->ident * GCOV_COUNTERS + entry->ctr;
127 }
128
129 static int
130 htab_counts_entry_eq (const void *of1, const void *of2)
131 {
132   const counts_entry_t *entry1 = of1;
133   const counts_entry_t *entry2 = of2;
134
135   return entry1->ident == entry2->ident && entry1->ctr == entry2->ctr;
136 }
137
138 static void
139 htab_counts_entry_del (void *of)
140 {
141   counts_entry_t *entry = of;
142
143   free (entry->counts);
144   free (entry);
145 }
146
147 /* Read in the counts file, if available.  */
148
149 static void
150 read_counts_file (void)
151 {
152   gcov_unsigned_t fn_ident = 0;
153   gcov_unsigned_t checksum = -1;
154   counts_entry_t *summaried = NULL;
155   unsigned seen_summary = 0;
156   gcov_unsigned_t tag;
157   int is_error = 0;
158
159   if (!gcov_open (da_file_name, 1))
160     return;
161
162   if (!gcov_magic (gcov_read_unsigned (), GCOV_DATA_MAGIC))
163     {
164       warning ("`%s' is not a gcov data file", da_file_name);
165       gcov_close ();
166       return;
167     }
168   else if ((tag = gcov_read_unsigned ()) != GCOV_VERSION)
169     {
170       char v[4], e[4];
171
172       GCOV_UNSIGNED2STRING (v, tag);
173       GCOV_UNSIGNED2STRING (e, GCOV_VERSION);
174
175       warning ("`%s' is version `%.4s', expected version `%.4s'",
176                da_file_name, v, e);
177       gcov_close ();
178       return;
179     }
180
181   /* Read and discard the stamp.  */
182   gcov_read_unsigned ();
183   
184   counts_hash = htab_create (10,
185                              htab_counts_entry_hash, htab_counts_entry_eq,
186                              htab_counts_entry_del);
187   while ((tag = gcov_read_unsigned ()))
188     {
189       gcov_unsigned_t length;
190       gcov_position_t offset;
191
192       length = gcov_read_unsigned ();
193       offset = gcov_position ();
194       if (tag == GCOV_TAG_FUNCTION)
195         {
196           fn_ident = gcov_read_unsigned ();
197           checksum = gcov_read_unsigned ();
198           if (seen_summary)
199             {
200               /* We have already seen a summary, this means that this
201                  new function begins a new set of program runs. We
202                  must unlink the summaried chain.  */
203               counts_entry_t *entry, *chain;
204
205               for (entry = summaried; entry; entry = chain)
206                 {
207                   chain = entry->chain;
208                   entry->chain = NULL;
209                 }
210               summaried = NULL;
211               seen_summary = 0;
212             }
213         }
214       else if (tag == GCOV_TAG_PROGRAM_SUMMARY)
215         {
216           counts_entry_t *entry;
217           struct gcov_summary summary;
218
219           gcov_read_summary (&summary);
220           seen_summary = 1;
221           for (entry = summaried; entry; entry = entry->chain)
222             {
223               struct gcov_ctr_summary *csum = &summary.ctrs[entry->ctr];
224
225               entry->summary.runs += csum->runs;
226               entry->summary.sum_all += csum->sum_all;
227               if (entry->summary.run_max < csum->run_max)
228                 entry->summary.run_max = csum->run_max;
229               entry->summary.sum_max += csum->sum_max;
230             }
231         }
232       else if (GCOV_TAG_IS_COUNTER (tag) && fn_ident)
233         {
234           counts_entry_t **slot, *entry, elt;
235           unsigned n_counts = GCOV_TAG_COUNTER_NUM (length);
236           unsigned ix;
237
238           elt.ident = fn_ident;
239           elt.ctr = GCOV_COUNTER_FOR_TAG (tag);
240
241           slot = (counts_entry_t **) htab_find_slot
242             (counts_hash, &elt, INSERT);
243           entry = *slot;
244           if (!entry)
245             {
246               *slot = entry = xcalloc (1, sizeof (counts_entry_t));
247               entry->ident = elt.ident;
248               entry->ctr = elt.ctr;
249               entry->checksum = checksum;
250               entry->summary.num = n_counts;
251               entry->counts = xcalloc (n_counts, sizeof (gcov_type));
252             }
253           else if (entry->checksum != checksum)
254             {
255               error ("coverage mismatch for function %u while reading execution counters.",
256                      fn_ident);
257               error ("checksum is %x instead of %x", entry->checksum, checksum);
258               htab_delete (counts_hash);
259               break;
260             }
261           else if (entry->summary.num != n_counts)
262             {
263               error ("coverage mismatch for function %u while reading execution counters.",
264                      fn_ident);
265               error ("number of counters is %d instead of %d", entry->summary.num, n_counts);
266               htab_delete (counts_hash);
267               break;
268             }
269           else if (elt.ctr >= GCOV_COUNTERS_SUMMABLE)
270             {
271               error ("cannot merge separate %s counters for function %u",
272                      ctr_names[elt.ctr], fn_ident);
273               goto skip_merge;
274             }
275
276           if (elt.ctr < GCOV_COUNTERS_SUMMABLE
277               /* This should always be true for a just allocated entry,
278                  and always false for an existing one. Check this way, in
279                  case the gcov file is corrupt.  */
280               && (!entry->chain || summaried != entry))
281             {
282               entry->chain = summaried;
283               summaried = entry;
284             }
285           for (ix = 0; ix != n_counts; ix++)
286             entry->counts[ix] += gcov_read_counter ();
287         skip_merge:;
288         }
289       gcov_sync (offset, length);
290       if ((is_error = gcov_is_error ()))
291         break;
292     }
293
294   if (!gcov_is_eof ())
295     {
296       error (is_error < 0 ? "`%s' has overflowed" : "`%s' is corrupted",
297              da_file_name);
298       htab_delete (counts_hash);
299     }
300
301   gcov_close ();
302 }
303
304 /* Returns the counters for a particular tag.  */
305
306 gcov_type *
307 get_coverage_counts (unsigned counter, unsigned expected,
308                      const struct gcov_ctr_summary **summary)
309 {
310   counts_entry_t *entry, elt;
311   gcov_unsigned_t checksum = -1;
312
313   /* No hash table, no counts.  */
314   if (!counts_hash)
315     {
316       static int warned = 0;
317
318       if (!warned++)
319         inform ("file %s not found, execution counts assumed to be zero",
320                 da_file_name);
321       return NULL;
322     }
323
324   elt.ident = current_function_funcdef_no + 1;
325   elt.ctr = counter;
326   entry = htab_find (counts_hash, &elt);
327   if (!entry)
328     {
329       warning ("no coverage for function '%s' found.", IDENTIFIER_POINTER
330                (DECL_ASSEMBLER_NAME (current_function_decl)));
331       return 0;
332     }
333
334   checksum = compute_checksum ();
335   if (entry->checksum != checksum)
336     {
337       error ("coverage mismatch for function '%s' while reading counter '%s'.",
338              IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl)),
339              ctr_names[counter]);
340       error ("checksum is %x instead of %x", entry->checksum, checksum);
341       return 0;
342     }
343   else if (entry->summary.num != expected)
344     {
345       error ("coverage mismatch for function '%s' while reading counter '%s'.",
346              IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl)),
347              ctr_names[counter]);
348       error ("number of counters is %d instead of %d", entry->summary.num, expected);
349       return 0;
350     }
351
352   if (summary)
353     *summary = &entry->summary;
354
355   return entry->counts;
356 }
357
358 /* Allocate NUM counters of type COUNTER. Returns nonzero if the
359    allocation succeeded.  */
360
361 int
362 coverage_counter_alloc (unsigned counter, unsigned num)
363 {
364   if (no_coverage)
365     return 0;
366
367   if (!num)
368     return 1;
369
370   if (!ctr_labels[counter])
371     {
372       /* Generate and save a copy of this so it can be shared.  */
373       char buf[20];
374
375       ASM_GENERATE_INTERNAL_LABEL (buf, "LPBX", counter + 1);
376       ctr_labels[counter] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
377     }
378   fn_b_ctrs[counter] = fn_n_ctrs[counter];
379   fn_n_ctrs[counter] += num;
380   fn_ctr_mask |= 1 << counter;
381   return 1;
382 }
383
384 /* Generate a MEM rtl to access COUNTER NO.  */
385
386 rtx
387 coverage_counter_ref (unsigned counter, unsigned no)
388 {
389   unsigned gcov_size = tree_low_cst (TYPE_SIZE (GCOV_TYPE_NODE), 1);
390   enum machine_mode mode = mode_for_size (gcov_size, MODE_INT, 0);
391   rtx ref;
392
393   if (no >= fn_n_ctrs[counter] - fn_b_ctrs[counter])
394     abort ();
395   no += prg_n_ctrs[counter] + fn_b_ctrs[counter];
396   ref = plus_constant (ctr_labels[counter], gcov_size / BITS_PER_UNIT * no);
397   ref = gen_rtx_MEM (mode, ref);
398   set_mem_alias_set (ref, new_alias_set ());
399
400   return ref;
401 }
402 \f
403 /* Generate a checksum for a string.  CHKSUM is the current
404    checksum.  */
405
406 static unsigned
407 checksum_string (unsigned chksum, const char *string)
408 {
409   do
410     {
411       unsigned value = *string << 24;
412       unsigned ix;
413
414       for (ix = 8; ix--; value <<= 1)
415         {
416           unsigned feedback;
417
418           feedback = (value ^ chksum) & 0x80000000 ? 0x04c11db7 : 0;
419           chksum <<= 1;
420           chksum ^= feedback;
421         }
422     }
423   while (*string++);
424
425   return chksum;
426 }
427
428 /* Compute checksum for the current function.  We generate a CRC32.  */
429
430 static unsigned
431 compute_checksum (void)
432 {
433   unsigned chksum = DECL_SOURCE_LINE (current_function_decl);
434
435   chksum = checksum_string (chksum, DECL_SOURCE_FILE (current_function_decl));
436   chksum = checksum_string
437     (chksum, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl)));
438
439   return chksum;
440 }
441 \f
442 /* Begin output to the graph file for the current function.
443    Opens the output file, if not already done. Writes the
444    function header, if not already done. Returns nonzero if data
445    should be output.  */
446
447 int
448 coverage_begin_output (void)
449 {
450   if (no_coverage)
451     return 0;
452
453   if (!bbg_function_announced)
454     {
455       const char *file = DECL_SOURCE_FILE (current_function_decl);
456       unsigned line = DECL_SOURCE_LINE (current_function_decl);
457       unsigned long offset;
458
459       if (!bbg_file_opened)
460         {
461           if (!gcov_open (bbg_file_name, -1))
462             error ("cannot open %s", bbg_file_name);
463           else
464             {
465               gcov_write_unsigned (GCOV_NOTE_MAGIC);
466               gcov_write_unsigned (GCOV_VERSION);
467               gcov_write_unsigned (local_tick);
468             }
469           bbg_file_opened = 1;
470         }
471
472       /* Announce function */
473       offset = gcov_write_tag (GCOV_TAG_FUNCTION);
474       gcov_write_unsigned (current_function_funcdef_no + 1);
475       gcov_write_unsigned (compute_checksum ());
476       gcov_write_string (IDENTIFIER_POINTER
477                          (DECL_ASSEMBLER_NAME (current_function_decl)));
478       gcov_write_string (file);
479       gcov_write_unsigned (line);
480       gcov_write_length (offset);
481
482       bbg_function_announced = 1;
483     }
484   return !gcov_is_error ();
485 }
486
487 /* Finish coverage data for the current function. Verify no output
488    error has occurred.  Save function coverage counts.  */
489
490 void
491 coverage_end_function (void)
492 {
493   unsigned i;
494
495   if (bbg_file_opened > 1 && gcov_is_error ())
496     {
497       warning ("error writing `%s'", bbg_file_name);
498       bbg_file_opened = -1;
499     }
500
501   if (fn_ctr_mask)
502     {
503       struct function_list *item;
504
505       item = xmalloc (sizeof (struct function_list));
506
507       *functions_tail = item;
508       functions_tail = &item->next;
509
510       item->next = 0;
511       item->ident = current_function_funcdef_no + 1;
512       item->checksum = compute_checksum ();
513       for (i = 0; i != GCOV_COUNTERS; i++)
514         {
515           item->n_ctrs[i] = fn_n_ctrs[i];
516           prg_n_ctrs[i] += fn_n_ctrs[i];
517           fn_n_ctrs[i] = fn_b_ctrs[i] = 0;
518         }
519       prg_ctr_mask |= fn_ctr_mask;
520       fn_ctr_mask = 0;
521     }
522   bbg_function_announced = 0;
523 }
524
525 /* Creates the gcov_fn_info RECORD_TYPE.  */
526
527 static tree
528 build_fn_info_type (unsigned int counters)
529 {
530   tree type = (*lang_hooks.types.make_type) (RECORD_TYPE);
531   tree field, fields;
532   tree array_type;
533
534   /* ident */
535   fields = build_decl (FIELD_DECL, NULL_TREE, unsigned_intSI_type_node);
536
537   /* checksum */
538   field = build_decl (FIELD_DECL, NULL_TREE, unsigned_intSI_type_node);
539   TREE_CHAIN (field) = fields;
540   fields = field;
541
542   array_type = build_index_type (build_int_2 (counters - 1, 0));
543   array_type = build_array_type (unsigned_type_node, array_type);
544
545   /* counters */
546   field = build_decl (FIELD_DECL, NULL_TREE, array_type);
547   TREE_CHAIN (field) = fields;
548   fields = field;
549
550   finish_builtin_struct (type, "__gcov_fn_info", fields, NULL_TREE);
551
552   return type;
553 }
554
555 /* Creates a CONSTRUCTOR for a gcov_fn_info. FUNCTION is
556    the function being processed and TYPE is the gcov_fn_info
557    RECORD_TYPE.  */
558
559 static tree
560 build_fn_info_value (const struct function_list *function, tree type)
561 {
562   tree value = NULL_TREE;
563   tree fields = TYPE_FIELDS (type);
564   unsigned ix;
565   tree array_value = NULL_TREE;
566
567   /* ident */
568   value = tree_cons (fields,
569                      convert (unsigned_intSI_type_node,
570                               build_int_2 (function->ident, 0)),
571                      value);
572   fields = TREE_CHAIN (fields);
573
574   /* checksum */
575   value = tree_cons (fields,
576                      convert (unsigned_intSI_type_node,
577                               build_int_2 (function->checksum, 0)),
578                      value);
579   fields = TREE_CHAIN (fields);
580
581   /* counters */
582   for (ix = 0; ix != GCOV_COUNTERS; ix++)
583     if (prg_ctr_mask & (1 << ix))
584       {
585         tree counters = convert (unsigned_type_node,
586                                  build_int_2 (function->n_ctrs[ix], 0));
587
588         array_value = tree_cons (NULL_TREE, counters, array_value);
589       }
590
591   array_value = build_constructor (TREE_TYPE (fields), nreverse (array_value));
592   value = tree_cons (fields, array_value, value);
593
594   value = build_constructor (type, nreverse (value));
595
596   return value;
597 }
598
599 /* Creates the gcov_ctr_info RECORD_TYPE.  */
600
601 static tree
602 build_ctr_info_type (void)
603 {
604   tree type = (*lang_hooks.types.make_type) (RECORD_TYPE);
605   tree field, fields = NULL_TREE;
606   tree gcov_ptr_type = build_pointer_type (GCOV_TYPE_NODE);
607   tree gcov_merge_fn_type;
608
609   /* counters */
610   field = build_decl (FIELD_DECL, NULL_TREE, unsigned_intSI_type_node);
611   TREE_CHAIN (field) = fields;
612   fields = field;
613
614   /* values */
615   field = build_decl (FIELD_DECL, NULL_TREE, gcov_ptr_type);
616   TREE_CHAIN (field) = fields;
617   fields = field;
618
619   /* merge */
620   gcov_merge_fn_type =
621     build_function_type_list (void_type_node,
622                               gcov_ptr_type, unsigned_type_node,
623                               NULL_TREE);
624   field = build_decl (FIELD_DECL, NULL_TREE,
625                       build_pointer_type (gcov_merge_fn_type));
626   TREE_CHAIN (field) = fields;
627   fields = field;
628
629   finish_builtin_struct (type, "__gcov_ctr_info", fields, NULL_TREE);
630
631   return type;
632 }
633
634 /* Creates a CONSTRUCTOR for a gcov_ctr_info. COUNTER is
635    the counter being processed and TYPE is the gcov_ctr_info
636    RECORD_TYPE.  */
637
638 static tree
639 build_ctr_info_value (unsigned int counter, tree type)
640 {
641   tree value = NULL_TREE;
642   tree fields = TYPE_FIELDS (type);
643   tree fn;
644
645   /* counters */
646   value = tree_cons (fields,
647                      convert (unsigned_intSI_type_node,
648                               build_int_2 (prg_n_ctrs[counter], 0)),
649                      value);
650   fields = TREE_CHAIN (fields);
651
652   if (prg_n_ctrs[counter])
653     {
654       tree array_type, array;
655
656       array_type = build_index_type (build_int_2 (prg_n_ctrs[counter] - 1, 0));
657       array_type = build_array_type (TREE_TYPE (TREE_TYPE (fields)),
658                                      array_type);
659
660       array = build_decl (VAR_DECL, NULL_TREE, array_type);
661       TREE_STATIC (array) = 1;
662       DECL_NAME (array) = get_identifier (XSTR (ctr_labels[counter], 0));
663       assemble_variable (array, 0, 0, 0);
664
665       value = tree_cons (fields,
666                          build1 (ADDR_EXPR, TREE_TYPE (fields), array),
667                          value);
668     }
669   else
670     value = tree_cons (fields, null_pointer_node, value);
671   fields = TREE_CHAIN (fields);
672
673   fn = build_decl (FUNCTION_DECL,
674                    get_identifier (ctr_merge_functions[counter]),
675                    TREE_TYPE (TREE_TYPE (fields)));
676   DECL_EXTERNAL (fn) = 1;
677   TREE_PUBLIC (fn) = 1;
678   DECL_ARTIFICIAL (fn) = 1;
679   TREE_NOTHROW (fn) = 1;
680   value = tree_cons (fields,
681                      build1 (ADDR_EXPR, TREE_TYPE (fields), fn),
682                      value);
683
684   value = build_constructor (type, nreverse (value));
685
686   return value;
687 }
688
689 /* Creates the gcov_info RECORD_TYPE and initializer for it. Returns a
690    CONSTRUCTOR.  */
691
692 static tree
693 build_gcov_info (void)
694 {
695   unsigned n_ctr_types, ix;
696   tree type, const_type;
697   tree fn_info_type, fn_info_value = NULL_TREE;
698   tree fn_info_ptr_type;
699   tree ctr_info_type, ctr_info_ary_type, ctr_info_value = NULL_TREE;
700   tree field, fields = NULL_TREE;
701   tree value = NULL_TREE;
702   tree filename_string;
703   char *filename;
704   int filename_len;
705   unsigned n_fns;
706   const struct function_list *fn;
707   tree string_type;
708
709   /* Count the number of active counters.  */
710   for (n_ctr_types = 0, ix = 0; ix != GCOV_COUNTERS; ix++)
711     if (prg_ctr_mask & (1 << ix))
712       n_ctr_types++;
713
714   type = (*lang_hooks.types.make_type) (RECORD_TYPE);
715   const_type = build_qualified_type (type, TYPE_QUAL_CONST);
716
717   /* Version ident */
718   field = build_decl (FIELD_DECL, NULL_TREE, unsigned_intSI_type_node);
719   TREE_CHAIN (field) = fields;
720   fields = field;
721   value = tree_cons (field, convert (unsigned_intSI_type_node,
722                                      build_int_2 (GCOV_VERSION, 0)),
723                      value);
724
725   /* next -- NULL */
726   field = build_decl (FIELD_DECL, NULL_TREE, build_pointer_type (const_type));
727   TREE_CHAIN (field) = fields;
728   fields = field;
729   value = tree_cons (field, null_pointer_node, value);
730
731   /* stamp */
732   field = build_decl (FIELD_DECL, NULL_TREE, unsigned_intSI_type_node);
733   TREE_CHAIN (field) = fields;
734   fields = field;
735   value = tree_cons (field, convert (unsigned_intSI_type_node,
736                                      build_int_2 (local_tick, 0)),
737                      value);
738
739   /* Filename */
740   string_type = build_pointer_type (build_qualified_type (char_type_node,
741                                                     TYPE_QUAL_CONST));
742   field = build_decl (FIELD_DECL, NULL_TREE, string_type);
743   TREE_CHAIN (field) = fields;
744   fields = field;
745   filename = getpwd ();
746   filename = (filename && da_file_name[0] != '/'
747               ? concat (filename, "/", da_file_name, NULL)
748               : da_file_name);
749   filename_len = strlen (filename);
750   filename_string = build_string (filename_len + 1, filename);
751   if (filename != da_file_name)
752     free (filename);
753   TREE_TYPE (filename_string) =
754           build_array_type (char_type_node,
755                             build_index_type (build_int_2 (filename_len, 0)));
756   value = tree_cons (field, build1 (ADDR_EXPR, string_type, filename_string),
757                      value);
758
759   /* Build the fn_info type and initializer.  */
760   fn_info_type = build_fn_info_type (n_ctr_types);
761   fn_info_ptr_type = build_pointer_type (build_qualified_type
762                                          (fn_info_type, TYPE_QUAL_CONST));
763   for (fn = functions_head, n_fns = 0; fn; fn = fn->next, n_fns++)
764     fn_info_value = tree_cons (NULL_TREE,
765                                build_fn_info_value (fn, fn_info_type),
766                                fn_info_value);
767   if (n_fns)
768     {
769       tree array_type;
770
771       array_type = build_index_type (build_int_2 (n_fns - 1, 0));
772       array_type = build_array_type (fn_info_type, array_type);
773
774       fn_info_value = build_constructor (array_type, nreverse (fn_info_value));
775       fn_info_value = build1 (ADDR_EXPR, fn_info_ptr_type, fn_info_value);
776     }
777   else
778     fn_info_value = null_pointer_node;
779
780   /* number of functions */
781   field = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node);
782   TREE_CHAIN (field) = fields;
783   fields = field;
784   value = tree_cons (field,
785                      convert (unsigned_type_node, build_int_2 (n_fns, 0)),
786                      value);
787
788   /* fn_info table */
789   field = build_decl (FIELD_DECL, NULL_TREE, fn_info_ptr_type);
790   TREE_CHAIN (field) = fields;
791   fields = field;
792   value = tree_cons (field, fn_info_value, value);
793
794   /* counter_mask */
795   field = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node);
796   TREE_CHAIN (field) = fields;
797   fields = field;
798   value = tree_cons (field,
799                      convert (unsigned_type_node,
800                               build_int_2 (prg_ctr_mask, 0)),
801                      value);
802
803   /* counters */
804   ctr_info_type = build_ctr_info_type ();
805   ctr_info_ary_type = build_index_type (build_int_2 (n_ctr_types, 0));
806   ctr_info_ary_type = build_array_type (ctr_info_type, ctr_info_ary_type);
807   for (ix = 0; ix != GCOV_COUNTERS; ix++)
808     if (prg_ctr_mask & (1 << ix))
809       ctr_info_value = tree_cons (NULL_TREE,
810                                   build_ctr_info_value (ix, ctr_info_type),
811                                   ctr_info_value);
812   ctr_info_value = build_constructor (ctr_info_ary_type,
813                                       nreverse (ctr_info_value));
814
815   field = build_decl (FIELD_DECL, NULL_TREE, ctr_info_ary_type);
816   TREE_CHAIN (field) = fields;
817   fields = field;
818   value = tree_cons (field, ctr_info_value, value);
819
820   finish_builtin_struct (type, "__gcov_info", fields, NULL_TREE);
821
822   value = build_constructor (type, nreverse (value));
823
824   return value;
825 }
826
827 /* Write out the structure which libgcov uses to locate all the
828    counters.  The structures used here must match those defined in
829    gcov-io.h.  Write out the constructor to call __gcov_init.  */
830
831 static void
832 create_coverage (void)
833 {
834   tree gcov_info, gcov_info_value;
835   char name[20];
836   char *ctor_name;
837   tree ctor;
838   rtx gcov_info_address;
839
840   no_coverage = 1; /* Disable any further coverage.  */
841
842   if (!prg_ctr_mask)
843     return;
844
845   gcov_info_value = build_gcov_info ();
846
847   gcov_info = build_decl (VAR_DECL, NULL_TREE, TREE_TYPE (gcov_info_value));
848   DECL_INITIAL (gcov_info) = gcov_info_value;
849
850   TREE_STATIC (gcov_info) = 1;
851   ASM_GENERATE_INTERNAL_LABEL (name, "LPBX", 0);
852   DECL_NAME (gcov_info) = get_identifier (name);
853
854   /* Build structure.  */
855   assemble_variable (gcov_info, 0, 0, 0);
856
857   /* Build the constructor function to invoke __gcov_init.  */
858   ctor_name = concat (IDENTIFIER_POINTER (get_file_function_name ('I')),
859                       "_GCOV", NULL);
860   ctor = build_decl (FUNCTION_DECL, get_identifier (ctor_name),
861                      build_function_type (void_type_node, NULL_TREE));
862   free (ctor_name);
863   DECL_EXTERNAL (ctor) = 0;
864
865   /* It can be a static function as long as collect2 does not have
866      to scan the object file to find its ctor/dtor routine.  */
867   TREE_PUBLIC (ctor) = ! targetm.have_ctors_dtors;
868   TREE_USED (ctor) = 1;
869   DECL_RESULT (ctor) = build_decl (RESULT_DECL, NULL_TREE, void_type_node);
870   DECL_UNINLINABLE (ctor) = 1;
871
872   ctor = (*lang_hooks.decls.pushdecl) (ctor);
873   rest_of_decl_compilation (ctor, 0, 1, 0);
874   announce_function (ctor);
875   current_function_decl = ctor;
876   make_decl_rtl (ctor, NULL);
877   init_function_start (ctor);
878   expand_function_start (ctor, 0);
879   /* Actually generate the code to call __gcov_init.  */
880   gcov_info_address = force_reg (Pmode, XEXP (DECL_RTL (gcov_info), 0));
881   emit_library_call (gcov_init_libfunc, LCT_NORMAL, VOIDmode, 1,
882                      gcov_info_address, Pmode);
883
884   expand_function_end ();
885   /* Create a dummy BLOCK.  */
886   DECL_INITIAL (ctor) = make_node (BLOCK);
887   TREE_USED (DECL_INITIAL (ctor)) = 1;
888
889   rest_of_compilation (ctor);
890
891   if (! quiet_flag)
892     fflush (asm_out_file);
893   current_function_decl = NULL_TREE;
894
895   if (targetm.have_ctors_dtors)
896     (* targetm.asm_out.constructor) (XEXP (DECL_RTL (ctor), 0),
897                                      DEFAULT_INIT_PRIORITY);
898 }
899 \f
900 /* Perform file-level initialization. Read in data file, generate name
901    of graph file.  */
902
903 void
904 coverage_init (const char *filename)
905 {
906   int len = strlen (filename);
907
908   /* Name of da file.  */
909   da_file_name = xmalloc (len + strlen (GCOV_DATA_SUFFIX) + 1);
910   strcpy (da_file_name, filename);
911   strcat (da_file_name, GCOV_DATA_SUFFIX);
912
913   /* Name of bbg file.  */
914   bbg_file_name = xmalloc (len + strlen (GCOV_NOTE_SUFFIX) + 1);
915   strcpy (bbg_file_name, filename);
916   strcat (bbg_file_name, GCOV_NOTE_SUFFIX);
917
918   read_counts_file ();
919 }
920
921 /* Performs file-level cleanup.  Close graph file, generate coverage
922    variables and constructor.  */
923
924 void
925 coverage_finish (void)
926 {
927   create_coverage ();
928   if (bbg_file_opened)
929     {
930       int error = gcov_close ();
931
932       if (error)
933         unlink (bbg_file_name);
934       if (!local_tick)
935         /* Only remove the da file, if we cannot stamp it. If we can
936            stamp it, libgcov will DTRT.  */
937         unlink (da_file_name);
938     }
939 }
940
941 #include "gt-coverage.h"