1/* Header file for libgcov-*.c.
2   Copyright (C) 1996-2014 Free Software Foundation, Inc.
3
4   This file is part of GCC.
5
6   GCC is free software; you can redistribute it and/or modify it under
7   the terms of the GNU General Public License as published by the Free
8   Software Foundation; either version 3, or (at your option) any later
9   version.
10
11   GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12   WARRANTY; without even the implied warranty of MERCHANTABILITY or
13   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14   for more details.
15
16   Under Section 7 of GPL version 3, you are granted additional
17   permissions described in the GCC Runtime Library Exception, version
18   3.1, as published by the Free Software Foundation.
19
20   You should have received a copy of the GNU General Public License and
21   a copy of the GCC Runtime Library Exception along with this program;
22   see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23   <http://www.gnu.org/licenses/>.  */
24
25#ifndef GCC_LIBGCOV_H
26#define GCC_LIBGCOV_H
27
28#ifndef __KERNEL__
29/* work around the poisoned malloc/calloc in system.h.  */
30#ifndef xmalloc
31#define xmalloc malloc
32#endif
33#ifndef xcalloc
34#define xcalloc calloc
35#endif
36#ifndef xrealloc
37#define xrealloc realloc
38#endif
39#ifndef xfree
40#define xfree free
41#endif
42#else /* __KERNEL__ */
43#include "libgcov-kernel.h"
44#endif /* __KERNEL__ */
45
46#ifndef IN_GCOV_TOOL
47/* About the target.  */
48/* This path will be used by libgcov runtime.  */
49
50#ifndef __KERNEL__
51#include "tconfig.h"
52#include "tsystem.h"
53#include "coretypes.h"
54#include "tm.h"
55#include "libgcc_tm.h"
56#endif /* __KERNEL__ */
57
58#undef FUNC_ID_WIDTH
59#undef FUNC_ID_MASK
60
61#if BITS_PER_UNIT == 8
62typedef unsigned gcov_unsigned_t __attribute__ ((mode (SI)));
63typedef unsigned gcov_position_t __attribute__ ((mode (SI)));
64#if LONG_LONG_TYPE_SIZE > 32
65typedef signed gcov_type __attribute__ ((mode (DI)));
66typedef unsigned gcov_type_unsigned __attribute__ ((mode (DI)));
67#define FUNC_ID_WIDTH 32
68#define FUNC_ID_MASK ((1ll << FUNC_ID_WIDTH) - 1)
69#else
70typedef signed gcov_type __attribute__ ((mode (SI)));
71typedef unsigned gcov_type_unsigned __attribute__ ((mode (SI)));
72#define FUNC_ID_WIDTH 16
73#define FUNC_ID_MASK ((1 << FUNC_ID_WIDTH) - 1)
74#endif
75#else  /* BITS_PER_UNIT != 8  */
76#if BITS_PER_UNIT == 16
77typedef unsigned gcov_unsigned_t __attribute__ ((mode (HI)));
78typedef unsigned gcov_position_t __attribute__ ((mode (HI)));
79#if LONG_LONG_TYPE_SIZE > 32
80typedef signed gcov_type __attribute__ ((mode (SI)));
81typedef unsigned gcov_type_unsigned __attribute__ ((mode (SI)));
82#define FUNC_ID_WIDTH 32
83#define FUNC_ID_MASK ((1ll << FUNC_ID_WIDTH) - 1)
84#else
85typedef signed gcov_type __attribute__ ((mode (HI)));
86typedef unsigned gcov_type_unsigned __attribute__ ((mode (HI)));
87#define FUNC_ID_WIDTH 16
88#define FUNC_ID_MASK ((1 << FUNC_ID_WIDTH) - 1)
89#endif
90#else /* BITS_PER_UNIT != 16  */
91typedef unsigned gcov_unsigned_t __attribute__ ((mode (QI)));
92typedef unsigned gcov_position_t __attribute__ ((mode (QI)));
93#if LONG_LONG_TYPE_SIZE > 32
94typedef signed gcov_type __attribute__ ((mode (HI)));
95typedef unsigned gcov_type_unsigned __attribute__ ((mode (HI)));
96#define FUNC_ID_WIDTH 32
97#define FUNC_ID_MASK ((1ll << FUNC_ID_WIDTH) - 1)
98#else
99typedef signed gcov_type __attribute__ ((mode (QI)));
100typedef unsigned gcov_type_unsigned __attribute__ ((mode (QI)));
101#define FUNC_ID_WIDTH 16
102#define FUNC_ID_MASK ((1 << FUNC_ID_WIDTH) - 1)
103#endif
104#endif  /* BITS_PER_UNIT == 16  */
105#endif  /* BITS_PER_UNIT == 8  */
106
107#if LONG_LONG_TYPE_SIZE > 32
108#define GCOV_TYPE_ATOMIC_FETCH_ADD_FN __atomic_fetch_add_8
109#define GCOV_TYPE_ATOMIC_FETCH_ADD BUILT_IN_ATOMIC_FETCH_ADD_8
110#else
111#define GCOV_TYPE_ATOMIC_FETCH_ADD_FN __atomic_fetch_add_4
112#define GCOV_TYPE_ATOMIC_FETCH_ADD BUILT_IN_ATOMIC_FETCH_ADD_4
113#endif
114
115#if defined (TARGET_POSIX_IO)
116#define GCOV_LOCKED 1
117#else
118#define GCOV_LOCKED 0
119#endif
120
121#else /* IN_GCOV_TOOL */
122/* About the host.  */
123/* This path will be compiled for the host and linked into
124   gcov-tool binary.  */
125
126#include "config.h"
127#include "system.h"
128#include "coretypes.h"
129#include "tm.h"
130
131typedef unsigned gcov_unsigned_t;
132typedef unsigned gcov_position_t;
133/* gcov_type is typedef'd elsewhere for the compiler */
134#if defined (HOST_HAS_F_SETLKW)
135#define GCOV_LOCKED 1
136#else
137#define GCOV_LOCKED 0
138#endif
139
140#define FUNC_ID_WIDTH 32
141#define FUNC_ID_MASK ((1ll << FUNC_ID_WIDTH) - 1)
142
143/* Some Macros specific to gcov-tool.  */
144
145#define L_gcov 1
146#define L_gcov_merge_add 1
147#define L_gcov_merge_single 1
148#define L_gcov_merge_delta 1
149#define L_gcov_merge_ior 1
150#define L_gcov_merge_time_profile 1
151#define L_gcov_merge_icall_topn 1
152#define L_gcov_merge_dc 1
153
154/* Make certian internal functions/variables in libgcov available for
155   gcov-tool access.  */
156#define GCOV_TOOL_LINKAGE
157
158extern gcov_type gcov_read_counter_mem ();
159extern unsigned gcov_get_merge_weight ();
160
161#endif /* !IN_GCOV_TOOL */
162
163#undef EXTRACT_MODULE_ID_FROM_GLOBAL_ID
164#undef EXTRACT_FUNC_ID_FROM_GLOBAL_ID
165#undef GEN_FUNC_GLOBAL_ID
166#define EXTRACT_MODULE_ID_FROM_GLOBAL_ID(gid) \
167                (gcov_unsigned_t)(((gid) >> FUNC_ID_WIDTH) & FUNC_ID_MASK)
168#define EXTRACT_FUNC_ID_FROM_GLOBAL_ID(gid) \
169                (gcov_unsigned_t)((gid) & FUNC_ID_MASK)
170#define GEN_FUNC_GLOBAL_ID(m,f) ((((gcov_type) (m)) << FUNC_ID_WIDTH) | (f))
171
172#if defined(inhibit_libc)
173#define IN_LIBGCOV (-1)
174#else
175#define IN_LIBGCOV 1
176#if defined(L_gcov)
177#define GCOV_LINKAGE /* nothing */
178#endif
179#endif
180
181/* In libgcov we need these functions to be extern, so prefix them with
182   __gcov.  In libgcov they must also be hidden so that the instance in
183   the executable is not also used in a DSO.  */
184#define gcov_var __gcov_var
185#define gcov_open __gcov_open
186#define gcov_close __gcov_close
187#define gcov_write_tag_length __gcov_write_tag_length
188#define gcov_position __gcov_position
189#define gcov_seek __gcov_seek
190#define gcov_rewrite __gcov_rewrite
191#define gcov_truncate __gcov_truncate
192#define gcov_is_error __gcov_is_error
193#define gcov_write_unsigned __gcov_write_unsigned
194#define gcov_write_counter __gcov_write_counter
195#define gcov_write_summary __gcov_write_summary
196#define gcov_write_module_info __gcov_write_module_info
197#define gcov_read_unsigned __gcov_read_unsigned
198#define gcov_read_counter __gcov_read_counter
199#define gcov_read_summary __gcov_read_summary
200#define gcov_read_buildinfo __gcov_read_buildinfo
201#define gcov_read_module_info __gcov_read_module_info
202#define gcov_sort_n_vals __gcov_sort_n_vals
203
204/* Poison these, so they don't accidentally slip in.  */
205#pragma GCC poison gcov_write_string gcov_write_tag gcov_write_length
206#pragma GCC poison gcov_time gcov_magic
207
208#ifdef HAVE_GAS_HIDDEN
209#define ATTRIBUTE_HIDDEN  __attribute__ ((__visibility__ ("hidden")))
210#else
211#define ATTRIBUTE_HIDDEN
212#endif
213
214#include "gcov-io.h"
215
216/* Structures embedded in coveraged program.  The structures generated
217   by write_profile must match these.  */
218/* Information about counters for a single function.  */
219struct gcov_ctr_info
220{
221  gcov_unsigned_t num;          /* number of counters.  */
222  gcov_type *values;            /* their values.  */
223};
224
225/* Information about a single function.  This uses the trailing array
226   idiom. The number of counters is determined from the merge pointer
227   array in gcov_info.  The key is used to detect which of a set of
228   comdat functions was selected -- it points to the gcov_info object
229   of the object file containing the selected comdat function.  */
230
231struct gcov_fn_info
232{
233  const struct gcov_info *key;          /* comdat key */
234  gcov_unsigned_t ident;                /* unique ident of function */
235  gcov_unsigned_t lineno_checksum;      /* function lineo_checksum */
236  gcov_unsigned_t cfg_checksum; /* function cfg checksum */
237  struct gcov_ctr_info ctrs[1];         /* instrumented counters */
238};
239
240/* Type of function used to merge counters.  */
241typedef void (*gcov_merge_fn) (gcov_type *, gcov_unsigned_t);
242
243/* Information about a single object file.  */
244struct gcov_info
245{
246  gcov_unsigned_t version;      /* expected version number */
247  struct gcov_module_info *mod_info; /* addtional module info.  */
248  struct gcov_info *next;       /* link to next, used by libgcov */
249
250  gcov_unsigned_t stamp;        /* uniquifying time stamp */
251  const char *filename;         /* output file name */
252  gcov_unsigned_t eof_pos;      /* end position of profile data */
253  gcov_merge_fn merge[GCOV_COUNTERS];  /* merge functions (null for
254                                          unused) */
255
256  unsigned n_functions;         /* number of functions */
257
258#if !defined (IN_GCOV_TOOL) && !defined (__KERNEL__)
259  const struct gcov_fn_info *const *functions; /* pointer to pointers
260                                                  to function information  */
261#elif defined (IN_GCOV_TOOL)
262  const struct gcov_fn_info **functions;
263#else
264  struct gcov_fn_info **functions;
265#endif /* !IN_GCOV_TOOL */
266  char **build_info;            /* strings to include in BUILD_INFO
267                                   section of gcda file.  */
268};
269
270/* Information about a single imported module.  */
271struct dyn_imp_mod
272{
273  const struct gcov_info *imp_mod;
274  double weight;
275};
276
277/* Register a new object file module.  */
278extern void __gcov_init (struct gcov_info *) ATTRIBUTE_HIDDEN;
279
280/* Set sampling rate to RATE.  */
281extern void __gcov_set_sampling_rate (unsigned int rate);
282
283/* Called before fork, to avoid double counting.  */
284extern void __gcov_flush (void) ATTRIBUTE_HIDDEN;
285
286/* Function to reset all counters to 0.  */
287extern void __gcov_reset (void);
288/* Function to enable early write of profile information so far.
289   __gcov_dump is also used by __gcov_dump_all. The latter
290   depends on __GCOV_DUMP to have hidden or protected visibility
291   so that each library has its own copy of the registered dumper.  */
292extern void __gcov_dump (void) ATTRIBUTE_HIDDEN;
293
294/* Call __gcov_dump registered from each shared library.
295   This function must have default visibility.  */
296void __gcov_dump_all (void);
297
298/* The merge function that just sums the counters.  */
299extern void __gcov_merge_add (gcov_type *, unsigned) ATTRIBUTE_HIDDEN;
300
301/* The merge function to choose the most common value.  */
302extern void __gcov_merge_single (gcov_type *, unsigned) ATTRIBUTE_HIDDEN;
303
304/* The merge function to choose the most common difference between
305   consecutive values.  */
306extern void __gcov_merge_delta (gcov_type *, unsigned) ATTRIBUTE_HIDDEN;
307
308/* The merge function that just ors the counters together.  */
309extern void __gcov_merge_ior (gcov_type *, unsigned) ATTRIBUTE_HIDDEN;
310
311/* The merge function used for direct call counters.  */
312extern void __gcov_merge_dc (gcov_type *, unsigned) ATTRIBUTE_HIDDEN;
313
314/* The merge function used for indirect call counters.  */
315extern void __gcov_merge_icall_topn (gcov_type *, unsigned) ATTRIBUTE_HIDDEN;
316
317extern void __gcov_merge_time_profile (gcov_type *, unsigned) ATTRIBUTE_HIDDEN;
318
319/* The profiler functions.  */
320extern void __gcov_interval_profiler (gcov_type *, gcov_type, int, unsigned);
321extern void __gcov_pow2_profiler (gcov_type *, gcov_type);
322extern void __gcov_one_value_profiler (gcov_type *, gcov_type);
323extern void __gcov_indirect_call_profiler (gcov_type*, gcov_type,
324                                           void*, void*);
325extern void __gcov_indirect_call_profiler_v2 (gcov_type, void *);
326extern void __gcov_indirect_call_topn_profiler (void *, void *, gcov_unsigned_t) ATTRIBUTE_HIDDEN;
327extern void __gcov_direct_call_profiler (void *, void *, gcov_unsigned_t) ATTRIBUTE_HIDDEN;
328extern void __gcov_average_profiler (gcov_type *, gcov_type);
329extern void __gcov_ior_profiler (gcov_type *, gcov_type);
330extern void __gcov_sort_n_vals (gcov_type *value_array, int n);
331extern void __gcov_time_profiler (gcov_type *);
332
333#ifndef inhibit_libc
334/* The wrappers around some library functions..  */
335extern pid_t __gcov_fork (void) ATTRIBUTE_HIDDEN;
336extern int __gcov_execl (const char *, char *, ...) ATTRIBUTE_HIDDEN;
337extern int __gcov_execlp (const char *, char *, ...) ATTRIBUTE_HIDDEN;
338extern int __gcov_execle (const char *, char *, ...) ATTRIBUTE_HIDDEN;
339extern int __gcov_execv (const char *, char *const []) ATTRIBUTE_HIDDEN;
340extern int __gcov_execvp (const char *, char *const []) ATTRIBUTE_HIDDEN;
341extern int __gcov_execve (const char *, char  *const [], char *const [])
342  ATTRIBUTE_HIDDEN;
343
344
345/* Functions that only available in libgcov.  */
346GCOV_LINKAGE int gcov_open (const char */*name*/) ATTRIBUTE_HIDDEN;
347GCOV_LINKAGE void gcov_write_counter (gcov_type) ATTRIBUTE_HIDDEN;
348GCOV_LINKAGE void gcov_write_tag_length (gcov_unsigned_t, gcov_unsigned_t)
349    ATTRIBUTE_HIDDEN;
350GCOV_LINKAGE void gcov_write_summary (gcov_unsigned_t /*tag*/,
351                                      const struct gcov_summary *)
352    ATTRIBUTE_HIDDEN;
353GCOV_LINKAGE void gcov_seek (gcov_position_t /*position*/) ATTRIBUTE_HIDDEN;
354GCOV_LINKAGE void gcov_truncate (void) ATTRIBUTE_HIDDEN;
355void gcov_write_module_info (const struct gcov_info *, unsigned)
356    ATTRIBUTE_HIDDEN;
357GCOV_LINKAGE void gcov_write_module_infos (struct gcov_info *mod_info)
358    ATTRIBUTE_HIDDEN;
359GCOV_LINKAGE const struct dyn_imp_mod **
360gcov_get_sorted_import_module_array (struct gcov_info *mod_info, unsigned *len)
361    ATTRIBUTE_HIDDEN;
362GCOV_LINKAGE inline void gcov_rewrite (void);
363
364extern void set_gcov_fn_fixed_up (int fixed_up);
365extern int get_gcov_fn_fixed_up (void);
366
367/* "Counts" stored in gcda files can be a real counter value, or
368   an target address. When differentiate these two types because
369   when manipulating counts, we should only change real counter values,
370   rather target addresses.  */
371
372static inline gcov_type
373gcov_get_counter (void)
374{
375#ifndef IN_GCOV_TOOL
376  /* This version is for reading count values in libgcov runtime:
377     we read from gcda files.  */
378
379  if (get_gcov_fn_fixed_up ())
380    {
381      gcov_read_counter ();
382      return 0;
383    }
384  else
385    return gcov_read_counter ();
386#else
387  /* This version is for gcov-tool. We read the value from memory and
388     multiply it by the merge weight.  */
389
390  return gcov_read_counter_mem () * gcov_get_merge_weight ();
391#endif
392}
393
394/* Similar function as gcov_get_counter(), but handles target address
395   counters.  */
396
397static inline gcov_type
398gcov_get_counter_target (void)
399{
400#ifndef IN_GCOV_TOOL
401  /* This version is for reading count target values in libgcov runtime:
402     we read from gcda files.  */
403
404  if (get_gcov_fn_fixed_up ())
405    {
406      gcov_read_counter ();
407      return 0;
408    }
409  else
410    return gcov_read_counter ();
411#else
412  /* This version is for gcov-tool.  We read the value from memory and we do NOT
413     multiply it by the merge weight.  */
414
415  return gcov_read_counter_mem ();
416#endif
417}
418
419#endif /* !inhibit_libc */
420
421#endif /* GCC_LIBGCOV_H */
422