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, 2004, 2005 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
9This file is part of GCC.
10
11GCC is free software; you can redistribute it and/or modify it under
12the terms of the GNU General Public License as published by the Free
13Software Foundation; either version 2, or (at your option) any later
14version.
15
16GCC is distributed in the hope that it will be useful, but WITHOUT ANY
17WARRANTY; without even the implied warranty of MERCHANTABILITY or
18FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
19for more details.
20
21You should have received a copy of the GNU General Public License
22along with GCC; see the file COPYING.  If not, write to the Free
23Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
2402110-1301, 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 "coverage.h"
43#include "langhooks.h"
44#include "hashtab.h"
45#include "tree-iterator.h"
46#include "cgraph.h"
47
48#include "gcov-io.c"
49
50struct 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.  */
59typedef 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
75static struct function_list *functions_head = 0;
76static struct function_list **functions_tail = &functions_head;
77static unsigned no_coverage = 0;
78
79/* Cumulative counter information for whole program.  */
80static unsigned prg_ctr_mask; /* Mask of counter types generated.  */
81static unsigned prg_n_ctrs[GCOV_COUNTERS]; /* Total counters allocated.  */
82
83/* Counter information for current function.  */
84static unsigned fn_ctr_mask; /* Mask of counters used.  */
85static unsigned fn_n_ctrs[GCOV_COUNTERS]; /* Counters allocated.  */
86static unsigned fn_b_ctrs[GCOV_COUNTERS]; /* Allocation base.  */
87
88/* Name of the output file for coverage output file.  */
89static char *bbg_file_name;
90static unsigned bbg_file_opened;
91static int bbg_function_announced;
92
93/* Name of the count data file.  */
94static char *da_file_name;
95
96/* Hash table of count data.  */
97static htab_t counts_hash = NULL;
98
99/* Trees representing the counter table arrays.  */
100static GTY(()) tree tree_ctr_tables[GCOV_COUNTERS];
101
102/* The names of the counter tables.  Not used if we're
103   generating counters at tree level.  */
104static GTY(()) rtx ctr_labels[GCOV_COUNTERS];
105
106/* The names of merge functions for counters.  */
107static const char *const ctr_merge_functions[GCOV_COUNTERS] = GCOV_MERGE_FUNCTIONS;
108static const char *const ctr_names[GCOV_COUNTERS] = GCOV_COUNTER_NAMES;
109
110/* Forward declarations.  */
111static hashval_t htab_counts_entry_hash (const void *);
112static int htab_counts_entry_eq (const void *, const void *);
113static void htab_counts_entry_del (void *);
114static void read_counts_file (void);
115static unsigned compute_checksum (void);
116static unsigned coverage_checksum_string (unsigned, const char *);
117static tree build_fn_info_type (unsigned);
118static tree build_fn_info_value (const struct function_list *, tree);
119static tree build_ctr_info_type (void);
120static tree build_ctr_info_value (unsigned, tree);
121static tree build_gcov_info (void);
122static void create_coverage (void);
123
124/* Return the type node for gcov_type.  */
125
126tree
127get_gcov_type (void)
128{
129  return lang_hooks.types.type_for_size (GCOV_TYPE_SIZE, false);
130}
131
132/* Return the type node for gcov_unsigned_t.  */
133
134static tree
135get_gcov_unsigned_t (void)
136{
137  return lang_hooks.types.type_for_size (32, true);
138}
139
140static hashval_t
141htab_counts_entry_hash (const void *of)
142{
143  const counts_entry_t *entry = of;
144
145  return entry->ident * GCOV_COUNTERS + entry->ctr;
146}
147
148static int
149htab_counts_entry_eq (const void *of1, const void *of2)
150{
151  const counts_entry_t *entry1 = of1;
152  const counts_entry_t *entry2 = of2;
153
154  return entry1->ident == entry2->ident && entry1->ctr == entry2->ctr;
155}
156
157static void
158htab_counts_entry_del (void *of)
159{
160  counts_entry_t *entry = of;
161
162  free (entry->counts);
163  free (entry);
164}
165
166/* Read in the counts file, if available.  */
167
168static void
169read_counts_file (void)
170{
171  gcov_unsigned_t fn_ident = 0;
172  gcov_unsigned_t checksum = -1;
173  counts_entry_t *summaried = NULL;
174  unsigned seen_summary = 0;
175  gcov_unsigned_t tag;
176  int is_error = 0;
177
178  if (!gcov_open (da_file_name, 1))
179    return;
180
181  if (!gcov_magic (gcov_read_unsigned (), GCOV_DATA_MAGIC))
182    {
183      warning (0, "%qs is not a gcov data file", da_file_name);
184      gcov_close ();
185      return;
186    }
187  else if ((tag = gcov_read_unsigned ()) != GCOV_VERSION)
188    {
189      char v[4], e[4];
190
191      GCOV_UNSIGNED2STRING (v, tag);
192      GCOV_UNSIGNED2STRING (e, GCOV_VERSION);
193
194      warning (0, "%qs is version %q.*s, expected version %q.*s",
195 	       da_file_name, 4, v, 4, e);
196      gcov_close ();
197      return;
198    }
199
200  /* Read and discard the stamp.  */
201  gcov_read_unsigned ();
202
203  counts_hash = htab_create (10,
204			     htab_counts_entry_hash, htab_counts_entry_eq,
205			     htab_counts_entry_del);
206  while ((tag = gcov_read_unsigned ()))
207    {
208      gcov_unsigned_t length;
209      gcov_position_t offset;
210
211      length = gcov_read_unsigned ();
212      offset = gcov_position ();
213      if (tag == GCOV_TAG_FUNCTION)
214	{
215	  fn_ident = gcov_read_unsigned ();
216	  checksum = gcov_read_unsigned ();
217	  if (seen_summary)
218	    {
219	      /* We have already seen a summary, this means that this
220		 new function begins a new set of program runs. We
221		 must unlink the summaried chain.  */
222	      counts_entry_t *entry, *chain;
223
224	      for (entry = summaried; entry; entry = chain)
225		{
226		  chain = entry->chain;
227		  entry->chain = NULL;
228		}
229	      summaried = NULL;
230	      seen_summary = 0;
231	    }
232	}
233      else if (tag == GCOV_TAG_PROGRAM_SUMMARY)
234	{
235	  counts_entry_t *entry;
236	  struct gcov_summary summary;
237
238	  gcov_read_summary (&summary);
239	  seen_summary = 1;
240	  for (entry = summaried; entry; entry = entry->chain)
241	    {
242	      struct gcov_ctr_summary *csum = &summary.ctrs[entry->ctr];
243
244	      entry->summary.runs += csum->runs;
245	      entry->summary.sum_all += csum->sum_all;
246	      if (entry->summary.run_max < csum->run_max)
247		entry->summary.run_max = csum->run_max;
248	      entry->summary.sum_max += csum->sum_max;
249	    }
250	}
251      else if (GCOV_TAG_IS_COUNTER (tag) && fn_ident)
252	{
253	  counts_entry_t **slot, *entry, elt;
254	  unsigned n_counts = GCOV_TAG_COUNTER_NUM (length);
255	  unsigned ix;
256
257	  elt.ident = fn_ident;
258	  elt.ctr = GCOV_COUNTER_FOR_TAG (tag);
259
260	  slot = (counts_entry_t **) htab_find_slot
261	    (counts_hash, &elt, INSERT);
262	  entry = *slot;
263	  if (!entry)
264	    {
265	      *slot = entry = xcalloc (1, sizeof (counts_entry_t));
266	      entry->ident = elt.ident;
267	      entry->ctr = elt.ctr;
268	      entry->checksum = checksum;
269	      entry->summary.num = n_counts;
270	      entry->counts = xcalloc (n_counts, sizeof (gcov_type));
271	    }
272	  else if (entry->checksum != checksum)
273	    {
274	      error ("coverage mismatch for function %u while reading execution counters",
275		     fn_ident);
276	      error ("checksum is %x instead of %x", entry->checksum, checksum);
277	      htab_delete (counts_hash);
278	      break;
279	    }
280	  else if (entry->summary.num != n_counts)
281	    {
282	      error ("coverage mismatch for function %u while reading execution counters",
283		     fn_ident);
284	      error ("number of counters is %d instead of %d", entry->summary.num, n_counts);
285	      htab_delete (counts_hash);
286	      break;
287	    }
288	  else if (elt.ctr >= GCOV_COUNTERS_SUMMABLE)
289	    {
290	      error ("cannot merge separate %s counters for function %u",
291		     ctr_names[elt.ctr], fn_ident);
292	      goto skip_merge;
293	    }
294
295	  if (elt.ctr < GCOV_COUNTERS_SUMMABLE
296	      /* This should always be true for a just allocated entry,
297		 and always false for an existing one. Check this way, in
298		 case the gcov file is corrupt.  */
299	      && (!entry->chain || summaried != entry))
300	    {
301	      entry->chain = summaried;
302	      summaried = entry;
303	    }
304	  for (ix = 0; ix != n_counts; ix++)
305	    entry->counts[ix] += gcov_read_counter ();
306	skip_merge:;
307	}
308      gcov_sync (offset, length);
309      if ((is_error = gcov_is_error ()))
310	{
311	  error (is_error < 0 ? "%qs has overflowed" : "%qs is corrupted",
312		 da_file_name);
313	  htab_delete (counts_hash);
314	  break;
315	}
316    }
317
318  gcov_close ();
319}
320
321/* Returns the counters for a particular tag.  */
322
323gcov_type *
324get_coverage_counts (unsigned counter, unsigned expected,
325		     const struct gcov_ctr_summary **summary)
326{
327  counts_entry_t *entry, elt;
328  gcov_unsigned_t checksum = -1;
329
330  /* No hash table, no counts.  */
331  if (!counts_hash)
332    {
333      static int warned = 0;
334
335      if (!warned++)
336	inform ((flag_guess_branch_prob
337		 ? "file %s not found, execution counts estimated"
338		 : "file %s not found, execution counts assumed to be zero"),
339		da_file_name);
340      return NULL;
341    }
342
343  elt.ident = current_function_funcdef_no + 1;
344  elt.ctr = counter;
345  entry = htab_find (counts_hash, &elt);
346  if (!entry)
347    {
348      warning (0, "no coverage for function %qs found", IDENTIFIER_POINTER
349	       (DECL_ASSEMBLER_NAME (current_function_decl)));
350      return 0;
351    }
352
353  checksum = compute_checksum ();
354  if (entry->checksum != checksum)
355    {
356      error ("coverage mismatch for function %qs while reading counter %qs",
357	     IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl)),
358	     ctr_names[counter]);
359      error ("checksum is %x instead of %x", entry->checksum, checksum);
360      return 0;
361    }
362  else if (entry->summary.num != expected)
363    {
364      error ("coverage mismatch for function %qs while reading counter %qs",
365	     IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl)),
366	     ctr_names[counter]);
367      error ("number of counters is %d instead of %d", entry->summary.num, expected);
368      return 0;
369    }
370
371  if (summary)
372    *summary = &entry->summary;
373
374  return entry->counts;
375}
376
377/* Allocate NUM counters of type COUNTER. Returns nonzero if the
378   allocation succeeded.  */
379
380int
381coverage_counter_alloc (unsigned counter, unsigned num)
382{
383  if (no_coverage)
384    return 0;
385
386  if (!num)
387    return 1;
388
389  if (!tree_ctr_tables[counter])
390    {
391      /* Generate and save a copy of this so it can be shared.  */
392      /* We don't know the size yet; make it big enough that nobody
393	 will make any clever transformation on it.  */
394      char buf[20];
395      tree gcov_type_node = get_gcov_type ();
396      tree domain_tree
397        = build_index_type (build_int_cst (NULL_TREE, 1000)); /* replaced later */
398      tree gcov_type_array_type
399        = build_array_type (gcov_type_node, domain_tree);
400      tree_ctr_tables[counter]
401        = build_decl (VAR_DECL, NULL_TREE, gcov_type_array_type);
402      TREE_STATIC (tree_ctr_tables[counter]) = 1;
403      ASM_GENERATE_INTERNAL_LABEL (buf, "LPBX", counter + 1);
404      DECL_NAME (tree_ctr_tables[counter]) = get_identifier (buf);
405      DECL_ALIGN (tree_ctr_tables[counter]) = TYPE_ALIGN (gcov_type_node);
406    }
407  fn_b_ctrs[counter] = fn_n_ctrs[counter];
408  fn_n_ctrs[counter] += num;
409  fn_ctr_mask |= 1 << counter;
410  return 1;
411}
412
413/* Generate a tree to access COUNTER NO.  */
414
415tree
416tree_coverage_counter_ref (unsigned counter, unsigned no)
417{
418  tree gcov_type_node = get_gcov_type ();
419  tree domain_type = TYPE_DOMAIN (TREE_TYPE (tree_ctr_tables[counter]));
420
421  gcc_assert (no < fn_n_ctrs[counter] - fn_b_ctrs[counter]);
422  no += prg_n_ctrs[counter] + fn_b_ctrs[counter];
423
424  /* "no" here is an array index, scaled to bytes later.  */
425  return build4 (ARRAY_REF, gcov_type_node, tree_ctr_tables[counter],
426		 fold_convert (domain_type,
427			       build_int_cst (NULL_TREE, no)),
428		 TYPE_MIN_VALUE (domain_type),
429		 size_binop (EXACT_DIV_EXPR, TYPE_SIZE_UNIT (gcov_type_node),
430			     size_int (TYPE_ALIGN_UNIT (gcov_type_node))));
431}
432
433/* Generate a checksum for a string.  CHKSUM is the current
434   checksum.  */
435
436static unsigned
437coverage_checksum_string (unsigned chksum, const char *string)
438{
439  int i;
440  char *dup = NULL;
441
442  /* Look for everything that looks if it were produced by
443     get_file_function_name_long and zero out the second part
444     that may result from flag_random_seed.  This is not critical
445     as the checksums are used only for sanity checking.  */
446  for (i = 0; string[i]; i++)
447    {
448      int offset = 0;
449      if (!strncmp (string + i, "_GLOBAL__N_", 11))
450      offset = 11;
451      if (!strncmp (string + i, "_GLOBAL__", 9))
452      offset = 9;
453
454      /* C++ namespaces do have scheme:
455         _GLOBAL__N_<filename>_<wrongmagicnumber>_<magicnumber>functionname
456       since filename might contain extra underscores there seems
457       to be no better chance then walk all possible offsets looking
458       for magicnuber.  */
459      if (offset)
460        for (;string[offset]; offset++)
461        for (i = i + offset; string[i]; i++)
462          if (string[i]=='_')
463            {
464              int y;
465
466              for (y = 1; y < 9; y++)
467                if (!(string[i + y] >= '0' && string[i + y] <= '9')
468                    && !(string[i + y] >= 'A' && string[i + y] <= 'F'))
469                  break;
470              if (y != 9 || string[i + 9] != '_')
471                continue;
472              for (y = 10; y < 18; y++)
473                if (!(string[i + y] >= '0' && string[i + y] <= '9')
474                    && !(string[i + y] >= 'A' && string[i + y] <= 'F'))
475                  break;
476              if (y != 18)
477                continue;
478              if (!dup)
479                string = dup = xstrdup (string);
480              for (y = 10; y < 18; y++)
481                dup[i + y] = '0';
482            }
483        break;
484    }
485
486  chksum = crc32_string (chksum, string);
487  if (dup)
488    free (dup);
489
490  return chksum;
491}
492
493/* Compute checksum for the current function.  We generate a CRC32.  */
494
495static unsigned
496compute_checksum (void)
497{
498  expanded_location xloc
499    = expand_location (DECL_SOURCE_LOCATION (current_function_decl));
500  unsigned chksum = xloc.line;
501
502  chksum = coverage_checksum_string (chksum, xloc.file);
503  chksum = coverage_checksum_string
504    (chksum, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl)));
505
506  return chksum;
507}
508
509/* Begin output to the graph file for the current function.
510   Opens the output file, if not already done. Writes the
511   function header, if not already done. Returns nonzero if data
512   should be output.  */
513
514int
515coverage_begin_output (void)
516{
517  if (no_coverage)
518    return 0;
519
520  if (!bbg_function_announced)
521    {
522      expanded_location xloc
523	= expand_location (DECL_SOURCE_LOCATION (current_function_decl));
524      unsigned long offset;
525
526      if (!bbg_file_opened)
527	{
528	  if (!gcov_open (bbg_file_name, -1))
529	    error ("cannot open %s", bbg_file_name);
530	  else
531	    {
532	      gcov_write_unsigned (GCOV_NOTE_MAGIC);
533	      gcov_write_unsigned (GCOV_VERSION);
534	      gcov_write_unsigned (local_tick);
535	    }
536	  bbg_file_opened = 1;
537	}
538
539      /* Announce function */
540      offset = gcov_write_tag (GCOV_TAG_FUNCTION);
541      gcov_write_unsigned (current_function_funcdef_no + 1);
542      gcov_write_unsigned (compute_checksum ());
543      gcov_write_string (IDENTIFIER_POINTER
544			 (DECL_ASSEMBLER_NAME (current_function_decl)));
545      gcov_write_string (xloc.file);
546      gcov_write_unsigned (xloc.line);
547      gcov_write_length (offset);
548
549      bbg_function_announced = 1;
550    }
551  return !gcov_is_error ();
552}
553
554/* Finish coverage data for the current function. Verify no output
555   error has occurred.  Save function coverage counts.  */
556
557void
558coverage_end_function (void)
559{
560  unsigned i;
561
562  if (bbg_file_opened > 1 && gcov_is_error ())
563    {
564      warning (0, "error writing %qs", bbg_file_name);
565      bbg_file_opened = -1;
566    }
567
568  if (fn_ctr_mask)
569    {
570      struct function_list *item;
571
572      item = xmalloc (sizeof (struct function_list));
573
574      *functions_tail = item;
575      functions_tail = &item->next;
576
577      item->next = 0;
578      item->ident = current_function_funcdef_no + 1;
579      item->checksum = compute_checksum ();
580      for (i = 0; i != GCOV_COUNTERS; i++)
581	{
582	  item->n_ctrs[i] = fn_n_ctrs[i];
583	  prg_n_ctrs[i] += fn_n_ctrs[i];
584	  fn_n_ctrs[i] = fn_b_ctrs[i] = 0;
585	}
586      prg_ctr_mask |= fn_ctr_mask;
587      fn_ctr_mask = 0;
588    }
589  bbg_function_announced = 0;
590}
591
592/* Creates the gcov_fn_info RECORD_TYPE.  */
593
594static tree
595build_fn_info_type (unsigned int counters)
596{
597  tree type = lang_hooks.types.make_type (RECORD_TYPE);
598  tree field, fields;
599  tree array_type;
600
601  /* ident */
602  fields = build_decl (FIELD_DECL, NULL_TREE, get_gcov_unsigned_t ());
603
604  /* checksum */
605  field = build_decl (FIELD_DECL, NULL_TREE, get_gcov_unsigned_t ());
606  TREE_CHAIN (field) = fields;
607  fields = field;
608
609  array_type = build_int_cst (NULL_TREE, counters - 1);
610  array_type = build_index_type (array_type);
611  array_type = build_array_type (unsigned_type_node, array_type);
612
613  /* counters */
614  field = build_decl (FIELD_DECL, NULL_TREE, array_type);
615  TREE_CHAIN (field) = fields;
616  fields = field;
617
618  finish_builtin_struct (type, "__gcov_fn_info", fields, NULL_TREE);
619
620  return type;
621}
622
623/* Creates a CONSTRUCTOR for a gcov_fn_info. FUNCTION is
624   the function being processed and TYPE is the gcov_fn_info
625   RECORD_TYPE.  */
626
627static tree
628build_fn_info_value (const struct function_list *function, tree type)
629{
630  tree value = NULL_TREE;
631  tree fields = TYPE_FIELDS (type);
632  unsigned ix;
633  tree array_value = NULL_TREE;
634
635  /* ident */
636  value = tree_cons (fields, build_int_cstu (get_gcov_unsigned_t (),
637					     function->ident), value);
638  fields = TREE_CHAIN (fields);
639
640  /* checksum */
641  value = tree_cons (fields, build_int_cstu (get_gcov_unsigned_t (),
642					     function->checksum), value);
643  fields = TREE_CHAIN (fields);
644
645  /* counters */
646  for (ix = 0; ix != GCOV_COUNTERS; ix++)
647    if (prg_ctr_mask & (1 << ix))
648      {
649	tree counters = build_int_cstu (unsigned_type_node,
650					function->n_ctrs[ix]);
651
652	array_value = tree_cons (NULL_TREE, counters, array_value);
653      }
654
655  /* FIXME: use build_constructor directly.  */
656  array_value = build_constructor_from_list (TREE_TYPE (fields),
657					     nreverse (array_value));
658  value = tree_cons (fields, array_value, value);
659
660  /* FIXME: use build_constructor directly.  */
661  value = build_constructor_from_list (type, nreverse (value));
662
663  return value;
664}
665
666/* Creates the gcov_ctr_info RECORD_TYPE.  */
667
668static tree
669build_ctr_info_type (void)
670{
671  tree type = lang_hooks.types.make_type (RECORD_TYPE);
672  tree field, fields = NULL_TREE;
673  tree gcov_ptr_type = build_pointer_type (get_gcov_type ());
674  tree gcov_merge_fn_type;
675
676  /* counters */
677  field = build_decl (FIELD_DECL, NULL_TREE, get_gcov_unsigned_t ());
678  TREE_CHAIN (field) = fields;
679  fields = field;
680
681  /* values */
682  field = build_decl (FIELD_DECL, NULL_TREE, gcov_ptr_type);
683  TREE_CHAIN (field) = fields;
684  fields = field;
685
686  /* merge */
687  gcov_merge_fn_type =
688    build_function_type_list (void_type_node,
689			      gcov_ptr_type, unsigned_type_node,
690			      NULL_TREE);
691  field = build_decl (FIELD_DECL, NULL_TREE,
692		      build_pointer_type (gcov_merge_fn_type));
693  TREE_CHAIN (field) = fields;
694  fields = field;
695
696  finish_builtin_struct (type, "__gcov_ctr_info", fields, NULL_TREE);
697
698  return type;
699}
700
701/* Creates a CONSTRUCTOR for a gcov_ctr_info. COUNTER is
702   the counter being processed and TYPE is the gcov_ctr_info
703   RECORD_TYPE.  */
704
705static tree
706build_ctr_info_value (unsigned int counter, tree type)
707{
708  tree value = NULL_TREE;
709  tree fields = TYPE_FIELDS (type);
710  tree fn;
711
712  /* counters */
713  value = tree_cons (fields,
714		     build_int_cstu (get_gcov_unsigned_t (),
715				     prg_n_ctrs[counter]),
716		     value);
717  fields = TREE_CHAIN (fields);
718
719  if (prg_n_ctrs[counter])
720    {
721      tree array_type;
722
723      array_type = build_int_cstu (unsigned_type_node,
724				   prg_n_ctrs[counter] - 1);
725      array_type = build_index_type (array_type);
726      array_type = build_array_type (TREE_TYPE (TREE_TYPE (fields)),
727				     array_type);
728
729      TREE_TYPE (tree_ctr_tables[counter]) = array_type;
730      DECL_SIZE (tree_ctr_tables[counter]) = TYPE_SIZE (array_type);
731      DECL_SIZE_UNIT (tree_ctr_tables[counter]) = TYPE_SIZE_UNIT (array_type);
732      assemble_variable (tree_ctr_tables[counter], 0, 0, 0);
733
734      value = tree_cons (fields,
735			 build1 (ADDR_EXPR, TREE_TYPE (fields),
736					    tree_ctr_tables[counter]),
737			 value);
738    }
739  else
740    value = tree_cons (fields, null_pointer_node, value);
741  fields = TREE_CHAIN (fields);
742
743  fn = build_decl (FUNCTION_DECL,
744		   get_identifier (ctr_merge_functions[counter]),
745		   TREE_TYPE (TREE_TYPE (fields)));
746  DECL_EXTERNAL (fn) = 1;
747  TREE_PUBLIC (fn) = 1;
748  DECL_ARTIFICIAL (fn) = 1;
749  TREE_NOTHROW (fn) = 1;
750  value = tree_cons (fields,
751		     build1 (ADDR_EXPR, TREE_TYPE (fields), fn),
752		     value);
753
754  /* FIXME: use build_constructor directly.  */
755  value = build_constructor_from_list (type, nreverse (value));
756
757  return value;
758}
759
760/* Creates the gcov_info RECORD_TYPE and initializer for it. Returns a
761   CONSTRUCTOR.  */
762
763static tree
764build_gcov_info (void)
765{
766  unsigned n_ctr_types, ix;
767  tree type, const_type;
768  tree fn_info_type, fn_info_value = NULL_TREE;
769  tree fn_info_ptr_type;
770  tree ctr_info_type, ctr_info_ary_type, ctr_info_value = NULL_TREE;
771  tree field, fields = NULL_TREE;
772  tree value = NULL_TREE;
773  tree filename_string;
774  char *filename;
775  int filename_len;
776  unsigned n_fns;
777  const struct function_list *fn;
778  tree string_type;
779
780  /* Count the number of active counters.  */
781  for (n_ctr_types = 0, ix = 0; ix != GCOV_COUNTERS; ix++)
782    if (prg_ctr_mask & (1 << ix))
783      n_ctr_types++;
784
785  type = lang_hooks.types.make_type (RECORD_TYPE);
786  const_type = build_qualified_type (type, TYPE_QUAL_CONST);
787
788  /* Version ident */
789  field = build_decl (FIELD_DECL, NULL_TREE, get_gcov_unsigned_t ());
790  TREE_CHAIN (field) = fields;
791  fields = field;
792  value = tree_cons (field, build_int_cstu (TREE_TYPE (field), GCOV_VERSION),
793		     value);
794
795  /* next -- NULL */
796  field = build_decl (FIELD_DECL, NULL_TREE, build_pointer_type (const_type));
797  TREE_CHAIN (field) = fields;
798  fields = field;
799  value = tree_cons (field, null_pointer_node, value);
800
801  /* stamp */
802  field = build_decl (FIELD_DECL, NULL_TREE, get_gcov_unsigned_t ());
803  TREE_CHAIN (field) = fields;
804  fields = field;
805  value = tree_cons (field, build_int_cstu (TREE_TYPE (field), local_tick),
806		     value);
807
808  /* Filename */
809  string_type = build_pointer_type (build_qualified_type (char_type_node,
810						    TYPE_QUAL_CONST));
811  field = build_decl (FIELD_DECL, NULL_TREE, string_type);
812  TREE_CHAIN (field) = fields;
813  fields = field;
814  filename = getpwd ();
815  filename = (filename && da_file_name[0] != '/'
816	      ? concat (filename, "/", da_file_name, NULL)
817	      : da_file_name);
818  filename_len = strlen (filename);
819  filename_string = build_string (filename_len + 1, filename);
820  if (filename != da_file_name)
821    free (filename);
822  TREE_TYPE (filename_string) = build_array_type
823    (char_type_node, build_index_type
824     (build_int_cst (NULL_TREE, filename_len)));
825  value = tree_cons (field, build1 (ADDR_EXPR, string_type, filename_string),
826		     value);
827
828  /* Build the fn_info type and initializer.  */
829  fn_info_type = build_fn_info_type (n_ctr_types);
830  fn_info_ptr_type = build_pointer_type (build_qualified_type
831					 (fn_info_type, TYPE_QUAL_CONST));
832  for (fn = functions_head, n_fns = 0; fn; fn = fn->next, n_fns++)
833    fn_info_value = tree_cons (NULL_TREE,
834			       build_fn_info_value (fn, fn_info_type),
835			       fn_info_value);
836  if (n_fns)
837    {
838      tree array_type;
839
840      array_type = build_index_type (build_int_cst (NULL_TREE, n_fns - 1));
841      array_type = build_array_type (fn_info_type, array_type);
842
843      /* FIXME: use build_constructor directly.  */
844      fn_info_value = build_constructor_from_list (array_type,
845						   nreverse (fn_info_value));
846      fn_info_value = build1 (ADDR_EXPR, fn_info_ptr_type, fn_info_value);
847    }
848  else
849    fn_info_value = null_pointer_node;
850
851  /* number of functions */
852  field = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node);
853  TREE_CHAIN (field) = fields;
854  fields = field;
855  value = tree_cons (field,
856		     build_int_cstu (unsigned_type_node, n_fns),
857		     value);
858
859  /* fn_info table */
860  field = build_decl (FIELD_DECL, NULL_TREE, fn_info_ptr_type);
861  TREE_CHAIN (field) = fields;
862  fields = field;
863  value = tree_cons (field, fn_info_value, value);
864
865  /* counter_mask */
866  field = build_decl (FIELD_DECL, NULL_TREE, unsigned_type_node);
867  TREE_CHAIN (field) = fields;
868  fields = field;
869  value = tree_cons (field,
870		     build_int_cstu (unsigned_type_node, prg_ctr_mask),
871		     value);
872
873  /* counters */
874  ctr_info_type = build_ctr_info_type ();
875  ctr_info_ary_type = build_index_type (build_int_cst (NULL_TREE,
876						       n_ctr_types));
877  ctr_info_ary_type = build_array_type (ctr_info_type, ctr_info_ary_type);
878  for (ix = 0; ix != GCOV_COUNTERS; ix++)
879    if (prg_ctr_mask & (1 << ix))
880      ctr_info_value = tree_cons (NULL_TREE,
881				  build_ctr_info_value (ix, ctr_info_type),
882				  ctr_info_value);
883  /* FIXME: use build_constructor directly.  */
884  ctr_info_value = build_constructor_from_list (ctr_info_ary_type,
885				                nreverse (ctr_info_value));
886
887  field = build_decl (FIELD_DECL, NULL_TREE, ctr_info_ary_type);
888  TREE_CHAIN (field) = fields;
889  fields = field;
890  value = tree_cons (field, ctr_info_value, value);
891
892  finish_builtin_struct (type, "__gcov_info", fields, NULL_TREE);
893
894  /* FIXME: use build_constructor directly.  */
895  value = build_constructor_from_list (type, nreverse (value));
896
897  return value;
898}
899
900/* Write out the structure which libgcov uses to locate all the
901   counters.  The structures used here must match those defined in
902   gcov-io.h.  Write out the constructor to call __gcov_init.  */
903
904static void
905create_coverage (void)
906{
907  tree gcov_info, gcov_init, body, t;
908  char name_buf[32];
909
910  no_coverage = 1; /* Disable any further coverage.  */
911
912  if (!prg_ctr_mask)
913    return;
914
915  t = build_gcov_info ();
916
917  gcov_info = build_decl (VAR_DECL, NULL_TREE, TREE_TYPE (t));
918  TREE_STATIC (gcov_info) = 1;
919  ASM_GENERATE_INTERNAL_LABEL (name_buf, "LPBX", 0);
920  DECL_NAME (gcov_info) = get_identifier (name_buf);
921  DECL_INITIAL (gcov_info) = t;
922
923  /* Build structure.  */
924  assemble_variable (gcov_info, 0, 0, 0);
925
926  /* Build a decl for __gcov_init.  */
927  t = build_pointer_type (TREE_TYPE (gcov_info));
928  t = build_function_type_list (void_type_node, t, NULL);
929  t = build_decl (FUNCTION_DECL, get_identifier ("__gcov_init"), t);
930  TREE_PUBLIC (t) = 1;
931  DECL_EXTERNAL (t) = 1;
932  gcov_init = t;
933
934  /* Generate a call to __gcov_init(&gcov_info).  */
935  body = NULL;
936  t = build_fold_addr_expr (gcov_info);
937  t = tree_cons (NULL, t, NULL);
938  t = build_function_call_expr (gcov_init, t);
939  append_to_statement_list (t, &body);
940
941  /* Generate a constructor to run it.  */
942  cgraph_build_static_cdtor ('I', body, DEFAULT_INIT_PRIORITY);
943}
944
945/* Perform file-level initialization. Read in data file, generate name
946   of graph file.  */
947
948void
949coverage_init (const char *filename)
950{
951  int len = strlen (filename);
952
953  /* Name of da file.  */
954  da_file_name = xmalloc (len + strlen (GCOV_DATA_SUFFIX) + 1);
955  strcpy (da_file_name, filename);
956  strcat (da_file_name, GCOV_DATA_SUFFIX);
957
958  /* Name of bbg file.  */
959  bbg_file_name = xmalloc (len + strlen (GCOV_NOTE_SUFFIX) + 1);
960  strcpy (bbg_file_name, filename);
961  strcat (bbg_file_name, GCOV_NOTE_SUFFIX);
962
963  read_counts_file ();
964}
965
966/* Performs file-level cleanup.  Close graph file, generate coverage
967   variables and constructor.  */
968
969void
970coverage_finish (void)
971{
972  create_coverage ();
973  if (bbg_file_opened)
974    {
975      int error = gcov_close ();
976
977      if (error)
978	unlink (bbg_file_name);
979      if (!local_tick)
980	/* Only remove the da file, if we cannot stamp it. If we can
981	   stamp it, libgcov will DTRT.  */
982	unlink (da_file_name);
983    }
984}
985
986#include "gt-coverage.h"
987